From 9573e7216b7639ec5fb9b1b4d0612c1ce3fba576 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 8 May 2020 23:20:37 -0700 Subject: [PATCH 001/848] Windows: Make init crash warnings more generic. Let's not trap ourselves in the mindset that it MUST be graphics. --- Windows/EmuThread.cpp | 4 ++-- Windows/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 5c60b495ad..7239929dae 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -148,8 +148,8 @@ void MainThreadFunc() { Reporting::ReportMessage("Graphics init error: %s", "ALL"); auto err = GetI18NCategory("Error"); - const char *defaultErrorAll = "Failed initializing any graphics. Try upgrading your graphics drivers."; - const char *genericError = err->T("GenericAllGraphicsError", defaultErrorAll); + const char *defaultErrorAll = "PPSSPP failed to startup with any graphics backend. Try upgrading your graphics and other drivers."; + const char *genericError = err->T("GenericAllStartupError", defaultErrorAll); std::wstring title = ConvertUTF8ToWString(err->T("GenericGraphicsError", "Graphics Error")); MessageBox(0, ConvertUTF8ToWString(genericError).c_str(), title.c_str(), MB_OK); diff --git a/Windows/main.cpp b/Windows/main.cpp index 73938e6093..356e48ff0b 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -291,7 +291,7 @@ void System_SendMessage(const char *command, const char *parameter) { } } else if (!strcmp(command, "graphics_failedBackend")) { auto err = GetI18NCategory("Error"); - const char *backendSwitchError = err->T("GenericBackendSwitchError", "PPSSPP crashed while initializing graphics. Try upgrading your graphics drivers.\n\nGraphics backend has been switched:"); + const char *backendSwitchError = err->T("GenericBackendSwitchCrash", "PPSSPP crashed while starting. This usually means a graphics driver problem. Try upgrading your graphics drivers.\n\nGraphics backend has been switched:"); std::wstring full_error = ConvertUTF8ToWString(StringFromFormat("%s %s", backendSwitchError, parameter)); std::wstring title = ConvertUTF8ToWString(err->T("GenericGraphicsError", "Graphics Error")); MessageBox(MainWindow::GetHWND(), full_error.c_str(), title.c_str(), MB_OK); From 69d806a83aab61e2c4587694d86bf07c735bb4fe Mon Sep 17 00:00:00 2001 From: iota97 Date: Sat, 16 May 2020 22:01:16 +0200 Subject: [PATCH 002/848] Add postprocessing CWCHEAT --- Core/CwCheat.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index bf66680122..3fdfeee9a6 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -421,6 +421,7 @@ enum class CheatOp { CopyBytesFrom, Vibration, VibrationFromMemory, + PostShader, Delay, Assert, @@ -475,6 +476,13 @@ struct CheatOperation { uint8_t vibrLTime; uint8_t vibrRTime; } vibrationValues; + struct { + union { + float f; + uint32_t i; + } value; + uint8_t uniform; + } PostShaderUniform; }; }; @@ -620,6 +628,13 @@ CheatOperation CWCheatEngine::InterpretNextCwCheat(const CheatCode &cheat, size_ case 0x1: // 0x1 reads value for gamepad vibration from memory addr = line1.part2; return { CheatOp::VibrationFromMemory, addr }; + case 0x2: // 0x2 sets postprocessing shader uniform + { + CheatOperation op = { CheatOp::PostShader }; + op.PostShaderUniform.uniform = line1.part1 & 0x000000FF; + op.PostShaderUniform.value.i = line1.part2; + return op; + } // Place for other PPSSPP specific cheats default: return { CheatOp::Invalid }; @@ -919,6 +934,11 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, } break; + case CheatOp::PostShader: + if (op.PostShaderUniform.uniform >= 0 && op.PostShaderUniform.uniform < 4) + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = op.PostShaderUniform.value.f; + break; + case CheatOp::Delay: // TODO: Not supported. break; From c83e2fb07001ba66957d2bcf766010e27d47bdc7 Mon Sep 17 00:00:00 2001 From: iota97 Date: Sun, 17 May 2020 00:13:11 +0200 Subject: [PATCH 003/848] Memory reading CWCheat --- Core/CwCheat.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 3fdfeee9a6..2a648960fd 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -422,6 +422,7 @@ enum class CheatOp { Vibration, VibrationFromMemory, PostShader, + PostShaderFromMemory, Delay, Assert, @@ -482,6 +483,7 @@ struct CheatOperation { uint32_t i; } value; uint8_t uniform; + uint8_t format; } PostShaderUniform; }; }; @@ -635,6 +637,14 @@ CheatOperation CWCheatEngine::InterpretNextCwCheat(const CheatCode &cheat, size_ op.PostShaderUniform.value.i = line1.part2; return op; } + case 0x3: // 0x3 sets postprocessing shader uniform from memory + { + addr = line1.part2; + CheatOperation op = { CheatOp::PostShaderFromMemory, addr }; + op.PostShaderUniform.uniform = line1.part1 & 0x000000FF; + op.PostShaderUniform.format = (line1.part1 >> 8) & 0x000000FF; + return op; + } // Place for other PPSSPP specific cheats default: return { CheatOp::Invalid }; @@ -939,6 +949,30 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = op.PostShaderUniform.value.f; break; + case CheatOp::PostShaderFromMemory: + if (Memory::IsValidAddress(op.addr) && op.PostShaderUniform.uniform >= 0 && op.PostShaderUniform.uniform < 4) { + union { + float f; + uint32_t u; + } value; + value.u = Memory::Read_U32(op.addr); + switch (op.PostShaderUniform.format) { + case (0): + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u & 0x000000FF; + break; + case (1): + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u & 0x0000FFFF; + break; + case (2): + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u; + break; + case (3): + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.f; + break; + } + } + break; + case CheatOp::Delay: // TODO: Not supported. break; From 6f59f02b38acb5824da46e3b1e72bd0d22d9cc35 Mon Sep 17 00:00:00 2001 From: iota97 Date: Sun, 17 May 2020 19:06:23 +0200 Subject: [PATCH 004/848] Support chain --- Core/CwCheat.cpp | 62 ++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 2a648960fd..7712153740 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -16,6 +16,7 @@ #include "Core/System.h" #include "Core/HLE/sceCtrl.h" #include "Core/MIPS/JitCommon/JitCommon.h" +#include "GPU/Common/PostShader.h" #ifdef _WIN32 #include "util/text/utf8.h" @@ -480,8 +481,9 @@ struct CheatOperation { struct { union { float f; - uint32_t i; + uint32_t u; } value; + uint8_t shader; uint8_t uniform; uint8_t format; } PostShaderUniform; @@ -634,7 +636,8 @@ CheatOperation CWCheatEngine::InterpretNextCwCheat(const CheatCode &cheat, size_ { CheatOperation op = { CheatOp::PostShader }; op.PostShaderUniform.uniform = line1.part1 & 0x000000FF; - op.PostShaderUniform.value.i = line1.part2; + op.PostShaderUniform.shader = (line1.part1 >> 16) & 0x000000FF; + op.PostShaderUniform.value.u = line1.part2; return op; } case 0x3: // 0x3 sets postprocessing shader uniform from memory @@ -643,6 +646,7 @@ CheatOperation CWCheatEngine::InterpretNextCwCheat(const CheatCode &cheat, size_ CheatOperation op = { CheatOp::PostShaderFromMemory, addr }; op.PostShaderUniform.uniform = line1.part1 & 0x000000FF; op.PostShaderUniform.format = (line1.part1 >> 8) & 0x000000FF; + op.PostShaderUniform.shader = (line1.part1 >> 16) & 0x000000FF; return op; } // Place for other PPSSPP specific cheats @@ -945,30 +949,42 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, break; case CheatOp::PostShader: - if (op.PostShaderUniform.uniform >= 0 && op.PostShaderUniform.uniform < 4) - g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = op.PostShaderUniform.value.f; + { + auto shaderChain = GetPostShaderChain(g_Config.sPostShaderName); + if (op.PostShaderUniform.shader < shaderChain.size()) { + std::string shaderName = shaderChain[op.PostShaderUniform.shader]->section; + if (shaderName != "Off") + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = op.PostShaderUniform.value.f; + } + } break; case CheatOp::PostShaderFromMemory: - if (Memory::IsValidAddress(op.addr) && op.PostShaderUniform.uniform >= 0 && op.PostShaderUniform.uniform < 4) { - union { - float f; - uint32_t u; - } value; - value.u = Memory::Read_U32(op.addr); - switch (op.PostShaderUniform.format) { - case (0): - g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u & 0x000000FF; - break; - case (1): - g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u & 0x0000FFFF; - break; - case (2): - g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u; - break; - case (3): - g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", g_Config.sPostShaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.f; - break; + { + auto shaderChain = GetPostShaderChain(g_Config.sPostShaderName); + if (Memory::IsValidAddress(op.addr) && op.PostShaderUniform.shader < shaderChain.size()) { + union { + float f; + uint32_t u; + } value; + value.u = Memory::Read_U32(op.addr); + std::string shaderName = shaderChain[op.PostShaderUniform.shader]->section; + if (shaderName != "Off") { + switch (op.PostShaderUniform.format) { + case (0): + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u & 0x000000FF; + break; + case (1): + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u & 0x0000FFFF; + break; + case (2): + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u; + break; + case (3): + g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.f; + break; + } + } } } break; From dc7ee541105bfd5790bb4643a6caf029ee0424e4 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 May 2020 20:37:26 -0700 Subject: [PATCH 005/848] UI: Take reporting screenshot at frame end. If we do it mid frame, we need to rebind the backbuffer and reset viewport/scissor. Without viewport, Intel drivers crash. Doing it at the end of the frame keeps the code simple, although we often create views an extra time. Fixes #12897. --- UI/ReportScreen.cpp | 37 +++++++++++++++++++++++++++---------- UI/ReportScreen.h | 2 ++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index fe0988733d..96ba662c6f 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -161,6 +161,28 @@ ReportScreen::ReportScreen(const std::string &gamePath) ratingEnabled_ = enableReporting_; } +void ReportScreen::postRender() { + // We do this after render because we need it to be within the frame (so the screenshot works). + // We could do it mid frame, but then we have to reapply viewport/scissor. + if (!tookScreenshot_) { + std::string path = GetSysDirectory(DIRECTORY_SCREENSHOT); + if (!File::Exists(path)) { + File::CreateDir(path); + } + screenshotFilename_ = path + ".reporting.jpg"; + if (TakeGameScreenshot(screenshotFilename_.c_str(), ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, nullptr, nullptr, 4)) { + // Redo the views already, now with a screenshot included. + RecreateViews(); + } else { + // Good news (?), the views are good as-is without a screenshot. + screenshotFilename_.clear(); + } + tookScreenshot_ = true; + } + + UIDialogScreenWithGameBackground::postRender(); +} + void ReportScreen::update() { if (screenshot_) { if (includeScreenshot_) { @@ -252,18 +274,13 @@ void ReportScreen::CreateViews() { } #endif - std::string path = GetSysDirectory(DIRECTORY_SCREENSHOT); - if (!File::Exists(path)) { - File::CreateDir(path); - } - screenshotFilename_ = path + ".reporting.jpg"; - int shotWidth = 0, shotHeight = 0; - if (TakeGameScreenshot(screenshotFilename_.c_str(), ScreenshotFormat::JPG, SCREENSHOT_DISPLAY, &shotWidth, &shotHeight, 4)) { - float scale = 340.0f * (1.0f / g_dpi_scale_y) * (1.0f / shotHeight); + if (tookScreenshot_ && !screenshotFilename_.empty()) { leftColumnItems->Add(new CheckBox(&includeScreenshot_, rp->T("FeedbackIncludeScreen", "Include a screenshot")))->SetEnabledPtr(&enableReporting_); screenshot_ = leftColumnItems->Add(new AsyncImageFileView(screenshotFilename_, IS_KEEP_ASPECT, nullptr, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Margins(12, 0)))); } else { - includeScreenshot_ = false; + if (tookScreenshot_) { + includeScreenshot_ = false; + } screenshot_ = nullptr; } @@ -333,7 +350,7 @@ EventReturn ReportScreen::HandleSubmit(EventParams &e) { g_Config.Save("ReportScreen::HandleSubmit"); } - std::string filename = includeScreenshot_ ? screenshotFilename_ : ""; + std::string filename = tookScreenshot_ && includeScreenshot_ ? screenshotFilename_ : ""; Reporting::ReportCompatibility(compat, graphics_ + 1, speed_ + 1, gameplay_ + 1, filename); TriggerFinish(DR_OK); screenManager()->push(new ReportFinishScreen(gamePath_, overall_)); diff --git a/UI/ReportScreen.h b/UI/ReportScreen.h index 18c0d2b930..e3992170ac 100644 --- a/UI/ReportScreen.h +++ b/UI/ReportScreen.h @@ -37,6 +37,7 @@ public: ReportScreen(const std::string &gamePath); protected: + void postRender() override; void update() override; void resized() override; void CreateViews() override; @@ -60,6 +61,7 @@ protected: int gameplay_ = -1; bool enableReporting_; bool ratingEnabled_; + bool tookScreenshot_ = false; bool includeScreenshot_ = true; }; From d295feda82dd602304ee4f0917d4744164077715 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 May 2020 20:40:22 -0700 Subject: [PATCH 006/848] Vulkan: Add asserts to catch no viewport render. Also assert to prevent a sync outside a frame, which goes badly. The curRenderStep_ reset on same fb made some debugging easier, but should not actually be hit in any real case. --- ext/native/thin3d/GLRenderManager.cpp | 1 + ext/native/thin3d/VulkanRenderManager.cpp | 11 +++++++++++ ext/native/thin3d/VulkanRenderManager.h | 6 ++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index e1d8393162..3d90882789 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -269,6 +269,7 @@ void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRende if (steps_.size() && steps_.back()->render.framebuffer == fb && steps_.back()->stepType == GLRStepType::RENDER) { if (color != GLRRenderPassAction::CLEAR && depth != GLRRenderPassAction::CLEAR && stencil != GLRRenderPassAction::CLEAR) { // We don't move to a new step, this bind was unnecessary and we can safely skip it. + curRenderStep_ = steps_.back(); return; } } diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index fb39fc3cd0..18536e9799 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -461,6 +461,14 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR if (color != VKRRenderPassAction::CLEAR && depth != VKRRenderPassAction::CLEAR && stencil != VKRRenderPassAction::CLEAR) { // We don't move to a new step, this bind was unnecessary and we can safely skip it. // Not sure how much this is still happening but probably worth checking for nevertheless. + curRenderStep_ = steps_.back(); + curStepHasViewport_ = false; + for (const auto &c : steps_.back()->commands) { + if (c.cmd == VKRRenderCommand::VIEWPORT) { + curStepHasViewport_ = true; + break; + } + } return; } } @@ -498,6 +506,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR } curRenderStep_ = step; + curStepHasViewport_ = false; if (fb) { curWidth_ = fb->width; curHeight_ = fb->height; @@ -508,6 +517,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR } bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) { + assert(insideFrame_); for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { steps_[i]->render.numReads++; @@ -568,6 +578,7 @@ bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int a } void VulkanRenderManager::CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) { + assert(insideFrame_); VKRStep *step = new VKRStep{ VKRStepType::READBACK_IMAGE }; step->readback_image.image = image; step->readback_image.srcRect.offset = { x, y }; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 530912d857..ebd7c6bda2 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -136,6 +136,7 @@ public: data.viewport.vp.minDepth = clamp_value(vp.minDepth, 0.0f, 1.0f); data.viewport.vp.maxDepth = clamp_value(vp.maxDepth, 0.0f, 1.0f); curRenderStep_->commands.push_back(data); + curStepHasViewport_ = true; } void SetScissor(const VkRect2D &rc) { @@ -178,7 +179,7 @@ public: void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask); void Draw(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, int count, int offset = 0) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_); VkRenderData data{ VKRRenderCommand::DRAW }; data.draw.count = count; data.draw.offset = offset; @@ -195,7 +196,7 @@ public: } void DrawIndexed(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType indexType) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_); VkRenderData data{ VKRRenderCommand::DRAW_INDEXED }; data.drawIndexed.count = count; data.drawIndexed.instances = numInstances; @@ -315,6 +316,7 @@ private: int curHeight_ = -1; bool insideFrame_ = false; VKRStep *curRenderStep_ = nullptr; + bool curStepHasViewport_ = false; std::vector steps_; bool splitSubmit_ = false; From 7fffe1d8859ff54ef6fab6666c872ee9d101ab09 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 May 2020 21:23:32 -0700 Subject: [PATCH 007/848] Vulkan: Verify scissor as well. Vulkan spec requires both are set - we do set both, so let's catch any mistakes. --- ext/native/thin3d/VulkanRenderManager.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index ebd7c6bda2..9398781400 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -146,6 +146,7 @@ public: VkRenderData data{ VKRRenderCommand::SCISSOR }; data.scissor.scissor = rc; curRenderStep_->commands.push_back(data); + curStepHasScissor_ = true; } void SetStencilParams(uint8_t writeMask, uint8_t compareMask, uint8_t refValue) { @@ -179,7 +180,7 @@ public: void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask); void Draw(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, int count, int offset = 0) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_); + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_); VkRenderData data{ VKRRenderCommand::DRAW }; data.draw.count = count; data.draw.offset = offset; @@ -196,7 +197,7 @@ public: } void DrawIndexed(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType indexType) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_); + _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_); VkRenderData data{ VKRRenderCommand::DRAW_INDEXED }; data.drawIndexed.count = count; data.drawIndexed.instances = numInstances; @@ -317,6 +318,7 @@ private: bool insideFrame_ = false; VKRStep *curRenderStep_ = nullptr; bool curStepHasViewport_ = false; + bool curStepHasScissor_ = false; std::vector steps_; bool splitSubmit_ = false; From 1e6cd11d4ee18a64d4f5fdd65f1aa21ff6484c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 18 May 2020 22:01:15 +0200 Subject: [PATCH 008/848] Vulkan: Switch the framebuffer-rebind-to-clear on reformat to, well, a normal clear instead. Who knows, might be related to #12927 (but in that case we also have more problems). --- GPU/Vulkan/FramebufferVulkan.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index dfef7d47b7..d8829a4ea1 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -265,9 +265,8 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, // to exactly reproduce in 4444 and 8888 formats. if (old == GE_FORMAT_565) { - // TODO: To match other backends, would be ideal to clear alpha only and not color. - // But probably doesn't matter that much... - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + // Previously started a render pass here to clear, but better to just, well, explicitly clear. + draw_->Clear(Draw::FBChannel::FB_COLOR_BIT | Draw::FBChannel::FB_STENCIL_BIT, 0, 0.0f, 0); } } From 4e00a20c1f0d62574e51cdf86bee435cca486479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 18 May 2020 23:16:00 +0200 Subject: [PATCH 009/848] Show "debug build" on the splash screen, in debug builds. --- UI/MiscScreens.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 7795ffc65e..a6542c65d0 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -516,6 +516,9 @@ void LogoScreen::render() { #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); +#ifdef _DEBUG + apiName += ", debug build"; +#endif dc.DrawText(gr->T(apiName), bounds.centerX(), ppsspp_org_y + 50, textColor, ALIGN_CENTER); #endif From d37893d1aca41560588182c97cbe20c8548c3c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 18 May 2020 23:21:03 +0200 Subject: [PATCH 010/848] Track scissors like we track viewports (bugfix?). --- ext/native/thin3d/VulkanRenderManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 18536e9799..ffbe99cd84 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -463,10 +463,14 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR // Not sure how much this is still happening but probably worth checking for nevertheless. curRenderStep_ = steps_.back(); curStepHasViewport_ = false; + curStepHasScissor_ = false; for (const auto &c : steps_.back()->commands) { if (c.cmd == VKRRenderCommand::VIEWPORT) { curStepHasViewport_ = true; break; + } else if (c.cmd == VKRRenderCommand::SCISSOR) { + curStepHasScissor_ = true; + break; } } return; @@ -507,6 +511,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR curRenderStep_ = step; curStepHasViewport_ = false; + curStepHasScissor_ = false; if (fb) { curWidth_ = fb->width; curHeight_ = fb->height; From 4ffc73bf5bb760b2bc1338ac0f4c44fee140f1e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 19 May 2020 00:10:39 +0200 Subject: [PATCH 011/848] Fix the Windows 32-bit build. (It was complaining about inline assembly in a lambda, I guess at some point we moved a call to Crash into a lambda and it became unhappy). --- Common/CommonFuncs.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Common/CommonFuncs.h b/Common/CommonFuncs.h index cfcbbe0e78..d9b4ea6d74 100644 --- a/Common/CommonFuncs.h +++ b/Common/CommonFuncs.h @@ -77,11 +77,7 @@ inline u64 __rotr64(u64 x, unsigned int shift){ #define ftello _ftelli64 #define atoll _atoi64 #endif - #if _M_IX86 - #define Crash() {__asm int 3} - #else - #define Crash() {__debugbreak();} - #endif // M_IX86 + #define Crash() {__debugbreak();} #endif // WIN32 ndef // Generic function to get last error message. From 29d1f97dd5da4c674e220ae30ae2dc1ec2a43af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 19 May 2020 00:41:41 +0200 Subject: [PATCH 012/848] Experimental commit that effectively reverts the Vulkan part of #12882. For the #12927 investigation. --- ext/native/thin3d/VulkanQueueRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index a74a679e6e..8374342813 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -790,7 +790,7 @@ void VulkanQueueRunner::ApplyRenderPassMerge(std::vector &steps) { case VKRStepType::RENDER: if (steps[j]->render.framebuffer == fb) { // Prevent Unknown's example case from https://github.com/hrydgard/ppsspp/pull/12242 - if (renderHasClear(steps[j]) || steps[j]->dependencies.contains(touchedFramebuffers)) { + if (steps[j]->dependencies.contains(touchedFramebuffers)) { goto done_fb; } else { // Safe to merge, great. From 612fdb957efac8912331db1876aff2e347c05539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 19 May 2020 00:44:42 +0200 Subject: [PATCH 013/848] Revert "Experimental commit that effectively reverts the Vulkan part of #12882." This reverts commit 29d1f97dd5da4c674e220ae30ae2dc1ec2a43af3. --- ext/native/thin3d/VulkanQueueRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 8374342813..a74a679e6e 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -790,7 +790,7 @@ void VulkanQueueRunner::ApplyRenderPassMerge(std::vector &steps) { case VKRStepType::RENDER: if (steps[j]->render.framebuffer == fb) { // Prevent Unknown's example case from https://github.com/hrydgard/ppsspp/pull/12242 - if (steps[j]->dependencies.contains(touchedFramebuffers)) { + if (renderHasClear(steps[j]) || steps[j]->dependencies.contains(touchedFramebuffers)) { goto done_fb; } else { // Safe to merge, great. From 4ef4325fdb339900e93531c01abd417cf9cfb4a8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 18 May 2020 21:30:56 -0700 Subject: [PATCH 014/848] GPU: Avoid unnecessary clear on stencil upload. In this common case, we've typically just bound the buffer to upload a texture to it. No need to start a new render pass. This dodges #12927 but doesn't really fix the underlying issue. --- GPU/Common/FramebufferCommon.cpp | 2 +- GPU/Common/FramebufferCommon.h | 7 ++++++- GPU/D3D11/FramebufferManagerD3D11.h | 2 +- GPU/D3D11/StencilBufferD3D11.cpp | 8 +++++--- GPU/Directx9/FramebufferDX9.h | 2 +- GPU/Directx9/StencilBufferDX9.cpp | 8 +++++--- GPU/GLES/FramebufferManagerGLES.h | 2 +- GPU/GLES/StencilBufferGLES.cpp | 4 ++-- GPU/Vulkan/FramebufferVulkan.h | 2 +- GPU/Vulkan/StencilBufferVulkan.cpp | 6 ++++-- 10 files changed, 27 insertions(+), 16 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 298f54d8ba..850b694701 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -379,7 +379,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame if (useBufferedRendering_ && !g_Config.bDisableSlowFramebufEffects) { gpu->PerformMemoryUpload(params.fb_address, byteSize); - NotifyStencilUpload(params.fb_address, byteSize, true); + NotifyStencilUpload(params.fb_address, byteSize, StencilUpload::STENCIL_IS_ZERO); // TODO: Is it worth trying to upload the depth buffer? } diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index bf92ae189d..93d2418417 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -146,6 +146,11 @@ inline DrawTextureFlags operator | (const DrawTextureFlags &lhs, const DrawTextu return DrawTextureFlags((u32)lhs | (u32)rhs); } +enum class StencilUpload { + NEEDS_CLEAR, + STENCIL_IS_ZERO, +}; + enum class TempFBO { DEPAL, BLIT, @@ -219,7 +224,7 @@ public: void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt); void UpdateFromMemory(u32 addr, int size, bool safe); void ApplyClearToMemory(int x1, int y1, int x2, int y2, u32 clearColor); - virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) = 0; + virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) = 0; // Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it. // In that case we hardly need to actually copy the bytes in VRAM, they will be wrong anyway (unless // read framebuffers is on, in which case this should always return false). diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index 73b917f326..1f91af61ae 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -49,7 +49,7 @@ public: void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); - virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; + virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; // TODO: Remove ID3D11Buffer *GetDynamicQuadBuffer() { diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index ad9faa7f0a..d3b08d69ff 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -70,7 +70,7 @@ VS_OUT main(VS_IN In) { )"; // TODO : If SV_StencilRef is available (D3D11.3) then this can be done in a single pass. -bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, bool skipZero) { +bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, StencilUpload flags) { addr &= 0x3FFFFFFF; if (!MayIntersectFramebuffer(addr)) { return false; @@ -117,7 +117,7 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, bool skipZ } if (usedBits == 0) { - if (skipZero) { + if (flags == StencilUpload::STENCIL_IS_ZERO) { // Common when creating buffers, it's already 0. We're done. return false; } @@ -164,7 +164,9 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, bool skipZ if (!tex) return false; if (dstBuffer->fbo) { - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + // Typically, STENCIL_IS_ZERO means it's already bound. + Draw::RPAction stencilAction = flags == StencilUpload::STENCIL_IS_ZERO ? Draw::RPAction::KEEP : Draw::RPAction::CLEAR; + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }); } else { // something is wrong... } diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index bab50d4dfc..d311c8aa78 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -54,7 +54,7 @@ public: void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); - virtual bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; + virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes); bool GetDepthbuffer(u32 fb_address, int fb_stride, u32 z_address, int z_stride, GPUDebugBuffer &buffer) override; diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 5302c9e4f6..78981a8969 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -66,7 +66,7 @@ VS_OUT main(VS_IN In) { } )"; -bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZero) { +bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUpload flags) { addr &= 0x3FFFFFFF; if (!MayIntersectFramebuffer(addr)) { return false; @@ -113,7 +113,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer } if (usedBits == 0) { - if (skipZero) { + if (flags == StencilUpload::STENCIL_IS_ZERO) { // Common when creating buffers, it's already 0. We're done. return false; } @@ -193,7 +193,9 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer u16 h = dstBuffer->renderHeight; if (dstBuffer->fbo) { - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + // Typically, STENCIL_IS_ZERO means it's already bound. + Draw::RPAction stencilAction = flags == StencilUpload::STENCIL_IS_ZERO ? Draw::RPAction::KEEP : Draw::RPAction::CLEAR; + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }); } D3DVIEWPORT9 vp{ 0, 0, w, h, 0.0f, 1.0f }; device_->SetViewport(&vp); diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 25f541fd81..f86fb1218f 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -54,7 +54,7 @@ public: // For use when texturing from a framebuffer. May create a duplicate if target. void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); - bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; + bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override; diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 387001db26..5f67d145ef 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -68,7 +68,7 @@ void main() { } )"; -bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZero) { +bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUpload flags) { addr &= 0x3FFFFFFF; if (!MayIntersectFramebuffer(addr)) { return false; @@ -114,7 +114,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe } if (usedBits == 0) { - if (skipZero) { + if (flags == StencilUpload::STENCIL_IS_ZERO) { // Common when creating buffers, it's already 0. We're done. return false; } diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index bbd799e1d0..be6c89775c 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -58,7 +58,7 @@ public: void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; + bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; VkImageView BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index a99480d497..3e9cc7e0aa 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -96,7 +96,7 @@ void main() { // In Vulkan we should be able to simply copy the stencil data directly to a stencil buffer without // messing about with bitplane textures and the like. Or actually, maybe not... Let's start with // the traditional approach. -bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skipZero) { +bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUpload flags) { addr &= 0x3FFFFFFF; if (!MayIntersectFramebuffer(addr)) { return false; @@ -168,7 +168,9 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, bool skip return false; if (dstBuffer->fbo) { - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + // Typically, STENCIL_IS_ZERO means it's already bound. + Draw::RPAction stencilAction = flags == StencilUpload::STENCIL_IS_ZERO ? Draw::RPAction::KEEP : Draw::RPAction::CLEAR; + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }); } else { // something is wrong... } From 2a5b465c441d649e29c1d9a9e073426f4cf105d4 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 18 May 2020 21:35:02 -0700 Subject: [PATCH 015/848] D3D9: Avoid clearing color on stencil upload. This makes it match Direct3D 9. We ideally want to clear alpha, but certainly not RGB. --- GPU/Directx9/StencilBufferDX9.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 78981a8969..fab9e99594 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -207,7 +207,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa if (!tex) return false; - device_->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, D3DCOLOR_RGBA(0, 0, 0, 0), 0.0f, 0); + // TODO: Ideally, we should clear alpha to zero here (but not RGB.) dxstate.stencilFunc.set(D3DCMP_ALWAYS, 0xFF, 0xFF); From 396bf1d1c739d3aa60c9ba5c3887d03303018d72 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 18 May 2020 21:33:09 -0700 Subject: [PATCH 016/848] Vulkan: Expand logging of render steps a bit. --- ext/native/thin3d/VulkanQueueRunner.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index a74a679e6e..dd910750fa 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -861,9 +861,22 @@ void VulkanQueueRunner::LogSteps(const std::vector &steps) { } } +const char *RenderPassActionName(VKRRenderPassAction a) { + switch (a) { + case VKRRenderPassAction::CLEAR: + return "CLEAR"; + case VKRRenderPassAction::DONT_CARE: + return "DONT_CARE"; + case VKRRenderPassAction::KEEP: + return "KEEP"; + } + return "?"; +} + void VulkanQueueRunner::LogRenderPass(const VKRStep &pass) { - int fb = (int)(intptr_t)(pass.render.framebuffer ? pass.render.framebuffer->framebuf : 0); - ILOG("RenderPass Begin(%x)", fb); + const auto &r = pass.render; + int fb = (int)(intptr_t)(r.framebuffer ? r.framebuffer->framebuf : 0); + ILOG("RenderPass Begin(%x, %s, %s, %s)", fb, RenderPassActionName(r.color), RenderPassActionName(r.depth), RenderPassActionName(r.stencil)); for (auto &cmd : pass.commands) { switch (cmd.cmd) { case VKRRenderCommand::REMOVED: From cb23c0c01dcb73b724bcba1a3e6794c764e94c4a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 18 May 2020 22:45:20 -0700 Subject: [PATCH 017/848] Vulkan: Create FB compatible pipelines in Draw. The easiest way is just to create both and support both. Perhaps we could optimize out the creation of the framebuffer one. Fixes #12928. --- ext/native/thin3d/thin3d_vulkan.cpp | 68 +++++++++++++++++++---------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index c89b079c68..c452f96a9f 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -251,7 +251,8 @@ public: ubo_ = new uint8_t[uboSize_]; } ~VKPipeline() { - vulkan_->Delete().QueueDeletePipeline(vkpipeline); + vulkan_->Delete().QueueDeletePipeline(backbufferPipeline); + vulkan_->Delete().QueueDeletePipeline(framebufferPipeline); delete[] ubo_; } @@ -272,7 +273,8 @@ public: return false; } - VkPipeline vkpipeline; + VkPipeline backbufferPipeline = VK_NULL_HANDLE; + VkPipeline framebufferPipeline = VK_NULL_HANDLE; int stride[4]{}; int dynamicUniformSize = 0; @@ -420,6 +422,7 @@ public: void DrawIndexed(int vertexCount, int offset) override; void DrawUP(const void *vdata, int vertexCount) override; + void BindCompatiblePipeline(); void ApplyDynamicState(); void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override; @@ -1024,30 +1027,40 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { VkPipelineRasterizationStateCreateInfo rs{ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; raster->ToVulkan(&rs); - VkGraphicsPipelineCreateInfo info{ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; - info.flags = 0; - info.stageCount = (uint32_t)stages.size(); - info.pStages = stages.data(); - info.pColorBlendState = &blend->info; - info.pDepthStencilState = &depth->info; - info.pDynamicState = &dynamicInfo; - info.pInputAssemblyState = &inputAssembly; - info.pTessellationState = nullptr; - info.pMultisampleState = &ms; - info.pVertexInputState = &input->visc; - info.pRasterizationState = &rs; - info.pViewportState = &vs; // Must set viewport and scissor counts even if we set the actual state dynamically. - info.layout = pipelineLayout_; - info.subpass = 0; - info.renderPass = renderManager_.GetBackbufferRenderPass(); + VkGraphicsPipelineCreateInfo createInfo[2]; + for (auto &info : createInfo) { + info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + info.flags = 0; + info.stageCount = (uint32_t)stages.size(); + info.pStages = stages.data(); + info.pColorBlendState = &blend->info; + info.pDepthStencilState = &depth->info; + info.pDynamicState = &dynamicInfo; + info.pInputAssemblyState = &inputAssembly; + info.pTessellationState = nullptr; + info.pMultisampleState = &ms; + info.pVertexInputState = &input->visc; + info.pRasterizationState = &rs; + info.pViewportState = &vs; // Must set viewport and scissor counts even if we set the actual state dynamically. + info.layout = pipelineLayout_; + info.subpass = 0; + } - // OK, need to create a new pipeline. - VkResult result = vkCreateGraphicsPipelines(device_, pipelineCache_, 1, &info, nullptr, &pipeline->vkpipeline); + createInfo[0].renderPass = renderManager_.GetBackbufferRenderPass(); + createInfo[1].renderPass = renderManager_.GetFramebufferRenderPass(); + + // OK, need to create new pipelines. + VkPipeline pipelines[2]{}; + VkResult result = vkCreateGraphicsPipelines(device_, pipelineCache_, 2, createInfo, nullptr, pipelines); if (result != VK_SUCCESS) { ELOG("Failed to create graphics pipeline"); delete pipeline; return nullptr; } + + pipeline->backbufferPipeline = pipelines[0]; + pipeline->framebufferPipeline = pipelines[1]; + if (desc.uniformDesc) { pipeline->dynamicUniformSize = (int)desc.uniformDesc->uniformBufferSize; } @@ -1249,7 +1262,7 @@ void VKContext::Draw(int vertexCount, int offset) { VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf); - renderManager_.BindPipeline(curPipeline_->vkpipeline); + BindCompatiblePipeline(); ApplyDynamicState(); renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount, offset); } @@ -1265,7 +1278,7 @@ void VKContext::DrawIndexed(int vertexCount, int offset) { VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf); - renderManager_.BindPipeline(curPipeline_->vkpipeline); + BindCompatiblePipeline(); ApplyDynamicState(); renderManager_.DrawIndexed(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT16); } @@ -1277,11 +1290,20 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) { VkDescriptorSet descSet = GetOrCreateDescriptorSet(vulkanUBObuf); - renderManager_.BindPipeline(curPipeline_->vkpipeline); + BindCompatiblePipeline(); ApplyDynamicState(); renderManager_.Draw(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vertexCount); } +void VKContext::BindCompatiblePipeline() { + VkRenderPass renderPass = renderManager_.GetCompatibleRenderPass(); + if (renderPass == renderManager_.GetBackbufferRenderPass()) { + renderManager_.BindPipeline(curPipeline_->backbufferPipeline); + } else { + renderManager_.BindPipeline(curPipeline_->framebufferPipeline); + } +} + void VKContext::Clear(int clearMask, uint32_t colorval, float depthVal, int stencilVal) { int mask = 0; if (clearMask & FBChannel::FB_COLOR_BIT) From 966ac4458a2a7beb66cfa2ec7b6fccd1e144809a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 18 May 2020 23:06:14 -0700 Subject: [PATCH 018/848] Vulkan: Fix leak and remove extra allocator. The leak was because we restored immediately after initializing, and therefore leaked several pipelines. This allocator isn't used right now, so just using up memory. --- GPU/Common/PresentationCommon.cpp | 1 + GPU/Vulkan/FramebufferVulkan.cpp | 17 +---------------- GPU/Vulkan/FramebufferVulkan.h | 1 - 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index c8b638f3ce..796e4e694f 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -352,6 +352,7 @@ Draw::Pipeline *PresentationCommon::CreatePipeline(std::vectorCreateBuffer(sizeof(Vertex) * 8, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA); diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index d8829a4ea1..e2bf96a6c3 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -78,7 +78,7 @@ FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw, Vulk vulkan_(vulkan) { presentation_->SetLanguage(GLSL_VULKAN); - DeviceRestore(vulkan, draw); + InitDeviceObjects(); // After a blit we do need to rebind for the VulkanRenderManager to know what to do. needGLESRebinds_ = true; @@ -410,17 +410,6 @@ void FramebufferManagerVulkan::DeviceLost() { DestroyAllFBOs(); DestroyDeviceObjects(); presentation_->DeviceLost(); - - if (allocator_) { - allocator_->Destroy(); - - // We have to delete on queue, so this can free its queued deletions. - vulkan_->Delete().QueueCallback([](void *ptr) { - auto allocator = static_cast(ptr); - delete allocator; - }, allocator_); - allocator_ = nullptr; - } } void FramebufferManagerVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *draw) { @@ -428,9 +417,5 @@ void FramebufferManagerVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawCo draw_ = draw; presentation_->DeviceRestore(draw); - _assert_(!allocator_); - - allocator_ = new VulkanDeviceAllocator(vulkan_, 1 * 1024 * 1024, 8 * 1024 * 1024); - InitDeviceObjects(); } diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index bbd799e1d0..5ceec728eb 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -84,7 +84,6 @@ private: TextureCacheVulkan *textureCacheVulkan_ = nullptr; ShaderManagerVulkan *shaderManagerVulkan_ = nullptr; DrawEngineVulkan *drawEngineVulkan_ = nullptr; - VulkanDeviceAllocator *allocator_ = nullptr; VulkanPushBuffer *push_; enum { From 69c092dce1c4c59d743d4ef6b354200da6291e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 19 May 2020 20:52:47 +0200 Subject: [PATCH 019/848] Vulkan crashfix (pNext was uninitialized) --- ext/native/thin3d/thin3d_vulkan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index c452f96a9f..bbe1e36e24 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1027,7 +1027,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { VkPipelineRasterizationStateCreateInfo rs{ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; raster->ToVulkan(&rs); - VkGraphicsPipelineCreateInfo createInfo[2]; + VkGraphicsPipelineCreateInfo createInfo[2]{}; for (auto &info : createInfo) { info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; info.flags = 0; From e64fdfa0c323eb43354343d6ee99b8669f34dfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 19 May 2020 20:53:51 +0200 Subject: [PATCH 020/848] Fix a case of pointer truncation in Vulkan on 32-bit. Fixes #12932 --- ext/native/thin3d/thin3d.h | 2 +- ext/native/thin3d/thin3d_d3d11.cpp | 20 ++++++++++---------- ext/native/thin3d/thin3d_d3d9.cpp | 8 ++++---- ext/native/thin3d/thin3d_gl.cpp | 4 ++-- ext/native/thin3d/thin3d_vulkan.cpp | 18 +++++++++--------- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index b64b33e886..97320ae52e 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -664,7 +664,7 @@ public: } virtual std::string GetInfoString(InfoField info) const = 0; - virtual uintptr_t GetNativeObject(NativeObject obj) = 0; + virtual uint64_t GetNativeObject(NativeObject obj) = 0; virtual void HandleEvent(Event ev, int width, int height, void *param1 = nullptr, void *param2 = nullptr) = 0; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 31a3ad7b88..7d2c2d538b 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -131,26 +131,26 @@ public: } } - uintptr_t GetNativeObject(NativeObject obj) override { + uint64_t GetNativeObject(NativeObject obj) override { switch (obj) { case NativeObject::DEVICE: - return (uintptr_t)device_; + return (uint64_t)(uintptr_t)device_; case NativeObject::CONTEXT: - return (uintptr_t)context_; + return (uint64_t)(uintptr_t)context_; case NativeObject::DEVICE_EX: - return (uintptr_t)device1_; + return (uint64_t)(uintptr_t)device1_; case NativeObject::CONTEXT_EX: - return (uintptr_t)context1_; + return (uint64_t)(uintptr_t)context1_; case NativeObject::BACKBUFFER_COLOR_TEX: - return (uintptr_t)bbRenderTargetTex_; + return (uint64_t)(uintptr_t)bbRenderTargetTex_; case NativeObject::BACKBUFFER_DEPTH_TEX: - return (uintptr_t)bbDepthStencilTex_; + return (uint64_t)(uintptr_t)bbDepthStencilTex_; case NativeObject::BACKBUFFER_COLOR_VIEW: - return (uintptr_t)bbRenderTargetView_; + return (uint64_t)(uintptr_t)bbRenderTargetView_; case NativeObject::BACKBUFFER_DEPTH_VIEW: - return (uintptr_t)bbDepthStencilView_; + return (uint64_t)(uintptr_t)bbDepthStencilView_; case NativeObject::FEATURE_LEVEL: - return (uintptr_t)featureLevel_; + return (uint64_t)(uintptr_t)featureLevel_; default: return 0; } diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index b4d446ed9d..672ebd36ab 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -572,14 +572,14 @@ public: void DrawUP(const void *vdata, int vertexCount) override; void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal); - uintptr_t GetNativeObject(NativeObject obj) override { + uint64_t GetNativeObject(NativeObject obj) override { switch (obj) { case NativeObject::CONTEXT: - return (uintptr_t)d3d_; + return (uint64_t)(uintptr_t)d3d_; case NativeObject::DEVICE: - return (uintptr_t)device_; + return (uint64_t)(uintptr_t)device_; case NativeObject::DEVICE_EX: - return (uintptr_t)deviceEx_; + return (uint64_t)(uintptr_t)deviceEx_; default: return 0; } diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 8eadd95644..d319c07101 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -467,10 +467,10 @@ public: } } - uintptr_t GetNativeObject(NativeObject obj) override { + uint64_t GetNativeObject(NativeObject obj) override { switch (obj) { case NativeObject::RENDER_MANAGER: - return (uintptr_t)&renderManager_; + return (uint64_t)(uintptr_t)&renderManager_; default: return 0; } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index bbe1e36e24..794fa2c8c2 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -455,25 +455,25 @@ public: std::vector GetFeatureList() const override; std::vector GetExtensionList() const override; - uintptr_t GetNativeObject(NativeObject obj) override { + uint64_t GetNativeObject(NativeObject obj) override { switch (obj) { case NativeObject::FRAMEBUFFER_RENDERPASS: // Return a representative renderpass. - return (uintptr_t)renderManager_.GetFramebufferRenderPass(); + return (uint64_t)renderManager_.GetFramebufferRenderPass(); case NativeObject::BACKBUFFER_RENDERPASS: - return (uintptr_t)renderManager_.GetBackbufferRenderPass(); + return (uint64_t)renderManager_.GetBackbufferRenderPass(); case NativeObject::COMPATIBLE_RENDERPASS: - return (uintptr_t)renderManager_.GetCompatibleRenderPass(); + return (uint64_t)renderManager_.GetCompatibleRenderPass(); case NativeObject::INIT_COMMANDBUFFER: - return (uintptr_t)renderManager_.GetInitCmd(); + return (uint64_t)renderManager_.GetInitCmd(); case NativeObject::BOUND_TEXTURE0_IMAGEVIEW: - return (uintptr_t)boundImageView_[0]; + return (uint64_t)boundImageView_[0]; case NativeObject::BOUND_TEXTURE1_IMAGEVIEW: - return (uintptr_t)boundImageView_[1]; + return (uint64_t)boundImageView_[1]; case NativeObject::RENDER_MANAGER: - return (uintptr_t)&renderManager_; + return (uint64_t)(uintptr_t)&renderManager_; case NativeObject::NULL_IMAGEVIEW: - return (uintptr_t)GetNullTexture()->GetImageView(); + return (uint64_t)GetNullTexture()->GetImageView(); default: Crash(); return 0; From 3a5e07ad4fa12a89583d41b49dbb5f9b175b561b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 19 May 2020 23:26:22 +0200 Subject: [PATCH 021/848] Vulkan: Stencil initialization: Use the adreno path for Mali as well. Appears to fix the Star Ocean issue and maybe more reported in #12890. Strange though... --- GPU/Vulkan/StencilBufferVulkan.cpp | 7 +++++-- UI/GPUDriverTestScreen.cpp | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 3e9cc7e0aa..a025763d54 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -29,6 +29,8 @@ // This shader references gl_FragDepth to prevent early fragment tests. // They shouldn't happen since it uses discard, but Adreno detects that incorrectly - see #10634. +// This only affected the 5xx generation and was fixed sometime before driver version 512.384.0.0 (whatever that means). +// Strangely, this same code appears to fix a different issue on Exynos instead so now it's enabled on Mali as well. static const char *stencil_fs_adreno = R"(#version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable @@ -146,7 +148,8 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp if (!stencilVs_) { const char *stencil_fs_source = stencil_fs; // See comment above the stencil_fs_adreno definition. - if (vulkan_->GetPhysicalDeviceProperties().properties.vendorID == VULKAN_VENDOR_QUALCOMM) + u32 vendorID = vulkan_->GetPhysicalDeviceProperties().properties.vendorID; + if (vendorID == VULKAN_VENDOR_QUALCOMM || vendorID == VULKAN_VENDOR_ARM) stencil_fs_source = stencil_fs_adreno; stencilVs_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, stencil_vs, &error); @@ -168,7 +171,7 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp return false; if (dstBuffer->fbo) { - // Typically, STENCIL_IS_ZERO means it's already bound. + // Typically, STENCIL_IS_ZERO means it's already bound, so this bind will be optimized away. Draw::RPAction stencilAction = flags == StencilUpload::STENCIL_IS_ZERO ? Draw::RPAction::KEEP : Draw::RPAction::CLEAR; draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }); } else { diff --git a/UI/GPUDriverTestScreen.cpp b/UI/GPUDriverTestScreen.cpp index dfad8aecb4..87018d8399 100644 --- a/UI/GPUDriverTestScreen.cpp +++ b/UI/GPUDriverTestScreen.cpp @@ -24,7 +24,7 @@ static const std::vector fsDiscard = { })" }, {Draw::ShaderLanguage::GLSL_VULKAN, - R"(#version 140 + R"(#version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable layout(location = 0) in vec4 oColor0; From 2e05d22eb7a0faaea03d72018726b11b6a4fbedb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 19 May 2020 22:12:30 -0700 Subject: [PATCH 022/848] Vulkan: Move Harvest Moon fix to Draw::Bugs. Also, make it so you can skip using ini settings. --- GPU/Vulkan/StateMappingVulkan.cpp | 2 +- ext/native/thin3d/thin3d.h | 1 + ext/native/thin3d/thin3d_vulkan.cpp | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index dde593bdd3..d2a3e8591c 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -239,7 +239,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag key.colorWriteMask = (rmask ? VK_COLOR_COMPONENT_R_BIT : 0) | (gmask ? VK_COLOR_COMPONENT_G_BIT : 0) | (bmask ? VK_COLOR_COMPONENT_B_BIT : 0) | (amask ? VK_COLOR_COMPONENT_A_BIT : 0); // Workaround proposed in #10421, for bug where the color write mask is not applied correctly on Adreno. - if ((gstate.pmskc & 0x00FFFFFF) == 0x00FFFFFF && vulkan_->GetPhysicalDeviceProperties().properties.vendorID == VULKAN_VENDOR_QUALCOMM) { + if ((gstate.pmskc & 0x00FFFFFF) == 0x00FFFFFF && g_Config.bVendorBugChecksEnabled && draw_->GetBugs().Has(Draw::Bugs::COLORWRITEMASK_BROKEN_WITH_DEPTHTEST)) { key.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; if (!key.blendEnable) { key.blendEnable = true; diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 97320ae52e..bf5f9bb87e 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -335,6 +335,7 @@ public: ANY_MAP_BUFFER_RANGE_SLOW = 2, PVR_GENMIPMAP_HEIGHT_GREATER = 3, BROKEN_NAN_IN_CONDITIONAL = 4, + COLORWRITEMASK_BROKEN_WITH_DEPTHTEST = 5, }; protected: diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 794fa2c8c2..78703fdd9b 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -774,6 +774,9 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) if (deviceProps.deviceID >= 0x05000000 && deviceProps.deviceID < 0x06000000) { bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL); } + // Color write mask not masking write in certain scenarios with a depth test, see #10421. + // Known still present on driver 0x80180000 and Adreno 5xx (possibly more.) + bugs_.Infest(Bugs::COLORWRITEMASK_BROKEN_WITH_DEPTHTEST); } else if (caps_.vendor == GPUVendor::VENDOR_AMD) { // See issue #10074, and also #10065 (AMD) and #10109 for the choice of the driver version to check for. if (deviceProps.driverVersion < 0x00407000) { From 8d900bb432db648d1378a37b2d340139536fd2e3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 19 May 2020 22:13:15 -0700 Subject: [PATCH 023/848] Vulkan: Check driver version for Adreno 5xx bug. It's now fixed at least as of this version (possibly earlier.) --- GPU/Vulkan/StencilBufferVulkan.cpp | 2 +- ext/native/thin3d/thin3d_vulkan.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index a025763d54..8b8b21090f 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -149,7 +149,7 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp const char *stencil_fs_source = stencil_fs; // See comment above the stencil_fs_adreno definition. u32 vendorID = vulkan_->GetPhysicalDeviceProperties().properties.vendorID; - if (vendorID == VULKAN_VENDOR_QUALCOMM || vendorID == VULKAN_VENDOR_ARM) + if (g_Config.bVendorBugChecksEnabled && (draw_->GetBugs().Has(Draw::Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL) || vendorID == VULKAN_VENDOR_ARM)) stencil_fs_source = stencil_fs_adreno; stencilVs_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, stencil_vs, &error); diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 78703fdd9b..919f3f59ac 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -772,7 +772,9 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) // Adreno 5xx devices, all known driver versions, fail to discard stencil when depth write is off. // See: https://github.com/hrydgard/ppsspp/pull/11684 if (deviceProps.deviceID >= 0x05000000 && deviceProps.deviceID < 0x06000000) { - bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL); + if (deviceProps.driverVersion < 0x80180000) { + bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL); + } } // Color write mask not masking write in certain scenarios with a depth test, see #10421. // Known still present on driver 0x80180000 and Adreno 5xx (possibly more.) From 86bbb447d3d9b41b26e9a7caf9fe2d75f92ea940 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 19 May 2020 22:14:47 -0700 Subject: [PATCH 024/848] Vulkan: Avoid stencilAction != depthAction. This is the only place we do it, and apparently there can be bugs on some drivers when you do that. Let's not. --- GPU/Vulkan/StencilBufferVulkan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 8b8b21090f..ec39e42c5b 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -171,9 +171,9 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp return false; if (dstBuffer->fbo) { + // Use keep because some drivers have trouble when stencilAction != depthAction. // Typically, STENCIL_IS_ZERO means it's already bound, so this bind will be optimized away. - Draw::RPAction stencilAction = flags == StencilUpload::STENCIL_IS_ZERO ? Draw::RPAction::KEEP : Draw::RPAction::CLEAR; - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }); + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); } else { // something is wrong... } From 52a3c2248d2d263df5e000467f1dbff2c45a6ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 20 May 2020 10:25:54 +0200 Subject: [PATCH 025/848] Move the check from #12908 into the firmware version check. The original change took care of #11660, let's hope it stay fixed. This fixes Toca (#12936). --- GPU/GPUCommon.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 3b5d220724..e1f64afb81 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -678,17 +678,18 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointernumStacks >= 256) { - ERROR_LOG_REPORT(G3D, "sceGeListEnqueue: invalid size %d", args->numStacks); - return SCE_KERNEL_ERROR_INVALID_SIZE; - } - + int id = -1; u64 currentTicks = CoreTiming::GetTicks(); u32_le stackAddr = args.IsValid() ? args->stackAddr : 0; // Check compatibility if (sceKernelGetCompiledSdkVersion() > 0x01FFFFFF) { + // See #12908. + if (args.IsValid() && args->numStacks >= 256) { + ERROR_LOG(G3D, "sceGeListEnqueue: invalid size %08x", args->numStacks); + return SCE_KERNEL_ERROR_INVALID_SIZE; + } + //numStacks = 0; //stack = NULL; for (int i = 0; i < DisplayListMaxCount; ++i) { From fabe987c8f312df67f0805dd3cf27757663e251d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 21 May 2020 11:24:05 +0200 Subject: [PATCH 026/848] Add a name tag for all render steps (GL/Vulkan). Helps with debugging and should be cheap enough (a single pointer per "step"). --- GPU/Common/FramebufferCommon.cpp | 36 ++++++++++++----------- GPU/Common/PresentationCommon.cpp | 4 +-- GPU/D3D11/FramebufferManagerD3D11.cpp | 10 +++---- GPU/D3D11/StencilBufferD3D11.cpp | 2 +- GPU/D3D11/TextureCacheD3D11.cpp | 4 +-- GPU/Directx9/FramebufferDX9.cpp | 10 +++---- GPU/Directx9/StencilBufferDX9.cpp | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GLES/DepthBufferGLES.cpp | 6 ++-- GPU/GLES/FramebufferManagerGLES.cpp | 18 ++++++------ GPU/GLES/StencilBufferGLES.cpp | 8 ++--- GPU/GLES/TextureCacheGLES.cpp | 6 ++-- GPU/Software/SoftGpu.cpp | 2 +- GPU/Vulkan/FramebufferVulkan.cpp | 8 ++--- GPU/Vulkan/StencilBufferVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 6 ++-- UI/EmuScreen.cpp | 12 ++++---- ext/native/thin3d/GLQueueRunner.h | 1 + ext/native/thin3d/GLRenderManager.cpp | 15 ++++++---- ext/native/thin3d/GLRenderManager.h | 10 +++---- ext/native/thin3d/VulkanQueueRunner.cpp | 12 ++++---- ext/native/thin3d/VulkanQueueRunner.h | 1 + ext/native/thin3d/VulkanRenderManager.cpp | 17 +++++++---- ext/native/thin3d/VulkanRenderManager.h | 10 +++---- ext/native/thin3d/thin3d.h | 9 +++--- ext/native/thin3d/thin3d_d3d11.cpp | 16 +++++----- ext/native/thin3d/thin3d_d3d9.cpp | 10 +++---- ext/native/thin3d/thin3d_gl.cpp | 24 +++++++-------- ext/native/thin3d/thin3d_vulkan.cpp | 24 +++++++-------- ext/native/ui/ui_screen.cpp | 2 +- 30 files changed, 152 insertions(+), 137 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 850b694701..01fb23796e 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -532,15 +532,17 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe // to it. This broke stuff before, so now it only clears on the first use of an // FBO in a frame. This means that some games won't be able to avoid the on-some-GPUs // performance-crushing framebuffer reloads from RAM, but we'll have to live with that. + + // Wait, can we even do this? Seems highly unsafe.. TODO: Remove if (vfb->last_frame_render != gpuStats.numFlips) { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "FramebufferSwitch"); // GLES resets the blend state on clears. gstate_c.Dirty(DIRTY_BLEND_STATE); } else { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "FramebufferSwitch"); } } else { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "FramebufferSwitch"); } } else { // This should only happen very briefly when toggling useBufferedRendering_. @@ -649,7 +651,7 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int DrawTextureFlags flags; if (useBufferedRendering_ && vfb && vfb->fbo) { flags = DRAWTEX_LINEAR; - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "DrawPixels"); SetViewport2D(0, 0, vfb->renderWidth, vfb->renderHeight); draw_->SetScissorRect(0, 0, vfb->renderWidth, vfb->renderHeight); } else { @@ -833,7 +835,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { DEBUG_LOG(FRAMEBUF, "Display disabled, displaying only black"); // No framebuffer to display! Clear to black. if (useBufferedRendering_) { - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput"); } gstate_c.Dirty(DIRTY_BLEND_STATE); return; @@ -894,7 +896,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { if (!vfb) { if (useBufferedRendering_) { // Bind and clear the backbuffer. This should be the first time during the frame that it's bound. - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput_Backbuffer"); } // Just a pointer to plain memory to draw. We should create a framebuffer, then draw to it. SetViewport2D(0, 0, pixelWidth_, pixelHeight_); @@ -908,7 +910,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { // No framebuffer to display! Clear to black. if (useBufferedRendering_) { // Bind and clear the backbuffer. This should be the first time during the frame that it's bound. - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput_NoFBO"); } gstate_c.Dirty(DIRTY_BLEND_STATE); return; @@ -1067,7 +1069,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, if (old.fbo) { INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %d x %d x %d", vfb->fb_address, w, h, vfb->format); if (vfb->fbo) { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); // GLES resets the blend state on clears. gstate_c.Dirty(DIRTY_BLEND_STATE); if (!skipCopy) { @@ -1076,10 +1078,10 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } fbosToDelete_.push_back(old.fbo); if (needGLESRebinds_) { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "ResizeFramebufFBO"); } } else { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); // GLES resets the blend state on clears. gstate_c.Dirty(DIRTY_BLEND_STATE); } @@ -1848,7 +1850,7 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB // TODO: Maybe should handle flipY inside CopyFramebufferToMemorySync somehow? bool flipY = (GetGPUBackend() == GPUBackend::OPENGL && !useBufferedRendering_) ? true : false; buffer.Allocate(w, h, GE_FORMAT_8888, flipY); - bool retval = draw_->CopyFramebufferToMemorySync(bound, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), w); + bool retval = draw_->CopyFramebufferToMemorySync(bound, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), w, "GetFramebuffer"); gpuStats.numReadbacks++; // After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); @@ -1884,7 +1886,7 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32 buffer.Allocate(w, h, GPU_DBG_FORMAT_FLOAT, flipY); } // No need to free on failure, that's the caller's job (it likely will reuse a buffer.) - bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, 0, w, h, Draw::DataFormat::D32F, buffer.GetData(), w); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, 0, w, h, Draw::DataFormat::D32F, buffer.GetData(), w, "GetDepthBuffer"); // After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); // That may have unbound the framebuffer, rebind to avoid crashes when debugging. @@ -1916,7 +1918,7 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G bool flipY = (GetGPUBackend() == GPUBackend::OPENGL && !useBufferedRendering_) ? true : false; // No need to free on failure, the caller/destructor will do that. Usually this is a reused buffer, anyway. buffer.Allocate(w, h, GPU_DBG_FORMAT_8BIT, flipY); - bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_STENCIL_BIT, 0, 0, w,h, Draw::DataFormat::S8, buffer.GetData(), w); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_STENCIL_BIT, 0, 0, w,h, Draw::DataFormat::S8, buffer.GetData(), w, "GetStencilbuffer"); // That may have unbound the framebuffer, rebind to avoid crashes when debugging. RebindFramebuffer(); return retval; @@ -1930,7 +1932,7 @@ bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) { if (fmt != Draw::DataFormat::B8G8R8A8_UNORM) fmt = Draw::DataFormat::R8G8B8A8_UNORM; buffer.Allocate(w, h, fmt == Draw::DataFormat::R8G8B8A8_UNORM ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_8888_BGRA, false); - bool retval = draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, fmt, buffer.GetData(), w); + bool retval = draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, fmt, buffer.GetData(), w, "GetOutputFramebuffer"); // That may have unbound the framebuffer, rebind to avoid crashes when debugging. RebindFramebuffer(); return retval; @@ -1972,7 +1974,7 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int DEBUG_LOG(G3D, "Reading framebuffer to mem, fb_address = %08x, ptr=%p", fb_address, destPtr); if (destPtr) { - draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, x, y, w, h, destFormat, destPtr, vfb->fb_stride); + draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, x, y, w, h, destFormat, destPtr, vfb->fb_stride, "PackFramebufferSync_"); } else { ERROR_LOG(G3D, "PackFramebufferSync_: Tried to readback to bad address %08x (stride = %d)", fb_address + dstByteOffset, vfb->fb_stride); } @@ -2057,10 +2059,10 @@ void FramebufferManagerCommon::DownloadFramebufferForClut(u32 fb_address, u32 lo void FramebufferManagerCommon::RebindFramebuffer() { shaderManager_->DirtyLastShader(); if (currentRenderVfb_ && currentRenderVfb_->fbo) { - draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "RebindFramebuffer"); } else { // Should this even happen? It could while debugging, but maybe we can just skip binding at all. - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "RebindFramebuffer_Bad"); } gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); } diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 796e4e694f..6f8459b588 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -585,7 +585,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u const ShaderInfo *shaderInfo = &postShaderInfo_[i]; Draw::Framebuffer *postShaderFramebuffer = postShaderFramebuffers_[i]; - draw_->BindFramebufferAsRenderTarget(postShaderFramebuffer, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(postShaderFramebuffer, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "PostShader"); if (usePostShaderOutput) { draw_->BindFramebufferAsTexture(postShaderFramebuffers_[i - 1], 0, Draw::FB_COLOR_BIT, 0); } else { @@ -628,7 +628,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u pipeline = postShaderPipelines_.back(); } - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "FinalBlit"); draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); draw_->BindPipeline(pipeline); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 70e2b19bfc..3ea5b73e55 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -267,7 +267,7 @@ void FramebufferManagerD3D11::ReformatFramebufferFrom(VirtualFramebuffer *vfb, G // and blit with a shader to that, then replace the FBO on vfb. Stencil would still be complex // to exactly reproduce in 4444 and 8888 formats. if (old == GE_FORMAT_565) { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "ReformatFramebuffer"); context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0xFF); context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[D3D11_COLOR_WRITE_ENABLE_ALPHA], nullptr, 0xFFFFFFFF); @@ -321,7 +321,7 @@ void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, Virt bool matchingRenderSize = src->renderWidth == dst->renderWidth && src->renderHeight == dst->renderHeight; if (matchingDepthBuffer && matchingSize && matchingRenderSize) { // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT); + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); RebindFramebuffer(); dst->last_frame_depth_updated = gpuStats.numFlips; } @@ -380,7 +380,7 @@ void FramebufferManagerD3D11::SimpleBlit( if (srcW == destW && srcH == destH && destX2 - destX1 == srcX2 - srcX1 && destY2 - destY1 == srcY2 - srcY1) { // Optimize to a copy - draw_->CopyFramebufferImage(src, 0, (int)srcX1, (int)srcY1, 0, dest, 0, (int)destX1, (int)destY1, 0, (int)(srcX2 - srcX1), (int)(srcY2 - srcY1), 1, Draw::FB_COLOR_BIT); + draw_->CopyFramebufferImage(src, 0, (int)srcX1, (int)srcY1, 0, dest, 0, (int)destX1, (int)destY1, 0, (int)(srcX2 - srcX1), (int)(srcY2 - srcY1), 1, Draw::FB_COLOR_BIT, "SimpleBlit"); return; } @@ -405,7 +405,7 @@ void FramebufferManagerD3D11::SimpleBlit( // Unbind the texture first to avoid the D3D11 hazard check (can't set render target to things bound as textures and vice versa, not even temporarily). draw_->BindTexture(0, nullptr); - draw_->BindFramebufferAsRenderTarget(dest, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(dest, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "SimpleBlit"); draw_->BindFramebufferAsTexture(src, 0, Draw::FB_COLOR_BIT, 0); Bind2DShader(); @@ -428,7 +428,7 @@ void FramebufferManagerD3D11::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if they recently switched from non-buffered. if (useBufferedRendering_) { - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitFramebuffer_Fail"); } return; } diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index d3b08d69ff..28b2a52fd6 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -166,7 +166,7 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, StencilUpl if (dstBuffer->fbo) { // Typically, STENCIL_IS_ZERO means it's already bound. Draw::RPAction stencilAction = flags == StencilUpload::STENCIL_IS_ZERO ? Draw::RPAction::KEEP : Draw::RPAction::CLEAR; - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }); + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }, "Stencil"); } else { // something is wrong... } diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 568343bdd8..a938376352 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -401,7 +401,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra ID3D11ShaderResourceView *nullTexture = nullptr; context_->PSSetShaderResources(0, 1, &nullTexture); // In case the target was used in the last draw call. Happens in Sega Rally. - draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "ApplyTextureFramebuffer_DepalShader"); context_->PSSetShaderResources(3, 1, &clutTexture); context_->PSSetSamplers(3, 1, &stockD3D11.samplerPoint2DWrap); framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY | BINDFBCOLOR_FORCE_SELF); @@ -779,7 +779,7 @@ bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level if (entry->framebuffer) { VirtualFramebuffer *vfb = entry->framebuffer; buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); - bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 0300bbf45a..0d90960ebd 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -243,7 +243,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { // to exactly reproduce in 4444 and 8888 formats. if (old == GE_FORMAT_565) { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "ReformatFramebuffer"); dxstate.scissorTest.disable(); dxstate.depthWrite.set(FALSE); @@ -387,7 +387,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if we recently switched from non-buffered. if (useBufferedRendering_) - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitFramebuffer_Fail"); return; } @@ -420,7 +420,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { bool result = draw_->BlitFramebuffer( src->fbo, srcX1, srcY1, srcX2, srcY2, tempFBO, dstX1, dstY1, dstX2, dstY2, - Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST); + Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebuffer"); if (result) { srcFBO = tempFBO; } @@ -428,7 +428,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { bool result = draw_->BlitFramebuffer( srcFBO, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, - Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST); + Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebuffer"); if (!result) { ERROR_LOG_REPORT(G3D, "fbo_blit_color failed in blit (%08x -> %08x)", src->fb_address, dst->fb_address); } @@ -614,7 +614,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { w = vfb->width * maxRes; h = vfb->height * maxRes; tempFBO = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888 }); - if (draw_->BlitFramebuffer(vfb->fbo, 0, 0, vfb->renderWidth, vfb->renderHeight, tempFBO, 0, 0, w, h, Draw::FB_COLOR_BIT, g_Config.iBufFilter == SCALE_LINEAR ? Draw::FB_BLIT_LINEAR : Draw::FB_BLIT_NEAREST)) { + if (draw_->BlitFramebuffer(vfb->fbo, 0, 0, vfb->renderWidth, vfb->renderHeight, tempFBO, 0, 0, w, h, Draw::FB_COLOR_BIT, g_Config.iBufFilter == SCALE_LINEAR ? Draw::FB_BLIT_LINEAR : Draw::FB_BLIT_NEAREST, "GetFramebuffer")) { renderTarget = (LPDIRECT3DSURFACE9)draw_->GetFramebufferAPITexture(tempFBO, Draw::FB_COLOR_BIT | Draw::FB_SURFACE_BIT, 0); } } diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index fab9e99594..972bcfd88f 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -195,7 +195,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa if (dstBuffer->fbo) { // Typically, STENCIL_IS_ZERO means it's already bound. Draw::RPAction stencilAction = flags == StencilUpload::STENCIL_IS_ZERO ? Draw::RPAction::KEEP : Draw::RPAction::CLEAR; - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }); + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, stencilAction }, "StencilUpload"); } D3DVIEWPORT9 vp{ 0, 0, w, h, 0.0f, 1.0f }; device_->SetViewport(&vp); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 321b980f44..4afe6baa26 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -427,7 +427,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame LPDIRECT3DTEXTURE9 clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_); Draw::Framebuffer *depalFBO = framebufferManagerDX9_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888); - draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "Depal"); shaderManager_->DirtyLastShader(); float xoff = -0.5f / framebuffer->renderWidth; diff --git a/GPU/GLES/DepthBufferGLES.cpp b/GPU/GLES/DepthBufferGLES.cpp index 534ee73d14..2a7238e8ea 100644 --- a/GPU/GLES/DepthBufferGLES.cpp +++ b/GPU/GLES/DepthBufferGLES.cpp @@ -126,7 +126,7 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int shaderManagerGL_->DirtyLastShader(); auto *blitFBO = GetTempFBO(TempFBO::COPY, vfb->renderWidth, vfb->renderHeight, Draw::FBO_8888); - draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "PackDepthbuffer"); render_->SetViewport({ 0, 0, (float)vfb->renderWidth, (float)vfb->renderHeight, 0.0f, 1.0f }); textureCacheGL_->ForgetLastTexture(); @@ -154,11 +154,11 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int float v1 = 1.0f; DrawActiveTexture(x, y, w, h, vfb->renderWidth, vfb->renderHeight, 0.0f, 0.0f, u1, v1, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST); - draw_->CopyFramebufferToMemorySync(blitFBO, Draw::FB_COLOR_BIT, 0, y, packWidth, h, Draw::DataFormat::R8G8B8A8_UNORM, convBuf_, vfb->z_stride); + draw_->CopyFramebufferToMemorySync(blitFBO, Draw::FB_COLOR_BIT, 0, y, packWidth, h, Draw::DataFormat::R8G8B8A8_UNORM, convBuf_, vfb->z_stride, "PackDepthbuffer"); // TODO: Use 4444 so we can copy lines directly? format16Bit = true; } else { - draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, y, packWidth, h, Draw::DataFormat::D32F, convBuf_, vfb->z_stride); + draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, y, packWidth, h, Draw::DataFormat::D32F, convBuf_, vfb->z_stride, "PackDepthbuffer"); format16Bit = false; } diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 266b4fde93..3314068d24 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -261,7 +261,7 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE if (old == GE_FORMAT_565) { // Clear alpha and stencil. - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "ReformatFramebuffer"); render_->Clear(0, 0.0f, 0, GL_COLOR_BUFFER_BIT, 0x8, 0, 0, 0, 0); } } @@ -277,7 +277,7 @@ void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, Virtu if (gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT)) { // Let's only do this if not clearing depth. - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST); + draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); dst->last_frame_depth_updated = gpuStats.numFlips; } } @@ -318,9 +318,9 @@ void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) // Discard the previous contents of this buffer where possible. if (gl_extensions.GLES3) { - draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "UpdateDownloadTempBuffer"); } else if (gl_extensions.IsGLES) { - draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(nvfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "UpdateDownloadTempBuffer"); gstate_c.Dirty(DIRTY_BLEND_STATE); } } @@ -329,7 +329,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if they recently switched from non-buffered. if (useBufferedRendering_) - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitFramebuffer"); return; } @@ -374,15 +374,15 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, const bool xOverlap = src == dst && srcX2 > dstX1 && srcX1 < dstX2; const bool yOverlap = src == dst && srcY2 > dstY1 && srcY1 < dstY2; if (sameSize && sameDepth && srcInsideBounds && dstInsideBounds && !(xOverlap && yOverlap)) { - draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, Draw::FB_COLOR_BIT); + draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, Draw::FB_COLOR_BIT, "BlitFramebuffer"); return; } } if (useBlit) { - draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST); + draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebuffer"); } else { - draw_->BindFramebufferAsRenderTarget(dst->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(dst->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitFramebuffer"); draw_->BindFramebufferAsTexture(src->fbo, 0, Draw::FB_COLOR_BIT, 0); // Make sure our 2D drawing program is ready. Compiles only if not already compiled. @@ -433,6 +433,6 @@ bool FramebufferManagerGLES::GetOutputFramebuffer(GPUDebugBuffer &buffer) { int w, h; draw_->GetFramebufferDimensions(nullptr, &w, &h); buffer.Allocate(w, h, GPU_DBG_FORMAT_888_RGB, true); - draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8_UNORM, buffer.GetData(), w); + draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8_UNORM, buffer.GetData(), w, "GetOutputFramebuffer"); return true; } diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 5f67d145ef..f18b2f90d6 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -122,7 +122,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo // Let's not bother with the shader if it's just zero. if (dstBuffer->fbo) { - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "NotifyStencilUpload_Clear"); } render_->Clear(0, 0, 0, GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT, 0x8, 0, 0, 0, 0); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); @@ -169,9 +169,9 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo Draw::Framebuffer *blitFBO = nullptr; if (useBlit) { blitFBO = GetTempFBO(TempFBO::STENCIL, w, h, Draw::FBO_8888); - draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "NotifyStencilUpload_Blit"); } else if (dstBuffer->fbo) { - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::DONT_CARE }, "NotifyStencilUpload_NoBlit"); } render_->SetViewport({ 0, 0, (float)w, (float)h, 0.0f, 1.0f }); @@ -212,7 +212,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo } if (useBlit) { - draw_->BlitFramebuffer(blitFBO, 0, 0, w, h, dstBuffer->fbo, 0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight, Draw::FB_STENCIL_BIT, Draw::FB_BLIT_NEAREST); + draw_->BlitFramebuffer(blitFBO, 0, 0, w, h, dstBuffer->fbo, 0, 0, dstBuffer->renderWidth, dstBuffer->renderHeight, Draw::FB_STENCIL_BIT, Draw::FB_BLIT_NEAREST, "NotifyStencilUpload_Blit"); } tex->Release(); diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 50e8ea9b6c..781aee4f56 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -476,7 +476,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); GLRTexture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_); Draw::Framebuffer *depalFBO = framebufferManagerGL_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888); - draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "Depal"); render_->SetScissor(GLRect2D{ 0, 0, (int)framebuffer->renderWidth, (int)framebuffer->renderHeight }); render_->SetViewport(GLRViewport{ 0.0f, 0.0f, (float)framebuffer->renderWidth, (float)framebuffer->renderHeight, 0.0f, 1.0f }); @@ -840,7 +840,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) if (entry->framebuffer) { VirtualFramebuffer *vfb = entry->framebuffer; buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); - bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); @@ -861,7 +861,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) } buffer.Allocate(w, h, GE_FORMAT_8888, false); - renderManager->CopyImageToMemorySync(entry->textureName, level, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, (uint8_t *)buffer.GetData(), w); + renderManager->CopyImageToMemorySync(entry->textureName, level, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, (uint8_t *)buffer.GetData(), w, "GetCurrentTextureDebug"); gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); framebufferManager_->RebindFramebuffer(); diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index a45b4791dc..7e17d54f89 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -257,7 +257,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { u1 = 1.0f; } if (!hasImage) { - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "CopyToCurrentFboFromDisplayRam"); return; } diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index e2bf96a6c3..6eadd4e86a 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -277,7 +277,7 @@ void FramebufferManagerVulkan::BlitFramebufferDepth(VirtualFramebuffer *src, Vir bool matchingRenderSize = src->renderWidth == dst->renderWidth && src->renderHeight == dst->renderHeight; if (matchingDepthBuffer && matchingRenderSize && matchingSize) { // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT); + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); dst->last_frame_depth_updated = gpuStats.numFlips; } else if (matchingDepthBuffer && matchingSize) { /* @@ -332,7 +332,7 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if they recently switched from non-buffered. if (useBufferedRendering_) - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitFramebuffer_Fail"); return; } @@ -393,9 +393,9 @@ void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX const bool xOverlap = src == dst && srcX2 > dstX1 && srcX1 < dstX2; const bool yOverlap = src == dst && srcY2 > dstY1 && srcY1 < dstY2; if (sameSize && sameDepth && srcInsideBounds && dstInsideBounds && !(xOverlap && yOverlap)) { - draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, Draw::FB_COLOR_BIT); + draw_->CopyFramebufferImage(src->fbo, 0, srcX1, srcY1, 0, dst->fbo, 0, dstX1, dstY1, 0, dstX2 - dstX1, dstY2 - dstY1, 1, Draw::FB_COLOR_BIT, "BlitFramebuffer_Copy"); } else { - draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST); + draw_->BlitFramebuffer(src->fbo, srcX1, srcY1, srcX2, srcY2, dst->fbo, dstX1, dstY1, dstX2, dstY2, Draw::FB_COLOR_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebuffer_Blit"); } } diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index ec39e42c5b..ebcec6c41e 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -173,7 +173,7 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp if (dstBuffer->fbo) { // Use keep because some drivers have trouble when stencilAction != depthAction. // Typically, STENCIL_IS_ZERO means it's already bound, so this bind will be optimized away. - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "Stencil"); } else { // something is wrong... } diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 7289e6222a..427672234c 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -843,7 +843,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr VulkanTexture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_, expand32); Draw::Framebuffer *depalFBO = framebufferManager_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888); - draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "Depal"); Vulkan2D::Vertex verts[4] = { { -1, -1, 0.0f, 0, 0 }, @@ -1388,7 +1388,7 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve if (entry->framebuffer) { VirtualFramebuffer *vfb = entry->framebuffer; buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); - bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); @@ -1428,7 +1428,7 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve int h = texture->GetHeight(); buffer.Allocate(w, h, bufferFormat); - renderManager->CopyImageToMemorySync(texture->GetImage(), level, 0, 0, w, h, drawFormat, (uint8_t *)buffer.GetData(), w); + renderManager->CopyImageToMemorySync(texture->GetImage(), level, 0, 0, w, h, drawFormat, (uint8_t *)buffer.GetData(), w, "GetCurrentTextureDebug"); // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 860bb354d1..7cd3a81099 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1339,9 +1339,9 @@ void EmuScreen::preRender() { if ((!useBufferedRendering && !g_Config.bSoftwareRendering) || Core_IsStepping()) { // We need to clear here already so that drawing during the frame is done on a clean slate. if (Core_IsStepping() && gpuStats.numFlips != 0) { - draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE, RPAction::DONT_CARE }); + draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE, RPAction::DONT_CARE }, "EmuScreen_BackBuffer"); } else { - draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 }); + draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 }, "EmuScreen_BackBuffer"); } Viewport viewport; @@ -1380,7 +1380,7 @@ void EmuScreen::render() { // It's possible this might be set outside PSP_RunLoopFor(). // In this case, we need to double check it here. checkPowerDown(); - thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR }); + thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR }, "EmuScreen_Invalid"); renderUI(); return; } @@ -1409,7 +1409,7 @@ void EmuScreen::render() { } else if (coreState == CORE_STEPPING) { // If we're stepping, it's convenient not to clear the screen entirely, so we copy display to output. // This won't work in non-buffered, but that's fine. - thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE }); + thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE }, "EmuScreen_Stepping"); // Just to make sure. if (PSP_IsInited()) { gpu->CopyDisplayToOutput(true); @@ -1418,7 +1418,7 @@ void EmuScreen::render() { // Didn't actually reach the end of the frame, ran out of the blockTicks cycles. // In this case we need to bind and wipe the backbuffer, at least. // It's possible we never ended up outputted anything - make sure we have the backbuffer cleared - thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR }); + thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR }, "EmuScreen_NoFrame"); } checkPowerDown(); @@ -1428,7 +1428,7 @@ void EmuScreen::render() { if (hasVisibleUI()) { // In most cases, this should already be bound and a no-op. - thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE, RPAction::DONT_CARE }); + thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::KEEP, RPAction::DONT_CARE, RPAction::DONT_CARE }, "EmuScreen_UI"); cardboardDisableButton_->SetVisibility(g_Config.bEnableCardboardVR ? UI::V_VISIBLE : UI::V_GONE); screenManager()->getUIContext()->BeginFrame(); renderUI(); diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index 813f8c020e..06ba82af31 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -297,6 +297,7 @@ struct GLRStep { GLRStepType stepType; std::vector commands; TinySet dependencies; + const char *tag; union { struct { GLRFramebuffer *framebuffer; diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 3d90882789..b2fe949cf2 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -260,7 +260,7 @@ void GLRenderManager::StopThread() { } } -void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil) { +void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag) { assert(insideFrame_); #ifdef _DEBUG curProgram_ = nullptr; @@ -284,6 +284,7 @@ void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRende step->render.depth = depth; step->render.stencil = stencil; step->render.numDraws = 0; + step->tag = tag; steps_.push_back(step); GLuint clearMask = 0; @@ -332,7 +333,7 @@ void GLRenderManager::BindFramebufferAsTexture(GLRFramebuffer *fb, int binding, curRenderStep_->dependencies.insert(fb); } -void GLRenderManager::CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLOffset2D dstPos, int aspectMask) { +void GLRenderManager::CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLOffset2D dstPos, int aspectMask, const char *tag) { GLRStep *step = new GLRStep{ GLRStepType::COPY }; step->copy.srcRect = srcRect; step->copy.dstPos = dstPos; @@ -340,6 +341,7 @@ void GLRenderManager::CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLR step->copy.dst = dst; step->copy.aspectMask = aspectMask; step->dependencies.insert(src); + step->tag = tag; bool fillsDst = dst && srcRect.x == 0 && srcRect.y == 0 && srcRect.w == dst->width && srcRect.h == dst->height; if (dstPos.x != 0 || dstPos.y != 0 || !fillsDst) step->dependencies.insert(dst); @@ -349,7 +351,7 @@ void GLRenderManager::CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLR gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); } -void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLRect2D dstRect, int aspectMask, bool filter) { +void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLRect2D dstRect, int aspectMask, bool filter, const char *tag) { GLRStep *step = new GLRStep{ GLRStepType::BLIT }; step->blit.srcRect = srcRect; step->blit.dstRect = dstRect; @@ -358,6 +360,7 @@ void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLR step->blit.aspectMask = aspectMask; step->blit.filter = filter; step->dependencies.insert(src); + step->tag = tag; bool fillsDst = dst && dstRect.x == 0 && dstRect.y == 0 && dstRect.w == dst->width && dstRect.h == dst->height; if (!fillsDst) step->dependencies.insert(dst); @@ -367,7 +370,7 @@ void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLR gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); } -bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) { +bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { _assert_(pixels); GLRStep *step = new GLRStep{ GLRStepType::READBACK }; @@ -376,6 +379,7 @@ bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspec step->readback.aspectMask = aspectBits; step->readback.dstFormat = destFormat; step->dependencies.insert(src); + step->tag = tag; steps_.push_back(step); // Every step clears this state. @@ -400,13 +404,14 @@ bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspec return true; } -void GLRenderManager::CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) { +void GLRenderManager::CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { _assert_(texture); _assert_(pixels); GLRStep *step = new GLRStep{ GLRStepType::READBACK_IMAGE }; step->readback_image.texture = texture; step->readback_image.mipLevel = mipLevel; step->readback_image.srcRect = { x, y, w, h }; + step->tag = tag; steps_.push_back(step); // Every step clears this state. diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 377344b073..47338a85eb 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -501,13 +501,13 @@ public: pushbuffer->End(); } - void BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil); + void BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag); void BindFramebufferAsTexture(GLRFramebuffer *fb, int binding, int aspectBit, int attachment); - bool CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride); - void CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride); + bool CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); + void CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); - void CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLOffset2D dstPos, int aspectMask); - void BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLRect2D dstRect, int aspectMask, bool filter); + void CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLOffset2D dstPos, int aspectMask, const char *tag); + void BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLRect2D dstRect, int aspectMask, bool filter, const char *tag); // Takes ownership of data if deleteData = true. void BufferSubdata(GLRBuffer *buffer, size_t offset, size_t size, uint8_t *data, bool deleteData = true) { diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index dd910750fa..80b00a087a 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -721,23 +721,23 @@ std::string VulkanQueueRunner::StepToString(const VKRStep &step) const { { int w = step.render.framebuffer ? step.render.framebuffer->width : vulkan_->GetBackbufferWidth(); int h = step.render.framebuffer ? step.render.framebuffer->height : vulkan_->GetBackbufferHeight(); - snprintf(buffer, sizeof(buffer), "RenderPass (draws: %d, %dx%d, fb: %p, )", step.render.numDraws, w, h, step.render.framebuffer); + snprintf(buffer, sizeof(buffer), "RenderPass %s (draws: %d, %dx%d, fb: %p, )", step.tag, step.render.numDraws, w, h, step.render.framebuffer); break; } case VKRStepType::COPY: - snprintf(buffer, sizeof(buffer), "Copy (%dx%d)", step.copy.srcRect.extent.width, step.copy.srcRect.extent.height); + snprintf(buffer, sizeof(buffer), "Copy '%s' (%dx%d)", step.tag, step.copy.srcRect.extent.width, step.copy.srcRect.extent.height); break; case VKRStepType::BLIT: - snprintf(buffer, sizeof(buffer), "Blit (%dx%d->%dx%d)", step.blit.srcRect.extent.width, step.blit.srcRect.extent.height, step.blit.dstRect.extent.width, step.blit.dstRect.extent.height); + snprintf(buffer, sizeof(buffer), "Blit '%s' (%dx%d->%dx%d)", step.tag, step.blit.srcRect.extent.width, step.blit.srcRect.extent.height, step.blit.dstRect.extent.width, step.blit.dstRect.extent.height); break; case VKRStepType::READBACK: - snprintf(buffer, sizeof(buffer), "Readback (%dx%d, fb: %p)", step.readback.srcRect.extent.width, step.readback.srcRect.extent.height, step.readback.src); + snprintf(buffer, sizeof(buffer), "Readback '%s' (%dx%d, fb: %p)", step.tag, step.readback.srcRect.extent.width, step.readback.srcRect.extent.height, step.readback.src); break; case VKRStepType::READBACK_IMAGE: - snprintf(buffer, sizeof(buffer), "ReadbackImage (%dx%d)", step.readback_image.srcRect.extent.width, step.readback_image.srcRect.extent.height); + snprintf(buffer, sizeof(buffer), "ReadbackImage '%s' (%dx%d)", step.tag, step.readback_image.srcRect.extent.width, step.readback_image.srcRect.extent.height); break; case VKRStepType::RENDER_SKIP: - snprintf(buffer, sizeof(buffer), "(SKIPPED RenderPass)"); + snprintf(buffer, sizeof(buffer), "(SKIPPED RenderPass) %s", step.tag); break; default: buffer[0] = 0; diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index 1c9e46a5cf..e7851c3554 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -127,6 +127,7 @@ struct VKRStep { std::vector commands; std::vector preTransitions; TinySet dependencies; + const char *tag; union { struct { VKRFramebuffer *framebuffer; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index ffbe99cd84..5535318e5c 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -454,10 +454,10 @@ VkCommandBuffer VulkanRenderManager::GetInitCmd() { return frameData_[curFrame].initCmd; } -void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil) { +void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag) { assert(insideFrame_); // Eliminate dupes. - if (steps_.size() && steps_.back()->render.framebuffer == fb && steps_.back()->stepType == VKRStepType::RENDER) { + if (!steps_.empty() && steps_.back()->stepType == VKRStepType::RENDER && steps_.back()->render.framebuffer == fb) { if (color != VKRRenderPassAction::CLEAR && depth != VKRRenderPassAction::CLEAR && stencil != VKRRenderPassAction::CLEAR) { // We don't move to a new step, this bind was unnecessary and we can safely skip it. // Not sure how much this is still happening but probably worth checking for nevertheless. @@ -500,6 +500,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR step->render.numDraws = 0; step->render.numReads = 0; step->render.finalColorLayout = !fb ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED; + step->tag = tag; steps_.push_back(step); if (fb) { @@ -521,7 +522,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR } } -bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) { +bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { assert(insideFrame_); for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { @@ -536,6 +537,7 @@ bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int a step->readback.srcRect.offset = { x, y }; step->readback.srcRect.extent = { (uint32_t)w, (uint32_t)h }; step->dependencies.insert(src); + step->tag = tag; steps_.push_back(step); curRenderStep_ = nullptr; @@ -582,13 +584,14 @@ bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int a return true; } -void VulkanRenderManager::CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) { +void VulkanRenderManager::CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { assert(insideFrame_); VKRStep *step = new VKRStep{ VKRStepType::READBACK_IMAGE }; step->readback_image.image = image; step->readback_image.srcRect.offset = { x, y }; step->readback_image.srcRect.extent = { (uint32_t)w, (uint32_t)h }; step->readback_image.mipLevel = mipLevel; + step->tag = tag; steps_.push_back(step); curRenderStep_ = nullptr; @@ -806,7 +809,7 @@ void VulkanRenderManager::Clear(uint32_t clearColor, float clearZ, int clearSten } } -void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, int aspectMask) { +void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, int aspectMask, const char *tag) { _dbg_assert_msg_(G3D, srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); _dbg_assert_msg_(G3D, srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); _dbg_assert_msg_(G3D, srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); @@ -846,6 +849,7 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, step->copy.dst = dst; step->copy.dstPos = dstPos; step->dependencies.insert(src); + step->tag = tag; bool fillsDst = dst && srcRect.offset.x == 0 && srcRect.offset.y == 0 && srcRect.extent.width == dst->width && srcRect.extent.height == dst->height; if (dstPos.x != 0 || dstPos.y != 0 || !fillsDst) step->dependencies.insert(dst); @@ -855,7 +859,7 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, curRenderStep_ = nullptr; } -void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter) { +void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter, const char *tag) { _dbg_assert_msg_(G3D, srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); _dbg_assert_msg_(G3D, srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); _dbg_assert_msg_(G3D, srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); @@ -888,6 +892,7 @@ void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, step->blit.dstRect = dstRect; step->blit.filter = filter; step->dependencies.insert(src); + step->tag = tag; bool fillsDst = dst && dstRect.offset.x == 0 && dstRect.offset.y == 0 && dstRect.extent.width == dst->width && dstRect.extent.height == dst->height; if (!fillsDst) step->dependencies.insert(dst); diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 9398781400..e12f220fcc 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -105,13 +105,13 @@ public: // Zaps queued up commands. Use if you know there's a risk you've queued up stuff that has already been deleted. Can happen during in-game shutdown. void Wipe(); - void BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil); + void BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag); VkImageView BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, int aspectBit, int attachment); - bool CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride); - void CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride); + bool CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); + void CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); - void CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, int aspectMask); - void BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter); + void CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, int aspectMask, const char *tag); + void BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter, const char *tag); void BindPipeline(VkPipeline pipeline) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index bf5f9bb87e..22af453d83 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -553,6 +553,7 @@ struct RenderPassInfo { uint32_t clearColor; float clearDepth; uint8_t clearStencil; + const char *tag; }; class DrawContext { @@ -596,9 +597,9 @@ public: // Copies data from the CPU over into the buffer, at a specific offset. This does not change the size of the buffer and cannot write outside it. virtual void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) = 0; - virtual void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) = 0; - virtual bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) = 0; - virtual bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride) { + virtual void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) = 0; + virtual bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) = 0; + virtual bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, const char *tag) { return false; } virtual DataFormat PreferredFramebufferReadbackFormat(Framebuffer *src) { @@ -607,7 +608,7 @@ public: // These functions should be self explanatory. // Binding a zero render target means binding the backbuffer. - virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) = 0; + virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) = 0; // color must be 0, for now. virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) = 0; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 7d2c2d538b..719c306b44 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -65,12 +65,12 @@ public: void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override; - void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override; - bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override; - bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride); + void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) override; + bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) override; + bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, const char *tag); // These functions should be self explanatory. - void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) override; + void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; // color must be 0, for now. void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; @@ -1348,7 +1348,7 @@ void D3D11DrawContext::BeginFrame() { } } -void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x, int y, int z, Framebuffer *dstfb, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBit) { +void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x, int y, int z, Framebuffer *dstfb, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBit, const char *tag) { D3D11Framebuffer *src = (D3D11Framebuffer *)srcfb; D3D11Framebuffer *dst = (D3D11Framebuffer *)dstfb; @@ -1396,13 +1396,13 @@ void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x } } -bool D3D11DrawContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) { +bool D3D11DrawContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) { // Unfortunately D3D11 has no equivalent to this, gotta render a quad. Well, in some cases we can issue a copy instead. Crash(); return false; } -bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int bx, int by, int bw, int bh, Draw::DataFormat format, void *pixels, int pixelStride) { +bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int bx, int by, int bw, int bh, Draw::DataFormat format, void *pixels, int pixelStride, const char *tag) { D3D11Framebuffer *fb = (D3D11Framebuffer *)src; if (fb) { @@ -1522,7 +1522,7 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel return true; } -void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) { +void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) { // TODO: deviceContext1 can actually discard. Useful on Windows Mobile. if (fbo) { D3D11Framebuffer *fb = (D3D11Framebuffer *)fbo; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 672ebd36ab..42fc0d29a2 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -525,11 +525,11 @@ public: void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override; - void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override {} - bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override; + void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) override {} + bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) override; // These functions should be self explanatory. - void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) override; + void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; // color must be 0, for now. void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; @@ -1131,7 +1131,7 @@ D3D9Framebuffer::~D3D9Framebuffer() { } } -void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) { +void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) { using namespace DX9; if (fbo) { D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo; @@ -1219,7 +1219,7 @@ void D3D9Context::GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) { } } -bool D3D9Context::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) { +bool D3D9Context::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) { D3D9Framebuffer *src = (D3D9Framebuffer *)srcfb; D3D9Framebuffer *dst = (D3D9Framebuffer *)dstfb; if (channelBits != FB_COLOR_BIT) diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index d319c07101..2a45ae2256 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -370,12 +370,12 @@ public: void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override; - void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override; - bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override; - bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride) override; + void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) override; + bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) override; + bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, const char *tag) override; // These functions should be self explanatory. - void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) override; + void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; // color must be 0, for now. void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; @@ -809,7 +809,7 @@ static void LogReadPixelsError(GLenum error) { } #endif -bool OpenGLContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat dataFormat, void *pixels, int pixelStride) { +bool OpenGLContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat dataFormat, void *pixels, int pixelStride, const char *tag) { if (gl_extensions.IsGLES && (channelBits & FB_COLOR_BIT) == 0) { // Can't readback depth or stencil on GLES. return false; @@ -822,7 +822,7 @@ bool OpenGLContext::CopyFramebufferToMemorySync(Framebuffer *src, int channelBit aspect |= GL_DEPTH_BUFFER_BIT; if (channelBits & FB_STENCIL_BIT) aspect |= GL_STENCIL_BUFFER_BIT; - renderManager_.CopyFramebufferToMemorySync(fb ? fb->framebuffer : nullptr, aspect, x, y, w, h, dataFormat, (uint8_t *)pixels, pixelStride); + renderManager_.CopyFramebufferToMemorySync(fb ? fb->framebuffer : nullptr, aspect, x, y, w, h, dataFormat, (uint8_t *)pixels, pixelStride, tag); return true; } @@ -1188,16 +1188,16 @@ Framebuffer *OpenGLContext::CreateFramebuffer(const FramebufferDesc &desc) { return fbo; } -void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) { +void OpenGLContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) { OpenGLFramebuffer *fb = (OpenGLFramebuffer *)fbo; GLRRenderPassAction color = (GLRRenderPassAction)rp.color; GLRRenderPassAction depth = (GLRRenderPassAction)rp.depth; GLRRenderPassAction stencil = (GLRRenderPassAction)rp.stencil; - renderManager_.BindFramebufferAsRenderTarget(fb ? fb->framebuffer : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil); + renderManager_.BindFramebufferAsRenderTarget(fb ? fb->framebuffer : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil, tag); } -void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) { +void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int srcX, int srcY, int srcZ, Framebuffer *fbdst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) { OpenGLFramebuffer *src = (OpenGLFramebuffer *)fbsrc; OpenGLFramebuffer *dst = (OpenGLFramebuffer *)fbdst; @@ -1210,10 +1210,10 @@ void OpenGLContext::CopyFramebufferImage(Framebuffer *fbsrc, int srcLevel, int s if (channelBits & FB_STENCIL_BIT) aspect |= GL_STENCIL_BUFFER_BIT; } - renderManager_.CopyFramebuffer(src->framebuffer, GLRect2D{ srcX, srcY, width, height }, dst->framebuffer, GLOffset2D{ dstX, dstY }, aspect); + renderManager_.CopyFramebuffer(src->framebuffer, GLRect2D{ srcX, srcY, width, height }, dst->framebuffer, GLOffset2D{ dstX, dstY }, aspect, tag); } -bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *fbdst, int dstX1, int dstY1, int dstX2, int dstY2, int channels, FBBlitFilter linearFilter) { +bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *fbdst, int dstX1, int dstY1, int dstX2, int dstY2, int channels, FBBlitFilter linearFilter, const char *tag) { OpenGLFramebuffer *src = (OpenGLFramebuffer *)fbsrc; OpenGLFramebuffer *dst = (OpenGLFramebuffer *)fbdst; GLuint aspect = 0; @@ -1224,7 +1224,7 @@ bool OpenGLContext::BlitFramebuffer(Framebuffer *fbsrc, int srcX1, int srcY1, in if (channels & FB_STENCIL_BIT) aspect |= GL_STENCIL_BUFFER_BIT; - renderManager_.BlitFramebuffer(src->framebuffer, GLRect2D{ srcX1, srcY1, srcX2 - srcX1, srcY2 - srcY1 }, dst->framebuffer, GLRect2D{ dstX1, dstY1, dstX2 - dstX1, dstY2 - dstY1 }, aspect, linearFilter == FB_BLIT_LINEAR); + renderManager_.BlitFramebuffer(src->framebuffer, GLRect2D{ srcX1, srcY1, srcX2 - srcX1, srcY2 - srcY1 }, dst->framebuffer, GLRect2D{ dstX1, dstY1, dstX2 - dstX1, dstY2 - dstY1 }, aspect, linearFilter == FB_BLIT_LINEAR, tag); return true; } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 919f3f59ac..e3160a944d 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -378,13 +378,13 @@ public: void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override; - void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) override; - bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) override; - bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride) override; + void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) override; + bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) override; + bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, const char *tag) override; DataFormat PreferredFramebufferReadbackFormat(Framebuffer *src) override; // These functions should be self explanatory. - void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) override; + void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) override; // color must be 0, for now. void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) override; @@ -1431,7 +1431,7 @@ Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) { return new VKFramebuffer(vkrfb); } -void VKContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x, int y, int z, Framebuffer *dstfb, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits) { +void VKContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x, int y, int z, Framebuffer *dstfb, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) { VKFramebuffer *src = (VKFramebuffer *)srcfb; VKFramebuffer *dst = (VKFramebuffer *)dstfb; @@ -1440,10 +1440,10 @@ void VKContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x, int y if (channelBits & FBChannel::FB_DEPTH_BIT) aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; if (channelBits & FBChannel::FB_STENCIL_BIT) aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - renderManager_.CopyFramebuffer(src->GetFB(), VkRect2D{ {x, y}, {(uint32_t)width, (uint32_t)height } }, dst->GetFB(), VkOffset2D{ dstX, dstY }, aspectMask); + renderManager_.CopyFramebuffer(src->GetFB(), VkRect2D{ {x, y}, {(uint32_t)width, (uint32_t)height } }, dst->GetFB(), VkOffset2D{ dstX, dstY }, aspectMask, tag); } -bool VKContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter) { +bool VKContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) { VKFramebuffer *src = (VKFramebuffer *)srcfb; VKFramebuffer *dst = (VKFramebuffer *)dstfb; @@ -1452,11 +1452,11 @@ bool VKContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int sr if (channelBits & FBChannel::FB_DEPTH_BIT) aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; if (channelBits & FBChannel::FB_STENCIL_BIT) aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - renderManager_.BlitFramebuffer(src->GetFB(), VkRect2D{ {srcX1, srcY1}, {(uint32_t)(srcX2 - srcX1), (uint32_t)(srcY2 - srcY1) } }, dst->GetFB(), VkRect2D{ {dstX1, dstY1}, {(uint32_t)(dstX2 - dstX1), (uint32_t)(dstY2 - dstY1) } }, aspectMask, filter == FB_BLIT_LINEAR ? VK_FILTER_LINEAR : VK_FILTER_NEAREST); + renderManager_.BlitFramebuffer(src->GetFB(), VkRect2D{ {srcX1, srcY1}, {(uint32_t)(srcX2 - srcX1), (uint32_t)(srcY2 - srcY1) } }, dst->GetFB(), VkRect2D{ {dstX1, dstY1}, {(uint32_t)(dstX2 - dstX1), (uint32_t)(dstY2 - dstY1) } }, aspectMask, filter == FB_BLIT_LINEAR ? VK_FILTER_LINEAR : VK_FILTER_NEAREST, tag); return true; } -bool VKContext::CopyFramebufferToMemorySync(Framebuffer *srcfb, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride) { +bool VKContext::CopyFramebufferToMemorySync(Framebuffer *srcfb, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, const char *tag) { VKFramebuffer *src = (VKFramebuffer *)srcfb; int aspectMask = 0; @@ -1464,7 +1464,7 @@ bool VKContext::CopyFramebufferToMemorySync(Framebuffer *srcfb, int channelBits, if (channelBits & FBChannel::FB_DEPTH_BIT) aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; if (channelBits & FBChannel::FB_STENCIL_BIT) aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - return renderManager_.CopyFramebufferToMemorySync(src ? src->GetFB() : nullptr, aspectMask, x, y, w, h, format, (uint8_t *)pixels, pixelStride); + return renderManager_.CopyFramebufferToMemorySync(src ? src->GetFB() : nullptr, aspectMask, x, y, w, h, format, (uint8_t *)pixels, pixelStride, tag); } DataFormat VKContext::PreferredFramebufferReadbackFormat(Framebuffer *src) { @@ -1478,13 +1478,13 @@ DataFormat VKContext::PreferredFramebufferReadbackFormat(Framebuffer *src) { return DrawContext::PreferredFramebufferReadbackFormat(src); } -void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp) { +void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) { VKFramebuffer *fb = (VKFramebuffer *)fbo; VKRRenderPassAction color = (VKRRenderPassAction)rp.color; VKRRenderPassAction depth = (VKRRenderPassAction)rp.depth; VKRRenderPassAction stencil = (VKRRenderPassAction)rp.stencil; - renderManager_.BindFramebufferAsRenderTarget(fb ? fb->GetFB() : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil); + renderManager_.BindFramebufferAsRenderTarget(fb ? fb->GetFB() : nullptr, color, depth, stencil, rp.clearColor, rp.clearDepth, rp.clearStencil, tag); curFramebuffer_ = fb; } diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index b0490bc762..835799b54f 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -80,7 +80,7 @@ void UIScreen::preRender() { } draw->BeginFrame(); // Bind and clear the back buffer - draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 }); + draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 }, "UI"); screenManager()->getUIContext()->BeginFrame(); Draw::Viewport viewport; From 7d10a0c609b4334e0879a172d178794dacffa60f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 21 May 2020 11:53:55 +0200 Subject: [PATCH 027/848] Remove a redundant framebuffer bind in CopyDisplayToOutput --- GPU/Common/FramebufferCommon.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 01fb23796e..b36ac5be19 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -894,13 +894,6 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { if (Memory::IsValidAddress(fbaddr)) { // The game is displaying something directly from RAM. In GTA, it's decoded video. if (!vfb) { - if (useBufferedRendering_) { - // Bind and clear the backbuffer. This should be the first time during the frame that it's bound. - draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput_Backbuffer"); - } - // Just a pointer to plain memory to draw. We should create a framebuffer, then draw to it. - SetViewport2D(0, 0, pixelWidth_, pixelHeight_); - draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); DrawFramebufferToOutput(Memory::GetPointer(fbaddr), displayFormat_, displayStride_); gstate_c.Dirty(DIRTY_BLEND_STATE); return; From 4aec10d04f1f2a4b83718c8e6e7e360d3a14ce7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 21 May 2020 11:54:48 +0200 Subject: [PATCH 028/848] Correct an issue where reformat didn't work if no renderpass was active due to the use of clear. Also instantly convert to a clear when binding the framebuffer in cases when we know it's the optimal thing. The QueueRunner would have later merged anyway hopefully, but I like the simplicity of this. --- GPU/Vulkan/FramebufferVulkan.cpp | 10 ++++++-- ext/native/thin3d/VulkanRenderManager.cpp | 30 ++++++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 6eadd4e86a..b22d4dffc6 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -265,8 +265,14 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, // to exactly reproduce in 4444 and 8888 formats. if (old == GE_FORMAT_565) { - // Previously started a render pass here to clear, but better to just, well, explicitly clear. - draw_->Clear(Draw::FBChannel::FB_COLOR_BIT | Draw::FBChannel::FB_STENCIL_BIT, 0, 0.0f, 0); + // We have to bind here instead of clear, since it can be that no framebuffer is bound. + // The backend can sometimes directly optimize it to a clear. + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP, Draw::RPAction::CLEAR }, "ReformatFramebuffer"); + // draw_->Clear(Draw::FBChannel::FB_COLOR_BIT | Draw::FBChannel::FB_STENCIL_BIT, 0, 0.0f, 0); + + // Need to dirty anything that has command buffer dynamic state, in case we started a new pass above. + // Should find a way to feed that information back, maybe... Or simply correct the issue in the rendermanager. + gstate_c.Dirty(DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE); } } diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 5535318e5c..0414e8ab33 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -456,11 +456,25 @@ VkCommandBuffer VulkanRenderManager::GetInitCmd() { void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag) { assert(insideFrame_); - // Eliminate dupes. + // Eliminate dupes, instantly convert to a clear if possible. if (!steps_.empty() && steps_.back()->stepType == VKRStepType::RENDER && steps_.back()->render.framebuffer == fb) { - if (color != VKRRenderPassAction::CLEAR && depth != VKRRenderPassAction::CLEAR && stencil != VKRRenderPassAction::CLEAR) { - // We don't move to a new step, this bind was unnecessary and we can safely skip it. - // Not sure how much this is still happening but probably worth checking for nevertheless. + u32 clearMask = 0; + if (color == VKRRenderPassAction::CLEAR) { + clearMask |= VK_IMAGE_ASPECT_COLOR_BIT; + } + if (depth == VKRRenderPassAction::CLEAR) { + clearMask |= VK_IMAGE_ASPECT_DEPTH_BIT; + } + if (stencil == VKRRenderPassAction::CLEAR) { + clearMask |= VK_IMAGE_ASPECT_STENCIL_BIT; + } + + // If we need a clear and the previous step has commands already, it's best to just add a clear and keep going. + // If there's no clear needed, let's also do that. + // + // However, if we do need a clear and there are no commands in the previous pass, + // we want the queuerunner to have the opportunity to merge, so we'll go ahead and make a new renderpass. + if (clearMask == 0 || !steps_.back()->commands.empty()) { curRenderStep_ = steps_.back(); curStepHasViewport_ = false; curStepHasScissor_ = false; @@ -473,6 +487,14 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR break; } } + if (clearMask != 0) { + VkRenderData data{ VKRRenderCommand::CLEAR }; + data.clear.clearColor = clearColor; + data.clear.clearZ = clearDepth; + data.clear.clearStencil = clearStencil; + data.clear.clearMask = clearMask; + curRenderStep_->commands.push_back(data); + } return; } } From e9e0ea9d05c1452b3a045fd81e9021230b71c7b0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 08:38:29 -0700 Subject: [PATCH 029/848] Vulkan: Cleanup some duplicate code. --- Common/Vulkan/VulkanDebug.cpp | 4 +-- Common/Vulkan/VulkanDebug.h | 2 ++ android/jni/AndroidVulkanContext.cpp | 38 +++------------------------- android/jni/AndroidVulkanContext.h | 6 ----- 4 files changed, 7 insertions(+), 43 deletions(-) diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index 55825f8209..ae704839ee 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -23,7 +23,7 @@ #include "Common/Vulkan/VulkanDebug.h" #include "base/logging.h" -const char *ObjTypeToString(VkDebugReportObjectTypeEXT type) { +const char *VulkanObjTypeToString(VkDebugReportObjectTypeEXT type) { switch (type) { case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; @@ -71,7 +71,7 @@ VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, Vk } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { message << "DEBUG: "; } - message << "[" << pLayerPrefix << "] " << ObjTypeToString(objType) << " Code " << msgCode << " : " << pMsg << "\n"; + message << "[" << pLayerPrefix << "] " << VulkanObjTypeToString(objType) << " Code " << msgCode << " : " << pMsg << "\n"; if (msgCode == 64) // Another useless perf warning that will be seen less and less as we optimize - vkCmdClearAttachments() issued on command buffer object 0x00000195296C6D40 prior to any Draw Cmds. It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw. return false; diff --git a/Common/Vulkan/VulkanDebug.h b/Common/Vulkan/VulkanDebug.h index 10cb70d8ed..0b6bda6b71 100644 --- a/Common/Vulkan/VulkanDebug.h +++ b/Common/Vulkan/VulkanDebug.h @@ -27,3 +27,5 @@ struct VulkanLogOptions { VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData); VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData); + +const char *VulkanObjTypeToString(VkDebugReportObjectTypeEXT type); diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 5a5b67b2f8..046fc29e36 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -3,8 +3,9 @@ #include "AndroidVulkanContext.h" #include "base/NativeApp.h" #include "base/display.h" -#include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanContext.h" +#include "Common/Vulkan/VulkanDebug.h" +#include "Common/Vulkan/VulkanLoader.h" #include "thin3d/VulkanRenderManager.h" #include "thin3d/thin3d_create.h" #include "util/text/parsers.h" @@ -14,39 +15,6 @@ static VulkanLogOptions g_LogOptions; -const char *ObjTypeToString(VkDebugReportObjectTypeEXT type) { - switch (type) { - case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore"; - case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapChainKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "CommandPool"; - default: return "Unknown"; - } -} - static VKAPI_ATTR VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; int loglevel = ANDROID_LOG_INFO; @@ -63,7 +31,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, } __android_log_print(loglevel, APP_NAME, "[%s] %s Code %d : %s", - pLayerPrefix, ObjTypeToString(objType), msgCode, pMsg); + pLayerPrefix, VulkanObjTypeToString(objType), msgCode, pMsg); // false indicates that layer should not bail-out of an // API call that had validation failures. This may mean that the diff --git a/android/jni/AndroidVulkanContext.h b/android/jni/AndroidVulkanContext.h index adb47e2806..82a041d1b5 100644 --- a/android/jni/AndroidVulkanContext.h +++ b/android/jni/AndroidVulkanContext.h @@ -34,9 +34,3 @@ private: VulkanContext *g_Vulkan = nullptr; Draw::DrawContext *draw_ = nullptr; }; - -struct VulkanLogOptions { - bool breakOnWarning; - bool breakOnError; - bool msgBoxOnError; -}; From 2dbb7a598da02984a4daf31c14abe57414231bec Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 08:38:48 -0700 Subject: [PATCH 030/848] Vulkan: Label render passes in RenderDoc/etc. --- ext/native/thin3d/VulkanQueueRunner.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 80b00a087a..6c335ae608 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -447,8 +447,16 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &st } } + bool emitLabels = vulkan_->DeviceExtensions().EXT_debug_utils; for (size_t i = 0; i < steps.size(); i++) { const VKRStep &step = *steps[i]; + + if (emitLabels) { + VkDebugUtilsLabelEXT labelInfo{ VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT }; + labelInfo.pLabelName = step.tag; + vkCmdBeginDebugUtilsLabelEXT(cmd, &labelInfo); + } + switch (step.stepType) { case VKRStepType::RENDER: PerformRenderPass(step, cmd); @@ -473,6 +481,10 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &st vkCmdWriteTimestamp(cmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, profile->queryPool, (uint32_t)profile->timestampDescriptions.size()); profile->timestampDescriptions.push_back(StepToString(step)); } + + if (emitLabels) { + vkCmdEndDebugUtilsLabelEXT(cmd); + } } // Deleting all in one go should be easier on the instruction cache than deleting From cd869d469d831da2de7b2fdae20b0babc47f11d3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 11:37:36 -0700 Subject: [PATCH 031/848] GPU: Ignore viewport for scissor of 481. Assume it's still wrong in this case and take 480x272. See #12746. --- GPU/Common/FramebufferCommon.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 01fb23796e..a4ae58d096 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -151,16 +151,17 @@ void FramebufferManagerCommon::EstimateDrawingSize(u32 fb_address, GEBufferForma drawing_width = scissor_width; drawing_height = std::max(drawing_height, scissor_height); } - if (scissor_width == 481 && region_width == 480 && scissor_height == 273 && region_height == 272) { - drawing_width = 480; - drawing_height = 272; - } } else { // If viewport wasn't valid, let's just take the greatest anything regardless of stride. drawing_width = std::min(std::max(region_width, scissor_width), fb_stride); drawing_height = std::max(region_height, scissor_height); } + if (scissor_width == 481 && region_width == 480 && scissor_height == 273 && region_height == 272) { + drawing_width = 480; + drawing_height = 272; + } + // Assume no buffer is > 512 tall, it couldn't be textured or displayed fully if so. if (drawing_height >= MAX_FRAMEBUF_HEIGHT) { if (region_height < MAX_FRAMEBUF_HEIGHT) { From 3777d32ac862f4e74669a914d787b0ddf71d6818 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 15:08:10 -0700 Subject: [PATCH 032/848] Io: Cleanup sceIoOpen errors and logging. --- Core/FileSystems/MetaFileSystem.cpp | 6 +++-- Core/HLE/sceIo.cpp | 42 +++++++++++------------------ 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 19bddf251e..648189b52e 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -178,7 +178,7 @@ IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle) int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, MountPoint **system) { - int error = -1; + int error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND; std::lock_guard guard(lock); std::string realpath; @@ -246,6 +246,8 @@ int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath return error == SCE_KERNEL_ERROR_NOCWD ? error : 0; } } + + error = SCE_KERNEL_ERROR_NODEV; } DEBUG_LOG(FILESYS, "MapFilePath: failed mapping \"%s\", returning false", inpath.c_str()); @@ -353,7 +355,7 @@ int MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char if (error == 0) return mount->system->OpenFile(of, access, mount->prefix.c_str()); else - return error == -1 ? SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND : error; + return error; } PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 567f0c069a..d35df60aee 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1463,41 +1463,33 @@ static FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) } static u32 sceIoOpen(const char *filename, int flags, int mode) { - if (!__KernelIsDispatchEnabled()) - return -1; + if (!__KernelIsDispatchEnabled()) { + return hleLogError(SCEIO, SCE_KERNEL_ERROR_CAN_NOT_WAIT, "dispatch disabled"); + } int error; FileNode *f = __IoOpen(error, filename, flags, mode); - if (f == NULL) - { - // Timing is not accurate, aiming low for now. - if (error == (int)SCE_KERNEL_ERROR_NOCWD) - { - ERROR_LOG(SCEIO, "SCE_KERNEL_ERROR_NOCWD=sceIoOpen(%s, %08x, %08x) - no current working directory", filename, flags, mode); - return hleDelayResult(SCE_KERNEL_ERROR_NOCWD, "no cwd", 10000); - } - else if (error != 0) - { - ERROR_LOG(SCEIO, "%08x=sceIoOpen(%s, %08x, %08x)", error, filename, flags, mode); - return hleDelayResult(error, "file opened", 10000); - } - else - { - ERROR_LOG(SCEIO, "ERROR_ERRNO_FILE_NOT_FOUND=sceIoOpen(%s, %08x, %08x) - file not found", filename, flags, mode); - return hleDelayResult(SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND, "file opened", 10000); + if (!f) { + assert(error != 0); + if (error == (int)SCE_KERNEL_ERROR_NOCWD) { + // TODO: Timing is not accurate. + return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000), "no current working directory"); + } else if (error == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) { + // TODO: Depends on filesys. + return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", 10000), "file not found"); + } else { + return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000)); } } int id = __IoAllocFd(f); if (id < 0) { - ERROR_LOG(SCEIO, "%08x=sceIoOpen(%s, %08x, %08x): out of fds", id, filename, flags, mode); kernelObjects.Destroy(f->GetUID()); - return id; + return hleLogError(SCEIO, id, "out of fds"); } else { - DEBUG_LOG(SCEIO, "%i=sceIoOpen(%s, %08x, %08x)", id, filename, flags, mode); asyncParams[id].priority = asyncDefaultPriority; // Timing is not accurate, aiming low for now. - return hleDelayResult(id, "file opened", 100); + return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", 100)); } } @@ -2044,9 +2036,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) // We have to return an fd here, which may have been destroyed when we reach Wait if it failed. if (f == nullptr) { - if (error == 0) - error = SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND; - + assert(error != 0); f = new FileNode(); f->handle = kernelObjects.Create(f); f->fullpath = filename; From 51db9f0f858de178c5d3fb491ee3abd69d5f14da Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 15:42:43 -0700 Subject: [PATCH 033/848] Io: Improve timing of sceIoOpen(). Currently ignores filesystem, but this is more accurate. --- Core/HLE/sceIo.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index d35df60aee..12e1781683 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1463,7 +1463,10 @@ static FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) } static u32 sceIoOpen(const char *filename, int flags, int mode) { + hleEatCycles(18000); + if (!__KernelIsDispatchEnabled()) { + hleEatCycles(48000); return hleLogError(SCEIO, SCE_KERNEL_ERROR_CAN_NOT_WAIT, "dispatch disabled"); } @@ -1474,6 +1477,8 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { if (error == (int)SCE_KERNEL_ERROR_NOCWD) { // TODO: Timing is not accurate. return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000), "no current working directory"); + } else if (error == (int)SCE_KERNEL_ERROR_NODEV) { + return hleLogError(SCEIO, error, "device not found"); } else if (error == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) { // TODO: Depends on filesys. return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", 10000), "file not found"); @@ -1485,11 +1490,11 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { int id = __IoAllocFd(f); if (id < 0) { kernelObjects.Destroy(f->GetUID()); - return hleLogError(SCEIO, id, "out of fds"); + return hleLogError(SCEIO, hleDelayResult(id, "file opened", 10000), "out of fds"); } else { asyncParams[id].priority = asyncDefaultPriority; - // Timing is not accurate, aiming low for now. - return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", 100)); + // TODO: Depends on filesys. Timing is not accurate, aiming low for now. + return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", 1000)); } } From 67416e591933c746ac6e7725ef9938304d56d44f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 15:55:25 -0700 Subject: [PATCH 034/848] Io: Simulate VFAT bug only when simulating FAT32. And cleanup flag handling a bit. --- Core/FileSystems/BlobFileSystem.cpp | 2 +- Core/FileSystems/BlobFileSystem.h | 2 +- Core/FileSystems/DirectoryFileSystem.cpp | 10 +++++++--- Core/FileSystems/DirectoryFileSystem.h | 8 ++++---- Core/FileSystems/FileSystem.h | 16 ++++++++++++---- Core/FileSystems/ISOFileSystem.h | 4 ++-- Core/FileSystems/MetaFileSystem.h | 2 +- Core/FileSystems/VirtualDiscFileSystem.h | 2 +- Core/HLE/sceIo.cpp | 9 ++++----- Core/PSPLoaders.cpp | 2 +- 10 files changed, 34 insertions(+), 23 deletions(-) diff --git a/Core/FileSystems/BlobFileSystem.cpp b/Core/FileSystems/BlobFileSystem.cpp index 0f02bbd821..ceaeb9e1c7 100644 --- a/Core/FileSystems/BlobFileSystem.cpp +++ b/Core/FileSystems/BlobFileSystem.cpp @@ -109,7 +109,7 @@ int BlobFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 out } int BlobFileSystem::DevType(u32 handle) { - return -1; + return PSP_DEV_TYPE_FILE; } bool BlobFileSystem::MkDir(const std::string &dirname) { diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h index 2a877918d9..756122468c 100644 --- a/Core/FileSystems/BlobFileSystem.h +++ b/Core/FileSystems/BlobFileSystem.h @@ -44,7 +44,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } bool MkDir(const std::string &dirname) override; bool RmDir(const std::string &dirname) override; diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index f5bbf8e03b..90d623b350 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -150,7 +150,7 @@ bool FixPathCase(const std::string &basePath, std::string &path, FixPathCaseBeha #endif -DirectoryFileSystem::DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, int _flags) : basePath(_basePath), flags(_flags) { +DirectoryFileSystem::DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, FileSystemFlags _flags) : basePath(_basePath), flags(_flags) { File::CreateFullPath(basePath); hAlloc = _hAlloc; } @@ -874,7 +874,9 @@ std::vector DirectoryFileSystem::GetDirListing(std::string path) { entry.size = 4096; else entry.size = findData.nFileSizeLow | ((u64)findData.nFileSizeHigh<<32); - entry.name = SimulateVFATBug(ConvertWStringToUTF8(findData.cFileName)); + entry.name = ConvertWStringToUTF8(findData.cFileName); + if (Flags() & FileSystemFlags::SIMULATE_FAT32) + entry.name = SimulateVFATBug(entry.name); bool hideFile = false; if (hideISOFiles && (endsWithNoCase(entry.name, ".cso") || endsWithNoCase(entry.name, ".iso"))) { @@ -921,7 +923,9 @@ std::vector DirectoryFileSystem::GetDirListing(std::string path) { else entry.type = FILETYPE_NORMAL; entry.access = s.st_mode & 0x1FF; - entry.name = SimulateVFATBug(dirp->d_name); + entry.name = dirp->d_name; + if (Flags() & FileSystemFlags::SIMULATE_FAT32) + entry.name = SimulateVFATBug(entry.name); entry.size = s.st_size; bool hideFile = false; diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index e00a4c4946..edc4b5db27 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -85,7 +85,7 @@ struct DirectoryFileHandle { class DirectoryFileSystem : public IFileSystem { public: - DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, int _flags = 0); + DirectoryFileSystem(IHandleAllocator *_hAlloc, std::string _basePath, FileSystemFlags _flags = FileSystemFlags::NONE); ~DirectoryFileSystem(); void CloseAll(); @@ -109,7 +109,7 @@ public: int RenameFile(const std::string &from, const std::string &to) override; bool RemoveFile(const std::string &filename) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; - int Flags() override { return flags; } + FileSystemFlags Flags() override { return flags; } u64 FreeSpace(const std::string &path) override; private: @@ -123,7 +123,7 @@ private: EntryMap entries; std::string basePath; IHandleAllocator *hAlloc; - int flags; + FileSystemFlags flags; // In case of Windows: Translate slashes, etc. std::string GetLocalPath(std::string localpath); }; @@ -154,7 +154,7 @@ public: int RenameFile(const std::string &from, const std::string &to) override; bool RemoveFile(const std::string &filename) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override { return 0; } private: diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 4f87736613..a958771de9 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -50,10 +50,18 @@ enum DevType { PSP_DEV_TYPE_ALIAS = 0x20, }; -enum FileSystemFlags { - FILESYSTEM_SIMULATE_FAT32 = 1, +enum class FileSystemFlags { + NONE = 0, + SIMULATE_FAT32 = 1, }; +inline FileSystemFlags operator |(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { + return FileSystemFlags((int)lhs | (int)rhs); +} +inline bool operator &(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { + return ((int)lhs & (int)rhs) != 0; +} + class IHandleAllocator { public: virtual ~IHandleAllocator() {} @@ -126,7 +134,7 @@ public: virtual bool GetHostPath(const std::string &inpath, std::string &outpath) = 0; virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) = 0; virtual int DevType(u32 handle) = 0; - virtual int Flags() = 0; + virtual FileSystemFlags Flags() = 0; virtual u64 FreeSpace(const std::string &path) = 0; }; @@ -152,7 +160,7 @@ public: virtual bool GetHostPath(const std::string &inpath, std::string &outpath) override {return false;} virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override {return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } virtual int DevType(u32 handle) override { return 0; } - virtual int Flags() override { return 0; } + virtual FileSystemFlags Flags() override { return FileSystemFlags::NONE; } virtual u64 FreeSpace(const std::string &path) override { return 0; } }; diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index 34b24bb081..a8a2ec7746 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -42,7 +42,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override { return 0; } size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override; @@ -137,7 +137,7 @@ public: int DevType(u32 handle) override { return isoFileSystem_->DevType(handle); } - int Flags() override { return isoFileSystem_->Flags(); } + FileSystemFlags Flags() override { return isoFileSystem_->Flags(); } u64 FreeSpace(const std::string &path) override { return isoFileSystem_->FreeSpace(path); } size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override { diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index c4bfd8d37f..37bde0d256 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -115,7 +115,7 @@ public: bool RemoveFile(const std::string &filename) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override; // Convenience helper - returns < 0 on failure. diff --git a/Core/FileSystems/VirtualDiscFileSystem.h b/Core/FileSystems/VirtualDiscFileSystem.h index b4ad72924b..9b676fd9ad 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.h +++ b/Core/FileSystems/VirtualDiscFileSystem.h @@ -41,7 +41,7 @@ public: int DevType(u32 handle) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; std::vector GetDirListing(std::string path) override; - int Flags() override { return 0; } + FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override { return 0; } // unsupported operations diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 12e1781683..186b7280ec 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -621,7 +621,7 @@ void __IoInit() { asyncNotifyEvent = CoreTiming::RegisterEvent("IoAsyncNotify", __IoAsyncNotify); syncNotifyEvent = CoreTiming::RegisterEvent("IoSyncNotify", __IoSyncNotify); - memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FILESYSTEM_SIMULATE_FAT32); + memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FileSystemFlags::SIMULATE_FAT32); #if defined(USING_WIN_UI) || defined(APPLE) flash0System = new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory); #else @@ -637,7 +637,7 @@ void __IoInit() { const std::string gameId = g_paramSFO.GetValueString("DISC_ID"); const std::string exdataPath = g_Config.memStickDirectory + "exdata/" + gameId + "/"; if (File::Exists(exdataPath)) { - exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FILESYSTEM_SIMULATE_FAT32); + exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FileSystemFlags::SIMULATE_FAT32); pspFileSystem.Mount("exdata0:", exdataSystem); INFO_LOG(SCEIO, "Mounted exdata/%s/ under memstick for exdata0:/", gameId.c_str()); } else { @@ -1423,8 +1423,7 @@ static u32 sceIoLseek32Async(int id, int offset, int whence) { return 0; } -static FileNode *__IoOpen(int &error, const char* filename, int flags, int mode) { - //memory stick filename +static FileNode *__IoOpen(int &error, const char *filename, int flags, int mode) { int access = FILEACCESS_NONE; if (flags & PSP_O_RDONLY) access |= FILEACCESS_READ; @@ -2290,7 +2289,7 @@ static u32 sceIoDread(int id, u32 dirent_addr) { bool isFAT = false; IFileSystem *sys = pspFileSystem.GetSystemFromFilename(dir->name); - if (sys && (sys->Flags() & FILESYSTEM_SIMULATE_FAT32)) + if (sys && (sys->Flags() & FileSystemFlags::SIMULATE_FAT32)) isFAT = true; else isFAT = false; diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index d72c648601..887b61b8c3 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -386,7 +386,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { pspFileSystem.SetStartingDirectory(ms_path); } - DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path); + DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path, FileSystemFlags::SIMULATE_FAT32); pspFileSystem.Mount("umd0:", fs); std::string finalName = ms_path + file + extension; From c829ccb87d89b209086b747ecda5a19ab78909b3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 16:10:08 -0700 Subject: [PATCH 035/848] Io: Track whether the game is on a UMD or storage. --- Core/FileSystems/BlobFileSystem.h | 2 +- Core/FileSystems/BlockDevices.h | 4 ++++ Core/FileSystems/DirectoryFileSystem.h | 2 +- Core/FileSystems/FileSystem.h | 3 +++ Core/FileSystems/ISOFileSystem.cpp | 6 ++++++ Core/FileSystems/ISOFileSystem.h | 2 +- Core/FileSystems/MetaFileSystem.h | 4 ++++ Core/FileSystems/VirtualDiscFileSystem.h | 2 +- Core/HLE/sceIo.cpp | 14 ++++---------- Core/PSPLoaders.cpp | 2 +- 10 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h index 756122468c..ded4829384 100644 --- a/Core/FileSystems/BlobFileSystem.h +++ b/Core/FileSystems/BlobFileSystem.h @@ -44,7 +44,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - FileSystemFlags Flags() override { return FileSystemFlags::NONE; } + FileSystemFlags Flags() override { return FileSystemFlags::FLASH; } bool MkDir(const std::string &dirname) override; bool RmDir(const std::string &dirname) override; diff --git a/Core/FileSystems/BlockDevices.h b/Core/FileSystems/BlockDevices.h index 6e17aaa4ea..2db068c777 100644 --- a/Core/FileSystems/BlockDevices.h +++ b/Core/FileSystems/BlockDevices.h @@ -45,6 +45,7 @@ public: } int GetBlockSize() const { return 2048;} // forced, it cannot be changed by subclasses virtual u32 GetNumBlocks() = 0; + virtual bool IsDisc() = 0; u32 CalculateCRC(); void NotifyReadError(); @@ -60,6 +61,7 @@ public: bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override; u32 GetNumBlocks() override { return numBlocks; } + bool IsDisc() override { return true; } private: FileLoader *fileLoader_; @@ -83,6 +85,7 @@ public: bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override; u32 GetNumBlocks() override {return (u32)(filesize_ / GetBlockSize());} + bool IsDisc() override { return true; } private: FileLoader *fileLoader_; @@ -107,6 +110,7 @@ public: bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override; u32 GetNumBlocks() override {return (u32)lbaSize;} + bool IsDisc() override { return false; } private: FileLoader *fileLoader_; diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index edc4b5db27..44c12b939d 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -154,7 +154,7 @@ public: int RenameFile(const std::string &from, const std::string &to) override; bool RemoveFile(const std::string &filename) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; - FileSystemFlags Flags() override { return FileSystemFlags::NONE; } + FileSystemFlags Flags() override { return FileSystemFlags::FLASH; } u64 FreeSpace(const std::string &path) override { return 0; } private: diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index a958771de9..93ad733192 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -53,6 +53,9 @@ enum DevType { enum class FileSystemFlags { NONE = 0, SIMULATE_FAT32 = 1, + UMD = 2, + CARD = 4, + FLASH = 8, }; inline FileSystemFlags operator |(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 39e54b8bb6..3a73b1a96e 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -467,6 +467,12 @@ int ISOFileSystem::DevType(u32 handle) return iter->second.isBlockSectorMode ? PSP_DEV_TYPE_BLOCK : PSP_DEV_TYPE_FILE; } +FileSystemFlags ISOFileSystem::Flags() { + // TODO: Here may be a good place to force things, in case users recompress games + // as PBP or CSO when they were originally the other type. + return blockDevice->IsDisc() ? FileSystemFlags::UMD : FileSystemFlags::CARD; +} + size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { int ignored; diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index a8a2ec7746..c2c73592d6 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -42,7 +42,7 @@ public: bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; int DevType(u32 handle) override; - FileSystemFlags Flags() override { return FileSystemFlags::NONE; } + FileSystemFlags Flags() override; u64 FreeSpace(const std::string &path) override { return 0; } size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override; diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index 37bde0d256..f348f476ab 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -56,6 +56,10 @@ public: IFileSystem *GetSystem(const std::string &prefix); IFileSystem *GetSystemFromFilename(const std::string &filename); + FileSystemFlags FlagsFromFilename(const std::string &filename) { + IFileSystem *sys = GetSystemFromFilename(filename); + return sys ? sys->Flags() : FileSystemFlags::NONE; + } void ThreadEnded(int threadID); diff --git a/Core/FileSystems/VirtualDiscFileSystem.h b/Core/FileSystems/VirtualDiscFileSystem.h index 9b676fd9ad..a2fd8be4ba 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.h +++ b/Core/FileSystems/VirtualDiscFileSystem.h @@ -41,7 +41,7 @@ public: int DevType(u32 handle) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; std::vector GetDirListing(std::string path) override; - FileSystemFlags Flags() override { return FileSystemFlags::NONE; } + FileSystemFlags Flags() override { return FileSystemFlags::UMD; } u64 FreeSpace(const std::string &path) override { return 0; } // unsupported operations diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 186b7280ec..8a56ab6a84 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -621,9 +621,9 @@ void __IoInit() { asyncNotifyEvent = CoreTiming::RegisterEvent("IoAsyncNotify", __IoAsyncNotify); syncNotifyEvent = CoreTiming::RegisterEvent("IoSyncNotify", __IoSyncNotify); - memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FileSystemFlags::SIMULATE_FAT32); + memstickSystem = new DirectoryFileSystem(&pspFileSystem, g_Config.memStickDirectory, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); #if defined(USING_WIN_UI) || defined(APPLE) - flash0System = new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory); + flash0System = new DirectoryFileSystem(&pspFileSystem, g_Config.flash0Directory, FileSystemFlags::FLASH); #else flash0System = new VFSFileSystem(&pspFileSystem, "flash0"); #endif @@ -637,7 +637,7 @@ void __IoInit() { const std::string gameId = g_paramSFO.GetValueString("DISC_ID"); const std::string exdataPath = g_Config.memStickDirectory + "exdata/" + gameId + "/"; if (File::Exists(exdataPath)) { - exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FileSystemFlags::SIMULATE_FAT32); + exdataSystem = new DirectoryFileSystem(&pspFileSystem, exdataPath, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); pspFileSystem.Mount("exdata0:", exdataSystem); INFO_LOG(SCEIO, "Mounted exdata/%s/ under memstick for exdata0:/", gameId.c_str()); } else { @@ -2287,13 +2287,7 @@ static u32 sceIoDread(int id, u32 dirent_addr) { strncpy(entry->d_name, info.name.c_str(), 256); entry->d_name[255] = '\0'; - bool isFAT = false; - IFileSystem *sys = pspFileSystem.GetSystemFromFilename(dir->name); - if (sys && (sys->Flags() & FileSystemFlags::SIMULATE_FAT32)) - isFAT = true; - else - isFAT = false; - + bool isFAT = pspFileSystem.FlagsFromFilename(dir->name) & FileSystemFlags::SIMULATE_FAT32; // Only write d_private for memory stick if (isFAT) { // write d_private for supporting Custom BGM diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 887b61b8c3..0f4732b772 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -386,7 +386,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { pspFileSystem.SetStartingDirectory(ms_path); } - DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path, FileSystemFlags::SIMULATE_FAT32); + DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path, FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD); pspFileSystem.Mount("umd0:", fs); std::string finalName = ms_path + file + extension; From 52283a50dcb6e88fcdaedbbcb54dfbda9ac5bbfa Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 16:28:05 -0700 Subject: [PATCH 036/848] Io: Improve non-async open timing. --- Core/HLE/sceIo.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 8a56ab6a84..8f630ad803 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1479,8 +1479,11 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { } else if (error == (int)SCE_KERNEL_ERROR_NODEV) { return hleLogError(SCEIO, error, "device not found"); } else if (error == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) { - // TODO: Depends on filesys. - return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", 10000), "file not found"); + // UMD: Varies between 5-10ms, could take longer if disc spins up. + // TODO: Bad filename at root (disc0:/no.exist) should take ~200us. + // Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo. + int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 6000 : 10000; + return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", delay), "file not found"); } else { return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000)); } @@ -1489,11 +1492,13 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { int id = __IoAllocFd(f); if (id < 0) { kernelObjects.Destroy(f->GetUID()); - return hleLogError(SCEIO, hleDelayResult(id, "file opened", 10000), "out of fds"); + return hleLogError(SCEIO, hleDelayResult(id, "file opened", 1000), "out of fds"); } else { asyncParams[id].priority = asyncDefaultPriority; - // TODO: Depends on filesys. Timing is not accurate, aiming low for now. - return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", 1000)); + // UMD: Speed varies from 1-6ms. + // Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo. + int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 4000 : 10000; + return hleLogSuccessI(SCEIO, hleDelayResult(id, "file opened", delay)); } } From 5e1adcdbd20e9d227544db1cb065062d1487638a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 16:34:04 -0700 Subject: [PATCH 037/848] Io: Fail without fd on bad device in OpenAsync. --- Core/HLE/sceIo.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 8f630ad803..fe6ee2e716 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -2033,8 +2033,9 @@ static u32 sceIoSetAsyncCallback(int id, u32 clbckId, u32 clbckArg) } } -static u32 sceIoOpenAsync(const char *filename, int flags, int mode) -{ +static u32 sceIoOpenAsync(const char *filename, int flags, int mode) { + hleEatCycles(18000); + // TOOD: Use an internal method so as not to pollute the log? // Intentionally does not work when interrupts disabled. if (!__KernelIsDispatchEnabled()) @@ -2046,6 +2047,9 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) // We have to return an fd here, which may have been destroyed when we reach Wait if it failed. if (f == nullptr) { assert(error != 0); + if (error == SCE_KERNEL_ERROR_NODEV) + return hleLogError(SCEIO, error, "device not found"); + f = new FileNode(); f->handle = kernelObjects.Create(f); f->fullpath = filename; @@ -2056,7 +2060,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) int fd = __IoAllocFd(f); if (fd < 0) { kernelObjects.Destroy(f->GetUID()); - return hleLogError(SCEIO, fd, "out of fds"); + return hleLogError(SCEIO, hleDelayResult(fd, "file opened", 1000), "out of fds"); } auto ¶ms = asyncParams[fd]; From 91427c1f4e83286f57583049b0dea00eb50b04de Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 16:58:19 -0700 Subject: [PATCH 038/848] Io: Account for OpenAsync timing. --- Core/HLE/sceIo.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index fe6ee2e716..eee2edc76d 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1482,6 +1482,7 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { // UMD: Varies between 5-10ms, could take longer if disc spins up. // TODO: Bad filename at root (disc0:/no.exist) should take ~200us. // Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo. + // TODO: If a UMD and spun down, this can easily take 1s+. int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 6000 : 10000; return hleLogWarning(SCEIO, hleDelayResult(error, "file opened", delay), "file not found"); } else { @@ -2709,10 +2710,15 @@ static int IoAsyncFinish(int id) { break; case IoAsyncOp::OPEN: - // TODO: Timing is very inconsistent. From ms0, 10ms - 20ms depending on filesize/dir depth? From umd, can take > 1s. - // For now let's aim low. - us = 100; + { + // See notes on timing in sceIoOpen. + FileSystemFlags flags = pspFileSystem.FlagsFromFilename(Memory::GetCharPointer(params.open.filenameAddr)); + if (f->asyncResult == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) + us = flags & FileSystemFlags::UMD ? 6000 : 10000; + else + us = flags & FileSystemFlags::UMD ? 4000 : 10000; break; + } case IoAsyncOp::CLOSE: f->asyncResult = 0; From 49abe9ed6c536d3803663948df51fbaf1cec260e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 17:57:41 -0700 Subject: [PATCH 039/848] Io: Open sce_lbn references and whole ISO faster. --- Core/FileSystems/BlobFileSystem.cpp | 4 ++-- Core/FileSystems/BlobFileSystem.h | 2 +- Core/FileSystems/DirectoryFileSystem.cpp | 8 +++---- Core/FileSystems/DirectoryFileSystem.h | 7 +++--- Core/FileSystems/FileSystem.h | 25 ++++++++++--------- Core/FileSystems/ISOFileSystem.cpp | 9 ++++--- Core/FileSystems/ISOFileSystem.h | 4 ++-- Core/FileSystems/MetaFileSystem.cpp | 4 ++-- Core/FileSystems/MetaFileSystem.h | 2 +- Core/FileSystems/VirtualDiscFileSystem.cpp | 5 ++-- Core/FileSystems/VirtualDiscFileSystem.h | 2 +- Core/HLE/sceIo.cpp | 28 ++++++++++++++++------ GPU/Common/PresentationCommon.h | 13 ++-------- UI/MainScreen.h | 9 +------ Windows/MainWindowMenu.cpp | 2 +- ext/native/base/basictypes.h | 14 +++++++++++ 16 files changed, 76 insertions(+), 62 deletions(-) diff --git a/Core/FileSystems/BlobFileSystem.cpp b/Core/FileSystems/BlobFileSystem.cpp index ceaeb9e1c7..730dca7854 100644 --- a/Core/FileSystems/BlobFileSystem.cpp +++ b/Core/FileSystems/BlobFileSystem.cpp @@ -108,8 +108,8 @@ int BlobFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 out return -1; } -int BlobFileSystem::DevType(u32 handle) { - return PSP_DEV_TYPE_FILE; +PSPDevType BlobFileSystem::DevType(u32 handle) { + return PSPDevType::FILE; } bool BlobFileSystem::MkDir(const std::string &dirname) { diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h index ded4829384..3657522ddd 100644 --- a/Core/FileSystems/BlobFileSystem.h +++ b/Core/FileSystems/BlobFileSystem.h @@ -43,7 +43,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; FileSystemFlags Flags() override { return FileSystemFlags::FLASH; } bool MkDir(const std::string &dirname) override; diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 90d623b350..4bfd6a3b43 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -663,8 +663,8 @@ int DirectoryFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u3 return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } -int DirectoryFileSystem::DevType(u32 handle) { - return PSP_DEV_TYPE_FILE; +PSPDevType DirectoryFileSystem::DevType(u32 handle) { + return PSPDevType::FILE; } size_t DirectoryFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { @@ -1121,8 +1121,8 @@ int VFSFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } -int VFSFileSystem::DevType(u32 handle) { - return PSP_DEV_TYPE_FILE; +PSPDevType VFSFileSystem::DevType(u32 handle) { + return PSPDevType::FILE; } size_t VFSFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index 44c12b939d..84e51bbf32 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -20,8 +20,7 @@ // TODO: Remove the Windows-specific code, FILE is fine there too. #include - -#include "../Core/FileSystems/FileSystem.h" +#include "Core/FileSystems/FileSystem.h" #ifdef _WIN32 typedef void * HANDLE; @@ -102,7 +101,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; bool MkDir(const std::string &dirname) override; bool RmDir(const std::string &dirname) override; @@ -147,7 +146,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; bool MkDir(const std::string &dirname) override; bool RmDir(const std::string &dirname) override; diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 93ad733192..542569071e 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -20,6 +20,7 @@ #include #include #include +#include "base/basictypes.h" #include "Core/HLE/sceKernel.h" @@ -44,11 +45,15 @@ enum FileType { FILETYPE_DIRECTORY = 2 }; -enum DevType { - PSP_DEV_TYPE_BLOCK = 0x04, - PSP_DEV_TYPE_FILE = 0x10, - PSP_DEV_TYPE_ALIAS = 0x20, +enum class PSPDevType { + INVALID = 0, + BLOCK = 0x04, + FILE = 0x10, + ALIAS = 0x20, + EMU_MASK = 0xFF, + EMU_LBN = 0x10000, }; +ENUM_CLASS_BITOPS(PSPDevType); enum class FileSystemFlags { NONE = 0, @@ -57,13 +62,7 @@ enum class FileSystemFlags { CARD = 4, FLASH = 8, }; - -inline FileSystemFlags operator |(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { - return FileSystemFlags((int)lhs | (int)rhs); -} -inline bool operator &(const FileSystemFlags &lhs, const FileSystemFlags &rhs) { - return ((int)lhs & (int)rhs) != 0; -} +ENUM_CLASS_BITOPS(FileSystemFlags); class IHandleAllocator { public: @@ -136,7 +135,7 @@ public: virtual bool RemoveFile(const std::string &filename) = 0; virtual bool GetHostPath(const std::string &inpath, std::string &outpath) = 0; virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) = 0; - virtual int DevType(u32 handle) = 0; + virtual PSPDevType DevType(u32 handle) = 0; virtual FileSystemFlags Flags() = 0; virtual u64 FreeSpace(const std::string &path) = 0; }; @@ -162,7 +161,7 @@ public: virtual bool RemoveFile(const std::string &filename) override {return false;} virtual bool GetHostPath(const std::string &inpath, std::string &outpath) override {return false;} virtual int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override {return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } - virtual int DevType(u32 handle) override { return 0; } + virtual PSPDevType DevType(u32 handle) override { return PSPDevType::INVALID; } virtual FileSystemFlags Flags() override { return FileSystemFlags::NONE; } virtual u64 FreeSpace(const std::string &path) override { return 0; } }; diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 3a73b1a96e..0e6593a71a 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -461,10 +461,12 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } -int ISOFileSystem::DevType(u32 handle) -{ +PSPDevType ISOFileSystem::DevType(u32 handle) { EntryMap::iterator iter = entries.find(handle); - return iter->second.isBlockSectorMode ? PSP_DEV_TYPE_BLOCK : PSP_DEV_TYPE_FILE; + PSPDevType type = iter->second.isBlockSectorMode ? PSPDevType::BLOCK : PSPDevType::FILE; + if (iter->second.isRawSector) + type |= PSPDevType::EMU_LBN; + return type; } FileSystemFlags ISOFileSystem::Flags() { @@ -613,6 +615,7 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) { PSPFileInfo fileInfo; fileInfo.name = filename; fileInfo.exists = true; + fileInfo.type = FILETYPE_NORMAL; fileInfo.size = readSize; fileInfo.startSector = sectorStart; fileInfo.isOnSectorSystem = true; diff --git a/Core/FileSystems/ISOFileSystem.h b/Core/FileSystems/ISOFileSystem.h index c2c73592d6..273d845301 100644 --- a/Core/FileSystems/ISOFileSystem.h +++ b/Core/FileSystems/ISOFileSystem.h @@ -41,7 +41,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; FileSystemFlags Flags() override; u64 FreeSpace(const std::string &path) override { return 0; } @@ -134,7 +134,7 @@ public: int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override { return isoFileSystem_->Ioctl(handle, cmd, indataPtr, inlen, outdataPtr, outlen, usec); } - int DevType(u32 handle) override { + PSPDevType DevType(u32 handle) override { return isoFileSystem_->DevType(handle); } FileSystemFlags Flags() override { return isoFileSystem_->Flags(); } diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 648189b52e..687dc20bd8 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -538,13 +538,13 @@ int MetaFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 out return SCE_KERNEL_ERROR_ERROR; } -int MetaFileSystem::DevType(u32 handle) +PSPDevType MetaFileSystem::DevType(u32 handle) { std::lock_guard guard(lock); IFileSystem *sys = GetHandleOwner(handle); if (sys) return sys->DevType(handle); - return SCE_KERNEL_ERROR_ERROR; + return PSPDevType::INVALID; } void MetaFileSystem::CloseFile(u32 handle) diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index f348f476ab..8294ba16da 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -118,7 +118,7 @@ public: int RenameFile(const std::string &from, const std::string &to) override; bool RemoveFile(const std::string &filename) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; FileSystemFlags Flags() override { return FileSystemFlags::NONE; } u64 FreeSpace(const std::string &path) override; diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 7ff3dc07ed..b7274ab9c0 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -552,9 +552,9 @@ int VirtualDiscFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } -int VirtualDiscFileSystem::DevType(u32 handle) { +PSPDevType VirtualDiscFileSystem::DevType(u32 handle) { EntryMap::iterator iter = entries.find(handle); - return iter->second.type == VFILETYPE_ISO ? PSP_DEV_TYPE_BLOCK : PSP_DEV_TYPE_FILE; + return iter->second.type == VFILETYPE_ISO ? PSPDevType::BLOCK : PSPDevType::FILE; } PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { @@ -569,6 +569,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { PSPFileInfo fileInfo; fileInfo.name = filename; fileInfo.exists = true; + fileInfo.type = FILETYPE_NORMAL; fileInfo.size = readSize; fileInfo.startSector = sectorStart; fileInfo.isOnSectorSystem = true; diff --git a/Core/FileSystems/VirtualDiscFileSystem.h b/Core/FileSystems/VirtualDiscFileSystem.h index a2fd8be4ba..cdf6a54ccd 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.h +++ b/Core/FileSystems/VirtualDiscFileSystem.h @@ -38,7 +38,7 @@ public: PSPFileInfo GetFileInfo(std::string filename) override; bool OwnsHandle(u32 handle) override; int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override; - int DevType(u32 handle) override; + PSPDevType DevType(u32 handle) override; bool GetHostPath(const std::string &inpath, std::string &outpath) override; std::vector GetDirListing(std::string path) override; FileSystemFlags Flags() override { return FileSystemFlags::UMD; } diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index eee2edc76d..d9a5c5ae8d 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1245,7 +1245,7 @@ static u32 sceIoWriteAsync(int id, u32 data_addr, int size) { static u32 sceIoGetDevType(int id) { if (id == PSP_STDOUT || id == PSP_STDERR || id == PSP_STDIN) { DEBUG_LOG(SCEIO, "sceIoGetDevType(%d)", id); - return PSP_DEV_TYPE_FILE; + return (u32)PSPDevType::FILE; } u32 error; @@ -1254,7 +1254,7 @@ static u32 sceIoGetDevType(int id) { if (f) { // TODO: When would this return PSP_DEV_TYPE_ALIAS? WARN_LOG(SCEIO, "sceIoGetDevType(%d - %s)", id, f->fullpath.c_str()); - result = pspFileSystem.DevType(f->handle); + result = (u32)pspFileSystem.DevType(f->handle) & (u32)PSPDevType::EMU_MASK; } else { ERROR_LOG(SCEIO, "sceIoGetDevType: unknown id %d", id); result = SCE_KERNEL_ERROR_BADF; @@ -1496,6 +1496,11 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { return hleLogError(SCEIO, hleDelayResult(id, "file opened", 1000), "out of fds"); } else { asyncParams[id].priority = asyncDefaultPriority; + IFileSystem *sys = pspFileSystem.GetSystemFromFilename(filename); + if (sys && (sys->DevType(f->handle) & (PSPDevType::BLOCK | PSPDevType::EMU_LBN))) { + // These are fast to open, no delay or even rescheduling happens. + return hleLogSuccessI(SCEIO, id); + } // UMD: Speed varies from 1-6ms. // Card: Path depth matters, but typically between 10-13ms on a standard Pro Duo. int delay = pspFileSystem.FlagsFromFilename(filename) & FileSystemFlags::UMD ? 4000 : 10000; @@ -2712,11 +2717,20 @@ static int IoAsyncFinish(int id) { case IoAsyncOp::OPEN: { // See notes on timing in sceIoOpen. - FileSystemFlags flags = pspFileSystem.FlagsFromFilename(Memory::GetCharPointer(params.open.filenameAddr)); - if (f->asyncResult == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) - us = flags & FileSystemFlags::UMD ? 6000 : 10000; - else - us = flags & FileSystemFlags::UMD ? 4000 : 10000; + const std::string filename = Memory::GetCharPointer(params.open.filenameAddr); + IFileSystem *sys = pspFileSystem.GetSystemFromFilename(filename); + if (sys) { + if (f->asyncResult == (int)SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND) { + us = sys->Flags() & FileSystemFlags::UMD ? 6000 : 10000; + } else if (sys->DevType(f->handle) & (PSPDevType::BLOCK | PSPDevType::EMU_LBN)) { + // These are fast to open, no delay or even rescheduling happens. + us = 80; + } else { + us = sys->Flags() & FileSystemFlags::UMD ? 4000 : 10000; + } + } else { + us = 80; + } break; } diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index eae2834abf..c3a695f310 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -17,6 +17,7 @@ #pragma once +#include "base/basictypes.h" #include "GPU/Common/ShaderCommon.h" struct CardboardSettings { @@ -59,17 +60,7 @@ enum class OutputFlags { BACKBUFFER_FLIPPED = 0x0004, POSITION_FLIPPED = 0x0008, }; - -inline OutputFlags operator | (const OutputFlags &lhs, const OutputFlags &rhs) { - return OutputFlags((int)lhs | (int)rhs); -} -inline OutputFlags operator |= (OutputFlags &lhs, const OutputFlags &rhs) { - lhs = lhs | rhs; - return lhs; -} -inline bool operator & (const OutputFlags &lhs, const OutputFlags &rhs) { - return ((int)lhs & (int)rhs) != 0; -} +ENUM_CLASS_BITOPS(OutputFlags); class PresentationCommon { public: diff --git a/UI/MainScreen.h b/UI/MainScreen.h index 832d104043..fe1b09ad4b 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -36,14 +36,7 @@ enum class BrowseFlags { HOMEBREW_STORE = 8, STANDARD = 1 | 2 | 4, }; - -static inline BrowseFlags operator |(const BrowseFlags &lhs, const BrowseFlags &rhs) { - return BrowseFlags((int)lhs | (int)rhs); -} - -static inline bool operator &(const BrowseFlags &lhs, const BrowseFlags &rhs) { - return ((int)lhs & (int)rhs) != 0; -} +ENUM_CLASS_BITOPS(BrowseFlags); class GameBrowser : public UI::LinearLayout { public: diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index b5e1bb0eb0..2ab276eec3 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -928,7 +928,7 @@ namespace MainWindow { u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ, ""); // Note: len may be in blocks. size_t len = pspFileSystem.SeekFile(handle, 0, FILEMOVE_END); - bool isBlockMode = pspFileSystem.DevType(handle) == PSP_DEV_TYPE_BLOCK; + bool isBlockMode = pspFileSystem.DevType(handle) & PSPDevType::BLOCK; FILE *fp = File::OpenCFile(fn, "wb"); pspFileSystem.SeekFile(handle, 0, FILEMOVE_BEGIN); diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h index 8cd0fd0e1e..2f9c7d0321 100644 --- a/ext/native/base/basictypes.h +++ b/ext/native/base/basictypes.h @@ -14,6 +14,20 @@ void operator =(const t &other) = delete; #endif +#ifndef ENUM_CLASS_BITOPS +#define ENUM_CLASS_BITOPS(T) \ + static inline T operator |(const T &lhs, const T &rhs) { \ + return T((int)lhs | (int)rhs); \ + } \ + static inline T &operator |= (T &lhs, const T &rhs) { \ + lhs = lhs | rhs; \ + return lhs; \ + } \ + static inline bool operator &(const T &lhs, const T &rhs) { \ + return ((int)lhs & (int)rhs) != 0; \ + } +#endif + #ifdef _WIN32 typedef intptr_t ssize_t; From 9b112efa0bbfe66e62470ed878e5856207512201 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 18:01:53 -0700 Subject: [PATCH 040/848] Headless: Handle umd mapping with block devices. --- Core/FileSystems/MetaFileSystem.cpp | 4 ++-- Core/PSPLoaders.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 687dc20bd8..fdd85a6245 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -258,8 +258,8 @@ std::string MetaFileSystem::NormalizePrefix(std::string prefix) const { // Let's apply some mapping here since it won't break savestates. if (prefix == "memstick:") prefix = "ms0:"; - // Seems like umd00: etc. work just fine... - if (startsWith(prefix, "umd")) + // Seems like umd00: etc. work just fine... avoid umd1/umd for tests. + if (startsWith(prefix, "umd") && prefix != "umd1:" && prefix != "umd:") prefix = "umd0:"; // Seems like umd00: etc. work just fine... if (startsWith(prefix, "host")) diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 0f4732b772..4773a670e4 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -340,10 +340,11 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { auto bd = constructBlockDevice(PSP_CoreParameter().mountIsoLoader); if (bd != NULL) { ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, bd); + ISOBlockSystem *blockSystem = new ISOBlockSystem(umd2); - pspFileSystem.Mount("umd1:", umd2); + pspFileSystem.Mount("umd1:", blockSystem); pspFileSystem.Mount("disc0:", umd2); - pspFileSystem.Mount("umd:", umd2); + pspFileSystem.Mount("umd:", blockSystem); } } From d7ad43b1d9e35cc4b6afdd5d3ebea616d1c3bb7d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 18:20:38 -0700 Subject: [PATCH 041/848] Io: Cleanup access bits for files. Also, we default a lot of these members, so don't need to reset. --- Core/FileSystems/DirectoryFileSystem.cpp | 6 +---- Core/FileSystems/FileSystem.h | 28 ++++++++++------------ Core/FileSystems/ISOFileSystem.cpp | 15 +++++------- Core/FileSystems/MetaFileSystem.cpp | 2 +- Core/FileSystems/VirtualDiscFileSystem.cpp | 11 ++++----- 5 files changed, 25 insertions(+), 37 deletions(-) diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 4bfd6a3b43..1e38103ff2 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -742,11 +742,6 @@ PSPFileInfo DirectoryFileSystem::GetFileInfo(std::string filename) { File::FileDetails details; if (!File::GetFileDetails(fullName, &details)) { ERROR_LOG(FILESYS, "DirectoryFileSystem::GetFileInfo: GetFileDetails failed: %s", fullName.c_str()); - x.size = 0; - x.access = 0; - memset(&x.atime, 0, sizeof(x.atime)); - memset(&x.ctime, 0, sizeof(x.ctime)); - memset(&x.mtime, 0, sizeof(x.mtime)); } else { x.size = details.size; x.access = details.access; @@ -1094,6 +1089,7 @@ PSPFileInfo VFSFileSystem::GetFileInfo(std::string filename) { if (x.exists) { x.size = fo.size; x.type = fo.isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; + x.access = fo.isWritable ? 0666 : 0444; } } else { x.exists = false; diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 542569071e..6c069efe0d 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -88,29 +88,25 @@ private: }; struct PSPFileInfo { - PSPFileInfo() - : size(0), access(0), exists(false), type(FILETYPE_NORMAL), isOnSectorSystem(false), startSector(0), numSectors(0), sectorSize(0) { - memset(&ctime, 0, sizeof(ctime)); - memset(&atime, 0, sizeof(atime)); - memset(&mtime, 0, sizeof(mtime)); + PSPFileInfo() { } void DoState(PointerWrap &p); std::string name; - s64 size; - u32 access; //unix 777 - bool exists; - FileType type; + s64 size = 0; + u32 access = 0; //unix 777 + bool exists = false; + FileType type = FILETYPE_NORMAL; - tm atime; - tm ctime; - tm mtime; + tm atime{}; + tm ctime{}; + tm mtime{}; - bool isOnSectorSystem; - u32 startSector; - u32 numSectors; - u32 sectorSize; + bool isOnSectorSystem = false; + u32 startSector = 0; + u32 numSectors = 0; + u32 sectorSize = 0; }; diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 0e6593a71a..3f481a2f9b 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -617,6 +617,7 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) { fileInfo.exists = true; fileInfo.type = FILETYPE_NORMAL; fileInfo.size = readSize; + fileInfo.access = 0444; fileInfo.startSector = sectorStart; fileInfo.isOnSectorSystem = true; fileInfo.numSectors = (readSize + sectorSize - 1) / sectorSize; @@ -625,12 +626,10 @@ PSPFileInfo ISOFileSystem::GetFileInfo(std::string filename) { TreeEntry *entry = GetFromPath(filename, false); PSPFileInfo x; - if (!entry) { - x.size = 0; - x.exists = false; - } else { + if (entry) { x.name = entry->name; - x.access = FILEACCESS_READ; + // Strangely, it seems to be executable even for files. + x.access = 0555; x.size = entry->size; x.exists = true; x.type = entry->isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; @@ -658,16 +657,14 @@ std::vector ISOFileSystem::GetDirListing(std::string path) { PSPFileInfo x; x.name = e->name; - x.access = FILEACCESS_READ; + // Strangely, it seems to be executable even for files. + x.access = 0555; x.size = e->size; x.type = e->isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; x.isOnSectorSystem = true; x.startSector = e->startingPosition/2048; x.sectorSize = sectorSize; x.numSectors = (u32)((e->size + sectorSize - 1) / sectorSize); - memset(&x.atime, 0, sizeof(x.atime)); - memset(&x.mtime, 0, sizeof(x.mtime)); - memset(&x.ctime, 0, sizeof(x.ctime)); myVector.push_back(x); } return myVector; diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index fdd85a6245..3b6d487e9f 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -370,7 +370,7 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) } else { - PSPFileInfo bogus; // TODO + PSPFileInfo bogus; return bogus; } } diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index b7274ab9c0..452b1b018e 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -571,6 +571,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { fileInfo.exists = true; fileInfo.type = FILETYPE_NORMAL; fileInfo.size = readSize; + fileInfo.access = 0444; fileInfo.startSector = sectorStart; fileInfo.isOnSectorSystem = true; fileInfo.numSectors = (readSize + 2047) / 2048; @@ -582,6 +583,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { x.type = FILETYPE_NORMAL; x.isOnSectorSystem = true; x.startSector = fileList[fileIndex].firstBlock; + x.access = 0555; HandlerFileHandle temp = fileList[fileIndex].handler; if (temp.Open(basePath, filename, FILEACCESS_READ)) { @@ -610,6 +612,7 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { x.type = File::IsDirectory(fullName) ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; x.exists = true; + x.access = 0555; if (fileIndex != -1) { x.isOnSectorSystem = true; x.startSector = fileList[fileIndex].firstBlock; @@ -621,12 +624,8 @@ PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { ERROR_LOG(FILESYS, "DirectoryFileSystem::GetFileInfo: GetFileDetails failed: %s", fullName.c_str()); x.size = 0; x.access = 0; - memset(&x.atime, 0, sizeof(x.atime)); - memset(&x.ctime, 0, sizeof(x.ctime)); - memset(&x.mtime, 0, sizeof(x.mtime)); } else { x.size = details.size; - x.access = details.access; time_t atime = details.atime; time_t ctime = details.ctime; time_t mtime = details.mtime; @@ -691,7 +690,7 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) entry.type = FILETYPE_NORMAL; } - entry.access = FILEACCESS_READ; + entry.access = 0555; entry.size = findData.nFileSizeLow | ((u64)findData.nFileSizeHigh<<32); entry.name = ConvertWStringToUTF8(findData.cFileName); tmFromFiletime(entry.atime, findData.ftLastAccessTime); @@ -737,7 +736,7 @@ std::vector VirtualDiscFileSystem::GetDirListing(std::string path) entry.type = FILETYPE_DIRECTORY; else entry.type = FILETYPE_NORMAL; - entry.access = s.st_mode & 0x1FF; + entry.access = 0555; entry.name = dirp->d_name; entry.size = s.st_size; localtime_r((time_t*)&s.st_atime,&entry.atime); From 5507116d3f87d7c9d666e7bcaea93334b71d0177 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 22:16:13 -0700 Subject: [PATCH 042/848] Ge: Check stack depth based on args struct size. Matches tests against firmware. --- Core/HLE/sceGe.cpp | 14 ++++++-------- GPU/GPUCommon.cpp | 13 ++++++------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index dafa5d09b1..1af22c00de 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -340,10 +340,9 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId, u32 optP if ((int)listID >= 0) listID = LIST_ID_MAGIC ^ listID; - DEBUG_LOG(SCEGE, "List %i enqueued.", listID); hleEatCycles(490); CoreTiming::ForceCheck(); - return listID; + return hleLogSuccessX(SCEGE, listID); } u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr) { @@ -353,13 +352,12 @@ u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, u32 auto optParam = PSPPointer::Create(optParamAddr); u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, true); - if ((int)listID >= 0) { + if ((int)listID >= 0) listID = LIST_ID_MAGIC ^ listID; - DEBUG_LOG(SCEGE, "List %i enqueued at head.", listID); - } + hleEatCycles(480); CoreTiming::ForceCheck(); - return listID; + return hleLogSuccessX(SCEGE, listID); } static int sceGeListDeQueue(u32 listID) { @@ -594,8 +592,8 @@ static u32 sceGeEdramSetAddrTranslation(int new_size) { const HLEFunction sceGe_user[] = { {0XE47E40E4, &WrapU_V, "sceGeEdramGetAddr", 'x', "" }, - {0XAB49E76A, &WrapU_UUIU, "sceGeListEnQueue", 'x', "xxix"}, - {0X1C0D95A6, &WrapU_UUIU, "sceGeListEnQueueHead", 'x', "xxix"}, + {0XAB49E76A, &WrapU_UUIU, "sceGeListEnQueue", 'x', "xxip"}, + {0X1C0D95A6, &WrapU_UUIU, "sceGeListEnQueueHead", 'x', "xxip"}, {0XE0D68148, &WrapI_UU, "sceGeListUpdateStallAddr", 'i', "xx" }, {0X03444EB4, &WrapI_UU, "sceGeListSync", 'i', "xx" }, {0XB287BD61, &WrapU_U, "sceGeDrawSync", 'x', "x" }, diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index e1f64afb81..7d05933ca5 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -679,17 +679,16 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointersize is below 16, it's the old struct without stack info. + if (args.IsValid() && args->size >= 16 && args->numStacks >= 256) { + return hleLogError(G3D, SCE_KERNEL_ERROR_INVALID_SIZE, "invalid stack depth %d", args->numStacks); + } + int id = -1; u64 currentTicks = CoreTiming::GetTicks(); - u32_le stackAddr = args.IsValid() ? args->stackAddr : 0; + u32_le stackAddr = args.IsValid() && args->size >= 16 ? args->stackAddr : 0; // Check compatibility if (sceKernelGetCompiledSdkVersion() > 0x01FFFFFF) { - // See #12908. - if (args.IsValid() && args->numStacks >= 256) { - ERROR_LOG(G3D, "sceGeListEnqueue: invalid size %08x", args->numStacks); - return SCE_KERNEL_ERROR_INVALID_SIZE; - } - //numStacks = 0; //stack = NULL; for (int i = 0; i < DisplayListMaxCount; ++i) { From cd90fb4d69da4fc68288a1659cbb2a063b82d755 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 23:37:27 -0700 Subject: [PATCH 043/848] Windows: Avoid crash for a mono output format. Let's just assume we're only going to get stereo formats. --- Windows/WASAPIStream.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Windows/WASAPIStream.cpp b/Windows/WASAPIStream.cpp index 3b04029bf8..2cee2d1afc 100644 --- a/Windows/WASAPIStream.cpp +++ b/Windows/WASAPIStream.cpp @@ -384,14 +384,14 @@ void WASAPIAudioThread::Run() { if (FAILED(hresult) || pData == nullptr) { // What to do? } else if (pNumAvFrames) { + int chans = deviceFormat_->Format.nChannels; switch (format_) { case Format::IEEE_FLOAT: - callback_(shortBuf_, pNumAvFrames, 16, sampleRate_, 2); - if (deviceFormat_->Format.nChannels == 2) { - ConvertS16ToF32((float *)pData, shortBuf_, pNumAvFrames * deviceFormat_->Format.nChannels); - } else { + callback_(shortBuf_, pNumAvFrames, 16, sampleRate_, chans); + if (chans == 2) { + ConvertS16ToF32((float *)pData, shortBuf_, pNumAvFrames * chans); + } else if (chans > 2) { float *ptr = (float *)pData; - int chans = deviceFormat_->Format.nChannels; memset(ptr, 0, pNumAvFrames * chans * sizeof(float)); for (UINT32 i = 0; i < pNumAvFrames; i++) { ptr[i * chans + 0] = (float)shortBuf_[i * 2] * (1.0f / 32768.0f); @@ -400,7 +400,7 @@ void WASAPIAudioThread::Run() { } break; case Format::PCM16: - callback_((short *)pData, pNumAvFrames, 16, sampleRate_, 2); + callback_((short *)pData, pNumAvFrames, 16, sampleRate_, chans); break; } } From 9d1e31f6a0fb8ad57532bea3645d25152e86f9ff Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 21 May 2020 23:39:29 -0700 Subject: [PATCH 044/848] Windows: Avoid WASAPI init for a bad format. --- Windows/WASAPIStream.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Windows/WASAPIStream.cpp b/Windows/WASAPIStream.cpp index 2cee2d1afc..ae43ce953b 100644 --- a/Windows/WASAPIStream.cpp +++ b/Windows/WASAPIStream.cpp @@ -196,6 +196,7 @@ private: bool InitAudioDevice(); void ShutdownAudioDevice(); bool DetectFormat(); + bool PrepareFormat(); std::atomic &threadData_; int &sampleRate_; @@ -252,6 +253,11 @@ bool WASAPIAudioThread::InitAudioDevice() { if (FAILED(hresult) || !deviceFormat_) return false; + if (!DetectFormat()) { + // Format unsupported - let's not even try to initialize. + return false; + } + hresult = audioInterface_->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, hnsBufferDuration, 0, &deviceFormat_->Format, nullptr); if (FAILED(hresult)) return false; @@ -285,7 +291,8 @@ bool WASAPIAudioThread::DetectFormat() { if (deviceFormat_->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) { if (!memcmp(&deviceFormat_->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(deviceFormat_->SubFormat))) { - format_ = Format::IEEE_FLOAT; + if (deviceFormat_->Format.nChannels >= 2) + format_ = Format::IEEE_FLOAT; } else { ERROR_LOG_REPORT_ONCE(unexpectedformat, SCEAUDIO, "Got unexpected WASAPI 0xFFFE stream format, expected float!"); if (deviceFormat_->Format.wBitsPerSample == 16 && deviceFormat_->Format.nChannels == 2) { @@ -293,7 +300,8 @@ bool WASAPIAudioThread::DetectFormat() { } } } else if (deviceFormat_->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { - format_ = Format::IEEE_FLOAT; + if (deviceFormat_->Format.nChannels >= 2) + format_ = Format::IEEE_FLOAT; } else { ERROR_LOG_REPORT_ONCE(unexpectedformat2, SCEAUDIO, "Got unexpected non-extensible WASAPI stream format, expected extensible float!"); if (deviceFormat_->Format.wBitsPerSample == 16 && deviceFormat_->Format.nChannels == 2) { @@ -301,11 +309,12 @@ bool WASAPIAudioThread::DetectFormat() { } } + return format_ != Format::UNKNOWN; +} + +bool WASAPIAudioThread::PrepareFormat() { delete [] shortBuf_; shortBuf_ = nullptr; - if (format_ == Format::UNKNOWN) { - return false; - } BYTE *pData = nullptr; HRESULT hresult = renderClient_->GetBuffer(numBufferFrames, &pData); @@ -356,7 +365,7 @@ void WASAPIAudioThread::Run() { ERROR_LOG(SCEAUDIO, "WASAPI: Could not init audio device"); return; } - if (!DetectFormat()) { + if (!PrepareFormat()) { ERROR_LOG(SCEAUDIO, "WASAPI: Could not find a suitable audio output format"); return; } @@ -430,7 +439,7 @@ void WASAPIAudioThread::Run() { ERROR_LOG(SCEAUDIO, "WASAPI: Could not init audio device"); return; } - if (!DetectFormat()) { + if (!PrepareFormat()) { ERROR_LOG(SCEAUDIO, "WASAPI: Could not find a suitable audio output format"); return; } From 0f1f3507f68adb42d0710cbbc079a139ab7ced10 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 22 May 2020 00:19:16 -0700 Subject: [PATCH 045/848] Windows: Ask for a specific device on failure. In case the new rules make things fail unexpectedly. --- Windows/WASAPIStream.cpp | 70 +++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/Windows/WASAPIStream.cpp b/Windows/WASAPIStream.cpp index ae43ce953b..d399781c46 100644 --- a/Windows/WASAPIStream.cpp +++ b/Windows/WASAPIStream.cpp @@ -35,8 +35,7 @@ public: } ~CMMNotificationClient() { - if (currentDevice_) - CoTaskMemFree(currentDevice_); + CoTaskMemFree(currentDevice_); currentDevice_ = nullptr; SAFE_RELEASE(_pEnumerator) } @@ -44,8 +43,8 @@ public: void SetCurrentDevice(IMMDevice *device) { std::lock_guard guard(lock_); - if (currentDevice_) - CoTaskMemFree(currentDevice_); + CoTaskMemFree(currentDevice_); + currentDevice_ = nullptr; if (!device || FAILED(device->GetId(¤tDevice_))) { currentDevice_ = nullptr; } @@ -196,6 +195,7 @@ private: bool InitAudioDevice(); void ShutdownAudioDevice(); bool DetectFormat(); + bool ValidateFormat(const WAVEFORMATEXTENSIBLE *fmt); bool PrepareFormat(); std::atomic &threadData_; @@ -285,26 +285,74 @@ void WASAPIAudioThread::ShutdownAudioDevice() { } bool WASAPIAudioThread::DetectFormat() { + if (!ValidateFormat(deviceFormat_)) { + // Last chance, let's try to ask for one we support instead. + WAVEFORMATEXTENSIBLE fmt{}; + fmt.Format.cbSize = sizeof(fmt); + fmt.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + fmt.Format.nChannels = 2; + fmt.Format.nSamplesPerSec = 44100; + if (deviceFormat_->Format.nSamplesPerSec >= 22050 && deviceFormat_->Format.nSamplesPerSec <= 192000) + fmt.Format.nSamplesPerSec = deviceFormat_->Format.nSamplesPerSec; + fmt.Format.nBlockAlign = 2 * sizeof(float); + fmt.Format.nAvgBytesPerSec = fmt.Format.nSamplesPerSec * fmt.Format.nBlockAlign; + fmt.Format.wBitsPerSample = sizeof(float) * 8; + fmt.Samples.wReserved = 0; + fmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; + fmt.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; + + WAVEFORMATEXTENSIBLE *closest = nullptr; + HRESULT hr = audioInterface_->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &fmt.Format, (WAVEFORMATEX **)&closest); + if (hr == S_OK) { + // Okay, great. Let's just use ours. + CoTaskMemFree(closest); + CoTaskMemFree(deviceFormat_); + deviceFormat_ = (WAVEFORMATEXTENSIBLE *)CoTaskMemAlloc(sizeof(fmt)); + memcpy(deviceFormat_, &fmt, sizeof(fmt)); + + // In case something above gets out of date. + return ValidateFormat(deviceFormat_); + } else if (hr == S_FALSE && closest != nullptr) { + // This means check closest. We'll allow it only if it's less specific on channels. + if (ValidateFormat(closest)) { + CoTaskMemFree(deviceFormat_); + deviceFormat_ = closest; + } else { + ERROR_LOG_REPORT_ONCE(badfallbackclosest, SCEAUDIO, "WASAPI fallback and closest unsupported"); + CoTaskMemFree(closest); + return false; + } + } else { + CoTaskMemFree(closest); + ERROR_LOG_REPORT_ONCE(badfallback, SCEAUDIO, "WASAPI fallback format was unsupported"); + return false; + } + } + + return true; +} + +bool WASAPIAudioThread::ValidateFormat(const WAVEFORMATEXTENSIBLE *fmt) { // Don't know if PCM16 ever shows up here, the documentation only talks about float... but let's blindly // try to support it :P format_ = Format::UNKNOWN; - if (deviceFormat_->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - if (!memcmp(&deviceFormat_->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(deviceFormat_->SubFormat))) { - if (deviceFormat_->Format.nChannels >= 2) + if (fmt->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) { + if (!memcmp(&fmt->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(fmt->SubFormat))) { + if (fmt->Format.nChannels >= 2) format_ = Format::IEEE_FLOAT; } else { ERROR_LOG_REPORT_ONCE(unexpectedformat, SCEAUDIO, "Got unexpected WASAPI 0xFFFE stream format, expected float!"); - if (deviceFormat_->Format.wBitsPerSample == 16 && deviceFormat_->Format.nChannels == 2) { + if (fmt->Format.wBitsPerSample == 16 && fmt->Format.nChannels == 2) { format_ = Format::PCM16; } } - } else if (deviceFormat_->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { - if (deviceFormat_->Format.nChannels >= 2) + } else if (fmt->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { + if (fmt->Format.nChannels >= 2) format_ = Format::IEEE_FLOAT; } else { ERROR_LOG_REPORT_ONCE(unexpectedformat2, SCEAUDIO, "Got unexpected non-extensible WASAPI stream format, expected extensible float!"); - if (deviceFormat_->Format.wBitsPerSample == 16 && deviceFormat_->Format.nChannels == 2) { + if (fmt->Format.wBitsPerSample == 16 && fmt->Format.nChannels == 2) { format_ = Format::PCM16; } } From 4bd60ed791c21b00d0da5596ba04cc399b1d28dc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 22 May 2020 00:31:17 -0700 Subject: [PATCH 046/848] Io: Fix LBN timing for virtual discs. --- Core/FileSystems/VirtualDiscFileSystem.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 452b1b018e..81ecbeef57 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -554,7 +554,10 @@ int VirtualDiscFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, PSPDevType VirtualDiscFileSystem::DevType(u32 handle) { EntryMap::iterator iter = entries.find(handle); - return iter->second.type == VFILETYPE_ISO ? PSPDevType::BLOCK : PSPDevType::FILE; + PSPDevType type = iter->second.type == VFILETYPE_ISO ? PSPDevType::BLOCK : PSPDevType::FILE; + if (iter->second.type == VFILETYPE_LBN) + type |= PSPDevType::EMU_LBN; + return type; } PSPFileInfo VirtualDiscFileSystem::GetFileInfo(std::string filename) { From 5c552771fcfbe459fa304239fa20e76b7a5759e1 Mon Sep 17 00:00:00 2001 From: Florin9doi Date: Fri, 22 May 2020 15:45:59 +0300 Subject: [PATCH 047/848] [Camera/V4L] Add support for jpeg and multiple buffers required for Sony EyeToy --- Core/HW/Camera.cpp | 81 +++++++++++++++++++++++++--------------------- Core/HW/Camera.h | 9 ++++-- 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/Core/HW/Camera.cpp b/Core/HW/Camera.cpp index 75c1a74eb8..48d5210432 100644 --- a/Core/HW/Camera.cpp +++ b/Core/HW/Camera.cpp @@ -242,15 +242,16 @@ void *v4l_loop(void *data) { int jpegLen = 0; if (v4l_format == V4L2_PIX_FMT_YUYV) { - convert_frame(v4l_hw_width, v4l_hw_height, (unsigned char*)v4l_buffer, AV_PIX_FMT_YUYV422, + convert_frame(v4l_hw_width, v4l_hw_height, (unsigned char*)v4l_buffers[buf.index].start, AV_PIX_FMT_YUYV422, v4l_ideal_width, v4l_ideal_height, &jpegData, &jpegLen); - } else if (v4l_format == V4L2_PIX_FMT_MJPEG) { + } else if (v4l_format == V4L2_PIX_FMT_JPEG + || v4l_format == V4L2_PIX_FMT_MJPEG) { // decompress jpeg int width, height, req_comps; unsigned char *rgbData = jpgd::decompress_jpeg_image_from_memory( - (unsigned char*)v4l_buffer, buf.bytesused, &width, &height, &req_comps, 3); + (unsigned char*)v4l_buffers[buf.index].start, buf.bytesused, &width, &height, &req_comps, 3); - convert_frame(v4l_hw_width, v4l_hw_height, (unsigned char*)v4l_buffer, AV_PIX_FMT_RGB24, + convert_frame(v4l_hw_width, v4l_hw_height, (unsigned char*)rgbData, AV_PIX_FMT_RGB24, v4l_ideal_width, v4l_ideal_height, &jpegData, &jpegLen); free(rgbData); } @@ -318,7 +319,8 @@ int __v4l_startCapture(int ideal_width, int ideal_height) { if (fmt.fmt.pix.pixelformat != 0) { continue; } else if (desc.pixelformat == V4L2_PIX_FMT_YUYV - || desc.pixelformat == V4L2_PIX_FMT_MJPEG) { + || desc.pixelformat == V4L2_PIX_FMT_JPEG + || desc.pixelformat == V4L2_PIX_FMT_MJPEG) { INFO_LOG(HLE, "V4L2: %s selected", desc.description); fmt.fmt.pix.pixelformat = desc.pixelformat; v4l_format = desc.pixelformat; @@ -373,38 +375,43 @@ int __v4l_startCapture(int ideal_width, int ideal_height) { ERROR_LOG(HLE, "VIDIOC_REQBUFS"); return -1; } + v4l_buffer_count = req.count; + INFO_LOG(HLE, "V4L2: buffer count: %d", v4l_buffer_count); + v4l_buffers = (v4l_buf_t*) calloc(v4l_buffer_count, sizeof(v4l_buf_t)); - struct v4l2_buffer buf; - memset(&buf, 0, sizeof(buf)); - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = 0; - if (ioctl(v4l_fd, VIDIOC_QUERYBUF, &buf) == -1) { - ERROR_LOG(HLE, "VIDIOC_QUERYBUF"); - return -1; + for (int buf_id = 0; buf_id < v4l_buffer_count; buf_id++) { + struct v4l2_buffer buf; + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = buf_id; + if (ioctl(v4l_fd, VIDIOC_QUERYBUF, &buf) == -1) { + ERROR_LOG(HLE, "VIDIOC_QUERYBUF"); + return -1; + } + + v4l_buffers[buf_id].length = buf.length; + v4l_buffers[buf_id].start = mmap(NULL, + buf.length, + PROT_READ | PROT_WRITE, + MAP_SHARED, + v4l_fd, buf.m.offset); + if (v4l_buffers[buf_id].start == MAP_FAILED) { + ERROR_LOG(HLE, "MAP_FAILED"); + return -1; + } + + memset(&buf, 0, sizeof(buf)); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = buf_id; + if (ioctl(v4l_fd, VIDIOC_QBUF, &buf) == -1) { + ERROR_LOG(HLE, "VIDIOC_QBUF"); + return -1; + } } - v4l_length = buf.length; - v4l_buffer = mmap(NULL, - v4l_length, - PROT_READ | PROT_WRITE, - MAP_SHARED, - v4l_fd, buf.m.offset); - if (v4l_buffer == MAP_FAILED) { - ERROR_LOG(HLE, "MAP_FAILED"); - return -1; - } - - memset(&buf, 0, sizeof(buf)); enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.type = type; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = 0; - if (ioctl(v4l_fd, VIDIOC_QBUF, &buf) == -1) { - ERROR_LOG(HLE, "VIDIOC_QBUF"); - return -1; - } - if (ioctl(v4l_fd, VIDIOC_STREAMON, &type) == -1) { ERROR_LOG(HLE, "VIDIOC_STREAMON"); return -1; @@ -427,9 +434,11 @@ int __v4l_stopCapture() { goto exit; } - if (munmap(v4l_buffer, v4l_length) == -1) { - ERROR_LOG(HLE, "munmap"); - goto exit; + for (int buf_id = 0; buf_id < v4l_buffer_count; buf_id++) { + if (munmap(v4l_buffers[buf_id].start, v4l_buffers[buf_id].length) == -1) { + ERROR_LOG(HLE, "munmap"); + goto exit; + } } if (close(v4l_fd) == -1) { diff --git a/Core/HW/Camera.h b/Core/HW/Camera.h index 9308e1e732..fbc691bf64 100644 --- a/Core/HW/Camera.h +++ b/Core/HW/Camera.h @@ -60,6 +60,11 @@ void __cameraDummyImage(int width, int height, unsigned char** outData, int* out #include "thread/threadutil.h" + typedef struct { + void *start; + int length; + } v4l_buf_t; + static int v4l_fd = -1; static uint32_t v4l_format; static int v4l_hw_width; @@ -69,8 +74,8 @@ void __cameraDummyImage(int width, int height, unsigned char** outData, int* out static int v4l_ideal_height; static pthread_t v4l_thread; - static void *v4l_buffer; - static int v4l_length; + static int v4l_buffer_count; + static v4l_buf_t *v4l_buffers; std::vector __v4l_getDeviceList(); int __v4l_startCapture(int width, int height); From 3a1bc6a86b1da72fd9b21a58037b7ef526909b58 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 00:12:22 -0700 Subject: [PATCH 048/848] GPU: Never set safe size larger than the buffer. Maybe this indicates the buffer size is wrong, but a safe size larger than the buffer will make us try to download outside the buffer and lose the Vulkan device. --- GPU/Common/FramebufferCommon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index a14209c6c3..07f16b1bf0 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -1686,8 +1686,8 @@ void FramebufferManagerCommon::SetRenderSize(VirtualFramebuffer *vfb) { void FramebufferManagerCommon::SetSafeSize(u16 w, u16 h) { VirtualFramebuffer *vfb = currentRenderVfb_; if (vfb) { - vfb->safeWidth = std::max(vfb->safeWidth, w); - vfb->safeHeight = std::max(vfb->safeHeight, h); + vfb->safeWidth = std::min(vfb->bufferWidth, std::max(vfb->safeWidth, w)); + vfb->safeHeight = std::min(vfb->bufferHeight, std::max(vfb->safeHeight, h)); } } From ea1f0a11957dde78c0988b8ef1dea30c408a9550 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 00:25:39 -0700 Subject: [PATCH 049/848] Vulkan: Match safe size behavior on all backends. Before, we would not mark a safe size for some Vulkan clears where depth was not cleared, deviating from other backends. We also never detected that on PowerVR. This makes things more consistent. --- GPU/Common/SoftwareTransformCommon.cpp | 9 +++++++-- GPU/Common/SoftwareTransformCommon.h | 4 ++++ GPU/D3D11/DrawEngineD3D11.cpp | 8 +++++--- GPU/Directx9/DrawEngineDX9.cpp | 8 +++++--- GPU/GLES/DrawEngineGLES.cpp | 8 ++++---- GPU/Vulkan/DrawEngineVulkan.cpp | 13 +++++++------ 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index e87d5a940a..09077acd9a 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -441,12 +441,17 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt // TODO: This bleeds outside the play area in non-buffered mode. Big deal? Probably not. // TODO: Allow creating a depth clear and a color draw. bool reallyAClear = false; - if (maxIndex > 1 && prim == GE_PRIM_RECTANGLES && gstate.isModeClear() && params_.allowClear) { + if (maxIndex > 1 && prim == GE_PRIM_RECTANGLES && gstate.isModeClear()) { int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; reallyAClear = IsReallyAClear(transformed, maxIndex, scissorX2, scissorY2); + if (reallyAClear) { + result->setSafeSize = true; + result->safeWidth = scissorX2; + result->safeHeight = scissorY2; + } } - if (reallyAClear && gl_extensions.gpuVendor != GPU_VENDOR_IMGTEC) { + if (params_.allowClear && reallyAClear && gl_extensions.gpuVendor != GPU_VENDOR_IMGTEC) { // 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(); diff --git a/GPU/Common/SoftwareTransformCommon.h b/GPU/Common/SoftwareTransformCommon.h index c93e12b58d..98250afbea 100644 --- a/GPU/Common/SoftwareTransformCommon.h +++ b/GPU/Common/SoftwareTransformCommon.h @@ -38,6 +38,10 @@ struct SoftwareTransformResult { bool setStencil; u8 stencilValue; + bool setSafeSize; + u32 safeWidth; + u32 safeHeight; + TransformedVertex *drawBuffer; int drawNumTrans; bool drawIndexed; diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index fde2dd0102..109935aa1d 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -590,6 +590,9 @@ rotateVBO: swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, maxIndex, &result); } + if (result.setSafeSize) + framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight); + if (result.action == SW_DRAW_PRIMITIVES) { const int vertexSize = sizeof(transformed[0]); @@ -653,12 +656,11 @@ rotateVBO: uint8_t clearStencil = clearColor >> 24; draw_->Clear(clearFlag, clearColor, clearDepth, clearStencil); - int scissorX2 = gstate.getScissorX2() + 1; - int scissorY2 = gstate.getScissorY2() + 1; - framebufferManager_->SetSafeSize(scissorX2, scissorY2); if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } } diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index a39d48f986..f447a8f153 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -550,6 +550,9 @@ rotateVBO: swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, maxIndex, &result); } + if (result.setSafeSize) + framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight); + ApplyDrawStateLate(); vshader = shaderManager_->ApplyShader(false, false, lastVType_); @@ -588,12 +591,11 @@ rotateVBO: dxstate.colorMask.set((mask & D3DCLEAR_TARGET) != 0, (mask & D3DCLEAR_TARGET) != 0, (mask & D3DCLEAR_TARGET) != 0, (mask & D3DCLEAR_STENCIL) != 0); device_->Clear(0, NULL, mask, SwapRB(clearColor), clearDepth, clearColor >> 24); - int scissorX2 = gstate.getScissorX2() + 1; - int scissorY2 = gstate.getScissorY2() + 1; - framebufferManager_->SetSafeSize(scissorX2, scissorY2); if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } } diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index ca32d8e508..107b68640e 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -573,6 +573,8 @@ rotateVBO: if (result.action == SW_NOT_READY) swTransform.BuildDrawingParams(prim, vertexCount, dec_->VertexType(), inds, maxIndex, &result); + if (result.setSafeSize) + framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight); ApplyDrawStateLate(result.setStencil, result.stencilValue); @@ -612,16 +614,14 @@ rotateVBO: if (alphaMask) target |= GL_STENCIL_BUFFER_BIT; if (depthMask) target |= GL_DEPTH_BUFFER_BIT; - int scissorX2 = gstate.getScissorX2() + 1; - int scissorY2 = gstate.getScissorY2() + 1; - render_->Clear(clearColor, clearDepth, clearColor >> 24, target, rgbaMask, vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH); framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); - framebufferManager_->SetSafeSize(scissorX2, scissorY2); if ((gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate.FrameBufFormat() == GE_FORMAT_565)) { int scissorX1 = gstate.getScissorX1(); int scissorY1 = gstate.getScissorY1(); + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } gstate_c.Dirty(DIRTY_BLEND_STATE); // Make sure the color mask gets re-applied. diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 62305dd14a..2a5b0401b0 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -910,6 +910,9 @@ void DrawEngineVulkan::DoFlush() { swTransform.BuildDrawingParams(prim, indexGen.VertexCount(), dec_->VertexType(), inds, maxIndex, &result); } + if (result.setSafeSize) + framebufferManager_->SetSafeSize(result.safeWidth, result.safeHeight); + // Only here, where we know whether to clear or to draw primitives, should we actually set the current framebuffer! Because that gives use the opportunity // to use a "pre-clear" render pass, for high efficiency on tilers. if (result.action == SW_DRAW_PRIMITIVES) { @@ -983,13 +986,11 @@ void DrawEngineVulkan::DoFlush() { // If non-buffered though, it'll just do a plain clear. framebufferManager_->NotifyClear(gstate.isClearModeColorMask(), gstate.isClearModeAlphaMask(), gstate.isClearModeDepthMask(), result.color, result.depth); - int scissorX1 = gstate.getScissorX1(); - int scissorY1 = gstate.getScissorY1(); - int scissorX2 = gstate.getScissorX2() + 1; - int scissorY2 = gstate.getScissorY2() + 1; - framebufferManager_->SetSafeSize(scissorX2, scissorY2); - if (gstate_c.Supports(GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { + int scissorX1 = gstate.getScissorX1(); + int scissorY1 = gstate.getScissorY1(); + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, result.color); } } From 1432cc94314ac9b39b0abb33b42736d00f37bdac Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 00:54:22 -0700 Subject: [PATCH 050/848] GPU: Try a bit harder to determine safe size. --- GPU/Common/SoftwareTransformCommon.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 09077acd9a..2c14865a6b 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -445,7 +445,7 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; reallyAClear = IsReallyAClear(transformed, maxIndex, scissorX2, scissorY2); - if (reallyAClear) { + if (reallyAClear && gstate.getColorMask() != 0 && gstate.getClearModeColorMask() != 0) { result->setSafeSize = true; result->safeWidth = scissorX2; result->safeHeight = scissorY2; @@ -466,6 +466,22 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt return; } } + + // Detect full screen "clears" that might not be so obvious, to set the safe size if possible. + if (!result->setSafeSize && prim == GE_PRIM_RECTANGLES && maxIndex == 2) { + bool clearingColor = gstate.isModeClear() && gstate.getClearModeColorMask() != 0; + bool writingColor = gstate.getColorMask() != 0; + bool startsZeroX = transformed[0].x <= 0.0f && transformed[1].x > transformed[0].x; + bool startsZeroY = transformed[0].y <= 0.0f && transformed[1].y > transformed[0].y; + + if (startsZeroX && startsZeroY && (clearingColor || writingColor)) { + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; + result->setSafeSize = true; + result->safeWidth = std::min(scissorX2, (int)transformed[1].x); + result->safeHeight = std::min(scissorY2, (int)transformed[1].y); + } + } } // Also, this assumes SetTexture() has already figured out the actual texture height. From 0ff922c3e0bac41c76c9ebf65c6d4721f9e9b42d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 08:29:21 -0700 Subject: [PATCH 051/848] Android: Buildfix. Not sure why the linker is having trouble with VulkanDebug.cpp. --- Common/Vulkan/VulkanContext.cpp | 33 +++++++++++++++++++++++++++++++++ Common/Vulkan/VulkanContext.h | 1 + Common/Vulkan/VulkanDebug.cpp | 33 --------------------------------- Common/Vulkan/VulkanDebug.h | 2 -- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index b901388a1c..12a457e481 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -1443,3 +1443,36 @@ std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props) { uint32_t branch = VK_VERSION_PATCH(props.driverVersion); return StringFromFormat("%d.%d.%d (%08x)", major, minor, branch, props.driverVersion); } + +const char *VulkanObjTypeToString(VkDebugReportObjectTypeEXT type) { + switch (type) { + case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device"; + case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue"; + case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory"; + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView"; + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image"; + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool"; + case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore"; + case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event"; + case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool"; + case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapChainKHR"; + case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "CommandPool"; + default: return ""; + } +} diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 7a5e515265..db3caa454e 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -370,6 +370,7 @@ bool GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std const char *VulkanResultToString(VkResult res); std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props); +const char *VulkanObjTypeToString(VkDebugReportObjectTypeEXT type); // Simple heuristic. bool IsHashMaliDriverVersion(const VkPhysicalDeviceProperties &props); diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index ae704839ee..26526eca96 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -23,39 +23,6 @@ #include "Common/Vulkan/VulkanDebug.h" #include "base/logging.h" -const char *VulkanObjTypeToString(VkDebugReportObjectTypeEXT type) { - switch (type) { - case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore"; - case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapChainKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "CommandPool"; - default: return ""; - } -} - VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; std::ostringstream message; diff --git a/Common/Vulkan/VulkanDebug.h b/Common/Vulkan/VulkanDebug.h index 0b6bda6b71..10cb70d8ed 100644 --- a/Common/Vulkan/VulkanDebug.h +++ b/Common/Vulkan/VulkanDebug.h @@ -27,5 +27,3 @@ struct VulkanLogOptions { VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData); VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData); - -const char *VulkanObjTypeToString(VkDebugReportObjectTypeEXT type); From efee79fd71e7639ee955af602a73a8b2e0eb6a43 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 10:26:27 -0700 Subject: [PATCH 052/848] Debugger: Don't break during startup. --- Core/Debugger/Breakpoints.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index 96f52ae0ba..f3501a370c 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -65,7 +65,7 @@ BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc) { int mask = write ? MEMCHECK_WRITE : MEMCHECK_READ; if (cond & mask) { Log(addr, write, size, pc); - if (result & BREAK_ACTION_PAUSE) { + if ((result & BREAK_ACTION_PAUSE) && coreState != CORE_POWERUP) { Core_EnableStepping(true); host->SetDebugMode(true); } @@ -364,7 +364,7 @@ BreakAction CBreakPoints::ExecBreakPoint(u32 addr) { NOTICE_LOG(JIT, "BKP PC=%08x: %s", addr, formatted.c_str()); } } - if (info.result & BREAK_ACTION_PAUSE) { + if ((info.result & BREAK_ACTION_PAUSE) && coreState != CORE_POWERUP) { Core_EnableStepping(true); host->SetDebugMode(true); } From 4c2969712032039c36699aa7b0f16472f6894d33 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 10:26:47 -0700 Subject: [PATCH 053/848] Debugger: Avoid symbol map if deleted. This isn't perfectly safe, but if the game quits very quickly, it's possible for the symbol map to get deleted. --- Windows/Debugger/Debugger_Disasm.cpp | 8 ++++---- Windows/Debugger/Debugger_MemoryDlg.cpp | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 4a2e54ee9d..112f854ab1 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -597,10 +597,9 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) break; case IDC_ALLFUNCTIONS: - { + if (g_symbolMap) g_symbolMap->FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION); - break; - } + break; default: return FALSE; } @@ -862,7 +861,8 @@ void CDisasm::SetDebugMode(bool _bDebug, bool switchPC) void CDisasm::NotifyMapLoaded() { - g_symbolMap->FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION); + if (g_symbolMap) + g_symbolMap->FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION); CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); ptr->clearFunctions(); ptr->redraw(); diff --git a/Windows/Debugger/Debugger_MemoryDlg.cpp b/Windows/Debugger/Debugger_MemoryDlg.cpp index 6943a8b1a3..dd4a3b91ce 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.cpp +++ b/Windows/Debugger/Debugger_MemoryDlg.cpp @@ -95,7 +95,8 @@ void CMemoryDlg::NotifyMapLoaded() if (m_hDlg) { HWND list = GetDlgItem(m_hDlg,IDC_SYMBOLS); - g_symbolMap->FillSymbolListBox(list,ST_DATA); + if (g_symbolMap) + g_symbolMap->FillSymbolListBox(list, ST_DATA); HWND lb = GetDlgItem(m_hDlg,IDC_REGIONS); int sel = ComboBox_GetCurSel(lb); ComboBox_ResetContent(lb); From 86c0418f14a0da1fdaea00e3d08a02d0610d4dd6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 10:40:32 -0700 Subject: [PATCH 054/848] Headless: Fix flash0/font path. This was causing some automated tests to fail incorrectly, after the assets/flash0/ change. --- headless/Headless.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 3b755cbd03..ef43d5ba85 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -405,9 +405,10 @@ int main(int argc, const char* argv[]) #endif // Try to find the flash0 directory. Often this is from a subdirectory. - for (int i = 0; i < 3; ++i) - { - if (!File::Exists(g_Config.flash0Directory)) + for (int i = 0; i < 4 && !File::Exists(g_Config.flash0Directory); ++i) { + if (File::Exists(g_Config.flash0Directory + "../assets/flash0/")) + g_Config.flash0Directory += "../assets/flash0/"; + else g_Config.flash0Directory += "../../flash0/"; } // Or else, maybe in the executable's dir. From 2a2584ec232da49d01ee78fd280080d5c1e4ebba Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 12:24:52 -0700 Subject: [PATCH 055/848] Global: Add more other platforms to MSVC project. To facilitate refactoring/searching files better. --- Common/Common.vcxproj.filters | 8 +- Windows/PPSSPP.vcxproj | 701 ++++++++++++++++++++++++++++++++- Windows/PPSSPP.vcxproj.filters | 436 ++++++++++++++++---- 3 files changed, 1059 insertions(+), 86 deletions(-) diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 9a413fe9a8..ebe7f50688 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -69,9 +69,11 @@ - + + Vulkan + @@ -132,7 +134,9 @@ - + + Vulkan + diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 56ab76c30e..6db2f99a7b 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -654,6 +654,76 @@ true true + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true true @@ -674,6 +744,116 @@ true true + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true true @@ -684,6 +864,16 @@ true true + + true + true + true + true + true + true + true + true + @@ -829,7 +1019,16 @@ true true - + + true + true + true + true + true + true + true + true + @@ -853,9 +1052,197 @@ true - + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + - + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true true @@ -866,6 +1253,136 @@ true true + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true true @@ -876,6 +1393,26 @@ true true + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + @@ -955,26 +1492,174 @@ + + + + + + + + - - - + + + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + + + + + + + + + + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + + @@ -1023,6 +1708,10 @@ + + + + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index cbc6580847..451be96f95 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -35,6 +35,24 @@ {1d0cc0ee-fdbd-419e-b322-b35075d9d9db} + + {5bfed059-8636-4b1e-a3cf-f948d645babb} + + + {950b34a4-d66c-4e7a-aada-e364887cb614} + + + {edf0716f-a255-4061-ad58-702e4b51b0ce} + + + {30a32908-a72f-4728-a721-1f44e700bcea} + + + {68db42ae-cf1b-42cd-b17a-c3e99211a7d8} + + + {21c262bc-bc21-49d7-a332-2e2614e89217} + @@ -154,37 +172,15 @@ Windows\System - Other Platforms\Qt Windows\System - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - Other Platforms\Qt - - Other Platforms - Windows\System @@ -194,6 +190,87 @@ Windows\Input + + Windows\System + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\iOS + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\Qt + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + @@ -289,9 +366,6 @@ Windows\Debugger - - Other Platforms - Windows\Input @@ -316,40 +390,15 @@ Windows\System - Other Platforms\Qt Windows\System - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - Other Platforms\Qt - - Other Platforms - Windows\System @@ -363,6 +412,132 @@ Windows\Input + + Windows\System + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\Android + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\Qt + + + Other Platforms\Qt + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + + + Other Platforms\UWP + @@ -371,50 +546,23 @@ Resource Files - - Other Platforms - Resource Files - - Other Platforms - - - Windows - - - Resource Files Resource Files - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - - - Other Platforms - Resource Files Resource Files - Other Platforms\Qt @@ -439,6 +587,130 @@ Other Platforms\Qt + + Resource Files + + + Resource Files + + + Resource Files + + + Other Platforms\Android + + + Build + + + Build + + + Build + + + Build + + + Build + + + Build + + + Build + + + Build + + + Build + + + Build + + + Build + + + + Build + + + Build + + + Other Platforms\Android + + + Other Platforms\iOS + + + Other Platforms\Android + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Build + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Build + + + Other Platforms\iOS + + + Other Platforms\iOS + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\libretro + + + Other Platforms\Qt + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\SDL + + + Other Platforms\SDL + @@ -450,4 +722,12 @@ Resource Files - + + + Build + + + Other Platforms\libretro + + + \ No newline at end of file From 9064bbcad1a2b3e3e91fd5d8e48039aecbaf22f8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 13:22:32 -0700 Subject: [PATCH 056/848] Windows: Move git-version update to build event. Doing it on each project made it possible for two to overwrite each other. It's rare, but this could corrupt git-version.cpp. This makes it run when Core is resolved, and also on Windows/Headless only. It may still require two compiles to update, but that's not a new problem. --- .gitignore | 2 ++ Common/Common.vcxproj | 32 --------------------- Core/Core.vcxproj | 49 +++++++++++++++++++------------- GPU/GPU.vcxproj | 32 --------------------- UI/UI.vcxproj | 32 --------------------- Windows/PPSSPP.vcxproj | 16 +++++------ Windows/git-version-gen.cmd | 56 +++++++++++++++++++++---------------- headless/Headless.vcxproj | 16 +++++------ 8 files changed, 79 insertions(+), 156 deletions(-) diff --git a/.gitignore b/.gitignore index b9d8b302da..07b897f328 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ Windows/ARM64 Windows/ipch Windows/bin-release Windows/win-version.h +Windows/win-version-*.tmp android/assets ext/_Output android/lint.xml @@ -78,6 +79,7 @@ memstick* Cheats /git-version.cpp +/git-version-*.tmp .pspsh.hist __testoutput.txt diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index ddc0fd6869..80278606df 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -152,10 +152,6 @@ Winmm.lib - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -180,10 +176,6 @@ Winmm.lib - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -208,10 +200,6 @@ Winmm.lib - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -236,10 +224,6 @@ Winmm.lib - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -269,10 +253,6 @@ Winmm.lib - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -304,10 +284,6 @@ Winmm.lib - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -339,10 +315,6 @@ Winmm.lib - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -374,10 +346,6 @@ Winmm.lib - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 5b675bd729..4a9a21fe25 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -129,7 +129,9 @@ - + + ResolveProjectReferences + Level3 @@ -147,10 +149,11 @@ true - + ../Windows/git-version-gen.cmd + ../git-version.cpp;%(Outputs) Updating git-version.cpp - + @@ -170,10 +173,11 @@ true - + ../Windows/git-version-gen.cmd + ../git-version.cpp;%(Outputs) Updating git-version.cpp - + @@ -193,10 +197,11 @@ true - + ../Windows/git-version-gen.cmd + ../git-version.cpp;%(Outputs) Updating git-version.cpp - + @@ -217,10 +222,11 @@ true - + ../Windows/git-version-gen.cmd + ../git-version.cpp;%(Outputs) Updating git-version.cpp - + @@ -244,14 +250,14 @@ true true - - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - %(AdditionalDependencies) + + ../Windows/git-version-gen.cmd + ../git-version.cpp;%(Outputs) + Updating git-version.cpp + @@ -278,10 +284,11 @@ true true - + ../Windows/git-version-gen.cmd + ../git-version.cpp;%(Outputs) Updating git-version.cpp - + @@ -308,10 +315,11 @@ true true - + ../Windows/git-version-gen.cmd + ../git-version.cpp;%(Outputs) Updating git-version.cpp - + @@ -338,10 +346,11 @@ true true - + ../Windows/git-version-gen.cmd + ../git-version.cpp;%(Outputs) Updating git-version.cpp - + diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 9b16ccf742..e427e500bf 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -178,10 +178,6 @@ true - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - @@ -202,10 +198,6 @@ true - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - @@ -225,10 +217,6 @@ true - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - @@ -249,10 +237,6 @@ true - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - @@ -276,10 +260,6 @@ true true - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - @@ -305,10 +285,6 @@ true true - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - @@ -334,10 +310,6 @@ true true - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - @@ -363,10 +335,6 @@ true true - - ../Windows/git-version-gen.cmd - Updating git-version.cpp - diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index 1f69ed9e27..2ea403dff0 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -220,10 +220,6 @@ Windows true - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -245,10 +241,6 @@ Windows true - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -270,10 +262,6 @@ Windows true - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -296,10 +284,6 @@ Windows true - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -325,10 +309,6 @@ true true - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -356,10 +336,6 @@ true true - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -387,10 +363,6 @@ true true - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - @@ -418,10 +390,6 @@ true true - - Updating git-version.cpp - ../Windows/git-version-gen.cmd - diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 6db2f99a7b..aed4bc4e16 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -261,7 +261,7 @@ /ignore:4049 /ignore:4217 %(AdditionalOptions) - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd PPSSPPWindows Updating git-version.cpp @@ -298,7 +298,7 @@ Windows - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd PPSSPPWindows Updating git-version.cpp @@ -333,7 +333,7 @@ Windows - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd PPSSPPWindows Updating git-version.cpp @@ -367,7 +367,7 @@ Windows - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd PPSSPPWindows Updating git-version.cpp @@ -409,7 +409,7 @@ true - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd PPSSPPWindows Updating git-version.cpp @@ -453,7 +453,7 @@ true - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd PPSSPPWindows Updating git-version.cpp @@ -494,7 +494,7 @@ true - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd PPSSPPWindows Updating git-version.cpp @@ -535,7 +535,7 @@ true - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd PPSSPPWindows Updating git-version.cpp diff --git a/Windows/git-version-gen.cmd b/Windows/git-version-gen.cmd index 3bf1fbd338..b2f5d3a26c 100644 --- a/Windows/git-version-gen.cmd +++ b/Windows/git-version-gen.cmd @@ -25,7 +25,9 @@ rem // If git is not installed, "unknown" is the version. setlocal ENABLEDELAYEDEXPANSION set GIT_VERSION_FILE=%~p0..\git-version.cpp +set GIT_VERSION_TEMP=%~p0..\git-version-%1%RANDOM%.tmp set WIN_VERSION_FILE=%~p0.\win-version.h +set WIN_VERSION_TEMP=%~p0.\win-version-%1%RANDOM%.tmp set GIT_MISSING=0 if not defined GIT ( @@ -78,28 +80,31 @@ if "%GIT_MISSING%" == "1" ( echo WARNING: Unable to update git-version.cpp, git not found. echo If you don't want to add it to your path, set the GIT environment variable. - echo // This is a generated file, by git-version-gen.cmd. > "%GIT_VERSION_FILE%" - echo. >> "%GIT_VERSION_FILE%" - echo // ERROR: Unable to determine version - git not on path. > "%GIT_VERSION_FILE%" - echo const char *PPSSPP_GIT_VERSION = "unknown"; >> "%GIT_VERSION_FILE%" + echo // This is a generated file, by git-version-gen.cmd. > "%GIT_VERSION_TEMP%" + echo. >> "%GIT_VERSION_TEMP%" + echo // ERROR: Unable to determine version - git not on path. > "%GIT_VERSION_TEMP%" + echo const char *PPSSPP_GIT_VERSION = "unknown"; >> "%GIT_VERSION_TEMP%" + + move /y "%GIT_VERSION_TEMP%" "%GIT_VERSION_FILE%" > NUL goto gitdone ) -rem // Don't modify the file if it already has the current version. if exist "%GIT_VERSION_FILE%" ( + rem // Don't modify the file if it already has the current version. findstr /C:"%GIT_VERSION%" "%GIT_VERSION_FILE%" > NUL if not errorlevel 1 ( goto gitdone ) ) -echo // This is a generated file, by git-version-gen.cmd. > "%GIT_VERSION_FILE%" -echo. >> "%GIT_VERSION_FILE%" -echo const char *PPSSPP_GIT_VERSION = "%GIT_VERSION%"; >> "%GIT_VERSION_FILE%" -echo. >> "%GIT_VERSION_FILE%" -echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_FILE%" -echo #define PPSSPP_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_FILE%" +echo // This is a generated file, by git-version-gen.cmd. > "%GIT_VERSION_TEMP%" +echo. >> "%GIT_VERSION_TEMP%" +echo const char *PPSSPP_GIT_VERSION = "%GIT_VERSION%"; >> "%GIT_VERSION_TEMP%" +echo. >> "%GIT_VERSION_TEMP%" +echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_TEMP%" +echo #define PPSSPP_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_TEMP%" +move /y "%GIT_VERSION_TEMP%" "%GIT_VERSION_FILE%" > NUL :gitdone if exist "%WIN_VERSION_FILE%" ( @@ -113,12 +118,13 @@ if exist "%WIN_VERSION_FILE%" ( if "%GIT_MISSING%" == "1" ( echo WARNING: Unable to update Windows/win-version.h, git not found. - echo // This is a generated file, by git-version-gen.cmd. > "%WIN_VERSION_FILE%" - echo. >> "%WIN_VERSION_FILE%" - echo // ERROR: Unable to determine version - git not on path. > "%WIN_VERSION_FILE%" - echo #define PPSSPP_WIN_VERSION_STRING "unknown" > "%WIN_VERSION_FILE%" - echo #define PPSSPP_WIN_VERSION_COMMA 0,0,0,0 > "%WIN_VERSION_FILE%" + echo // This is a generated file, by git-version-gen.cmd. > "%WIN_VERSION_TEMP%" + echo. >> "%WIN_VERSION_TEMP%" + echo // ERROR: Unable to determine version - git not on path. > "%WIN_VERSION_TEMP%" + echo #define PPSSPP_WIN_VERSION_STRING "unknown" > "%WIN_VERSION_TEMP%" + echo #define PPSSPP_WIN_VERSION_COMMA 0,0,0,0 > "%WIN_VERSION_TEMP%" + move /y "%WIN_VERSION_TEMP%" "%WIN_VERSION_FILE%" > NUL goto done ) @@ -143,13 +149,15 @@ if /i "%GIT_VERSION:~0,1%" == "v" ( set WIN_VERSION_COMMA=0,0,0x%GIT_VERSION:~0,4%,0x%GIT_VERSION:~4,4% ) -echo // This is a generated file, by git-version-gen.cmd. > "%WIN_VERSION_FILE%" -echo // GIT_VERSION=%GIT_VERSION% >> "%WIN_VERSION_FILE%" -echo. >> "%WIN_VERSION_FILE%" -echo #define PPSSPP_WIN_VERSION_STRING "%GIT_VERSION%" >> "%WIN_VERSION_FILE%" -echo #define PPSSPP_WIN_VERSION_COMMA %WIN_VERSION_COMMA% >> "%WIN_VERSION_FILE%" -echo. >> "%WIN_VERSION_FILE%" -echo // If you don't want this file to update/recompile, change to 1. >> "%WIN_VERSION_FILE%" -echo #define PPSSPP_WIN_VERSION_NO_UPDATE 0 >> "%WIN_VERSION_FILE%" +echo // This is a generated file, by git-version-gen.cmd. > "%WIN_VERSION_TEMP%" +echo // GIT_VERSION=%GIT_VERSION% >> "%WIN_VERSION_TEMP%" +echo. >> "%WIN_VERSION_TEMP%" +echo #define PPSSPP_WIN_VERSION_STRING "%GIT_VERSION%" >> "%WIN_VERSION_TEMP%" +echo #define PPSSPP_WIN_VERSION_COMMA %WIN_VERSION_COMMA% >> "%WIN_VERSION_TEMP%" +echo. >> "%WIN_VERSION_TEMP%" +echo // If you don't want this file to update/recompile, change to 1. >> "%WIN_VERSION_TEMP%" +echo #define PPSSPP_WIN_VERSION_NO_UPDATE 0 >> "%WIN_VERSION_TEMP%" + +move /y "%WIN_VERSION_TEMP%" "%WIN_VERSION_FILE%" > NUL :done diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 7ad31e3578..13618da2af 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -198,7 +198,7 @@ ../ffmpeg/Windows/x86/lib - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd Headless Updating git-version.cpp @@ -231,7 +231,7 @@ ../ffmpeg/Windows/x86_64/lib - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd Headless Updating git-version.cpp @@ -261,7 +261,7 @@ ../ffmpeg/Windows/aarch64/lib - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd Headless Updating git-version.cpp @@ -292,7 +292,7 @@ ../ffmpeg/Windows/arm/lib - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd Headless Updating git-version.cpp @@ -328,7 +328,7 @@ ../ffmpeg/Windows/x86/lib - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd Headless Updating git-version.cpp @@ -366,7 +366,7 @@ ../ffmpeg/Windows/x86_64/lib - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd Headless Updating git-version.cpp @@ -401,7 +401,7 @@ ../ffmpeg/Windows/aarch64/lib - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd Headless Updating git-version.cpp @@ -436,7 +436,7 @@ ../ffmpeg/Windows/arm/lib - ../Windows/git-version-gen.cmd + ../Windows/git-version-gen.cmd Headless Updating git-version.cpp From b46bf8e4e716d42fa78908a9d369cfcc775ed51a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 16:26:47 -0700 Subject: [PATCH 057/848] SDL: Try to continue if EGL init fails. Probably we should just stop using EGL on SDL2, but I'm not sure if that's making things work for some users. But if EGL init fails, try to avoid a segfault and skip EGL. Should help #12474. --- SDL/SDLGLGraphicsContext.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index f7e142f595..7f1a58c66a 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -23,6 +23,7 @@ static EGLSurface g_eglSurface = nullptr; static EGLNativeDisplayType g_Display = nullptr; static bool g_XDisplayOpen = false; static EGLNativeWindowType g_Window = (EGLNativeWindowType)nullptr; +static bool useEGLSwap = false; int CheckEGLErrors(const char *file, int line) { EGLenum error; @@ -328,7 +329,7 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: SetGLCoreContext(true); #endif - window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode); + window = SDL_CreateWindow("PPSSPP", x, y, pixel_xres, pixel_yres, mode); if (!window) { // Definitely don't shutdown here: we'll keep trying more GL versions. fprintf(stderr, "SDL_CreateWindow failed for GL %d.%d: %s\n", ver.major, ver.minor, SDL_GetError()); @@ -353,7 +354,7 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SetGLCoreContext(false); - window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode); + window = SDL_CreateWindow("PPSSPP", x, y, pixel_xres, pixel_yres, mode); if (window == nullptr) { NativeShutdown(); fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); @@ -376,11 +377,10 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: #ifdef USING_EGL if (EGL_Open(window) != 0) { printf("EGL_Open() failed\n"); - return 1; - } - if (EGL_Init(window) != 0) { + } else if (EGL_Init(window) != 0) { printf("EGL_Init() failed\n"); - return 1; + } else { + useEGLSwap = true; } #endif @@ -415,7 +415,10 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: assert(success); renderManager_->SetSwapFunction([&]() { #ifdef USING_EGL - eglSwapBuffers(g_eglDisplay, g_eglSurface); + if (useEGLSwap) + eglSwapBuffers(g_eglDisplay, g_eglSurface); + else + SDL_GL_SwapWindow(window_); #else SDL_GL_SwapWindow(window_); #endif @@ -433,7 +436,6 @@ void SDLGLGraphicsContext::ShutdownFromRenderThread() { #ifdef USING_EGL EGL_Close(); -#else - SDL_GL_DeleteContext(glContext); #endif + SDL_GL_DeleteContext(glContext); } From bf118298368bdeceb8bf59a4813738bbcf7617d2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 14:38:16 -0700 Subject: [PATCH 058/848] Windows: Avoid calling git describe 3 times. We only need to call it once per build, which should save a little build time. Of course, cl.exe takes longer, but still... --- Windows/git-version-gen.cmd | 67 +++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/Windows/git-version-gen.cmd b/Windows/git-version-gen.cmd index b2f5d3a26c..7d14bb5469 100644 --- a/Windows/git-version-gen.cmd +++ b/Windows/git-version-gen.cmd @@ -33,39 +33,38 @@ set GIT_MISSING=0 if not defined GIT ( set GIT="git" ) -call %GIT% describe --always > NUL 2> NUL -if errorlevel 1 ( - echo Git not on path, trying default Msysgit paths... - set GIT="%ProgramFiles(x86)%\Git\bin\git.exe" - call !GIT! describe > NUL 2> NUL - if errorlevel 1 ( - echo !GIT! - set GIT="%ProgramFiles%\Git\bin\git.exe" - call !GIT! describe > NUL 2> NUL - if errorlevel 1 ( - set GIT="%ProgramW6432%\Git\bin\git.exe" - ) - ) -) +call %GIT% describe --always > "%GIT_VERSION_TEMP%" 2> NUL +if not errorlevel 1 goto gitfound -call %GIT% describe --always > NUL 2> NUL -if errorlevel 1 ( - echo Git not on path, trying GitHub Desktop.. - rem // Cheating using short filenames. - set GIT="%USERPROFILE%\AppData\Local\GitHub\PORTAB~1\bin\git.exe" - call !GIT! describe > NUL 2> NUL - if errorlevel 1 ( - set GIT="%USERPROFILE%\AppData\Local\GitHub\PORTAB~2\bin\git.exe" - ) -) +echo Git not on path, trying default Msysgit paths... +set GIT="%ProgramFiles(x86)%\Git\bin\git.exe" +call %GIT% describe --always > "%GIT_VERSION_TEMP%" 2> NUL +if not errorlevel 1 goto gitfound -call %GIT% describe --always > NUL 2> NUL -if errorlevel 1 ( - set GIT_MISSING=1 -) +set GIT="%ProgramFiles%\Git\bin\git.exe" +call %GIT% describe --always > "%GIT_VERSION_TEMP%" 2> NUL +if not errorlevel 1 goto gitfound +set GIT="%ProgramW6432%\Git\bin\git.exe" +call %GIT% describe --always > "%GIT_VERSION_TEMP%" 2> NUL +if not errorlevel 1 goto gitfound + +echo Git not on path, trying GitHub Desktop.. +rem // Cheating using short filenames. +set GIT="%USERPROFILE%\AppData\Local\GitHub\PORTAB~1\bin\git.exe" +call %GIT% describe --always > "%GIT_VERSION_TEMP%" 2> NUL +if not errorlevel 1 goto gitfound + +set GIT="%USERPROFILE%\AppData\Local\GitHub\PORTAB~2\bin\git.exe" +call %GIT% describe --always > "%GIT_VERSION_TEMP%" 2> NUL +if not errorlevel 1 goto gitfound + +set GIT_MISSING=1 + +:gitfound if not "%GIT_MISSING%" == "1" ( - for /F %%I in ('call %GIT% describe --always') do set GIT_VERSION=%%I + for /F %%I in ('type "%GIT_VERSION_TEMP%"') do set GIT_VERSION=%%I + del "%GIT_VERSION_TEMP%" > NUL 2> NUL ) if exist "%GIT_VERSION_FILE%" ( @@ -105,6 +104,11 @@ echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_V echo #define PPSSPP_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_TEMP%" move /y "%GIT_VERSION_TEMP%" "%GIT_VERSION_FILE%" > NUL +if errorlevel 1 ( + rem // Cheap delay tactic. + call %GIT% describe --always > NUL 2> NUL + move /y "%GIT_VERSION_TEMP%" "%GIT_VERSION_FILE%" > NUL +) :gitdone if exist "%WIN_VERSION_FILE%" ( @@ -159,5 +163,10 @@ echo // If you don't want this file to update/recompile, change to 1. >> "%WIN_V echo #define PPSSPP_WIN_VERSION_NO_UPDATE 0 >> "%WIN_VERSION_TEMP%" move /y "%WIN_VERSION_TEMP%" "%WIN_VERSION_FILE%" > NUL +if errorlevel 1 ( + rem // Cheap delay tactic. + call %GIT% describe --always > NUL 2> NUL + move /y "%WIN_VERSION_TEMP%" "%WIN_VERSION_FILE%" > NUL +) :done From 8ccbfcd1f2a9075c072654704e65f359b766110a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 14:48:43 -0700 Subject: [PATCH 059/848] Windows: Workaround for custom build step error. Apparently this is a known bug in some MSVC versions. --- Core/Core.vcxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 4a9a21fe25..4498efe743 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -129,6 +129,10 @@ + + + ResolveProjectReferences From 4f586f9567abaa9f491063cb4238b1e3edfcda2a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 19:59:56 -0700 Subject: [PATCH 060/848] PPGe: Left align messages in dialogs. It was previously left aligned, but the TextDrawer was being told to center. These are meant to just center the enclosing box of text, not the individual lines within. Makes Final Fantasy 3 look a lot better. --- Core/Dialog/PSPDialog.cpp | 8 ++--- Core/Dialog/PSPMsgDialog.cpp | 16 ++++----- Core/Dialog/PSPNetconfDialog.cpp | 6 ++-- Core/Dialog/PSPOskDialog.cpp | 38 +++++++++++----------- Core/Dialog/PSPSaveDialog.cpp | 36 ++++++++++---------- Core/Util/PPGeDraw.cpp | 56 +++++++++++++++----------------- Core/Util/PPGeDraw.h | 31 +++++++++--------- 7 files changed, 94 insertions(+), 97 deletions(-) diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp index 9ddc44f630..8bc866c731 100644 --- a/Core/Dialog/PSPDialog.cpp +++ b/Core/Dialog/PSPDialog.cpp @@ -217,13 +217,13 @@ void PSPDialog::DisplayButtons(int flags, const char *caption) const char *text = useCaption ? safeCaption : di->T("Enter"); PPGeDrawImage(okButtonImg, x2, 258, 11.5f, 11.5f, 0, CalcFadedColor(0x80000000)); PPGeDrawImage(okButtonImg, x2, 256, 11.5f, 11.5f, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(text, x2 + 15.5f, 254, PPGE_ALIGN_LEFT, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(text, x2 + 14.5f, 252, PPGE_ALIGN_LEFT, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(text, x2 + 15.5f, 254, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawText(text, x2 + 14.5f, 252, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); } if (flags & DS_BUTTON_CANCEL) { const char *text = useCaption ? safeCaption : di->T("Back"); - PPGeDrawText(text, x1 + 15.5f, 254, PPGE_ALIGN_LEFT, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(text, x1 + 14.5f, 252, PPGE_ALIGN_LEFT, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(text, x1 + 15.5f, 254, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawText(text, x1 + 14.5f, 252, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); PPGeDrawImage(cancelButtonImg, x1, 258, 11.5f, 11.5f, 0, CalcFadedColor(0x80000000)); PPGeDrawImage(cancelButtonImg, x1, 256, 11.5f, 11.5f, 0, CalcFadedColor(0xFFFFFFFF)); } diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index 20b3fb84a3..22960aa7a1 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -178,10 +178,10 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) h2 += h + 5.0f; y = 135.0f - h; PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x6DCFCFCF)); - PPGeDrawText(di->T("Yes"), 204.0f, y2 + 1.0f, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("Yes"), 203.0f, y2 - 1.0f, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(yesColor)); - PPGeDrawText(di->T("No"), 273.0f, y2 + 1.0f, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("No"), 272.0f, y2 - 1.0f, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(noColor)); + PPGeDrawText(di->T("Yes"), 204.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawText(di->T("Yes"), 203.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(yesColor)); + PPGeDrawText(di->T("No"), 273.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawText(di->T("No"), 272.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(noColor)); if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) { yesnoChoice = 1; } @@ -201,13 +201,13 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) h2 += h + 5.0f; y = 135.0f - h; PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x6DCFCFCF)); - PPGeDrawText(di->T("OK"), 240.0f, y2 + 1.0f, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("OK"), 239.0f, y2 - 1.0f, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("OK"), 240.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawText(di->T("OK"), 239.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); ey = y2 + 25.0f; } - PPGeDrawTextWrapped(text.c_str(), 241.0f, y+2, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(text.c_str(), 241.0f, y+2, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); sy = 125.0f - h2; PPGeDrawRect(40.0f, sy, 440.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawRect(40.0f, ey, 440.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index a5c278bf06..37332f926b 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -68,7 +68,7 @@ void PSPNetconfDialog::DrawBanner() { // TODO: Draw a hexagon icon PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, CalcFadedColor(0xFFFFFFFF)); auto di = GetI18NCategory("Dialog"); - PPGeDrawText(di->T("Network Connection"), 30, 11, PPGE_ALIGN_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("Network Connection"), 30, 11, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); } int PSPNetconfDialog::Update(int animSpeed) { @@ -88,9 +88,9 @@ int PSPNetconfDialog::Update(int animSpeed) { StartDraw(); DrawBanner(); PPGeDrawRect(0, 0, 480, 272, CalcFadedColor(0x63636363)); - PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawImage(confirmBtnImage, 195, 250, 20, 20, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("OK"), 225, 252, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("OK"), 225, 252, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); if (IsButtonPressed(confirmBtn)) { StartFade(false); diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index a475d0ec36..dbe5ae697b 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -766,7 +766,7 @@ void PSPOskDialog::RenderKeyboard() float previewLeftSide = (480.0f - (12.0f * drawLimit)) / 2.0f; float title = (480.0f - (0.5f * drawLimit)) / 2.0f; - PPGeDrawText(oskDesc.c_str(), title , 20, PPGE_ALIGN_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(oskDesc.c_str(), title , 20, PPGeAlign::BOX_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF)); std::u16string result; @@ -781,7 +781,7 @@ void PSPOskDialog::RenderKeyboard() { temp[0] = result[drawIndex]; ConvertUCS2ToUTF8(buffer, temp); - PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color); + PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); } else { @@ -798,21 +798,21 @@ void PSPOskDialog::RenderKeyboard() ConvertUCS2ToUTF8(buffer, temp); - PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color); + PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); // Also draw the underline for the same reason. color = CalcFadedColor(0xFFFFFFFF); - PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color); + PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); } else { ConvertUCS2ToUTF8(buffer, temp); - PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color); + PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); } } else { - PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGE_ALIGN_HCENTER, 0.5f, color); + PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); } } } @@ -828,10 +828,10 @@ void PSPOskDialog::RenderKeyboard() temp[0] = oskKeys[currentKeyboard][row][col]; ConvertUCS2ToUTF8(buffer, temp); - PPGeDrawText(buffer.c_str(), keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), PPGE_ALIGN_HCENTER, 0.6f, color); + PPGeDrawText(buffer.c_str(), keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), PPGeAlign::BOX_HCENTER, 0.6f, color); if (selectedRow == row && col == selectedCol) - PPGeDrawText("_", keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), PPGE_ALIGN_HCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("_", keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), PPGeAlign::BOX_HCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); } } } @@ -945,7 +945,7 @@ int PSPOskDialog::Update(int animSpeed) { auto di = GetI18NCategory("Dialog"); PPGeDrawImage(ImageID("I_SQUARE"), 365, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("Space"), 390, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("Space"), 390, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); if (g_Config.iButtonPreference != PSP_SYSTEMPARAM_BUTTON_CIRCLE) { PPGeDrawImage(ImageID("I_CROSS"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); @@ -955,11 +955,11 @@ int PSPOskDialog::Update(int animSpeed) { PPGeDrawImage(ImageID("I_CROSS"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); } - PPGeDrawText(di->T("Select"), 75, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("Delete"), 75, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("Select"), 75, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("Delete"), 75, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText("Start", 135, 220, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("Finish"), 185, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("Start", 135, 220, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("Finish"), 185, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); auto lookupLangName = [&](int direction) { // First, find the valid one... @@ -983,20 +983,20 @@ int PSPOskDialog::Update(int animSpeed) { }; if (OskKeyboardNames[currentKeyboardLanguage] != "ko_KR" && IsKeyboardShiftValid(oskParams->fields[0].inputtype, currentKeyboardLanguage, currentKeyboard)) { - PPGeDrawText("Select", 135, 245, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("Shift"), 185, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("Select", 135, 245, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("Shift"), 185, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); } const char *prevLang = lookupLangName(-1); if (prevLang) { - PPGeDrawText("L", 235, 220, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(prevLang, 255, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("L", 235, 220, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(prevLang, 255, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); } const char *nextLang = lookupLangName(1); if (nextLang) { - PPGeDrawText("R", 235, 245, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(nextLang, 255, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("R", 235, 245, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(nextLang, 255, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); } if (IsButtonPressed(CTRL_UP) || IsButtonHeld(CTRL_UP, upBtnFramesHeld, framesHeldThreshold, framesHeldRepeatRate)) { diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 4e0de7f909..c78c6055bf 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -300,7 +300,7 @@ void PSPSaveDialog::DisplayBanner(int which) } // TODO: Draw a hexagon icon PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(title, 30, 11, PPGE_ALIGN_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(title, 30, 11, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); } void PSPSaveDialog::DisplaySaveList(bool canMove) { @@ -395,7 +395,7 @@ void PSPSaveDialog::DisplaySaveDataInfo1() std::lock_guard guard(paramLock); if (param.GetFileInfo(currentSelectedSave).size == 0) { auto di = GetI18NCategory("Dialog"); - PPGeDrawText(di->T("NEW DATA"), 180, 136, PPGE_ALIGN_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("NEW DATA"), 180, 136, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); } else { char title[512]; char time[512]; @@ -452,14 +452,14 @@ void PSPSaveDialog::DisplaySaveDataInfo1() std::string saveTitleTxt = saveTitle; std::string saveDetailTxt = saveDetail; - PPGeDrawText(titleTxt.c_str(), 181, 138, PPGE_ALIGN_BOTTOM, 0.6f, CalcFadedColor(0x80000000)); - PPGeDrawText(titleTxt.c_str(), 180, 136, PPGE_ALIGN_BOTTOM, 0.6f, CalcFadedColor(0xFFC0C0C0)); - PPGeDrawText(timeTxt.c_str(), 181, 139, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0x80000000)); - PPGeDrawText(timeTxt.c_str(), 180, 137, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(saveTitleTxt.c_str(), 176, 162, PPGE_ALIGN_LEFT, 0.55f, CalcFadedColor(0x80000000)); - PPGeDrawText(saveTitleTxt.c_str(), 175, 159, PPGE_ALIGN_LEFT, 0.55f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawTextWrapped(saveDetailTxt.c_str(), 176, 183, 480 - 175, 250 - 183, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0x80000000)); - PPGeDrawTextWrapped(saveDetailTxt.c_str(), 175, 181, 480 - 175, 250 - 181, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(titleTxt.c_str(), 181, 138, PPGeAlign::BOX_BOTTOM, 0.6f, CalcFadedColor(0x80000000)); + PPGeDrawText(titleTxt.c_str(), 180, 136, PPGeAlign::BOX_BOTTOM, 0.6f, CalcFadedColor(0xFFC0C0C0)); + PPGeDrawText(timeTxt.c_str(), 181, 139, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000)); + PPGeDrawText(timeTxt.c_str(), 180, 137, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(saveTitleTxt.c_str(), 176, 162, PPGeAlign::BOX_LEFT, 0.55f, CalcFadedColor(0x80000000)); + PPGeDrawText(saveTitleTxt.c_str(), 175, 159, PPGeAlign::BOX_LEFT, 0.55f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(saveDetailTxt.c_str(), 176, 183, 480 - 175, 250 - 183, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000)); + PPGeDrawTextWrapped(saveDetailTxt.c_str(), 175, 181, 480 - 175, 250 - 181, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); } } @@ -526,8 +526,8 @@ void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) { } std::string saveinfoTxt = StringFromFormat("%.128s\n%s %s\n%lld KB", save_title, date, hour_time, sizeK); - PPGeDrawText(saveinfoTxt.c_str(), 9, 202, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0x80000000)); - PPGeDrawText(saveinfoTxt.c_str(), 8, 200, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(saveinfoTxt.c_str(), 9, 202, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000)); + PPGeDrawText(saveinfoTxt.c_str(), 8, 200, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); } void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo) @@ -561,10 +561,10 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo) h2 += h + 4.0f; y = 132.0f - h; PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x40C0C0C0)); - PPGeDrawText(di->T("Yes"), 303.0f, y2+2, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("Yes"), 302.0f, y2, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(yesColor)); - PPGeDrawText(di->T("No"), 367.0f, y2+2, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("No"), 366.0f, y2, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(noColor)); + PPGeDrawText(di->T("Yes"), 303.0f, y2+2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawText(di->T("Yes"), 302.0f, y2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(yesColor)); + PPGeDrawText(di->T("No"), 367.0f, y2+2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawText(di->T("No"), 366.0f, y2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(noColor)); if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) { yesnoChoice = 1; } @@ -572,8 +572,8 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo) yesnoChoice = 0; } } - PPGeDrawTextWrapped(text.c_str(), 335.0f, y+2, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawTextWrapped(text.c_str(), 334.0f, y, WRAP_WIDTH, 0, PPGE_ALIGN_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(text.c_str(), 335.0f, y+2, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); + PPGeDrawTextWrapped(text.c_str(), 334.0f, y, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); float sy = 122.0f - h2, ey = 150.0f + h2; PPGeDrawRect(202.0f, sy, 466.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawRect(202.0f, ey, 466.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 43381a4b3b..ebb555ba63 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -125,7 +125,7 @@ struct PPGeTextDrawerImage { std::map textDrawerImages; // Overwrite the current text lines buffer so it can be drawn later. -void PPGePrepareText(const char *text, float x, float y, int align, float scale, float lineHeightScale, +void PPGePrepareText(const char *text, float x, float y, PPGeAlign align, float scale, float lineHeightScale, int WrapType = PPGE_LINE_NONE, int wrapWidth = 0); // These functions must be called between PPGeBegin and PPGeEnd. @@ -455,7 +455,7 @@ static const AtlasChar *PPGeGetChar(const AtlasFont &atlasfont, unsigned int cva // Break a single text string into mutiple lines. static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, float x, float y, - int align, float scale, float lineHeightScale, int wrapType, float wrapWidth, bool dryRun) + PPGeAlign align, float scale, float lineHeightScale, int wrapType, float wrapWidth, bool dryRun) { y += atlasfont.ascend * scale; float sx = x, sy = y; @@ -665,26 +665,22 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, const float w = maxw; const float h = (float)numLines * lineHeight; - if (align) - { - if (!dryRun) - { - for (auto i = char_lines.begin(); i != char_lines.end(); ++i) - { - for (auto j = i->begin(); j != i->end(); ++j) - { - if (align & PPGE_ALIGN_HCENTER) j->x -= w / 2.0f; - else if (align & PPGE_ALIGN_RIGHT) j->x -= w; + if (align & PPGeAlign::ANY) { + if (!dryRun) { + for (auto i = char_lines.begin(); i != char_lines.end(); ++i) { + for (auto j = i->begin(); j != i->end(); ++j) { + if (align & PPGeAlign::BOX_HCENTER) j->x -= w / 2.0f; + else if (align & PPGeAlign::BOX_RIGHT) j->x -= w; - if (align & PPGE_ALIGN_VCENTER) j->y -= h / 2.0f; - else if (align & PPGE_ALIGN_BOTTOM) j->y -= h; + if (align & PPGeAlign::BOX_VCENTER) j->y -= h / 2.0f; + else if (align & PPGeAlign::BOX_BOTTOM) j->y -= h; } } } - if (align & PPGE_ALIGN_HCENTER) sx -= w / 2.0f; - else if (align & PPGE_ALIGN_RIGHT) sx -= w; - if (align & PPGE_ALIGN_VCENTER) sy -= h / 2.0f; - else if (align & PPGE_ALIGN_BOTTOM) sy -= h; + if (align & PPGeAlign::BOX_HCENTER) sx -= w / 2.0f; + else if (align & PPGeAlign::BOX_RIGHT) sx -= w; + if (align & PPGeAlign::BOX_VCENTER) sy -= h / 2.0f; + else if (align & PPGeAlign::BOX_BOTTOM) sy -= h; } AtlasTextMetrics metrics = { sx, sy, w, lineHeight, scale, numLines }; @@ -734,12 +730,12 @@ void PPGeMeasureText(float *w, float *h, const char *text, float scale, int Wrap } const AtlasFont &atlasfont = g_ppge_atlas.fonts[0]; - AtlasTextMetrics metrics = BreakLines(text, atlasfont, 0, 0, 0, scale, scale, WrapType, wrapWidth, true); + AtlasTextMetrics metrics = BreakLines(text, atlasfont, 0, 0, PPGeAlign::BOX_TOP, scale, scale, WrapType, wrapWidth, true); if (w) *w = metrics.maxWidth; if (h) *h = metrics.lineHeight * metrics.numLines; } -void PPGePrepareText(const char *text, float x, float y, int align, float scale, float lineHeightScale, int WrapType, int wrapWidth) +void PPGePrepareText(const char *text, float x, float y, PPGeAlign align, float scale, float lineHeightScale, int WrapType, int wrapWidth) { const AtlasFont &atlasfont = g_ppge_atlas.fonts[0]; if (!g_ppge_atlas.IsMetadataLoaded() || g_ppge_atlas.num_fonts < 1) { @@ -794,8 +790,8 @@ int GetPow2(int x) { return ret; } -static PPGeTextDrawerImage PPGeGetTextImage(const char *text, int align, float scale, float maxWidth, bool wrap) { - int tdalign = (align & PPGE_ALIGN_HCENTER) ? ALIGN_HCENTER : 0; +static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, float scale, float maxWidth, bool wrap) { + int tdalign = 0; tdalign |= FLAG_ELLIPSIZE_TEXT; if (wrap) { tdalign |= FLAG_WRAP_TEXT; @@ -847,7 +843,7 @@ static PPGeTextDrawerImage PPGeGetTextImage(const char *text, int align, float s return im; } -static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, int align, float scale, u32 color) { +static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, PPGeAlign align, float scale, u32 color) { int bufw = ((im.entry.bmWidth + 31) / 32) * 32; int wp2 = GetPow2(im.entry.bmWidth); int hp2 = GetPow2(im.entry.bmHeight); @@ -859,13 +855,13 @@ static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, int alig float w = im.entry.width * scale; float h = im.entry.height * scale; - if (align & PPGE_ALIGN_HCENTER) + if (align & PPGeAlign::BOX_HCENTER) x -= w / 2.0f; - else if (align & PPGE_ALIGN_RIGHT) + else if (align & PPGeAlign::BOX_RIGHT) x -= w; - if (align & PPGE_ALIGN_VCENTER) + if (align & PPGeAlign::BOX_VCENTER) y -= h / 2.0f; - else if (align & PPGE_ALIGN_BOTTOM) + else if (align & PPGeAlign::BOX_BOTTOM) y -= h; BeginVertexData(); @@ -878,7 +874,7 @@ static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, int alig PPGeSetDefaultTexture(); } -void PPGeDrawText(const char *text, float x, float y, int align, float scale, u32 color) { +void PPGeDrawText(const char *text, float x, float y, PPGeAlign align, float scale, u32 color) { if (HasTextDrawer()) { PPGeTextDrawerImage im = PPGeGetTextImage(text, align, scale, 480.0f - x, false); PPGeDrawTextImage(im, x, y, align, scale, color); @@ -912,7 +908,7 @@ static std::string CropLinesToCount(const std::string &s, int numLines) { return s.substr(0, len); } -void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, int align, float scale, u32 color) { +void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, PPGeAlign align, float scale, u32 color) { std::string s = text; if (wrapHeight != 0.0f) { s = StripTrailingWhite(s); @@ -924,7 +920,7 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl if (HasTextDrawer()) { float actualWidth, actualHeight; Bounds b(0, 0, wrapWidth <= 0 ? 480.0f - x : wrapWidth, wrapHeight); - int tdalign = (align & PPGE_ALIGN_HCENTER) ? ALIGN_HCENTER : 0; + int tdalign = 0; textDrawer->SetFontScale(scale, scale); textDrawer->MeasureStringRect(s.c_str(), s.size(), b, &actualWidth, &actualHeight, tdalign | FLAG_WRAP_TEXT); if (wrapHeight != 0.0f && actualHeight > wrapHeight) { diff --git a/Core/Util/PPGeDraw.h b/Core/Util/PPGeDraw.h index f97b482769..38eddea82c 100644 --- a/Core/Util/PPGeDraw.h +++ b/Core/Util/PPGeDraw.h @@ -45,21 +45,22 @@ void __PPGeShutdown(); void PPGeBegin(); void PPGeEnd(); -enum { - PPGE_ALIGN_LEFT = 0, - PPGE_ALIGN_RIGHT = 16, - PPGE_ALIGN_TOP = 0, - PPGE_ALIGN_BOTTOM = 1, - PPGE_ALIGN_HCENTER = 4, - PPGE_ALIGN_VCENTER = 8, - PPGE_ALIGN_VBASELINE = 32, // text only, possibly not yet working +enum class PPGeAlign { + BOX_LEFT = 0x00, + BOX_RIGHT = 0x01, + BOX_HCENTER = 0x02, - PPGE_ALIGN_CENTER = PPGE_ALIGN_HCENTER | PPGE_ALIGN_VCENTER, - PPGE_ALIGN_TOPLEFT = PPGE_ALIGN_TOP | PPGE_ALIGN_LEFT, - PPGE_ALIGN_TOPRIGHT = PPGE_ALIGN_TOP | PPGE_ALIGN_RIGHT, - PPGE_ALIGN_BOTTOMLEFT = PPGE_ALIGN_BOTTOM | PPGE_ALIGN_LEFT, - PPGE_ALIGN_BOTTOMRIGHT = PPGE_ALIGN_BOTTOM | PPGE_ALIGN_RIGHT, + BOX_TOP = 0x00, + BOX_BOTTOM = 0x10, + BOX_VCENTER = 0x20, + + BOX_CENTER = 0x22, + + ANY = 0xFF, }; +inline bool operator &(const PPGeAlign &lhs, const PPGeAlign &rhs) { + return ((int)lhs & (int)rhs) != 0; +} enum { PPGE_LINE_NONE = 0, @@ -73,8 +74,8 @@ void PPGeMeasureText(float *w, float *h, const char *text, float scale, int Wrap // Draws some text using the one font we have. // Clears the text buffer when done. -void PPGeDrawText(const char *text, float x, float y, int align, float scale = 1.0f, u32 color = 0xFFFFFFFF); -void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, int align, float scale = 1.0f, u32 color = 0xFFFFFFFF); +void PPGeDrawText(const char *text, float x, float y, PPGeAlign align, float scale = 1.0f, u32 color = 0xFFFFFFFF); +void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, PPGeAlign align, float scale = 1.0f, u32 color = 0xFFFFFFFF); // Draws a "4-patch" for button-like things that can be resized. void PPGeDraw4Patch(ImageID atlasImage, float x, float y, float w, float h, u32 color = 0xFFFFFFFF); From 921b9b89d6bcbd16df89d9dcb3b43661c53e6a16 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 00:12:41 -0700 Subject: [PATCH 061/848] GPU: Don't reapply LoadClut each frame. Definitely don't need to reapply this one. --- GPU/GPUCommon.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 7d05933ca5..b3d2703f31 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1141,7 +1141,9 @@ void GPUCommon::ReapplyGfxState() { // There are a few here in the middle that we shouldn't execute... for (int i = GE_CMD_VIEWPORTXSCALE; i < GE_CMD_TRANSFERSTART; i++) { - ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF); + if (i != GE_CMD_LOADCLUT) { + ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF); + } } // Let's just skip the transfer size stuff, it's just values. From f0550a6ded38cff65266e4f5cfd335375a08a49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 May 2020 16:30:37 +0200 Subject: [PATCH 062/848] Exclude a couple more commands from re-execution in ReapplyGfxState. See --- GPU/GPUCommon.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index b3d2703f31..0a09725677 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1126,6 +1126,9 @@ void GPUCommon::ReapplyGfxState() { // The commands are embedded in the command memory so we can just reexecute the words. Convenient. // To be safe we pass 0xFFFFFFFF as the diff. + // TODO: Consider whether any of this should really be done. We might be able to get all the way + // by simplying dirtying the appropriate gstate_c dirty flags. + for (int i = GE_CMD_VERTEXTYPE; i < GE_CMD_BONEMATRIXNUMBER; i++) { if (i != GE_CMD_ORIGIN && i != GE_CMD_OFFSETADDR) { ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF); @@ -1140,9 +1143,16 @@ void GPUCommon::ReapplyGfxState() { // There are a few here in the middle that we shouldn't execute... + // 0x42 to 0xEA for (int i = GE_CMD_VIEWPORTXSCALE; i < GE_CMD_TRANSFERSTART; i++) { - if (i != GE_CMD_LOADCLUT) { + switch (i) { + case GE_CMD_LOADCLUT: + case GE_CMD_TEXSYNC: + case GE_CMD_TEXFLUSH: + break; + default: ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF); + break; } } From defa8aa4803f9e73c902efbac90dda40b924cdda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 May 2020 16:51:37 +0200 Subject: [PATCH 063/848] DarkStalkers: Handle the "normal" screen stretch too, not just "wide", to avoid a surprising performance drop. --- GPU/Common/PresentationCommon.cpp | 7 +++++ GPU/Common/PresentationCommon.h | 1 + GPU/Software/RasterizerRectangle.cpp | 44 +++++++++++++++------------- GPU/Software/SoftGpu.cpp | 7 +++-- GPU/Software/SoftGpu.h | 7 +++++ 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 6f8459b588..83fffeecc0 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -570,6 +570,13 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u } } + if (flags & OutputFlags::PILLARBOX) { + for (int i = 0; i < 4; i++) { + // Looks about right. + verts[i].x *= 0.75f; + } + } + if (usePostShader) { bool flipped = flags & OutputFlags::POSITION_FLIPPED; float post_v0 = !flipped ? 1.0f : 0.0f; diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index eae2834abf..919f63b42a 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -58,6 +58,7 @@ enum class OutputFlags { RB_SWIZZLE = 0x0002, BACKBUFFER_FLIPPED = 0x0004, POSITION_FLIPPED = 0x0008, + PILLARBOX = 0x0010, }; inline OutputFlags operator | (const OutputFlags &lhs, const OutputFlags &rhs) { diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index e396d3a16a..b6697b52c7 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -1,4 +1,4 @@ -// See comment in header for the purpose of this. +// See comment in header for the purpose of the code in this file. #include #include @@ -24,7 +24,7 @@ #include #endif -extern bool g_DarkStalkerStretch; +extern DSStretch g_DarkStalkerStretch; // For Darkstalkers hack. Ugh. extern bool currentDialogActive; @@ -224,11 +224,11 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { } } -bool needsClear = false; +bool g_needsClearAfterDialog = false; // Returns true if the normal path should be skipped. bool RectangleFastPath(const VertexData &v0, const VertexData &v1) { - g_DarkStalkerStretch = false; + g_DarkStalkerStretch = DSStretch::Off; // Check for 1:1 texture mapping. In that case we can call DrawSprite. int xdiff = v1.screenpos.x - v0.screenpos.x; int ydiff = v1.screenpos.y - v0.screenpos.y; @@ -246,24 +246,28 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1) { // Eliminate the stretch blit in DarkStalkers. // We compensate for that when blitting the framebuffer in SoftGpu.cpp. if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && v0.texturecoords.x == 64.0f && v0.texturecoords.y == 16.0f && v1.texturecoords.x == 448.0f && v1.texturecoords.y == 240.0f) { - if (v0.screenpos.x == 0x7100 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8f00 && v1.screenpos.y == 0x8880) { - // Also check for save/load dialog. - if (!currentDialogActive) { - g_DarkStalkerStretch = true; - if (needsClear) { - needsClear = false; - // Afterwards, we also need to clear the actual destination. Can do a fast rectfill. - gstate.textureMapEnable &= ~1; - VertexData newV0 = v0; - newV0.color0 = Vec4(0, 0, 0, 255); - Rasterizer::DrawSprite(newV0, v1); - gstate.textureMapEnable |= 1; - } - return true; + // check for save/load dialog. + if (!currentDialogActive) { + if (v0.screenpos.x == 0x7100 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8f00 && v1.screenpos.y == 0x8880) { + g_DarkStalkerStretch = DSStretch::Wide; + } else if (v0.screenpos.x == 0x7400 && v0.screenpos.y == 0x7780 && v1.screenpos.x == 0x8C00 && v1.screenpos.y == 0x8880) { + g_DarkStalkerStretch = DSStretch::Normal; } else { - needsClear = true; + return false; } - } // else, handle the Capcom screen stretch, or the non-wide stretch? Or let's just not bother. + if (g_needsClearAfterDialog) { + g_needsClearAfterDialog = false; + // Afterwards, we also need to clear the actual destination. Can do a fast rectfill. + gstate.textureMapEnable &= ~1; + VertexData newV0 = v0; + newV0.color0 = Vec4(0, 0, 0, 255); + Rasterizer::DrawSprite(newV0, v1); + gstate.textureMapEnable |= 1; + } + return true; + } else { + g_needsClearAfterDialog = true; + } } return false; } diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 7e17d54f89..d0d49548b9 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -132,7 +132,7 @@ void SoftGPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for GPURecord::NotifyDisplay(framebuf, stride, format); } -bool g_DarkStalkerStretch; +DSStretch g_DarkStalkerStretch; void SoftGPU::ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight, u8 *overrideData) { // TODO: This should probably be converted in a shader instead.. @@ -200,7 +200,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { OutputFlags outputFlags = g_Config.iBufFilter == SCALE_NEAREST ? OutputFlags::NEAREST : OutputFlags::LINEAR; bool hasPostShader = presentation_->HasPostShader(); - if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch) { + if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch != DSStretch::Off) { u8 *data = Memory::GetPointer(0x04088000); bool fillDesc = true; if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { @@ -223,6 +223,9 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { u1 = 447.5f / (float)desc.width; v0 = 16.0f / (float)desc.height; v1 = 240.0f / (float)desc.height; + if (g_DarkStalkerStretch == DSStretch::Normal) { + outputFlags |= OutputFlags::PILLARBOX; + } } else if (!Memory::IsValidAddress(displayFramebuf_) || srcwidth == 0 || srcheight == 0) { hasImage = false; u1 = 1.0f; diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index e97f6c1dde..fc9bf68b7e 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -121,3 +121,10 @@ private: extern u32 clut[4096]; extern FormatBuffer fb; extern FormatBuffer depthbuf; + +// Type for the DarkStalkers stretch replacement. +enum class DSStretch { + Off = 0, + Normal, + Wide, +}; From cba0d16583792a6ed9c574e4df63c070d29991f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 20 May 2020 09:47:11 +0200 Subject: [PATCH 064/848] Vulkan: After binding a new framebuffer, we always need to dirty the viewport/scissor state. So that viewport and scissor commands get written to the new render pass. Temporary solution until I can figure out how to abstract this away in the RenderManager without losing perf. --- GPU/Common/FramebufferCommon.cpp | 12 ++++++++---- GPU/Vulkan/FramebufferVulkan.cpp | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 07f16b1bf0..a35423e9ce 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -549,6 +549,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe // This should only happen very briefly when toggling useBufferedRendering_. ResizeFramebufFBO(vfb, vfb->width, vfb->height, true); } + // GLES resets the blend state on clears. Since we switched target, we also need to redo viewportscissorstate. + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } else { if (vfb->fbo) { // This should only happen very briefly when toggling useBufferedRendering_. @@ -653,6 +655,7 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int if (useBufferedRendering_ && vfb && vfb->fbo) { flags = DRAWTEX_LINEAR; draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "DrawPixels"); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); SetViewport2D(0, 0, vfb->renderWidth, vfb->renderHeight); draw_->SetScissorRect(0, 0, vfb->renderWidth, vfb->renderHeight); } else { @@ -838,7 +841,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { if (useBufferedRendering_) { draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput"); } - gstate_c.Dirty(DIRTY_BLEND_STATE); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); return; } @@ -906,7 +909,8 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { // Bind and clear the backbuffer. This should be the first time during the frame that it's bound. draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput_NoFBO"); } - gstate_c.Dirty(DIRTY_BLEND_STATE); + // GLES resets the blend state on clears. + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); return; } } @@ -1065,7 +1069,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, if (vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); // GLES resets the blend state on clears. - gstate_c.Dirty(DIRTY_BLEND_STATE); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); if (!skipCopy) { BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min((u16)oldWidth, std::min(vfb->bufferWidth, vfb->width)), std::min((u16)oldHeight, std::min(vfb->height, vfb->bufferHeight)), 0); } @@ -1077,7 +1081,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); // GLES resets the blend state on clears. - gstate_c.Dirty(DIRTY_BLEND_STATE); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } if (!vfb->fbo) { diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index b22d4dffc6..8eead37278 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -337,8 +337,10 @@ void FramebufferManagerVulkan::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb void FramebufferManagerVulkan::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) { if (!dst->fbo || !src->fbo || !useBufferedRendering_) { // This can happen if they recently switched from non-buffered. - if (useBufferedRendering_) + if (useBufferedRendering_) { draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "BlitFramebuffer_Fail"); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); + } return; } From bef078a3bd8bb6611ddd9c605c24b94b3945ee50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 May 2020 19:18:04 +0200 Subject: [PATCH 065/848] GLRenderManager: Removes some redundant dirtying. Preserves blend state (color mask) across clears. --- ext/native/thin3d/GLQueueRunner.cpp | 5 ++++- ext/native/thin3d/GLRenderManager.cpp | 16 ---------------- ext/native/thin3d/GLRenderManager.h | 2 +- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 5a297aa974..7be3fd09c2 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -796,7 +796,6 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { } if (c.clear.colorMask != colorMask) { glColorMask(c.clear.colorMask & 1, (c.clear.colorMask >> 1) & 1, (c.clear.colorMask >> 2) & 1, (c.clear.colorMask >> 3) & 1); - colorMask = c.clear.colorMask; } if (c.clear.clearMask & GL_COLOR_BUFFER_BIT) { float color[4]; @@ -818,6 +817,10 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { glClearStencil(c.clear.clearStencil); } glClear(c.clear.clearMask); + // Restore the color mask if it was different. + if (c.clear.colorMask != colorMask) { + glColorMask(colorMask & 1, (colorMask >> 1) & 1, (colorMask >> 2) & 1, (colorMask >> 3) & 1); + } if (c.clear.scissorW == 0) { glEnable(GL_SCISSOR_TEST); } diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index b2fe949cf2..f04d8f9390 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -5,7 +5,6 @@ #include "thin3d/thin3d.h" #include "thread/threadutil.h" #include "base/logging.h" -#include "GPU/GPUState.h" #include "Common/MemoryUtil.h" #if 0 // def _DEBUG @@ -318,9 +317,6 @@ void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRende step->dependencies.insert(fb); } } - - // Every step clears this state. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); } void GLRenderManager::BindFramebufferAsTexture(GLRFramebuffer *fb, int binding, int aspectBit, int attachment) { @@ -346,9 +342,6 @@ void GLRenderManager::CopyFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLR if (dstPos.x != 0 || dstPos.y != 0 || !fillsDst) step->dependencies.insert(dst); steps_.push_back(step); - - // Every step clears this state. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); } void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLRFramebuffer *dst, GLRect2D dstRect, int aspectMask, bool filter, const char *tag) { @@ -365,9 +358,6 @@ void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLR if (!fillsDst) step->dependencies.insert(dst); steps_.push_back(step); - - // Every step clears this state. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); } bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { @@ -382,9 +372,6 @@ bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspec step->tag = tag; steps_.push_back(step); - // Every step clears this state. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); - curRenderStep_ = nullptr; FlushSync(); @@ -414,9 +401,6 @@ void GLRenderManager::CopyImageToMemorySync(GLRTexture *texture, int mipLevel, i step->tag = tag; steps_.push_back(step); - // Every step clears this state. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); - curRenderStep_ = nullptr; FlushSync(); diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 47338a85eb..bffa535895 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -812,7 +812,7 @@ public: curRenderStep_->commands.push_back(data); } - // If scissorW == 0, no scissor is applied. + // If scissorW == 0, no scissor is applied (the whole render target is cleared). void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask, int colorMask, int scissorX, int scissorY, int scissorW, int scissorH) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); if (!clearMask) From 4f7e5df29aba24decc7e21d97e93351f28b4b3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 May 2020 19:21:46 +0200 Subject: [PATCH 066/848] Remove all those "GLES reset the blend state" comments. --- GPU/Common/FramebufferCommon.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index a35423e9ce..b5d899f3af 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012- PPSSPP Project. -// This program is free software: you can redistribute it and/or modify +4// This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 2.0 or later versions. @@ -537,8 +537,6 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe // Wait, can we even do this? Seems highly unsafe.. TODO: Remove if (vfb->last_frame_render != gpuStats.numFlips) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "FramebufferSwitch"); - // GLES resets the blend state on clears. - gstate_c.Dirty(DIRTY_BLEND_STATE); } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "FramebufferSwitch"); } @@ -549,8 +547,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe // This should only happen very briefly when toggling useBufferedRendering_. ResizeFramebufFBO(vfb, vfb->width, vfb->height, true); } - // GLES resets the blend state on clears. Since we switched target, we also need to redo viewportscissorstate. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + // Since we switched target, we need to redo viewportscissorstate. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); } else { if (vfb->fbo) { // This should only happen very briefly when toggling useBufferedRendering_. @@ -841,7 +839,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { if (useBufferedRendering_) { draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput"); } - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); return; } @@ -899,7 +897,6 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { // The game is displaying something directly from RAM. In GTA, it's decoded video. if (!vfb) { DrawFramebufferToOutput(Memory::GetPointer(fbaddr), displayFormat_, displayStride_); - gstate_c.Dirty(DIRTY_BLEND_STATE); return; } } else { @@ -909,8 +906,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { // Bind and clear the backbuffer. This should be the first time during the frame that it's bound. draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "CopyDisplayToOutput_NoFBO"); } - // GLES resets the blend state on clears. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); return; } } @@ -1068,8 +1064,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %d x %d x %d", vfb->fb_address, w, h, vfb->format); if (vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); - // GLES resets the blend state on clears. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); if (!skipCopy) { BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min((u16)oldWidth, std::min(vfb->bufferWidth, vfb->width)), std::min((u16)oldHeight, std::min(vfb->height, vfb->bufferHeight)), 0); } @@ -1081,7 +1076,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); // GLES resets the blend state on clears. - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); } if (!vfb->fbo) { From 544576e6c2d52ce3cb535ebd816e9ccbcb8d91d9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 10:57:32 -0700 Subject: [PATCH 067/848] UI: Lock around removal from dispatch queue. --- ext/native/ui/root.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index 0fd4700445..ac26a663f7 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -50,6 +50,7 @@ void DispatchEvents() { } void RemoveQueuedEventsByView(View *view) { + std::unique_lock guard(eventMutex_); for (auto it = g_dispatchQueue.begin(); it != g_dispatchQueue.end(); ) { if (it->params.v == view) { it = g_dispatchQueue.erase(it); @@ -60,6 +61,7 @@ void RemoveQueuedEventsByView(View *view) { } void RemoveQueuedEventsByEvent(Event *event) { + std::unique_lock guard(eventMutex_); for (auto it = g_dispatchQueue.begin(); it != g_dispatchQueue.end(); ) { if (it->e == event) { it = g_dispatchQueue.erase(it); From bebf649705833ad32e064ade083e0758da85dbe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 May 2020 20:27:58 +0200 Subject: [PATCH 068/848] OpenGL/Vulkan: Rework the contract around dynamic state. Removes some ugly dirtying from the GL render manager. --- GPU/Common/FramebufferCommon.cpp | 13 ++++++------- GPU/GLES/DrawEngineGLES.cpp | 11 +++++++++++ GPU/GLES/DrawEngineGLES.h | 2 ++ GPU/GLES/StateMappingGLES.cpp | 4 ++-- GPU/Vulkan/DrawEngineVulkan.cpp | 13 ++++++++++--- GPU/Vulkan/DrawEngineVulkan.h | 2 ++ ext/native/thin3d/GLRenderManager.h | 23 +++++++++++++++++++++++ ext/native/thin3d/VulkanRenderManager.h | 25 +++++++++++++++++++++++++ 8 files changed, 81 insertions(+), 12 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index b5d899f3af..47a9c2c89a 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2012- PPSSPP Project. -4// This program is free software: you can redistribute it and/or modify +// This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 2.0 or later versions. @@ -450,13 +450,13 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { // Wipe some pointers if (currentRenderVfb_ == v) - currentRenderVfb_ = 0; + currentRenderVfb_ = nullptr; if (displayFramebuf_ == v) - displayFramebuf_ = 0; + displayFramebuf_ = nullptr; if (prevDisplayFramebuf_ == v) - prevDisplayFramebuf_ = 0; + prevDisplayFramebuf_ = nullptr; if (prevPrevDisplayFramebuf_ == v) - prevPrevDisplayFramebuf_ = 0; + prevPrevDisplayFramebuf_ = nullptr; delete v; } @@ -471,7 +471,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED); - // ugly... + // Ugly... if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_CULLRANGE); } @@ -1075,7 +1075,6 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); - // GLES resets the blend state on clears. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); } diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index ca32d8e508..3d6282771f 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -159,6 +159,8 @@ void DrawEngineGLES::BeginFrame() { FrameData &frameData = frameData_[render_->GetCurFrame()]; render_->BeginPushBuffer(frameData.pushIndex); render_->BeginPushBuffer(frameData.pushVertex); + + lastRenderStepId_ = -1; } void DrawEngineGLES::EndFrame() { @@ -305,6 +307,15 @@ void DrawEngineGLES::DoFlush() { gpuStats.numFlushes++; gpuStats.numTrackedVertexArrays = (int)vai_.size(); + // A new render step means we need to flush any dynamic state. Really, any state that is reset in + // GLQueueRunner::PerformRenderPass. + int curRenderStepId = render_->GetCurrentStepId(); + if (lastRenderStepId_ != curRenderStepId) { + // Dirty everything that has dynamic state that will need re-recording. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); + lastRenderStepId_ = curRenderStepId; + } + bool textureNeedsApply = false; if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) { textureCache_->SetTexture(); diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 8fd17e0514..51abeb6d24 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -229,6 +229,8 @@ private: int bufferDecimationCounter_ = 0; + int lastRenderStepId_ = -1; + // Hardware tessellation TessellationDataTransferGLES *tessDataTransferGLES; }; diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 0df2077834..4e2f7f36f1 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -320,8 +320,8 @@ void DrawEngineGLES::ApplyDrawState(int prim) { } } -void DrawEngineGLES::ApplyDrawStateLate(bool setStencil, int stencilValue) { - if (setStencil) { +void DrawEngineGLES::ApplyDrawStateLate(bool setStencilValue, int stencilValue) { + if (setStencilValue) { render_->SetStencilFunc(GL_TRUE, GL_ALWAYS, stencilValue, 255); } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 62305dd14a..8802e4c064 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -259,9 +259,10 @@ void DrawEngineVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext *d } void DrawEngineVulkan::BeginFrame() { - // Too many issues right now to allow reuse. lastPipeline_ = nullptr; + lastRenderStepId_ = -1; + int curFrame = vulkan_->GetCurFrame(); FrameData *frame = &frame_[curFrame]; @@ -587,10 +588,16 @@ void DrawEngineVulkan::DoFlush() { VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - // HACK: These two lines should only execute if we started on a new render pass. Can't tell from in here though... + // TODO: Move this into the below if statement. Little scary change though so holding off until 1.11. lastPipeline_ = nullptr; + // Since we have a new cmdbuf, dirty our dynamic state so it gets re-set. - // gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE|DIRTY_DEPTHSTENCIL_STATE|DIRTY_BLEND_STATE); + int curRenderStepId = renderManager->GetCurrentStepId(); + if (lastRenderStepId_ != curRenderStepId) { + // Dirty everything that has dynamic state that will need re-recording. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE); + lastRenderStepId_ = curRenderStepId; + } FrameData *frame = &frame_[vulkan_->GetCurFrame()]; diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index cbbaeebb5b..8ea60dec73 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -302,4 +302,6 @@ private: // Hardware tessellation TessellationDataTransferVulkan *tessDataTransferVulkan; + + int lastRenderStepId_ = -1; }; diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index bffa535895..a31ab31b23 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -501,8 +501,25 @@ public: pushbuffer->End(); } + // This starts a new step (like a "render pass" in Vulkan). + // + // After a "CopyFramebuffer" or the other functions that start "steps", you need to call this beforce + // making any new render state changes or draw calls. + // + // The following state needs to be reset by the caller after calling this (and will thus not safely carry over from + // the previous one): + // * Viewport/Scissor + // * Depth/stencil + // * Blend + // * Raster state like primitive, culling, etc. + // + // It can be useful to use GetCurrentStepId() to figure out when you need to send all this state again, if you're + // not keeping track of your calls to this function on your own. void BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag); + + // Binds a framebuffer as a texture, for the following draws. void BindFramebufferAsTexture(GLRFramebuffer *fb, int binding, int aspectBit, int attachment); + bool CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); void CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); @@ -920,6 +937,12 @@ public: skipGLCalls_ = true; } + // Gets a frame-unique ID of the current step being recorded. Can be used to figure out + // when the current step has changed, which means the caller will need to re-record its state. + int GetCurrentStepId() const { + return (int)steps_.size(); + } + private: void BeginSubmitFrame(int frame); void EndSubmitFrame(int frame); diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index e12f220fcc..fc4b3fc7da 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -105,8 +105,27 @@ public: // Zaps queued up commands. Use if you know there's a risk you've queued up stuff that has already been deleted. Can happen during in-game shutdown. void Wipe(); + // This starts a new step containing a render pass. + // + // After a "CopyFramebuffer" or the other functions that start "steps", you need to call this beforce + // making any new render state changes or draw calls. + // + // The following dynamic state needs to be reset by the caller after calling this (and will thus not safely carry over from + // the previous one): + // * Viewport/Scissor + // * Stencil parameters + // * Blend color + // + // (Most other state is directly decided by your choice of pipeline and descriptor set, so not handled here). + // + // It can be useful to use GetCurrentStepId() to figure out when you need to send all this state again, if you're + // not keeping track of your calls to this function on your own. void BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag); + + // Returns an ImageView corresponding to a framebuffer. Is called BindFramebufferAsTexture to maintain a similar interface + // as the other backends, even though there's no actual binding happening here. VkImageView BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, int aspectBit, int attachment); + bool CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); void CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); @@ -232,6 +251,12 @@ public: } } + // Gets a frame-unique ID of the current step being recorded. Can be used to figure out + // when the current step has changed, which means the caller will need to re-record its state. + int GetCurrentStepId() const { + return (int)steps_.size(); + } + void CreateBackbuffers(); void DestroyBackbuffers(); From 370678c4989a7f4960ecc9afe179c500809ee98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 24 May 2020 20:57:59 +0200 Subject: [PATCH 069/848] Do a similar thing for D3D (let the backend handle the dirtying). --- GPU/Common/FramebufferCommon.cpp | 14 +++----------- GPU/D3D11/DrawEngineD3D11.cpp | 10 ++++++++++ GPU/D3D11/DrawEngineD3D11.h | 2 ++ GPU/Directx9/DrawEngineDX9.cpp | 17 +++++++++++++++-- GPU/Directx9/DrawEngineDX9.h | 7 ++++++- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/GLES/DrawEngineGLES.cpp | 2 ++ GPU/GLES/DrawEngineGLES.h | 2 +- GPU/GLES/GPU_GLES.cpp | 1 - ext/native/thin3d/thin3d.h | 2 ++ ext/native/thin3d/thin3d_d3d11.cpp | 11 +++++++++++ ext/native/thin3d/thin3d_d3d9.cpp | 14 ++++++++++---- ext/native/thin3d/thin3d_gl.cpp | 4 ++++ ext/native/thin3d/thin3d_vulkan.cpp | 4 ++++ 14 files changed, 71 insertions(+), 21 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 47a9c2c89a..0d85958f94 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -547,8 +547,6 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe // This should only happen very briefly when toggling useBufferedRendering_. ResizeFramebufFBO(vfb, vfb->width, vfb->height, true); } - // Since we switched target, we need to redo viewportscissorstate. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); } else { if (vfb->fbo) { // This should only happen very briefly when toggling useBufferedRendering_. @@ -566,7 +564,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe } textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED); - // ugly... + // ugly... is all this needed? if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { gstate_c.Dirty(DIRTY_PROJTHROUGHMATRIX | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_CULLRANGE); } @@ -1064,7 +1062,6 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %d x %d x %d", vfb->fb_address, w, h, vfb->format); if (vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); if (!skipCopy) { BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min((u16)oldWidth, std::min(vfb->bufferWidth, vfb->width)), std::min((u16)oldHeight, std::min(vfb->height, vfb->bufferHeight)), 0); } @@ -1075,7 +1072,6 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); } if (!vfb->fbo) { @@ -1845,7 +1841,7 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB bool retval = draw_->CopyFramebufferToMemorySync(bound, Draw::FB_COLOR_BIT, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), w, "GetFramebuffer"); gpuStats.numReadbacks++; // After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); + gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); // We may have blitted to a temp FBO. RebindFramebuffer(); return retval; @@ -1880,7 +1876,7 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32 // No need to free on failure, that's the caller's job (it likely will reuse a buffer.) bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_DEPTH_BIT, 0, 0, w, h, Draw::DataFormat::D32F, buffer.GetData(), w, "GetDepthBuffer"); // After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); + gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); // That may have unbound the framebuffer, rebind to avoid crashes when debugging. RebindFramebuffer(); return retval; @@ -1971,9 +1967,6 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int ERROR_LOG(G3D, "PackFramebufferSync_: Tried to readback to bad address %08x (stride = %d)", fb_address + dstByteOffset, vfb->fb_stride); } - // A new command buffer will begin after CopyFrameBufferToMemorySync, so we need to trigger - // updates of any dynamic command buffer state by dirtying some stuff. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); gpuStats.numReadbacks++; } @@ -2056,7 +2049,6 @@ void FramebufferManagerCommon::RebindFramebuffer() { // Should this even happen? It could while debugging, but maybe we can just skip binding at all. draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "RebindFramebuffer_Bad"); } - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); } std::vector FramebufferManagerCommon::GetFramebufferList() { diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index fde2dd0102..371910cac7 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -307,6 +307,8 @@ void DrawEngineD3D11::BeginFrame() { NOTICE_LOG(G3D, buffer); } #endif + + lastRenderStepId_ = -1; } VertexArrayInfoD3D11::~VertexArrayInfoD3D11() { @@ -325,6 +327,14 @@ void DrawEngineD3D11::DoFlush() { gpuStats.numFlushes++; gpuStats.numTrackedVertexArrays = (int)vai_.size(); + // In D3D, we're synchronous and state carries over so all we reset here on a new step is the viewport/scissor. + int curRenderStepId = draw_->GetCurrentStepId(); + if (lastRenderStepId_ != curRenderStepId) { + // Dirty everything that has dynamic state that will need re-recording. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); + lastRenderStepId_ = curRenderStepId; + } + // This is not done on every drawcall, we collect vertex data // until critical state changes. That's when we draw (flush). diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index 11ed3e41e9..3511f760f5 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -216,4 +216,6 @@ private: // Hardware tessellation TessellationDataTransferD3D11 *tessDataTransferD3D11; + + int lastRenderStepId_ = -1; }; diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index a39d48f986..436ea508fa 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -83,7 +83,7 @@ static const D3DVERTEXELEMENT9 TransformedVertexElements[] = { D3DDECL_END() }; -DrawEngineDX9::DrawEngineDX9(Draw::DrawContext *draw) : vai_(256), vertexDeclMap_(64) { +DrawEngineDX9::DrawEngineDX9(Draw::DrawContext *draw) : draw_(draw), vai_(256), vertexDeclMap_(64) { device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); decOptions_.expandAllWeightsToFloat = true; decOptions_.expand8BitNormalsToFloat = true; @@ -299,14 +299,27 @@ static uint32_t SwapRB(uint32_t c) { return (c & 0xFF00FF00) | ((c >> 16) & 0xFF) | ((c << 16) & 0xFF0000); } +void DrawEngineDX9::BeginFrame() { + DecimateTrackedVertexArrays(); + + lastRenderStepId_ = -1; +} + // The inline wrapper in the header checks for numDrawCalls == 0 void DrawEngineDX9::DoFlush() { gpuStats.numFlushes++; gpuStats.numTrackedVertexArrays = (int)vai_.size(); + // In D3D, we're synchronous and state carries over so all we reset here on a new step is the viewport/scissor. + int curRenderStepId = draw_->GetCurrentStepId(); + if (lastRenderStepId_ != curRenderStepId) { + // Dirty everything that has dynamic state that will need re-recording. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); + lastRenderStepId_ = curRenderStepId; + } + // This is not done on every drawcall, we should collect vertex data // until critical state changes. That's when we draw (flush). - GEPrimitiveType prim = prevPrim_; ApplyDrawState(prim); diff --git a/GPU/Directx9/DrawEngineDX9.h b/GPU/Directx9/DrawEngineDX9.h index 41c828908a..2d01617b40 100644 --- a/GPU/Directx9/DrawEngineDX9.h +++ b/GPU/Directx9/DrawEngineDX9.h @@ -123,7 +123,8 @@ public: void DestroyDeviceObjects(); void ClearTrackedVertexArrays() override; - void DecimateTrackedVertexArrays(); + + void BeginFrame(); // So that this can be inlined void Flush() { @@ -143,6 +144,7 @@ public: protected: // Not currently supported. bool UpdateUseHWTessellation(bool enable) override { return false; } + void DecimateTrackedVertexArrays(); private: void DoFlush(); @@ -156,6 +158,7 @@ private: void MarkUnreliable(VertexArrayInfoDX9 *vai); LPDIRECT3DDEVICE9 device_ = nullptr; + Draw::DrawContext *draw_; PrehashMap vai_; DenseHashMap vertexDeclMap_; @@ -170,6 +173,8 @@ private: // Hardware tessellation TessellationDataTransferDX9 *tessDataTransferDX9; + + int lastRenderStepId_ = -1; }; } // namespace diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 1b4aaf857b..d3de79ec2b 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -282,7 +282,7 @@ void GPU_DX9::ReapplyGfxState() { void GPU_DX9::BeginFrame() { textureCacheDX9_->StartFrame(); - drawEngine_.DecimateTrackedVertexArrays(); + drawEngine_.BeginFrame(); depalShaderCache_.Decimate(); // fragmentTestCache_.Decimate(); diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 3d6282771f..7d80f20fd4 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -156,6 +156,8 @@ void DrawEngineGLES::ClearInputLayoutMap() { } void DrawEngineGLES::BeginFrame() { + DecimateTrackedVertexArrays(); + FrameData &frameData = frameData_[render_->GetCurFrame()]; render_->BeginPushBuffer(frameData.pushIndex); render_->BeginPushBuffer(frameData.pushVertex); diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 51abeb6d24..165329a3d7 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -150,7 +150,6 @@ public: void DeviceRestore(Draw::DrawContext *draw); void ClearTrackedVertexArrays() override; - void DecimateTrackedVertexArrays(); void BeginFrame(); void EndFrame(); @@ -186,6 +185,7 @@ public: protected: bool UpdateUseHWTessellation(bool enable) override; + void DecimateTrackedVertexArrays(); private: void InitDeviceObjects(); diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 81a53c3dc8..ceefecbcb3 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -373,7 +373,6 @@ void GPU_GLES::ReapplyGfxState() { void GPU_GLES::BeginFrame() { textureCacheGL_->StartFrame(); - drawEngine_.DecimateTrackedVertexArrays(); depalShaderCache_.Decimate(); fragmentTestCache_.Decimate(); diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 22af453d83..4e61672b7f 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -673,6 +673,8 @@ public: // Flush state like scissors etc so the caller can do its own custom drawing. virtual void FlushState() {} + virtual int GetCurrentStepId() const = 0; + protected: ShaderModule *vsPresets_[VS_MAX_PRESET]; ShaderModule *fsPresets_[FS_MAX_PRESET]; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 719c306b44..96b9e1ad63 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -158,6 +158,10 @@ public: void HandleEvent(Event ev, int width, int height, void *param1, void *param2) override; + int GetCurrentStepId() const override { + return stepId_; + } + private: void ApplyCurrentState(); @@ -166,6 +170,7 @@ private: ID3D11DeviceContext *context_; ID3D11Device1 *device1_; ID3D11DeviceContext1 *context1_; + int stepId_ = -1; ID3D11Texture2D *bbRenderTargetTex_ = nullptr; // NOT OWNED ID3D11RenderTargetView *bbRenderTargetView_ = nullptr; @@ -353,6 +358,7 @@ void D3D11DrawContext::HandleEvent(Event ev, int width, int height, void *param1 // Make sure that we don't eliminate the next time the render target is set. curRenderTargetView_ = nullptr; curDepthStencilView_ = nullptr; + stepId_ = 0; break; } } @@ -1394,11 +1400,13 @@ void D3D11DrawContext::CopyFramebufferImage(Framebuffer *srcfb, int level, int x D3D11_BOX srcBox{ (UINT)x, (UINT)y, (UINT)z, (UINT)(x + width), (UINT)(y + height), (UINT)(z + depth) }; context_->CopySubresourceRegion(dstTex, dstLevel, dstX, dstY, dstZ, srcTex, level, &srcBox); } + stepId_++; } bool D3D11DrawContext::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dstfb, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) { // Unfortunately D3D11 has no equivalent to this, gotta render a quad. Well, in some cases we can issue a copy instead. Crash(); + stepId_++; return false; } @@ -1519,6 +1527,7 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel if (!useGlobalPacktex) { packTex->Release(); } + stepId_++; return true; } @@ -1562,6 +1571,8 @@ void D3D11DrawContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const Ren if (mask && curDepthStencilView_) { context_->ClearDepthStencilView(curDepthStencilView_, mask, rp.clearDepth, rp.clearStencil); } + + stepId_++; } // color must be 0, for now. diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 42fc0d29a2..a787bbeef5 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -599,11 +599,16 @@ public: void HandleEvent(Event ev, int width, int height, void *param1, void *param2) override; + int GetCurrentStepId() const override { + return stepId_; + } + private: LPDIRECT3D9 d3d_; LPDIRECT3D9EX d3dEx_; LPDIRECT3DDEVICE9 device_; LPDIRECT3DDEVICE9EX deviceEx_; + int stepId_ = -1; int adapterId_ = -1; D3DADAPTER_IDENTIFIER9 identifier_{}; D3DCAPS9 d3dCaps_; @@ -1160,6 +1165,7 @@ void D3D9Context::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPa dxstate.scissorRect.restore(); dxstate.viewport.restore(); + stepId_++; } uintptr_t D3D9Context::GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) { @@ -1187,10 +1193,6 @@ uintptr_t D3D9Context::GetFramebufferAPITexture(Framebuffer *fbo, int channelBit } } -LPDIRECT3DSURFACE9 fbo_get_color_for_read(D3D9Framebuffer *fbo) { - return fbo->surf; -} - void D3D9Context::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int color) { D3D9Framebuffer *fb = (D3D9Framebuffer *)fbo; switch (channelBit) { @@ -1228,6 +1230,7 @@ bool D3D9Context::BlitFramebuffer(Framebuffer *srcfb, int srcX1, int srcY1, int RECT dstRect{ (LONG)dstX1, (LONG)dstY1, (LONG)dstX2, (LONG)dstY2 }; LPDIRECT3DSURFACE9 srcSurf = src ? src->surf : deviceRTsurf; LPDIRECT3DSURFACE9 dstSurf = dst ? dst->surf : deviceRTsurf; + stepId_++; return SUCCEEDED(device_->StretchRect(srcSurf, &srcRect, dstSurf, &dstRect, filter == FB_BLIT_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT)); } @@ -1245,6 +1248,9 @@ void D3D9Context::HandleEvent(Event ev, int width, int height, void *param1, voi device_->GetRenderTarget(0, &deviceRTsurf); device_->GetDepthStencilSurface(&deviceDSsurf); break; + case Event::PRESENTED: + stepId_ = 0; + break; } } diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 2a45ae2256..0bbe2466d5 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -478,6 +478,10 @@ public: void HandleEvent(Event ev, int width, int height, void *param1, void *param2) override {} + int GetCurrentStepId() const { + return renderManager_.GetCurrentStepId(); + } + private: void ApplySamplers(); diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index e3160a944d..43fe931f6c 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -482,6 +482,10 @@ public: void HandleEvent(Event ev, int width, int height, void *param1, void *param2) override; + int GetCurrentStepId() const { + return renderManager_.GetCurrentStepId(); + } + private: VulkanTexture *GetNullTexture(); VulkanContext *vulkan_ = nullptr; From c051e9ec2cd5a2890d1b4697586e83b4d600c799 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 14:05:54 -0700 Subject: [PATCH 070/848] GLES: Fix disabled vertex cache code. --- GPU/GLES/DrawEngineGLES.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 7d80f20fd4..df8b106f19 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -374,6 +374,9 @@ void DrawEngineGLES::DoFlush() { vai->maxIndex = indexGen.MaxIndex(); vai->flags = gstate_c.vertexFullAlpha ? VAI_FLAG_VERTEXFULLALPHA : 0; + size_t size = decodedVerts_ * dec_->GetDecVtxFmt().stride; + u8 *dest = (u8 *)frameData.pushVertex->Push(size, &vertexBufferOffset, &vertexBuffer); + memcpy(dest, decoded, size); goto rotateVBO; } @@ -394,8 +397,7 @@ void DrawEngineGLES::DoFlush() { } if (newMiniHash != vai->minihash || newHash != vai->hash) { MarkUnreliable(vai); - DecodeVerts(decoded); - goto rotateVBO; + goto skipVBO; } if (vai->numVerts > 64) { // exponential backoff up to 16 draws, then every 32 @@ -413,12 +415,11 @@ void DrawEngineGLES::DoFlush() { u32 newMiniHash = ComputeMiniHash(); if (newMiniHash != vai->minihash) { MarkUnreliable(vai); - DecodeVerts(decoded); - goto rotateVBO; + goto skipVBO; } } - if (vai->vbo == 0) { + if (vai->vbo == nullptr) { DecodeVerts(decoded); vai->numVerts = indexGen.VertexCount(); vai->prim = indexGen.Prim(); @@ -433,14 +434,18 @@ void DrawEngineGLES::DoFlush() { size_t vsz = dec_->GetDecVtxFmt().stride * indexGen.MaxIndex(); vai->vbo = render_->CreateBuffer(GL_ARRAY_BUFFER, vsz, GL_STATIC_DRAW); - render_->BufferSubdata(vai->vbo, 0, vsz, decoded); + uint8_t *vertexData = new uint8_t[vsz]; + memcpy(vertexData, decoded, vsz); + render_->BufferSubdata(vai->vbo, 0, vsz, vertexData); // If there's only been one primitive type, and it's either TRIANGLES, LINES or POINTS, // there is no need for the index buffer we built. We can then use glDrawArrays instead // for a very minor speed boost. if (useElements) { size_t esz = sizeof(short) * indexGen.VertexCount(); vai->ebo = render_->CreateBuffer(GL_ELEMENT_ARRAY_BUFFER, esz, GL_STATIC_DRAW); - render_->BufferSubdata(vai->ebo, 0, esz, (uint8_t *)decIndex, false); + uint8_t *indexData = new uint8_t[esz]; + memcpy(indexData, decIndex, esz); + render_->BufferSubdata(vai->ebo, 0, esz, indexData); } else { vai->ebo = 0; render_->BindIndexBuffer(vai->ebo); @@ -482,13 +487,13 @@ void DrawEngineGLES::DoFlush() { if (vai->lastFrame != gpuStats.numFlips) { vai->numFrames++; } - DecodeVerts(decoded); - goto rotateVBO; + goto skipVBO; } } vai->lastFrame = gpuStats.numFlips; } else { +skipVBO: if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) { // If software skinning, we've already predecoded into "decoded". So push that content. size_t size = decodedVerts_ * dec_->GetDecVtxFmt().stride; @@ -530,8 +535,8 @@ rotateVBO: if (useElements) { if (!indexBuffer) { indexBufferOffset = (uint32_t)frameData.pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &indexBuffer); - render_->BindIndexBuffer(indexBuffer); } + render_->BindIndexBuffer(indexBuffer); render_->DrawIndexed(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, (GLvoid*)(intptr_t)indexBufferOffset); } else { render_->Draw(glprim[prim], 0, vertexCount); From 56f4335915d78c048fce0090fffd7b354e24ecd3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 14:45:06 -0700 Subject: [PATCH 071/848] GLES: Delay buffer use in vertex cache. This creates the buffer on frame 2, starts using it on frame 3. --- GPU/GLES/DrawEngineGLES.cpp | 103 +++++++++++++++++------------------- GPU/GLES/DrawEngineGLES.h | 2 +- 2 files changed, 51 insertions(+), 54 deletions(-) diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index df8b106f19..6ab5620fe5 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -232,7 +232,7 @@ GLRInputLayout *DrawEngineGLES::SetupDecFmtForDraw(LinkedShader *program, const return inputLayout; } -void DrawEngineGLES::DecodeVertsToPushBuffer(GLPushBuffer *push, uint32_t *bindOffset, GLRBuffer **buf) { +void *DrawEngineGLES::DecodeVertsToPushBuffer(GLPushBuffer *push, uint32_t *bindOffset, GLRBuffer **buf) { u8 *dest = decoded; // Figure out how much pushbuffer space we need to allocate. @@ -241,6 +241,7 @@ void DrawEngineGLES::DecodeVertsToPushBuffer(GLPushBuffer *push, uint32_t *bindO dest = (u8 *)push->Push(vertsToDecode * dec_->GetDecVtxFmt().stride, bindOffset, buf); } DecodeVerts(dest); + return dest; } void DrawEngineGLES::MarkUnreliable(VertexArrayInfo *vai) { @@ -341,6 +342,8 @@ void DrawEngineGLES::DoFlush() { if (vshader->UseHWTransform()) { int vertexCount = 0; bool useElements = true; + bool populateCache = false; + VertexArrayInfo *vai = nullptr; // Cannot cache vertex data with morph enabled. bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK); @@ -353,7 +356,7 @@ void DrawEngineGLES::DoFlush() { if (useCache) { u32 id = dcid_ ^ gstate.getUVGenMode(); // This can have an effect on which UV decoder we need to use! And hence what the decoded data will look like. See #9263 - VertexArrayInfo *vai = vai_.Get(id); + vai = vai_.Get(id); if (!vai) { vai = new VertexArrayInfo(); vai_.Insert(id, vai); @@ -368,16 +371,8 @@ void DrawEngineGLES::DoFlush() { vai->minihash = ComputeMiniHash(); vai->status = VertexArrayInfo::VAI_HASHING; vai->drawsUntilNextFullHash = 0; - DecodeVerts(decoded); // writes to indexGen - vai->numVerts = indexGen.VertexCount(); - vai->prim = indexGen.Prim(); - vai->maxIndex = indexGen.MaxIndex(); - vai->flags = gstate_c.vertexFullAlpha ? VAI_FLAG_VERTEXFULLALPHA : 0; - - size_t size = decodedVerts_ * dec_->GetDecVtxFmt().stride; - u8 *dest = (u8 *)frameData.pushVertex->Push(size, &vertexBufferOffset, &vertexBuffer); - memcpy(dest, decoded, size); - goto rotateVBO; + useCache = false; + break; } // Hashing - still gaining confidence about the buffer. @@ -397,7 +392,8 @@ void DrawEngineGLES::DoFlush() { } if (newMiniHash != vai->minihash || newHash != vai->hash) { MarkUnreliable(vai); - goto skipVBO; + useCache = false; + break; } if (vai->numVerts > 64) { // exponential backoff up to 16 draws, then every 32 @@ -415,51 +411,27 @@ void DrawEngineGLES::DoFlush() { u32 newMiniHash = ComputeMiniHash(); if (newMiniHash != vai->minihash) { MarkUnreliable(vai); - goto skipVBO; + break; } } if (vai->vbo == nullptr) { - DecodeVerts(decoded); - vai->numVerts = indexGen.VertexCount(); - vai->prim = indexGen.Prim(); - vai->maxIndex = indexGen.MaxIndex(); - vai->flags = gstate_c.vertexFullAlpha ? VAI_FLAG_VERTEXFULLALPHA : 0; - useElements = !indexGen.SeenOnlyPurePrims(); - if (!useElements && indexGen.PureCount()) { - vai->numVerts = indexGen.PureCount(); - } - _dbg_assert_msg_(G3D, gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); - size_t vsz = dec_->GetDecVtxFmt().stride * indexGen.MaxIndex(); - vai->vbo = render_->CreateBuffer(GL_ARRAY_BUFFER, vsz, GL_STATIC_DRAW); - uint8_t *vertexData = new uint8_t[vsz]; - memcpy(vertexData, decoded, vsz); - render_->BufferSubdata(vai->vbo, 0, vsz, vertexData); - // If there's only been one primitive type, and it's either TRIANGLES, LINES or POINTS, - // there is no need for the index buffer we built. We can then use glDrawArrays instead - // for a very minor speed boost. - if (useElements) { - size_t esz = sizeof(short) * indexGen.VertexCount(); - vai->ebo = render_->CreateBuffer(GL_ELEMENT_ARRAY_BUFFER, esz, GL_STATIC_DRAW); - uint8_t *indexData = new uint8_t[esz]; - memcpy(indexData, decIndex, esz); - render_->BufferSubdata(vai->ebo, 0, esz, indexData); - } else { - vai->ebo = 0; - render_->BindIndexBuffer(vai->ebo); - } + // We'll populate the cache this time around, use it next time. + populateCache = true; + useCache = false; } else { gpuStats.numCachedDrawCalls++; useElements = vai->ebo ? true : false; gpuStats.numCachedVertsDrawn += vai->numVerts; gstate_c.vertexFullAlpha = vai->flags & VAI_FLAG_VERTEXFULLALPHA; + + vertexBuffer = vai->vbo; + indexBuffer = vai->ebo; + vertexCount = vai->numVerts; + prim = static_cast(vai->prim); } - vertexBuffer = vai->vbo; - indexBuffer = vai->ebo; - vertexCount = vai->numVerts; - prim = static_cast(vai->prim); break; } @@ -487,13 +459,17 @@ void DrawEngineGLES::DoFlush() { if (vai->lastFrame != gpuStats.numFlips) { vai->numFrames++; } - goto skipVBO; + useCache = false; + break; } } - vai->lastFrame = gpuStats.numFlips; - } else { -skipVBO: + if (useCache) { + vai->lastFrame = gpuStats.numFlips; + } + } + + if (!useCache) { if (g_Config.bSoftwareSkinning && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) { // If software skinning, we've already predecoded into "decoded". So push that content. size_t size = decodedVerts_ * dec_->GetDecVtxFmt().stride; @@ -501,11 +477,25 @@ skipVBO: memcpy(dest, decoded, size); } else { // Decode directly into the pushbuffer - DecodeVertsToPushBuffer(frameData.pushVertex, &vertexBufferOffset, &vertexBuffer); + u8 *dest = (u8 *)DecodeVertsToPushBuffer(frameData.pushVertex, &vertexBufferOffset, &vertexBuffer); + if (populateCache) { + size_t size = decodedVerts_ * dec_->GetDecVtxFmt().stride; + vai->vbo = render_->CreateBuffer(GL_ARRAY_BUFFER, size, GL_STATIC_DRAW); + render_->BufferSubdata(vai->vbo, 0, size, dest, false); + } + } + + if (populateCache || (vai && vai->status == VertexArrayInfo::VAI_NEW)) { + vai->numVerts = indexGen.VertexCount(); + vai->prim = indexGen.Prim(); + vai->maxIndex = indexGen.MaxIndex(); + vai->flags = gstate_c.vertexFullAlpha ? VAI_FLAG_VERTEXFULLALPHA : 0; } -rotateVBO: gpuStats.numUncachedVertsDrawn += indexGen.VertexCount(); + // If there's only been one primitive type, and it's either TRIANGLES, LINES or POINTS, + // there is no need for the index buffer we built. We can then use glDrawArrays instead + // for a very minor speed boost. useElements = !indexGen.SeenOnlyPurePrims(); vertexCount = indexGen.VertexCount(); if (!useElements && indexGen.PureCount()) { @@ -534,7 +524,14 @@ rotateVBO: render_->BindVertexBuffer(inputLayout, vertexBuffer, vertexBufferOffset); if (useElements) { if (!indexBuffer) { - indexBufferOffset = (uint32_t)frameData.pushIndex->Push(decIndex, sizeof(uint16_t) * indexGen.VertexCount(), &indexBuffer); + size_t esz = sizeof(uint16_t) * indexGen.VertexCount(); + void *dest = frameData.pushIndex->Push(esz, &indexBufferOffset, &indexBuffer); + memcpy(dest, decIndex, esz); + + if (populateCache) { + vai->ebo = render_->CreateBuffer(GL_ELEMENT_ARRAY_BUFFER, esz, GL_STATIC_DRAW); + render_->BufferSubdata(vai->ebo, 0, esz, (uint8_t *)dest, false); + } } render_->BindIndexBuffer(indexBuffer); render_->DrawIndexed(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, (GLvoid*)(intptr_t)indexBufferOffset); diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 165329a3d7..70159d7e2e 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -198,7 +198,7 @@ private: GLRInputLayout *SetupDecFmtForDraw(LinkedShader *program, const DecVtxFormat &decFmt); - void DecodeVertsToPushBuffer(GLPushBuffer *push, uint32_t *bindOffset, GLRBuffer **buf); + void *DecodeVertsToPushBuffer(GLPushBuffer *push, uint32_t *bindOffset, GLRBuffer **buf); void FreeVertexArray(VertexArrayInfo *vai); From 61f907fd1836b6c601162819d48399d21015c84d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 18:43:32 -0700 Subject: [PATCH 072/848] GE Debugger: Fix alignment in GE dumps. --- GPU/Debugger/Record.cpp | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/GPU/Debugger/Record.cpp b/GPU/Debugger/Record.cpp index 8d1b216677..1262cf9d48 100644 --- a/GPU/Debugger/Record.cpp +++ b/GPU/Debugger/Record.cpp @@ -155,30 +155,43 @@ static void GetVertDataSizes(int vcount, const void *indices, u32 &vbytes, u32 & } } -static const u8 *mymemmem(const u8 *haystack, size_t hlen, const u8 *needle, size_t nlen) { +static const u8 *mymemmem(const u8 *haystack, size_t off, size_t hlen, const u8 *needle, size_t nlen, uintptr_t align) { if (!nlen) { return nullptr; } const u8 *last_possible = haystack + hlen - nlen; int first = *needle; - const u8 *p = haystack; + const u8 *p = haystack + off; + + const uintptr_t align_mask = align - 1; + auto poffset = [&]() { + return ((uintptr_t)(p - haystack) & align_mask); + }; + auto alignp = [&]() { + uintptr_t offset = poffset(); + if (offset != 0) + p += align - offset; + }; + + alignp(); while (p <= last_possible) { p = (const u8 *)memchr(p, first, last_possible - p + 1); if (!p) { return nullptr; } - if (!memcmp(p, needle, nlen)) { + if (poffset() == 0 && !memcmp(p, needle, nlen)) { return p; } p++; + alignp(); } return nullptr; } -static Command EmitCommandWithRAM(CommandType t, const void *p, u32 sz) { +static Command EmitCommandWithRAM(CommandType t, const void *p, u32 sz, u32 align) { FlushRegisters(); Command cmd{t, sz, 0}; @@ -189,10 +202,10 @@ static Command EmitCommandWithRAM(CommandType t, const void *p, u32 sz) { const size_t NEAR_WINDOW = std::max((int)sz * 2, 1024 * 10); // Let's try nearby first... it will often be nearby. if (pushbuf.size() > NEAR_WINDOW) { - prev = mymemmem(pushbuf.data() + pushbuf.size() - NEAR_WINDOW, NEAR_WINDOW, (const u8 *)p, sz); + prev = mymemmem(pushbuf.data(), pushbuf.size() - NEAR_WINDOW, pushbuf.size(), (const u8 *)p, sz, align); } if (!prev) { - prev = mymemmem(pushbuf.data(), pushbuf.size(), (const u8 *)p, sz); + prev = mymemmem(pushbuf.data(), 0, pushbuf.size(), (const u8 *)p, sz, align); } if (prev) { @@ -200,8 +213,8 @@ static Command EmitCommandWithRAM(CommandType t, const void *p, u32 sz) { } else { cmd.ptr = (u32)pushbuf.size(); int pad = 0; - if (cmd.ptr & 0xF) { - pad = 0x10 - (cmd.ptr & 0xF); + if (cmd.ptr & (align - 1)) { + pad = align - (cmd.ptr & (align - 1)); cmd.ptr += pad; } pushbuf.resize(pushbuf.size() + sz + pad); @@ -269,7 +282,7 @@ static void EmitTextureData(int level, u32 texaddr) { } // Not there, gotta emit anew. - Command cmd = EmitCommandWithRAM(type, p, bytes); + Command cmd = EmitCommandWithRAM(type, p, bytes, 16); lastTextures.push_back(cmd.ptr); } } @@ -302,10 +315,10 @@ static void FlushPrimState(int vcount) { GetVertDataSizes(vcount, indices, vbytes, ibytes); if (indices && ibytes > 0) { - EmitCommandWithRAM(CommandType::INDICES, indices, ibytes); + EmitCommandWithRAM(CommandType::INDICES, indices, ibytes, 4); } if (verts && vbytes > 0) { - EmitCommandWithRAM(CommandType::VERTICES, verts, vbytes); + EmitCommandWithRAM(CommandType::VERTICES, verts, vbytes, 4); } } @@ -330,7 +343,7 @@ static void EmitTransfer(u32 op) { srcBytes = Memory::ValidSize(srcBasePtr, srcBytes); if (srcBytes != 0) { - EmitCommandWithRAM(CommandType::TRANSFERSRC, Memory::GetPointerUnchecked(srcBasePtr), srcBytes); + EmitCommandWithRAM(CommandType::TRANSFERSRC, Memory::GetPointerUnchecked(srcBasePtr), srcBytes, 16); } lastRegisters.push_back(op); @@ -342,7 +355,7 @@ static void EmitClut(u32 op) { bytes = Memory::ValidSize(addr, bytes); if (bytes != 0) { - EmitCommandWithRAM(CommandType::CLUT, Memory::GetPointerUnchecked(addr), bytes); + EmitCommandWithRAM(CommandType::CLUT, Memory::GetPointerUnchecked(addr), bytes, 16); } lastRegisters.push_back(op); @@ -463,7 +476,7 @@ void NotifyMemcpy(u32 dest, u32 src, u32 sz) { sz = Memory::ValidSize(dest, sz); if (sz != 0) { - EmitCommandWithRAM(CommandType::MEMCPYDATA, Memory::GetPointer(dest), sz); + EmitCommandWithRAM(CommandType::MEMCPYDATA, Memory::GetPointer(dest), sz, 1); } } } From 00656a2d8df2401a8920f71ade405395c43b93ef Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 19:39:14 -0700 Subject: [PATCH 073/848] GLES: Avoid duplicate state resets. Between render passes, we don't need to re-disable stencil test each time. Only when it changes. This makes render logs clearer. --- ext/native/thin3d/GLQueueRunner.cpp | 88 ++++++++++++++++++----------- ext/native/thin3d/GLQueueRunner.h | 3 +- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 7be3fd09c2..c67e3fcfc3 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -582,12 +582,26 @@ void GLQueueRunner::RunSteps(const std::vector &steps, bool skipGLCal return; } + size_t totalRenderCount = 0; + for (auto &step : steps) { + if (step->stepType == GLRStepType::RENDER) { + // Skip empty render steps. + if (step->commands.empty()) { + step->stepType = GLRStepType::RENDER_SKIP; + continue; + } + totalRenderCount++; + } + } + CHECK_GL_ERROR_IF_DEBUG(); + size_t renderCount = 0; for (size_t i = 0; i < steps.size(); i++) { const GLRStep &step = *steps[i]; switch (step.stepType) { case GLRStepType::RENDER: - PerformRenderPass(step); + renderCount++; + PerformRenderPass(step, renderCount == 1, renderCount == totalRenderCount); break; case GLRStepType::COPY: PerformCopy(step); @@ -601,6 +615,8 @@ void GLQueueRunner::RunSteps(const std::vector &steps, bool skipGLCal case GLRStepType::READBACK_IMAGE: PerformReadbackImage(step); break; + case GLRStepType::RENDER_SKIP: + break; default: Crash(); break; @@ -644,27 +660,24 @@ void GLQueueRunner::PerformBlit(const GLRStep &step) { } } -void GLQueueRunner::PerformRenderPass(const GLRStep &step) { +void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last) { CHECK_GL_ERROR_IF_DEBUG(); - // Don't execute empty renderpasses. - if (step.commands.empty()) { - // Nothing to do. - return; - } PerformBindFramebufferAsRenderTarget(step); - glDisable(GL_DEPTH_TEST); - glDisable(GL_STENCIL_TEST); - glDisable(GL_BLEND); - glDisable(GL_CULL_FACE); - glDisable(GL_DITHER); - glEnable(GL_SCISSOR_TEST); + if (first) { + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_DITHER); + glEnable(GL_SCISSOR_TEST); #ifndef USING_GLES2 - if (!gl_extensions.IsGLES) { - glDisable(GL_COLOR_LOGIC_OP); - } + if (!gl_extensions.IsGLES) { + glDisable(GL_COLOR_LOGIC_OP); + } #endif + } /* #ifndef USING_GLES2 @@ -678,21 +691,22 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { #endif */ - if (gl_extensions.ARB_vertex_array_object) { + if (first && gl_extensions.ARB_vertex_array_object) { glBindVertexArray(globalVAO_); } GLRProgram *curProgram = nullptr; int activeSlot = 0; - glActiveTexture(GL_TEXTURE0 + activeSlot); + if (first) + glActiveTexture(GL_TEXTURE0 + activeSlot); // State filtering tracking. int attrMask = 0; int colorMask = -1; int depthMask = -1; int depthFunc = -1; - GLuint curArrayBuffer = (GLuint)-1; - GLuint curElemArrayBuffer = (GLuint)-1; + GLuint curArrayBuffer = (GLuint)0; + GLuint curElemArrayBuffer = (GLuint)0; bool depthEnabled = false; bool stencilEnabled = false; bool blendEnabled = false; @@ -929,9 +943,9 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { case GLRRenderCommand::UNIFORMMATRIX: { assert(curProgram); - int loc = c.uniform4.loc ? *c.uniform4.loc : -1; - if (c.uniform4.name) { - loc = curProgram->GetUniformLoc(c.uniform4.name); + int loc = c.uniformMatrix4.loc ? *c.uniformMatrix4.loc : -1; + if (c.uniformMatrix4.name) { + loc = curProgram->GetUniformLoc(c.uniformMatrix4.name); } if (loc >= 0) { glUniformMatrix4fv(loc, 1, false, c.uniformMatrix4.m); @@ -1179,22 +1193,30 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { CHECK_GL_ERROR_IF_DEBUG(); // Wipe out the current state. - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - if (gl_extensions.ARB_vertex_array_object) { + if (curArrayBuffer != 0) + glBindBuffer(GL_ARRAY_BUFFER, 0); + if (curElemArrayBuffer != 0) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + if (last && gl_extensions.ARB_vertex_array_object) { glBindVertexArray(0); } - glDisable(GL_SCISSOR_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_STENCIL_TEST); - glDisable(GL_BLEND); - glDisable(GL_CULL_FACE); + if (last) + glDisable(GL_SCISSOR_TEST); + if (depthEnabled) + glDisable(GL_DEPTH_TEST); + if (stencilEnabled) + glDisable(GL_STENCIL_TEST); + if (blendEnabled) + glDisable(GL_BLEND); + if (cullEnabled) + glDisable(GL_CULL_FACE); #ifndef USING_GLES2 - if (!gl_extensions.IsGLES) { + if (!gl_extensions.IsGLES && logicEnabled) { glDisable(GL_COLOR_LOGIC_OP); } #endif - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + if ((colorMask & 15) != 15) + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); CHECK_GL_ERROR_IF_DEBUG(); } diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index 06ba82af31..8fb5165415 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -276,6 +276,7 @@ enum class GLRStepType : uint8_t { BLIT, READBACK, READBACK_IMAGE, + RENDER_SKIP, }; enum class GLRRenderPassAction { @@ -372,7 +373,7 @@ private: void InitCreateFramebuffer(const GLRInitStep &step); void PerformBindFramebufferAsRenderTarget(const GLRStep &pass); - void PerformRenderPass(const GLRStep &pass); + void PerformRenderPass(const GLRStep &pass, bool first, bool last); void PerformCopy(const GLRStep &pass); void PerformBlit(const GLRStep &pass); void PerformReadback(const GLRStep &pass); From 356468fe83d72388df764dfd724c7d3d05c46576 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 19:58:59 -0700 Subject: [PATCH 074/848] GLES: Use debug groups for render steps. --- ext/native/thin3d/GLQueueRunner.cpp | 27 +++++++++++++++++++++++++++ ext/native/thin3d/GLQueueRunner.h | 1 + 2 files changed, 28 insertions(+) diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index c67e3fcfc3..cb5d63d847 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -56,6 +56,8 @@ void GLQueueRunner::CreateDeviceObjects() { populate(GL_EXTENSIONS); } CHECK_GL_ERROR_IF_DEBUG(); + + useDebugGroups_ = !gl_extensions.IsGLES && gl_extensions.VersionGEThan(4, 3); } void GLQueueRunner::DestroyDeviceObjects() { @@ -132,6 +134,11 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski return; } +#if !defined(USING_GLES2) + if (useDebugGroups_) + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "InitSteps"); +#endif + CHECK_GL_ERROR_IF_DEBUG(); glActiveTexture(GL_TEXTURE0); GLuint boundTexture = (GLuint)-1; @@ -379,6 +386,14 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski WARN_LOG(G3D, "Got an error after init: %08x (%s)", err, GLEnumToString(err).c_str()); } } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + +#if !defined(USING_GLES2) + if (useDebugGroups_) + glPopDebugGroup(); +#endif } void GLQueueRunner::InitCreateFramebuffer(const GLRInitStep &step) { @@ -598,6 +613,12 @@ void GLQueueRunner::RunSteps(const std::vector &steps, bool skipGLCal size_t renderCount = 0; for (size_t i = 0; i < steps.size(); i++) { const GLRStep &step = *steps[i]; + +#if !defined(USING_GLES2) + if (useDebugGroups_) + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, (GLuint)i + 10000, -1, step.tag); +#endif + switch (step.stepType) { case GLRStepType::RENDER: renderCount++; @@ -621,6 +642,12 @@ void GLQueueRunner::RunSteps(const std::vector &steps, bool skipGLCal Crash(); break; } + +#if !defined(USING_GLES2) + if (useDebugGroups_) + glPopDebugGroup(); +#endif + delete steps[i]; } CHECK_GL_ERROR_IF_DEBUG(); diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index 8fb5165415..d62c61e4ba 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -421,4 +421,5 @@ private: std::unordered_map glStrings_; bool sawOutOfMemory_ = false; + bool useDebugGroups_ = false; }; From c8f8d551189eefad0d67343fbe258cec87bb3c48 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 21:36:23 -0700 Subject: [PATCH 075/848] Vulkan: Correct viewport flag reset on rebind. Can't break since we're checking two separate flags. --- ext/native/thin3d/VulkanRenderManager.cpp | 2 -- ext/native/thin3d/thin3d_gl.cpp | 2 +- ext/native/thin3d/thin3d_vulkan.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 0414e8ab33..d85af88469 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -481,10 +481,8 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR for (const auto &c : steps_.back()->commands) { if (c.cmd == VKRRenderCommand::VIEWPORT) { curStepHasViewport_ = true; - break; } else if (c.cmd == VKRRenderCommand::SCISSOR) { curStepHasScissor_ = true; - break; } } if (clearMask != 0) { diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 0bbe2466d5..dd3aa97fb3 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -478,7 +478,7 @@ public: void HandleEvent(Event ev, int width, int height, void *param1, void *param2) override {} - int GetCurrentStepId() const { + int GetCurrentStepId() const override { return renderManager_.GetCurrentStepId(); } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 43fe931f6c..e7f569d7ea 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -482,7 +482,7 @@ public: void HandleEvent(Event ev, int width, int height, void *param1, void *param2) override; - int GetCurrentStepId() const { + int GetCurrentStepId() const override { return renderManager_.GetCurrentStepId(); } From 24c844445ee980fcad9ec62814a269fbbe2f7388 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 22:39:29 -0700 Subject: [PATCH 076/848] GPU: Don't allow step id to decrease at a sync. This might've caused us to miss necessary dynamic state dirtying in games, but only in fairly specific cases. But it happens a lot when stepping via the GE debugger. --- ext/native/thin3d/GLRenderManager.cpp | 3 +++ ext/native/thin3d/GLRenderManager.h | 4 +++- ext/native/thin3d/VulkanRenderManager.cpp | 3 +++ ext/native/thin3d/VulkanRenderManager.h | 4 +++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index f04d8f9390..3ceb142b69 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -442,6 +442,7 @@ void GLRenderManager::BeginFrame() { // In GL, we have to do deletes on the submission thread. insideFrame_ = true; + renderStepOffset_ = 0; } void GLRenderManager::Finish() { @@ -565,6 +566,8 @@ void GLRenderManager::Run(int frame) { void GLRenderManager::FlushSync() { // TODO: Reset curRenderStep_? + renderStepOffset_ += (int)steps_.size(); + int curFrame = curFrame_; FrameData &frameData = frameData_[curFrame]; { diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index a31ab31b23..eac80eac6f 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -940,7 +940,7 @@ public: // Gets a frame-unique ID of the current step being recorded. Can be used to figure out // when the current step has changed, which means the caller will need to re-record its state. int GetCurrentStepId() const { - return (int)steps_.size(); + return renderStepOffset_ + (int)steps_.size(); } private: @@ -989,6 +989,8 @@ private: // Submission time state bool insideFrame_ = false; + // This is the offset within this frame, in case of a mid-frame sync. + int renderStepOffset_ = 0; GLRStep *curRenderStep_ = nullptr; std::vector steps_; std::vector initSteps_; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index d85af88469..7addb203a9 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -422,6 +422,7 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) { vulkan_->BeginFrame(); insideFrame_ = true; + renderStepOffset_ = 0; frameData.profile.timestampDescriptions.clear(); if (frameData_->profilingEnabled_) { @@ -1173,6 +1174,8 @@ void VulkanRenderManager::EndSyncFrame(int frame) { void VulkanRenderManager::FlushSync() { // TODO: Reset curRenderStep_? + renderStepOffset_ += (int)steps_.size(); + int curFrame = vulkan_->GetCurFrame(); FrameData &frameData = frameData_[curFrame]; if (!useThread_) { diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index fc4b3fc7da..391d559f61 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -254,7 +254,7 @@ public: // Gets a frame-unique ID of the current step being recorded. Can be used to figure out // when the current step has changed, which means the caller will need to re-record its state. int GetCurrentStepId() const { - return (int)steps_.size(); + return renderStepOffset_ + (int)steps_.size(); } void CreateBackbuffers(); @@ -341,6 +341,8 @@ private: int curWidth_ = -1; int curHeight_ = -1; bool insideFrame_ = false; + // This is the offset within this frame, in case of a mid-frame sync. + int renderStepOffset_ = 0; VKRStep *curRenderStep_ = nullptr; bool curStepHasViewport_ = false; bool curStepHasScissor_ = false; From e8b651fbd62d3e394164fb566fca92846bc4d9a3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 00:02:34 -0700 Subject: [PATCH 077/848] Thread: Default to kernel threads from kernel. This is an experiment. In most cases, allowKernel will be false. --- Core/HLE/sceKernelModule.cpp | 14 +++++++++++++- Core/HLE/sceKernelModule.h | 1 + Core/HLE/sceKernelThread.cpp | 17 ++++++++++++----- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 1d37b3c802..31d18cf2f4 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -66,7 +66,8 @@ #include "GPU/GPUState.h" enum { - PSP_THREAD_ATTR_USER = 0x80000000 + PSP_THREAD_ATTR_KERNEL = 0x00001000, + PSP_THREAD_ATTR_USER = 0x80000000, }; enum { @@ -1593,6 +1594,7 @@ static void __KernelStartModule(PSPModule *m, int args, const char *argp, SceKer currentMIPS->pc = m->nm.module_start_func; } + WARN_LOG(SCEKERNEL, "Root thread attr: %08x", options->attribute); SceUID threadID = __KernelSetupRootThread(m->GetUID(), args, argp, options->priority, options->stacksize, options->attribute); __KernelSetThreadRA(threadID, NID_MODULERETURN); } @@ -1608,6 +1610,16 @@ u32 __KernelGetModuleGP(SceUID uid) { } } +bool KernelModuleIsKernelMode(SceUID uid) { + u32 error; + PSPModule *module = kernelObjects.Get(uid, error); + if (module) { + return (module->nm.attribute & 0x1000) != 0; + } else { + return false; + } +} + void __KernelLoadReset() { // Wipe kernel here, loadexec should reset the entire system if (__KernelIsRunning()) { diff --git a/Core/HLE/sceKernelModule.h b/Core/HLE/sceKernelModule.h index 232c71d23f..e6fabd9829 100644 --- a/Core/HLE/sceKernelModule.h +++ b/Core/HLE/sceKernelModule.h @@ -39,6 +39,7 @@ void __KernelModuleDoState(PointerWrap &p); void __KernelModuleShutdown(); u32 __KernelGetModuleGP(SceUID module); +bool KernelModuleIsKernelMode(SceUID module); bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_string); bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string); void __KernelGPUReplay(); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 698b80c44b..2a28d5d9b6 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1959,9 +1959,15 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 // Some are USB/VSH specific, probably removes when they are from the wrong module? attr &= ~PSP_THREAD_ATTR_USER_ERASE; - // We're assuming all threads created are user threads. - if ((attr & PSP_THREAD_ATTR_KERNEL) == 0) - attr |= PSP_THREAD_ATTR_USER; + if ((attr & PSP_THREAD_ATTR_KERNEL) == 0) { + if (allowKernel && (attr & PSP_THREAD_ATTR_USER) == 0) { + WARN_LOG(SCEKERNEL, "sceKernelCreateThread: Kernel allowed, so creating as a kernel thread"); + attr |= PSP_THREAD_ATTR_KERNEL; + } else { + WARN_LOG(SCEKERNEL, "sceKernelCreateThread: Kernel not allowed, so creating as a user thread"); + attr |= PSP_THREAD_ATTR_USER; + } + } SceUID id = __KernelCreateThreadInternal(threadName, moduleID, entry, prio, stacksize, attr); if ((u32)id == SCE_KERNEL_ERROR_NO_MEMORY) @@ -1986,8 +1992,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) { PSPThread *cur = __GetCurrentThread(); - bool allowKernel = cur ? (cur->nt.attr & PSP_THREAD_ATTR_KERNEL) != 0 : false; - return __KernelCreateThread(threadName, __KernelGetCurThreadModuleId(), entry, prio, stacksize, attr, optionAddr, allowKernel); + SceUID module = __KernelGetCurThreadModuleId(); + bool allowKernel = KernelModuleIsKernelMode(module) || hleIsKernelMode() || (cur ? (cur->nt.attr & PSP_THREAD_ATTR_KERNEL) != 0 : false); + return __KernelCreateThread(threadName, module, entry, prio, stacksize, attr, optionAddr, allowKernel); } int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs) { From c46015e23792efcd84b5cdebe379d4961aae068b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 09:16:03 -0700 Subject: [PATCH 078/848] UWP: Fix TextDrawer with latest changes. --- ext/native/gfx_es2/draw_text_uwp.cpp | 281 ++++++++++++++------------- ext/native/gfx_es2/draw_text_uwp.h | 2 +- 2 files changed, 144 insertions(+), 139 deletions(-) diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index 52183a5c40..a78240b227 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -1,3 +1,4 @@ +#include #include "base/display.h" #include "base/logging.h" #include "base/stringutil.h" @@ -243,18 +244,22 @@ void TextDrawerUWP::MeasureString(const char *str, size_t len, float *w, float * } void TextDrawerUWP::MeasureStringRect(const char *str, size_t len, const Bounds &bounds, float *w, float *h, int align) { - - IDWriteTextFormat* format = nullptr; + IDWriteTextFormat *format = nullptr; auto iter = fontMap_.find(fontHash_); if (iter != fontMap_.end()) { format = iter->second->textFmt; } - if (!format) return; + if (!format) { + *w = 0; + *h = 0; + return; + } std::string toMeasure = std::string(str, len); - if (align & FLAG_WRAP_TEXT) { + int wrap = align & (FLAG_WRAP_TEXT | FLAG_ELLIPSIZE_TEXT); + if (wrap) { bool rotated = (align & (ROTATE_90DEG_LEFT | ROTATE_90DEG_RIGHT)) != 0; - WrapString(toMeasure, toMeasure.c_str(), rotated ? bounds.h : bounds.w); + WrapString(toMeasure, toMeasure.c_str(), rotated ? bounds.h : bounds.w, wrap); } std::vector lines; @@ -308,13 +313,131 @@ void TextDrawerUWP::MeasureStringRect(const char *str, size_t len, const Bounds *h = total_h * dpiScale_; } +void TextDrawerUWP::DrawStringBitmap(std::vector &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, const char *str, int align) { + if (!strlen(str)) { + bitmapData.clear(); + return; + } + + std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(ReplaceAll(str, "\n", "\r\n"), "&&", "&")); + SIZE size; + + IDWriteTextFormat *format = nullptr; + auto iter = fontMap_.find(fontHash_); + if (iter != fontMap_.end()) { + format = iter->second->textFmt; + } + if (!format) { + bitmapData.clear(); + return; + } + + if (align & ALIGN_HCENTER) + format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); + else if (align & ALIGN_LEFT) + format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); + else if (align & ALIGN_RIGHT) + format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_TRAILING); + + IDWriteTextLayout *layout; + m_dwriteFactory->CreateTextLayout( + (LPWSTR)wstr.c_str(), + (int)wstr.size(), + format, + MAX_TEXT_WIDTH, + MAX_TEXT_HEIGHT, + &layout + ); + + DWRITE_TEXT_METRICS metrics; + layout->GetMetrics(&metrics); + + // Set the max size the same as current size, avoiding alignment issues + layout->SetMaxHeight(metrics.height); + layout->SetMaxWidth(metrics.width); + + size.cx = metrics.width + 1; + size.cy = metrics.height + 1; + + // Prevent zero-sized textures, which can occur. Not worth to avoid + // creating the texture altogether in this case. One example is a string + // containing only '\r\n', see issue #10764. + if (size.cx == 0) + size.cx = 1; + if (size.cy == 0) + size.cy = 1; + + entry.texture = nullptr; + entry.width = size.cx; + entry.height = size.cy; + entry.bmWidth = (size.cx + 3) & ~3; + entry.bmHeight = (size.cy + 3) & ~3; + entry.lastUsedFrame = frameCount_; + + m_d2dContext->BeginDraw(); + m_d2dContext->Clear(); + m_d2dContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), layout, m_d2dWhiteBrush); + m_d2dContext->EndDraw(); + + layout->Release(); + + D2D1_POINT_2U dstP = D2D1::Point2U(0, 0); + D2D1_RECT_U srcR = D2D1::RectU(0, 0, entry.bmWidth, entry.bmHeight); + D2D1_MAPPED_RECT map; + ctx_->mirror_bmp->CopyFromBitmap(&dstP, ctx_->bitmap, &srcR); + ctx_->mirror_bmp->Map(D2D1_MAP_OPTIONS_READ, &map); + + // Convert the bitmap to a Thin3D compatible array of 16-bit pixels. Can't use a single channel format + // because we need white. Well, we could using swizzle, but not all our backends support that. + if (texFormat == Draw::DataFormat::R8G8B8A8_UNORM || texFormat == Draw::DataFormat::B8G8R8A8_UNORM) { + bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint32_t)); + uint32_t *bitmapData32 = (uint32_t *)&bitmapData[0]; + for (int y = 0; y < entry.bmHeight; y++) { + for (int x = 0; x < entry.bmWidth; x++) { + uint8_t bAlpha = (uint8_t)(map.bits[map.pitch * y + x * 4] & 0xff); + bitmapData32[entry.bmWidth * y + x] = (bAlpha << 24) | 0x00ffffff; + } + } + } else if (texFormat == Draw::DataFormat::B4G4R4A4_UNORM_PACK16 || texFormat == Draw::DataFormat::R4G4B4A4_UNORM_PACK16) { + bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint16_t)); + uint16_t *bitmapData16 = (uint16_t *)&bitmapData[0]; + for (int y = 0; y < entry.bmHeight; y++) { + for (int x = 0; x < entry.bmWidth; x++) { + uint8_t bAlpha = (uint8_t)((map.bits[map.pitch * y + x * 4] & 0xff) >> 4); + bitmapData16[entry.bmWidth * y + x] = (bAlpha) | 0xfff0; + } + } + } else if (texFormat == Draw::DataFormat::A4R4G4B4_UNORM_PACK16) { + bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint16_t)); + uint16_t *bitmapData16 = (uint16_t *)&bitmapData[0]; + for (int y = 0; y < entry.bmHeight; y++) { + for (int x = 0; x < entry.bmWidth; x++) { + uint8_t bAlpha = (uint8_t)((map.bits[map.pitch * y + x * 4] & 0xff) >> 4); + bitmapData16[entry.bmWidth * y + x] = (bAlpha << 12) | 0x0fff; + } + } + } else if (texFormat == Draw::DataFormat::R8_UNORM) { + bitmapData.resize(entry.bmWidth * entry.bmHeight); + for (int y = 0; y < entry.bmHeight; y++) { + for (int x = 0; x < entry.bmWidth; x++) { + uint8_t bAlpha = (uint8_t)(map.bits[map.pitch * y + x * 4] & 0xff); + bitmapData[entry.bmWidth * y + x] = bAlpha; + } + } + } else { + ELOG("Bad TextDrawer format"); + assert(false); + } + + ctx_->mirror_bmp->Unmap(); +} + void TextDrawerUWP::DrawString(DrawBuffer &target, const char *str, float x, float y, uint32_t color, int align) { using namespace Draw; if (!strlen(str)) return; CacheKey key{ std::string(str), fontHash_ }; - target.Flush(true); TextStringEntry *entry; @@ -323,74 +446,7 @@ void TextDrawerUWP::DrawString(DrawBuffer &target, const char *str, float x, flo if (iter != cache_.end()) { entry = iter->second.get(); entry->lastUsedFrame = frameCount_; - } - else { - // Render the string to our bitmap and save to a GL texture. - std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(ReplaceAll(str, "\n", "\r\n"), "&&", "&")); - SIZE size; - - IDWriteTextFormat* format = nullptr; - auto iter = fontMap_.find(fontHash_); - if (iter != fontMap_.end()) { - format = iter->second->textFmt; - } - if (!format) return; - - if (align & ALIGN_HCENTER) - format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); - else if (align & ALIGN_LEFT) - format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); - else if (align & ALIGN_RIGHT) - format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_TRAILING); - - IDWriteTextLayout* layout; - m_dwriteFactory->CreateTextLayout( - (LPWSTR)wstr.c_str(), - (int)wstr.size(), - format, - MAX_TEXT_WIDTH, - MAX_TEXT_HEIGHT, - &layout - ); - - DWRITE_TEXT_METRICS metrics; - layout->GetMetrics(&metrics); - - // Set the max size the same as current size, avoiding alignment issues - layout->SetMaxHeight(metrics.height); - layout->SetMaxWidth(metrics.width); - - size.cx = metrics.width + 1; - size.cy = metrics.height + 1; - - // Prevent zero-sized textures, which can occur. Not worth to avoid - // creating the texture altogether in this case. One example is a string - // containing only '\r\n', see issue #10764. - if (size.cx == 0) - size.cx = 1; - if (size.cy == 0) - size.cy = 1; - - entry = new TextStringEntry(); - entry->width = size.cx; - entry->height = size.cy; - entry->bmWidth = (size.cx + 3) & ~3; - entry->bmHeight = (size.cy + 3) & ~3; - entry->lastUsedFrame = frameCount_; - - m_d2dContext->BeginDraw(); - m_d2dContext->Clear(); - m_d2dContext->DrawTextLayout(D2D1::Point2F(0.0f, 0.0f), layout, m_d2dWhiteBrush); - m_d2dContext->EndDraw(); - - layout->Release(); - - D2D1_POINT_2U dstP = D2D1::Point2U(0, 0); - D2D1_RECT_U srcR = D2D1::RectU(0, 0, entry->bmWidth, entry->bmHeight); - D2D1_MAPPED_RECT map; - ctx_->mirror_bmp->CopyFromBitmap(&dstP, ctx_->bitmap, &srcR); - ctx_->mirror_bmp->Map(D2D1_MAP_OPTIONS_READ, &map); - + } else { DataFormat texFormat; // For our purposes these are equivalent, so just choose the supported one. D3D can emulate them. if (draw_->GetDataFormatSupport(Draw::DataFormat::A4R4G4B4_UNORM_PACK16) & FMT_TEXTURE) @@ -400,41 +456,14 @@ void TextDrawerUWP::DrawString(DrawBuffer &target, const char *str, float x, flo else texFormat = Draw::DataFormat::R8G8B8A8_UNORM; + entry = new TextStringEntry(); + // Convert the bitmap to a Thin3D compatible array of 16-bit pixels. Can't use a single channel format // because we need white. Well, we could using swizzle, but not all our backends support that. TextureDesc desc{}; - uint32_t *bitmapData32 = nullptr; - uint16_t *bitmapData16 = nullptr; - if (texFormat == Draw::DataFormat::R8G8B8A8_UNORM || texFormat == Draw::DataFormat::B8G8R8A8_UNORM) { - bitmapData32 = new uint32_t[entry->bmWidth * entry->bmHeight]; - for (int y = 0; y < entry->bmHeight; y++) { - for (int x = 0; x < entry->bmWidth; x++) { - uint8_t bAlpha = (uint8_t)(map.bits[map.pitch * y + x * 4] & 0xff); - bitmapData32[entry->bmWidth * y + x] = (bAlpha << 24) | 0x00ffffff; - } - } - desc.initData.push_back((uint8_t *)bitmapData32); - } else if (texFormat == Draw::DataFormat::B4G4R4A4_UNORM_PACK16) { - bitmapData16 = new uint16_t[entry->bmWidth * entry->bmHeight]; - for (int y = 0; y < entry->bmHeight; y++) { - for (int x = 0; x < entry->bmWidth; x++) { - uint8_t bAlpha = (uint8_t)((map.bits[map.pitch * y + x * 4] & 0xff) >> 4); - bitmapData16[entry->bmWidth * y + x] = (bAlpha) | 0xfff0; - } - } - desc.initData.push_back((uint8_t *)bitmapData16); - } else if (texFormat == Draw::DataFormat::A4R4G4B4_UNORM_PACK16) { - bitmapData16 = new uint16_t[entry->bmWidth * entry->bmHeight]; - for (int y = 0; y < entry->bmHeight; y++) { - for (int x = 0; x < entry->bmWidth; x++) { - uint8_t bAlpha = (uint8_t)((map.bits[map.pitch * y + x * 4] & 0xff) >> 4); - bitmapData16[entry->bmWidth * y + x] = (bAlpha << 12) | 0x0fff; - } - } - desc.initData.push_back((uint8_t *)bitmapData16); - } - - ctx_->mirror_bmp->Unmap(); + std::vector bitmapData; + DrawStringBitmap(bitmapData, *entry, texFormat, str, align); + desc.initData.push_back(&bitmapData[0]); desc.type = TextureType::LINEAR2D; desc.format = texFormat; @@ -444,14 +473,12 @@ void TextDrawerUWP::DrawString(DrawBuffer &target, const char *str, float x, flo desc.mipLevels = 1; desc.tag = "TextDrawer"; entry->texture = draw_->CreateTexture(desc); - if (bitmapData16) - delete[] bitmapData16; - if (bitmapData32) - delete[] bitmapData32; cache_[key] = std::unique_ptr(entry); } - draw_->BindTexture(0, entry->texture); + if (entry->texture) { + draw_->BindTexture(0, entry->texture); + } // Okay, the texture is bound, let's draw. float w = entry->width * fontScaleX_ * dpiScale_; @@ -459,13 +486,14 @@ void TextDrawerUWP::DrawString(DrawBuffer &target, const char *str, float x, flo float u = entry->width / (float)entry->bmWidth; float v = entry->height / (float)entry->bmHeight; DrawBuffer::DoAlign(align, &x, &y, &w, &h); - target.DrawTexRect(x, y, x + w, y + h, 0.0f, 0.0f, u, v, color); - target.Flush(true); - + if (entry->texture) { + target.DrawTexRect(x, y, x + w, y + h, 0.0f, 0.0f, u, v, color); + target.Flush(true); + } } void TextDrawerUWP::RecreateFonts() { - for (auto& iter : fontMap_) { + for (auto &iter : fontMap_) { iter.second->dpiScale = dpiScale_; iter.second->Create(); } @@ -480,29 +508,6 @@ void TextDrawerUWP::ClearCache() { sizeCache_.clear(); } -void TextDrawerUWP::DrawStringRect(DrawBuffer &target, const char *str, const Bounds &bounds, uint32_t color, int align) { - float x = bounds.x; - float y = bounds.y; - if (align & ALIGN_HCENTER) { - x = bounds.centerX(); - } else if (align & ALIGN_RIGHT) { - x = bounds.x2(); - } - if (align & ALIGN_VCENTER) { - y = bounds.centerY(); - } else if (align & ALIGN_BOTTOM) { - y = bounds.y2(); - } - - std::string toDraw = str; - if (align & FLAG_WRAP_TEXT) { - bool rotated = (align & (ROTATE_90DEG_LEFT | ROTATE_90DEG_RIGHT)) != 0; - WrapString(toDraw, str, rotated ? bounds.h : bounds.w); - } - - DrawString(target, toDraw.c_str(), x, y, color, align); -} - void TextDrawerUWP::OncePerFrame() { frameCount_++; // If DPI changed (small-mode, future proper monitor DPI support), drop everything. diff --git a/ext/native/gfx_es2/draw_text_uwp.h b/ext/native/gfx_es2/draw_text_uwp.h index 0697ea62d6..59995f491b 100644 --- a/ext/native/gfx_es2/draw_text_uwp.h +++ b/ext/native/gfx_es2/draw_text_uwp.h @@ -24,7 +24,7 @@ public: void MeasureString(const char *str, size_t len, float *w, float *h) override; void MeasureStringRect(const char *str, size_t len, const Bounds &bounds, float *w, float *h, int align = ALIGN_TOPLEFT) override; void DrawString(DrawBuffer &target, const char *str, float x, float y, uint32_t color, int align = ALIGN_TOPLEFT) override; - void DrawStringRect(DrawBuffer &target, const char *str, const Bounds &bounds, uint32_t color, int align) override; + void DrawStringBitmap(std::vector &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, const char *str, int align = ALIGN_TOPLEFT) override; // Use for housekeeping like throwing out old strings. void OncePerFrame() override; From f23235245765e1513287825a6a9817bf2693a6eb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 09:34:52 -0700 Subject: [PATCH 079/848] UWP: Include TextDrawer in main MSVC project. --- ext/native/native.vcxproj | 2 ++ ext/native/native.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 60f361b959..919ce1166b 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -426,6 +426,7 @@ + @@ -1137,6 +1138,7 @@ + diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 9c6af13184..91a926358b 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -353,6 +353,9 @@ util + + gfx + @@ -835,6 +838,9 @@ ui + + gfx + From b97fbcb4629d2e169bce26832948bb06f2e21050 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 09:19:26 -0700 Subject: [PATCH 080/848] UWP: Add libpng17 include path. --- UWP/CoreUWP/CoreUWP.vcxproj | 24 ++++++++++++------------ UWP/NativeUWP/NativeUWP.vcxproj | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 0bbac0c46e..75b8b2c4c5 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -204,7 +204,7 @@ false true pch.h - ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -219,7 +219,7 @@ false true pch.h - ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -234,7 +234,7 @@ false true pch.h - ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -249,7 +249,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -264,7 +264,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -279,7 +279,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -294,7 +294,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -309,7 +309,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -324,7 +324,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -339,7 +339,7 @@ false true pch.h - ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -354,7 +354,7 @@ false true pch.h - ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -369,7 +369,7 @@ false true pch.h - ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index f6adacf851..a25e4fbd1a 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -204,7 +204,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -219,7 +219,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -234,7 +234,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -249,7 +249,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -264,7 +264,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -279,7 +279,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -294,7 +294,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -309,7 +309,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -324,7 +324,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -339,7 +339,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -354,7 +354,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -369,7 +369,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) From 1b6b0c16497d53a2aad64f296b214819bc10219a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 09:21:24 -0700 Subject: [PATCH 081/848] UWP: Buildfix for controller vibration. --- Windows/XinputDevice.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 7da92f221c..4693dd6e24 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -15,6 +15,8 @@ #include "Core/HLE/sceCtrl.h" #include "Common/Timer.h" +static int newVibrationTime = 0; + // Utilities to dynamically load XInput. Adapted from SDL. #if !PPSSPP_PLATFORM(UWP) @@ -27,7 +29,6 @@ static XInputSetState_t PPSSPP_XInputSetState = NULL; static DWORD PPSSPP_XInputVersion = 0; static HMODULE s_pXInputDLL = 0; static int s_XInputDLLRefCount = 0; -static int newVibrationTime = 0; static void UnloadXInputDLL(); From 8f2fb0530c423e72867b65559047476af9ad17b9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 09:56:21 -0700 Subject: [PATCH 082/848] UWP: Stub new inputbox system func. --- UWP/PPSSPP_UWPMain.cpp | 9 +++------ libretro/libretro.cpp | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 35739b4dc8..92c877ed0b 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -473,12 +473,9 @@ PermissionStatus System_GetPermissionStatus(SystemPermission permission) { return PERMISSION_STATUS_GRANTED; } -bool System_InputBoxGetString(const char *title, const char *defaultValue, char *outValue, size_t outLength) { - return false; -} - -bool System_InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue) { - return false; +void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function cb) { + // TODO + cb(false, ""); } std::string GetCPUBrandString() { diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 9f29455794..b188283a2f 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -801,7 +801,6 @@ void System_SendMessage(const char *command, const char *parameter) {} void NativeUpdate() {} void NativeRender(GraphicsContext *graphicsContext) {} void NativeResized() {} -bool System_InputBoxGetWString(const wchar_t *title, const std::wstring &defaultvalue, std::wstring &outvalue) { return false; } #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) std::vector __cameraGetDeviceList() { return std::vector(); } From e299eb8743bd74c7ea8dc512fbbdfff24b0a80de Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 09:56:40 -0700 Subject: [PATCH 083/848] UWP: Link ChatScreen. --- UWP/UI_UWP/UI_UWP.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UWP/UI_UWP/UI_UWP.vcxproj b/UWP/UI_UWP/UI_UWP.vcxproj index 120a7b5f86..9db7ab4ac7 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj +++ b/UWP/UI_UWP/UI_UWP.vcxproj @@ -380,6 +380,7 @@ + @@ -414,6 +415,7 @@ + From 085a9ec0ce7b78bc492d6b18541749e661ec3515 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 08:48:52 -0700 Subject: [PATCH 084/848] Travis: Build UWP also. --- .travis.sh | 6 +++++- .travis.yml | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.travis.sh b/.travis.sh index 5e6afecd23..eaa0e8eaf0 100644 --- a/.travis.sh +++ b/.travis.sh @@ -171,7 +171,11 @@ travis_script() { sed -i 's/>ProgramDatabase<\/DebugInformationFormat>/><\/DebugInformationFormat>/g' $f done - msbuild.exe Windows\\PPSSPP.sln -m -p:CLToolExe=clcache.exe -p:Configuration=Release -p:Platform=x64 -p:TrackFileAccess=false + if [ "$UWP" == "TRUE" ]; then + msbuild.exe UWP\\PPSSPP_UWP.sln -m -p:CLToolExe=clcache.exe -p:Configuration=Release -p:Platform=x64 -p:TrackFileAccess=false -p:AppxPackageSigningEnabled=false + else + msbuild.exe Windows\\PPSSPP.sln -m -p:CLToolExe=clcache.exe -p:Configuration=Release -p:Platform=x64 -p:TrackFileAccess=false + fi fi } diff --git a/.travis.yml b/.travis.yml index b5fc79998f..9057234e50 100644 --- a/.travis.yml +++ b/.travis.yml @@ -96,6 +96,10 @@ jobs: - os: windows compiler: "msvc2017" env: PPSSPP_BUILD_TYPE=Windows + - os: windows + compiler: "msvc2017" + env: PPSSPP_BUILD_TYPE=Windows + UWP=TRUE before_install: - travis_retry bash .travis.sh travis_before_install From c90c29df32190c0f8c8c2a67402b8e9765e722e2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 12:04:18 -0700 Subject: [PATCH 085/848] Vulkan: Trivially kill more empty steps. Just in case we have a DONT_CARE step. --- ext/native/thin3d/VulkanRenderManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 7addb203a9..8290195a9b 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -499,7 +499,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR } // More redundant bind elimination. - if (curRenderStep_ && curRenderStep_->commands.size() == 0 && curRenderStep_->render.color == VKRRenderPassAction::KEEP && curRenderStep_->render.depth == VKRRenderPassAction::KEEP && curRenderStep_->render.stencil == VKRRenderPassAction::KEEP) { + if (curRenderStep_ && curRenderStep_->commands.size() == 0 && curRenderStep_->render.color != VKRRenderPassAction::CLEAR && curRenderStep_->render.depth != VKRRenderPassAction::CLEAR && curRenderStep_->render.stencil != VKRRenderPassAction::CLEAR) { // Can trivially kill the last empty render step. assert(steps_.back() == curRenderStep_); delete steps_.back(); From 40a0525aeacc729477de0f78d1255842355f72b6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 12:14:03 -0700 Subject: [PATCH 086/848] Vulkan: Ensure depth/stencil load match on Mali. --- GPU/Vulkan/StencilBufferVulkan.cpp | 3 +-- ext/native/thin3d/VulkanRenderManager.cpp | 27 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index ebcec6c41e..6587069149 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -171,9 +171,8 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp return false; if (dstBuffer->fbo) { - // Use keep because some drivers have trouble when stencilAction != depthAction. // Typically, STENCIL_IS_ZERO means it's already bound, so this bind will be optimized away. - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "Stencil"); + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::DONT_CARE }, "Stencil"); } else { // something is wrong... } diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 8290195a9b..474ed3a2f0 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -510,6 +510,23 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR VLOG("Empty render step. Usually happens after uploading pixels.."); } + // Older Mali drivers have issues with depth and stencil don't match load/clear/etc. + // TODO: Determine which versions and do this only where necessary. + u32 lateClearMask = 0; + if (depth != stencil && vulkan_->GetPhysicalDeviceProperties().properties.vendorID == VULKAN_VENDOR_ARM) { + if (stencil == VKRRenderPassAction::DONT_CARE) { + stencil = depth; + } else if (depth == VKRRenderPassAction::DONT_CARE) { + depth = stencil; + } else if (stencil == VKRRenderPassAction::CLEAR) { + depth = stencil; + lateClearMask |= VK_IMAGE_ASPECT_STENCIL_BIT; + } else if (depth == VKRRenderPassAction::CLEAR) { + stencil = depth; + lateClearMask |= VK_IMAGE_ASPECT_DEPTH_BIT; + } + } + VKRStep *step = new VKRStep{ VKRStepType::RENDER }; step->render.framebuffer = fb; step->render.color = color; @@ -541,6 +558,16 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR curWidth_ = vulkan_->GetBackbufferWidth(); curHeight_ = vulkan_->GetBackbufferHeight(); } + + // See above - we add a clear afterward if only one side for depth/stencil CLEAR/KEEP. + if (lateClearMask != 0) { + VkRenderData data{ VKRRenderCommand::CLEAR }; + data.clear.clearColor = clearColor; + data.clear.clearZ = clearDepth; + data.clear.clearStencil = clearStencil; + data.clear.clearMask = lateClearMask; + curRenderStep_->commands.push_back(data); + } } bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { From 0edc3fa8696a124f71953fbfab047ac940122ef4 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 15:10:55 -0700 Subject: [PATCH 087/848] UWP: Fix safe insets. --- UWP/PPSSPP_UWPMain.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 92c877ed0b..24f3b964d1 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -377,6 +377,11 @@ float System_GetPropertyFloat(SystemProperty prop) { switch (prop) { case SYSPROP_DISPLAY_REFRESH_RATE: return 60.f; + case SYSPROP_DISPLAY_SAFE_INSET_LEFT: + case SYSPROP_DISPLAY_SAFE_INSET_RIGHT: + case SYSPROP_DISPLAY_SAFE_INSET_TOP: + case SYSPROP_DISPLAY_SAFE_INSET_BOTTOM: + return 0.0f; default: return -1; } From 3cf2e7edca0d28bed0879278c2c70a0072e993dd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 25 May 2020 17:16:57 -0700 Subject: [PATCH 088/848] Android: Request stable layout and update on focus. This seems to keep immersive better when switching apps. --- android/src/org/ppsspp/ppsspp/NativeActivity.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index 2b6f2d4890..ac272d2d75 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -412,7 +412,9 @@ public abstract class NativeActivity extends Activity { flags |= View.SYSTEM_UI_FLAG_LOW_PROFILE; } if (useImmersive()) { - flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; + flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; + flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; + flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; } View decorView = getWindow().peekDecorView(); @@ -536,6 +538,9 @@ public abstract class NativeActivity extends Activity { public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); updateSustainedPerformanceMode(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + updateSystemUiVisibility(); + } } public void notifySurface(Surface surface) { From 2ba65c831a6dc441f0b349fc729eb652fe41d2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 26 May 2020 23:10:28 +0200 Subject: [PATCH 089/848] Fix minor bug in StereoResampler debug display --- Core/HW/StereoResampler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index a6e06fafcf..27617e3ba7 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -179,7 +179,9 @@ unsigned int StereoResampler::Mix(short* samples, unsigned int numSamples, bool u32 indexW = m_indexW.load(); const int INDEX_MASK = (m_maxBufsize * 2 - 1); - lastBufSize_ = (indexR - m_indexW) & INDEX_MASK; + + // This is only for debug visualization, not used for anything. + lastBufSize_ = ((indexW - indexR) & INDEX_MASK) / 2; // Drift prevention mechanism. float numLeft = (float)(((indexW - indexR) & INDEX_MASK) / 2); From 751136f2e2183f5b5f8b7f3d77ade807b4d692bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 28 May 2020 23:00:51 +0200 Subject: [PATCH 090/848] Time to update gradle again (Android Studio 4.0 was released) --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 8e0dd83012..c28ec21af5 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.6.3' + classpath 'com.android.tools.build:gradle:4.0.0' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2f632ddb58..3967b35ba1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Feb 25 00:57:06 CET 2020 +#Thu May 28 22:53:27 CEST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip From 6f07e2b48b689eceb0ec437ae9c7fb85cac4749c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 29 May 2020 09:44:04 +0200 Subject: [PATCH 091/848] Experimentally enable pixel-depth-rounding for Tales of Phantasia, tries to work around an Exynos driver bug. See #12890. --- assets/compat.ini | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 49a228e5ed..4324accfed 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -84,6 +84,15 @@ NPJH50579 = true NPJH50558 = true ULJS00456 = true ULJS00454 = true + +# Tales of Phantasia: Full Voice Edition +# Attempted workaround for stencil testing driver bug on Arm Exynos (similar to the previous Adreno bug). +# Seems that writing to depth disables a faulty optimization it's trying to do (as we saw in stencil draw). +ULJS00079 = true +ULJS19016 = true +UCAS40110 = true +NPJH50854 = true + # Heroes Phantasia Limited Edition Disc requires pixel depth rounding. ULJS00455 = true # Phantasy Star games flickering From 6848a3d1e755160567a0187dca902088987b81b6 Mon Sep 17 00:00:00 2001 From: kaiomatico Date: Fri, 29 May 2020 15:35:01 +0200 Subject: [PATCH 092/848] add raspberry pi 64 bit build files --- b.sh | 3 ++ cmake/Toolchains/raspberry.armv8.cmake | 42 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 cmake/Toolchains/raspberry.armv8.cmake diff --git a/b.sh b/b.sh index c901e4fadc..a707c92f79 100755 --- a/b.sh +++ b/b.sh @@ -22,6 +22,9 @@ do --rpi) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/raspberry.armv7.cmake ${CMAKE_ARGS}" ;; + --rpi64) + CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/raspberry.armv8.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.armv8.cmake b/cmake/Toolchains/raspberry.armv8.cmake new file mode 100644 index 0000000000..c1c8f5fd02 --- /dev/null +++ b/cmake/Toolchains/raspberry.armv8.cmake @@ -0,0 +1,42 @@ +file(READ "/sys/firmware/devicetree/base/compatible" PPSSPP_PI_MODEL) + +if(PPSSPP_PI_MODEL MATCHES "raspberrypi,4") + set(PPSSPP_PI_MODEL4 ON) +endif() + +if(NOT PPSSPP_PI_MODEL4 AND NOT EXISTS "/opt/vc/include/bcm_host.h") + message(FATAL_ERROR "RaspberryPI platform not recognized") +endif() + +include_directories(SYSTEM + /opt/vc/include + /opt/vc/include/interface/vcos/pthreads + /opt/vc/include/interface/vmcx_host/linux +) + +if(NOT PPSSPP_PI_MODEL4) + add_definitions( + -DPPSSPP_PLATFORM_RPI=1 + -U__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 + ) +endif() + +if(PPSSPP_PI_MODEL4) + set(ARCH_FLAGS "-march=armv8-a+crc -mtune=cortex-a72 -funsafe-math-optimizations") +else() + set(ARCH_FLAGS "-mcpu=cortex-a7 -mfpu=neon -mfloat-abi=hard") +endif() +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_FLAGS}" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_FLAGS}" CACHE STRING "" FORCE) +set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${ARCH_FLAGS}" CACHE STRING "" FORCE) + +set(CMAKE_EXE_LINKER_FLAGS "-L/opt/vc/lib" CACHE STRING "" FORCE) + +if(NOT PPSSPP_PI_MODEL4) + set(OPENGL_LIBRARIES brcmGLESv2 bcm_host) + set(EGL_LIBRARIES brcmEGL) + set(USING_FBDEV ON) +endif() +set(USING_GLES2 ON) +set(ARMV7 ON) +set(USE_WAYLAND_WSI OFF) From d347d3b216c18f956eabc2071b24e385245baf18 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 30 May 2020 19:19:33 +0800 Subject: [PATCH 093/848] Remove log as @unknownbrackets suggest --- Core/HLE/sceKernelModule.cpp | 1 - Core/HLE/sceKernelThread.cpp | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 31d18cf2f4..431870fc45 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1594,7 +1594,6 @@ static void __KernelStartModule(PSPModule *m, int args, const char *argp, SceKer currentMIPS->pc = m->nm.module_start_func; } - WARN_LOG(SCEKERNEL, "Root thread attr: %08x", options->attribute); SceUID threadID = __KernelSetupRootThread(m->GetUID(), args, argp, options->priority, options->stacksize, options->attribute); __KernelSetThreadRA(threadID, NID_MODULERETURN); } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 2a28d5d9b6..31831b1ff7 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1960,11 +1960,9 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 attr &= ~PSP_THREAD_ATTR_USER_ERASE; if ((attr & PSP_THREAD_ATTR_KERNEL) == 0) { - if (allowKernel && (attr & PSP_THREAD_ATTR_USER) == 0) { - WARN_LOG(SCEKERNEL, "sceKernelCreateThread: Kernel allowed, so creating as a kernel thread"); + if (allowKernel && (attr & PSP_THREAD_ATTR_USER) == 0) { attr |= PSP_THREAD_ATTR_KERNEL; - } else { - WARN_LOG(SCEKERNEL, "sceKernelCreateThread: Kernel not allowed, so creating as a user thread"); + } else { attr |= PSP_THREAD_ATTR_USER; } } From 9900a761f85c6c3142e6eda5c427a0649d0f84c8 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 30 May 2020 19:44:48 +0800 Subject: [PATCH 094/848] oop --- Core/HLE/sceKernelThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 31831b1ff7..a1518f248e 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1960,7 +1960,7 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 attr &= ~PSP_THREAD_ATTR_USER_ERASE; if ((attr & PSP_THREAD_ATTR_KERNEL) == 0) { - if (allowKernel && (attr & PSP_THREAD_ATTR_USER) == 0) { + if (allowKernel && (attr & PSP_THREAD_ATTR_USER) == 0) { attr |= PSP_THREAD_ATTR_KERNEL; } else { attr |= PSP_THREAD_ATTR_USER; From 8e7d2109fece19c7107df91b6fa9004d68d05628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 31 May 2020 19:35:19 +0200 Subject: [PATCH 095/848] VulkanQueueRunner: Fix some uninitialized struct members (not sure if it has any effect) --- ext/native/thin3d/VulkanQueueRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 6c335ae608..f078dd705a 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -1585,7 +1585,7 @@ void VulkanQueueRunner::PerformReadback(const VKRStep &step, VkCommandBuffer cmd void VulkanQueueRunner::PerformReadbackImage(const VKRStep &step, VkCommandBuffer cmd) { // TODO: Clean this up - just reusing `SetupTransitionToTransferSrc`. - VKRImage srcImage; + VKRImage srcImage{}; srcImage.image = step.readback_image.image; srcImage.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; From e559fc022f84aceeb73f56bd1b25ea57d655846a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 31 May 2020 19:45:28 +0200 Subject: [PATCH 096/848] Minor refactor in PresentationCommon (combine loose coordinates to a struct) --- GPU/Common/FramebufferCommon.cpp | 6 ++-- GPU/Common/GPUStateUtils.cpp | 7 +++- GPU/Common/PresentationCommon.cpp | 60 +++++++++++++++---------------- GPU/Common/PresentationCommon.h | 10 +++++- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 0d85958f94..8cdbeb88bc 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -660,9 +660,9 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int std::swap(v0, v1); flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST; flags = flags | DRAWTEX_TO_BACKBUFFER; - float x, y, w, h; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL); - SetViewport2D(x, y, w, h); + FRect rc; + CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL); + SetViewport2D(rc.x, rc.y, rc.w, rc.h); draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); } diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 3ffc8d8038..273619042d 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -557,7 +557,12 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo } else { float pixelW = PSP_CoreParameter().pixelWidth; float pixelH = PSP_CoreParameter().pixelHeight; - CenterDisplayOutputRect(&displayOffsetX, &displayOffsetY, &renderWidth, &renderHeight, 480, 272, pixelW, pixelH, ROTATION_LOCKED_HORIZONTAL); + FRect rc; + CenterDisplayOutputRect(&rc, 480, 272, pixelW, pixelH, ROTATION_LOCKED_HORIZONTAL); + displayOffsetX = rc.x; + displayOffsetY = rc.y; + renderWidth = rc.w; + renderHeight = rc.h; renderWidthFactor = renderWidth / 480.0f; renderHeightFactor = renderHeight / 272.0f; } diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 83fffeecc0..a18dde1722 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -39,7 +39,7 @@ struct Vertex { uint32_t rgba; }; -void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW, float origH, float frameW, float frameH, int rotation) { +void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW, float frameH, int rotation) { float outW; float outH; @@ -60,16 +60,16 @@ void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW float smallDisplayW = origW * customZoom; float smallDisplayH = origH * customZoom; if (!rotated) { - *x = floorf(((frameW - smallDisplayW) / 2.0f) + offsetX); - *y = floorf(((frameH - smallDisplayH) / 2.0f) + offsetY); - *w = floorf(smallDisplayW); - *h = floorf(smallDisplayH); + rc->x = floorf(((frameW - smallDisplayW) / 2.0f) + offsetX); + rc->y = floorf(((frameH - smallDisplayH) / 2.0f) + offsetY); + rc->w = floorf(smallDisplayW); + rc->h = floorf(smallDisplayH); return; } else { - *x = floorf(((frameW - smallDisplayH) / 2.0f) + offsetX); - *y = floorf(((frameH - smallDisplayW) / 2.0f) + offsetY); - *w = floorf(smallDisplayH); - *h = floorf(smallDisplayW); + rc->x = floorf(((frameW - smallDisplayH) / 2.0f) + offsetX); + rc->y = floorf(((frameH - smallDisplayW) / 2.0f) + offsetY); + rc->w = floorf(smallDisplayH); + rc->h = floorf(smallDisplayW); return; } } else if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::AUTO) { @@ -77,10 +77,10 @@ void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW float pixelCrop = frameH / 270.0f; float resCommonWidescreen = pixelCrop - floor(pixelCrop); if (!rotated && resCommonWidescreen == 0.0f && frameW >= pixelCrop * 480.0f) { - *x = floorf((frameW - pixelCrop * 480.0f) * 0.5f); - *y = floorf(-pixelCrop); - *w = floorf(pixelCrop * 480.0f); - *h = floorf(pixelCrop * 272.0f); + rc->x = floorf((frameW - pixelCrop * 480.0f) * 0.5f); + rc->y = floorf(-pixelCrop); + rc->w = floorf(pixelCrop * 480.0f); + rc->h = floorf(pixelCrop * 272.0f); return; } } @@ -104,10 +104,10 @@ void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW } } - *x = floorf((frameW - outW) / 2.0f); - *y = floorf((frameH - outH) / 2.0f); - *w = floorf(outW); - *h = floorf(outH); + rc->x = floorf((frameW - outW) / 2.0f); + rc->y = floorf((frameH - outH) / 2.0f); + rc->w = floorf(outW); + rc->h = floorf(outH); } PresentationCommon::PresentationCommon(Draw::DrawContext *draw) : draw_(draw) { @@ -252,10 +252,10 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha nextHeight *= next->SSAAFilterLevel; } else if (shaderInfo->outputResolution) { // If the current shader uses output res (not next), we will use output res for it. - float x, y, w, h; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, g_Config.iInternalScreenRotation); - nextWidth = (int)w; - nextHeight = (int)h; + FRect rc; + CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, g_Config.iInternalScreenRotation); + nextWidth = (int)rc.w; + nextHeight = (int)rc.h; } // No depth/stencil for post processing @@ -499,13 +499,13 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u int lastHeight = srcHeight_; // These are the output coordinates. - float x, y, w, h; - CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation); + FRect rc; + CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation); if (GetGPUBackend() == GPUBackend::DIRECT3D9) { - x -= 0.5f; + rc.x -= 0.5f; // This is plus because the top is larger y. - y += 0.5f; + rc.y += 0.5f; } if ((flags & OutputFlags::BACKBUFFER_FLIPPED) || (flags & OutputFlags::POSITION_FLIPPED)) { @@ -515,10 +515,10 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u // To make buffer updates easier, we use one array of verts. int postVertsOffset = (int)sizeof(Vertex) * 4; Vertex verts[8] = { - { x, y, 0, u0, v0, 0xFFFFFFFF }, // TL - { x, y + h, 0, u0, v1, 0xFFFFFFFF }, // BL - { x + w, y + h, 0, u1, v1, 0xFFFFFFFF }, // BR - { x + w, y, 0, u1, v0, 0xFFFFFFFF }, // TR + { rc.x, rc.y, 0, u0, v0, 0xFFFFFFFF }, // TL + { rc.x, rc.y + rc.h, 0, u0, v1, 0xFFFFFFFF }, // BL + { rc.x + rc.w, rc.y + rc.h, 0, u1, v1, 0xFFFFFFFF }, // BR + { rc.x + rc.w, rc.y, 0, u1, v0, 0xFFFFFFFF }, // TR }; float invDestW = 1.0f / (pixelWidth_ * 0.5f); @@ -648,7 +648,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u if (isFinalAtOutputResolution) { PostShaderUniforms uniforms; - CalculatePostShaderUniforms(lastWidth, lastHeight, (int)w, (int)h, &postShaderInfo_.back(), &uniforms); + CalculatePostShaderUniforms(lastWidth, lastHeight, (int)rc.w, (int)rc.h, &postShaderInfo_.back(), &uniforms); draw_->UpdateDynamicUniformBuffer(&uniforms, sizeof(uniforms)); } else { Draw::VsTexColUB ub{}; diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index 919f63b42a..50f6508880 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -37,7 +37,15 @@ struct PostShaderUniforms { float gl_HalfPixel[4]; }; -void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW, float origH, float frameW, float frameH, int rotation); +// Could use UI::Bounds but don't want to depend on that here. +struct FRect { + float x; + float y; + float w; + float h; +}; + +void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW, float frameH, int rotation); namespace Draw { class Buffer; From c8d48a877743c5c1f0dc71256192cab896a7bdae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 31 May 2020 20:13:35 +0200 Subject: [PATCH 097/848] Handle insets correctly for the in-game final screen blit. Should help #12982 in case of phones with inset cameras. --- GPU/Common/FramebufferCommon.cpp | 6 ++- GPU/Common/GPUStateUtils.cpp | 3 +- GPU/Common/PresentationCommon.cpp | 77 +++++++++++++++++++++---------- GPU/Common/PresentationCommon.h | 3 +- 4 files changed, 61 insertions(+), 28 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 8cdbeb88bc..548d82faef 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -655,13 +655,15 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int SetViewport2D(0, 0, vfb->renderWidth, vfb->renderHeight); draw_->SetScissorRect(0, 0, vfb->renderWidth, vfb->renderHeight); } else { - // We are drawing to the back buffer so need to flip. + // We are drawing directly to the back buffer so need to flip. + // Should more of this be handled by the presentation engine? if (needBackBufferYSwap_) std::swap(v0, v1); flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST; flags = flags | DRAWTEX_TO_BACKBUFFER; + FRect frame = GetInsetScreenFrame(pixelWidth_, pixelHeight_); FRect rc; - CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL); + CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, ROTATION_LOCKED_HORIZONTAL); SetViewport2D(rc.x, rc.y, rc.w, rc.h); draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_); } diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 273619042d..dc29213429 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -557,8 +557,9 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo } else { float pixelW = PSP_CoreParameter().pixelWidth; float pixelH = PSP_CoreParameter().pixelHeight; + FRect frame = GetInsetScreenFrame(pixelW, pixelH); FRect rc; - CenterDisplayOutputRect(&rc, 480, 272, pixelW, pixelH, ROTATION_LOCKED_HORIZONTAL); + CenterDisplayOutputRect(&rc, 480, 272, frame, ROTATION_LOCKED_HORIZONTAL); displayOffsetX = rc.x; displayOffsetY = rc.y; renderWidth = rc.w; diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index a18dde1722..871322073e 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -19,8 +19,10 @@ #include #include #include + #include "base/display.h" #include "base/timeutil.h" +#include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" #include "thin3d/thin3d.h" @@ -39,19 +41,40 @@ struct Vertex { uint32_t rgba; }; -void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW, float frameH, int rotation) { +FRect GetInsetScreenFrame(float pixelWidth, float pixelHeight) { + FRect rc = FRect{ + 0.0f, + 0.0f, + pixelWidth, + pixelHeight, + }; + + float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT); + float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT); + float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP); + float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM); + + // Adjust left edge to compensate for cutouts (notches) if any. + rc.x += left; + rc.w -= (left + right); + rc.y += top; + rc.h -= (top + bottom); + return rc; +} + +void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &frame, int rotation) { float outW; float outH; bool rotated = rotation == ROTATION_LOCKED_VERTICAL || rotation == ROTATION_LOCKED_VERTICAL180; if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::STRETCH) { - outW = frameW; - outH = frameH; + outW = frame.w; + outH = frame.h; } else { if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::MANUAL) { - float offsetX = (g_Config.fSmallDisplayOffsetX - 0.5f) * 2.0f * frameW; - float offsetY = (g_Config.fSmallDisplayOffsetY - 0.5f) * 2.0f * frameH; + float offsetX = (g_Config.fSmallDisplayOffsetX - 0.5f) * 2.0f * frame.w; + float offsetY = (g_Config.fSmallDisplayOffsetY - 0.5f) * 2.0f * frame.h; // Have to invert Y for GL if (GetGPUBackend() == GPUBackend::OPENGL) { offsetY = offsetY * -1.0f; @@ -60,24 +83,24 @@ void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW, float smallDisplayW = origW * customZoom; float smallDisplayH = origH * customZoom; if (!rotated) { - rc->x = floorf(((frameW - smallDisplayW) / 2.0f) + offsetX); - rc->y = floorf(((frameH - smallDisplayH) / 2.0f) + offsetY); + rc->x = floorf(((frame.w - smallDisplayW) / 2.0f) + offsetX); + rc->y = floorf(((frame.h - smallDisplayH) / 2.0f) + offsetY); rc->w = floorf(smallDisplayW); rc->h = floorf(smallDisplayH); return; } else { - rc->x = floorf(((frameW - smallDisplayH) / 2.0f) + offsetX); - rc->y = floorf(((frameH - smallDisplayW) / 2.0f) + offsetY); + rc->x = floorf(((frame.w - smallDisplayH) / 2.0f) + offsetX); + rc->y = floorf(((frame.h - smallDisplayW) / 2.0f) + offsetY); rc->w = floorf(smallDisplayH); rc->h = floorf(smallDisplayW); return; } } else if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::AUTO) { // Stretch to 1080 for 272*4. But don't distort if not widescreen (i.e. ultrawide of halfwide.) - float pixelCrop = frameH / 270.0f; + float pixelCrop = frame.h / 270.0f; float resCommonWidescreen = pixelCrop - floor(pixelCrop); - if (!rotated && resCommonWidescreen == 0.0f && frameW >= pixelCrop * 480.0f) { - rc->x = floorf((frameW - pixelCrop * 480.0f) * 0.5f); + if (!rotated && resCommonWidescreen == 0.0f && frame.w >= pixelCrop * 480.0f) { + rc->x = floorf((frame.h - pixelCrop * 480.0f) * 0.5f); rc->y = floorf(-pixelCrop); rc->w = floorf(pixelCrop * 480.0f); rc->h = floorf(pixelCrop * 272.0f); @@ -86,26 +109,26 @@ void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW, } float origRatio = !rotated ? origW / origH : origH / origW; - float frameRatio = frameW / frameH; + float frameRatio = frame.w / frame.h; if (origRatio > frameRatio) { // Image is wider than frame. Center vertically. - outW = frameW; - outH = frameW / origRatio; + outW = frame.w; + outH = frame.w / origRatio; // Stretch a little bit if (!rotated && g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::PARTIAL_STRETCH) - outH = (frameH + outH) / 2.0f; // (408 + 720) / 2 = 564 + outH = (frame.h + outH) / 2.0f; // (408 + 720) / 2 = 564 } else { // Image is taller than frame. Center horizontally. - outW = frameH * origRatio; - outH = frameH; + outW = frame.h * origRatio; + outH = frame.h; if (rotated && g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::PARTIAL_STRETCH) - outW = (frameH + outH) / 2.0f; // (408 + 720) / 2 = 564 + outW = (frame.h + outH) / 2.0f; // (408 + 720) / 2 = 564 } } - rc->x = floorf((frameW - outW) / 2.0f); - rc->y = floorf((frameH - outH) / 2.0f); + rc->x = floorf((frame.w - outW) / 2.0f + frame.x); + rc->y = floorf((frame.h - outH) / 2.0f + frame.y); rc->w = floorf(outW); rc->h = floorf(outH); } @@ -119,6 +142,10 @@ PresentationCommon::~PresentationCommon() { } void PresentationCommon::GetCardboardSettings(CardboardSettings *cardboardSettings) { + if (!g_Config.bEnableCardboardVR) { + cardboardSettings->enabled = false; + return; + } // Calculate Cardboard Settings float cardboardScreenScale = g_Config.iCardboardScreenSize / 100.0f; float cardboardScreenWidth = pixelWidth_ / 2.0f * cardboardScreenScale; @@ -131,7 +158,7 @@ void PresentationCommon::GetCardboardSettings(CardboardSettings *cardboardSettin float cardboardUserYShift = g_Config.iCardboardYShift / 100.0f * cardboardMaxYShift; float cardboardScreenY = cardboardMaxYShift + cardboardUserYShift; - cardboardSettings->enabled = g_Config.bEnableCardboardVR; + cardboardSettings->enabled = true; cardboardSettings->leftEyeXPosition = cardboardLeftEyeX; cardboardSettings->rightEyeXPosition = cardboardRightEyeX; cardboardSettings->screenYPosition = cardboardScreenY; @@ -253,7 +280,8 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha } else if (shaderInfo->outputResolution) { // If the current shader uses output res (not next), we will use output res for it. FRect rc; - CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, g_Config.iInternalScreenRotation); + FRect frame = GetInsetScreenFrame((float)pixelWidth_, (float)pixelHeight_); + CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, g_Config.iInternalScreenRotation); nextWidth = (int)rc.w; nextHeight = (int)rc.h; } @@ -499,8 +527,9 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u int lastHeight = srcHeight_; // These are the output coordinates. + FRect frame = GetInsetScreenFrame((float)pixelWidth_, (float)pixelHeight_); FRect rc; - CenterDisplayOutputRect(&rc, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, uvRotation); + CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, uvRotation); if (GetGPUBackend() == GPUBackend::DIRECT3D9) { rc.x -= 0.5f; diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index 50f6508880..502ef318e9 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -45,7 +45,8 @@ struct FRect { float h; }; -void CenterDisplayOutputRect(FRect *rc, float origW, float origH, float frameW, float frameH, int rotation); +FRect GetInsetScreenFrame(float pixelWidth, float pixelHeight); +void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &frame, int rotation); namespace Draw { class Buffer; From 34a2713c3f88f092fe4060dd9671b74be6853d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 31 May 2020 23:20:13 +0200 Subject: [PATCH 098/848] Have DisplayLayoutScreen implemented insets manually. Gave up refactoring it. --- UI/DisplayLayoutScreen.cpp | 19 ++++++++++++------- UI/EmuScreen.cpp | 2 +- ext/native/ui/root.cpp | 4 ++-- ext/native/ui/root.h | 2 +- ext/native/ui/ui_screen.cpp | 4 ++-- ext/native/ui/ui_screen.h | 1 + 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 5514cc5bbd..7b210c2c85 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -84,7 +84,9 @@ private: }; DisplayLayoutScreen::DisplayLayoutScreen() { -}; + // Ignore insets - just couldn't get the logic to work. + ignoreInsets_ = true; +} bool DisplayLayoutScreen::touch(const TouchInput &touch) { UIScreen::touch(touch); @@ -253,11 +255,14 @@ void DisplayLayoutScreen::CreateViews() { // This makes it have at least 10.0f padding below at 1x. const float vertBoundariesHeight = 52.0f; + // We manually implement insets here for the buttons. This file defied refactoring :( + float leftInset = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT); + // Left side, right, top, bottom. - root_->Add(new Boundary(new AnchorLayoutParams(horizBoundariesWidth, FILL_PARENT, NONE, 0, horizPreviewPadding + previewWidth, 0))); + root_->Add(new Boundary(new AnchorLayoutParams(horizBoundariesWidth, FILL_PARENT, horizPreviewPadding - horizBoundariesWidth, 0, NONE, 0))); root_->Add(new Boundary(new AnchorLayoutParams(horizBoundariesWidth, FILL_PARENT, horizPreviewPadding + previewWidth, 0, NONE, 0))); root_->Add(new Boundary(new AnchorLayoutParams(previewWidth, vertBoundariesHeight, horizPreviewPadding, vertPreviewPadding - vertBoundariesHeight, NONE, NONE))); - root_->Add(new Boundary(new AnchorLayoutParams(previewWidth, vertBoundariesHeight, horizPreviewPadding, NONE, NONE, vertPreviewPadding - vertBoundariesHeight))); + root_->Add(new Boundary(new AnchorLayoutParams(previewWidth, vertBoundariesHeight, horizPreviewPadding, vertPreviewPadding + previewHeight, NONE, NONE))); bool displayRotEnable = (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) || g_Config.bSoftwareRendering; bRotated_ = false; @@ -290,16 +295,16 @@ void DisplayLayoutScreen::CreateViews() { g_Config.fSmallDisplayOffsetX = 0.5f; g_Config.fSmallDisplayOffsetY = 0.5f; } else { // Manual Scaling - Choice *center = new Choice(di->T("Center"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 74)); + Choice *center = new Choice(di->T("Center"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10 + leftInset, NONE, NONE, 74)); center->OnClick.Handle(this, &DisplayLayoutScreen::OnCenter); root_->Add(center); float minZoom = 1.0f; if (g_dpi_scale_x > 1.0f) { minZoom /= g_dpi_scale_x; } - PopupSliderChoiceFloat *zoomlvl = new PopupSliderChoiceFloat(&g_Config.fSmallDisplayZoomLevel, minZoom, 10.0f, di->T("Zoom"), 1.0f, screenManager(), di->T("* PSP res"), new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 10 + 64 + 64)); + PopupSliderChoiceFloat *zoomlvl = new PopupSliderChoiceFloat(&g_Config.fSmallDisplayZoomLevel, minZoom, 10.0f, di->T("Zoom"), 1.0f, screenManager(), di->T("* PSP res"), new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10 + leftInset, NONE, NONE, 10 + 64 + 64)); root_->Add(zoomlvl); - mode_ = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158 + 64 + 10)); + mode_ = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10 + leftInset, NONE, NONE, 158 + 64 + 10)); mode_->AddChoice(di->T("Move")); mode_->AddChoice(di->T("Resize")); mode_->SetSelection(0); @@ -359,7 +364,7 @@ void DisplayLayoutScreen::CreateViews() { }); root_->Add(rotation); - Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 10)); + Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10 + leftInset, NONE, NONE, 10)); back->OnClick.Handle(this, &UIScreen::OnBack); root_->Add(back); } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 7cd3a81099..2b0b068b6f 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1487,7 +1487,7 @@ void EmuScreen::renderUI() { DrawBuffer *draw2d = ctx->Draw(); if (root_) { - UI::LayoutViewHierarchy(*ctx, root_); + UI::LayoutViewHierarchy(*ctx, root_, false); root_->Draw(*ctx); } diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index ac26a663f7..ef44036747 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -102,13 +102,13 @@ bool IsFocusMovementEnabled() { return focusMovementEnabled; } -void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root) { +void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root, bool ignoreInsets) { if (!root) { ELOG("Tried to layout a view hierarchy from a zero pointer root"); return; } - Bounds rootBounds = dc.GetLayoutBounds(); + Bounds rootBounds = ignoreInsets ? dc.GetBounds() : dc.GetLayoutBounds(); MeasureSpec horiz(EXACTLY, rootBounds.w); MeasureSpec vert(EXACTLY, rootBounds.h); diff --git a/ext/native/ui/root.h b/ext/native/ui/root.h index a51a20d095..8cfca36f29 100644 --- a/ext/native/ui/root.h +++ b/ext/native/ui/root.h @@ -19,7 +19,7 @@ void DispatchEvents(); class ViewGroup; -void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root); +void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root, bool ignoreInsets); void UpdateViewHierarchy(ViewGroup *root); // Hooks arrow keys for navigation bool KeyEvent(const KeyInput &key, ViewGroup *root); diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 835799b54f..0a2a665e34 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -45,7 +45,7 @@ void UIScreen::DoRecreateViews() { // Update layout and refocus so things scroll into view. // This is for resizing down, when focused on something now offscreen. - UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_); + UI::LayoutViewHierarchy(*screenManager()->getUIContext(), root_, ignoreInsets_); UI::View *focused = UI::GetFocusedView(); if (focused) { root_->SubviewFocused(focused); @@ -107,7 +107,7 @@ void UIScreen::render() { if (root_) { UIContext *uiContext = screenManager()->getUIContext(); - UI::LayoutViewHierarchy(*uiContext, root_); + UI::LayoutViewHierarchy(*uiContext, root_, ignoreInsets_); uiContext->PushTransform({translation_, scale_, alpha_}); diff --git a/ext/native/ui/ui_screen.h b/ext/native/ui/ui_screen.h index 1f1c5b4317..14d9472750 100644 --- a/ext/native/ui/ui_screen.h +++ b/ext/native/ui/ui_screen.h @@ -48,6 +48,7 @@ protected: Vec3 translation_ = Vec3(0.0f); Vec3 scale_ = Vec3(1.0f); float alpha_ = 1.0f; + bool ignoreInsets_ = false; private: void DoRecreateViews(); From 4fa6c7fd7f6b9d08adac7422cc2522410554e8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 1 Jun 2020 16:19:17 +0200 Subject: [PATCH 099/848] Typo fix. Will hopefully help #12992. --- GPU/Common/PresentationCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 871322073e..8e04dafe43 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -100,7 +100,7 @@ void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &f float pixelCrop = frame.h / 270.0f; float resCommonWidescreen = pixelCrop - floor(pixelCrop); if (!rotated && resCommonWidescreen == 0.0f && frame.w >= pixelCrop * 480.0f) { - rc->x = floorf((frame.h - pixelCrop * 480.0f) * 0.5f); + rc->x = floorf((frame.w - pixelCrop * 480.0f) * 0.5f); rc->y = floorf(-pixelCrop); rc->w = floorf(pixelCrop * 480.0f); rc->h = floorf(pixelCrop * 272.0f); From 3dc9f61da042c9619b2af3b6756a21f6210f1d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 2 Jun 2020 00:28:25 +0200 Subject: [PATCH 100/848] Disable range culling for MGS:PW and MGS:PO. See #12348 --- assets/compat.ini | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 4324accfed..54af84b6fb 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -156,6 +156,32 @@ ULES00637 = true ULKS46126 = true ULUS10249 = true +# Metal Gear Solid : Peace Walker (see issue #12348) +ULUS10509 = true +ULES01372 = true +ULJM08038 = true +NPJH50045 = true +ULJM05630 = true +NPJH90082 = true +NPJH90063 = true + +# Metal Gear Solid : Peace Walker Demo Ops (see issue #12348) +NPUH90066 = true +NPHH00145 = true +NPEH90023 = true + +# Metal Gear Solid: Portable Ops (see issue #12348) +ULES00645 = true +ULJM05193 = true +ULJM05227 = true +ULUS10202 = true +ULES01003 = true +ULJM05261 = true +ULUS10290 = true +ULED90040 = true +ULJM05284 = true +ULES00645 = true + [ClearToRAM] # SOCOM Navy Seals games require this. See issue #8973. # Navy Seals : Tactical Strike @@ -360,6 +386,8 @@ ULES01372 = true ULJM08038 = true NPJH50045 = true ULJM05630 = true +NPJH90082 = true +NPJH90063 = true # Star Ocean : Second Evolution ULUS10375 = true ULES01187 = true From f4dcbe9d28531610606381f44a54123d45819d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 2 Jun 2020 09:50:20 +0200 Subject: [PATCH 101/848] Vulkan DrawEngine: Move the renderstep changed check until after the last place where it can change. --- GPU/Vulkan/DrawEngineVulkan.cpp | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 8802e4c064..f383f436de 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -588,17 +588,10 @@ void DrawEngineVulkan::DoFlush() { VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - // TODO: Move this into the below if statement. Little scary change though so holding off until 1.11. + // TODO: Needs to be behind a check for changed render pass, at an appropriate time in this function. + // Similar issues as with the lastRenderStepId_ check. Will need a bit of a rethink. lastPipeline_ = nullptr; - // Since we have a new cmdbuf, dirty our dynamic state so it gets re-set. - int curRenderStepId = renderManager->GetCurrentStepId(); - if (lastRenderStepId_ != curRenderStepId) { - // Dirty everything that has dynamic state that will need re-recording. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE); - lastRenderStepId_ = curRenderStepId; - } - FrameData *frame = &frame_[vulkan_->GetCurFrame()]; bool tess = gstate_c.bezier || gstate_c.spline; @@ -831,6 +824,17 @@ void DrawEngineVulkan::DoFlush() { return; } BindShaderBlendTex(); // This might cause copies so important to do before BindPipeline. + + // If have a new render pass, dirty our dynamic state so it gets re-set. + // WARNING: We have to do this AFTER the last possible place in DoFlush that can cause a renderpass switch + // like a shader blend blit or similar. But before we actually set the state! + int curRenderStepId = renderManager->GetCurrentStepId(); + if (lastRenderStepId_ != curRenderStepId) { + // Dirty everything that has dynamic state that will need re-recording. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE); + lastRenderStepId_ = curRenderStepId; + } + renderManager->BindPipeline(pipeline->pipeline); if (pipeline != lastPipeline_) { if (lastPipeline_ && !(lastPipeline_->UsesBlendConstant() && pipeline->UsesBlendConstant())) { @@ -942,6 +946,17 @@ void DrawEngineVulkan::DoFlush() { return; } BindShaderBlendTex(); // This might cause copies so super important to do before BindPipeline. + + // If have a new render pass, dirty our dynamic state so it gets re-set. + // WARNING: We have to do this AFTER the last possible place in DoFlush that can cause a renderpass switch + // like a shader blend blit or similar. But before we actually set the state! + int curRenderStepId = renderManager->GetCurrentStepId(); + if (lastRenderStepId_ != curRenderStepId) { + // Dirty everything that has dynamic state that will need re-recording. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE); + lastRenderStepId_ = curRenderStepId; + } + renderManager->BindPipeline(pipeline->pipeline); if (pipeline != lastPipeline_) { if (lastPipeline_ && !lastPipeline_->UsesBlendConstant() && pipeline->UsesBlendConstant()) { From 737688a22aff80b911ba8ee754b0ca1ed1bb5f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 2 Jun 2020 09:51:38 +0200 Subject: [PATCH 102/848] Annotate calls to RebindFramebuffer with their cause. --- GPU/Common/FramebufferCommon.cpp | 28 +++++++++++------------ GPU/Common/FramebufferCommon.h | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 4 ++-- GPU/D3D11/StencilBufferD3D11.cpp | 2 +- GPU/D3D11/TextureCacheD3D11.cpp | 6 ++--- GPU/Directx9/FramebufferDX9.cpp | 2 +- GPU/Directx9/StencilBufferDX9.cpp | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GLES/StateMappingGLES.cpp | 2 +- GPU/GLES/StencilBufferGLES.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 8 +++---- GPU/Vulkan/FramebufferVulkan.cpp | 2 +- GPU/Vulkan/StencilBufferVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 7 +++--- ext/native/thin3d/VulkanRenderManager.cpp | 1 - 16 files changed, 36 insertions(+), 38 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 548d82faef..b6578a4737 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -635,7 +635,7 @@ void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) { } } - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - UpdateFromMemory"); } // TODO: Necessary? gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE); @@ -1167,7 +1167,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, // Just do the blit! BlitFramebuffer(dstBuffer, 0, dstY, srcBuffer, 0, srcY, srcBuffer->width, srcH, 0); SetColorUpdated(dstBuffer, skipDrawReason); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - Inter-buffer memcpy"); } return false; } else if (dstBuffer) { @@ -1179,7 +1179,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, const u8 *srcBase = Memory::GetPointerUnchecked(src); DrawPixels(dstBuffer, 0, dstY, srcBase, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstH); SetColorUpdated(dstBuffer, skipDrawReason); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - Memcpy fbo upload"); // This is a memcpy, let's still copy just in case. return false; } else if (srcBuffer) { @@ -1556,7 +1556,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); FlushBeforeCopy(); BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); - RebindFramebuffer(); + RebindFramebuffer("rebind after intra block transfer"); SetColorUpdated(dstBuffer, skipDrawReason); return true; } else { @@ -1568,7 +1568,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst // Just do the blit! FlushBeforeCopy(); BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - Inter-buffer block transfer"); SetColorUpdated(dstBuffer, skipDrawReason); return true; // No need to actually do the memory copy behind, probably. } @@ -1645,7 +1645,7 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS } DrawPixels(dstBuffer, static_cast(dstX * dstXFactor), dstY, srcBase, dstBuffer->format, static_cast(srcStride * dstXFactor), static_cast(dstWidth * dstXFactor), dstHeight); SetColorUpdated(dstBuffer, skipDrawReason); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - NotifyBlockTransferAfter"); } } } @@ -1845,7 +1845,7 @@ bool FramebufferManagerCommon::GetFramebuffer(u32 fb_address, int fb_stride, GEB // After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe. gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); // We may have blitted to a temp FBO. - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - GetFramebuffer"); return retval; } @@ -1880,7 +1880,7 @@ bool FramebufferManagerCommon::GetDepthbuffer(u32 fb_address, int fb_stride, u32 // After a readback we'll have flushed and started over, need to dirty a bunch of things to be safe. gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); // That may have unbound the framebuffer, rebind to avoid crashes when debugging. - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - GetDepthbuffer"); return retval; } @@ -1910,7 +1910,7 @@ bool FramebufferManagerCommon::GetStencilbuffer(u32 fb_address, int fb_stride, G buffer.Allocate(w, h, GPU_DBG_FORMAT_8BIT, flipY); bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_STENCIL_BIT, 0, 0, w,h, Draw::DataFormat::S8, buffer.GetData(), w, "GetStencilbuffer"); // That may have unbound the framebuffer, rebind to avoid crashes when debugging. - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - GetStencilbuffer"); return retval; } @@ -1924,7 +1924,7 @@ bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) { buffer.Allocate(w, h, fmt == Draw::DataFormat::R8G8B8A8_UNORM ? GPU_DBG_FORMAT_8888 : GPU_DBG_FORMAT_8888_BGRA, false); bool retval = draw_->CopyFramebufferToMemorySync(nullptr, Draw::FB_COLOR_BIT, 0, 0, w, h, fmt, buffer.GetData(), w, "GetOutputFramebuffer"); // That may have unbound the framebuffer, rebind to avoid crashes when debugging. - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - GetOutputFramebuffer"); return retval; } @@ -1992,7 +1992,7 @@ void FramebufferManagerCommon::ReadFramebufferToMemory(VirtualFramebuffer *vfb, } textureCache_->ForgetLastTexture(); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - ReadFramebufferToMemory"); } } @@ -2038,15 +2038,15 @@ void FramebufferManagerCommon::DownloadFramebufferForClut(u32 fb_address, u32 lo } textureCache_->ForgetLastTexture(); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - DownloadFramebufferForClut"); } } } -void FramebufferManagerCommon::RebindFramebuffer() { +void FramebufferManagerCommon::RebindFramebuffer(const char *tag) { shaderManager_->DirtyLastShader(); if (currentRenderVfb_ && currentRenderVfb_->fbo) { - draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "RebindFramebuffer"); + draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, tag); } else { // Should this even happen? It could while debugging, but maybe we can just skip binding at all. draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "RebindFramebuffer_Bad"); diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 93d2418417..7f5eb26bdc 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -215,7 +215,7 @@ public: return vfb; } } - void RebindFramebuffer(); + void RebindFramebuffer(const char *tag); std::vector GetFramebufferList(); void CopyDisplayToOutput(bool reallyDirty); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 3ea5b73e55..1ec5128cdb 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -322,7 +322,7 @@ void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, Virt if (matchingDepthBuffer && matchingSize && matchingRenderSize) { // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); dst->last_frame_depth_updated = gpuStats.numFlips; } } @@ -349,7 +349,7 @@ void FramebufferManagerD3D11::BindFramebufferAsColorTexture(int stage, VirtualFr VirtualFramebuffer copyInfo = *framebuffer; copyInfo.fbo = renderCopy; CopyFramebufferForColorTexture(©Info, framebuffer, flags); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - BindFramebufferAsColorTexture"); draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0); } else { draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index 28b2a52fd6..7c47806c74 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -243,6 +243,6 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, StencilUpl } tex->Release(); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer stencil"); return true; } diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index a938376352..def69c626a 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -408,7 +408,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DWrap); shaderApply.Shade(); - framebufferManagerD3D11_->RebindFramebuffer(); + framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0); const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16); @@ -422,7 +422,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); - framebufferManagerD3D11_->RebindFramebuffer(); // Probably not necessary. + framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); // Probably not necessary. } SamplerCacheKey samplerKey{}; SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey); @@ -784,7 +784,7 @@ bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); // We may have blitted to a temp FBO. - framebufferManager_->RebindFramebuffer(); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); return retval; } diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 0d90960ebd..c3cb5ff1dd 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -369,7 +369,7 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { copyInfo.fbo = renderCopy; CopyFramebufferForColorTexture(©Info, framebuffer, flags); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - BindFramebufferAsColorTexture"); draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0); } else { draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 972bcfd88f..707f63b9d6 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -256,7 +256,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa tex->Release(); dxstate.stencilMask.set(0xFF); dxstate.viewport.restore(); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer stencil"); return true; } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 4afe6baa26..e10aff8cc2 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -466,7 +466,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); } - framebufferManagerDX9_->RebindFramebuffer(); + framebufferManagerDX9_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFromFramebuffer"); SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); InvalidateLastTexture(); diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index ceefecbcb3..a38334dace 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -398,7 +398,7 @@ void GPU_GLES::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat fo void GPU_GLES::CopyDisplayToOutput(bool reallyDirty) { // Flush anything left over. - framebufferManagerGL_->RebindFramebuffer(); + framebufferManagerGL_->RebindFramebuffer("RebindFramebuffer - CopyDisplayToOutput"); drawEngine_.Flush(); shaderManagerGL_->DirtyLastShader(); diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 4e2f7f36f1..ce958e0403 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -184,7 +184,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { fboTexBound_ = true; fboTexNeedBind_ = false; - framebufferManager_->RebindFramebuffer(); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyDrawState"); // Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects. gstate_c.Dirty(DIRTY_BLEND_STATE); } diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index f18b2f90d6..ab843c5059 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -217,6 +217,6 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo tex->Release(); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - Stencil"); return true; } diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 781aee4f56..48c4a3eda8 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -505,7 +505,7 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); } - framebufferManagerGL_->RebindFramebuffer(); + framebufferManagerGL_->RebindFramebuffer("ApplyTextureFramebuffer"); SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, false); InvalidateLastTexture(); @@ -833,7 +833,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) // Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer. TexCacheEntry *entry = nextTexture_; // We might need a render pass to set the sampling params, unfortunately. Otherwise BuildTexture may crash. - framebufferManagerGL_->RebindFramebuffer(); + framebufferManagerGL_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); ApplyTexture(); // TODO: Centralize? @@ -845,7 +845,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); // We may have blitted to a temp FBO. - framebufferManager_->RebindFramebuffer(); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); return retval; } @@ -863,7 +863,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) buffer.Allocate(w, h, GE_FORMAT_8888, false); renderManager->CopyImageToMemorySync(entry->textureName, level, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, (uint8_t *)buffer.GetData(), w, "GetCurrentTextureDebug"); gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); - framebufferManager_->RebindFramebuffer(); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); return true; #else diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 8eead37278..fe328bbd1a 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -314,7 +314,7 @@ VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, V VirtualFramebuffer copyInfo = *framebuffer; copyInfo.fbo = renderCopy; CopyFramebufferForColorTexture(©Info, framebuffer, flags); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - BindFramebufferAsColorTexture"); draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0); } else { draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 6587069149..1384d957c1 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -222,6 +222,6 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp } tex->Release(); - RebindFramebuffer(); + RebindFramebuffer("RebindFramebuffer - NotifyStencilUpload"); return true; } diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 427672234c..f729c75224 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -917,7 +917,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr TexCacheEntry::TexStatus alphaStatus = CheckAlpha(clutBuf_, getClutDestFormatVulkan(clutFormat), clutTotalColors, clutTotalColors, 1); gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); - framebufferManager_->RebindFramebuffer(); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0); imageView_ = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW); @@ -928,7 +928,6 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr } else { entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; - framebufferManager_->RebindFramebuffer(); // TODO: This line should usually not be needed. imageView_ = framebufferManagerVulkan_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); drawEngine_->SetDepalTexture(VK_NULL_HANDLE); gstate_c.SetUseShaderDepal(false); @@ -1393,7 +1392,7 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); // We may have blitted to a temp FBO. - framebufferManager_->RebindFramebuffer(); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); return retval; } @@ -1433,7 +1432,7 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); - framebufferManager_->RebindFramebuffer(); + framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); return true; } diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 474ed3a2f0..9e047d00be 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -1200,7 +1200,6 @@ void VulkanRenderManager::EndSyncFrame(int frame) { } void VulkanRenderManager::FlushSync() { - // TODO: Reset curRenderStep_? renderStepOffset_ += (int)steps_.size(); int curFrame = vulkan_->GetCurFrame(); From 0c489e2d0d8857eb6b47156d14a91ee8257d8839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 2 Jun 2020 11:18:42 +0200 Subject: [PATCH 103/848] We need to check for renderpass change and dirty here too. What a mess.. --- GPU/Vulkan/DrawEngineVulkan.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index f383f436de..6d300be92b 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -591,6 +591,15 @@ void DrawEngineVulkan::DoFlush() { // TODO: Needs to be behind a check for changed render pass, at an appropriate time in this function. // Similar issues as with the lastRenderStepId_ check. Will need a bit of a rethink. lastPipeline_ = nullptr; + // If have a new render pass, dirty our dynamic state so it gets re-set. + // We have to do this again after the last possible place in DoFlush that can cause a renderpass switch + // like a shader blend blit or similar. But before we actually set the state! + int curRenderStepId = renderManager->GetCurrentStepId(); + if (lastRenderStepId_ != curRenderStepId) { + // Dirty everything that has dynamic state that will need re-recording. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE); + lastRenderStepId_ = curRenderStepId; + } FrameData *frame = &frame_[vulkan_->GetCurFrame()]; From dd948383af7ee5c44cc9f95ee759970565d77407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 2 Jun 2020 23:18:09 +0200 Subject: [PATCH 104/848] VFPU interpreter: Improve some error messages, after seeing a bad one in #10196. --- Core/MIPS/MIPSIntVFPU.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 8e3ad0ba01..322d334153 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -213,7 +213,7 @@ namespace MIPSInt { if (addr & 0x3) { - _dbg_assert_msg_(CPU, 0, "Misaligned lvX.q"); + _dbg_assert_msg_(CPU, 0, "Misaligned lvX.q at %08x (pc = %08x)", addr, PC); } float d[4]; ReadVector(d, V_Quad, vt); @@ -241,7 +241,7 @@ namespace MIPSInt case 54: //lv.q if (addr & 0xF) { - _dbg_assert_msg_(CPU, 0, "Misaligned lv.q"); + _dbg_assert_msg_(CPU, 0, "Misaligned lv.q at %08x (pc = %08x)", addr, PC); } #ifndef COMMON_BIG_ENDIAN WriteVector((const float*)Memory::GetPointer(addr), V_Quad, vt); @@ -261,7 +261,7 @@ namespace MIPSInt { if (addr & 0x3) { - _dbg_assert_msg_(CPU, 0, "Misaligned svX.q"); + _dbg_assert_msg_(CPU, 0, "Misaligned svX.q at %08x (pc = %08x)", addr, PC); } float d[4]; ReadVector(d, V_Quad, vt); @@ -288,7 +288,7 @@ namespace MIPSInt case 62: //sv.q if (addr & 0xF) { - _dbg_assert_msg_(CPU, 0, "Misaligned sv.q"); + _dbg_assert_msg_(CPU, 0, "Misaligned sv.q at %08x (pc = %08x)", addr, PC); } #ifndef COMMON_BIG_ENDIAN ReadVector(reinterpret_cast(Memory::GetPointer(addr)), V_Quad, vt); @@ -422,7 +422,7 @@ namespace MIPSInt } else if (type == 7) { f[0] = Float16ToFloat32((u16)uimm16); // vfim } else { - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(CPU, 0, "Invalid Viim opcode type %d", type); f[0] = 0; } @@ -634,7 +634,7 @@ namespace MIPSInt case 26: { d[i] = -vfpu_sin(s[i]); } break; // vnsin case 28: d[i] = 1.0f / powf(2.0, s[i]); break; // vrexp2 default: - _dbg_assert_msg_(CPU,0,"Trying to interpret VV2Op instruction that can't be interpreted"); + _dbg_assert_msg_(CPU, false, "Invalid VV2Op op type %d", optype); break; } } @@ -993,7 +993,7 @@ namespace MIPSInt break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(CPU, false, "Trying to interpret instruction that can't be interpreted"); break; } @@ -1051,7 +1051,7 @@ namespace MIPSInt case V_Pair: oz = V_Single; break; case V_Single: oz = V_Single; break; default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(CPU, false, "Trying to interpret instruction that can't be interpreted"); oz = V_Single; break; } From 1d9d15a1d73e4c311f5050ad6b04742ee9534a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 3 Jun 2020 09:18:06 +0200 Subject: [PATCH 105/848] Experimental commit: Bump up scratchpad size so that Android will act like Windows in #10196 (Spider-Man 3) --- Core/MemMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MemMap.h b/Core/MemMap.h index 28c635c181..7b57a1331e 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -97,7 +97,7 @@ enum VRAM_SIZE = 0x00200000, - SCRATCHPAD_SIZE = 0x00004000, + SCRATCHPAD_SIZE = 0x00010000, #ifdef MASKED_PSP_MEMORY // This wraparound should work for PSP too. From 20afef4c35da34fa94648e53c7a19bf360da105b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 3 Jun 2020 09:19:38 +0200 Subject: [PATCH 106/848] Revert "Experimental commit: Bump up scratchpad size so that Android will act like Windows in #10196 (Spider-Man 3)" This reverts commit 1d9d15a1d73e4c311f5050ad6b04742ee9534a81. --- Core/MemMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MemMap.h b/Core/MemMap.h index 7b57a1331e..28c635c181 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -97,7 +97,7 @@ enum VRAM_SIZE = 0x00200000, - SCRATCHPAD_SIZE = 0x00010000, + SCRATCHPAD_SIZE = 0x00004000, #ifdef MASKED_PSP_MEMORY // This wraparound should work for PSP too. From d8992a6ae3b8f8238ecfff25e516075153d67b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 3 Jun 2020 10:34:21 +0200 Subject: [PATCH 107/848] Repeat of the experimental commit, was too fast for the build bot. --- Core/MemMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MemMap.h b/Core/MemMap.h index 28c635c181..7b57a1331e 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -97,7 +97,7 @@ enum VRAM_SIZE = 0x00200000, - SCRATCHPAD_SIZE = 0x00004000, + SCRATCHPAD_SIZE = 0x00010000, #ifdef MASKED_PSP_MEMORY // This wraparound should work for PSP too. From c739d4e16424751a4dde73fe769dd783ec5037b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 3 Jun 2020 11:55:14 +0200 Subject: [PATCH 108/848] Revert "Repeat of the experimental commit, was too fast for the build bot." This reverts commit d8992a6ae3b8f8238ecfff25e516075153d67b86. --- Core/MemMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MemMap.h b/Core/MemMap.h index 7b57a1331e..28c635c181 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -97,7 +97,7 @@ enum VRAM_SIZE = 0x00200000, - SCRATCHPAD_SIZE = 0x00010000, + SCRATCHPAD_SIZE = 0x00004000, #ifdef MASKED_PSP_MEMORY // This wraparound should work for PSP too. From 45bfb4f52baf0185dc9ab1704c32c2cd54c6cbb9 Mon Sep 17 00:00:00 2001 From: iota97 Date: Thu, 4 Jun 2020 19:08:10 +0200 Subject: [PATCH 109/848] Code style fix --- Core/CwCheat.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 7712153740..3b8e643097 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -971,16 +971,16 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, std::string shaderName = shaderChain[op.PostShaderUniform.shader]->section; if (shaderName != "Off") { switch (op.PostShaderUniform.format) { - case (0): + case 0: g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u & 0x000000FF; break; - case (1): + case 1: g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u & 0x0000FFFF; break; - case (2): + case 2: g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.u; break; - case (3): + case 3: g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderName.c_str(), op.PostShaderUniform.uniform + 1)] = value.f; break; } From 021e783b4af1dd438bf33d570141adecda16bc8a Mon Sep 17 00:00:00 2001 From: Nikita Filippov Date: Sun, 24 May 2020 18:18:48 +0100 Subject: [PATCH 110/848] rudimentary serch function added for the memory dialog fixed the memory addressing bug in search the search box almost works search now works, however the strings in search window neeed a fix fixed the address display in search results search works fixed review comments, except .rc preadjust the button placement fixed rc --- Windows/Debugger/CtrlMemView.cpp | 53 ++++++- Windows/Debugger/CtrlMemView.h | 12 +- Windows/Debugger/Debugger_MemoryDlg.cpp | 200 ++++++++++++++---------- Windows/Debugger/Debugger_MemoryDlg.h | 11 +- Windows/InputBox.cpp | 8 +- Windows/ppsspp.rc | 17 +- Windows/resource.h | 3 + 7 files changed, 197 insertions(+), 107 deletions(-) diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 331126a00e..72afbffcb6 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -2,14 +2,13 @@ #include #include - +#include #include "Core/Config.h" #include "Windows/resource.h" #include "Core/MemMap.h" #include "Windows/W32Util/Misc.h" #include "Windows/InputBox.h" #include "Windows/main.h" -#include "Core/Debugger/SymbolMap.h" #include "base/display.h" #include "Debugger_Disasm.h" @@ -174,8 +173,6 @@ CtrlMemView *CtrlMemView::getFrom(HWND hwnd) } - - void CtrlMemView::onPaint(WPARAM wParam, LPARAM lParam) { auto memLock = Memory::Lock(); @@ -634,6 +631,39 @@ void CtrlMemView::scrollCursor(int bytes) redraw(); } + +std::vector CtrlMemView::searchString(std::string searchQuery) +{ + + std::vector searchResAddrs; + std::vector searchData; + + auto memLock = Memory::Lock(); + if (!PSP_IsInited()) + return searchResAddrs; + + size_t queryLength = searchQuery.length(); + u32 segmentStart = PSP_GetKernelMemoryBase(); //RAM start + u32 const segmentEnd = PSP_GetUserMemoryEnd() - queryLength; //RAM end + u8* ptr; + + redraw(); + for (segmentStart = PSP_GetKernelMemoryBase(); segmentStart < segmentEnd; segmentStart++) { + if (KeyDownAsync(VK_ESCAPE)) + { + return searchResAddrs; + } + + ptr = Memory::GetPointer(segmentStart); + if (memcmp(ptr, searchQuery.c_str(), queryLength) == 0) { + searchResAddrs.push_back(segmentStart); + } + }; + redraw(); + + return searchResAddrs; +}; + void CtrlMemView::search(bool continueSearch) { auto memLock = Memory::Lock(); @@ -641,6 +671,9 @@ void CtrlMemView::search(bool continueSearch) return; u32 searchAddress; + u32 segmentStart; + u32 segmentEnd; + u8* dataPointer; if (continueSearch == false || searchQuery[0] == 0) { if (InputBox_GetString(GetModuleHandle(NULL),wnd,L"Search for", "",searchQuery) == false) @@ -698,11 +731,15 @@ void CtrlMemView::search(bool continueSearch) searching = true; redraw(); // so the cursor is disabled + + + for (size_t i = 0; i < memoryAreas.size(); i++) { - u32 segmentStart = memoryAreas[i].first; - u32 segmentEnd = memoryAreas[i].second; - u8* dataPointer = Memory::GetPointer(segmentStart); + segmentStart = memoryAreas[i].first; + segmentEnd = memoryAreas[i].second; + + dataPointer = Memory::GetPointer(segmentStart); if (dataPointer == NULL) continue; // better safe than sorry, I guess if (searchAddress < segmentStart) searchAddress = segmentStart; @@ -756,7 +793,7 @@ void CtrlMemView::drawOffsetScale(HDC hdc) } -void CtrlMemView::toggleOffsetScale(OffsetToggles toggle) +void CtrlMemView::toggleOffsetScale(CommonToggles toggle) { if (toggle == On) displayOffsetScale = true; diff --git a/Windows/Debugger/CtrlMemView.h b/Windows/Debugger/CtrlMemView.h index d5f8079d7f..44ab3bcdf0 100644 --- a/Windows/Debugger/CtrlMemView.h +++ b/Windows/Debugger/CtrlMemView.h @@ -24,7 +24,7 @@ enum OffsetSpacing { offsetLine = 1, // the line on which the offsets should be written }; -enum OffsetToggles { +enum CommonToggles { On, Off, }; @@ -54,8 +54,11 @@ class CtrlMemView int visibleRows; std::string searchQuery; + + int matchAddress; bool searching; + bool searchStringValue; bool hasFocus; static wchar_t szClassName[]; @@ -78,7 +81,7 @@ public: { return debugger; } - + std::vector searchString(std::string searchQuery); void onPaint(WPARAM wParam, LPARAM lParam); void onVScroll(WPARAM wParam, LPARAM lParam); void onKeyDown(WPARAM wParam, LPARAM lParam); @@ -94,5 +97,6 @@ public: void scrollCursor(int bytes); void drawOffsetScale(HDC hdc); - void toggleOffsetScale(OffsetToggles toggle); -}; \ No newline at end of file + void toggleOffsetScale(CommonToggles toggle); + void toggleStringSearch(CommonToggles toggle); +}; diff --git a/Windows/Debugger/Debugger_MemoryDlg.cpp b/Windows/Debugger/Debugger_MemoryDlg.cpp index dd4a3b91ce..f5c2fa493d 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.cpp +++ b/Windows/Debugger/Debugger_MemoryDlg.cpp @@ -13,11 +13,15 @@ #include "Debugger_MemoryDlg.h" #include "CtrlMemView.h" #include "DebuggerShared.h" +#include "LogManager.h" +#include "winnt.h" +#include +#include -RECT CMemoryDlg::slRect; +RECT CMemoryDlg::slRect; //sym list rect -FAR WNDPROC DefAddressEditProc; +FAR WNDPROC DefAddressEditProc; HWND AddressEditParentHwnd = 0; LRESULT CALLBACK AddressEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) @@ -58,22 +62,30 @@ CMemoryDlg::CMemoryDlg(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu SetWindowText(m_hDlg,temp); ShowWindow(m_hDlg,SW_HIDE); - CtrlMemView *ptr = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_MEMVIEW)); - ptr->setDebugger(_cpu); + + memViewHdl = GetDlgItem(m_hDlg, IDC_MEMVIEW); + symListHdl = GetDlgItem(m_hDlg, IDC_SYMBOLS); + searchBoxHdl = GetDlgItem(m_hDlg, IDC_SEARCH_BOX); + srcListHdl = GetDlgItem(m_hDlg, IDC_SEARCH_RESULTS); + + memView = CtrlMemView::getFrom(memViewHdl); + memView->setDebugger(_cpu); Button_SetCheck(GetDlgItem(m_hDlg,IDC_RAM), TRUE); Button_SetCheck(GetDlgItem(m_hDlg,IDC_MODESYMBOLS), TRUE); - GetWindowRect(GetDlgItem(m_hDlg,IDC_SYMBOLS),&slRect); + GetWindowRect(symListHdl, &slRect); + GetWindowRect(srcListHdl, &srRect); + // subclass the edit box - HWND editWnd = GetDlgItem(m_hDlg,IDC_ADDRESS); + editWnd = GetDlgItem(m_hDlg,IDC_ADDRESS); DefAddressEditProc = (WNDPROC)GetWindowLongPtr(editWnd,GWLP_WNDPROC); SetWindowLongPtr(editWnd,GWLP_WNDPROC,(LONG_PTR)AddressEditProc); AddressEditParentHwnd = m_hDlg; Size(); -} +} CMemoryDlg::~CMemoryDlg(void) @@ -84,22 +96,33 @@ void CMemoryDlg::Update(void) { if (m_hDlg != NULL) { - CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_MEMVIEW)); - if (mv != NULL) - mv->redraw(); + if (memView != NULL) + memView->redraw(); } } +void CMemoryDlg::searchBoxRedraw(std::vector results) { + int index; + wchar_t temp[256]; + SendMessage(srcListHdl, WM_SETREDRAW, FALSE, 0); + ListBox_ResetContent(srcListHdl); + for (int i = 0; i < results.size(); i++) { + wsprintf(temp, L"0x%08X", results[i]); + index = (int)ListBox_AddString(srcListHdl,temp); + ListBox_SetItemData(srcListHdl, index, results[i]); + } + SendMessage(srcListHdl, WM_SETREDRAW, TRUE, 0); + RedrawWindow(srcListHdl, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); +} + + void CMemoryDlg::NotifyMapLoaded() { if (m_hDlg) { - HWND list = GetDlgItem(m_hDlg,IDC_SYMBOLS); - if (g_symbolMap) - g_symbolMap->FillSymbolListBox(list, ST_DATA); - HWND lb = GetDlgItem(m_hDlg,IDC_REGIONS); - int sel = ComboBox_GetCurSel(lb); - ComboBox_ResetContent(lb); + g_symbolMap->FillSymbolListBox(symListHdl,ST_DATA); + int sel = ComboBox_GetCurSel(memViewHdl); + ComboBox_ResetContent(memViewHdl); /* for (int i = 0; i < cpu->getMemMap()->numRegions; i++) { @@ -107,84 +130,91 @@ void CMemoryDlg::NotifyMapLoaded() int n = ComboBox_AddString(lb,cpu->getMemMap()->regions[i].name); ComboBox_SetItemData(lb,n,cpu->getMemMap()->regions[i].start); }*/ - ComboBox_SetCurSel(lb,sel>=0?sel:0); + ComboBox_SetCurSel(memViewHdl,sel>=0?sel:0); } Update(); } - BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { - - switch(message) - { - case WM_COMMAND: - { - CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_MEMVIEW)); - switch (LOWORD(wParam)) + switch(message){ + case WM_COMMAND:{ + HWND lb = GetDlgItem(m_hDlg, LOWORD(wParam)); + switch (LOWORD(wParam)){ + case IDC_REGIONS: + switch (HIWORD(wParam)) { + case LBN_DBLCLK:{ + int n = ComboBox_GetCurSel(lb); + if (n!=-1){ + unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n); + memView->gotoAddr(addr); + } + } + break; + }; + break; + case IDC_SYMBOLS: + switch (HIWORD(wParam)) { + case LBN_DBLCLK:{ + int n = ListBox_GetCurSel(lb); + if (n!=-1) { + unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n); + memView->gotoAddr(addr); + } + } + break; + }; + case IDC_SEARCH_RESULTS: + switch (HIWORD(wParam)) { + case LBN_DBLCLK: { + int n = ListBox_GetCurSel(lb); + if (n != -1) { + unsigned int addr = (unsigned int)ListBox_GetItemData(lb, n); + memView->gotoAddr(addr); + } + } + break; + }; + break; + case IDC_SHOWOFFSETS: + switch (HIWORD(wParam)) { - case IDC_REGIONS: - switch (HIWORD(wParam)) - { - case LBN_DBLCLK: - { - HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam)); - int n = ComboBox_GetCurSel(lb); - if (n!=-1) - { - unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n); - mv->gotoAddr(addr); - } - } - break; - }; + case BN_CLICKED: + if (SendDlgItemMessage(m_hDlg, IDC_SHOWOFFSETS, BM_GETCHECK, 0, 0)) + memView->toggleOffsetScale(On); + else + memView->toggleOffsetScale(Off); break; - case IDC_SYMBOLS: - switch (HIWORD(wParam)) - { - case LBN_DBLCLK: - { - - HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam)); - int n = ListBox_GetCurSel(lb); - if (n!=-1) - { - unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n); - mv->gotoAddr(addr); - } - } - break; - }; - break; - case IDC_SHOWOFFSETS: - switch (HIWORD(wParam)) - { - case BN_CLICKED: - if (SendDlgItemMessage(m_hDlg, IDC_SHOWOFFSETS, BM_GETCHECK, 0, 0)) - mv->toggleOffsetScale(On); - else - mv->toggleOffsetScale(Off); - break; + } + break; + case IDC_BUTTON_SEARCH: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + wchar_t temp[256]; + GetWindowText(searchBoxHdl, temp, 255); + std::vector results = memView->searchString(ConvertWStringToUTF8(temp).c_str()); + if (results.size() > 0){ + searchBoxRedraw(results); } break; } } + } break; case WM_DEB_MAPLOADED: NotifyMapLoaded(); break; - case WM_DEB_GOTOADDRESSEDIT: - { - CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_MEMVIEW)); + case WM_DEB_GOTOADDRESSEDIT:{ wchar_t temp[256]; u32 addr; - GetWindowText(GetDlgItem(m_hDlg,IDC_ADDRESS),temp,255); + GetWindowText(editWnd,temp,255); if (parseExpression(ConvertWStringToUTF8(temp).c_str(),cpu,addr) == false) { displayExpressionError(m_hDlg); } else { - mv->gotoAddr(addr); - SetFocus(GetDlgItem(m_hDlg,IDC_MEMVIEW)); + memView->gotoAddr(addr); + SetFocus(memViewHdl); } break; } @@ -198,6 +228,7 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) return TRUE; } break; + case WM_SIZE: Size(); break; @@ -212,9 +243,8 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) void CMemoryDlg::Goto(u32 addr) { Show(true); - CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(CMemoryDlg::m_hDlg,IDC_MEMVIEW)); - mv->gotoAddr(addr); - SetFocus(GetDlgItem(CMemoryDlg::m_hDlg,IDC_MEMVIEW)); + memView->gotoAddr(addr); + SetFocus(memViewHdl); } @@ -222,15 +252,17 @@ void CMemoryDlg::Size() { const float fontScale = 1.0f / g_dpi_scale_real_y; - RECT rc; - GetClientRect(m_hDlg,&rc); - int dw=rc.right-rc.left; - int dh=rc.bottom-rc.top; - HWND memView = GetDlgItem(m_hDlg, IDC_MEMVIEW); - HWND symList = GetDlgItem(m_hDlg, IDC_SYMBOLS); + GetClientRect(m_hDlg,&winRect); + int dlg_w = winRect.right - winRect.left; + int dlg_h = winRect.bottom - winRect.top; + + int wf = slRect.right-slRect.left; - int w = dw - 3 * fontScale - wf; + int w = dlg_w - 3 * fontScale - wf*2; int top = 48 * fontScale; - MoveWindow(symList,0,top,wf,dh-top,TRUE); - MoveWindow(memView,wf+4,top,w,dh-top,TRUE); + int height = dlg_h - top; + //HWND, X, Y, width, height, repaint + MoveWindow(symListHdl, 0 ,top, wf, height, TRUE); + MoveWindow(memViewHdl, wf+4 ,top, w, height, TRUE); + MoveWindow(srcListHdl, wf + 4 + w+ 4, top, wf-4, height, TRUE); } diff --git a/Windows/Debugger/Debugger_MemoryDlg.h b/Windows/Debugger/Debugger_MemoryDlg.h index d8e2c5fef4..91bf07e986 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.h +++ b/Windows/Debugger/Debugger_MemoryDlg.h @@ -6,7 +6,7 @@ #include "Core/MemMap.h" #include "Core/Debugger/DebugInterface.h" - +#include "CtrlMemView.h" #include "Common/CommonWindows.h" class CMemoryDlg : public Dialog @@ -14,11 +14,16 @@ class CMemoryDlg : public Dialog private: DebugInterface *cpu; static RECT slRect; - + RECT winRect, srRect; + CtrlMemView *memView; + HWND memViewHdl, symListHdl, editWnd, searchBoxHdl, srcListHdl; BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam); + public: int index; //helper + void searchBoxRedraw(std::vector results); + // constructor CMemoryDlg(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu); @@ -29,6 +34,8 @@ public: void Update(void); void NotifyMapLoaded(); + void NotifySearchCompleted(); + void Size(void); }; diff --git a/Windows/InputBox.cpp b/Windows/InputBox.cpp index f3aebb8582..d661e39a9c 100644 --- a/Windows/InputBox.cpp +++ b/Windows/InputBox.cpp @@ -108,10 +108,10 @@ bool InputBox_GetWString(HINSTANCE hInst, HWND hParent, const wchar_t *title, co return false; } -bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 defaultvalue, u32 &outvalue) +bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t* title, u32 defaultvalue, u32& outvalue) { wchar_t temp[256]; - wsprintf(temp,L"%08x",defaultvalue); + wsprintf(temp, L"%08x", defaultvalue); textBoxContents = temp; INT_PTR value = DialogBox(hInst, (LPCWSTR)IDD_INPUTBOX, hParent, InputBoxFunc); @@ -124,9 +124,9 @@ bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 de return true; return false; } - else + else { outvalue = 0; return false; } -} \ No newline at end of file +} diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 99da8d11f6..07c3c49fd6 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -306,7 +306,7 @@ END #include "aboutbox.rc" #endif -IDD_MEMORY DIALOGEX 0, 0, 566, 287 +IDD_MEMORY DIALOGEX 0, 0, 700, 287 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_TOOLWINDOW CAPTION "Memory View" @@ -316,11 +316,18 @@ BEGIN EDITTEXT IDC_ADDRESS,23,5,61,13,ES_AUTOHSCROLL CONTROL "Custom2",IDC_MEMVIEW,"CtrlMemView",WS_BORDER | WS_TABSTOP,126,23,316,263 LISTBOX IDC_SYMBOLS,1,23,120,263,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - CONTROL "Normal",IDC_MODENORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,248,9,40,9 - CONTROL "Symbols",IDC_MODESYMBOLS,"Button",BS_AUTORADIOBUTTON,291,9,43,8 - GROUPBOX "Mode",IDC_STATIC,241,0,104,22 - AUTOCHECKBOX "Show Offsets",IDC_SHOWOFFSETS,365,9,55,8 + + CONTROL "Normal",IDC_MODENORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,198,9,40,9 + CONTROL "Symbols",IDC_MODESYMBOLS,"Button",BS_AUTORADIOBUTTON,241,9,43,8 + GROUPBOX "Mode",IDC_STATIC,191,0,104,22 + AUTOCHECKBOX "Show Offsets",IDC_SHOWOFFSETS,300,9,55,8 COMBOBOX IDC_REGIONS,87,5,88,139,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LISTBOX IDC_SEARCH_RESULTS,557,14,140,272,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + + EDITTEXT IDC_SEARCH_BOX,397,6,100,13,ES_AUTOHSCROLL + PUSHBUTTON "Search",IDC_BUTTON_SEARCH,504,5,50,14 + LTEXT "Search:",IDC_STATIC,369,6,27,8 END IDD_INPUTBOX DIALOGEX 0, 0, 163, 55 diff --git a/Windows/resource.h b/Windows/resource.h index 3e9cc8ad93..e5e3307fae 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -86,6 +86,7 @@ #define IDC_STOPGO 1001 #define IDC_ADDRESS 1002 #define IDC_DEBUG_COUNT 1003 +#define IDC_SEARCH_BOX 1004 #define IDC_MEMORY 1006 #define IDC_SH4REGISTERS 1007 #define IDC_REGISTERS 1007 @@ -115,6 +116,7 @@ #define IDC_MODENORMAL 1099 #define IDC_MODESYMBOLS 1100 #define IDC_LOG_SHOW 1101 +#define IDC_SEARCH_RESULTS 1102 #define IDC_UPDATELOG 1108 #define IDC_SETPC 1118 #define IDC_UPDATEMISC 1134 @@ -167,6 +169,7 @@ #define IDC_BREAKPOINT_LOG_FORMAT 1199 #define IDC_SHOWOFFSETS 1200 #define IDC_GEDBG_PRIMCOUNTER 1201 +#define IDC_BUTTON_SEARCH 1204 #define ID_SHADERS_BASE 5000 From 4e7944a353e7a5455961bc1193786a0d2c5c52f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 6 Jun 2020 14:29:39 +0200 Subject: [PATCH 111/848] Fix some bugs and style for #12994 --- Windows/Debugger/CtrlMemView.cpp | 44 ++++++++++--------------- Windows/Debugger/Debugger_MemoryDlg.cpp | 13 ++++---- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 72afbffcb6..4dda0822e1 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -634,17 +634,16 @@ void CtrlMemView::scrollCursor(int bytes) std::vector CtrlMemView::searchString(std::string searchQuery) { - std::vector searchResAddrs; std::vector searchData; auto memLock = Memory::Lock(); if (!PSP_IsInited()) return searchResAddrs; - + size_t queryLength = searchQuery.length(); u32 segmentStart = PSP_GetKernelMemoryBase(); //RAM start - u32 const segmentEnd = PSP_GetUserMemoryEnd() - queryLength; //RAM end + const u32 segmentEnd = PSP_GetUserMemoryEnd() - (u32)queryLength; //RAM end u8* ptr; redraw(); @@ -660,7 +659,7 @@ std::vector CtrlMemView::searchString(std::string searchQuery) } }; redraw(); - + return searchResAddrs; }; @@ -670,11 +669,11 @@ void CtrlMemView::search(bool continueSearch) if (!PSP_IsInited()) return; - u32 searchAddress; - u32 segmentStart; - u32 segmentEnd; - u8* dataPointer; - if (continueSearch == false || searchQuery[0] == 0) + u32 searchAddress = 0; + u32 segmentStart = 0; + u32 segmentEnd = 0; + u8* dataPointer = 0; + if (continueSearch == false || searchQuery.empty()) { if (InputBox_GetString(GetModuleHandle(NULL),wnd,L"Search for", "",searchQuery) == false) { @@ -706,7 +705,7 @@ void CtrlMemView::search(bool continueSearch) } u8 value = 0; - for (int i = 0; i < 2; i++) + for (int i = 0; i < 2 && index < searchQuery.size(); i++) { char c = tolower(searchQuery[index++]); if (c >= 'a' && c <= 'f') @@ -726,19 +725,16 @@ void CtrlMemView::search(bool continueSearch) } std::vector> memoryAreas; - memoryAreas.push_back(std::pair(0x04000000,0x04200000)); - memoryAreas.push_back(std::pair(0x08000000,0x0A000000)); + memoryAreas.push_back(std::pair(0x04000000, 0x04200000)); + memoryAreas.push_back(std::pair(0x08000000, 0x0A000000)); searching = true; redraw(); // so the cursor is disabled - - - for (size_t i = 0; i < memoryAreas.size(); i++) - { + for (size_t i = 0; i < memoryAreas.size(); i++) { segmentStart = memoryAreas[i].first; segmentEnd = memoryAreas[i].second; - + dataPointer = Memory::GetPointer(segmentStart); if (dataPointer == NULL) continue; // better safe than sorry, I guess @@ -746,19 +742,15 @@ void CtrlMemView::search(bool continueSearch) if (searchAddress >= segmentEnd) continue; int index = searchAddress-segmentStart; - int endIndex = segmentEnd-segmentStart-(int)searchData.size(); + int endIndex = segmentEnd-segmentStart - (int)searchData.size(); - while (index < endIndex) - { + while (index < endIndex) { // cancel search - if ((index % 256) == 0 && KeyDownAsync(VK_ESCAPE)) - { + if ((index % 256) == 0 && KeyDownAsync(VK_ESCAPE)) { searching = false; return; } - - if (memcmp(&dataPointer[index],searchData.data(),searchData.size()) == 0) - { + if (memcmp(&dataPointer[index], searchData.data(), searchData.size()) == 0) { matchAddress = index+segmentStart; searching = false; gotoAddr(matchAddress); @@ -783,14 +775,12 @@ void CtrlMemView::drawOffsetScale(HDC hdc) currentX = addressStart + ((8 + 1)*charWidth); // the start offset, the size of the hex addresses and one space char temp[64]; - for (int i = 0; i < 16; i++) { sprintf(temp, "%02X", i); TextOutA(hdc, currentX, offsetPositionY, temp, 2); currentX += 3 * charWidth; // hex and space } - } void CtrlMemView::toggleOffsetScale(CommonToggles toggle) diff --git a/Windows/Debugger/Debugger_MemoryDlg.cpp b/Windows/Debugger/Debugger_MemoryDlg.cpp index f5c2fa493d..c2bcd0d18f 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.cpp +++ b/Windows/Debugger/Debugger_MemoryDlg.cpp @@ -102,13 +102,12 @@ void CMemoryDlg::Update(void) } void CMemoryDlg::searchBoxRedraw(std::vector results) { - int index; - wchar_t temp[256]; + wchar_t temp[256]{}; SendMessage(srcListHdl, WM_SETREDRAW, FALSE, 0); ListBox_ResetContent(srcListHdl); for (int i = 0; i < results.size(); i++) { wsprintf(temp, L"0x%08X", results[i]); - index = (int)ListBox_AddString(srcListHdl,temp); + int index = (int)ListBox_AddString(srcListHdl, temp); ListBox_SetItemData(srcListHdl, index, results[i]); } SendMessage(srcListHdl, WM_SETREDRAW, TRUE, 0); @@ -139,13 +138,13 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch(message){ case WM_COMMAND:{ - HWND lb = GetDlgItem(m_hDlg, LOWORD(wParam)); + HWND lb = GetDlgItem(m_hDlg, LOWORD(wParam)); switch (LOWORD(wParam)){ case IDC_REGIONS: - switch (HIWORD(wParam)) { + switch (HIWORD(wParam)) { case LBN_DBLCLK:{ int n = ComboBox_GetCurSel(lb); - if (n!=-1){ + if (n != -1) { unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n); memView->gotoAddr(addr); } @@ -157,7 +156,7 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) switch (HIWORD(wParam)) { case LBN_DBLCLK:{ int n = ListBox_GetCurSel(lb); - if (n!=-1) { + if (n != -1) { unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n); memView->gotoAddr(addr); } From 29cfec9bb304f2f29c72d2ace2ab02cafbd57142 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 10:14:46 +0800 Subject: [PATCH 112/848] Warp some ThreadManForKernel --- Core/HLE/sceKernel.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 520295f2d9..e638ce2886 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -870,6 +870,9 @@ const HLEFunction ThreadManForKernel[] = {0xCEADEB47, &WrapI_U, "sceKernelDelayThread", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED | HLE_KERNEL_SYSCALL }, {0x446D8DE6, &WrapI_CUUIUU, "sceKernelCreateThread", 'i', "sxxixx", HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL }, {0xF475845D, &WrapI_IIU, "sceKernelStartThread", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL }, + {0X9FA03CD3, &WrapI_I, "sceKernelDeleteThread", 'i', "i" }, + {0XAA73C935, &WrapV_I, "sceKernelExitThread", 'v', "i" }, + {0X809CE29B, &WrapV_I, "sceKernelExitDeleteThread", 'v', "i" }, }; void Register_ThreadManForUser() From 3f6ec47f181746fcc2a38e619756465c12c37549 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 10:30:55 +0800 Subject: [PATCH 113/848] Wrap sceKernelExitVSHKernel --- Core/HLE/sceKernel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index e638ce2886..392ce8a4f3 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -901,6 +901,7 @@ const HLEFunction LoadExecForKernel[] = {0x4AC57943, &WrapI_I, "sceKernelRegisterExitCallback", 'i', "i", HLE_KERNEL_SYSCALL }, {0XA3D5E142, nullptr, "LoadExecForKernel_a3d5e142", '?', "" }, {0X28D0D249, &WrapI_CU, "sceKernelLoadExec_28D0D249", 'i', "sx" }, + {0x6D302D3D, &WrapV_V, "sceKernelExitVSHKernel", 'v', "" },// when called in game mode it will have the same effect that sceKernelExitGame }; void Register_LoadExecForKernel() From bb48006b8e22166344ff37cbc2b12d55e314cf02 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 10:37:50 +0800 Subject: [PATCH 114/848] Forget HLE_KERNEL_SYSCALL flag --- Core/HLE/sceKernel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 392ce8a4f3..3e51fb8da7 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -870,9 +870,9 @@ const HLEFunction ThreadManForKernel[] = {0xCEADEB47, &WrapI_U, "sceKernelDelayThread", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED | HLE_KERNEL_SYSCALL }, {0x446D8DE6, &WrapI_CUUIUU, "sceKernelCreateThread", 'i', "sxxixx", HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL }, {0xF475845D, &WrapI_IIU, "sceKernelStartThread", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL }, - {0X9FA03CD3, &WrapI_I, "sceKernelDeleteThread", 'i', "i" }, - {0XAA73C935, &WrapV_I, "sceKernelExitThread", 'v', "i" }, - {0X809CE29B, &WrapV_I, "sceKernelExitDeleteThread", 'v', "i" }, + {0X9FA03CD3, &WrapI_I, "sceKernelDeleteThread", 'i', "i", HLE_KERNEL_SYSCALL }, + {0XAA73C935, &WrapV_I, "sceKernelExitThread", 'v', "i", HLE_KERNEL_SYSCALL }, + {0X809CE29B, &WrapV_I, "sceKernelExitDeleteThread", 'v', "i", HLE_KERNEL_SYSCALL }, }; void Register_ThreadManForUser() @@ -901,7 +901,7 @@ const HLEFunction LoadExecForKernel[] = {0x4AC57943, &WrapI_I, "sceKernelRegisterExitCallback", 'i', "i", HLE_KERNEL_SYSCALL }, {0XA3D5E142, nullptr, "LoadExecForKernel_a3d5e142", '?', "" }, {0X28D0D249, &WrapI_CU, "sceKernelLoadExec_28D0D249", 'i', "sx" }, - {0x6D302D3D, &WrapV_V, "sceKernelExitVSHKernel", 'v', "" },// when called in game mode it will have the same effect that sceKernelExitGame + {0x6D302D3D, &WrapV_V, "sceKernelExitVSHKernel", 'v', "", HLE_KERNEL_SYSCALL },// when called in game mode it will have the same effect that sceKernelExitGame }; void Register_LoadExecForKernel() From 8a905bbb9d6e1519e601b8c9db27bcb9ea3f8114 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 10:59:04 +0800 Subject: [PATCH 115/848] Wrap some SysMemForKernel Used in "Hatsune Miku Project Diva Extend" chinese patched version Prepare real support the chinese patched game. --- Core/HLE/sceKernelHeap.cpp | 3 +++ Core/HLE/sceKernelMemory.cpp | 6 +++--- Core/HLE/sceKernelMemory.h | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index 7b99eca184..1fc08f1a57 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -87,6 +87,9 @@ const HLEFunction SysMemForKernel[] = { { 0X636C953B, &WrapI_II, "sceKernelAllocHeapMemory", 'x', "ii" }, { 0XC9805775, &WrapI_I, "sceKernelDeleteHeap", 'i', "i" }, { 0X1C1FBFE7, &WrapI_IIIC, "sceKernelCreateHeap", 'i', "iixs" }, + { 0X237DBD4F, &WrapI_ICIUU, "sceKernelAllocPartitionMemory", 'i', "isixx",HLE_KERNEL_SYSCALL }, + { 0XB6D61D02, &WrapI_I, "sceKernelFreePartitionMemory", 'i', "i",HLE_KERNEL_SYSCALL }, + { 0X9D9A5BA1, &WrapU_I, "sceKernelGetBlockHeadAddr", 'x', "i",HLE_KERNEL_SYSCALL }, }; void Register_SysMemForKernel() { diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 40cccaa03d..41ccd6d82a 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -969,7 +969,7 @@ static u32 sceKernelTotalFreeMemSize() return retVal; } -static int sceKernelAllocPartitionMemory(int partition, const char *name, int type, u32 size, u32 addr) +int sceKernelAllocPartitionMemory(int partition, const char *name, int type, u32 size, u32 addr) { if (name == NULL) { @@ -1019,14 +1019,14 @@ static int sceKernelAllocPartitionMemory(int partition, const char *name, int ty return uid; } -static int sceKernelFreePartitionMemory(SceUID id) +int sceKernelFreePartitionMemory(SceUID id) { DEBUG_LOG(SCEKERNEL,"sceKernelFreePartitionMemory(%d)",id); return kernelObjects.Destroy(id); } -static u32 sceKernelGetBlockHeadAddr(SceUID id) +u32 sceKernelGetBlockHeadAddr(SceUID id) { u32 error; PartitionMemoryBlock *block = kernelObjects.Get(id, error); diff --git a/Core/HLE/sceKernelMemory.h b/Core/HLE/sceKernelMemory.h index dce6df77e0..29d7356d00 100644 --- a/Core/HLE/sceKernelMemory.h +++ b/Core/HLE/sceKernelMemory.h @@ -67,3 +67,7 @@ int sceKernelFreeTlspl(SceUID uid); int sceKernelReferTlsplStatus(SceUID uid, u32 infoPtr); void Register_SysMemUserForUser(); + +int sceKernelAllocPartitionMemory(int partition, const char *name, int type, u32 size, u32 addr); +int sceKernelFreePartitionMemory(SceUID id); +u32 sceKernelGetBlockHeadAddr(SceUID id); From e8bd231cfb454e85c5aa22ed0fcac4ea7229f91e Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 11:17:53 +0800 Subject: [PATCH 116/848] Wrap sceKernelUnloadModule in ModuleMgrForKernel --- Core/HLE/sceKernelModule.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 431870fc45..bc8f91acec 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2546,6 +2546,7 @@ const HLEFunction ModuleMgrForKernel[] = {0xA1A78C58, &WrapU_CUU, "sceKernelLoadModuleForLoadExecVSHDisc", 'x', "sxx", HLE_KERNEL_SYSCALL }, //fix for tiger x dragon {0x748CBED9, &WrapU_UU, "sceKernelQueryModuleInfo", 'x', "xx", HLE_KERNEL_SYSCALL }, {0x644395E2, &WrapU_UUU, "sceKernelGetModuleIdList", 'x', "xxx", HLE_KERNEL_SYSCALL }, + {0X2E0911AA, &WrapU_U, "sceKernelUnloadModule", 'x', "x" , HLE_KERNEL_SYSCALL }, }; void Register_ModuleMgrForUser() From 5a7ed46938e1975ecb366d38096bf569a1e4770b Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 11:46:08 +0800 Subject: [PATCH 117/848] Fix logging as @unknownbrackets suggest --- Core/HLE/sceKernel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 3e51fb8da7..e07cc2b2be 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -901,7 +901,7 @@ const HLEFunction LoadExecForKernel[] = {0x4AC57943, &WrapI_I, "sceKernelRegisterExitCallback", 'i', "i", HLE_KERNEL_SYSCALL }, {0XA3D5E142, nullptr, "LoadExecForKernel_a3d5e142", '?', "" }, {0X28D0D249, &WrapI_CU, "sceKernelLoadExec_28D0D249", 'i', "sx" }, - {0x6D302D3D, &WrapV_V, "sceKernelExitVSHKernel", 'v', "", HLE_KERNEL_SYSCALL },// when called in game mode it will have the same effect that sceKernelExitGame + {0x6D302D3D, &WrapV_V, "sceKernelExitVSHKernel", 'v', "x", HLE_KERNEL_SYSCALL },// when called in game mode it will have the same effect that sceKernelExitGame }; void Register_LoadExecForKernel() From b3468b2c7489f802ab5c41bada9fd62d5b53c46b Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 18:15:49 +0800 Subject: [PATCH 118/848] Real support "Hatsune Miku Project Diva Extend" chinese version --- Core/PSPLoaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index d72c648601..eb910487f2 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -203,7 +203,7 @@ static const char *altBootNames[] = { "disc0:/PSP_GAME/SYSDIR/EBOOT.LLD", //"disc0:/PSP_GAME/SYSDIR/OLD_EBOOT.BIN", //Utawareru Mono Chinese version "disc0:/PSP_GAME/SYSDIR/EBOOT.123", - "disc0:/PSP_GAME/SYSDIR/EBOOT_LRC_CH.BIN", + //"disc0:/PSP_GAME/SYSDIR/EBOOT_LRC_CH.BIN", // Hatsune Miku Project Diva Extend chinese version "disc0:/PSP_GAME/SYSDIR/BOOT0.OLD", "disc0:/PSP_GAME/SYSDIR/BOOT1.OLD", "disc0:/PSP_GAME/SYSDIR/BINOT.BIN", From 6254c12e6ccc295a55cfde06ade366208f679bd8 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 18:17:09 +0800 Subject: [PATCH 119/848] Reduce sysclib_memcpy log level The function is right. Tested on "Hatsune Miku Project Diva Extend" chinese patched version --- Core/HLE/sceKernelInterrupt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 6ec86f99af..aafa7150eb 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -681,7 +681,7 @@ const HLEFunction Kernel_Library[] = }; static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) { - ERROR_LOG(SCEKERNEL, "Untested sysclib_memcpy(dest=%08x, src=%08x, size=%i)", dst, src, size); + DEBUG_LOG(SCEKERNEL, "Untested sysclib_memcpy(dest=%08x, src=%08x, size=%i)", dst, src, size); if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { memcpy(Memory::GetPointer(dst), Memory::GetPointer(src), size); } From d17f50e07bf689ece053a625059c236968ac0e56 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 18:28:09 +0800 Subject: [PATCH 120/848] Kill the log as @hrydgard suggest --- Core/HLE/sceKernelInterrupt.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index aafa7150eb..72d0c98da6 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -680,8 +680,7 @@ const HLEFunction Kernel_Library[] = {0XFA835CDE, &WrapI_I, "sceKernelGetTlsAddr", 'i', "i" }, }; -static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) { - DEBUG_LOG(SCEKERNEL, "Untested sysclib_memcpy(dest=%08x, src=%08x, size=%i)", dst, src, size); +static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) { if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { memcpy(Memory::GetPointer(dst), Memory::GetPointer(src), size); } From d43c1baa193340b69ab834895608b3474caf41f8 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 7 Jun 2020 19:36:12 +0800 Subject: [PATCH 121/848] Add sceKernelStdout --- Core/HLE/sceIo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 567f0c069a..9f3cf81f78 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -2865,7 +2865,7 @@ const HLEFunction StdioForKernel[] = { {0X2CCF071A, nullptr, "fdprintf", '?', "" }, {0XD97C8CB9, nullptr, "puts", '?', "" }, {0X172D316E, nullptr, "sceKernelStdin", '?', "" }, - {0XA6BAB2E9, nullptr, "sceKernelStdout", '?', "" }, + {0XA6BAB2E9, &WrapU_V, "sceKernelStdout", 'i', "" ,HLE_KERNEL_SYSCALL }, {0XF78BA90A, nullptr, "sceKernelStderr", '?', "" }, }; From 0a2145a9f5e3bd7a8fc6854414a5525890b1024a Mon Sep 17 00:00:00 2001 From: Rokkuman X <50436544+RokkumanX@users.noreply.github.com> Date: Wed, 10 Jun 2020 19:46:21 +0200 Subject: [PATCH 122/848] Link to buildbot builds of PPSSPP Orphis is king, nuff said! --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index aa36a2b225..937e70fdfe 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ For the latest source code, see [our github page](https://github.com/hrydgard/pp For build instructions and other development tutorials, see [the wiki](https://github.com/hrydgard/ppsspp/wiki). +If you want to download regularly updated builds for Android, Windows x86 and x64, proceed to this [page](https://buildbot.orphis.net/ppsspp/) + For game compatibility, see [community compatibility feedback](https://report.ppsspp.org/games). What's new in 1.9.0/1.9.3 From 9ef521d945a13b5d40b040eac5a6eef712b30b9b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 May 2020 09:57:01 -0700 Subject: [PATCH 123/848] GPU: Avoid immediate postshader FBO recreate. Before, we created things at the wrong size, then recreated at the right. Now we just start at the correct size once. --- GPU/Common/FramebufferCommon.cpp | 5 ++--- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/GLES/FramebufferManagerGLES.cpp | 2 -- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/Vulkan/FramebufferVulkan.cpp | 6 ------ GPU/Vulkan/FramebufferVulkan.h | 2 -- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- 8 files changed, 6 insertions(+), 17 deletions(-) diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 548d82faef..1b4751b527 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -45,7 +45,6 @@ FramebufferManagerCommon::FramebufferManagerCommon(Draw::DrawContext *draw) : draw_(draw), displayFormat_(GE_FORMAT_565) { presentation_ = new PresentationCommon(draw); - UpdateSize(); } FramebufferManagerCommon::~FramebufferManagerCommon() { @@ -70,8 +69,8 @@ FramebufferManagerCommon::~FramebufferManagerCommon() { } void FramebufferManagerCommon::Init() { - BeginFrame(); - presentation_->UpdatePostShader(); + // We may need to override the render size if the shader is upscaling or SSAA. + Resized(); } bool FramebufferManagerCommon::UpdateSize() { diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 29faefeef3..6e497064c7 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -87,10 +87,10 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) drawEngine_.SetShaderManager(shaderManagerD3D11_); drawEngine_.SetTextureCache(textureCacheD3D11_); drawEngine_.SetFramebufferManager(framebufferManagerD3D11_); - framebufferManagerD3D11_->Init(); framebufferManagerD3D11_->SetTextureCache(textureCacheD3D11_); framebufferManagerD3D11_->SetShaderManager(shaderManagerD3D11_); framebufferManagerD3D11_->SetDrawEngine(&drawEngine_); + framebufferManagerD3D11_->Init(); textureCacheD3D11_->SetFramebufferManager(framebufferManagerD3D11_); textureCacheD3D11_->SetDepalShaderCache(depalShaderCache_); textureCacheD3D11_->SetShaderManager(shaderManagerD3D11_); diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index d3de79ec2b..a51db99ca4 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -70,10 +70,10 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) drawEngine_.SetShaderManager(shaderManagerDX9_); drawEngine_.SetTextureCache(textureCacheDX9_); drawEngine_.SetFramebufferManager(framebufferManagerDX9_); - framebufferManagerDX9_->Init(); framebufferManagerDX9_->SetTextureCache(textureCacheDX9_); framebufferManagerDX9_->SetShaderManager(shaderManagerDX9_); framebufferManagerDX9_->SetDrawEngine(&drawEngine_); + framebufferManagerDX9_->Init(); textureCacheDX9_->SetFramebufferManager(framebufferManagerDX9_); textureCacheDX9_->SetDepalShaderCache(&depalShaderCache_); textureCacheDX9_->SetShaderManager(shaderManagerDX9_); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 3314068d24..cd63cb8c0d 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -111,8 +111,6 @@ FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw, GLRender void FramebufferManagerGLES::Init() { FramebufferManagerCommon::Init(); - // Workaround for upscaling shaders where we force x1 resolution without saving it - Resized(); CompileDraw2DProgram(); } diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index ceefecbcb3..5635363338 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -71,10 +71,10 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) drawEngine_.SetTextureCache(textureCacheGL_); drawEngine_.SetFramebufferManager(framebufferManagerGL_); drawEngine_.SetFragmentTestCache(&fragmentTestCache_); - framebufferManagerGL_->Init(); framebufferManagerGL_->SetTextureCache(textureCacheGL_); framebufferManagerGL_->SetShaderManager(shaderManagerGL_); framebufferManagerGL_->SetDrawEngine(&drawEngine_); + framebufferManagerGL_->Init(); depalShaderCache_.Init(); textureCacheGL_->SetFramebufferManager(framebufferManagerGL_); textureCacheGL_->SetDepalShaderCache(&depalShaderCache_); diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 8eead37278..0d266d3c99 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -170,12 +170,6 @@ void FramebufferManagerVulkan::NotifyClear(bool clearColor, bool clearAlpha, boo } } -void FramebufferManagerVulkan::Init() { - FramebufferManagerCommon::Init(); - // Workaround for upscaling shaders where we force x1 resolution without saving it - Resized(); -} - void FramebufferManagerVulkan::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags) { float texCoords[8] = { u0,v0, diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index 3a8e1f4304..622ad28164 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -46,8 +46,6 @@ public: // x,y,w,h are relative to destW, destH which fill out the target completely. void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags) override; - virtual void Init() override; - void BeginFrameVulkan(); // there's a BeginFrame in the base class, which this calls void EndFrame(); diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 43de4d1078..d111a1db77 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -72,10 +72,10 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) drawEngine_.SetShaderManager(shaderManagerVulkan_); drawEngine_.SetPipelineManager(pipelineManager_); framebufferManagerVulkan_->SetVulkan2D(&vulkan2D_); - framebufferManagerVulkan_->Init(); framebufferManagerVulkan_->SetTextureCache(textureCacheVulkan_); framebufferManagerVulkan_->SetDrawEngine(&drawEngine_); framebufferManagerVulkan_->SetShaderManager(shaderManagerVulkan_); + framebufferManagerVulkan_->Init(); textureCacheVulkan_->SetDepalShaderCache(&depalShaderCache_); textureCacheVulkan_->SetFramebufferManager(framebufferManagerVulkan_); textureCacheVulkan_->SetShaderManager(shaderManagerVulkan_); From dcf4498f82f4c218726b39ce132b7be4c34a2bcc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 May 2020 10:02:12 -0700 Subject: [PATCH 124/848] GPU: Alternate FBOs for chained postshaders. If you apply 4 in a row at the same resolution, we only need two actual FBOs. This will use less VRAM. --- GPU/Common/PresentationCommon.cpp | 31 +++++++++++++++++++++++++++---- GPU/Common/PresentationCommon.h | 8 ++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 871322073e..fc0a5c89e0 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -286,13 +286,10 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha nextHeight = (int)rc.h; } - // No depth/stencil for post processing - Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ nextWidth, nextHeight, 1, 1, false, Draw::FBO_8888 }); - if (!fbo) { + if (!AllocateFramebuffer(nextWidth, nextHeight)) { pipeline->Release(); return false; } - postShaderFramebuffers_.push_back(fbo); } postShaderPipelines_.push_back(pipeline); @@ -300,6 +297,31 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha return true; } +bool PresentationCommon::AllocateFramebuffer(int w, int h) { + using namespace Draw; + + // First, let's try to find a framebuffer of the right size that is NOT the most recent. + Framebuffer *last = postShaderFramebuffers_.empty() ? nullptr : postShaderFramebuffers_.back(); + for (const auto &prev : postShaderFBOUsage_) { + if (prev.w == w && prev.h == h && prev.fbo != last) { + // Great, this one's perfect. Ref it for when we release. + prev.fbo->AddRef(); + postShaderFramebuffers_.push_back(prev.fbo); + return true; + } + } + + // No depth/stencil for post processing + Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888 }); + if (!fbo) { + return false; + } + + postShaderFBOUsage_.push_back({ fbo, w, h }); + postShaderFramebuffers_.push_back(fbo); + return true; +} + void PresentationCommon::ShowPostShaderError(const std::string &errorString) { // let's show the first line of the error string as an OSM. std::set blacklistedLines; @@ -435,6 +457,7 @@ void PresentationCommon::DestroyPostShader() { DoReleaseVector(postShaderPipelines_); DoReleaseVector(postShaderFramebuffers_); postShaderInfo_.clear(); + postShaderFBOUsage_.clear(); } Draw::ShaderModule *PresentationCommon::CompileShaderModule(Draw::ShaderStage stage, ShaderLanguage lang, const std::string &src, std::string *errorString) { diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index 502ef318e9..96f6832f8d 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -122,6 +122,7 @@ protected: Draw::ShaderModule *CompileShaderModule(Draw::ShaderStage stage, ShaderLanguage lang, const std::string &src, std::string *errorString); Draw::Pipeline *CreatePipeline(std::vector shaders, bool postShader, const Draw::UniformBufferDesc *uniformDesc); bool BuildPostShader(const ShaderInfo *shaderInfo, const ShaderInfo *next); + bool AllocateFramebuffer(int w, int h); void BindSource(); @@ -155,4 +156,11 @@ protected: bool usePostShader_ = false; bool restorePostShader_ = false; ShaderLanguage lang_; + + struct PrevFBO { + Draw::Framebuffer *fbo; + int w; + int h; + }; + std::vector postShaderFBOUsage_; }; From 64435e56b1ad783d5dbedd252dfb97667cb9f423 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 May 2020 10:34:11 -0700 Subject: [PATCH 125/848] Draw: Use uniform locs for GLES, add samplers. So that we can initialize and bind samplers. --- ext/native/thin3d/GLQueueRunner.cpp | 6 +++--- ext/native/thin3d/GLQueueRunner.h | 4 ++-- ext/native/thin3d/GLRenderManager.h | 10 +++++----- ext/native/thin3d/thin3d_gl.cpp | 23 ++++++++++++++++++----- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 7be3fd09c2..c629c73d91 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -929,9 +929,9 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { case GLRRenderCommand::UNIFORMMATRIX: { assert(curProgram); - int loc = c.uniform4.loc ? *c.uniform4.loc : -1; - if (c.uniform4.name) { - loc = curProgram->GetUniformLoc(c.uniform4.name); + int loc = c.uniformMatrix4.loc ? *c.uniformMatrix4.loc : -1; + if (c.uniformMatrix4.name) { + loc = curProgram->GetUniformLoc(c.uniformMatrix4.name); } if (loc >= 0) { glUniformMatrix4fv(loc, 1, false, c.uniformMatrix4.m); diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index 06ba82af31..37838f8383 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -117,13 +117,13 @@ struct GLRRenderData { } drawIndexed; struct { const char *name; // if null, use loc - GLint *loc; // NOTE: This is a pointer so we can immediately use things that are "queried" during program creation. + const GLint *loc; // NOTE: This is a pointer so we can immediately use things that are "queried" during program creation. GLint count; float v[4]; } uniform4; struct { const char *name; // if null, use loc - GLint *loc; + const GLint *loc; float m[16]; } uniformMatrix4; struct { diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index eac80eac6f..40cbcb0d27 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -647,7 +647,7 @@ public: curRenderStep_->commands.push_back(data); } - void SetUniformI(GLint *loc, int count, const int *udata) { + void SetUniformI(const GLint *loc, int count, const int *udata) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); @@ -659,7 +659,7 @@ public: curRenderStep_->commands.push_back(data); } - void SetUniformI1(GLint *loc, int udata) { + void SetUniformI1(const GLint *loc, int udata) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); @@ -671,7 +671,7 @@ public: curRenderStep_->commands.push_back(data); } - void SetUniformF(GLint *loc, int count, const float *udata) { + void SetUniformF(const GLint *loc, int count, const float *udata) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); @@ -683,7 +683,7 @@ public: curRenderStep_->commands.push_back(data); } - void SetUniformF1(GLint *loc, const float udata) { + void SetUniformF1(const GLint *loc, const float udata) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); @@ -707,7 +707,7 @@ public: curRenderStep_->commands.push_back(data); } - void SetUniformM4x4(GLint *loc, const float *udata) { + void SetUniformM4x4(const GLint *loc, const float *udata) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index dd3aa97fb3..f35f5daece 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -323,6 +323,8 @@ public: // TODO: Optimize by getting the locations first and putting in a custom struct UniformBufferDesc dynamicUniforms; + GLint samplerLocs_[8]; + std::vector dynamicUniformLocs_; GLRProgram *program_ = nullptr; private: @@ -964,6 +966,10 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { return nullptr; } } + if (desc.uniformDesc) { + pipeline->dynamicUniforms = *desc.uniformDesc; + pipeline->dynamicUniformLocs_.resize(desc.uniformDesc->uniforms.size()); + } ILOG("Linking shaders."); if (pipeline->LinkShaders()) { // Build the rest of the virtual pipeline object. @@ -976,8 +982,6 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { pipeline->blend->AddRef(); pipeline->raster->AddRef(); pipeline->inputLayout->AddRef(); - if (desc.uniformDesc) - pipeline->dynamicUniforms = *desc.uniformDesc; return pipeline; } else { ELOG("Failed to create pipeline - shaders failed to link"); @@ -1050,7 +1054,14 @@ bool OpenGLPipeline::LinkShaders() { semantics.push_back({ SEM_POSITION, "a_position" }); semantics.push_back({ SEM_TEXCOORD0, "a_texcoord0" }); std::vector queries; + queries.push_back({ &samplerLocs_[0], "sampler0" }); + queries.push_back({ &samplerLocs_[1], "sampler1" }); + for (size_t i = 0; i < dynamicUniforms.uniforms.size(); ++i) { + queries.push_back({ &dynamicUniformLocs_[i], dynamicUniforms.uniforms[i].name }); + } std::vector initialize; + initialize.push_back({ &samplerLocs_[0], 0, 0 }); + initialize.push_back({ &samplerLocs_[1], 0, 1 }); program_ = render_->CreateProgram(linkShaders, semantics, queries, initialize, false); return true; } @@ -1070,17 +1081,19 @@ void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { Crash(); } - for (auto &uniform : curPipeline_->dynamicUniforms.uniforms) { + for (size_t i = 0; i < curPipeline_->dynamicUniforms.uniforms.size(); ++i) { + const auto &uniform = curPipeline_->dynamicUniforms.uniforms[i]; + const GLint &loc = curPipeline_->dynamicUniformLocs_[i]; const float *data = (const float *)((uint8_t *)ub + uniform.offset); switch (uniform.type) { case UniformType::FLOAT1: case UniformType::FLOAT2: case UniformType::FLOAT3: case UniformType::FLOAT4: - renderManager_.SetUniformF(uniform.name, 1 + (int)uniform.type - (int)UniformType::FLOAT1, data); + renderManager_.SetUniformF(&loc, 1 + (int)uniform.type - (int)UniformType::FLOAT1, data); break; case UniformType::MATRIX4X4: - renderManager_.SetUniformM4x4(uniform.name, data); + renderManager_.SetUniformM4x4(&loc, data); break; } } From 21ac3ca7a4edcca76bf6dd6e29b085c008f5e4ad Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 May 2020 10:44:21 -0700 Subject: [PATCH 126/848] Draw: Fix textures and samplers at an offset. --- ext/native/thin3d/thin3d_d3d9.cpp | 2 +- ext/native/thin3d/thin3d_gl.cpp | 6 +++--- ext/native/thin3d/thin3d_vulkan.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index a787bbeef5..d8556210ea 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -540,7 +540,7 @@ public: void BindTextures(int start, int count, Texture **textures) override; void BindSamplerStates(int start, int count, SamplerState **states) override { for (int i = 0; i < count; ++i) { - D3D9SamplerState *s = static_cast(states[start + i]); + D3D9SamplerState *s = static_cast(states[i]); s->Apply(device_, start + i); } } diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index f35f5daece..b168cb02a5 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -389,7 +389,7 @@ public: } for (int i = 0; i < count; i++) { int index = i + start; - boundSamplers_[index] = static_cast(states[index]); + boundSamplers_[index] = static_cast(states[i]); } } @@ -993,9 +993,9 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { void OpenGLContext::BindTextures(int start, int count, Texture **textures) { maxTextures_ = std::max(maxTextures_, start + count); for (int i = start; i < start + count; i++) { - OpenGLTexture *glTex = static_cast(textures[i]); + OpenGLTexture *glTex = static_cast(textures[i - start]); if (!glTex) { - boundTextures_[i] = 0; + boundTextures_[i] = nullptr; renderManager_.BindTexture(i, nullptr); continue; } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index e7f569d7ea..b6ca1ca230 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -676,7 +676,7 @@ RasterState *VKContext::CreateRasterState(const RasterStateDesc &desc) { void VKContext::BindSamplerStates(int start, int count, SamplerState **state) { for (int i = start; i < start + count; i++) { - boundSamplers_[i] = (VKSamplerState *)state[i]; + boundSamplers_[i] = (VKSamplerState *)state[i - start]; } } @@ -1223,7 +1223,7 @@ void VKContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, void VKContext::BindTextures(int start, int count, Texture **textures) { for (int i = start; i < start + count; i++) { - boundTextures_[i] = static_cast(textures[i]); + boundTextures_[i] = static_cast(textures[i - start]); boundImageView_[i] = boundTextures_[i] ? boundTextures_[i]->GetImageView() : GetNullTexture()->GetImageView(); } } From cdb7e2fc1e6b6f4d4c180d9c9e90ae67e1be3c81 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 May 2020 10:47:39 -0700 Subject: [PATCH 127/848] GPU: Add sampler1 for postshader orig source. --- GPU/Common/PresentationCommon.cpp | 14 +++++++++----- GPU/Common/PresentationCommon.h | 2 +- GPU/Common/ShaderTranslation.cpp | 9 ++++++++- GPU/GLES/DepalettizeShaderGLES.cpp | 7 ++++--- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index fc0a5c89e0..3771d74344 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -520,11 +520,11 @@ void PresentationCommon::SourceFramebuffer(Draw::Framebuffer *fb, int bufferWidt srcHeight_ = bufferHeight; } -void PresentationCommon::BindSource() { +void PresentationCommon::BindSource(int binding) { if (srcTexture_) { - draw_->BindTexture(0, srcTexture_); + draw_->BindTexture(binding, srcTexture_); } else if (srcFramebuffer_) { - draw_->BindFramebufferAsTexture(srcFramebuffer_, 0, Draw::FB_COLOR_BIT, 0); + draw_->BindFramebufferAsTexture(srcFramebuffer_, binding, Draw::FB_COLOR_BIT, 0); } else { assert(false); } @@ -648,8 +648,9 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u if (usePostShaderOutput) { draw_->BindFramebufferAsTexture(postShaderFramebuffers_[i - 1], 0, Draw::FB_COLOR_BIT, 0); } else { - BindSource(); + BindSource(0); } + BindSource(1); int nextWidth, nextHeight; draw_->GetFramebufferDimensions(postShaderFramebuffer, &nextWidth, &nextHeight); @@ -665,6 +666,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u Draw::SamplerState *sampler = useNearest || shaderInfo->isUpscalingFilter ? samplerNearest_ : samplerLinear_; draw_->BindSamplerStates(0, 1, &sampler); + draw_->BindSamplerStates(1, 1, &sampler); draw_->BindVertexBuffers(0, 1, &vdata_, &postVertsOffset); draw_->BindIndexBuffer(idata_, 0); @@ -695,8 +697,9 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u if (usePostShaderOutput) { draw_->BindFramebufferAsTexture(postShaderFramebuffers_.back(), 0, Draw::FB_COLOR_BIT, 0); } else { - BindSource(); + BindSource(0); } + BindSource(1); if (isFinalAtOutputResolution) { PostShaderUniforms uniforms; @@ -713,6 +716,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u Draw::SamplerState *sampler = useNearest ? samplerNearest_ : samplerLinear_; draw_->BindSamplerStates(0, 1, &sampler); + draw_->BindSamplerStates(1, 1, &sampler); auto setViewport = [&](float x, float y, float w, float h) { Draw::Viewport viewport{ x, y, w, h, 0.0f, 1.0f }; diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index 96f6832f8d..5741c6d79d 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -124,7 +124,7 @@ protected: bool BuildPostShader(const ShaderInfo *shaderInfo, const ShaderInfo *next); bool AllocateFramebuffer(int w, int h); - void BindSource(); + void BindSource(int binding); void GetCardboardSettings(CardboardSettings *cardboardSettings); void CalculatePostShaderUniforms(int bufferWidth, int bufferHeight, int targetWidth, int targetHeight, const ShaderInfo *shaderInfo, PostShaderUniforms *uniforms); diff --git a/GPU/Common/ShaderTranslation.cpp b/GPU/Common/ShaderTranslation.cpp index 192e59f186..2361ba9e11 100644 --- a/GPU/Common/ShaderTranslation.cpp +++ b/GPU/Common/ShaderTranslation.cpp @@ -140,6 +140,10 @@ std::string Postprocess(std::string code, ShaderLanguage lang, Draw::ShaderStage out << "sampler2D sampler0 : register(s0);\n"; continue; } + if (line == "uniform sampler2D sampler1;" && lang == HLSL_DX9) { + out << "sampler2D sampler1 : register(s1);\n"; + continue; + } if (line.find("uniform float") != std::string::npos) { continue; } @@ -181,7 +185,10 @@ bool ConvertToVulkanGLSL(std::string *dest, TranslatedShaderMetadata *destMetada if (line.find("uniform bool") != std::string::npos) { continue; } else if (line.find("uniform sampler2D") == 0) { - line = "layout(set = 0, binding = 1) " + line; + if (line.find("sampler0") != line.npos) + line = "layout(set = 0, binding = 1) " + line; + else + line = "layout(set = 0, binding = 2) " + line; } else if (line.find("uniform ") != std::string::npos) { continue; } else if (2 == sscanf(line.c_str(), "varying vec%d v_texcoord%d;", &vecSize, &num)) { diff --git a/GPU/GLES/DepalettizeShaderGLES.cpp b/GPU/GLES/DepalettizeShaderGLES.cpp index 5abe33d77c..348411e082 100644 --- a/GPU/GLES/DepalettizeShaderGLES.cpp +++ b/GPU/GLES/DepalettizeShaderGLES.cpp @@ -21,7 +21,8 @@ #include "Common/Log.h" #include "Common/StringUtils.h" #include "Core/Reporting.h" -#include "DepalettizeShaderGLES.h" +#include "GPU/GLES/DepalettizeShaderGLES.h" +#include "GPU/GLES/DrawEngineGLES.h" #include "GPU/GLES/TextureCacheGLES.h" #include "GPU/Common/DepalettizeShaderCommon.h" @@ -178,8 +179,8 @@ DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(uint32_t clutMode, GEBuf queries.push_back({ &depal->u_pal, "pal" }); std::vector initializer; - initializer.push_back({ &depal->u_tex, 0, 0 }); - initializer.push_back({ &depal->u_pal, 0, 3 }); + initializer.push_back({ &depal->u_tex, 0, TEX_SLOT_PSP_TEXTURE }); + initializer.push_back({ &depal->u_pal, 0, TEX_SLOT_CLUT }); std::vector shaders{ vertexShader_, fragShader }; From 201d2782b46c56e5ba9c779803340ef0e727d212 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 17 May 2020 10:50:11 -0700 Subject: [PATCH 128/848] Draw: Allow 2 textures bound in Vulkan. Not working properly though... --- ext/native/thin3d/thin3d_vulkan.cpp | 77 +++++++++++++++++------------ 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index b6ca1ca230..4eef100ddf 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -39,6 +39,7 @@ // We use a simple descriptor set for all rendering: 1 sampler, 1 texture, 1 UBO binding point. // binding 0 - uniform data // binding 1 - sampler +// binding 2 - sampler // // Vertex data lives in a separate namespace (location = 0, 1, etc) @@ -292,14 +293,20 @@ class VKTexture; class VKBuffer; class VKSamplerState; +enum { + MAX_BOUND_TEXTURES = 2 +}; + struct DescriptorSetKey { - VkImageView imageView_; - VKSamplerState *sampler_; + VkImageView imageViews_[MAX_BOUND_TEXTURES]; + VKSamplerState *samplers_[MAX_BOUND_TEXTURES]; VkBuffer buffer_; bool operator < (const DescriptorSetKey &other) const { - if (imageView_ < other.imageView_) return true; else if (imageView_ > other.imageView_) return false; - if (sampler_ < other.sampler_) return true; else if (sampler_ > other.sampler_) return false; + for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) { + if (imageViews_[i] < other.imageViews_[i]) return true; else if (imageViews_[i] > other.imageViews_[i]) return false; + if (samplers_[i] < other.samplers_[i]) return true; else if (samplers_[i] > other.samplers_[i]) return false; + } if (buffer_ < other.buffer_) return true; else if (buffer_ > other.buffer_) return false; return false; } @@ -512,7 +519,6 @@ private: int queueFamilyIndex_; enum { - MAX_BOUND_TEXTURES = 2, MAX_FRAME_COMMAND_BUFFERS = 256, }; VKTexture *boundTextures_[MAX_BOUND_TEXTURES]{}; @@ -802,7 +808,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) VkDescriptorPoolSize dpTypes[2]; dpTypes[0].descriptorCount = 200; dpTypes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; - dpTypes[1].descriptorCount = 200; + dpTypes[1].descriptorCount = 200 * MAX_BOUND_TEXTURES; dpTypes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; VkDescriptorPoolCreateInfo dp{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; @@ -823,21 +829,24 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) } // binding 0 - uniform data - // binding 1 - combined sampler/image - VkDescriptorSetLayoutBinding bindings[2]; + // binding 1 - combined sampler/image 0 + // binding 2 - combined sampler/image 1 + VkDescriptorSetLayoutBinding bindings[MAX_BOUND_TEXTURES + 1]; bindings[0].descriptorCount = 1; bindings[0].pImmutableSamplers = nullptr; bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; bindings[0].binding = 0; - bindings[1].descriptorCount = 1; - bindings[1].pImmutableSamplers = nullptr; - bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - bindings[1].binding = 1; + for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) { + bindings[i + 1].descriptorCount = 1; + bindings[i + 1].pImmutableSamplers = nullptr; + bindings[i + 1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + bindings[i + 1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + bindings[i + 1].binding = i + 1; + } VkDescriptorSetLayoutCreateInfo dsl = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; - dsl.bindingCount = 2; + dsl.bindingCount = ARRAY_SIZE(bindings); dsl.pBindings = bindings; VkResult res = vkCreateDescriptorSetLayout(device_, &dsl, nullptr, &descriptorSetLayout_); assert(VK_SUCCESS == res); @@ -915,8 +924,10 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) { FrameData *frame = &frame_[vulkan_->GetCurFrame()]; - key.imageView_ = boundTextures_[0] ? boundTextures_[0]->GetImageView() : boundImageView_[0]; - key.sampler_ = boundSamplers_[0]; + for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) { + key.imageViews_[i] = boundTextures_[i] ? boundTextures_[i]->GetImageView() : boundImageView_[i]; + key.samplers_[i] = boundSamplers_[i]; + } key.buffer_ = buf; auto iter = frame->descSets_.find(key); @@ -939,7 +950,7 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) { VkDescriptorImageInfo imageDesc; - VkWriteDescriptorSet writes[2] = {}; + VkWriteDescriptorSet writes[1 + MAX_BOUND_TEXTURES] = {}; // If handles are NULL for whatever buggy reason, it's best to leave the descriptors // unwritten instead of trying to write a zero, which is not legal. @@ -958,24 +969,26 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) { numWrites++; } - if (key.imageView_ && boundSamplers_[0] && boundSamplers_[0]->GetSampler()) { - imageDesc.imageView = key.imageView_ ? key.imageView_ : VK_NULL_HANDLE; - imageDesc.sampler = boundSamplers_[0] ? boundSamplers_[0]->GetSampler() : VK_NULL_HANDLE; + for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) { + if (key.imageViews_[i] && key.samplers_[i] && key.samplers_[i]->GetSampler()) { + imageDesc.imageView = key.imageViews_[i]; + imageDesc.sampler = key.samplers_[i]->GetSampler(); #ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR - imageDesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + imageDesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; #else - imageDesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imageDesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; #endif - writes[numWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writes[numWrites].dstSet = descSet; - writes[numWrites].dstArrayElement = 0; - writes[numWrites].dstBinding = 1; - writes[numWrites].pBufferInfo = nullptr; - writes[numWrites].pImageInfo = &imageDesc; - writes[numWrites].pTexelBufferView = nullptr; - writes[numWrites].descriptorCount = 1; - writes[numWrites].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - numWrites++; + writes[numWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes[numWrites].dstSet = descSet; + writes[numWrites].dstArrayElement = 0; + writes[numWrites].dstBinding = i + 1; + writes[numWrites].pBufferInfo = nullptr; + writes[numWrites].pImageInfo = &imageDesc; + writes[numWrites].pTexelBufferView = nullptr; + writes[numWrites].descriptorCount = 1; + writes[numWrites].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + numWrites++; + } } vkUpdateDescriptorSets(device_, numWrites, writes, 0, nullptr); From 804b673d8e947e051dd1c9643ee4e57f435c6d63 Mon Sep 17 00:00:00 2001 From: iota97 Date: Fri, 12 Jun 2020 12:40:53 -0700 Subject: [PATCH 129/848] Vulkan: Correct secondary texture binding in Draw. --- ext/native/thin3d/thin3d_vulkan.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 4eef100ddf..7bab539197 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -948,9 +948,8 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) { bufferDesc.offset = 0; bufferDesc.range = curPipeline_->GetUBOSize(); - VkDescriptorImageInfo imageDesc; - - VkWriteDescriptorSet writes[1 + MAX_BOUND_TEXTURES] = {}; + VkDescriptorImageInfo imageDesc[MAX_BOUND_TEXTURES]{}; + VkWriteDescriptorSet writes[1 + MAX_BOUND_TEXTURES]{}; // If handles are NULL for whatever buggy reason, it's best to leave the descriptors // unwritten instead of trying to write a zero, which is not legal. @@ -971,19 +970,19 @@ VkDescriptorSet VKContext::GetOrCreateDescriptorSet(VkBuffer buf) { for (int i = 0; i < MAX_BOUND_TEXTURES; ++i) { if (key.imageViews_[i] && key.samplers_[i] && key.samplers_[i]->GetSampler()) { - imageDesc.imageView = key.imageViews_[i]; - imageDesc.sampler = key.samplers_[i]->GetSampler(); + imageDesc[i].imageView = key.imageViews_[i]; + imageDesc[i].sampler = key.samplers_[i]->GetSampler(); #ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR - imageDesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + imageDesc[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL; #else - imageDesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imageDesc[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; #endif writes[numWrites].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes[numWrites].dstSet = descSet; writes[numWrites].dstArrayElement = 0; writes[numWrites].dstBinding = i + 1; writes[numWrites].pBufferInfo = nullptr; - writes[numWrites].pImageInfo = &imageDesc; + writes[numWrites].pImageInfo = &imageDesc[i]; writes[numWrites].pTexelBufferView = nullptr; writes[numWrites].descriptorCount = 1; writes[numWrites].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; From 6913d3942f9532568671d03e0d8c1598b655ced6 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 13 Jun 2020 06:50:12 +0800 Subject: [PATCH 130/848] Add sysclib_strstr jpcsp ref: https://github.com/jpcsp/jpcsp/commit/b4158f2ec7fc6db3efb0c0efcaa70df99b3f6b1a --- Core/HLE/sceKernelInterrupt.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 72d0c98da6..b558797fb0 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -752,6 +752,17 @@ static u32 sysclib_memset(u32 destAddr, int data, int size) { return 0; } +static int sysclib_strstr(u32 s1, u32 s2 ) { + ERROR_LOG(SCEKERNEL, "Untested sysclib_strstr(%08x, %08x)", s1, s2); + std::string str1 = Memory::GetCharPointer(s1); + std::string str2 = Memory::GetCharPointer(s2); + int index = str1.find(str2); + if (index < 0) { + return 0; + } + return s1 + index; +} + const HLEFunction SysclibForKernel[] = { {0xAB7592FF, &WrapU_UUU, "memcpy", 'x', "xxx", HLE_KERNEL_SYSCALL }, @@ -762,6 +773,7 @@ const HLEFunction SysclibForKernel[] = {0x81D0D1F7, &WrapI_UUU, "memcmp", 'i', "xxx", HLE_KERNEL_SYSCALL }, {0x7661E728, &WrapI_UU, "sprintf", 'i', "xx", HLE_KERNEL_SYSCALL }, {0x10F3BB61, &WrapU_UII, "memset", 'x', "xii", HLE_KERNEL_SYSCALL }, + {0x0D188658, &WrapI_CC, "strstr", 'i', "xx", HLE_KERNEL_SYSCALL }, }; void Register_Kernel_Library() From d0d2834fc93adf85fd631a81daee00ac8dc239f4 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 13 Jun 2020 06:58:02 +0800 Subject: [PATCH 131/848] oop --- Core/HLE/sceKernelInterrupt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index b558797fb0..08158e9afb 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -752,7 +752,7 @@ static u32 sysclib_memset(u32 destAddr, int data, int size) { return 0; } -static int sysclib_strstr(u32 s1, u32 s2 ) { +static int sysclib_strstr(u32 s1, u32 s2) { ERROR_LOG(SCEKERNEL, "Untested sysclib_strstr(%08x, %08x)", s1, s2); std::string str1 = Memory::GetCharPointer(s1); std::string str2 = Memory::GetCharPointer(s2); @@ -773,7 +773,7 @@ const HLEFunction SysclibForKernel[] = {0x81D0D1F7, &WrapI_UUU, "memcmp", 'i', "xxx", HLE_KERNEL_SYSCALL }, {0x7661E728, &WrapI_UU, "sprintf", 'i', "xx", HLE_KERNEL_SYSCALL }, {0x10F3BB61, &WrapU_UII, "memset", 'x', "xii", HLE_KERNEL_SYSCALL }, - {0x0D188658, &WrapI_CC, "strstr", 'i', "xx", HLE_KERNEL_SYSCALL }, + {0x0D188658, &WrapI_UU, "strstr", 'i', "xx", HLE_KERNEL_SYSCALL }, }; void Register_Kernel_Library() From 10112fa6a2d4589e1ccd44625ed6bf80b2a997ac Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 13 Jun 2020 20:46:35 +0800 Subject: [PATCH 132/848] Change to @unknownbrackets logic Avoid warnings --- Core/HLE/sceKernelInterrupt.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 08158e9afb..18c8cfb35c 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -756,11 +756,11 @@ static int sysclib_strstr(u32 s1, u32 s2) { ERROR_LOG(SCEKERNEL, "Untested sysclib_strstr(%08x, %08x)", s1, s2); std::string str1 = Memory::GetCharPointer(s1); std::string str2 = Memory::GetCharPointer(s2); - int index = str1.find(str2); - if (index < 0) { + size_t index = str1.find(str2); + if (index == str1.npos) { return 0; } - return s1 + index; + return s1 + (uint32_t)index; } const HLEFunction SysclibForKernel[] = From 06b682140608787a837908f51d8d56050c6c41a6 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 13 Jun 2020 21:17:56 +0800 Subject: [PATCH 133/848] Add some ThreadManForKernel nids Used in "Code Geass: Lost Colors" chinese patched game --- Core/HLE/sceKernel.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index e07cc2b2be..ae804a4520 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -873,6 +873,9 @@ const HLEFunction ThreadManForKernel[] = {0X9FA03CD3, &WrapI_I, "sceKernelDeleteThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0XAA73C935, &WrapV_I, "sceKernelExitThread", 'v', "i", HLE_KERNEL_SYSCALL }, {0X809CE29B, &WrapV_I, "sceKernelExitDeleteThread", 'v', "i", HLE_KERNEL_SYSCALL }, + {0X9944F31F, &WrapI_I, "sceKernelSuspendThread", 'i', "i", HLE_KERNEL_SYSCALL }, + {0X75156E8F, &WrapI_I, "sceKernelResumeThread", 'i', "i", HLE_KERNEL_SYSCALL }, + {0X94416130, &WrapU_UUUU, "sceKernelGetThreadmanIdList", 'x', "xxxx", HLE_KERNEL_SYSCALL }, }; void Register_ThreadManForUser() From 5ef442f682970fbdf0c82aabcb4e1588a7748055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 13 Jun 2020 19:00:55 +0200 Subject: [PATCH 134/848] Add Kurok (homebrew with a distinctive GameID to compat.ini ForceMax60FPS. Fixes #13025 --- assets/compat.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 54af84b6fb..03ec98bbb0 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -670,6 +670,9 @@ ULES01037 = true # 7 Wonders of the Ancient World ULES00364 = true ULUS10132 = true +# Homebrew Kurok (we don't normally add homebrew here but it has a distinctive GameID) +KURO00767 = 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 From d19ee07ebfb41f6e5a78ee32b72d52ce153ed5bb Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 14 Jun 2020 09:42:24 +0800 Subject: [PATCH 135/848] Some work in sceKernelPartitionTotalFreeMemSize,sceKernelPartitionMaxFreeMemSize jpcsp ref: https://github.com/jpcsp/jpcsp/commit/6d28d8799ce03e926ad8c764fd5deb8de165dc3b We ignore ePartition now --- Core/HLE/sceKernelHeap.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index 1fc08f1a57..a7385d537c 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -83,13 +83,29 @@ static int sceKernelDeleteHeap(int heapId) { } } +static u32 sceKernelPartitionTotalFreeMemSize(int partitionId) { + ERROR_LOG(SCEKERNEL, "UNIMP sceKernelPartitionTotalFreeMemSize(%d)", partitionId); + //Need more work #13021 + ///We ignore partitionId for now + return userMemory.GetTotalFreeBytes(); +} + +static u32 sceKernelPartitionMaxFreeMemSize(int partitionId) { + ERROR_LOG(SCEKERNEL, "UNIMP sceKernelPartitionMaxFreeMemSize(%d)", partitionId); + //Need more work #13021 + ///We ignore partitionId for now + return userMemory.GetLargestFreeBlockSize(); +} + const HLEFunction SysMemForKernel[] = { - { 0X636C953B, &WrapI_II, "sceKernelAllocHeapMemory", 'x', "ii" }, - { 0XC9805775, &WrapI_I, "sceKernelDeleteHeap", 'i', "i" }, - { 0X1C1FBFE7, &WrapI_IIIC, "sceKernelCreateHeap", 'i', "iixs" }, - { 0X237DBD4F, &WrapI_ICIUU, "sceKernelAllocPartitionMemory", 'i', "isixx",HLE_KERNEL_SYSCALL }, - { 0XB6D61D02, &WrapI_I, "sceKernelFreePartitionMemory", 'i', "i",HLE_KERNEL_SYSCALL }, - { 0X9D9A5BA1, &WrapU_I, "sceKernelGetBlockHeadAddr", 'x', "i",HLE_KERNEL_SYSCALL }, + { 0X636C953B, &WrapI_II, "sceKernelAllocHeapMemory", 'x', "ii", HLE_KERNEL_SYSCALL }, + { 0XC9805775, &WrapI_I, "sceKernelDeleteHeap", 'i', "i" , HLE_KERNEL_SYSCALL }, + { 0X1C1FBFE7, &WrapI_IIIC, "sceKernelCreateHeap", 'i', "iixs", HLE_KERNEL_SYSCALL }, + { 0X237DBD4F, &WrapI_ICIUU, "sceKernelAllocPartitionMemory", 'i', "isixx", HLE_KERNEL_SYSCALL }, + { 0XB6D61D02, &WrapI_I, "sceKernelFreePartitionMemory", 'i', "i", HLE_KERNEL_SYSCALL }, + { 0X9D9A5BA1, &WrapU_I, "sceKernelGetBlockHeadAddr", 'x', "i", HLE_KERNEL_SYSCALL }, + { 0x9697CD32, &WrapU_I, "sceKernelPartitionTotalFreeMemSize", 'x', "i",HLE_KERNEL_SYSCALL }, + { 0xE6581468, &WrapU_I, "sceKernelPartitionMaxFreeMemSize", 'x', "i",HLE_KERNEL_SYSCALL }, }; void Register_SysMemForKernel() { From adf8d5e831bd21098856957e1c786603ee743ba7 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 14 Jun 2020 09:43:08 +0800 Subject: [PATCH 136/848] Real support Code Geass: Lost Colors chinese patched version --- Core/PSPLoaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index eb910487f2..d29f1b3b89 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -212,7 +212,7 @@ static const char *altBootNames[] = { "disc0:/PSP_GAME/SYSDIR/EBOOT.LEI", "disc0:/PSP_GAME/SYSDIR/EBOOT.DNR", "disc0:/PSP_GAME/SYSDIR/DBZ2.BIN", - "disc0:/PSP_GAME/SYSDIR/ss.RAW", + //"disc0:/PSP_GAME/SYSDIR/ss.RAW",//Code Geass: Lost Colors chinese version }; bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) { From 77d05dafbb5fc584bde66be3406bb997d5c72b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 14 Jun 2020 15:01:47 +0200 Subject: [PATCH 137/848] Update README.md for 1.10.0. --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index aa36a2b225..73a42bef51 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,26 @@ 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.10.0 +-------------------- +* Graphics and compatibility fixes (#12800, #12670, ...) +* Assorted minor performance improvements (#12462, ...) +* Screen inset (notch) support on Android +* Analog stick support for menu navigation (#12685) +* Fixed audio glitches in SDL builds (#12920, ...) +* Fix missing CJK characters in in-game dialogs +* Fix some Vulkan-only glitches (#12941, ...) +* Workaround for Mali driver bugs regarding stencil +* Fix some crashes (#12908, #12876? ...) +* Postprocessing shader improvements (can now have parameters) +* Fix some state bugs in GLES +* Mac build now supports Vulkan on top of MoltenVK (#12583) +* VSync fixes, support for frame duplication for 30Hz games +* HLE timing fixes, helping some games (#12635) +* Camera supported on Windows (still no microphone though) (#12572) +* Darkstalkers fixed and working (#12443, ...) +* Hot Shots Golf slowdown and flicker fixed (#12873, #12746) + What's new in 1.9.0/1.9.3 ------------------------- * Sizing/touch fixes on Android From 6b93e73a8e5d7e816d25e7fc0a0c7db7aceb1838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 14 Jun 2020 17:14:00 +0200 Subject: [PATCH 138/848] Update lang submodule. (also sneak in a couple of log lines) --- Common/Vulkan/VulkanContext.cpp | 2 ++ assets/lang | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 12a457e481..b64def5502 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -133,6 +133,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { } instance_extensions_enabled_.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); extensionsLookup_.EXT_debug_utils = true; + ILOG("Vulkan debug_utils validation enabled."); } else if (IsInstanceExtensionAvailable(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { for (size_t i = 0; i < ARRAY_SIZE(validationLayers); i++) { instance_layer_names_.push_back(validationLayers[i]); @@ -140,6 +141,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { } instance_extensions_enabled_.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); extensionsLookup_.EXT_debug_report = true; + ILOG("Vulkan debug_report validation enabled."); } else { ELOG("Validation layer extension not available - not enabling Vulkan validation."); flags_ &= ~VULKAN_FLAG_VALIDATE; diff --git a/assets/lang b/assets/lang index 3a5eb3fcb4..d8c45f0652 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 3a5eb3fcb4852cb28c9138e78492effa0c227253 +Subproject commit d8c45f0652905aa27b94bc3f373b49a77766d24a From 1349b83d54ee981082a03bdcde110640194837f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 14 Jun 2020 19:58:54 +0200 Subject: [PATCH 139/848] Android: Fix odd screen centering with insets. --- GPU/Common/PresentationCommon.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 8e04dafe43..b88cc1affe 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -49,10 +49,11 @@ FRect GetInsetScreenFrame(float pixelWidth, float pixelHeight) { pixelHeight, }; - float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT); - float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT); - float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP); - float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM); + // Remove the DPI scale to get back to pixels. + float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT) / g_dpi_scale_x; + float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT) / g_dpi_scale_x; + float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP) / g_dpi_scale_y; + float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM) / g_dpi_scale_y; // Adjust left edge to compensate for cutouts (notches) if any. rc.x += left; @@ -73,8 +74,8 @@ void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &f outH = frame.h; } else { if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::MANUAL) { - float offsetX = (g_Config.fSmallDisplayOffsetX - 0.5f) * 2.0f * frame.w; - float offsetY = (g_Config.fSmallDisplayOffsetY - 0.5f) * 2.0f * frame.h; + float offsetX = (g_Config.fSmallDisplayOffsetX - 0.5f) * 2.0f * frame.w + frame.x; + float offsetY = (g_Config.fSmallDisplayOffsetY - 0.5f) * 2.0f * frame.h + frame.y; // Have to invert Y for GL if (GetGPUBackend() == GPUBackend::OPENGL) { offsetY = offsetY * -1.0f; @@ -100,8 +101,8 @@ void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &f float pixelCrop = frame.h / 270.0f; float resCommonWidescreen = pixelCrop - floor(pixelCrop); if (!rotated && resCommonWidescreen == 0.0f && frame.w >= pixelCrop * 480.0f) { - rc->x = floorf((frame.w - pixelCrop * 480.0f) * 0.5f); - rc->y = floorf(-pixelCrop); + rc->x = floorf((frame.w - pixelCrop * 480.0f) * 0.5f + frame.x); + rc->y = floorf(-pixelCrop + frame.y); rc->w = floorf(pixelCrop * 480.0f); rc->h = floorf(pixelCrop * 272.0f); return; From ca7de39abeae5307c1fdcd0fa49ef402617bd069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 14 Jun 2020 22:57:09 +0200 Subject: [PATCH 140/848] iota97's suggested README.md items. --- README.md | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 73a42bef51..e9e0c1a709 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -PPSSPP - a fast and portable PSP emulator +PPSSPP - a fast and portable PSP emulator ========================================= Created by Henrik RydgÃ¥rd @@ -25,23 +25,35 @@ For game compatibility, see [community compatibility feedback](https://report.pp What's new in 1.10.0 -------------------- -* Graphics and compatibility fixes (#12800, #12670, ...) -* Assorted minor performance improvements (#12462, ...) -* Screen inset (notch) support on Android +* Graphics and compatibility fixes (#12800, #12670, #12635, more) +* Assorted minor performance improvements (#12462) +* Screen inset (notch) support on Android (#12779) * Analog stick support for menu navigation (#12685) -* Fixed audio glitches in SDL builds (#12920, ...) -* Fix missing CJK characters in in-game dialogs -* Fix some Vulkan-only glitches (#12941, ...) -* Workaround for Mali driver bugs regarding stencil -* Fix some crashes (#12908, #12876? ...) -* Postprocessing shader improvements (can now have parameters) -* Fix some state bugs in GLES +* Fixed audio glitches in SDL builds (#12920) +* Fix missing CJK characters in in-game dialogs (#12702) +* Fix some Vulkan-only glitches (#12941) +* Simple multiplayer chat (#12667) +* More advanced postprocessing (multipass, parameters) (#12905, #12901) +* Add PPSSPP-specific CWCheat (#12816, #12912) +* Reintroduce Cardboard VR (#12449) +* Fix some crashes (#12908, #12876) * Mac build now supports Vulkan on top of MoltenVK (#12583) * VSync fixes, support for frame duplication for 30Hz games -* HLE timing fixes, helping some games (#12635) -* Camera supported on Windows (still no microphone though) (#12572) -* Darkstalkers fixed and working (#12443, ...) +* Camera supported on Windows, Linux and Mac (still no microphone though) (#12572, #12580, #12607) +* Darkstalkers fixed and working through software rendering (#12443) * Hot Shots Golf slowdown and flicker fixed (#12873, #12746) +* Allow rebinding of right touch screen analog (#12486) +* Add option to prevent mipmaps from being dumped (#12818) +* Tilt control now have a base radius to help with deadzone (#12756) +* Mappable auto rotating analog stick to pass some game checks (#12749) +* Touch control position can now be snapped to a grid (#12517) +* HiDPI retina display support (#12552) +* Rapid-fire on touch control (#12601) +* Toggle mute button (#12643) +* Add option to resize game icons and more (#12646, #12637) +* Frames in-flight now configurable to reduce input lag at the cost of speed (#12660) +* Add toggle mode to combo button (#12623) +* SDL mouse support (#12612) What's new in 1.9.0/1.9.3 ------------------------- From d9ec36eadb449fceb6cbc2ce31c6e9d5e9b6b579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 14 Jun 2020 23:02:09 +0200 Subject: [PATCH 141/848] Incorporate unknownbrackets' suggestions for the README.md update. --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e9e0c1a709..fc6c6a17ee 100644 --- a/README.md +++ b/README.md @@ -29,19 +29,21 @@ What's new in 1.10.0 * Assorted minor performance improvements (#12462) * Screen inset (notch) support on Android (#12779) * Analog stick support for menu navigation (#12685) -* Fixed audio glitches in SDL builds (#12920) -* Fix missing CJK characters in in-game dialogs (#12702) +* Fixed audio glitches in SDL builds (#12916, #12920) +* Support more languages in in-game dialogs (#12702) * Fix some Vulkan-only glitches (#12941) * Simple multiplayer chat (#12667) * More advanced postprocessing (multipass, parameters) (#12905, #12901) * Add PPSSPP-specific CWCheat (#12816, #12912) * Reintroduce Cardboard VR (#12449) * Fix some crashes (#12908, #12876) +* Ghost in the Shell graphics fixed (JIT inaccuracy with inf*0) (#12519) * Mac build now supports Vulkan on top of MoltenVK (#12583) -* VSync fixes, support for frame duplication for 30Hz games +* VSync now supported on all backends, frame duplication option added for 30 Hz games * Camera supported on Windows, Linux and Mac (still no microphone though) (#12572, #12580, #12607) * Darkstalkers fixed and working through software rendering (#12443) -* Hot Shots Golf slowdown and flicker fixed (#12873, #12746) +* Hot Shots Golf slowdown and flicker on Vulkan fixed (#12873, #12746) +* Pangya Golf crashes and hangs fixed (#12718) * Allow rebinding of right touch screen analog (#12486) * Add option to prevent mipmaps from being dumped (#12818) * Tilt control now have a base radius to help with deadzone (#12756) @@ -53,7 +55,7 @@ What's new in 1.10.0 * Add option to resize game icons and more (#12646, #12637) * Frames in-flight now configurable to reduce input lag at the cost of speed (#12660) * Add toggle mode to combo button (#12623) -* SDL mouse support (#12612) +* SDL mouse support, Qt menu upgrades (#12612, #12817) What's new in 1.9.0/1.9.3 ------------------------- From 76bba24d8877b2064eb882f26b2b5ac5b2af3343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 14 Jun 2020 23:05:24 +0200 Subject: [PATCH 142/848] Don't forget rpi4 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fc6c6a17ee..f9e524d0d2 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ What's new in 1.10.0 * Fix some crashes (#12908, #12876) * Ghost in the Shell graphics fixed (JIT inaccuracy with inf*0) (#12519) * Mac build now supports Vulkan on top of MoltenVK (#12583) +* Raspberry Pi 4 EGL crash fixed (#12474) * VSync now supported on all backends, frame duplication option added for 30 Hz games * Camera supported on Windows, Linux and Mac (still no microphone though) (#12572, #12580, #12607) * Darkstalkers fixed and working through software rendering (#12443) From 2685bfc882a171d61dd73c723fa90839d8bfd79c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 15 Jun 2020 09:42:28 +0200 Subject: [PATCH 143/848] More README.md updates --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f9e524d0d2..21b6547125 100644 --- a/README.md +++ b/README.md @@ -25,24 +25,23 @@ For game compatibility, see [community compatibility feedback](https://report.pp What's new in 1.10.0 -------------------- -* Graphics and compatibility fixes (#12800, #12670, #12635, more) -* Assorted minor performance improvements (#12462) +* Graphics and compatibility fixes (#12800, #12670, #12635, #12857, #12941, more) +* Assorted minor performance improvements, game load speedup (#12462, #12652) * Screen inset (notch) support on Android (#12779) * Analog stick support for menu navigation (#12685) * Fixed audio glitches in SDL builds (#12916, #12920) * Support more languages in in-game dialogs (#12702) -* Fix some Vulkan-only glitches (#12941) * Simple multiplayer chat (#12667) * More advanced postprocessing (multipass, parameters) (#12905, #12901) * Add PPSSPP-specific CWCheat (#12816, #12912) -* Reintroduce Cardboard VR (#12449) +* Reintroduce Cardboard VR, allow more resolutions (#12449, #8714) * Fix some crashes (#12908, #12876) * Ghost in the Shell graphics fixed (JIT inaccuracy with inf*0) (#12519) * Mac build now supports Vulkan on top of MoltenVK (#12583) * Raspberry Pi 4 EGL crash fixed (#12474) * VSync now supported on all backends, frame duplication option added for 30 Hz games * Camera supported on Windows, Linux and Mac (still no microphone though) (#12572, #12580, #12607) -* Darkstalkers fixed and working through software rendering (#12443) +* Darkstalkers fixed and working through software rendering. SW rendering fixed on GLES 2.0 (#12443, #12898) * Hot Shots Golf slowdown and flicker on Vulkan fixed (#12873, #12746) * Pangya Golf crashes and hangs fixed (#12718) * Allow rebinding of right touch screen analog (#12486) From 78382133bdbc605535c90ef9c8e8c7ccba7116ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 15 Jun 2020 13:34:02 +0200 Subject: [PATCH 144/848] More README updates --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 21b6547125..818b7373ab 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,12 @@ For game compatibility, see [community compatibility feedback](https://report.pp What's new in 1.10.0 -------------------- -* Graphics and compatibility fixes (#12800, #12670, #12635, #12857, #12941, more) +* Graphics and compatibility fixes (#12800, #12670, #12635, #12857, #12941, #11898, #12695, more) * Assorted minor performance improvements, game load speedup (#12462, #12652) * Screen inset (notch) support on Android (#12779) * Analog stick support for menu navigation (#12685) * Fixed audio glitches in SDL builds (#12916, #12920) -* Support more languages in in-game dialogs (#12702) +* Support more languages in in-game dialogs (#12702). Croatian language added to PPSSPP. * Simple multiplayer chat (#12667) * More advanced postprocessing (multipass, parameters) (#12905, #12901) * Add PPSSPP-specific CWCheat (#12816, #12912) From 414b0e00e5db33628305b46e9ebea3da91b3df17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 15 Jun 2020 16:11:47 +0200 Subject: [PATCH 145/848] ColorConv: Fix typo introduced in #12882, fixing #13014 --- Common/ColorConv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/ColorConv.cpp b/Common/ColorConv.cpp index 449643b37c..0146967e99 100644 --- a/Common/ColorConv.cpp +++ b/Common/ColorConv.cpp @@ -485,7 +485,7 @@ void ConvertRGBA5551ToBGRA8888(u32 *dst, const u16 *src, u32 numPixels) { for (u32 x = 0; x < numPixels; x++) { u16 c = src[x]; u32 r = Convert5To8(c & 0x001f); - u32 g = Convert6To8((c >> 5) & 0x001f); + u32 g = Convert5To8((c >> 5) & 0x001f); u32 b = Convert5To8((c >> 10) & 0x001f); // We force an arithmetic shift to get the sign bits/ u32 a = ((s32)(s16)c) & 0xff000000; From b0221a9064170bba17d2ec210c1b20ab4cdb88fc Mon Sep 17 00:00:00 2001 From: vnctdj <3978690+vnctdj@users.noreply.github.com> Date: Sat, 20 Jun 2020 23:13:08 +0200 Subject: [PATCH 146/848] Reuse some already translated strings + fix a typo --- UI/TouchControlVisibilityScreen.cpp | 15 ++++++++------- assets/shaders/defaultshaders.ini | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/UI/TouchControlVisibilityScreen.cpp b/UI/TouchControlVisibilityScreen.cpp index 9923b7bf9e..1e3b1fd63d 100644 --- a/UI/TouchControlVisibilityScreen.cpp +++ b/UI/TouchControlVisibilityScreen.cpp @@ -104,7 +104,7 @@ void TouchControlVisibilityScreen::CreateViews() { row->Add(checkbox); if (toggle.key == rightAnalogKey) { - Choice *rightAnalog = new Choice(co->T(rightAnalogKey), "", false, new LinearLayoutParams(1.0f)); + Choice *rightAnalog = new Choice(mc->T(rightAnalogKey), "", false, new LinearLayoutParams(1.0f)); rightAnalog->SetCentered(true); row->Add(rightAnalog)->OnClick.Handle(this, &TouchControlVisibilityScreen::RightAnalogBindScreen); } else { @@ -130,6 +130,7 @@ void RightAnalogMappingScreen::CreateViews() { auto di = GetI18NCategory("Dialog"); auto co = GetI18NCategory("Controls"); + auto mc = GetI18NCategory("MappableControls"); root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth - 10, WRAP_CONTENT, 10, NONE, NONE, 10)); @@ -141,14 +142,14 @@ void RightAnalogMappingScreen::CreateViews() { LinearLayout *vert = rightPanel->Add(new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT))); vert->SetSpacing(0); - static const char *rightAnalogButton[] = {"None", "Left trigger", "Right trigger", "Square", "Triangle", "Circle", "Cross", "D-PAD Up", "D-PAD Down", "D-PAD Left", "D-PAD Right", "Start", "Select"}; + static const char *rightAnalogButton[] = {"None", "L", "R", "Square", "Triangle", "Circle", "Cross", "D-pad up", "D-pad down", "D-pad left", "D-pad right", "Start", "Select"}; vert->Add(new CheckBox(&g_Config.bRightAnalogCustom, co->T("Use custom right analog"))); - PopupMultiChoice *rightAnalogUp = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogUp, co->T("Right analog up"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager())); - PopupMultiChoice *rightAnalogDown = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogDown, co->T("Right analog down"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager())); - PopupMultiChoice *rightAnalogLeft = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogLeft, co->T("Right analog left"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager())); - PopupMultiChoice *rightAnalogRight = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogRight, co->T("Right analog right"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager())); - PopupMultiChoice *rightAnalogPress = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogPress, co->T("Keep this button pressed when right analog is pressed"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), co->GetName(), screenManager())); + PopupMultiChoice *rightAnalogUp = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogUp, mc->T("RightAn.Up"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager())); + PopupMultiChoice *rightAnalogDown = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogDown, mc->T("RightAn.Down"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager())); + PopupMultiChoice *rightAnalogLeft = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogLeft, mc->T("RightAn.Left"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager())); + PopupMultiChoice *rightAnalogRight = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogRight, mc->T("RightAn.Right"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager())); + PopupMultiChoice *rightAnalogPress = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogPress, co->T("Keep this button pressed when right analog is pressed"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager())); vert->Add(new CheckBox(&g_Config.touchRightAnalogStick.show, co->T("Show right analog"))); rightAnalogUp->SetEnabledPtr(&g_Config.bRightAnalogCustom); rightAnalogDown->SetEnabledPtr(&g_Config.bRightAnalogCustom); diff --git a/assets/shaders/defaultshaders.ini b/assets/shaders/defaultshaders.ini index 2fe8c9499b..d364ad93af 100644 --- a/assets/shaders/defaultshaders.ini +++ b/assets/shaders/defaultshaders.ini @@ -134,7 +134,7 @@ SettingDefaultValue2=1.0 SettingMaxValue2=2.0 SettingMinValue2=0.0 SettingStep2=0.1 -SettingName3=Constrast +SettingName3=Contrast SettingDefaultValue3=1.0 SettingMaxValue3=3.0 SettingMinValue3=0.1 From 1f37ce65bb6f359ec077163c505fb9cef60ca5b9 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 21 Jun 2020 10:24:10 +0800 Subject: [PATCH 147/848] Add sysclib_strncmp,sysclib_memmove Add a memory check in sysclib_strstr ref: https://github.com/jpcsp/jpcsp/blob/master/src/jpcsp/HLE/modules/SysclibForKernel.java#L107 --- Core/HLE/FunctionWrappers.h | 5 +++++ Core/HLE/sceKernelInterrupt.cpp | 35 +++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index 01124ea157..4b9e6c2853 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -201,6 +201,11 @@ template void WrapI_UU() { RETURN(retval); } +template void WrapI_UUU() { + int retval = func(PARAM(0), PARAM(1), PARAM(2)); + RETURN(retval); +} + template void WrapI_UFF() { // Not sure about the float arguments. int retval = func(PARAM(0), PARAMF(0), PARAMF(1)); diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 18c8cfb35c..661010aa38 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -754,13 +754,34 @@ static u32 sysclib_memset(u32 destAddr, int data, int size) { static int sysclib_strstr(u32 s1, u32 s2) { ERROR_LOG(SCEKERNEL, "Untested sysclib_strstr(%08x, %08x)", s1, s2); - std::string str1 = Memory::GetCharPointer(s1); - std::string str2 = Memory::GetCharPointer(s2); - size_t index = str1.find(str2); - if (index == str1.npos) { - return 0; + if (Memory::IsValidAddress(s1) && Memory::IsValidAddress(s2)) { + std::string str1 = Memory::GetCharPointer(s1); + std::string str2 = Memory::GetCharPointer(s2); + size_t index = str1.find(str2); + if (index == str1.npos) { + return 0; + } + return s1 + (uint32_t)index; } - return s1 + (uint32_t)index; + return 0; +} + +static int sysclib_strncmp(u32 s1, u32 s2, u32 size) { + ERROR_LOG(SCEKERNEL, "Untested sysclib_strncmp(%08x, %08x, x)", s1, s2, size); + if (Memory::IsValidAddress(s1) && Memory::IsValidAddress(s2)) { + const char * str1 = Memory::GetCharPointer(s1); + const char * str2 = Memory::GetCharPointer(s2); + return strncmp(str1, str2, size); + } + return 0; +} + +static int sysclib_memmove(u32 dst, u32 src, u32 size) { + ERROR_LOG(SCEKERNEL, "Untested sysclib_memmove(%08x, %08x, x)", dst, src, size); + if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { + memmove(Memory::GetPointer(dst), Memory::GetPointer(src), size); + } + return 0; } const HLEFunction SysclibForKernel[] = @@ -774,6 +795,8 @@ const HLEFunction SysclibForKernel[] = {0x7661E728, &WrapI_UU, "sprintf", 'i', "xx", HLE_KERNEL_SYSCALL }, {0x10F3BB61, &WrapU_UII, "memset", 'x', "xii", HLE_KERNEL_SYSCALL }, {0x0D188658, &WrapI_UU, "strstr", 'i', "xx", HLE_KERNEL_SYSCALL }, + {0x7AB35214, &WrapI_UUU, "strncmp", 'i', "xxx", HLE_KERNEL_SYSCALL }, + {0xA48D2592, &WrapI_UUU, "memmove", 'i', "xxx", HLE_KERNEL_SYSCALL }, }; void Register_Kernel_Library() From 2fcb55a7729462c7f1967d17a7ff5b7e5db7dd84 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 21 Jun 2020 11:01:21 +0800 Subject: [PATCH 148/848] Add a sceOpenPSID_driver nid Used in "Shin Sangoku Musou 6 special" chinese patched game --- Core/HLE/HLETables.cpp | 1 + Core/HLE/sceOpenPSID.cpp | 25 +++++++++++++++++++++++++ Core/HLE/sceOpenPSID.h | 1 + 3 files changed, 27 insertions(+) diff --git a/Core/HLE/HLETables.cpp b/Core/HLE/HLETables.cpp index b4f0636f77..a83fc9970e 100644 --- a/Core/HLE/HLETables.cpp +++ b/Core/HLE/HLETables.cpp @@ -252,6 +252,7 @@ void RegisterAllModules() { Register_scePsmf(); Register_scePsmfPlayer(); Register_sceOpenPSID(); + Register_sceOpenPSID_driver(); Register_sceParseUri(); Register_sceSsl(); Register_sceParseHttp(); diff --git a/Core/HLE/sceOpenPSID.cpp b/Core/HLE/sceOpenPSID.cpp index 19577dae22..44e4af77ef 100644 --- a/Core/HLE/sceOpenPSID.cpp +++ b/Core/HLE/sceOpenPSID.cpp @@ -35,6 +35,21 @@ static int sceOpenPSIDGetOpenPSID(u32 OpenPSIDPtr) return 0; } +static int sceOpenPSID_driver_0x19D579F0(u32 OpenPSIDPtr,u32 unknown) +{ + ERROR_LOG(HLE, "UNTESTED sceOpenPSID_driver_0x19D579F0(%d,%d)", OpenPSIDPtr,unknown); + u8 dummyOpenPSID[16] = { 0x10, 0x02, 0xA3, 0x44, 0x13, 0xF5, 0x93, 0xB0, 0xCC, 0x6E, 0xD1, 0x32, 0x27, 0x85, 0x0F, 0x9D }; + + if (Memory::IsValidAddress(OpenPSIDPtr)) + { + for (int i = 0; i < 16; i++) + { + Memory::Write_U8(dummyOpenPSID[i], OpenPSIDPtr + i); + } + } + return 0; +} + const HLEFunction sceOpenPSID[] = { {0XC69BEBCE, &WrapI_U, "sceOpenPSIDGetOpenPSID", 'i', "x"}, @@ -44,3 +59,13 @@ void Register_sceOpenPSID() { RegisterModule("sceOpenPSID", ARRAY_SIZE(sceOpenPSID), sceOpenPSID); } + +const HLEFunction sceOpenPSID_driver[] = +{ + {0x19D579F0, &WrapI_UU, "sceOpenPSID_driver_0x19D579F0", 'i', "xx" }, +}; + +void Register_sceOpenPSID_driver() +{ + RegisterModule("sceOpenPSID_driver", ARRAY_SIZE(sceOpenPSID_driver), sceOpenPSID_driver); +} \ No newline at end of file diff --git a/Core/HLE/sceOpenPSID.h b/Core/HLE/sceOpenPSID.h index 07c5171e59..24855ef4a4 100644 --- a/Core/HLE/sceOpenPSID.h +++ b/Core/HLE/sceOpenPSID.h @@ -20,3 +20,4 @@ void __sceOpenPSIDInit(); void Register_sceOpenPSID(); +void Register_sceOpenPSID_driver(); \ No newline at end of file From a6b1f9d1f8905017f3c3881288a531df58f3da4f Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 21 Jun 2020 11:03:04 +0800 Subject: [PATCH 149/848] oop --- Core/HLE/HLETables.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/HLE/HLETables.cpp b/Core/HLE/HLETables.cpp index a83fc9970e..843e4195aa 100644 --- a/Core/HLE/HLETables.cpp +++ b/Core/HLE/HLETables.cpp @@ -252,7 +252,6 @@ void RegisterAllModules() { Register_scePsmf(); Register_scePsmfPlayer(); Register_sceOpenPSID(); - Register_sceOpenPSID_driver(); Register_sceParseUri(); Register_sceSsl(); Register_sceParseHttp(); @@ -303,7 +302,7 @@ void RegisterAllModules() { Register_KUBridge(); Register_sceUsbAcc(); Register_sceUsbMic(); - + Register_sceOpenPSID_driver(); // add new modules here. } From de947a6f611f4a95678ac65940ebc639aebf7eeb Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 21 Jun 2020 11:21:11 +0800 Subject: [PATCH 150/848] Fix by @unknownbrackets --- Core/HLE/sceKernelInterrupt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 661010aa38..2b3da424ef 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -776,7 +776,7 @@ static int sysclib_strncmp(u32 s1, u32 s2, u32 size) { return 0; } -static int sysclib_memmove(u32 dst, u32 src, u32 size) { +static u32 sysclib_memmove(u32 dst, u32 src, u32 size) { ERROR_LOG(SCEKERNEL, "Untested sysclib_memmove(%08x, %08x, x)", dst, src, size); if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { memmove(Memory::GetPointer(dst), Memory::GetPointer(src), size); @@ -796,7 +796,7 @@ const HLEFunction SysclibForKernel[] = {0x10F3BB61, &WrapU_UII, "memset", 'x', "xii", HLE_KERNEL_SYSCALL }, {0x0D188658, &WrapI_UU, "strstr", 'i', "xx", HLE_KERNEL_SYSCALL }, {0x7AB35214, &WrapI_UUU, "strncmp", 'i', "xxx", HLE_KERNEL_SYSCALL }, - {0xA48D2592, &WrapI_UUU, "memmove", 'i', "xxx", HLE_KERNEL_SYSCALL }, + {0xA48D2592, &WrapU_UUU, "memmove", 'x', "xxx", HLE_KERNEL_SYSCALL }, }; void Register_Kernel_Library() From fe68a21ea78d53bcef4337c2638c8c9c53975941 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 21 Jun 2020 11:23:14 +0800 Subject: [PATCH 151/848] oop --- Core/HLE/FunctionWrappers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index 4b9e6c2853..0233dd7bdd 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -201,7 +201,7 @@ template void WrapI_UU() { RETURN(retval); } -template void WrapI_UUU() { +template void WrapU_UUU() { int retval = func(PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } From d691627a35474420a9e50a9a4afdc32e9de1cec9 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 21 Jun 2020 11:36:02 +0800 Subject: [PATCH 152/848] oop --- Core/HLE/FunctionWrappers.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index 0233dd7bdd..01124ea157 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -201,11 +201,6 @@ template void WrapI_UU() { RETURN(retval); } -template void WrapU_UUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); - RETURN(retval); -} - template void WrapI_UFF() { // Not sure about the float arguments. int retval = func(PARAM(0), PARAMF(0), PARAMF(1)); From cbf967844271a9e0c22854903e7bb761025bae13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 21 Jun 2020 23:03:42 +0200 Subject: [PATCH 153/848] Update lang and pspautotests submodules --- assets/lang | 2 +- pspautotests | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/lang b/assets/lang index d8c45f0652..b3fd7fccf9 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit d8c45f0652905aa27b94bc3f373b49a77766d24a +Subproject commit b3fd7fccf9a2182270d998667c64390c8c50bc91 diff --git a/pspautotests b/pspautotests index 2970fbcc23..328b839c72 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit 2970fbcc23c258ebc03bba922926003fe37555e5 +Subproject commit 328b839c7243e7f733f9eae88d059485e3d808e7 From 1793b65ec1829a2cf8b0f49fc930027c71c78a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 21 Jun 2020 22:49:44 +0200 Subject: [PATCH 154/848] Vulkan: Remove support for the old VK_EXT_debug_report extension --- CMakeLists.txt | 2 - Common/Vulkan/VulkanContext.cpp | 85 ++-------------------------- Common/Vulkan/VulkanContext.h | 9 +-- Common/Vulkan/VulkanDebug.cpp | 60 ++++---------------- Common/Vulkan/VulkanDebug.h | 1 - Common/Vulkan/VulkanLoader.cpp | 9 --- Common/Vulkan/VulkanLoader.h | 7 --- Windows/GPU/WindowsVulkanContext.cpp | 19 ++----- android/jni/AndroidVulkanContext.cpp | 35 +----------- android/jni/AndroidVulkanContext.h | 2 - 10 files changed, 24 insertions(+), 205 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a40d4334ec..9c352f1f0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -398,8 +398,6 @@ source_group(Windows FILES ${CommonWindows}) set(CommonVulkan ${CommonExtra} Common/Vulkan/VulkanContext.cpp Common/Vulkan/VulkanContext.h - Common/Vulkan/VulkanDebug.cpp - Common/Vulkan/VulkanDebug.h Common/Vulkan/VulkanImage.cpp Common/Vulkan/VulkanImage.h Common/Vulkan/VulkanLoader.cpp diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index b64def5502..0017df5ba6 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -7,7 +7,8 @@ #include "base/basictypes.h" #include "base/display.h" -#include "VulkanContext.h" +#include "Common/Vulkan/VulkanContext.h" +#include "Common/Vulkan/VulkanDebug.h" #include "GPU/Common/ShaderCommon.h" #include "Common/StringUtils.h" #include "Core/Config.h" @@ -134,14 +135,6 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { instance_extensions_enabled_.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); extensionsLookup_.EXT_debug_utils = true; ILOG("Vulkan debug_utils validation enabled."); - } else if (IsInstanceExtensionAvailable(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { - for (size_t i = 0; i < ARRAY_SIZE(validationLayers); i++) { - instance_layer_names_.push_back(validationLayers[i]); - device_layer_names_.push_back(validationLayers[i]); - } - instance_extensions_enabled_.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); - extensionsLookup_.EXT_debug_report = true; - ILOG("Vulkan debug_report validation enabled."); } else { ELOG("Validation layer extension not available - not enabling Vulkan validation."); flags_ &= ~VULKAN_FLAG_VALIDATE; @@ -668,47 +661,12 @@ VkResult VulkanContext::CreateDevice() { return res; } -VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFunc, int bits, void *userdata) { - VkDebugReportCallbackEXT msg_callback; - - if (!(flags_ & VULKAN_FLAG_VALIDATE)) { - WLOG("Not registering debug report callback - extension not enabled!"); - return VK_SUCCESS; - } - ILOG("Registering debug report callback"); - - VkDebugReportCallbackCreateInfoEXT cb{VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT}; - cb.flags = bits; - cb.pfnCallback = dbgFunc; - cb.pUserData = userdata; - VkResult res = vkCreateDebugReportCallbackEXT(instance_, &cb, nullptr, &msg_callback); - switch (res) { - case VK_SUCCESS: - msg_callbacks.push_back(msg_callback); - break; - case VK_ERROR_OUT_OF_HOST_MEMORY: - return VK_ERROR_INITIALIZATION_FAILED; - default: - return VK_ERROR_INITIALIZATION_FAILED; - } - return res; -} - -void VulkanContext::DestroyDebugMsgCallback() { - if (!extensionsLookup_.EXT_debug_report) - return; - while (msg_callbacks.size() > 0) { - vkDestroyDebugReportCallbackEXT(instance_, msg_callbacks.back(), nullptr); - msg_callbacks.pop_back(); - } -} - -VkResult VulkanContext::InitDebugUtilsCallback(PFN_vkDebugUtilsMessengerCallbackEXT callback, int bits, void *userdata) { +VkResult VulkanContext::InitDebugUtilsCallback(int bits, VulkanLogOptions *logOptions) { VkDebugUtilsMessengerCreateInfoEXT callback1{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; callback1.messageSeverity = bits; callback1.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - callback1.pfnUserCallback = callback; - callback1.pUserData = userdata; + callback1.pfnUserCallback = &VulkanDebugUtilsCallback; + callback1.pUserData = (void *)logOptions; VkDebugUtilsMessengerEXT messenger; VkResult res = vkCreateDebugUtilsMessengerEXT(instance_, &callback1, nullptr, &messenger); if (res != VK_SUCCESS) { @@ -1445,36 +1403,3 @@ std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props) { uint32_t branch = VK_VERSION_PATCH(props.driverVersion); return StringFromFormat("%d.%d.%d (%08x)", major, minor, branch, props.driverVersion); } - -const char *VulkanObjTypeToString(VkDebugReportObjectTypeEXT type) { - switch (type) { - case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore"; - case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapChainKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "CommandPool"; - default: return ""; - } -} diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index db3caa454e..3bcae0e56c 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -7,6 +7,7 @@ #include "base/logging.h" #include "Common/Vulkan/VulkanLoader.h" +#include "Common/Vulkan/VulkanDebug.h" enum { VULKAN_FLAG_VALIDATE = 1, @@ -169,13 +170,9 @@ public: bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); - VkResult InitDebugUtilsCallback(PFN_vkDebugUtilsMessengerCallbackEXT callback, int bits, void *userdata); + VkResult InitDebugUtilsCallback(int bits, VulkanLogOptions *logOptions); void DestroyDebugUtilsCallback(); - // Legacy reporting - VkResult InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFunc, int bits, void *userdata); - void DestroyDebugMsgCallback(); - VkPhysicalDevice GetPhysicalDevice(int n) const { return physical_devices_[n]; } @@ -342,7 +339,6 @@ private: // the next time the frame comes around again. VulkanDeleteList globalDeleteList_; - std::vector msg_callbacks; std::vector utils_callbacks; VkSwapchainKHR swapchain_ = VK_NULL_HANDLE; @@ -370,7 +366,6 @@ bool GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std const char *VulkanResultToString(VkResult res); std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props); -const char *VulkanObjTypeToString(VkDebugReportObjectTypeEXT type); // Simple heuristic. bool IsHashMaliDriverVersion(const VkPhysicalDeviceProperties &props); diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index 26526eca96..9397338ced 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -19,57 +19,9 @@ #include #include +#include "base/logging.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanDebug.h" -#include "base/logging.h" - -VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { - const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; - std::ostringstream message; - - if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - message << "ERROR: "; - } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { - message << "WARNING: "; - } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { - message << "PERFORMANCE WARNING: "; - } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { - message << "INFO: "; - } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { - message << "DEBUG: "; - } - message << "[" << pLayerPrefix << "] " << VulkanObjTypeToString(objType) << " Code " << msgCode << " : " << pMsg << "\n"; - - if (msgCode == 64) // Another useless perf warning that will be seen less and less as we optimize - vkCmdClearAttachments() issued on command buffer object 0x00000195296C6D40 prior to any Draw Cmds. It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw. - return false; - if (msgCode == 5) - return false; // Not exactly a false positive, see https://github.com/KhronosGroup/glslang/issues/1418 -#ifdef _WIN32 - std::string msg = message.str(); - OutputDebugStringA(msg.c_str()); - if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - if (options->breakOnError && IsDebuggerPresent()) { - DebugBreak(); - } - if (options->msgBoxOnError) { - MessageBoxA(NULL, message.str().c_str(), "Alert", MB_OK); - } - } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { - if (options->breakOnWarning && IsDebuggerPresent()) { - DebugBreak(); - } - } -#else - ILOG("%s", message.str().c_str()); -#endif - - // false indicates that layer should not bail-out of an - // API call that had validation failures. This may mean that the - // app dies inside the driver due to invalid parameter(s). - // That's what would happen without validation layers, so we'll - // keep that behavior here. - return false; -} VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, @@ -108,8 +60,9 @@ VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( } message << ":" << pCallbackData->messageIdNumber << ") " << pMessage << "\n"; -#ifdef _WIN32 std::string msg = message.str(); + +#ifdef _WIN32 OutputDebugStringA(msg.c_str()); if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { if (options->breakOnError && IsDebuggerPresent()) { @@ -124,6 +77,13 @@ VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( DebugBreak(); } } +#else + // TODO: Improve. + if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { + ELOG("VKDEBUG: %s", msg.c_str()); + } else { + WLOG("VKDEBUG: %s", msg.c_str()); + } #endif // false indicates that layer should not bail-out of an diff --git a/Common/Vulkan/VulkanDebug.h b/Common/Vulkan/VulkanDebug.h index 10cb70d8ed..30159d3a23 100644 --- a/Common/Vulkan/VulkanDebug.h +++ b/Common/Vulkan/VulkanDebug.h @@ -25,5 +25,4 @@ struct VulkanLogOptions { bool msgBoxOnError; }; -VkBool32 VKAPI_CALL VulkanDebugReportCallback(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData); VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData); diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index c748696c2c..43298ec9c4 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -199,10 +199,6 @@ PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR; PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; PFN_vkQueuePresentKHR vkQueuePresentKHR; -// And the DEBUG_REPORT extension. We dynamically load this. -PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT; -PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT; - PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT; PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT; PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT; @@ -542,11 +538,6 @@ void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensio LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceFeatures2KHR); } - if (enabledExtensions.EXT_debug_report) { - LOAD_INSTANCE_FUNC(instance, vkCreateDebugReportCallbackEXT); - LOAD_INSTANCE_FUNC(instance, vkDestroyDebugReportCallbackEXT); - } - if (enabledExtensions.EXT_debug_utils) { LOAD_INSTANCE_FUNC(instance, vkCreateDebugUtilsMessengerEXT); LOAD_INSTANCE_FUNC(instance, vkDestroyDebugUtilsMessengerEXT); diff --git a/Common/Vulkan/VulkanLoader.h b/Common/Vulkan/VulkanLoader.h index 99b560cfa6..e9c7f96156 100644 --- a/Common/Vulkan/VulkanLoader.h +++ b/Common/Vulkan/VulkanLoader.h @@ -199,11 +199,6 @@ extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR; extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; extern PFN_vkQueuePresentKHR vkQueuePresentKHR; -// And the DEBUG_REPORT extension. Since we load this dynamically even in static -// linked mode, we have to rename it :( -extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT; -extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT; - extern PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT; extern PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT; extern PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT; @@ -219,10 +214,8 @@ extern PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesE extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; - // For fast extension-enabled checks. struct VulkanDeviceExtensions { - bool EXT_debug_report; bool EXT_debug_utils; bool KHR_maintenance1; // required for KHR_create_renderpass2 bool KHR_maintenance2; diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index c747026e38..d9737f4858 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -55,7 +55,6 @@ #include "Core/System.h" #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanDebug.h" #include "base/stringutil.h" #include "thin3d/thin3d.h" @@ -131,17 +130,12 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m return false; } if (g_validate_) { - 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_ERROR_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; - g_Vulkan->InitDebugMsgCallback(&VulkanDebugReportCallback, bits, &g_LogOptions); - } + int bits = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_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(bits, &g_LogOptions); } g_Vulkan->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd); if (!g_Vulkan->InitObjects()) { @@ -178,7 +172,6 @@ void WindowsVulkanContext::Shutdown() { g_Vulkan->DestroyObjects(); g_Vulkan->DestroyDevice(); g_Vulkan->DestroyDebugUtilsCallback(); - g_Vulkan->DestroyDebugMsgCallback(); g_Vulkan->DestroyInstance(); delete g_Vulkan; diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 046fc29e36..3dbe65adb3 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -15,34 +15,7 @@ static VulkanLogOptions g_LogOptions; -static VKAPI_ATTR VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { - const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; - int loglevel = ANDROID_LOG_INFO; - if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - loglevel = ANDROID_LOG_ERROR; - } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { - loglevel = ANDROID_LOG_WARN; - } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { - loglevel = ANDROID_LOG_WARN; - } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { - loglevel = ANDROID_LOG_WARN; - } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { - loglevel = ANDROID_LOG_WARN; - } - - __android_log_print(loglevel, APP_NAME, "[%s] %s Code %d : %s", - pLayerPrefix, VulkanObjTypeToString(objType), msgCode, pMsg); - - // false indicates that layer should not bail-out of an - // API call that had validation failures. This may mean that the - // app dies inside the driver due to invalid parameter(s). - // That's what would happen without validation layers, so we'll - // keep that behavior here. - return false; -} - -AndroidVulkanContext::AndroidVulkanContext() { -} +AndroidVulkanContext::AndroidVulkanContext() {} AndroidVulkanContext::~AndroidVulkanContext() { delete g_Vulkan; @@ -128,11 +101,6 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB return false; } - if (g_validate_) { - int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; - g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions); - } - bool success = true; if (g_Vulkan->InitObjects()) { draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, g_Config.bGfxDebugSplitSubmit); @@ -153,7 +121,6 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB g_Vulkan->DestroyObjects(); g_Vulkan->DestroyDevice(); g_Vulkan->DestroyDebugUtilsCallback(); - g_Vulkan->DestroyDebugMsgCallback(); g_Vulkan->DestroyInstance(); } diff --git a/android/jni/AndroidVulkanContext.h b/android/jni/AndroidVulkanContext.h index 82a041d1b5..2e5cfb7328 100644 --- a/android/jni/AndroidVulkanContext.h +++ b/android/jni/AndroidVulkanContext.h @@ -2,8 +2,6 @@ #include "AndroidGraphicsContext.h" -static const bool g_validate_ = true; - class VulkanContext; class AndroidVulkanContext : public AndroidGraphicsContext { From 6532c345c8638c55cbf510a5d35f1d6b35436ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 21 Jun 2020 22:56:01 +0200 Subject: [PATCH 155/848] Simplify the validation interface code, bugfixes --- Common/Vulkan/VulkanContext.cpp | 23 +++++++++++++++-------- Common/Vulkan/VulkanContext.h | 4 +++- SDL/SDLVulkanGraphicsContext.cpp | 1 - Windows/GPU/WindowsVulkanContext.cpp | 9 +-------- android/jni/AndroidVulkanContext.cpp | 2 -- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 0017df5ba6..abc16b9e09 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -36,6 +36,8 @@ #define new DBG_NEW #endif +VulkanLogOptions g_LogOptions; + static const char *validationLayers[] = { "VK_LAYER_KHRONOS_validation", /* @@ -661,12 +663,18 @@ VkResult VulkanContext::CreateDevice() { return res; } -VkResult VulkanContext::InitDebugUtilsCallback(int bits, VulkanLogOptions *logOptions) { +VkResult VulkanContext::InitDebugUtilsCallback() { + // We're intentionally skipping VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT and + // VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, just too spammy. + int bits = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + VkDebugUtilsMessengerCreateInfoEXT callback1{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; callback1.messageSeverity = bits; callback1.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; callback1.pfnUserCallback = &VulkanDebugUtilsCallback; - callback1.pUserData = (void *)logOptions; + callback1.pUserData = (void *)&g_LogOptions; VkDebugUtilsMessengerEXT messenger; VkResult res = vkCreateDebugUtilsMessengerEXT(instance_, &callback1, nullptr, &messenger); if (res != VK_SUCCESS) { @@ -680,15 +688,14 @@ VkResult VulkanContext::InitDebugUtilsCallback(int bits, VulkanLogOptions *logOp } void VulkanContext::DestroyDebugUtilsCallback() { - if (!extensionsLookup_.EXT_debug_utils) - return; - while (utils_callbacks.size() > 0) { - vkDestroyDebugUtilsMessengerEXT(instance_, utils_callbacks.back(), nullptr); - utils_callbacks.pop_back(); + if (extensionsLookup_.EXT_debug_utils) { + while (utils_callbacks.size() > 0) { + vkDestroyDebugUtilsMessengerEXT(instance_, utils_callbacks.back(), nullptr); + utils_callbacks.pop_back(); + } } } - VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) { winsys_ = winsys; winsysData1_ = data1; diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 3bcae0e56c..7043438ecf 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -170,7 +170,7 @@ public: bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); - VkResult InitDebugUtilsCallback(int bits, VulkanLogOptions *logOptions); + VkResult InitDebugUtilsCallback(); void DestroyDebugUtilsCallback(); VkPhysicalDevice GetPhysicalDevice(int n) const { @@ -369,3 +369,5 @@ std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props); // Simple heuristic. bool IsHashMaliDriverVersion(const VkPhysicalDeviceProperties &props); + +extern VulkanLogOptions g_LogOptions; diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 02123b105d..60c05583e4 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -114,7 +114,6 @@ void SDLVulkanGraphicsContext::Shutdown() { vulkan_->WaitUntilQueueIdle(); vulkan_->DestroyObjects(); vulkan_->DestroyDevice(); - vulkan_->DestroyDebugMsgCallback(); vulkan_->DestroyInstance(); delete vulkan_; vulkan_ = nullptr; diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index d9737f4858..db03b6e802 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -71,8 +71,6 @@ static const bool g_validate_ = false; static VulkanContext *g_Vulkan; -static VulkanLogOptions g_LogOptions; - static uint32_t FlagsFromConfig() { uint32_t flags = 0; flags = g_Config.bVSync ? VULKAN_FLAG_PRESENT_FIFO : VULKAN_FLAG_PRESENT_MAILBOX; @@ -130,12 +128,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m return false; } if (g_validate_) { - int bits = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_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(bits, &g_LogOptions); + g_Vulkan->InitDebugUtilsCallback(); } g_Vulkan->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd); if (!g_Vulkan->InitObjects()) { diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 3dbe65adb3..9ad5aa2031 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -142,8 +142,6 @@ void AndroidVulkanContext::Shutdown() { ILOG("Calling NativeShutdownGraphics"); g_Vulkan->DestroyDevice(); g_Vulkan->DestroyDebugUtilsCallback(); - g_Vulkan->DestroyDebugMsgCallback(); - g_Vulkan->DestroyInstance(); // We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app. finalize_glslang(); From fbc4fa5bca8ee4715962bc2bc95546f494b9cd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 21 Jun 2020 22:59:55 +0200 Subject: [PATCH 156/848] Move the responsibility to register the debugutils callback to the VulkanContext. We only use one anyway. --- Common/Vulkan/VulkanContext.cpp | 21 ++++++++++++--------- Common/Vulkan/VulkanContext.h | 5 ++--- Windows/GPU/WindowsVulkanContext.cpp | 5 +---- android/jni/AndroidVulkanContext.cpp | 3 --- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index abc16b9e09..96c170423d 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -247,6 +247,11 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { vkGetPhysicalDeviceProperties(physical_devices_[i], &physicalDeviceProperties_[i].properties); } } + + if (extensionsLookup_.EXT_debug_utils) { + InitDebugUtilsCallback(); + } + return VK_SUCCESS; } @@ -255,6 +260,13 @@ VulkanContext::~VulkanContext() { } void VulkanContext::DestroyInstance() { + if (extensionsLookup_.EXT_debug_utils) { + while (utils_callbacks.size() > 0) { + vkDestroyDebugUtilsMessengerEXT(instance_, utils_callbacks.back(), nullptr); + utils_callbacks.pop_back(); + } + } + vkDestroyInstance(instance_, nullptr); VulkanFree(); instance_ = VK_NULL_HANDLE; @@ -687,15 +699,6 @@ VkResult VulkanContext::InitDebugUtilsCallback() { return res; } -void VulkanContext::DestroyDebugUtilsCallback() { - if (extensionsLookup_.EXT_debug_utils) { - while (utils_callbacks.size() > 0) { - vkDestroyDebugUtilsMessengerEXT(instance_, utils_callbacks.back(), nullptr); - utils_callbacks.pop_back(); - } - } -} - VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) { winsys_ = winsys; winsysData1_ = data1; diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 7043438ecf..3a8e519381 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -170,9 +170,6 @@ public: bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); - VkResult InitDebugUtilsCallback(); - void DestroyDebugUtilsCallback(); - VkPhysicalDevice GetPhysicalDevice(int n) const { return physical_devices_[n]; } @@ -276,6 +273,8 @@ public: void GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation); private: + VkResult InitDebugUtilsCallback(); + // A layer can expose extensions, keep track of those extensions here. struct LayerProperties { VkLayerProperties properties; diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index db03b6e802..abdc03e603 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -127,9 +127,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m g_Vulkan = nullptr; return false; } - if (g_validate_) { - g_Vulkan->InitDebugUtilsCallback(); - } + g_Vulkan->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd); if (!g_Vulkan->InitObjects()) { *error_message = g_Vulkan->InitError(); @@ -164,7 +162,6 @@ void WindowsVulkanContext::Shutdown() { g_Vulkan->WaitUntilQueueIdle(); g_Vulkan->DestroyObjects(); g_Vulkan->DestroyDevice(); - g_Vulkan->DestroyDebugUtilsCallback(); g_Vulkan->DestroyInstance(); delete g_Vulkan; diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 9ad5aa2031..adcf4738ae 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -120,8 +120,6 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB if (!success) { g_Vulkan->DestroyObjects(); g_Vulkan->DestroyDevice(); - g_Vulkan->DestroyDebugUtilsCallback(); - g_Vulkan->DestroyInstance(); } return success; @@ -141,7 +139,6 @@ void AndroidVulkanContext::ShutdownFromRenderThread() { void AndroidVulkanContext::Shutdown() { ILOG("Calling NativeShutdownGraphics"); g_Vulkan->DestroyDevice(); - g_Vulkan->DestroyDebugUtilsCallback(); g_Vulkan->DestroyInstance(); // We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app. finalize_glslang(); From 3d743a5ae7ab9539840046e6e36e1b8bdb66e720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 21 Jun 2020 23:13:05 +0200 Subject: [PATCH 157/848] Buildfixes --- CMakeLists.txt | 2 ++ Common/Vulkan/VulkanDebug.cpp | 2 +- Common/Vulkan/VulkanDebug.h | 2 +- SDL/SDLVulkanGraphicsContext.h | 1 - android/jni/AndroidVulkanContext.cpp | 2 -- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c352f1f0c..ee98014740 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -396,6 +396,8 @@ set(CommonWindows source_group(Windows FILES ${CommonWindows}) set(CommonVulkan ${CommonExtra} + Common/Vulkan/VulkanDebug.cpp + Common/Vulkan/VulkanDebug.h Common/Vulkan/VulkanContext.cpp Common/Vulkan/VulkanContext.h Common/Vulkan/VulkanImage.cpp diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index 9397338ced..3129e98938 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -23,7 +23,7 @@ #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanDebug.h" -VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( +VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, diff --git a/Common/Vulkan/VulkanDebug.h b/Common/Vulkan/VulkanDebug.h index 30159d3a23..e622f542c7 100644 --- a/Common/Vulkan/VulkanDebug.h +++ b/Common/Vulkan/VulkanDebug.h @@ -25,4 +25,4 @@ struct VulkanLogOptions { bool msgBoxOnError; }; -VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData); +VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData); diff --git a/SDL/SDLVulkanGraphicsContext.h b/SDL/SDLVulkanGraphicsContext.h index 6ecfecfe1e..533406560e 100644 --- a/SDL/SDLVulkanGraphicsContext.h +++ b/SDL/SDLVulkanGraphicsContext.h @@ -42,5 +42,4 @@ public: private: Draw::DrawContext *draw_ = nullptr; VulkanContext *vulkan_ = nullptr; - VulkanLogOptions g_LogOptions; }; diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index adcf4738ae..39fe573057 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -13,8 +13,6 @@ #include "Core/ConfigValues.h" #include "Core/System.h" -static VulkanLogOptions g_LogOptions; - AndroidVulkanContext::AndroidVulkanContext() {} AndroidVulkanContext::~AndroidVulkanContext() { From cd1d73436d0cde3a08a91d73d137cdee1d2d4b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 21 Jun 2020 22:34:37 +0200 Subject: [PATCH 158/848] Vulkan: Recreate the swapchain if we get too many "out of date" frames. Should help an issue on my Linux laptop with Intel GPU. --- Common/GraphicsContext.h | 4 ++++ UI/NativeApp.cpp | 2 ++ Windows/GPU/WindowsVulkanContext.cpp | 14 +++++++++++--- Windows/GPU/WindowsVulkanContext.h | 4 ++++ ext/native/thin3d/VulkanRenderManager.cpp | 5 +++++ ext/native/thin3d/VulkanRenderManager.h | 7 +++++++ 6 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Common/GraphicsContext.h b/Common/GraphicsContext.h index 5dfec7f6d9..d17d77d726 100644 --- a/Common/GraphicsContext.h +++ b/Common/GraphicsContext.h @@ -34,6 +34,10 @@ public: virtual void ThreadEnd() {} virtual void StopThread() {} + // Useful for checks that need to be performed every frame. + // Should strive to get rid of these. + virtual void Poll() {} + virtual Draw::DrawContext *GetDrawContext() = 0; }; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 9e3ea05102..e6fca738f3 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1095,6 +1095,8 @@ void NativeRender(GraphicsContext *graphicsContext) { NativeMessageReceived("gpu_resized", ""); } #endif + } else { + graphicsContext->Poll(); } ui_draw2d.PopDrawMatrix(); diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index abdc03e603..8f7249dbc5 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -143,9 +143,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m _assert_msg_(G3D, success, "Failed to compile preset shaders"); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - renderManager->SetInflightFrames(g_Config.iInflightFrames); - if (!renderManager->HasBackbuffers()) { + renderManager_ = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + renderManager_->SetInflightFrames(g_Config.iInflightFrames); + if (!renderManager_->HasBackbuffers()) { Shutdown(); return false; } @@ -166,6 +166,7 @@ void WindowsVulkanContext::Shutdown() { delete g_Vulkan; g_Vulkan = nullptr; + renderManager_ = nullptr; finalize_glslang(); } @@ -181,6 +182,13 @@ void WindowsVulkanContext::Resize() { draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); } +void WindowsVulkanContext::Poll() { + // Check for existing swapchain to avoid issues during shutdown. + if (g_Vulkan->GetSwapchain() && renderManager_->NeedsSwapchainRecreate()) { + Resize(); + } +} + void *WindowsVulkanContext::GetAPIContext() { return g_Vulkan; } diff --git a/Windows/GPU/WindowsVulkanContext.h b/Windows/GPU/WindowsVulkanContext.h index 0a00dfeab8..a006c52ed1 100644 --- a/Windows/GPU/WindowsVulkanContext.h +++ b/Windows/GPU/WindowsVulkanContext.h @@ -21,6 +21,8 @@ #include "Windows/GPU/WindowsGraphicsContext.h" #include "thin3d/thin3d.h" +class VulkanRenderManager; + class WindowsVulkanContext : public WindowsGraphicsContext { public: WindowsVulkanContext() : draw_(nullptr) {} @@ -29,11 +31,13 @@ public: void SwapInterval(int interval) override {} void SwapBuffers() override {} void Resize() override; + void Poll() override; void *GetAPIContext(); Draw::DrawContext *GetDrawContext() override { return draw_; } private: Draw::DrawContext *draw_; + VulkanRenderManager *renderManager_ = nullptr; }; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 9e047d00be..573f0ce6c5 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -209,6 +209,8 @@ void VulkanRenderManager::CreateBackbuffers() { newInflightFrames_ = -1; } + outOfDateFrames_ = 0; + // Start the thread. if (useThread_ && HasBackbuffers()) { run_ = true; @@ -1029,11 +1031,14 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) { 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"); + outOfDateFrames_++; } else if (res == VK_ERROR_OUT_OF_DATE_KHR) { WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - not presenting"); frameData.skipSwap = true; + outOfDateFrames_++; } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res)); + outOfDateFrames_ = 0; } VkCommandBufferBeginInfo begin{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 391d559f61..baf2990ab4 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -285,6 +285,11 @@ public: return frameData_[vulkan_->GetCurFrame()].profile.profileSummary; } + bool NeedsSwapchainRecreate() const { + // Accepting a few of these makes shutdown simpler. + return outOfDateFrames_ > VulkanContext::MAX_INFLIGHT_FRAMES; + } + private: bool InitBackbufferFramebuffers(int width, int height); bool InitDepthStencilBuffer(VkCommandBuffer cmd); // Used for non-buffered rendering. @@ -337,6 +342,8 @@ private: int newInflightFrames_ = -1; int inflightFramesAtStart_ = 0; + int outOfDateFrames_ = 0; + // Submission time state int curWidth_ = -1; int curHeight_ = -1; From 8b980475020b734e12136ab0669bcb86b191acfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 22 Jun 2020 00:54:51 +0200 Subject: [PATCH 159/848] Finish the Linux part of this change --- SDL/SDLVulkanGraphicsContext.cpp | 19 +++++++++++++++++++ SDL/SDLVulkanGraphicsContext.h | 13 ++++++------- UI/NativeApp.cpp | 1 + 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 60c05583e4..389030d594 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -4,6 +4,7 @@ #include "base/display.h" #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" +#include "thin3d/VulkanRenderManager.h" #include "util/text/parsers.h" #include "Core/System.h" @@ -103,6 +104,9 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, assert(success); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); + renderManager_ = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + renderManager_->SetInflightFrames(g_Config.iInflightFrames); + return true; } @@ -119,3 +123,18 @@ void SDLVulkanGraphicsContext::Shutdown() { vulkan_ = nullptr; finalize_glslang(); } + +void SDLVulkanGraphicsContext::Resize() { + draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); + vulkan_->DestroyObjects(); + vulkan_->ReinitSurface(); + vulkan_->InitObjects(); + draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); +} + +void SDLVulkanGraphicsContext::Poll() { + // Check for existing swapchain to avoid issues during shutdown. + if (vulkan_->GetSwapchain() && renderManager_->NeedsSwapchainRecreate()) { + Resize(); + } +} \ No newline at end of file diff --git a/SDL/SDLVulkanGraphicsContext.h b/SDL/SDLVulkanGraphicsContext.h index 533406560e..02e5f496e4 100644 --- a/SDL/SDLVulkanGraphicsContext.h +++ b/SDL/SDLVulkanGraphicsContext.h @@ -7,6 +7,8 @@ #include "thin3d/thin3d.h" +class VulkanRenderManager; + class SDLVulkanGraphicsContext : public GraphicsContext { public: SDLVulkanGraphicsContext() {} @@ -22,13 +24,9 @@ public: // We don't do it this way. } - void Resize() override { - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - vulkan_->DestroyObjects(); - vulkan_->ReinitSurface(); - vulkan_->InitObjects(); - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - } + void Resize() override; + + void Poll() override; void SwapInterval(int interval) override { } @@ -42,4 +40,5 @@ public: private: Draw::DrawContext *draw_ = nullptr; VulkanContext *vulkan_ = nullptr; + VulkanRenderManager *renderManager_ = nullptr; }; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index e6fca738f3..f2cd00a812 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1096,6 +1096,7 @@ void NativeRender(GraphicsContext *graphicsContext) { } #endif } else { + // ILOG("Polling graphics context"); graphicsContext->Poll(); } From 4bcd8df079b283837a7d2f52b87a03b55c13e715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 22 Jun 2020 22:45:24 +0200 Subject: [PATCH 160/848] Logging improvements and warning fixes. (Had a super odd crash that I can't repro anymore in PPGe init...) --- Core/HLE/sceKernelInterrupt.cpp | 4 ++-- Core/Util/PPGeDraw.cpp | 7 +++---- ext/native/image/zim_load.cpp | 12 ++++++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 2b3da424ef..e00b5ea875 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -767,7 +767,7 @@ static int sysclib_strstr(u32 s1, u32 s2) { } static int sysclib_strncmp(u32 s1, u32 s2, u32 size) { - ERROR_LOG(SCEKERNEL, "Untested sysclib_strncmp(%08x, %08x, x)", s1, s2, size); + ERROR_LOG(SCEKERNEL, "Untested sysclib_strncmp(%08x, %08x, %08x)", s1, s2, size); if (Memory::IsValidAddress(s1) && Memory::IsValidAddress(s2)) { const char * str1 = Memory::GetCharPointer(s1); const char * str2 = Memory::GetCharPointer(s2); @@ -777,7 +777,7 @@ static int sysclib_strncmp(u32 s1, u32 s2, u32 size) { } static u32 sysclib_memmove(u32 dst, u32 src, u32 size) { - ERROR_LOG(SCEKERNEL, "Untested sysclib_memmove(%08x, %08x, x)", dst, src, size); + ERROR_LOG(SCEKERNEL, "Untested sysclib_memmove(%08x, %08x, %08x)", dst, src, size); if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { memmove(Memory::GetPointer(dst), Memory::GetPointer(src), size); } diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index ebb555ba63..fc0d7301ca 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -225,9 +225,8 @@ void __PPGeInit() { if (loadedZIM) { size_t atlas_data_size; - uint8_t *atlas_data; if (!g_ppge_atlas.IsMetadataLoaded()) { - atlas_data = VFSReadFile("ppge_atlas.meta", &atlas_data_size); + uint8_t *atlas_data = VFSReadFile("ppge_atlas.meta", &atlas_data_size); if (atlas_data) g_ppge_atlas.Load(atlas_data, atlas_data_size); delete[] atlas_data; @@ -262,7 +261,7 @@ void __PPGeInit() { u8 cval = (a2 << 4) | a1; ramPtr[i] = cval; } - + free(imageData[0]); // We can't create it here, because Android needs it on the right thread. @@ -271,7 +270,7 @@ void __PPGeInit() { textDrawer = nullptr; textDrawerImages.clear(); - DEBUG_LOG(SCEGE, "PPGe drawing library initialized. DL: %08x Data: %08x Atlas: %08x (%i) Args: %08x", + INFO_LOG(SCEGE, "PPGe drawing library initialized. DL: %08x Data: %08x Atlas: %08x (%i) Args: %08x", dlPtr, dataPtr, atlasPtr, atlasSize, listArgs.ptr); } diff --git a/ext/native/image/zim_load.cpp b/ext/native/image/zim_load.cpp index 2b9f097d72..89901f5dc7 100644 --- a/ext/native/image/zim_load.cpp +++ b/ext/native/image/zim_load.cpp @@ -82,8 +82,7 @@ int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int total_data_size += image_data_size[i]; } - if (total_data_size == 0) - { + if (total_data_size == 0) { ELOG("Invalid ZIM data size 0"); return 0; } @@ -95,12 +94,15 @@ int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int if (*flags & ZIM_ZLIB_COMPRESSED) { long outlen = (long)total_data_size; - if (Z_OK != ezuncompress(*image, &outlen, (unsigned char *)(zim + 16), (long)datasize - 16)) { + int retcode = ezuncompress(*image, &outlen, (unsigned char *)(zim + 16), (long)datasize - 16); + if (Z_OK != retcode) { + ELOG("ZIM zlib format decompression failed: %d", retcode); free(*image); *image = 0; return 0; } if (outlen != total_data_size) { + // Shouldn't happen if return value was Z_OK. ELOG("Wrong size data in ZIM: %i vs %i", (int)outlen, (int)total_data_size); } } else { @@ -116,11 +118,13 @@ int LoadZIM(const char *filename, int *width, int *height, int *format, uint8_t size_t size; uint8_t *buffer = VFSReadFile(filename, &size); if (!buffer) { + ELOG("Couldn't read data for '%s'", buffer); return 0; } + int retval = LoadZIMPtr(buffer, (int)size, width, height, format, image); if (!retval) { - ELOG("Not a valid ZIM file: %s", filename); + ELOG("Not a valid ZIM file: %s (size: %d bytes)", filename, (int)size); } delete [] buffer; return retval; From cefad00a56522476713c780c6a9837bdeed4fe4e Mon Sep 17 00:00:00 2001 From: sum2012 Date: Tue, 23 Jun 2020 21:04:03 +0800 Subject: [PATCH 161/848] Update readme for v1.10 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 818b7373ab..ee0b5b70e3 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ What's new in 1.10.0 * Frames in-flight now configurable to reduce input lag at the cost of speed (#12660) * Add toggle mode to combo button (#12623) * SDL mouse support, Qt menu upgrades (#12612, #12817) +* Real support "Hatsune Miku Project Diva Extend" chinese patched version (#13007) +* Some minor kernel module support (#13028,#12225,#13026,#13004,#13038,#13023) What's new in 1.9.0/1.9.3 ------------------------- From bdd3c6b48919dc849f16029d934592722c16a70c Mon Sep 17 00:00:00 2001 From: iota97 Date: Tue, 23 Jun 2020 15:59:58 +0200 Subject: [PATCH 162/848] Minor style --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ee0b5b70e3..d86c43ddde 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ What's new in 1.10.0 * Ghost in the Shell graphics fixed (JIT inaccuracy with inf*0) (#12519) * Mac build now supports Vulkan on top of MoltenVK (#12583) * Raspberry Pi 4 EGL crash fixed (#12474) -* VSync now supported on all backends, frame duplication option added for 30 Hz games +* VSync now supported on all backends, frame duplication option added for 30 Hz games (#12659, #12602) * Camera supported on Windows, Linux and Mac (still no microphone though) (#12572, #12580, #12607) * Darkstalkers fixed and working through software rendering. SW rendering fixed on GLES 2.0 (#12443, #12898) * Hot Shots Golf slowdown and flicker on Vulkan fixed (#12873, #12746) @@ -56,8 +56,8 @@ What's new in 1.10.0 * Frames in-flight now configurable to reduce input lag at the cost of speed (#12660) * Add toggle mode to combo button (#12623) * SDL mouse support, Qt menu upgrades (#12612, #12817) -* Real support "Hatsune Miku Project Diva Extend" chinese patched version (#13007) -* Some minor kernel module support (#13028,#12225,#13026,#13004,#13038,#13023) +* Real support for chinese patched version of Hatsune Miku Project Diva Extend (#13007) +* Some minor kernel module support (#13028, #12225, #13026, #13004, #13038, #13023) What's new in 1.9.0/1.9.3 ------------------------- From 72a5719459830b05264d687f33ecde3cef3276ea Mon Sep 17 00:00:00 2001 From: sum2012 Date: Tue, 23 Jun 2020 22:41:16 +0800 Subject: [PATCH 163/848] Update Lang --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index b3fd7fccf9..3801783d05 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit b3fd7fccf9a2182270d998667c64390c8c50bc91 +Subproject commit 3801783d05be6353ff7f8ced32022d5df414eea0 From 7180c2a4c28ec18667577d4f119a738ba8d8de52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 23 Jun 2020 21:57:02 +0200 Subject: [PATCH 164/848] Enable Vulkan validation in SDL debug builds --- Common/Vulkan/VulkanContext.cpp | 5 ++++- SDL/SDLVulkanGraphicsContext.cpp | 12 +++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 96c170423d..31cb1573d3 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -88,6 +88,9 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { return VK_ERROR_INITIALIZATION_FAILED; } + instance_layer_names_.clear(); + device_layer_names_.clear(); + // We can get the list of layers and extensions without an instance so we can use this information // to enable the extensions we need that are available. GetInstanceLayerProperties(); @@ -177,7 +180,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { #endif if (res != VK_SUCCESS) { if (res == VK_ERROR_LAYER_NOT_PRESENT) { - WLOG("Validation on but layers not available - dropping layers"); + WLOG("Validation on but instance layer not available - dropping layers"); // Drop the validation layers and try again. instance_layer_names_.clear(); device_layer_names_.clear(); diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 389030d594..45898f3826 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -9,10 +9,17 @@ #include "Core/System.h" #include "SDLVulkanGraphicsContext.h" + #if defined(VK_USE_PLATFORM_METAL_EXT) #include "SDLCocoaMetalLayer.h" #endif +#ifdef _DEBUG +static const bool g_Validate = true; +#else +static const bool g_Validate = false; +#endif + bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) { window = SDL_CreateWindow("Initializing Vulkan...", x, y, pixel_xres, pixel_yres, mode); if (!window) { @@ -35,7 +42,10 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, vulkan_ = new VulkanContext(); int vulkanFlags = VULKAN_FLAG_PRESENT_MAILBOX; - // vulkanFlags |= VULKAN_FLAG_VALIDATE; + if (g_Validate) { + vulkanFlags |= VULKAN_FLAG_VALIDATE; + } + VulkanContext::CreateInfo info{}; info.app_name = "PPSSPP"; info.app_ver = gitVer.ToInteger(); From f9cef5b6b220c8c0e10abf625858b2f33fa1d089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 24 Jun 2020 01:04:41 +0200 Subject: [PATCH 165/848] Partly clean up SDL resize code, should help #11974 --- Common/Log.h | 2 ++ Core/Core.cpp | 2 +- GPU/GPUCommon.h | 2 +- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- SDL/SDLMain.cpp | 11 +++++------ UI/NativeApp.cpp | 12 +++++------- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Common/Log.h b/Common/Log.h index 1e463acadc..c53da51cb2 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -122,6 +122,8 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * #if MAX_LOGLEVEL >= DEBUG_LEVEL #define _dbg_assert_(_t_, _a_) \ if (!(_a_)) {\ + printf(#_a_ "\n\nError...\n\n Line: %d\n File: %s\n\n", \ + __LINE__, __FILE__); \ ERROR_LOG(_t_, #_a_ "\n\nError...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \ __LINE__, __FILE__); \ if (!PanicYesNo("*** Assertion ***\n")) { Crash(); } \ diff --git a/Core/Core.cpp b/Core/Core.cpp index 3f66794576..6a89148be2 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -187,7 +187,7 @@ bool UpdateScreenScale(int width, int height) { dp_yres = new_dp_yres; pixel_xres = width; pixel_yres = height; - DEBUG_LOG(SYSTEM, "pixel_res: %dx%d. Calling NativeResized()", pixel_xres, pixel_yres); + ILOG("pixel_res: %dx%d. Calling NativeResized()", pixel_xres, pixel_yres); NativeResized(); return true; } diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 7dff718c35..27deb1b77b 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -340,7 +340,7 @@ protected: bool dumpThisFrame_; bool debugRecording_; bool interruptsEnabled_; - bool resized_; + bool resized_ = false; DrawType lastDraw_ = DRAW_UNKNOWN; GEPrimitiveType lastPrim_ = GE_PRIM_INVALID; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 43de4d1078..8678876de6 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -292,8 +292,8 @@ void GPU_Vulkan::BeginHostFrame() { if (vulkan_->GetDeviceFeatures().enabled.wideLines) { drawEngine_.SetLineWidth(PSP_CoreParameter().renderWidth / 480.0f); } + resized_ = false; } - resized_ = false; textureCacheVulkan_->StartFrame(); diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 52028d0879..a5928d45ba 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -776,19 +776,18 @@ int main(int argc, char *argv[]) { case SDL_WINDOWEVENT: switch (event.window.event) { case SDL_WINDOWEVENT_SIZE_CHANGED: // better than RESIZED, more general - case SDL_WINDOWEVENT_MAXIMIZED: - case SDL_WINDOWEVENT_RESTORED: { + int new_width = event.window.data1; + int new_height = event.window.data2; + windowHidden = false; Core_NotifyWindowHidden(windowHidden); Uint32 window_flags = SDL_GetWindowFlags(window); bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN); - if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { - UpdateScreenScale(event.window.data1, event.window.data2); - } - NativeMessageReceived("gpu_resized", ""); + // This one calls NativeResized if the size changed. + UpdateScreenScale(new_width, new_height); // Set variable here in case fullscreen was toggled by hotkey g_Config.bFullScreen = fullscreen; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index f2cd00a812..4420a5a04d 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1087,13 +1087,11 @@ void NativeRender(GraphicsContext *graphicsContext) { graphicsContext->Resize(); screenManager->resized(); - // TODO: Move this to new GraphicsContext objects for each backend. -#ifndef _WIN32 - if (GetGPUBackend() == GPUBackend::OPENGL) { - PSP_CoreParameter().pixelWidth = pixel_xres; - PSP_CoreParameter().pixelHeight = pixel_yres; - NativeMessageReceived("gpu_resized", ""); - } + // TODO: Move this to the GraphicsContext objects for each backend. +#if !defined(_WIN32) && !defined(ANDROID) + PSP_CoreParameter().pixelWidth = pixel_xres; + PSP_CoreParameter().pixelHeight = pixel_yres; + NativeMessageReceived("gpu_resized", ""); #endif } else { // ILOG("Polling graphics context"); From a0f8ad41d1a61bf7d488e3f3b945374396f24cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 23 Jun 2020 20:59:44 +0200 Subject: [PATCH 166/848] Update lang submodule --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index 3801783d05..5b8b5abbe6 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 3801783d05be6353ff7f8ced32022d5df414eea0 +Subproject commit 5b8b5abbe6b19cbf0ba29c9de334100b33bd5652 From 85e645e71a95f08a0e815a25c543bcf84b2a8918 Mon Sep 17 00:00:00 2001 From: vnctdj <3978690+vnctdj@users.noreply.github.com> Date: Thu, 25 Jun 2020 23:32:20 +0200 Subject: [PATCH 167/848] Add https://github.com/hrydgard/ppsspp/issues/11974 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d86c43ddde..62b5fb0d1b 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ No BIOS file required to play, PPSSPP is an "HLE" emulator. Default settings ba To contribute, see [the development page](https://www.ppsspp.org/development.html). Help testing, investigating, or fixing is always welcome. See [the list of issues](https://github.com/hrydgard/ppsspp/issues). -For the latest source code, see [our github page](https://github.com/hrydgard/ppsspp). +For the latest source code, see [our GitHub page](https://github.com/hrydgard/ppsspp). For build instructions and other development tutorials, see [the wiki](https://github.com/hrydgard/ppsspp/wiki). @@ -58,6 +58,7 @@ What's new in 1.10.0 * SDL mouse support, Qt menu upgrades (#12612, #12817) * Real support for chinese patched version of Hatsune Miku Project Diva Extend (#13007) * Some minor kernel module support (#13028, #12225, #13026, #13004, #13038, #13023) +* Fixed fullscreen toggling with Vulkan in SDL builds (#11974) What's new in 1.9.0/1.9.3 ------------------------- From 82992c4c16eb6dadee3251749666fe0bb73ad271 Mon Sep 17 00:00:00 2001 From: vnctdj <3978690+vnctdj@users.noreply.github.com> Date: Thu, 25 Jun 2020 23:41:09 +0200 Subject: [PATCH 168/848] Archive changelog for older versions We show the latest 4 versions on https://www.ppsspp.org/downloads.html --- README.md | 45 --------------------------------------------- history.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 62b5fb0d1b..c76d0ddef2 100644 --- a/README.md +++ b/README.md @@ -153,51 +153,6 @@ What's new in 1.7.0 * Texture decoding optimizations (#11350) * Tons and tons of miscellaneous bugfixes and compatibility fixes -What's new in 1.6.3 -------------------- -* Crashfixes, task switching and one in Phantasy Star Portable -* Improve graphics in PoP on some devices - -What's new in 1.6.1, 1.6.2 --------------------------- -* Crashfixes -* Fix broken graphics in flOw. - -What's new in 1.6.0 -------------------- -* OpenGL backend now properly multithreaded, giving a good speed boost. -* Various Vulkan performance improvements (like #10911) and memory allocation fixes. -* GPU command interpreter performance improvements (#10658) -* Various fixes for app switching and widgets (#10855) on Android -* Bugfixes and some performance improvements in the ARM64 JIT compiler and IR interpreter -* Shader cache enabled for Vulkan -* Multiple iOS fixes, including JIT (#10465) and file browser (#10921). -* Improved compatibility on Mac (#10113) -* Texture replacement ID bugfix (note: some textures from 1.5.4 may become incompatible) -* Adhoc multiplayer fixes (#8975) -* Vulkan support on Linux/SDL (#10413) -* Retroarch support - -What's new in 1.5.4 -------------------- -* Bugfixes and crashfixes! - -What's new in 1.5.0 -------------------- -* Full Vulkan support, also for Android now. Very fast on supported devices. (#10033, #10049) -* Smarter graphics state management, reduced CPU consumption on all backends (#9899) -* Android: Support for Arabic and other scripts we couldn't support before -* Fix Android widgets, screen scaling (#10145) -* Fixes to video dumping -* Geometry problems fixed in Medal of Honor -* Implement immediate draws, fixing Thrillville (#7459) -* Software rendering improvements, speed and accuracy -* Hardware tesselation of PSP Beziers and Splines (used by a few games) -* Partial sceUsbGps and sceUsbCam support (Android) -* Android "Sustained performance mode" to avoid thermal throttling (#9901) -* Linux controller mapping fixes (#9997) -* Assorted bugfixes and compatibility improvements - Looking for [older news](history.md)? diff --git a/history.md b/history.md index 38af1adf76..e8a6cb48d1 100644 --- a/history.md +++ b/history.md @@ -1,6 +1,51 @@ This is history moved out from README.md, which was getting a bit long. +What's new in 1.6.3 +------------------- +* Crashfixes, task switching and one in Phantasy Star Portable +* Improve graphics in PoP on some devices + +What's new in 1.6.1, 1.6.2 +-------------------------- +* Crashfixes +* Fix broken graphics in flOw. + +What's new in 1.6.0 +------------------- +* OpenGL backend now properly multithreaded, giving a good speed boost. +* Various Vulkan performance improvements (like #10911) and memory allocation fixes. +* GPU command interpreter performance improvements (#10658) +* Various fixes for app switching and widgets (#10855) on Android +* Bugfixes and some performance improvements in the ARM64 JIT compiler and IR interpreter +* Shader cache enabled for Vulkan +* Multiple iOS fixes, including JIT (#10465) and file browser (#10921). +* Improved compatibility on Mac (#10113) +* Texture replacement ID bugfix (note: some textures from 1.5.4 may become incompatible) +* Adhoc multiplayer fixes (#8975) +* Vulkan support on Linux/SDL (#10413) +* Retroarch support + +What's new in 1.5.4 +------------------- +* Bugfixes and crashfixes! + +What's new in 1.5.0 +------------------- +* Full Vulkan support, also for Android now. Very fast on supported devices. (#10033, #10049) +* Smarter graphics state management, reduced CPU consumption on all backends (#9899) +* Android: Support for Arabic and other scripts we couldn't support before +* Fix Android widgets, screen scaling (#10145) +* Fixes to video dumping +* Geometry problems fixed in Medal of Honor +* Implement immediate draws, fixing Thrillville (#7459) +* Software rendering improvements, speed and accuracy +* Hardware tesselation of PSP Beziers and Splines (used by a few games) +* Partial sceUsbGps and sceUsbCam support (Android) +* Android "Sustained performance mode" to avoid thermal throttling (#9901) +* Linux controller mapping fixes (#9997) +* Assorted bugfixes and compatibility improvements + What's new in 1.4.2 ------------------- * Fixed longstanding bug causing games to crash on ARM64 From f65be705c5b54a368110d447f507d7db0f8c416a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 27 Jun 2020 11:10:19 +0200 Subject: [PATCH 169/848] Update lang submodule again --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index 5b8b5abbe6..d184ba2b60 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 5b8b5abbe6b19cbf0ba29c9de334100b33bd5652 +Subproject commit d184ba2b607a03435be579406b816c90add334e6 From 401df203844465b84015d4710c6f02914b890589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 27 Jun 2020 11:11:04 +0200 Subject: [PATCH 170/848] Update version number to 1.10. This required changing the Android version code pattern, but should be ok. --- android/AndroidManifest.xml | 4 ++-- android/build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 3c5a48a78a..7ea2d8f0a6 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="110000000" + android:versionName="1.10.0.0"> diff --git a/android/build.gradle b/android/build.gradle index 26440d6405..aedd4e852f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -4,7 +4,7 @@ plugins { apply plugin: 'com.android.application' androidGitVersion { - codeFormat = "MNPPBBBB" + codeFormat = "MNNPPBBBB" format = "%tag%%-count%%-branch%%-dirty%" prefix = "v" // Only tags beginning with v are considered. untrackedIsDirty = false From e479bf7f7bb1431f4f0f54a66d7f7245625916f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sat, 27 Jun 2020 17:29:21 +0200 Subject: [PATCH 171/848] TextureDecoder: Fix misuse of NEON on all armv7 `ppsspp_config.h` properly defines `PPSSPP_ARCH(ARM_NEON)` already for arm64v8 and armv7+NEON, so we use that instead of using NEON instructions on all armv7. --- GPU/Common/TextureDecoder.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/GPU/Common/TextureDecoder.cpp b/GPU/Common/TextureDecoder.cpp index 68056ce4cd..0aca26ec84 100644 --- a/GPU/Common/TextureDecoder.cpp +++ b/GPU/Common/TextureDecoder.cpp @@ -614,7 +614,7 @@ CheckAlphaResult CheckAlphaRGBA8888Basic(const u32 *pixelData, int stride, int w if ((w & 3) == 0 && (stride & 3) == 0) { #ifdef _M_SSE return CheckAlphaRGBA8888SSE2(pixelData, stride, w, h); -#elif PPSSPP_ARCH(ARMV7) || PPSSPP_ARCH(ARM64) +#elif PPSSPP_ARCH(ARM_NEON) if (cpu_info.bNEON) { return CheckAlphaRGBA8888NEON(pixelData, stride, w, h); } @@ -644,7 +644,7 @@ CheckAlphaResult CheckAlphaABGR4444Basic(const u32 *pixelData, int stride, int w if ((w & 7) == 0 && (stride & 7) == 0) { #ifdef _M_SSE return CheckAlphaABGR4444SSE2(pixelData, stride, w, h); -#elif PPSSPP_ARCH(ARMV7) || PPSSPP_ARCH(ARM64) +#elif PPSSPP_ARCH(ARM_NEON) if (cpu_info.bNEON) { return CheckAlphaABGR4444NEON(pixelData, stride, w, h); } @@ -677,7 +677,7 @@ CheckAlphaResult CheckAlphaABGR1555Basic(const u32 *pixelData, int stride, int w if ((w & 7) == 0 && (stride & 7) == 0) { #ifdef _M_SSE return CheckAlphaABGR1555SSE2(pixelData, stride, w, h); -#elif PPSSPP_ARCH(ARMV7) || PPSSPP_ARCH(ARM64) +#elif PPSSPP_ARCH(ARM_NEON) if (cpu_info.bNEON) { return CheckAlphaABGR1555NEON(pixelData, stride, w, h); } @@ -709,7 +709,7 @@ CheckAlphaResult CheckAlphaRGBA4444Basic(const u32 *pixelData, int stride, int w if ((w & 7) == 0 && (stride & 7) == 0) { #ifdef _M_SSE return CheckAlphaRGBA4444SSE2(pixelData, stride, w, h); -#elif PPSSPP_ARCH(ARMV7) || PPSSPP_ARCH(ARM64) +#elif PPSSPP_ARCH(ARM_NEON) if (cpu_info.bNEON) { return CheckAlphaRGBA4444NEON(pixelData, stride, w, h); } @@ -742,7 +742,7 @@ CheckAlphaResult CheckAlphaRGBA5551Basic(const u32 *pixelData, int stride, int w if ((w & 7) == 0 && (stride & 7) == 0) { #ifdef _M_SSE return CheckAlphaRGBA5551SSE2(pixelData, stride, w, h); -#elif PPSSPP_ARCH(ARMV7) || PPSSPP_ARCH(ARM64) +#elif PPSSPP_ARCH(ARM_NEON) if (cpu_info.bNEON) { return CheckAlphaRGBA5551NEON(pixelData, stride, w, h); } From cad7603ccdc612a444a950869f3583088b30df33 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Sat, 27 Jun 2020 18:43:17 +0000 Subject: [PATCH 172/848] Qt: unbreak build without SDL Qt/QtMain.cpp:51:1: error: unknown type name 'SDL_AudioSpec' SDL_AudioSpec g_retFmt; ^ 1 error generated. --- Qt/QtMain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 7713b6587d..7f9726b417 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -48,9 +48,9 @@ static int browseFileEvent = -1; static int browseFolderEvent = -1; QTCamera *qtcamera = nullptr; +#ifdef SDL SDL_AudioSpec g_retFmt; -#ifdef SDL static SDL_AudioDeviceID audioDev = 0; extern void mixaudio(void *userdata, Uint8 *stream, int len) { @@ -147,10 +147,12 @@ std::string System_GetProperty(SystemProperty prop) { int System_GetPropertyInt(SystemProperty prop) { switch (prop) { +#if defined(SDL) case SYSPROP_AUDIO_SAMPLE_RATE: return g_retFmt.freq; case SYSPROP_AUDIO_FRAMES_PER_BUFFER: return g_retFmt.samples; +#endif case SYSPROP_DEVICE_TYPE: #if defined(__ANDROID__) return DEVICE_TYPE_MOBILE; From 2c7290e98b81a2f42a2e71c5bdfda4298fcbc8e6 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Sat, 27 Jun 2020 20:18:33 +0000 Subject: [PATCH 173/848] cmake: don't install bundled glslang lib/libglslang.a lib/cmake/glslangTargets.cmake lib/cmake/glslangTargets-release.cmake include/glslang/Public/ShaderLang.h include/glslang/Include/arrays.h [...] --- ext/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index 322d1c368b..16b4adbd7e 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -13,7 +13,7 @@ if(ANDROID) set(ENABLE_HLSL OFF CACHE BOOL "let's not build HLSL support we don't need" FORCE) endif() -add_subdirectory(glslang) +add_subdirectory(glslang EXCLUDE_FROM_ALL) add_subdirectory(snappy) add_subdirectory(udis86) add_subdirectory(SPIRV-Cross-build) From 1a8084cdbc2a7c82789cb3217d96f8b637338ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 28 Jun 2020 10:03:03 +0200 Subject: [PATCH 174/848] Different handling of Download lifetimes. Might help an issue from #13057 (1.10 crash mysteries) --- ext/native/net/http_client.cpp | 24 ++++++++++++++---------- ext/native/net/http_client.h | 9 +++++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index 91fec283a8..162bd5707a 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -436,12 +436,18 @@ Download::Download(const std::string &url, const std::string &outfile) } Download::~Download() { - if (thread_.joinable()) - thread_.join(); + if (!joined_) { + FLOG("Download destructed without join"); + } } -void Download::Start(std::shared_ptr self) { - thread_ = std::thread(std::bind(&Download::Do, this, self)); +void Download::Start() { + thread_ = std::thread(std::bind(&Download::Do, this)); +} + +void Download::Join() { + thread_.join(); + joined_ = true; } void Download::SetFailed(int code) { @@ -489,11 +495,8 @@ std::string Download::RedirectLocation(const std::string &baseUrl) { return redirectUrl; } -void Download::Do(std::shared_ptr self) { +void Download::Do() { setCurrentThreadName("Downloader::Do"); - // as long as this is in scope, we won't get destructed. - // yeah this is ugly, I need to think about how life time should be managed for these... - std::shared_ptr self_ = self; resultCode_ = 0; std::string downloadURL = url_; @@ -542,7 +545,7 @@ void Download::Do(std::shared_ptr self) { std::shared_ptr Downloader::StartDownload(const std::string &url, const std::string &outfile) { std::shared_ptr dl(new Download(url, outfile)); downloads_.push_back(dl); - dl->Start(dl); + dl->Start(); return dl; } @@ -553,7 +556,7 @@ std::shared_ptr Downloader::StartDownloadWithCallback( std::shared_ptr dl(new Download(url, outfile)); dl->SetCallback(callback); downloads_.push_back(dl); - dl->Start(dl); + dl->Start(); return dl; } @@ -562,6 +565,7 @@ void Downloader::Update() { for (size_t i = 0; i < downloads_.size(); i++) { if (downloads_[i]->Progress() == 1.0f || downloads_[i]->Failed()) { downloads_[i]->RunCallback(); + downloads_[i]->Join(); downloads_.erase(downloads_.begin() + i); goto restart; } diff --git a/ext/native/net/http_client.h b/ext/native/net/http_client.h index b671169585..694cad33ed 100644 --- a/ext/native/net/http_client.h +++ b/ext/native/net/http_client.h @@ -93,9 +93,9 @@ public: Download(const std::string &url, const std::string &outfile); ~Download(); - // Keeps around an instance of the shared_ptr, so that it doesn't get destructed - // until done. - void Start(std::shared_ptr self); + void Start(); + + void Join(); // Returns 1.0 when done. That one value can be compared exactly - or just use Done(). float Progress() const { return progress_; } @@ -138,7 +138,7 @@ public: void SetHidden(bool hidden) { hidden_ = hidden; } private: - void Do(std::shared_ptr self); // Actually does the download. Runs on thread. + void Do(); // Actually does the download. Runs on thread. int PerformGET(const std::string &url); std::string RedirectLocation(const std::string &baseUrl); void SetFailed(int code); @@ -153,6 +153,7 @@ private: bool failed_ = false; bool cancelled_ = false; bool hidden_ = false; + bool joined_ = false; std::function callback_; }; From 37b57d925ca5f1db8399db30c3abc6c4ca07aca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 28 Jun 2020 18:18:12 +0200 Subject: [PATCH 175/848] D3D9: Fix a sign mistake generating the projection matrix. Fixes #13063 --- GPU/Directx9/ShaderManagerDX9.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 50beedfe5e..4c3c79701b 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -251,9 +251,9 @@ static void ConvertProjMatrixToD3D(Matrix4x4 &in, bool invertedX, bool invertedY float yoff = -1.0f / gstate_c.curRTRenderHeight; if (invertedY) { - yoff = gstate_c.vpYOffset - yoff; - } else { yoff = -gstate_c.vpYOffset - yoff; + } else { + yoff = gstate_c.vpYOffset - yoff; } const Vec3 trans(xoff, yoff, gstate_c.vpZOffset * 0.5f + 0.5f); From bd8083fb26a7ccaf16f0a4c61bfcb8bb2f24a30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 28 Jun 2020 18:34:00 +0200 Subject: [PATCH 176/848] Downloader: Join threads in CancelAll --- ext/native/net/http_client.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index 162bd5707a..ca2fb0f36c 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -446,6 +446,9 @@ void Download::Start() { } void Download::Join() { + if (joined_) { + ELOG("Already joined thread!"); + } thread_.join(); joined_ = true; } @@ -585,6 +588,9 @@ void Downloader::CancelAll() { for (size_t i = 0; i < downloads_.size(); i++) { downloads_[i]->Cancel(); } + for (size_t i = 0; i < downloads_.size(); i++) { + downloads_[i]->Join(); + } downloads_.clear(); } From 63ead85c7f9465784e5dda322b53f3af483f33d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 28 Jun 2020 21:35:19 +0200 Subject: [PATCH 177/848] Some paranoid checks in PPGeDraw. Might help the crash seen in #13047. --- Core/Util/PPGeDraw.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index fc0d7301ca..3e4efc8afb 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -797,7 +797,7 @@ static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, f } PPGeTextDrawerCacheKey key{ text, tdalign, maxWidth / scale }; - PPGeTextDrawerImage im; + PPGeTextDrawerImage im{}; auto cacheItem = textDrawerImages.find(key); if (cacheItem != textDrawerImages.end()) { @@ -843,6 +843,10 @@ static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, f } static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, PPGeAlign align, float scale, u32 color) { + if (!im.ptr) { + return; + } + int bufw = ((im.entry.bmWidth + 31) / 32) * 32; int wp2 = GetPow2(im.entry.bmWidth); int hp2 = GetPow2(im.entry.bmHeight); @@ -874,6 +878,10 @@ static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, PPGeAlig } void PPGeDrawText(const char *text, float x, float y, PPGeAlign align, float scale, u32 color) { + if (!text || !strlen(text)) { + return; + } + if (HasTextDrawer()) { PPGeTextDrawerImage im = PPGeGetTextImage(text, align, scale, 480.0f - x, false); PPGeDrawTextImage(im, x, y, align, scale, color); From df6f2160560f0fa00f55a52bcced243e30fcf972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 28 Jun 2020 22:05:19 +0200 Subject: [PATCH 178/848] Disable the "Duplicate frames" feature if frameskip != 0. Works around / Fixes #13068 --- Core/HLE/sceDisplay.cpp | 7 +++++-- UI/GameSettingsScreen.cpp | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index f18a056be9..56fcf9bfc9 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -754,12 +754,15 @@ void __DisplayFlip(int cyclesLate) { // Also let's always flip for animated shaders. const ShaderInfo *shaderInfo = g_Config.sPostShaderName == "Off" ? nullptr : GetPostShaderInfo(g_Config.sPostShaderName); bool postEffectRequiresFlip = false; + + bool duplicateFrames = g_Config.bRenderDuplicateFrames && g_Config.iFrameSkip == 0; + // postEffectRequiresFlip is not compatible with frameskip unthrottling, see #12325. if (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && !(g_Config.bFrameSkipUnthrottle && !FrameTimingThrottled())) { if (shaderInfo) { - postEffectRequiresFlip = (shaderInfo->requires60fps || g_Config.bRenderDuplicateFrames); + postEffectRequiresFlip = (shaderInfo->requires60fps || duplicateFrames); } else { - postEffectRequiresFlip = g_Config.bRenderDuplicateFrames; + postEffectRequiresFlip = duplicateFrames; } } diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 8202870c79..1a9ca4a977 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -356,6 +356,9 @@ void GameSettingsScreen::CreateViews() { settingInfo_->Show(gr->T("RenderDuplicateFrames Tip", "Can make framerate smoother in games that run at lower framerates"), e.v); return UI::EVENT_CONTINUE; }); + frameDuplication->SetEnabledFunc([]() -> bool { + return g_Config.iFrameSkip == 0; + }); if (GetGPUBackend() == GPUBackend::VULKAN || GetGPUBackend() == GPUBackend::OPENGL) { static const char *bufferOptions[] = { "No buffer", "Up to 1", "Up to 2" }; From 5f57d4775f1ef692eb8dfe6d2f82cd959038db4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 29 Jun 2020 22:47:34 +0200 Subject: [PATCH 179/848] Add some excessive null checks to GameScreen::render(), might fix the crash seen in #13057 --- Core/ELF/ParamSFO.h | 24 +++++++---------------- UI/GameScreen.cpp | 47 +++++++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/Core/ELF/ParamSFO.h b/Core/ELF/ParamSFO.h index 940280bac3..dca5d1b23e 100644 --- a/Core/ELF/ParamSFO.h +++ b/Core/ELF/ParamSFO.h @@ -67,28 +67,18 @@ private: class ValueData { public: - ValueType type; - int max_size; + ValueType type = VT_INT; + int max_size = 0; std::string s_value; - int i_value; + int i_value = 0; - u8* u_value; - unsigned int u_size; + u8* u_value = nullptr; + unsigned int u_size = 0; void SetData(const u8* data, int size); - ValueData() - { - u_value = 0; - u_size = 0; - type = VT_INT; - max_size = 0; - i_value = 0; - } - - ~ValueData() - { - if(u_value) + ~ValueData() { + if (u_value) delete[] u_value; } }; diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index f584f45faa..1c900beecd 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -47,8 +47,9 @@ GameScreen::~GameScreen() { void GameScreen::CreateViews() { std::shared_ptr info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE); - if (info && !info->id.empty()) + if (info && !info->id.empty()) { saveDirs = info->GetSaveDataDirectories(); // Get's very heavy, let's not do it in update() + } auto di = GetI18NCategory("Dialog"); auto ga = GetI18NCategory("Game"); @@ -119,9 +120,7 @@ void GameScreen::CreateViews() { rightColumnItems->Add(btnDeleteSaveData_)->OnClick.Handle(this, &GameScreen::OnDeleteSaveData); btnDeleteSaveData_->SetVisibility(V_GONE); - if (info && !info->pending) { - otherChoices_.clear(); - } + otherChoices_.clear(); rightColumnItems->Add(AddOtherChoice(new Choice(ga->T("Delete Game"))))->OnClick.Handle(this, &GameScreen::OnDeleteGame); if (host->CanCreateShortcut()) { @@ -200,29 +199,35 @@ void GameScreen::render() { if (info->gameSize) { char temp[256]; - snprintf(temp, sizeof(temp), "%s: %1.1f %s", ga->T("Game"), (float) (info->gameSize) / 1024.f / 1024.f, ga->T("MB")); - tvGameSize_->SetText(temp); - snprintf(temp, sizeof(temp), "%s: %1.2f %s", ga->T("SaveData"), (float) (info->saveDataSize) / 1024.f / 1024.f, ga->T("MB")); - tvSaveDataSize_->SetText(temp); - if (info->installDataSize > 0) { + if (tvGameSize_) { + snprintf(temp, sizeof(temp), "%s: %1.1f %s", ga->T("Game"), (float)(info->gameSize) / 1024.f / 1024.f, ga->T("MB")); + tvGameSize_->SetText(temp); + } + if (tvSaveDataSize_) { + snprintf(temp, sizeof(temp), "%s: %1.2f %s", ga->T("SaveData"), (float)(info->saveDataSize) / 1024.f / 1024.f, ga->T("MB")); + tvSaveDataSize_->SetText(temp); + } + if (info->installDataSize > 0 && tvInstallDataSize_) { snprintf(temp, sizeof(temp), "%s: %1.2f %s", ga->T("InstallData"), (float) (info->installDataSize) / 1024.f / 1024.f, ga->T("MB")); tvInstallDataSize_->SetText(temp); tvInstallDataSize_->SetVisibility(UI::V_VISIBLE); } } - if (info->region >= 0 && info->region < GAMEREGION_MAX && info->region != GAMEREGION_OTHER) { - static const char *regionNames[GAMEREGION_MAX] = { - "Japan", - "USA", - "Europe", - "Hong Kong", - "Asia", - "Korea" - }; - tvRegion_->SetText(ga->T(regionNames[info->region])); - } else if (info->region > GAMEREGION_MAX){ - tvRegion_->SetText(ga->T("Homebrew")); + if (tvRegion_) { + if (info->region >= 0 && info->region < GAMEREGION_MAX && info->region != GAMEREGION_OTHER) { + static const char *regionNames[GAMEREGION_MAX] = { + "Japan", + "USA", + "Europe", + "Hong Kong", + "Asia", + "Korea" + }; + tvRegion_->SetText(ga->T(regionNames[info->region])); + } else if (info->region > GAMEREGION_MAX) { + tvRegion_->SetText(ga->T("Homebrew")); + } } if (!info->id.empty()) { From 20dd7db3511a72995e1bb04eca59b4752e3f6f51 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 29 Jun 2020 19:37:55 -0700 Subject: [PATCH 180/848] SaveState: Make sure to default init net data. Otherwise, we may crash when loading a save state. --- Core/HLE/proAdhoc.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index dedf1d6992..90f5dfe4dc 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -778,11 +778,10 @@ public: } void run(MipsCall &call) override; void SetContextID(u32 ContextID, u32 eventId); - void SetContext(SceNetAdhocMatchingContext *Context, u32 eventId) { context = Context; EventID = eventId; } private: - u32 EventID; - SceNetAdhocMatchingContext *context; + u32 EventID = 0; + SceNetAdhocMatchingContext *context = nullptr; }; extern int actionAfterMatchingMipsCall; From e6b42f392144aa96055fdf8b11b422280b0659e2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 29 Jun 2020 19:40:54 -0700 Subject: [PATCH 181/848] SaveState: Prevent edge case on old save state. If we load an old save state and it errors, could crash. --- Core/HLE/sceFont.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 1e1300858d..0bb70b5bfb 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -361,6 +361,8 @@ public: p.Do(fontLibID_); if (s >= 2) { p.Do(errorCodePtr_); + } else { + errorCodePtr_ = 0; } } void run(MipsCall &call) override; @@ -721,7 +723,8 @@ void PostAllocCallback::run(MipsCall &call) { u32 v0 = currentMIPS->r[MIPS_REG_V0]; if (v0 == 0) { // TODO: Who deletes fontLib? - Memory::Write_U32(ERROR_FONT_OUT_OF_MEMORY, errorCodePtr_); + if (errorCodePtr_) + Memory::Write_U32(ERROR_FONT_OUT_OF_MEMORY, errorCodePtr_); call.setReturnValue(0); } else { FontLib *fontLib = fontLibList[fontLibID_]; From cec261c6c616de9dacbd726efdcee654f3ccba0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 2 Jul 2020 13:33:53 +0200 Subject: [PATCH 182/848] Update README, lang submodule for 1.10.1 --- README.md | 7 +++++++ assets/lang | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 046a1a3c2e..0f225d091c 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,13 @@ If you want to download regularly updated builds for Android, Windows x86 and x6 For game compatibility, see [community compatibility feedback](https://report.ppsspp.org/games). +The #-numbers below are github issues, to see one go to https://github.com/hrydgard/ppsspp/issues/XXXXX where XXXXX is the number. + + +What's new in 1.10.1 +-------------------- +* Fixes for common crashes (#13077, #13076, see #13057) + What's new in 1.10.0 -------------------- * Graphics and compatibility fixes (#12800, #12670, #12635, #12857, #12941, #11898, #12695, more) diff --git a/assets/lang b/assets/lang index d184ba2b60..942934a3d5 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit d184ba2b607a03435be579406b816c90add334e6 +Subproject commit 942934a3d55f600622fb3f3ad60ecc1f3da23b6b From 01eea46455674a88c42b9410262ef2f38439a092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 2 Jul 2020 13:36:33 +0200 Subject: [PATCH 183/848] Update version to 1.10.1 --- android/AndroidManifest.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 7ea2d8f0a6..6efd752992 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,10 +2,10 @@ - - + android:versionCode="110010000" + android:versionName="1.10.1.0"> + + From 99411472d1dbd1640dd47e1192b46b1b5bf18b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 2 Jul 2020 13:39:52 +0200 Subject: [PATCH 184/848] README.md update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0f225d091c..428b5b1c91 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ The #-numbers below are github issues, to see one go to https://github.com/hrydg What's new in 1.10.1 -------------------- * Fixes for common crashes (#13077, #13076, see #13057) +* Fix for offset rendering in D3D9 (#13071) What's new in 1.10.0 -------------------- From 460ef63f5dac8b6134f9c3500fa8a99d58b7b36c Mon Sep 17 00:00:00 2001 From: vnctdj <3978690+vnctdj@users.noreply.github.com> Date: Thu, 2 Jul 2020 23:07:31 +0200 Subject: [PATCH 185/848] Fix reliability of the CMake generated version steps to reproduce : git checkout v1.10.1~3 git describe --always --> v1.10-19-g9aab3d986 [build now] PPSSPPSDL --version --> v1.10-19-g9aab3d986 git checkout v1.10.1 git describe --always --> v1.10.1 [build now] PPSSPPSDL --version --> v1.10-19-g9aab3d986 Indeed, the "v1.10.1" regex matches the "v1.10-19-g9aab3d986" string. How unfortunate! So I just deleted that check, building the same commit twice should not happen that often :) --- git-version.cmake | 7 ------- 1 file changed, 7 deletions(-) diff --git a/git-version.cmake b/git-version.cmake index 97a9de9710..efd4983b8c 100644 --- a/git-version.cmake +++ b/git-version.cmake @@ -23,13 +23,6 @@ if(EXISTS ${GIT_VERSION_FILE}) if(NOT ${match} EQUAL "") set(GIT_VERSION_UPDATE "0") endif() - - # Don't update if it's already the same. - file(STRINGS ${GIT_VERSION_FILE} match - REGEX "${GIT_VERSION}") - if(NOT ${match} EQUAL "") - set(GIT_VERSION_UPDATE "0") - endif() endif() set(code_string "// This is a generated file.\n\n" From fd81c123b027222872b14d240b8ff36edfd9077c Mon Sep 17 00:00:00 2001 From: TotalCaesar659 <14265316+TotalCaesar659@users.noreply.github.com> Date: Fri, 3 Jul 2020 16:43:31 +0300 Subject: [PATCH 186/848] Update submodule URL --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index a89001dc67..fe342fd22f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ url = https://github.com/hrydgard/minidx9.git [submodule "ext/armips"] path = ext/armips - url = https://github.com/Kingcom/armips + url = https://github.com/Kingcom/armips.git [submodule "ext/glslang"] path = ext/glslang url = https://github.com/hrydgard/glslang.git From 5f073d24baae2ffd8f41b8e0b3eb161711ed92fc Mon Sep 17 00:00:00 2001 From: TotalCaesar659 <14265316+TotalCaesar659@users.noreply.github.com> Date: Fri, 3 Jul 2020 21:03:14 +0300 Subject: [PATCH 187/848] Fix radio button in "Window size" menu --- Qt/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index b1c303f434..544eaa93ed 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -602,7 +602,7 @@ void MainWindow::createMenus() MenuTree* windowMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("&Window size")); windowGroup = new MenuActionGroup(this, windowMenu, SLOT(windowGroup_triggered(QAction *)), QStringList() << "&1x" << "&2x" << "&3x" << "&4x" << "&5x" << "&6x" << "&7x" << "&8x" << "&9x" << "1&0x", - QList() << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10); + QList() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9); MenuTree* renderingModeMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("Rendering m&ode")); renderingModeGroup = new MenuActionGroup(this, renderingModeMenu, SLOT(renderingModeGroup_triggered(QAction *)), From 833e91516d594fa7e7c85ce3567c3f3abddae304 Mon Sep 17 00:00:00 2001 From: TotalCaesar659 <14265316+TotalCaesar659@users.noreply.github.com> Date: Sat, 4 Jul 2020 01:16:36 +0300 Subject: [PATCH 188/848] Change default rendering resolution on Linux to auto --- Core/Config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 214aeb433e..8af00b96ac 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -517,8 +517,8 @@ static ConfigSetting cpuSettings[] = { }; static int DefaultInternalResolution() { - // Auto on Windows, 2x on large screens, 1x elsewhere. -#if defined(USING_WIN_UI) + // Auto on Windows and Linux, 2x on large screens, 1x elsewhere. +#if defined(USING_WIN_UI) || defined(USING_QT_UI) return 0; #else int longestDisplaySide = std::max(System_GetPropertyInt(SYSPROP_DISPLAY_XRES), System_GetPropertyInt(SYSPROP_DISPLAY_YRES)); From 7a58c8afbf22049a008dc6850ed68f78d6336c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jul 2020 23:21:05 +0200 Subject: [PATCH 189/848] Add a try/catch to Android camera device listing. Might help #13091 and the issue seen in #13057. --- android/src/org/ppsspp/ppsspp/CameraHelper.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/android/src/org/ppsspp/ppsspp/CameraHelper.java b/android/src/org/ppsspp/ppsspp/CameraHelper.java index 2b46fe8393..290a1b0027 100644 --- a/android/src/org/ppsspp/ppsspp/CameraHelper.java +++ b/android/src/org/ppsspp/ppsspp/CameraHelper.java @@ -140,10 +140,14 @@ class CameraHelper { ArrayList deviceList = new ArrayList<>(); int nrCam = Camera.getNumberOfCameras(); for (int index = 0; index < nrCam; index++) { - Camera.CameraInfo info = new Camera.CameraInfo(); - Camera.getCameraInfo(index, info); - String devName = index + ":" + (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK ? "Back Camera" : "Front Camera"); - deviceList.add(devName); + try { + Camera.CameraInfo info = new Camera.CameraInfo(); + Camera.getCameraInfo(index, info); + String devName = index + ":" + (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK ? "Back Camera" : "Front Camera"); + deviceList.add(devName); + } catch (Exception e) { + Log.e(TAG, "Failed to get camera info: " + e.toString()); + } } return deviceList; } From b5053b947ccb865fa35eb1125237a92d3f3652b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jul 2020 01:31:28 +0200 Subject: [PATCH 190/848] CameraHelper: Do a better job of choosing an appropriate preview size. Add sanity checks so we get a black image instead of crash if we would still fail. --- .../src/org/ppsspp/ppsspp/CameraHelper.java | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/android/src/org/ppsspp/ppsspp/CameraHelper.java b/android/src/org/ppsspp/ppsspp/CameraHelper.java index 2b46fe8393..f4b712d72f 100644 --- a/android/src/org/ppsspp/ppsspp/CameraHelper.java +++ b/android/src/org/ppsspp/ppsspp/CameraHelper.java @@ -33,6 +33,8 @@ class CameraHelper { private long mLastFrameTime = 0; private SurfaceTexture mSurfaceTexture; + private static boolean firstRotation = true; + private int getCameraRotation() { int displayRotation = mDisplay.getRotation(); int displayDegrees = 0; @@ -49,8 +51,13 @@ class CameraHelper { } } + // Does not work if the source is smaller than the destination! static byte[] rotateNV21(final byte[] input, final int inWidth, final int inHeight, final int outWidth, final int outHeight, final int rotation) { + if (firstRotation) { + Log.i(TAG, "rotateNV21: in: " + inWidth + "x" + inHeight + " out: " + outWidth + "x" + outHeight + " rotation: " + rotation); + firstRotation = false; + } final int inFrameSize = inWidth * inHeight; final int outFrameSize = outWidth * outHeight; @@ -59,6 +66,12 @@ class CameraHelper { if (rotation == 0 || rotation == 180) { final int crop_left = (inWidth - outWidth) / 2; final int crop_top = (inHeight - outHeight) / 2; + + if (crop_left < 0 || crop_top < 0) { + // Math will fail. Return a black image. + return output; + } + for (int j = 0; j < outHeight; j++) { final int yInCol = (crop_top + j) * inWidth + crop_left; final int uvInCol = inFrameSize + ((crop_top + j) >> 1) * inWidth + crop_left; @@ -79,8 +92,14 @@ class CameraHelper { } } } else if (rotation == 90 || rotation == 270) { - int crop_left = (inWidth - outHeight) / 2; - int crop_top = (inHeight - outWidth) / 2; + final int crop_left = (inWidth - outHeight) / 2; + final int crop_top = (inHeight - outWidth) / 2; + + if (crop_left < 0 || crop_top < 0) { + // Math will fail. Return a black image. + return output; + } + for (int j = 0; j < outWidth; j++) { final int yInCol = (crop_top + j) * inWidth + crop_left; final int uvInCol = inFrameSize + ((crop_top + j) >> 1) * inWidth + crop_left; @@ -98,6 +117,8 @@ class CameraHelper { output[vOut] = input[vIn]; } } + } else { + Log.e(TAG, "Unknown rotation " + rotation); } return output; } @@ -166,16 +187,37 @@ class CameraHelper { mCamera = Camera.open(cameraId); Camera.Parameters param = mCamera.getParameters(); + List supportedPreviewFormats = param.getSupportedPreviewFormats(); + for (int i = 0; i < supportedPreviewFormats.size(); i++) { + Log.i(TAG, "Supported preview format: " + i); + } + // Set preview size List previewSizes = param.getSupportedPreviewSizes(); - mPreviewSize = previewSizes.get(0); + mPreviewSize = null; + + // Find the preview size that's the closest above or equal the requested size. + // We can not depend on the ordering of the incoming sizes. for (int i = 0; i < previewSizes.size(); i++) { - Log.d(TAG, "getSupportedPreviewSizes[" + i + "]: " + previewSizes.get(i).height + " " + previewSizes.get(i).width); - if (previewSizes.get(i).width <= 640 && previewSizes.get(i).height <= 480) { + int width = previewSizes.get(i).width; + int height = previewSizes.get(i).height; + Log.d(TAG, "getSupportedPreviewSizes[" + i + "]: " + width + "x" + height); + + // Reject too small preview sizes. + if (width < mTargetWidth || height < mTargetHeight) { + continue; + } + + if (mPreviewSize == null) { + Log.i(TAG, "Selected first viable preview size: " + width + "x" + height); + mPreviewSize = previewSizes.get(i); + } else if (width < mPreviewSize.width || height < mPreviewSize.height) { + // Only select the new size if it's smaller. + Log.i(TAG, "Selected better viable preview size: " + width + "x" + height); mPreviewSize = previewSizes.get(i); - break; } } + Log.d(TAG, "setPreviewSize(" + mPreviewSize.width + ", " + mPreviewSize.height + ")"); param.setPreviewSize(mPreviewSize.width, mPreviewSize.height); From 7bb524810d97c414994dd1de1cfc49ebdbf199ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jul 2020 01:33:27 +0200 Subject: [PATCH 191/848] Check that we actually got a preview size. --- android/src/org/ppsspp/ppsspp/CameraHelper.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/android/src/org/ppsspp/ppsspp/CameraHelper.java b/android/src/org/ppsspp/ppsspp/CameraHelper.java index f4b712d72f..642504f038 100644 --- a/android/src/org/ppsspp/ppsspp/CameraHelper.java +++ b/android/src/org/ppsspp/ppsspp/CameraHelper.java @@ -218,6 +218,10 @@ class CameraHelper { } } + if (mPreviewSize == null) { + throw new Exception("Couldn't find a viable preview size"); + } + Log.d(TAG, "setPreviewSize(" + mPreviewSize.width + ", " + mPreviewSize.height + ")"); param.setPreviewSize(mPreviewSize.width, mPreviewSize.height); @@ -239,7 +243,7 @@ class CameraHelper { mCamera.setPreviewCallback(mPreviewCallback); mCamera.startPreview(); mIsCameraRunning = true; - } catch (IOException e) { + } catch (Exception e) { Log.e(TAG, "Cannot start camera: " + e.toString()); } } From 3cc20e5550375763588485c395403707bf5add84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jul 2020 01:49:34 +0200 Subject: [PATCH 192/848] Sneak in some paranoia in InstallZipScreen.cpp (another one from #13057) --- UI/InstallZipScreen.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index 2a7bda7d1c..873ddaf0c5 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -81,6 +81,9 @@ void InstallZipScreen::CreateViews() { returnToHomebrew_ = false; } else { leftColumn->Add(new TextView(iz->T("Zip file does not contain PSP software"), ALIGN_LEFT, false, new AnchorLayoutParams(10, 10, NONE, NONE))); + doneView_ = nullptr; + progressBar_ = nullptr; + installChoice_ = nullptr; backChoice_ = rightColumnItems->Add(new Choice(di->T("Back"))); } @@ -99,7 +102,9 @@ bool InstallZipScreen::key(const KeyInput &key) { UI::EventReturn InstallZipScreen::OnInstall(UI::EventParams ¶ms) { if (g_GameManager.InstallGameOnThread(zipPath_, zipPath_, deleteZipFile_)) { installStarted_ = true; - installChoice_->SetEnabled(false); + if (installChoice_) { + installChoice_->SetEnabled(false); + } } return UI::EVENT_DONE; } From 4d47715e4133db91521e63f12a6c4a6a452a490f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 4 Jul 2020 21:17:59 -0700 Subject: [PATCH 193/848] http: Check cancel flag more often. Would be better to use non-blocking sockets, but this code is working, so not planning to rewrite it right now. --- ext/native/base/buffer.cpp | 31 ++++++++++++++++++++++++------- ext/native/base/buffer.h | 2 +- ext/native/net/http_client.cpp | 34 +++++++++++++++++++++++----------- ext/native/net/http_client.h | 6 +++--- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/ext/native/base/buffer.cpp b/ext/native/base/buffer.cpp index 68cc412dd3..2c28a09f7b 100644 --- a/ext/native/base/buffer.cpp +++ b/ext/native/base/buffer.cpp @@ -152,11 +152,22 @@ bool Buffer::FlushToFile(const char *filename) { return true; } -bool Buffer::FlushSocket(uintptr_t sock, double timeout) { +bool Buffer::FlushSocket(uintptr_t sock, double timeout, bool *cancelled) { + static constexpr float CANCEL_INTERVAL = 0.25f; for (size_t pos = 0, end = data_.size(); pos < end; ) { - if (timeout >= 0.0 && !fd_util::WaitUntilReady(sock, timeout, true)) { - ELOG("FlushSocket timed out"); - return false; + bool ready = false; + double leftTimeout = timeout; + while (!ready && (leftTimeout >= 0 || cancelled)) { + if (cancelled && *cancelled) + return false; + ready = fd_util::WaitUntilReady(sock, CANCEL_INTERVAL, true); + if (!ready && leftTimeout >= 0.0) { + leftTimeout -= CANCEL_INTERVAL; + if (leftTimeout < 0) { + ELOG("FlushSocket timed out"); + return false; + } + } } int sent = send(sock, &data_[pos], (int)(end - pos), MSG_NOSIGNAL); if (sent < 0) { @@ -199,6 +210,7 @@ bool Buffer::ReadAll(int fd, int hintSize) { } bool Buffer::ReadAllWithProgress(int fd, int knownSize, float *progress, bool *cancelled) { + static constexpr float CANCEL_INTERVAL = 0.25f; std::vector buf; if (knownSize >= 65536 * 16) { buf.resize(65536); @@ -210,8 +222,12 @@ bool Buffer::ReadAllWithProgress(int fd, int knownSize, float *progress, bool *c int total = 0; while (true) { - if (cancelled && *cancelled) - return false; + bool ready = false; + while (!ready && cancelled) { + if (*cancelled) + return false; + ready = fd_util::WaitUntilReady(fd, CANCEL_INTERVAL, false); + } int retval = recv(fd, &buf[0], (int)buf.size(), 0); if (retval == 0) { return true; @@ -222,7 +238,8 @@ bool Buffer::ReadAllWithProgress(int fd, int knownSize, float *progress, bool *c char *p = Append((size_t)retval); memcpy(p, &buf[0], retval); total += retval; - *progress = (float)total / (float)knownSize; + if (progress) + *progress = (float)total / (float)knownSize; } return true; } diff --git a/ext/native/base/buffer.h b/ext/native/base/buffer.h index b34901fb17..87018a3999 100644 --- a/ext/native/base/buffer.h +++ b/ext/native/base/buffer.h @@ -64,7 +64,7 @@ class Buffer { // written. bool Flush(int fd); bool FlushToFile(const char *filename); - bool FlushSocket(uintptr_t sock, double timeout = -1.0); // Windows portability + bool FlushSocket(uintptr_t sock, double timeout = -1.0, bool *cancelled = nullptr); // Windows portability bool ReadAll(int fd, int hintSize = 0); bool ReadAllWithProgress(int fd, int knownSize, float *progress, bool *cancelled); diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index ca2fb0f36c..29641aff77 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -229,13 +229,13 @@ int Client::GET(const char *resource, Buffer *output, std::vector & const char *otherHeaders = "Accept: */*\r\n" "Accept-Encoding: gzip\r\n"; - int err = SendRequest("GET", resource, otherHeaders, progress); + int err = SendRequest("GET", resource, otherHeaders, progress, cancelled); if (err < 0) { return err; } Buffer readbuf; - int code = ReadResponseHeaders(&readbuf, responseHeaders, progress); + int code = ReadResponseHeaders(&readbuf, responseHeaders, progress, cancelled); if (code < 0) { return code; } @@ -283,11 +283,11 @@ int Client::POST(const char *resource, const std::string &data, Buffer *output, return POST(resource, data, "", output, progress); } -int Client::SendRequest(const char *method, const char *resource, const char *otherHeaders, float *progress) { - return SendRequestWithData(method, resource, "", otherHeaders, progress); +int Client::SendRequest(const char *method, const char *resource, const char *otherHeaders, float *progress, bool *cancelled) { + return SendRequestWithData(method, resource, "", otherHeaders, progress, cancelled); } -int Client::SendRequestWithData(const char *method, const char *resource, const std::string &data, const char *otherHeaders, float *progress) { +int Client::SendRequestWithData(const char *method, const char *resource, const std::string &data, const char *otherHeaders, float *progress, bool *cancelled) { if (progress) { *progress = 0.01f; } @@ -314,12 +314,24 @@ int Client::SendRequestWithData(const char *method, const char *resource, const return 0; } -int Client::ReadResponseHeaders(Buffer *readbuf, std::vector &responseHeaders, float *progress) { +int Client::ReadResponseHeaders(Buffer *readbuf, std::vector &responseHeaders, float *progress, bool *cancelled) { // Snarf all the data we can into RAM. A little unsafe but hey. - if (dataTimeout_ >= 0.0 && !fd_util::WaitUntilReady(sock(), dataTimeout_, false)) { - ELOG("HTTP headers timed out"); - return -1; - } + static constexpr float CANCEL_INTERVAL = 0.25f; + bool ready = false; + double leftTimeout = dataTimeout_; + while (!ready) { + if (cancelled && *cancelled) + return -1; + ready = fd_util::WaitUntilReady(sock(), CANCEL_INTERVAL, false); + if (!ready && leftTimeout >= 0.0) { + leftTimeout -= CANCEL_INTERVAL; + if (leftTimeout < 0) { + ELOG("HTTP headers timed out"); + return -1; + } + } + }; + // Let's hope all the headers are available in a single packet... if (readbuf->Read(sock(), 4096) < 0) { ELOG("Failed to read HTTP headers :("); return -1; @@ -396,7 +408,7 @@ int Client::ReadResponseEntity(Buffer *readbuf, const std::vector & if (!contentLength || !progress) { // No way to know how far along we are. Let's just not update the progress counter. - if (!readbuf->ReadAll(sock(), contentLength)) + if (!readbuf->ReadAllWithProgress(sock(), contentLength, nullptr, cancelled)) return -1; } else { // Let's read in chunks, updating progress between each. diff --git a/ext/native/net/http_client.h b/ext/native/net/http_client.h index 694cad33ed..9c935858fa 100644 --- a/ext/native/net/http_client.h +++ b/ext/native/net/http_client.h @@ -71,9 +71,9 @@ public: // HEAD, PUT, DELETE aren't implemented yet, but can be done with SendRequest. - int SendRequest(const char *method, const char *resource, const char *otherHeaders = nullptr, float *progress = nullptr); - int SendRequestWithData(const char *method, const char *resource, const std::string &data, const char *otherHeaders = nullptr, float *progress = nullptr); - int ReadResponseHeaders(Buffer *readbuf, std::vector &responseHeaders, float *progress = nullptr); + int SendRequest(const char *method, const char *resource, const char *otherHeaders = nullptr, float *progress = nullptr, bool *cancelled = nullptr); + int SendRequestWithData(const char *method, const char *resource, const std::string &data, const char *otherHeaders = nullptr, float *progress = nullptr, bool *cancelled = nullptr); + int ReadResponseHeaders(Buffer *readbuf, std::vector &responseHeaders, float *progress = nullptr, bool *cancelled = nullptr); // If your response contains a response, you must read it. int ReadResponseEntity(Buffer *readbuf, const std::vector &responseHeaders, Buffer *output, float *progress = nullptr, bool *cancelled = nullptr); From 177d697a15fa27e35b4803e02b0dbc97a2862677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jul 2020 10:37:44 +0200 Subject: [PATCH 194/848] Revert "Remove the I/O on Thread option - treat it as always on." This reverts commit 9c40381db090285aa7848bfee93dca6c4a220b62. --- Core/Config.cpp | 1 + Core/Config.h | 1 + Core/HLE/sceIo.cpp | 18 ++++++++++++------ UI/GameSettingsScreen.cpp | 2 ++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 8af00b96ac..df3bf415dc 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -504,6 +504,7 @@ static bool DefaultSasThread() { static ConfigSetting cpuSettings[] = { ReportedConfigSetting("CPUCore", &g_Config.iCpuCore, &DefaultCpuCore, true, true), ReportedConfigSetting("SeparateSASThread", &g_Config.bSeparateSASThread, &DefaultSasThread, true, true), + ReportedConfigSetting("SeparateIOThread", &g_Config.bSeparateIOThread, true, true, true), ReportedConfigSetting("IOTimingMethod", &g_Config.iIOTimingMethod, IOTIMING_FAST, true, true), ConfigSetting("FastMemoryAccess", &g_Config.bFastMemory, true, true, true), ReportedConfigSetting("FuncReplacements", &g_Config.bFuncReplacements, true, true, true), diff --git a/Core/Config.h b/Core/Config.h index 084eacc942..2e5cea51c9 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -108,6 +108,7 @@ public: uint32_t uJitDisableFlags; bool bSeparateSASThread; + bool bSeparateIOThread; int iIOTimingMethod; int iLockedCPUSpeed; bool bAutoSaveSymbolMap; diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 9f3cf81f78..7865d4cea5 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -129,7 +129,7 @@ static MemStickFatState lastMemStickFatState; static AsyncIOManager ioManager; static bool ioManagerThreadEnabled = false; -static std::thread ioManagerThread; +static std::thread *ioManagerThread; // TODO: Is it better to just put all on the thread? // Let's try. (was 256) @@ -649,10 +649,12 @@ void __IoInit() { memset(fds, 0, sizeof(fds)); - ioManagerThreadEnabled = true; + ioManagerThreadEnabled = g_Config.bSeparateIOThread; ioManager.SetThreadEnabled(ioManagerThreadEnabled); - Core_ListenLifecycle(&__IoWakeManager); - ioManagerThread = std::thread(&__IoManagerThread); + if (ioManagerThreadEnabled) { + Core_ListenLifecycle(&__IoWakeManager); + ioManagerThread = new std::thread(&__IoManagerThread); + } __KernelRegisterWaitTypeFuncs(WAITTYPE_ASYNCIO, __IoAsyncBeginCallback, __IoAsyncEndCallback); @@ -733,8 +735,12 @@ void __IoShutdown() { ioManagerThreadEnabled = false; ioManager.SyncThread(); ioManager.FinishEventLoop(); - ioManagerThread.join(); - ioManager.Shutdown(); + if (ioManagerThread != nullptr) { + ioManagerThread->join(); + delete ioManagerThread; + ioManagerThread = nullptr; + ioManager.Shutdown(); + } for (int i = 0; i < PSP_COUNT_FDS; ++i) { asyncParams[i].op = IoAsyncOp::NONE; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 1a9ca4a977..9d824e28b3 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -771,8 +771,10 @@ void GameSettingsScreen::CreateViews() { systemSettings->Add(new CheckBox(&g_Config.bFastMemory, sy->T("Fast Memory", "Fast Memory (Unstable)")))->OnClick.Handle(this, &GameSettingsScreen::OnJitAffectingSetting); + systemSettings->Add(new CheckBox(&g_Config.bSeparateIOThread, sy->T("I/O on thread (experimental)")))->SetEnabled(!PSP_IsInited()); static const char *ioTimingMethods[] = { "Fast (lag on slow storage)", "Host (bugs, less lag)", "Simulate UMD delays" }; View *ioTimingMethod = systemSettings->Add(new PopupMultiChoice(&g_Config.iIOTimingMethod, sy->T("IO timing method"), ioTimingMethods, 0, ARRAY_SIZE(ioTimingMethods), sy->GetName(), screenManager())); + ioTimingMethod->SetEnabledPtr(&g_Config.bSeparateIOThread); systemSettings->Add(new CheckBox(&g_Config.bForceLagSync, sy->T("Force real clock sync (slower, less lag)"))); PopupSliderChoice *lockedMhz = systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, sy->T("Change CPU Clock", "Change CPU Clock (unstable)"), screenManager(), sy->T("MHz, 0:default"))); lockedMhz->OnChange.Add([&](UI::EventParams &) { From 7e5527285dbc87f058d67969da87b091807a5320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jul 2020 11:55:40 +0200 Subject: [PATCH 195/848] Screen: Unlock the inputLock_ mutex slightly earlier in processFinishDialog It's really just there to protect the stack. --- ext/native/ui/screen.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/ext/native/ui/screen.cpp b/ext/native/ui/screen.cpp index 958c1d70c3..3b99486d69 100644 --- a/ext/native/ui/screen.cpp +++ b/ext/native/ui/screen.cpp @@ -272,22 +272,24 @@ Screen *ScreenManager::dialogParent(const Screen *dialog) const { void ScreenManager::processFinishDialog() { if (dialogFinished_) { - std::lock_guard guard(inputLock_); - // Another dialog may have been pushed before the render, so search for it. - Screen *caller = dialogParent(dialogFinished_); - for (size_t i = 0; i < stack_.size(); ++i) { - if (stack_[i].screen == dialogFinished_) { - stack_.erase(stack_.begin() + i); + { + std::lock_guard guard(inputLock_); + // Another dialog may have been pushed before the render, so search for it. + Screen *caller = dialogParent(dialogFinished_); + for (size_t i = 0; i < stack_.size(); ++i) { + if (stack_[i].screen == dialogFinished_) { + stack_.erase(stack_.begin() + i); + } } - } - if (!caller) { - ELOG("ERROR: no top screen when finishing dialog"); - } else if (caller != topScreen()) { - // The caller may get confused if we call dialogFinished() now. - WLOG("Skipping non-top dialog when finishing dialog."); - } else { - caller->dialogFinished(dialogFinished_, dialogResult_); + if (!caller) { + ELOG("ERROR: no top screen when finishing dialog"); + } else if (caller != topScreen()) { + // The caller may get confused if we call dialogFinished() now. + WLOG("Skipping non-top dialog when finishing dialog."); + } else { + caller->dialogFinished(dialogFinished_, dialogResult_); + } } delete dialogFinished_; dialogFinished_ = nullptr; From 11e5f8653bfbb2ffe6fe7989f067ba173e7e1b29 Mon Sep 17 00:00:00 2001 From: iota97 Date: Sun, 5 Jul 2020 21:57:16 +0200 Subject: [PATCH 196/848] Link PR and issues in README --- README.md | 197 ++++++++++++++++++++++++++--------------------------- history.md | 81 +++++++++++----------- 2 files changed, 139 insertions(+), 139 deletions(-) diff --git a/README.md b/README.md index 428b5b1c91..6a9a37701f 100644 --- a/README.md +++ b/README.md @@ -25,50 +25,48 @@ If you want to download regularly updated builds for Android, Windows x86 and x6 For game compatibility, see [community compatibility feedback](https://report.ppsspp.org/games). -The #-numbers below are github issues, to see one go to https://github.com/hrydgard/ppsspp/issues/XXXXX where XXXXX is the number. - What's new in 1.10.1 -------------------- -* Fixes for common crashes (#13077, #13076, see #13057) -* Fix for offset rendering in D3D9 (#13071) +* Fixes for common crashes ([#13077](https://github.com/hrydgard/ppsspp/issues/13077), [#13076](https://github.com/hrydgard/ppsspp/issues/13076), see [#13057](https://github.com/hrydgard/ppsspp/issues/13057)) +* Fix for offset rendering in D3D9 ([#13071](https://github.com/hrydgard/ppsspp/issues/13071)) What's new in 1.10.0 -------------------- -* Graphics and compatibility fixes (#12800, #12670, #12635, #12857, #12941, #11898, #12695, more) -* Assorted minor performance improvements, game load speedup (#12462, #12652) -* Screen inset (notch) support on Android (#12779) -* Analog stick support for menu navigation (#12685) -* Fixed audio glitches in SDL builds (#12916, #12920) -* Support more languages in in-game dialogs (#12702). Croatian language added to PPSSPP. -* Simple multiplayer chat (#12667) -* More advanced postprocessing (multipass, parameters) (#12905, #12901) -* Add PPSSPP-specific CWCheat (#12816, #12912) -* Reintroduce Cardboard VR, allow more resolutions (#12449, #8714) -* Fix some crashes (#12908, #12876) -* Ghost in the Shell graphics fixed (JIT inaccuracy with inf*0) (#12519) -* Mac build now supports Vulkan on top of MoltenVK (#12583) -* Raspberry Pi 4 EGL crash fixed (#12474) -* VSync now supported on all backends, frame duplication option added for 30 Hz games (#12659, #12602) -* Camera supported on Windows, Linux and Mac (still no microphone though) (#12572, #12580, #12607) -* Darkstalkers fixed and working through software rendering. SW rendering fixed on GLES 2.0 (#12443, #12898) -* Hot Shots Golf slowdown and flicker on Vulkan fixed (#12873, #12746) -* Pangya Golf crashes and hangs fixed (#12718) -* Allow rebinding of right touch screen analog (#12486) -* Add option to prevent mipmaps from being dumped (#12818) -* Tilt control now have a base radius to help with deadzone (#12756) -* Mappable auto rotating analog stick to pass some game checks (#12749) -* Touch control position can now be snapped to a grid (#12517) -* HiDPI retina display support (#12552) -* Rapid-fire on touch control (#12601) -* Toggle mute button (#12643) -* Add option to resize game icons and more (#12646, #12637) -* Frames in-flight now configurable to reduce input lag at the cost of speed (#12660) -* Add toggle mode to combo button (#12623) -* SDL mouse support, Qt menu upgrades (#12612, #12817) -* Real support for chinese patched version of Hatsune Miku Project Diva Extend (#13007) -* Some minor kernel module support (#13028, #12225, #13026, #13004, #13038, #13023) -* Fixed fullscreen toggling with Vulkan in SDL builds (#11974) +* Graphics and compatibility fixes ([#12800](https://github.com/hrydgard/ppsspp/issues/12800), [#12670](https://github.com/hrydgard/ppsspp/issues/12670), [#12635](https://github.com/hrydgard/ppsspp/issues/12635), [#12857](https://github.com/hrydgard/ppsspp/issues/12857), [#12941](https://github.com/hrydgard/ppsspp/issues/12941), [#11898](https://github.com/hrydgard/ppsspp/issues/11898), [#12695](https://github.com/hrydgard/ppsspp/issues/12695), more) +* Assorted minor performance improvements, game load speedup ([#12462](https://github.com/hrydgard/ppsspp/issues/12462), [#12652](https://github.com/hrydgard/ppsspp/issues/12652)) +* Screen inset (notch) support on Android ([#12779](https://github.com/hrydgard/ppsspp/issues/12779)) +* Analog stick support for menu navigation ([#12685](https://github.com/hrydgard/ppsspp/issues/12685)) +* Fixed audio glitches in SDL builds ([#12916](https://github.com/hrydgard/ppsspp/issues/12916), [#12920](https://github.com/hrydgard/ppsspp/issues/12920)) +* Support more languages in in-game dialogs ([#12702](https://github.com/hrydgard/ppsspp/issues/12702)). Croatian language added to PPSSPP. +* Simple multiplayer chat ([#12667](https://github.com/hrydgard/ppsspp/issues/12667)) +* More advanced postprocessing (multipass, parameters) ([#12905](https://github.com/hrydgard/ppsspp/issues/12905), [#12901](https://github.com/hrydgard/ppsspp/issues/12901)) +* Add PPSSPP-specific CWCheat ([#12816](https://github.com/hrydgard/ppsspp/issues/12816), [#12912](https://github.com/hrydgard/ppsspp/issues/12912)) +* Reintroduce Cardboard VR, allow more resolutions ([#12449](https://github.com/hrydgard/ppsspp/issues/12449), [#8714](https://github.com/hrydgard/ppsspp/issues/8714)) +* Fix some crashes ([#12908](https://github.com/hrydgard/ppsspp/issues/12908), [#12876](https://github.com/hrydgard/ppsspp/issues/12876)) +* Ghost in the Shell graphics fixed (JIT inaccuracy with inf*0) ([#12519](https://github.com/hrydgard/ppsspp/issues/12519)) +* Mac build now supports Vulkan on top of MoltenVK ([#12583](https://github.com/hrydgard/ppsspp/issues/12583)) +* Raspberry Pi 4 EGL crash fixed ([#12474](https://github.com/hrydgard/ppsspp/issues/12474)) +* VSync now supported on all backends, frame duplication option added for 30 Hz games ([#12659](https://github.com/hrydgard/ppsspp/issues/12659), [#12602](https://github.com/hrydgard/ppsspp/issues/12602)) +* Camera supported on Windows, Linux and Mac (still no microphone though) ([#12572](https://github.com/hrydgard/ppsspp/issues/12572), [#12580](https://github.com/hrydgard/ppsspp/issues/12580), [#12607](https://github.com/hrydgard/ppsspp/issues/12607)) +* Darkstalkers fixed and working through software rendering. SW rendering fixed on GLES 2.0 ([#12443](https://github.com/hrydgard/ppsspp/issues/12443), [#12898](https://github.com/hrydgard/ppsspp/issues/12898)) +* Hot Shots Golf slowdown and flicker on Vulkan fixed ([#12873](https://github.com/hrydgard/ppsspp/issues/12873), [#12746](https://github.com/hrydgard/ppsspp/issues/12746)) +* Pangya Golf crashes and hangs fixed ([#12718](https://github.com/hrydgard/ppsspp/issues/12718)) +* Allow rebinding of right touch screen analog ([#12486](https://github.com/hrydgard/ppsspp/issues/12486)) +* Add option to prevent mipmaps from being dumped ([#12818](https://github.com/hrydgard/ppsspp/issues/12818)) +* Tilt control now have a base radius to help with deadzone ([#12756](https://github.com/hrydgard/ppsspp/issues/12756)) +* Mappable auto rotating analog stick to pass some game checks ([#12749](https://github.com/hrydgard/ppsspp/issues/12749)) +* Touch control position can now be snapped to a grid ([#12517](https://github.com/hrydgard/ppsspp/issues/12517)) +* HiDPI retina display support ([#12552](https://github.com/hrydgard/ppsspp/issues/12552)) +* Rapid-fire on touch control ([#12601](https://github.com/hrydgard/ppsspp/issues/12601)) +* Toggle mute button ([#12643](https://github.com/hrydgard/ppsspp/issues/12643)) +* Add option to resize game icons and more ([#12646](https://github.com/hrydgard/ppsspp/issues/12646), [#12637](https://github.com/hrydgard/ppsspp/issues/12637)) +* Frames in-flight now configurable to reduce input lag at the cost of speed ([#12660](https://github.com/hrydgard/ppsspp/issues/12660)) +* Add toggle mode to combo button ([#12623](https://github.com/hrydgard/ppsspp/issues/12623)) +* SDL mouse support, Qt menu upgrades ([#12612](https://github.com/hrydgard/ppsspp/issues/12612), [#12817](https://github.com/hrydgard/ppsspp/issues/12817)) +* Real support for chinese patched version of Hatsune Miku Project Diva Extend ([#13007](https://github.com/hrydgard/ppsspp/issues/13007)) +* Some minor kernel module support ([#13028](https://github.com/hrydgard/ppsspp/issues/13028), [#12225](https://github.com/hrydgard/ppsspp/issues/12225), [#13026](https://github.com/hrydgard/ppsspp/issues/13026), [#13004](https://github.com/hrydgard/ppsspp/issues/13004), [#13038](https://github.com/hrydgard/ppsspp/issues/13038), [#13023](https://github.com/hrydgard/ppsspp/issues/13023)) +* Fixed fullscreen toggling with Vulkan in SDL builds ([#11974](https://github.com/hrydgard/ppsspp/issues/11974)) What's new in 1.9.0/1.9.3 ------------------------- @@ -77,62 +75,62 @@ What's new in 1.9.0/1.9.3 What's new in 1.9.0/1.9.2 ------------------------- -* Flicker fixed in God of War that appeared with newer drivers for Mali GPUs (#12224) -* Improve performance of God of War on Vulkan (#12242), implement built-in GPU profiler (#12262, #12266) -* Vertex range culling fixed on ARM Mali (#12227) -* Started to improve VFPU precision, resulting so far in a fix for the long standing Tekken 6 leg shaking problem (#12217) -* Fixed a VFPU precision snafu on ARM64, fixing disappearing officers in Warriors Orochi (#11299) and some problems in Tomb Raider (#11179). +* Flicker fixed in God of War that appeared with newer drivers for Mali GPUs ([#12224](https://github.com/hrydgard/ppsspp/issues/12224)) +* Improve performance of God of War on Vulkan ([#12242](https://github.com/hrydgard/ppsspp/issues/12242)), implement built-in GPU profiler ([#12262](https://github.com/hrydgard/ppsspp/issues/12262), [#12266](https://github.com/hrydgard/ppsspp/issues/12266)) +* Vertex range culling fixed on ARM Mali ([#12227](https://github.com/hrydgard/ppsspp/issues/12227)) +* Started to improve VFPU precision, resulting so far in a fix for the long standing Tekken 6 leg shaking problem ([#12217](https://github.com/hrydgard/ppsspp/issues/12217)) +* Fixed a VFPU precision snafu on ARM64, fixing disappearing officers in Warriors Orochi ([#11299](https://github.com/hrydgard/ppsspp/issues/11299)) and some problems in Tomb Raider ([#11179](https://github.com/hrydgard/ppsspp/issues/11179)). * Vulkan is the default again on Android versions newer than Pie * Fix various homebrew store issues -* GPU pause signal handling fixed, fixing some hangs in Bleach and Armored Core games (#12160) -* Audio sample rate conversion handling fixes (#12147) -* Some Vulkan optimizations (pre-rotation (#12216), perf fix in Metal Gear Acid, etc) -* Multiple fixes for the UWP build (#12036, others) -* MP3 playback fixes (#12005) -* Audio in Motorstorm: Arctic Edge fixed by returning errors correctly (#12121) -* Audio glitches in Final Fantasy Tactics fixed (#9956) -* Camera display in Invizimals fixed (#12278, #8521) -* Added hotkeys for texture dump and replace (#11938) -* Added Visual Studio 2019 support. Windows XP is no longer supported (#11995, others) -* Fixes for video capture (#12069) -* Added a separate sound volume for alternative speed (#12124) -* Improved mouse control (Windows only) (#12173, #12176) -* Support for installing texture packs and ISOs from zips (#12175) -* Right analog support for touch controls (only used by patched games and some HD remasters) (#12182) -* Android: Fix OpenSL initialization, possibly helps audio crackle a little. (#12333). +* GPU pause signal handling fixed, fixing some hangs in Bleach and Armored Core games ([#12160](https://github.com/hrydgard/ppsspp/issues/12160)) +* Audio sample rate conversion handling fixes ([#12147](https://github.com/hrydgard/ppsspp/issues/12147)) +* Some Vulkan optimizations (pre-rotation ([#12216](https://github.com/hrydgard/ppsspp/issues/12216)), perf fix in Metal Gear Acid, etc) +* Multiple fixes for the UWP build ([#12036](https://github.com/hrydgard/ppsspp/issues/12036), others) +* MP3 playback fixes ([#12005](https://github.com/hrydgard/ppsspp/issues/12005)) +* Audio in Motorstorm: Arctic Edge fixed by returning errors correctly ([#12121](https://github.com/hrydgard/ppsspp/issues/12121)) +* Audio glitches in Final Fantasy Tactics fixed ([#9956](https://github.com/hrydgard/ppsspp/issues/9956)) +* Camera display in Invizimals fixed ([#12278](https://github.com/hrydgard/ppsspp/issues/12278), [#8521](https://github.com/hrydgard/ppsspp/issues/8521)) +* Added hotkeys for texture dump and replace ([#11938](https://github.com/hrydgard/ppsspp/issues/11938)) +* Added Visual Studio 2019 support. Windows XP is no longer supported ([#11995](https://github.com/hrydgard/ppsspp/issues/11995), others) +* Fixes for video capture ([#12069](https://github.com/hrydgard/ppsspp/issues/12069)) +* Added a separate sound volume for alternative speed ([#12124](https://github.com/hrydgard/ppsspp/issues/12124)) +* Improved mouse control (Windows only) ([#12173](https://github.com/hrydgard/ppsspp/issues/12173), [#12176](https://github.com/hrydgard/ppsspp/issues/12176)) +* Support for installing texture packs and ISOs from zips ([#12175](https://github.com/hrydgard/ppsspp/issues/12175)) +* Right analog support for touch controls (only used by patched games and some HD remasters) ([#12182](https://github.com/hrydgard/ppsspp/issues/12182)) +* Android: Fix OpenSL initialization, possibly helps audio crackle a little. ([#12333](https://github.com/hrydgard/ppsspp/issues/12333)). * Fix graphics on Amazon Fire TV Stick 4K -* Fixed strange vehicle behavior in MGS:PW (somehow) (#12342) +* Fixed strange vehicle behavior in MGS:PW (somehow) ([#12342](https://github.com/hrydgard/ppsspp/issues/12342)) 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) -* 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) -* 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) +* Avoid crash when starting PPSSPP due to bad AMD Vulkan drivers ([#11802](https://github.com/hrydgard/ppsspp/issues/11802)) +* PowerVR Vulkan display corruption fixed ([#11744](https://github.com/hrydgard/ppsspp/issues/11744), [#11747](https://github.com/hrydgard/ppsspp/issues/11747)) +* Naruto Shippuden 3 hang fixed ([#11780](https://github.com/hrydgard/ppsspp/issues/11780)) +* Fixes to various lighting bugs ([#11567](https://github.com/hrydgard/ppsspp/issues/11567), [#11574](https://github.com/hrydgard/ppsspp/issues/11574), [#11577](https://github.com/hrydgard/ppsspp/issues/11577)) +* Fix control issue in Sonic Rivals and Rock Band ([#11878](https://github.com/hrydgard/ppsspp/issues/11878), [#11798](https://github.com/hrydgard/ppsspp/issues/11798), [#11879](https://github.com/hrydgard/ppsspp/issues/11879)) +* Significant performance improvement in Earth Defense Force 2 ([#11172](https://github.com/hrydgard/ppsspp/issues/11172)) +* Fix "real clock sync" setting (helps with latency for music games - [#11813](https://github.com/hrydgard/ppsspp/issues/11813)) +* More speed in FF4 effects and other generated curves ([#11425](https://github.com/hrydgard/ppsspp/issues/11425)) +* Support for resizing Vulkan on Linux ([#11451](https://github.com/hrydgard/ppsspp/issues/11451)) +* Improved support for GLES on Linux/IoT ([#11507](https://github.com/hrydgard/ppsspp/issues/11507), [#11537](https://github.com/hrydgard/ppsspp/issues/11537), [#11541](https://github.com/hrydgard/ppsspp/issues/11541), [#11632](https://github.com/hrydgard/ppsspp/issues/11632), [#11746](https://github.com/hrydgard/ppsspp/issues/11746), [#11806](https://github.com/hrydgard/ppsspp/issues/11806), [#11845](https://github.com/hrydgard/ppsspp/issues/11845)) +* Percentage based frameskipping ([#11523](https://github.com/hrydgard/ppsspp/issues/11523)) +* DXT accuracy improved, fixing thick white line in Gran Turismo sky ([#11530](https://github.com/hrydgard/ppsspp/issues/11530)) +* Fix Motorstorm freeze on non-Windows ([#11618](https://github.com/hrydgard/ppsspp/issues/11618)) +* Faster block transfer in some games like Digimon Adventures ([#11531](https://github.com/hrydgard/ppsspp/issues/11531), [#11553](https://github.com/hrydgard/ppsspp/issues/11553), [#11776](https://github.com/hrydgard/ppsspp/issues/11776)) +* Blending optimizations and improvements ([#11543](https://github.com/hrydgard/ppsspp/issues/11543), [#11620](https://github.com/hrydgard/ppsspp/issues/11620)) +* Improve D3D11 rendering issues ([#11584](https://github.com/hrydgard/ppsspp/issues/11584)) +* Change default graphics backend to D3D11 or OpenGL ([#11621](https://github.com/hrydgard/ppsspp/issues/11621), [#11658](https://github.com/hrydgard/ppsspp/issues/11658)) +* Remove some outdated settings ([#11665](https://github.com/hrydgard/ppsspp/issues/11665), [#11666](https://github.com/hrydgard/ppsspp/issues/11666), [#11667](https://github.com/hrydgard/ppsspp/issues/11667)) +* Fix remote disc streaming with ipv6 ([#11689](https://github.com/hrydgard/ppsspp/issues/11689), [#11700](https://github.com/hrydgard/ppsspp/issues/11700)) +* Vulkan: Workarounds for some driver bugs for 5xx series Qualcomm GPUs ([#11691](https://github.com/hrydgard/ppsspp/issues/11691), [#11694](https://github.com/hrydgard/ppsspp/issues/11694)) +* Fix some Qt port issues with recent performance improvements ([#11720](https://github.com/hrydgard/ppsspp/issues/11720), [#11807](https://github.com/hrydgard/ppsspp/issues/11807), [#11808](https://github.com/hrydgard/ppsspp/issues/11808)) +* UWP Xbox One: fix X/Back button confusion ([#11740](https://github.com/hrydgard/ppsspp/issues/11740)) +* Fix Formula 1 2006 timing issue ([#11767](https://github.com/hrydgard/ppsspp/issues/11767)) +* Fixes and workarounds for some vertex range culling bugs that broke a few games ([#11785](https://github.com/hrydgard/ppsspp/issues/11785), [#11859](https://github.com/hrydgard/ppsspp/issues/11859)), and disable it on older GPUs ([#11712](https://github.com/hrydgard/ppsspp/issues/11712), [#11773](https://github.com/hrydgard/ppsspp/issues/11773), [#11787](https://github.com/hrydgard/ppsspp/issues/11787)) +* Android: Allow putting PSP storage on custom paths like SD cards ([#11812](https://github.com/hrydgard/ppsspp/issues/11812)) +* Corrected vocp instruction, fixing models in Artdink games ([#11822](https://github.com/hrydgard/ppsspp/issues/11822), [#11835](https://github.com/hrydgard/ppsspp/issues/11835)) +* Bundle SDL in binary for macOS builds ([#11831](https://github.com/hrydgard/ppsspp/issues/11831)) +* Prevent keeping games open on Windows ([#11842](https://github.com/hrydgard/ppsspp/issues/11842)) What's new in 1.7.3/1.7.4/1.7.5 ------------------- @@ -147,20 +145,20 @@ What's new in 1.7.2 What's new in 1.7.1 ------------------- * Minor crashfixes, lang updates -* Save bug fixed (#11508) +* Save bug fixed ([#11508](https://github.com/hrydgard/ppsspp/issues/11508)) What's new in 1.7.0 ------------------- -* Fix for insta-crash on Galaxy Note 9, some Xiaomi devices, and the new nVidia Shield (#11441) -* Vertex range culling on most platforms, fixes DTM: Race Driver and similar (#11393) -* Major speed boost in some Gundam and Earth Defense Force games (#10973) -* Fix for issues with post processing shaders in GL 3+ (#11182) -* Fixes to sound output switching on Windows (WASAPI) (#11438) -* Detects DirectInput devices when running (#11461) -* Simple Discord integration (#11307) -* New debugging APIs (#10909) -* Task switching made a lot more robust (fixes GPD XD problems) (#11447) -* Texture decoding optimizations (#11350) +* Fix for insta-crash on Galaxy Note 9, some Xiaomi devices, and the new nVidia Shield ([#11441](https://github.com/hrydgard/ppsspp/issues/11441)) +* Vertex range culling on most platforms, fixes DTM: Race Driver and similar ([#11393](https://github.com/hrydgard/ppsspp/issues/11393)) +* Major speed boost in some Gundam and Earth Defense Force games ([#10973](https://github.com/hrydgard/ppsspp/issues/10973)) +* Fix for issues with post processing shaders in GL 3+ ([#11182](https://github.com/hrydgard/ppsspp/issues/11182)) +* Fixes to sound output switching on Windows (WASAPI) ([#11438](https://github.com/hrydgard/ppsspp/issues/11438)) +* Detects DirectInput devices when running ([#11461](https://github.com/hrydgard/ppsspp/issues/11461)) +* Simple Discord integration ([#11307](https://github.com/hrydgard/ppsspp/issues/11307)) +* New debugging APIs ([#10909](https://github.com/hrydgard/ppsspp/issues/10909)) +* Task switching made a lot more robust (fixes GPD XD problems) ([#11447](https://github.com/hrydgard/ppsspp/issues/11447)) +* Texture decoding optimizations ([#11350](https://github.com/hrydgard/ppsspp/issues/11350)) * Tons and tons of miscellaneous bugfixes and compatibility fixes Looking for [older news](history.md)? @@ -174,3 +172,4 @@ Credit goes to: - Igor Calabria - [coldbird's code](https://code.google.com/archive/p/aemu/) - Kyhel + diff --git a/history.md b/history.md index e8a6cb48d1..33e74ce4c2 100644 --- a/history.md +++ b/history.md @@ -14,16 +14,16 @@ What's new in 1.6.1, 1.6.2 What's new in 1.6.0 ------------------- * OpenGL backend now properly multithreaded, giving a good speed boost. -* Various Vulkan performance improvements (like #10911) and memory allocation fixes. -* GPU command interpreter performance improvements (#10658) -* Various fixes for app switching and widgets (#10855) on Android +* Various Vulkan performance improvements (like [#10911](https://github.com/hrydgard/ppsspp/issues/10911)) and memory allocation fixes. +* GPU command interpreter performance improvements ([#10658](https://github.com/hrydgard/ppsspp/issues/10658)) +* Various fixes for app switching and widgets ([#10855](https://github.com/hrydgard/ppsspp/issues/10855)) on Android * Bugfixes and some performance improvements in the ARM64 JIT compiler and IR interpreter * Shader cache enabled for Vulkan -* Multiple iOS fixes, including JIT (#10465) and file browser (#10921). -* Improved compatibility on Mac (#10113) +* Multiple iOS fixes, including JIT ([#10465](https://github.com/hrydgard/ppsspp/issues/10465)) and file browser ([#10921](https://github.com/hrydgard/ppsspp/issues/10921)). +* Improved compatibility on Mac ([#10113](https://github.com/hrydgard/ppsspp/issues/10113)) * Texture replacement ID bugfix (note: some textures from 1.5.4 may become incompatible) -* Adhoc multiplayer fixes (#8975) -* Vulkan support on Linux/SDL (#10413) +* Adhoc multiplayer fixes ([#8975](https://github.com/hrydgard/ppsspp/issues/8975)) +* Vulkan support on Linux/SDL ([#10413](https://github.com/hrydgard/ppsspp/issues/10413)) * Retroarch support What's new in 1.5.4 @@ -32,18 +32,18 @@ What's new in 1.5.4 What's new in 1.5.0 ------------------- -* Full Vulkan support, also for Android now. Very fast on supported devices. (#10033, #10049) -* Smarter graphics state management, reduced CPU consumption on all backends (#9899) +* Full Vulkan support, also for Android now. Very fast on supported devices. ([#10033](https://github.com/hrydgard/ppsspp/issues/10033), [#10049](https://github.com/hrydgard/ppsspp/issues/10049)) +* Smarter graphics state management, reduced CPU consumption on all backends ([#9899](https://github.com/hrydgard/ppsspp/issues/9899)) * Android: Support for Arabic and other scripts we couldn't support before -* Fix Android widgets, screen scaling (#10145) +* Fix Android widgets, screen scaling ([#10145](https://github.com/hrydgard/ppsspp/issues/10145)) * Fixes to video dumping * Geometry problems fixed in Medal of Honor -* Implement immediate draws, fixing Thrillville (#7459) +* Implement immediate draws, fixing Thrillville ([#7459](https://github.com/hrydgard/ppsspp/issues/7459)) * Software rendering improvements, speed and accuracy * Hardware tesselation of PSP Beziers and Splines (used by a few games) * Partial sceUsbGps and sceUsbCam support (Android) -* Android "Sustained performance mode" to avoid thermal throttling (#9901) -* Linux controller mapping fixes (#9997) +* Android "Sustained performance mode" to avoid thermal throttling ([#9901](https://github.com/hrydgard/ppsspp/issues/9901)) +* Linux controller mapping fixes ([#9997](https://github.com/hrydgard/ppsspp/issues/9997)) * Assorted bugfixes and compatibility improvements What's new in 1.4.2 @@ -55,15 +55,15 @@ What's new in 1.4.2 What's new in 1.4.1 ------------------- -* Fixes for some common hangs and crashes (#9698, ...) -* Vertex decoder optimizations (#9674) -* Corrections to mipmap bias and selection function (#9633) -* Major improvements and fixes to software renderer, including mipmap support (#9635, ...) +* Fixes for some common hangs and crashes ([#9698](https://github.com/hrydgard/ppsspp/issues/9698), ...) +* Vertex decoder optimizations ([#9674](https://github.com/hrydgard/ppsspp/issues/9674)) +* Corrections to mipmap bias and selection function ([#9633](https://github.com/hrydgard/ppsspp/issues/9633)) +* Major improvements and fixes to software renderer, including mipmap support ([#9635](https://github.com/hrydgard/ppsspp/issues/9635), ...) * UI background image support * Basic mouse input support on Windows -* Windows desktop touch fixes (#9560) +* Windows desktop touch fixes ([#9560](https://github.com/hrydgard/ppsspp/issues/9560)) * D3D11 "depal" color fixes, fixing Sonic Rivals -* Fix crash in framebuffer blits affecting Persona 3 (#9566) +* Fix crash in framebuffer blits affecting Persona 3 ([#9566](https://github.com/hrydgard/ppsspp/issues/9566)) What's new in 1.4-2 ------------------- @@ -72,12 +72,12 @@ What's new in 1.4-2 What's new in 1.4 ----------------- * Support D3D11 (performs better than OpenGL or D3D9 on most hardware) -* Audio quality improvement (linear interpolation) (#8950) +* Audio quality improvement (linear interpolation) ([#8950](https://github.com/hrydgard/ppsspp/issues/8950)) * Hardware spline/bezier tesselation in OpenGL, D3D11 and Vulkan (...) * Post-processing shaders in D3D11 -* Prescale UV setting removed, now the default (improves perf) (#9176) +* Prescale UV setting removed, now the default (improves perf) ([#9176](https://github.com/hrydgard/ppsspp/issues/9176)) * High DPI display fixes -* Various fixes for UMD switching for multi-UMD games (#9245, #9256) +* Various fixes for UMD switching for multi-UMD games ([#9245](https://github.com/hrydgard/ppsspp/issues/9245), [#9256](https://github.com/hrydgard/ppsspp/issues/9256)) * New audio setting to improve compatibility with Bluetooth headsets * Various desktop gamepad compatibility fixes * Workaround for mipmap issue, fixing fonts in Tactics Ogre Japanese @@ -87,25 +87,25 @@ Support for Symbian, Maemo and Blackberry has been removed. What's new in 1.3.0 ------------------- -* Fix JIT problems on Galaxy S7 and iOS 9+ devices. (#8965, #8937) -* Fix Android TV support and use latest FFmpeg. (#8651, #8870) -* Texture replacement support - for custom textures and upscaling. (#8715, #8821) -* Initial game recording / TAS features. (#8939, #8945) -* Correctly map memory on Raspberry Pi 3, much better performance. (#8801) +* Fix JIT problems on Galaxy S7 and iOS 9+ devices. ([#8965](https://github.com/hrydgard/ppsspp/issues/8965), [#8937](https://github.com/hrydgard/ppsspp/issues/8937)) +* Fix Android TV support and use latest FFmpeg. ([#8651](https://github.com/hrydgard/ppsspp/issues/8651), [#8870](https://github.com/hrydgard/ppsspp/issues/8870)) +* Texture replacement support - for custom textures and upscaling. ([#8715](https://github.com/hrydgard/ppsspp/issues/8715), [#8821](https://github.com/hrydgard/ppsspp/issues/8821)) +* Initial game recording / TAS features. ([#8939](https://github.com/hrydgard/ppsspp/issues/8939), [#8945](https://github.com/hrydgard/ppsspp/issues/8945)) +* Correctly map memory on Raspberry Pi 3, much better performance. ([#8801](https://github.com/hrydgard/ppsspp/issues/8801)) * Workaround rendering issues on Tegra K1/X1. (8294a54) -* Disc streaming to play quickly from tablet/phone on wifi. (#8845) -* Initial Vulkan support - not full featured yet. (#8601, etc.) -* Experimental new CPU backend and CPU fixes. (#8725) -* Allow insert/eject of memstick - required by some games. (#8889) -* Better support for ps3 controller mapping. (#8949) -* Better UI handling for settings with long names in some languages. (#8900, #8898) -* Screenshots in compatibility reporting, better website. (#8812) -* Fix type D cheat codes, allow for homebrew. (#8818) -* Graphic glitch fixes in several games. (#8686, #8757, #8804) -* Fix video playback glitches in several games. (#8793, #8803, #8867, #8914) -* Various performance and compatibility improvements. (#8868, #8884, #8932, #8934, #8813, #8701, #8960) -* Various debugger and GE debugger improvements. (#8882, #8762) -* Fix some problems when switching away from and back to the app (#8968) +* Disc streaming to play quickly from tablet/phone on wifi. ([#8845](https://github.com/hrydgard/ppsspp/issues/8845)) +* Initial Vulkan support - not full featured yet. ([#8601](https://github.com/hrydgard/ppsspp/issues/8601), etc.) +* Experimental new CPU backend and CPU fixes. ([#8725](https://github.com/hrydgard/ppsspp/issues/8725)) +* Allow insert/eject of memstick - required by some games. ([#8889](https://github.com/hrydgard/ppsspp/issues/8889)) +* Better support for ps3 controller mapping. ([#8949](https://github.com/hrydgard/ppsspp/issues/8949)) +* Better UI handling for settings with long names in some languages. ([#8900](https://github.com/hrydgard/ppsspp/issues/8900), [#8898](https://github.com/hrydgard/ppsspp/issues/8898)) +* Screenshots in compatibility reporting, better website. ([#8812](https://github.com/hrydgard/ppsspp/issues/8812)) +* Fix type D cheat codes, allow for homebrew. ([#8818](https://github.com/hrydgard/ppsspp/issues/8818)) +* Graphic glitch fixes in several games. ([#8686](https://github.com/hrydgard/ppsspp/issues/8686), [#8757](https://github.com/hrydgard/ppsspp/issues/8757), [#8804](https://github.com/hrydgard/ppsspp/issues/8804)) +* Fix video playback glitches in several games. ([#8793](https://github.com/hrydgard/ppsspp/issues/8793), [#8803](https://github.com/hrydgard/ppsspp/issues/8803), [#8867](https://github.com/hrydgard/ppsspp/issues/8867), [#8914](https://github.com/hrydgard/ppsspp/issues/8914)) +* Various performance and compatibility improvements. ([#8868](https://github.com/hrydgard/ppsspp/issues/8868), [#8884](https://github.com/hrydgard/ppsspp/issues/8884), [#8932](https://github.com/hrydgard/ppsspp/issues/8932), [#8934](https://github.com/hrydgard/ppsspp/issues/8934), [#8813](https://github.com/hrydgard/ppsspp/issues/8813), [#8701](https://github.com/hrydgard/ppsspp/issues/8701), [#8960](https://github.com/hrydgard/ppsspp/issues/8960)) +* Various debugger and GE debugger improvements. ([#8882](https://github.com/hrydgard/ppsspp/issues/8882), [#8762](https://github.com/hrydgard/ppsspp/issues/8762)) +* Fix some problems when switching away from and back to the app ([#8968](https://github.com/hrydgard/ppsspp/issues/8968)) What's new in 1.2.2 ------------------- @@ -319,3 +319,4 @@ Update (Kyhel) : go to see there http://forums.ppsspp.org/showthread.php?tid=3595&pid=59241#pid59241 * Got it tested windows <-> mac osx <-> psp, it works * Monster Hunter 3rd HD works too, as well as God Eater Burst. + From 036191cf34f3c544a7d60f22c6641f808b634862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jul 2020 22:24:18 +0200 Subject: [PATCH 197/848] Remove unnecessary logging of preview formats See comment in #13094 --- android/src/org/ppsspp/ppsspp/CameraHelper.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/android/src/org/ppsspp/ppsspp/CameraHelper.java b/android/src/org/ppsspp/ppsspp/CameraHelper.java index 9236672a4d..d324d50819 100644 --- a/android/src/org/ppsspp/ppsspp/CameraHelper.java +++ b/android/src/org/ppsspp/ppsspp/CameraHelper.java @@ -191,11 +191,6 @@ class CameraHelper { mCamera = Camera.open(cameraId); Camera.Parameters param = mCamera.getParameters(); - List supportedPreviewFormats = param.getSupportedPreviewFormats(); - for (int i = 0; i < supportedPreviewFormats.size(); i++) { - Log.i(TAG, "Supported preview format: " + i); - } - // Set preview size List previewSizes = param.getSupportedPreviewSizes(); mPreviewSize = null; From 73046239e3af8541a1a84a095a4ccafbdf5392fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jul 2020 22:46:04 +0200 Subject: [PATCH 198/848] Android: Add option to ignore camera notches when sizing the display. This is generally what you want, at least on phones with small notches. Not sure about the most intuitive polarity and name of the setting.. bit of a shame to create another setting with a negation. But most people should probably ignore this. --- Core/Config.cpp | 1 + Core/Config.h | 1 + GPU/Common/FramebufferCommon.cpp | 2 +- GPU/Common/GPUStateUtils.cpp | 2 +- GPU/Common/PresentationCommon.cpp | 30 +++++++++++++++++------------- GPU/Common/PresentationCommon.h | 2 +- UI/GameSettingsScreen.cpp | 11 ++++++++++- 7 files changed, 32 insertions(+), 17 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index df3bf415dc..9ff2635200 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -758,6 +758,7 @@ static ConfigSetting graphicsSettings[] = { ConfigSetting("SmallDisplayZoomLevel", &g_Config.fSmallDisplayZoomLevel, 1.0f, true, true), ConfigSetting("ImmersiveMode", &g_Config.bImmersiveMode, false, true, true), ConfigSetting("SustainedPerformanceMode", &g_Config.bSustainedPerformanceMode, false, true, true), + ConfigSetting("IgnoreScreenInsets", &g_Config.bIgnoreScreenInsets, true, true, false), ReportedConfigSetting("ReplaceTextures", &g_Config.bReplaceTextures, true, true, true), ReportedConfigSetting("SaveNewTextures", &g_Config.bSaveNewTextures, false, true, true), diff --git a/Core/Config.h b/Core/Config.h index 2e5cea51c9..c4ba00d2b1 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -156,6 +156,7 @@ public: float fSmallDisplayZoomLevel; //This is used for zoom values, both in and out. bool bImmersiveMode; // Mode on Android Kitkat 4.4 that hides the back button etc. bool bSustainedPerformanceMode; // Android: Slows clocks down to avoid overheating/speed fluctuations. + bool bIgnoreScreenInsets; // Android: Center screen disregarding insets if this is enabled. bool bVSync; int iFrameSkip; int iFrameSkipType; diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index b6578a4737..98a7bbd9e3 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -661,7 +661,7 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int std::swap(v0, v1); flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST; flags = flags | DRAWTEX_TO_BACKBUFFER; - FRect frame = GetInsetScreenFrame(pixelWidth_, pixelHeight_); + FRect frame = GetScreenFrame(pixelWidth_, pixelHeight_); FRect rc; CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, ROTATION_LOCKED_HORIZONTAL); SetViewport2D(rc.x, rc.y, rc.w, rc.h); diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index dc29213429..5406f9d360 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -557,7 +557,7 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo } else { float pixelW = PSP_CoreParameter().pixelWidth; float pixelH = PSP_CoreParameter().pixelHeight; - FRect frame = GetInsetScreenFrame(pixelW, pixelH); + FRect frame = GetScreenFrame(pixelW, pixelH); FRect rc; CenterDisplayOutputRect(&rc, 480, 272, frame, ROTATION_LOCKED_HORIZONTAL); displayOffsetX = rc.x; diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index b88cc1affe..4432568b7d 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -41,7 +41,7 @@ struct Vertex { uint32_t rgba; }; -FRect GetInsetScreenFrame(float pixelWidth, float pixelHeight) { +FRect GetScreenFrame(float pixelWidth, float pixelHeight) { FRect rc = FRect{ 0.0f, 0.0f, @@ -49,17 +49,21 @@ FRect GetInsetScreenFrame(float pixelWidth, float pixelHeight) { pixelHeight, }; - // Remove the DPI scale to get back to pixels. - float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT) / g_dpi_scale_x; - float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT) / g_dpi_scale_x; - float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP) / g_dpi_scale_y; - float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM) / g_dpi_scale_y; + bool applyInset = !g_Config.bIgnoreScreenInsets; - // Adjust left edge to compensate for cutouts (notches) if any. - rc.x += left; - rc.w -= (left + right); - rc.y += top; - rc.h -= (top + bottom); + if (applyInset) { + // Remove the DPI scale to get back to pixels. + float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT) / g_dpi_scale_x; + float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT) / g_dpi_scale_x; + float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP) / g_dpi_scale_y; + float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM) / g_dpi_scale_y; + + // Adjust left edge to compensate for cutouts (notches) if any. + rc.x += left; + rc.w -= (left + right); + rc.y += top; + rc.h -= (top + bottom); + } return rc; } @@ -281,7 +285,7 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha } else if (shaderInfo->outputResolution) { // If the current shader uses output res (not next), we will use output res for it. FRect rc; - FRect frame = GetInsetScreenFrame((float)pixelWidth_, (float)pixelHeight_); + FRect frame = GetScreenFrame((float)pixelWidth_, (float)pixelHeight_); CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, g_Config.iInternalScreenRotation); nextWidth = (int)rc.w; nextHeight = (int)rc.h; @@ -528,7 +532,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u int lastHeight = srcHeight_; // These are the output coordinates. - FRect frame = GetInsetScreenFrame((float)pixelWidth_, (float)pixelHeight_); + FRect frame = GetScreenFrame((float)pixelWidth_, (float)pixelHeight_); FRect rc; CenterDisplayOutputRect(&rc, 480.0f, 272.0f, frame, uvRotation); diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index 502ef318e9..30395ab161 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -45,7 +45,7 @@ struct FRect { float h; }; -FRect GetInsetScreenFrame(float pixelWidth, float pixelHeight); +FRect GetScreenFrame(float pixelWidth, float pixelHeight); void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &frame, int rotation); namespace Draw { diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 9d824e28b3..62a70b67a4 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -313,7 +313,16 @@ void GameSettingsScreen::CreateViews() { displayEditor_ = graphicsSettings->Add(new Choice(gr->T("Display layout editor"))); displayEditor_->OnClick.Handle(this, &GameSettingsScreen::OnDisplayLayoutEditor); -#ifdef __ANDROID__ +#if PPSSPP_PLATFORM(ANDROID) + // Hide insets option if no insets, or OS too old. + if (System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 29 && + (System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT) != 0.0f || + System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP) != 0.0f || + System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT) != 0.0f || + System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM) != 0.0f)) { + graphicsSettings->Add(new CheckBox(&g_Config.bIgnoreScreenInsets, gr->T("Ignore camera inset when centering"))); + } + // Hide Immersive Mode on pre-kitkat Android if (System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 19) { // Let's reuse the Fullscreen translation string from desktop. From c76a72ba9339a6b96770bc5f42acab996baa9e7d Mon Sep 17 00:00:00 2001 From: iota97 Date: Mon, 6 Jul 2020 12:02:10 +0200 Subject: [PATCH 199/848] Add automated script for link on readme --- link_readme.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 link_readme.py diff --git a/link_readme.py b/link_readme.py new file mode 100755 index 0000000000..c2e8a998f6 --- /dev/null +++ b/link_readme.py @@ -0,0 +1,10 @@ +#!/bin/python + +import re +f = open("README.md", "r+") +cont = f.read() +updated = re.sub(r"([^[])#(\d+)", r"\1[#\2](https://github.com/hrydgard/ppsspp/issues/\2)", cont) +f.seek(0) +f.write(updated) +f.truncate() +f.close() From 893d26b67907c311cd50fd57547d40a480f7024a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 6 Jul 2020 21:21:54 +0200 Subject: [PATCH 200/848] Add some paranoid checks in AfterMatchingMipsCall::run(). Might work around a crash in #13057 --- Core/HLE/proAdhoc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index e5e7d278fb..17e675e175 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -912,7 +912,9 @@ bool IsMatchingInCallback(SceNetAdhocMatchingContext * context) { } void AfterMatchingMipsCall::run(MipsCall &call) { - if (context == NULL) return; + if (!context || !context->eventlock) + return; + DEBUG_LOG(SCENET, "Entering AfterMatchingMipsCall::run [ID=%i][Event=%d] [cbId: %u]", context->id, EventID, call.cbId); //u32 v0 = currentMIPS->r[MIPS_REG_V0]; if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", context->id, EventID); From 70edcf1a060abf23d7190fa28f66287b6ab6ccf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 6 Jul 2020 21:14:49 +0200 Subject: [PATCH 201/848] Update README.md for 1.10.2 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 6a9a37701f..cd94b6d6f9 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,11 @@ If you want to download regularly updated builds for Android, Windows x86 and x6 For game compatibility, see [community compatibility feedback](https://report.ppsspp.org/games). +What's new in 1.10.2 +-------------------- +* More crashfixes ([#13094](https://github.com/hrydgard/ppsspp/issues/13094), [#13093](https://github.com/hrydgard/ppsspp/issues/13093)) +* Improve download performance and cancel behavior ([#13095](https://github.com/hrydgard/ppsspp/issues/13095)) +* Restore the removed I/O on Thread option ([#13096](https://github.com/hrydgard/ppsspp/issues/13096)) What's new in 1.10.1 -------------------- From 9ec2c2baff0894d2b998254d52389d253d1dd386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 6 Jul 2020 21:31:26 +0200 Subject: [PATCH 202/848] Update version for 1.10.2 --- android/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 6efd752992..ca12de8a42 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="110020000" + android:versionName="1.10.2.0"> From 143d54aa12716498c8565ef75d979b427165dc7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 6 Jul 2020 23:43:55 +0200 Subject: [PATCH 203/848] Change wording of camera notch ignore setting --- UI/GameSettingsScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 62a70b67a4..0fab4eb865 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -320,7 +320,7 @@ void GameSettingsScreen::CreateViews() { System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP) != 0.0f || System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT) != 0.0f || System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM) != 0.0f)) { - graphicsSettings->Add(new CheckBox(&g_Config.bIgnoreScreenInsets, gr->T("Ignore camera inset when centering"))); + graphicsSettings->Add(new CheckBox(&g_Config.bIgnoreScreenInsets, gr->T("Ignore camera notch when centering"))); } // Hide Immersive Mode on pre-kitkat Android From 649f12f8ab8bd633dce35e400dccdbee41059319 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 10 Jul 2020 06:48:20 +0200 Subject: [PATCH 204/848] (Libretro) Buildfixes --- Core/HLE/sceUsbCam.cpp | 12 ++++++++---- libretro/Makefile.common | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index c2ab2979fa..c2d0ed1609 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -26,7 +26,11 @@ #include "Core/HW/Camera.h" #include "Core/MemMapHelpers.h" -#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) +#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) +#define HAVE_WIN32_CAMERA +#endif + +#ifdef HAVE_WIN32_CAMERA #ifndef NOMINMAX #define NOMINMAX #endif @@ -300,7 +304,7 @@ void Register_sceUsbCam() } std::vector Camera::getDeviceList() { - #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) + #ifdef HAVE_WIN32_CAMERA if (winCamera) { return winCamera->getDeviceList(); } @@ -320,7 +324,7 @@ int Camera::startCapture() { INFO_LOG(HLE, "%s resolution: %dx%d", __FUNCTION__, width, height); config->mode = Camera::Mode::Video; - #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) + #ifdef HAVE_WIN32_CAMERA if (winCamera) { if (winCamera->isShutDown()) { delete winCamera; @@ -344,7 +348,7 @@ int Camera::startCapture() { int Camera::stopCapture() { INFO_LOG(HLE, "%s", __FUNCTION__); - #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) + #ifdef HAVE_WIN32_CAMERA if (winCamera) { winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::STOP, nullptr }); } diff --git a/libretro/Makefile.common b/libretro/Makefile.common index ef28c58eca..4387a5ae0c 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -308,6 +308,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/thin3d/DataFormatGL.cpp \ $(NATIVEDIR)/thread/threadutil.cpp \ $(NATIVEDIR)/thread/threadpool.cpp \ + $(NATIVEDIR)/thread/prioritizedworkqueue.cpp \ $(NATIVEDIR)/ui/root.cpp \ $(NATIVEDIR)/ui/screen.cpp \ $(NATIVEDIR)/ui/ui.cpp \ @@ -478,7 +479,8 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/Util/PPGeDraw.cpp \ $(COREDIR)/Util/AudioFormat.cpp \ $(EXTDIR)/disarm.cpp \ - $(CORE_DIR)/UI/TextureUtil.cpp + $(CORE_DIR)/UI/TextureUtil.cpp \ + $(CORE_DIR)/UI/GameInfoCache.cpp SOURCES_CXX += $(COREDIR)/HLE/__sceAudio.cpp From d203f30445f0848720fd8d571738373485a84b44 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 10 Jul 2020 20:12:06 +0200 Subject: [PATCH 205/848] (Libretro) Makefile build fixes --- libretro/Makefile.common | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 4387a5ae0c..6af1da0886 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -7,6 +7,10 @@ GPUDIR = $(CORE_DIR)/GPU EXTDIR = $(CORE_DIR)/ext NATIVEDIR = $(EXTDIR)/native +SOURCES_CXX := +SOURCES_C := +SOURCES_ASM := + INCFLAGS += \ -I$(CORE_DIR) \ -I$(COMMONDIR) \ @@ -699,11 +703,7 @@ ifneq (,$(findstring $(GIT_VERSION),$(shell grep -s char $(GIT_VERSION_SRC)))) endif ifneq ($(GIT_VERSION_NO_UPDATE),1) - $(shell echo '// This is a generated file.' > $(GIT_VERSION_SRC)) - $(shell echo >> $(GIT_VERSION_SRC)) $(shell echo 'const char *PPSSPP_GIT_VERSION = "${GIT_VERSION}";' >> $(GIT_VERSION_SRC)) - $(shell echo >> $(GIT_VERSION_SRC)) - $(shell echo "// If you don't want this file to update/recompile, change to 1." >> $(GIT_VERSION_SRC)) $(shell echo '#define PPSSPP_GIT_VERSION_NO_UPDATE 0' >> $(GIT_VERSION_SRC)) endif From 1f7fcc1b5a0365e881861fbd03fe866aad8f8932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 00:21:07 +0200 Subject: [PATCH 206/848] Refactor TouchControlLayoutScreen - break out the actual editor into a separate view. This solves most or all offset issues. --- UI/TouchControlLayoutScreen.cpp | 144 ++++++++++++++++++++++---------- UI/TouchControlLayoutScreen.h | 17 ++-- 2 files changed, 105 insertions(+), 56 deletions(-) diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 3e454c5190..e0476aca68 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -31,8 +31,6 @@ #include "UI/TouchControlLayoutScreen.h" #include "UI/TouchControlVisibilityScreen.h" -static const int leftColumnWidth = 140; - static u32 GetButtonColor() { return g_Config.iTouchButtonStyle != 0 ? 0xFFFFFF : 0xc0b080; } @@ -40,7 +38,7 @@ static u32 GetButtonColor() { class DragDropButton : public MultiTouchButton { public: DragDropButton(ConfigTouchPos &pos, ImageID bgImg, ImageID img, const Bounds &screenBounds) - : MultiTouchButton(bgImg, bgImg, img, pos.scale, new UI::AnchorLayoutParams(fromFullscreenCoord(pos.x, screenBounds), pos.y * screenBounds.h, UI::NONE, UI::NONE, true)), + : MultiTouchButton(bgImg, bgImg, img, pos.scale, new UI::AnchorLayoutParams(pos.x * screenBounds.w, pos.y * screenBounds.h, UI::NONE, UI::NONE, true)), x_(pos.x), y_(pos.y), theScale_(pos.scale), screenBounds_(screenBounds) { scale_ = theScale_; } @@ -52,8 +50,8 @@ public: }; virtual void SavePosition() { - x_ = toFullscreenCoord(bounds_.centerX()); - y_ = bounds_.centerY() / screenBounds_.h; + x_ = (bounds_.centerX() - screenBounds_.x) / screenBounds_.w; + y_ = (bounds_.centerY() - screenBounds_.y) / screenBounds_.h; scale_ = theScale_; } @@ -70,16 +68,6 @@ protected: } private: - // convert from screen coordinates (leftColumnWidth to dp_xres) to actual fullscreen coordinates (0 to 1.0) - inline float toFullscreenCoord(int screenx) { - return (float)(screenx - leftColumnWidth) / (screenBounds_.w - leftColumnWidth); - } - - // convert from external fullscreen coordinates(0 to 1.0) to the current partial coordinates (leftColumnWidth to dp_xres) - inline int fromFullscreenCoord(float controllerX, const Bounds &screenBounds) { - return leftColumnWidth + (screenBounds.w - leftColumnWidth) * controllerX; - }; - float &x_, &y_; float &theScale_; const Bounds &screenBounds_; @@ -93,19 +81,19 @@ public: roundId_ = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND"); }; - void setCircleVisibility(bool visible){ + void setCircleVisibility(bool visible) { circleVisible_ = visible; } - void setCrossVisibility(bool visible){ + void setCrossVisibility(bool visible) { crossVisible_ = visible; } - void setTriangleVisibility(bool visible){ + void setTriangleVisibility(bool visible) { triangleVisible_ = visible; } - void setSquareVisibility(bool visible){ + void setSquareVisibility(bool visible) { squareVisible_ = visible; } @@ -221,10 +209,12 @@ public: if (g_Config.bTouchSnapToGrid) { dc.Flush(); dc.BeginNoTex(); + float xOffset = bounds_.x; + float yOffset = bounds_.y; for (int x = x1; x < x2; x += g_Config.iTouchSnapGridSize) - dc.Draw()->vLine(x, y1, y2, col); + dc.Draw()->vLine(x + xOffset, y1 + yOffset, y2 + yOffset, col); for (int y = y1; y < y2; y += g_Config.iTouchSnapGridSize) - dc.Draw()->hLine(x1, y, x2, col); + dc.Draw()->hLine(x1 + xOffset, y + yOffset, x2 + xOffset, col); dc.Flush(); dc.Begin(); } @@ -236,41 +226,68 @@ private: }; TouchControlLayoutScreen::TouchControlLayoutScreen() { - pickedControl_ = 0; +}; + + +class DragDropButton; + +class ControlLayoutView : public UI::AnchorLayout { +public: + ControlLayoutView(UI::LayoutParams *layoutParams); + + void Touch(const TouchInput &input) override; + void CreateViews(); + bool HasCreatedViews() const { + return !controls_.empty(); + } + + DragDropButton *pickedControl_ = nullptr; + DragDropButton *getPickedControl(const int x, const int y); + std::vector controls_; + + // Touch down state for drag to resize etc + float startX_ = -1.0f; + float startY_ = -1.0f; + float startScale_ = -1.0f; + float startSpacing_ = -1.0f; + + int mode_ = 0; }; static Point ClampTo(const Point &p, const Bounds &b) { return Point(clamp_value(p.x, b.x, b.x + b.w), clamp_value(p.y, b.y, b.y + b.h)); } -bool TouchControlLayoutScreen::touch(const TouchInput &touch) { - UIScreen::touch(touch); - +void ControlLayoutView::Touch(const TouchInput &touch) { using namespace UI; if ((touch.flags & TOUCH_MOVE) && pickedControl_ != nullptr) { - int mode = mode_->GetSelection(); - if (mode == 0) { - const Bounds &bounds = pickedControl_->GetBounds(); + if (mode_ == 0) { + const Bounds &controlBounds = pickedControl_->GetBounds(); const auto &prevParams = pickedControl_->GetLayoutParams()->As(); Point newPos(prevParams->left, prevParams->top); - Bounds validRange = screenManager()->getUIContext()->GetBounds(); - validRange.x += leftColumnWidth + bounds.w * 0.5f; - validRange.w -= leftColumnWidth + bounds.w; - validRange.y += bounds.h * 0.5f; - validRange.h -= bounds.h; + // Allow placing the control halfway outside the play area. + Bounds validRange = this->GetBounds(); + // Control coordinates are relative inside the bounds. + validRange.x = 0.0f; + validRange.y = 0.0f; - newPos.x = touch.x; - newPos.y = touch.y; + validRange.x += controlBounds.w * 0.5f; + validRange.w -= controlBounds.w; + validRange.y += controlBounds.h * 0.5f; + validRange.h -= controlBounds.h; + + newPos.x = touch.x - this->GetBounds().x; + newPos.y = touch.y - this->GetBounds().y; if (g_Config.bTouchSnapToGrid) { - newPos.x -= (int)(newPos.x - bounds.w) % g_Config.iTouchSnapGridSize; - newPos.y -= (int)(newPos.y - bounds.h) % g_Config.iTouchSnapGridSize; + newPos.x -= (int)(newPos.x - controlBounds.w) % g_Config.iTouchSnapGridSize; + newPos.y -= (int)(newPos.y - controlBounds.h) % g_Config.iTouchSnapGridSize; } newPos = ClampTo(newPos, validRange); pickedControl_->ReplaceLayoutParams(new AnchorLayoutParams(newPos.x, newPos.y, NONE, NONE, true)); - } else if (mode == 1) { + } else if (mode_ == 1) { // Resize. Vertical = scaling, horizontal = spacing; // Up should be bigger so let's negate in that direction float diffX = (touch.x - startX_); @@ -305,7 +322,6 @@ bool TouchControlLayoutScreen::touch(const TouchInput &touch) { pickedControl_->SavePosition(); pickedControl_ = 0; } - return true; } void TouchControlLayoutScreen::resized() { @@ -334,11 +350,33 @@ void TouchControlLayoutScreen::dialogFinished(const Screen *dialog, DialogResult RecreateViews(); } +UI::EventReturn TouchControlLayoutScreen::OnMode(UI::EventParams &e) { + int mode = mode_->GetSelection(); + if (layoutView_) { + layoutView_->mode_ = mode; + } + return UI::EVENT_DONE; +} + +void TouchControlLayoutScreen::update() { + UIDialogScreenWithBackground::update(); + + // TODO: We really, really need a cleaner solution for creating sub-views + // of custom compound controls. + if (layoutView_) { + if (!layoutView_->HasCreatedViews()) { + layoutView_->CreateViews(); + } + } +} + void TouchControlLayoutScreen::CreateViews() { // setup g_Config for button layout const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); InitPadLayout(bounds.w, bounds.h); + const float leftColumnWidth = 140.0f; + using namespace UI; auto co = GetI18NCategory("Controls"); @@ -360,6 +398,7 @@ void TouchControlLayoutScreen::CreateViews() { mode_->AddChoice(di->T("Move")); mode_->AddChoice(di->T("Resize")); mode_->SetSelection(0); + mode_->OnChoice.Handle(this, &TouchControlLayoutScreen::OnMode); reset->OnClick.Handle(this, &TouchControlLayoutScreen::OnReset); back->OnClick.Handle(this, &UIScreen::OnBack); @@ -375,10 +414,12 @@ void TouchControlLayoutScreen::CreateViews() { tabHolder->SetTag("TouchControlLayout"); root_->Add(tabHolder); + layoutView_ = root_->Add(new ControlLayoutView(new AnchorLayoutParams(leftColumnWidth + 10, 0.0f, 0.0f, 0.0f, false))); + // this is more for show than anything else. It's used to provide a boundary // so that buttons like back can be placed within the boundary. // serves no other purpose. - AnchorLayout *controlsHolder = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); + // AnchorLayout *controlsHolder = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); auto ms = GetI18NCategory("MainSettings"); @@ -388,8 +429,23 @@ void TouchControlLayoutScreen::CreateViews() { // Shouldn't even be able to get here as the way into this dialog should be closed. return; } +} - controls_.clear(); + +ControlLayoutView::ControlLayoutView(UI::LayoutParams *layoutParams) + : UI::AnchorLayout(layoutParams) { + +} + +void ControlLayoutView::CreateViews() { + const Bounds &bounds = GetBounds(); + if (bounds.w == 0.0f || bounds.h == 0.0f) { + // Layout hasn't happened yet, return. + // See comment in TouchControlLayoutScreen::update(). + return; + } + + // Create all the views. PSPActionButtons *actionButtons = new PSPActionButtons(g_Config.touchActionButtonCenter, g_Config.fActionButtonSpacing, bounds); actionButtons->setCircleVisibility(g_Config.bShowTouchCircle); @@ -457,15 +513,15 @@ void TouchControlLayoutScreen::CreateViews() { addDragDropButton(g_Config.touchCombo4, roundImage, comboKeyImages[4]); for (size_t i = 0; i < controls_.size(); i++) { - root_->Add(controls_[i]); + Add(controls_[i]); } - root_->Add(new SnapGrid(leftColumnWidth+10, bounds.w, 0, bounds.h, 0x3FFFFFFF)); + Add(new SnapGrid(0, bounds.w, 0, bounds.h, 0x3FFFFFFF)); } // return the control which was picked up by the touchEvent. If a control // was already picked up, then it's being dragged around, so just return that instead -DragDropButton *TouchControlLayoutScreen::getPickedControl(const int x, const int y) { +DragDropButton *ControlLayoutView::getPickedControl(const int x, const int y) { if (pickedControl_ != 0) { return pickedControl_; } diff --git a/UI/TouchControlLayoutScreen.h b/UI/TouchControlLayoutScreen.h index 789d5a25e7..c21c24116d 100644 --- a/UI/TouchControlLayoutScreen.h +++ b/UI/TouchControlLayoutScreen.h @@ -24,31 +24,24 @@ #include "ui/viewgroup.h" #include "MiscScreens.h" -class DragDropButton; +class ControlLayoutView; class TouchControlLayoutScreen : public UIDialogScreenWithBackground { public: TouchControlLayoutScreen(); virtual void CreateViews() override; - virtual bool touch(const TouchInput &touch) override; virtual void dialogFinished(const Screen *dialog, DialogResult result) override; virtual void onFinish(DialogResult reason) override; + virtual void update() override; virtual void resized() override; protected: virtual UI::EventReturn OnReset(UI::EventParams &e); virtual UI::EventReturn OnVisibility(UI::EventParams &e); + virtual UI::EventReturn OnMode(UI::EventParams &e); private: - DragDropButton *pickedControl_; - std::vector controls_; - UI::ChoiceStrip *mode_; - DragDropButton *getPickedControl(const int x, const int y); - - // Touch down state for drag to resize etc - float startX_; - float startY_; - float startScale_; - float startSpacing_; + UI::ChoiceStrip *mode_ = nullptr; + ControlLayoutView *layoutView_ = nullptr; }; From 1df9a842136339876e373b06c3fcc7ffdbc51a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 00:21:46 +0200 Subject: [PATCH 207/848] TouchControlLayoutScreen: Reorder functions in the file to make more sense. --- UI/TouchControlLayoutScreen.cpp | 222 ++++++++++++++++---------------- 1 file changed, 108 insertions(+), 114 deletions(-) diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index e0476aca68..178a17181a 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -225,15 +225,13 @@ private: u32 col; }; -TouchControlLayoutScreen::TouchControlLayoutScreen() { -}; - - class DragDropButton; class ControlLayoutView : public UI::AnchorLayout { public: - ControlLayoutView(UI::LayoutParams *layoutParams); + explicit ControlLayoutView(UI::LayoutParams *layoutParams) + : UI::AnchorLayout(layoutParams) { + } void Touch(const TouchInput &input) override; void CreateViews(); @@ -324,6 +322,111 @@ void ControlLayoutView::Touch(const TouchInput &touch) { } } +void ControlLayoutView::CreateViews() { + const Bounds &bounds = GetBounds(); + if (bounds.w == 0.0f || bounds.h == 0.0f) { + // Layout hasn't happened yet, return. + // See comment in TouchControlLayoutScreen::update(). + return; + } + + // Create all the views. + + PSPActionButtons *actionButtons = new PSPActionButtons(g_Config.touchActionButtonCenter, g_Config.fActionButtonSpacing, bounds); + actionButtons->setCircleVisibility(g_Config.bShowTouchCircle); + actionButtons->setCrossVisibility(g_Config.bShowTouchCross); + actionButtons->setTriangleVisibility(g_Config.bShowTouchTriangle); + actionButtons->setSquareVisibility(g_Config.bShowTouchSquare); + + controls_.push_back(actionButtons); + + ImageID rectImage = g_Config.iTouchButtonStyle ? ImageID("I_RECT_LINE") : ImageID("I_RECT"); + ImageID shoulderImage = g_Config.iTouchButtonStyle ? ImageID("I_SHOULDER_LINE") : ImageID("I_SHOULDER"); + ImageID dirImage = g_Config.iTouchButtonStyle ? ImageID("I_DIR_LINE") : ImageID("I_DIR"); + ImageID stickImage = g_Config.iTouchButtonStyle ? ImageID("I_STICK_LINE") : ImageID("I_STICK"); + ImageID stickBg = g_Config.iTouchButtonStyle ? ImageID("I_STICK_BG_LINE") : ImageID("I_STICK_BG"); + ImageID roundImage = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND"); + + const ImageID comboKeyImages[5] = { ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5") }; + + auto addDragDropButton = [&](ConfigTouchPos &pos, ImageID bgImg, ImageID img) { + DragDropButton *b = nullptr; + if (pos.show) { + b = new DragDropButton(pos, bgImg, img, bounds); + controls_.push_back(b); + } + return b; + }; + + if (g_Config.touchDpad.show) { + controls_.push_back(new PSPDPadButtons(g_Config.touchDpad, g_Config.fDpadSpacing, bounds)); + } + + addDragDropButton(g_Config.touchSelectKey, rectImage, ImageID("I_SELECT")); + addDragDropButton(g_Config.touchStartKey, rectImage, ImageID("I_START")); + + if (auto *unthrottle = addDragDropButton(g_Config.touchUnthrottleKey, rectImage, ImageID("I_ARROW"))) { + unthrottle->SetAngle(180.0f); + } + if (auto *speed1 = addDragDropButton(g_Config.touchSpeed1Key, rectImage, ImageID("I_ARROW"))) { + speed1->SetAngle(170.0f, 180.0f); + } + if (auto *speed2 = addDragDropButton(g_Config.touchSpeed2Key, rectImage, ImageID("I_ARROW"))) { + speed2->SetAngle(190.0f, 180.0f); + } + if (auto *rapidFire = addDragDropButton(g_Config.touchRapidFireKey, rectImage, ImageID("I_ARROW"))) { + rapidFire->SetAngle(90.0f, 180.0f); + } + if (auto *analogRotationCW = addDragDropButton(g_Config.touchAnalogRotationCWKey, rectImage, ImageID("I_ARROW"))) { + analogRotationCW->SetAngle(190.0f, 180.0f); + } + if (auto *analogRotationCCW = addDragDropButton(g_Config.touchAnalogRotationCCWKey, rectImage, ImageID("I_ARROW"))) { + analogRotationCCW->SetAngle(350.0f, 180.0f); + } + + addDragDropButton(g_Config.touchLKey, shoulderImage, ImageID("I_L")); + if (auto *rbutton = addDragDropButton(g_Config.touchRKey, shoulderImage, ImageID("I_R"))) { + rbutton->FlipImageH(true); + } + + addDragDropButton(g_Config.touchAnalogStick, stickBg, stickImage); + addDragDropButton(g_Config.touchRightAnalogStick, stickBg, stickImage); + addDragDropButton(g_Config.touchCombo0, roundImage, comboKeyImages[0]); + addDragDropButton(g_Config.touchCombo1, roundImage, comboKeyImages[1]); + addDragDropButton(g_Config.touchCombo2, roundImage, comboKeyImages[2]); + addDragDropButton(g_Config.touchCombo3, roundImage, comboKeyImages[3]); + addDragDropButton(g_Config.touchCombo4, roundImage, comboKeyImages[4]); + + for (size_t i = 0; i < controls_.size(); i++) { + Add(controls_[i]); + } + + Add(new SnapGrid(0, bounds.w, 0, bounds.h, 0x3FFFFFFF)); +} + +// return the control which was picked up by the touchEvent. If a control +// was already picked up, then it's being dragged around, so just return that instead +DragDropButton *ControlLayoutView::getPickedControl(const int x, const int y) { + if (pickedControl_ != 0) { + return pickedControl_; + } + + for (size_t i = 0; i < controls_.size(); i++) { + DragDropButton *control = controls_[i]; + const Bounds &bounds = control->GetBounds(); + const float thresholdFactor = 1.5f; + + Bounds tolerantBounds(bounds.x, bounds.y, bounds.w * thresholdFactor, bounds.h * thresholdFactor); + if (tolerantBounds.Contains(x, y)) { + return control; + } + } + + return 0; +} + +TouchControlLayoutScreen::TouchControlLayoutScreen() {} + void TouchControlLayoutScreen::resized() { RecreateViews(); } @@ -430,112 +533,3 @@ void TouchControlLayoutScreen::CreateViews() { return; } } - - -ControlLayoutView::ControlLayoutView(UI::LayoutParams *layoutParams) - : UI::AnchorLayout(layoutParams) { - -} - -void ControlLayoutView::CreateViews() { - const Bounds &bounds = GetBounds(); - if (bounds.w == 0.0f || bounds.h == 0.0f) { - // Layout hasn't happened yet, return. - // See comment in TouchControlLayoutScreen::update(). - return; - } - - // Create all the views. - - PSPActionButtons *actionButtons = new PSPActionButtons(g_Config.touchActionButtonCenter, g_Config.fActionButtonSpacing, bounds); - actionButtons->setCircleVisibility(g_Config.bShowTouchCircle); - actionButtons->setCrossVisibility(g_Config.bShowTouchCross); - actionButtons->setTriangleVisibility(g_Config.bShowTouchTriangle); - actionButtons->setSquareVisibility(g_Config.bShowTouchSquare); - - controls_.push_back(actionButtons); - - ImageID rectImage = g_Config.iTouchButtonStyle ? ImageID("I_RECT_LINE") : ImageID("I_RECT"); - ImageID shoulderImage = g_Config.iTouchButtonStyle ? ImageID("I_SHOULDER_LINE") : ImageID("I_SHOULDER"); - ImageID dirImage = g_Config.iTouchButtonStyle ? ImageID("I_DIR_LINE") : ImageID("I_DIR"); - ImageID stickImage = g_Config.iTouchButtonStyle ? ImageID("I_STICK_LINE") : ImageID("I_STICK"); - ImageID stickBg = g_Config.iTouchButtonStyle ? ImageID("I_STICK_BG_LINE") : ImageID("I_STICK_BG"); - ImageID roundImage = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND"); - - const ImageID comboKeyImages[5] = { ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5") }; - - auto addDragDropButton = [&](ConfigTouchPos &pos, ImageID bgImg, ImageID img) { - DragDropButton *b = nullptr; - if (pos.show) { - b = new DragDropButton(pos, bgImg, img, bounds); - controls_.push_back(b); - } - return b; - }; - - if (g_Config.touchDpad.show) { - controls_.push_back(new PSPDPadButtons(g_Config.touchDpad, g_Config.fDpadSpacing, bounds)); - } - - addDragDropButton(g_Config.touchSelectKey, rectImage, ImageID("I_SELECT")); - addDragDropButton(g_Config.touchStartKey, rectImage, ImageID("I_START")); - - if (auto *unthrottle = addDragDropButton(g_Config.touchUnthrottleKey, rectImage, ImageID("I_ARROW"))) { - unthrottle->SetAngle(180.0f); - } - if (auto *speed1 = addDragDropButton(g_Config.touchSpeed1Key, rectImage, ImageID("I_ARROW"))) { - speed1->SetAngle(170.0f, 180.0f); - } - if (auto *speed2 = addDragDropButton(g_Config.touchSpeed2Key, rectImage, ImageID("I_ARROW"))) { - speed2->SetAngle(190.0f, 180.0f); - } - if (auto *rapidFire = addDragDropButton(g_Config.touchRapidFireKey, rectImage, ImageID("I_ARROW"))) { - rapidFire->SetAngle(90.0f, 180.0f); - } - if (auto *analogRotationCW = addDragDropButton(g_Config.touchAnalogRotationCWKey, rectImage, ImageID("I_ARROW"))) { - analogRotationCW->SetAngle(190.0f, 180.0f); - } - if (auto *analogRotationCCW = addDragDropButton(g_Config.touchAnalogRotationCCWKey, rectImage, ImageID("I_ARROW"))) { - analogRotationCCW->SetAngle(350.0f, 180.0f); - } - - addDragDropButton(g_Config.touchLKey, shoulderImage, ImageID("I_L")); - if (auto *rbutton = addDragDropButton(g_Config.touchRKey, shoulderImage, ImageID("I_R"))) { - rbutton->FlipImageH(true); - } - - addDragDropButton(g_Config.touchAnalogStick, stickBg, stickImage); - addDragDropButton(g_Config.touchRightAnalogStick, stickBg, stickImage); - addDragDropButton(g_Config.touchCombo0, roundImage, comboKeyImages[0]); - addDragDropButton(g_Config.touchCombo1, roundImage, comboKeyImages[1]); - addDragDropButton(g_Config.touchCombo2, roundImage, comboKeyImages[2]); - addDragDropButton(g_Config.touchCombo3, roundImage, comboKeyImages[3]); - addDragDropButton(g_Config.touchCombo4, roundImage, comboKeyImages[4]); - - for (size_t i = 0; i < controls_.size(); i++) { - Add(controls_[i]); - } - - Add(new SnapGrid(0, bounds.w, 0, bounds.h, 0x3FFFFFFF)); -} - -// return the control which was picked up by the touchEvent. If a control -// was already picked up, then it's being dragged around, so just return that instead -DragDropButton *ControlLayoutView::getPickedControl(const int x, const int y) { - if (pickedControl_ != 0) { - return pickedControl_; - } - - for (size_t i = 0; i < controls_.size(); i++) { - DragDropButton *control = controls_[i]; - const Bounds &bounds = control->GetBounds(); - const float thresholdFactor = 1.5f; - - Bounds tolerantBounds(bounds.x, bounds.y, bounds.w * thresholdFactor, bounds.h * thresholdFactor); - if (tolerantBounds.Contains(x, y)) { - return control; - } - } - - return 0; -} From 8e9061539fcb56bad9cac0c0c2c2fe83a968d1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 09:15:31 +0200 Subject: [PATCH 208/848] Touch control layout: Make dragging a lot less "jumpy" --- UI/TouchControlLayoutScreen.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 178a17181a..e6553480dc 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -243,9 +243,11 @@ public: DragDropButton *getPickedControl(const int x, const int y); std::vector controls_; - // Touch down state for drag to resize etc - float startX_ = -1.0f; - float startY_ = -1.0f; + // Touch down state for dragging + float startObjectX_ = -1.0f; + float startObjectY_ = -1.0f; + float startDragX_ = -1.0f; + float startDragY_ = -1.0f; float startScale_ = -1.0f; float startSpacing_ = -1.0f; @@ -262,8 +264,6 @@ void ControlLayoutView::Touch(const TouchInput &touch) { if ((touch.flags & TOUCH_MOVE) && pickedControl_ != nullptr) { if (mode_ == 0) { const Bounds &controlBounds = pickedControl_->GetBounds(); - const auto &prevParams = pickedControl_->GetLayoutParams()->As(); - Point newPos(prevParams->left, prevParams->top); // Allow placing the control halfway outside the play area. Bounds validRange = this->GetBounds(); @@ -276,8 +276,9 @@ void ControlLayoutView::Touch(const TouchInput &touch) { validRange.y += controlBounds.h * 0.5f; validRange.h -= controlBounds.h; - newPos.x = touch.x - this->GetBounds().x; - newPos.y = touch.y - this->GetBounds().y; + Point newPos; + newPos.x = startObjectX_ + (touch.x - startDragX_); + newPos.y = startObjectY_ + (touch.y - startDragY_); if (g_Config.bTouchSnapToGrid) { newPos.x -= (int)(newPos.x - controlBounds.w) % g_Config.iTouchSnapGridSize; newPos.y -= (int)(newPos.y - controlBounds.h) % g_Config.iTouchSnapGridSize; @@ -288,13 +289,13 @@ void ControlLayoutView::Touch(const TouchInput &touch) { } else if (mode_ == 1) { // Resize. Vertical = scaling, horizontal = spacing; // Up should be bigger so let's negate in that direction - float diffX = (touch.x - startX_); - float diffY = -(touch.y - startY_); + float diffX = (touch.x - startDragX_); + float diffY = -(touch.y - startDragY_); // Snap to grid if (g_Config.bTouchSnapToGrid) { - diffX -= (int)(touch.x - startX_) % (g_Config.iTouchSnapGridSize/2); - diffY += (int)(touch.y - startY_) % (g_Config.iTouchSnapGridSize/2); + diffX -= (int)(touch.x - startDragX_) % (g_Config.iTouchSnapGridSize/2); + diffY += (int)(touch.y - startDragY_) % (g_Config.iTouchSnapGridSize/2); } float movementScale = 0.02f; float newScale = startScale_ + diffY * movementScale; @@ -310,8 +311,12 @@ void ControlLayoutView::Touch(const TouchInput &touch) { if ((touch.flags & TOUCH_DOWN) && pickedControl_ == 0) { pickedControl_ = getPickedControl(touch.x, touch.y); if (pickedControl_) { - startX_ = touch.x; - startY_ = touch.y; + startDragX_ = touch.x; + startDragY_ = touch.y; + const auto &prevParams = pickedControl_->GetLayoutParams()->As(); + startObjectX_ = prevParams->left; + startObjectY_ = prevParams->top; + startSpacing_ = pickedControl_->GetSpacing(); startScale_ = pickedControl_->GetScale(); } From 23f7f27c45522f30883322d132b7ef0df8d0f0f8 Mon Sep 17 00:00:00 2001 From: iota97 Date: Sun, 12 Jul 2020 09:47:44 +0200 Subject: [PATCH 209/848] Fix decimal part --- UI/TouchControlLayoutScreen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index e6553480dc..a5462dd236 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -280,8 +280,8 @@ void ControlLayoutView::Touch(const TouchInput &touch) { newPos.x = startObjectX_ + (touch.x - startDragX_); newPos.y = startObjectY_ + (touch.y - startDragY_); if (g_Config.bTouchSnapToGrid) { - newPos.x -= (int)(newPos.x - controlBounds.w) % g_Config.iTouchSnapGridSize; - newPos.y -= (int)(newPos.y - controlBounds.h) % g_Config.iTouchSnapGridSize; + newPos.x -= fmod(newPos.x - controlBounds.w, g_Config.iTouchSnapGridSize); + newPos.y -= fmod(newPos.y - controlBounds.h, g_Config.iTouchSnapGridSize); } newPos = ClampTo(newPos, validRange); @@ -294,8 +294,8 @@ void ControlLayoutView::Touch(const TouchInput &touch) { // Snap to grid if (g_Config.bTouchSnapToGrid) { - diffX -= (int)(touch.x - startDragX_) % (g_Config.iTouchSnapGridSize/2); - diffY += (int)(touch.y - startDragY_) % (g_Config.iTouchSnapGridSize/2); + diffX -= fmod(touch.x - startDragX_, g_Config.iTouchSnapGridSize/2); + diffY += fmod(touch.y - startDragY_, g_Config.iTouchSnapGridSize/2); } float movementScale = 0.02f; float newScale = startScale_ + diffY * movementScale; From e184ed368d4c6edcdaf6af5d25f7f4e8f65c427f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 10:16:42 +0200 Subject: [PATCH 210/848] Kernel: Add a little paranoia check on chained mipscalls. See #13057 --- Core/HLE/sceKernelThread.cpp | 7 ++++--- Core/HLE/sceKernelThread.h | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index a1518f248e..c125764a8f 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -3100,6 +3100,7 @@ static bool __CanExecuteCallbackNow(PSPThread *thread) { return currentCallbackThreadID == 0 && g_inCbCount == 0; } +// Takes ownership of afterAction. void __KernelCallAddress(PSPThread *thread, u32 entryPoint, PSPAction *afterAction, const u32 args[], int numargs, bool reschedAfter, SceUID cbId) { if (!thread || thread->isStopped()) { WARN_LOG_REPORT(SCEKERNEL, "Running mipscall on dormant thread"); @@ -3244,11 +3245,11 @@ void __KernelReturnFromMipsCall() u32 retVal = currentMIPS->r[MIPS_REG_V0]; DEBUG_LOG(SCEKERNEL, "__KernelReturnFromMipsCall(), returned %08x", retVal); - // Should also save/restore wait state here. - if (call->doAfter) - { + // TODO: Should also save/restore wait state here? + if (call->doAfter) { call->doAfter->run(*call); delete call->doAfter; + call->doAfter = nullptr; } u32 &sp = currentMIPS->r[MIPS_REG_SP]; diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 73ba3474ba..a3fbbf1aeb 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -219,6 +219,7 @@ int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr); class PSPAction; // Not an official Callback object, just calls a mips function on the current thread. +// Takes ownership of afterAction. void __KernelDirectMipsCall(u32 entryPoint, PSPAction *afterAction, u32 args[], int numargs, bool reschedAfter); void __KernelReturnFromMipsCall(); // Called as HLE function From 2e19d7aa0a7013af2f19ebf3829f141c52ed10db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 10:38:53 +0200 Subject: [PATCH 211/848] Touch control layout screen: Make the expanded click zone around the controls symmetrical. Just a minor tweak. --- UI/TouchControlLayoutScreen.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index a5462dd236..e895ebd384 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -419,9 +419,11 @@ DragDropButton *ControlLayoutView::getPickedControl(const int x, const int y) { for (size_t i = 0; i < controls_.size(); i++) { DragDropButton *control = controls_[i]; const Bounds &bounds = control->GetBounds(); - const float thresholdFactor = 1.5f; + const float thresholdFactor = 0.25f; + const float thresholdW = thresholdFactor * bounds.w; + const float thresholdH = thresholdFactor * bounds.h; - Bounds tolerantBounds(bounds.x, bounds.y, bounds.w * thresholdFactor, bounds.h * thresholdFactor); + Bounds tolerantBounds(bounds.x - thresholdW * 0.5, bounds.y - thresholdH * 0.5 , bounds.w + thresholdW, bounds.h + thresholdH); if (tolerantBounds.Contains(x, y)) { return control; } From 90dc94a7b397d5f56a8463a239facac0905a996f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 11:21:02 +0200 Subject: [PATCH 212/848] Travis: Disable OSX/iOS until we can fix them --- .travis.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9057234e50..b4b8105a4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,14 +85,6 @@ jobs: compiler: "clang" env: PPSSPP_BUILD_TYPE=Linux LIBRETRO=TRUE - - os: osx - osx_image: xcode9 - compiler: "clang" - env: PPSSPP_BUILD_TYPE=macOS - - os: osx - osx_image: xcode9 - compiler: "clang" - env: PPSSPP_BUILD_TYPE=iOS - os: windows compiler: "msvc2017" env: PPSSPP_BUILD_TYPE=Windows @@ -100,6 +92,14 @@ jobs: compiler: "msvc2017" env: PPSSPP_BUILD_TYPE=Windows UWP=TRUE +# - os: osx +# osx_image: xcode9 +# compiler: "clang" +# env: PPSSPP_BUILD_TYPE=macOS +# - os: osx +# osx_image: xcode9 +# compiler: "clang" +# env: PPSSPP_BUILD_TYPE=iOS before_install: - travis_retry bash .travis.sh travis_before_install From 550aef0eefc17c6c65fc0bbffcab2ccb86429ca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 12:49:47 +0200 Subject: [PATCH 213/848] Update README for 1.10.3 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index cd94b6d6f9..a45b103025 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ If you want to download regularly updated builds for Android, Windows x86 and x6 For game compatibility, see [community compatibility feedback](https://report.ppsspp.org/games). +What's new in 1.10.3 +-------------------- +* Fix for control layout editor (#13125) + What's new in 1.10.2 -------------------- * More crashfixes ([#13094](https://github.com/hrydgard/ppsspp/issues/13094), [#13093](https://github.com/hrydgard/ppsspp/issues/13093)) From 17f2e6e8927e12649a33f53cc856baa3d76adf79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 13:04:09 +0200 Subject: [PATCH 214/848] Update lang submodule --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index 942934a3d5..1c64b8fbd3 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 942934a3d55f600622fb3f3ad60ecc1f3da23b6b +Subproject commit 1c64b8fbd3cb6bd87935eb53f302f7de6f86e209 From 087de849bdc74205dd00d8e6e11ba17a591213ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 13:04:16 +0200 Subject: [PATCH 215/848] Update version for 1.10.3 --- android/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index ca12de8a42..11e2682563 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="110030000" + android:versionName="1.10.3.0"> From efc3f4f5e4c84af7d0fe3c77572d929db6479739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jul 2020 20:19:56 +0200 Subject: [PATCH 216/848] Split CORE_ERROR into CORE_BOOT_ERROR and CORE_RUNTIME_ERROR --- Core/Core.cpp | 3 ++- Core/HLE/HLE.cpp | 5 +++-- Core/HLE/sceIo.cpp | 2 +- Core/HLE/sceKernelModule.cpp | 2 +- Core/HW/AsyncIOManager.h | 4 ++-- Core/Loaders.cpp | 6 +++--- Core/MIPS/MIPSDebugInterface.cpp | 2 +- Core/MIPS/x86/Jit.cpp | 2 +- Core/PSPLoaders.cpp | 10 +++++----- Core/System.cpp | 4 ++-- Core/System.h | 3 ++- Core/ThreadEventQueue.h | 2 +- UI/EmuScreen.cpp | 3 +++ Windows/MainWindowMenu.cpp | 2 +- 14 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index 6a89148be2..2e4bba6f06 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -339,7 +339,8 @@ void Core_Run(GraphicsContext *ctx) { case CORE_POWERUP: case CORE_POWERDOWN: - case CORE_ERROR: + case CORE_BOOT_ERROR: + case CORE_RUNTIME_ERROR: // Exit loop!! Core_StateProcessed(); diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index a19c170800..d1dadad229 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -469,7 +469,7 @@ void HLEReturnFromMipsCall() { if ((stackData->nextOff & 0x0000000F) != 0 || !Memory::IsValidAddress(sp + stackData->nextOff)) { ERROR_LOG(HLE, "Corrupt stack on HLE mips call return: %08x", stackData->nextOff); - Core_UpdateState(CORE_ERROR); + Core_UpdateState(CORE_RUNTIME_ERROR); return; } @@ -482,9 +482,10 @@ void HLEReturnFromMipsCall() { while ((finalMarker->nextOff & 0x0000000F) == 0 && Memory::IsValidAddress(finalMarker.ptr + finalMarker->nextOff)) { finalMarker.ptr += finalMarker->nextOff; } + if (finalMarker->nextOff != 0xFFFFFFFF) { ERROR_LOG(HLE, "Corrupt stack on HLE mips call return action: %08x", finalMarker->nextOff); - Core_UpdateState(CORE_ERROR); + Core_UpdateState(CORE_RUNTIME_ERROR); return; } diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 7865d4cea5..fad7769c02 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -555,7 +555,7 @@ static VFSFileSystem *flash0System = nullptr; static void __IoManagerThread() { setCurrentThreadName("IO"); - while (ioManagerThreadEnabled && coreState != CORE_ERROR && coreState != CORE_POWERDOWN) { + while (ioManagerThreadEnabled && coreState != CORE_BOOT_ERROR && coreState != CORE_RUNTIME_ERROR && coreState != CORE_POWERDOWN) { ioManager.RunEventsUntil(CoreTiming::GetTicks() + msToCycles(1000)); } } diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index bc8f91acec..2c3b7aef08 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1837,7 +1837,7 @@ int sceKernelLoadExec(const char *filename, u32 paramPtr) std::string error_string; if (!__KernelLoadExec(exec_filename.c_str(), paramPtr, &error_string)) { ERROR_LOG(SCEMODULE, "sceKernelLoadExec failed: %s", error_string.c_str()); - Core_UpdateState(CORE_ERROR); + Core_UpdateState(CORE_RUNTIME_ERROR); return -1; } if (gpu) { diff --git a/Core/HW/AsyncIOManager.h b/Core/HW/AsyncIOManager.h index 41b997b089..6bb9be5039 100644 --- a/Core/HW/AsyncIOManager.h +++ b/Core/HW/AsyncIOManager.h @@ -91,7 +91,7 @@ public: protected: void ProcessEvent(AsyncIOEvent ref) override; bool ShouldExitEventLoop() override { - return coreState == CORE_ERROR || coreState == CORE_POWERDOWN; + return coreState == CORE_BOOT_ERROR || coreState == CORE_RUNTIME_ERROR || coreState == CORE_POWERDOWN; } private: @@ -106,4 +106,4 @@ private: std::condition_variable resultsWait_; std::set resultsPending_; std::map results_; -}; \ No newline at end of file +}; diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index a4d102e122..a15b8e3c98 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -258,7 +258,7 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) { } else if (ebootType == IdentifiedFileType::PSP_PS1_PBP) { *error_string = "PS1 EBOOTs are not supported by PPSSPP."; - coreState = CORE_ERROR; + coreState = CORE_BOOT_ERROR; return false; } std::string path = fileLoader->Path(); @@ -270,7 +270,7 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) { return Load_PSP_ELF_PBP(fileLoader, error_string); } else { *error_string = "No EBOOT.PBP, misidentified game"; - coreState = CORE_ERROR; + coreState = CORE_BOOT_ERROR; return false; } } @@ -352,7 +352,7 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) { break; } - coreState = CORE_ERROR; + coreState = CORE_BOOT_ERROR; return false; } diff --git a/Core/MIPS/MIPSDebugInterface.cpp b/Core/MIPS/MIPSDebugInterface.cpp index e99e86073c..f81b55ca98 100644 --- a/Core/MIPS/MIPSDebugInterface.cpp +++ b/Core/MIPS/MIPSDebugInterface.cpp @@ -215,7 +215,7 @@ unsigned int MIPSDebugInterface::readMemory(unsigned int address) bool MIPSDebugInterface::isAlive() { - return PSP_IsInited() && coreState != CORE_ERROR && coreState != CORE_POWERDOWN; + return PSP_IsInited() && coreState != CORE_BOOT_ERROR && coreState != CORE_RUNTIME_ERROR && coreState != CORE_POWERDOWN; } bool MIPSDebugInterface::isBreakpoint(unsigned int address) diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index a8050ac0ac..a9b24fa8a2 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -747,7 +747,7 @@ void Jit::WriteExitDestInReg(X64Reg reg) { if (g_Config.bIgnoreBadMemAccess) { CMP(32, R(EAX), Imm32(0)); FixupBranch skip = J_CC(CC_NE); - ABI_CallFunctionA((const void *)&Core_UpdateState, Imm32(CORE_ERROR)); + ABI_CallFunctionA((const void *)&Core_UpdateState, Imm32(CORE_RUNTIME_ERROR)); SetJumpTarget(skip); } diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index d29f1b3b89..8f61f3542c 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -278,7 +278,7 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) { } else { *error_string = "A PSP game couldn't be found on the disc."; } - coreState = CORE_ERROR; + coreState = CORE_BOOT_ERROR; return false; } @@ -303,7 +303,7 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) { if (success && coreState == CORE_POWERUP) { coreState = PSP_CoreParameter().startBreak ? CORE_STEPPING : CORE_RUNNING; } else { - coreState = CORE_ERROR; + coreState = CORE_BOOT_ERROR; // TODO: This is a crummy way to communicate the error... PSP_CoreParameter().fileToStart = ""; } @@ -374,7 +374,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { // If root is not a subpath of path, we can't boot the game. if (!startsWith(pathNorm, rootNorm)) { *error_string = "Cannot boot ELF located outside mountRoot."; - coreState = CORE_ERROR; + coreState = CORE_BOOT_ERROR; return false; } @@ -433,7 +433,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) { if (success && coreState == CORE_POWERUP) { coreState = PSP_CoreParameter().startBreak ? CORE_STEPPING : CORE_RUNNING; } else { - coreState = CORE_ERROR; + coreState = CORE_BOOT_ERROR; // TODO: This is a crummy way to communicate the error... PSP_CoreParameter().fileToStart = ""; } @@ -457,7 +457,7 @@ bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string) { if (success && coreState == CORE_POWERUP) { coreState = PSP_CoreParameter().startBreak ? CORE_STEPPING : CORE_RUNNING; } else { - coreState = CORE_ERROR; + coreState = CORE_BOOT_ERROR; // TODO: This is a crummy way to communicate the error... PSP_CoreParameter().fileToStart = ""; } diff --git a/Core/System.cpp b/Core/System.cpp index eff04fbead..4b95c2bda0 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -433,7 +433,7 @@ void PSP_Shutdown() { // Make sure things know right away that PSP memory, etc. is going away. pspIsQuitting = true; if (coreState == CORE_RUNNING) - Core_UpdateState(CORE_ERROR); + Core_UpdateState(CORE_POWERDOWN); #ifndef MOBILE_DEVICE if (g_Config.bFuncHashMap) { @@ -486,7 +486,7 @@ void PSP_RunLoopWhileState() { void PSP_RunLoopUntil(u64 globalticks) { SaveState::Process(); - if (coreState == CORE_POWERDOWN || coreState == CORE_ERROR) { + if (coreState == CORE_POWERDOWN || coreState == CORE_BOOT_ERROR || coreState == CORE_RUNTIME_ERROR) { return; } else if (coreState == CORE_STEPPING) { Core_ProcessStepping(); diff --git a/Core/System.h b/Core/System.h index 43be1e55eb..4f4ffece77 100644 --- a/Core/System.h +++ b/Core/System.h @@ -106,7 +106,8 @@ enum CoreState { CORE_STEPPING, CORE_POWERUP, CORE_POWERDOWN, - CORE_ERROR, + CORE_BOOT_ERROR, + CORE_RUNTIME_ERROR, }; extern bool coreCollectDebugStats; diff --git a/Core/ThreadEventQueue.h b/Core/ThreadEventQueue.h index 66f442cdfd..d365454776 100644 --- a/Core/ThreadEventQueue.h +++ b/Core/ThreadEventQueue.h @@ -139,7 +139,7 @@ struct ThreadEventQueue : public B { // Don't run if it's not running, but wait for startup. if (!eventsRunning_) { - if (eventsHaveRun_ || coreState == CORE_ERROR || coreState == CORE_POWERDOWN) { + if (eventsHaveRun_ || coreState == CORE_BOOT_ERROR || coreState == CORE_RUNTIME_ERROR || coreState == CORE_POWERDOWN) { return false; } } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 2b0b068b6f..cc9dd9205f 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1414,6 +1414,9 @@ void EmuScreen::render() { if (PSP_IsInited()) { gpu->CopyDisplayToOutput(true); } + } else if (coreState == CORE_RUNTIME_ERROR) { + // Blue screen :) + thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE, 0xFF0000FF }, "EmuScreen_RuntimeError"); } else { // Didn't actually reach the end of the frame, ran out of the blockTicks cycles. // In this case we need to bind and wipe the backbuffer, at least. diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index b5e1bb0eb0..78801f6145 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -1354,7 +1354,7 @@ namespace MainWindow { void UpdateCommands() { static GlobalUIState lastGlobalUIState = UISTATE_PAUSEMENU; - static CoreState lastCoreState = CORE_ERROR; + static CoreState lastCoreState = CORE_BOOT_ERROR; HMENU menu = GetMenu(GetHWND()); EnableMenuItem(menu, ID_DEBUG_LOG, !g_Config.bEnableLogging); From 8461ea19b166d6a341abfe9ba857da41ed00ab68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jul 2020 20:30:05 +0200 Subject: [PATCH 217/848] Centralize handling of memory exceptions a bit --- Core/Core.cpp | 31 ++++++++++++++++++++++++++ Core/Core.h | 10 +++++++++ Core/MIPS/IR/IRInterpreter.cpp | 5 +---- Core/MIPS/MIPSInt.cpp | 7 +----- Core/MemMapFunctions.cpp | 40 ++++------------------------------ Core/System.cpp | 13 ++++++----- 6 files changed, 54 insertions(+), 52 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index 2e4bba6f06..41e5c170c0 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -29,6 +29,7 @@ #include "profiler/profiler.h" #include "Common/GraphicsContext.h" +#include "Common/Log.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/Host.h" @@ -368,3 +369,33 @@ void Core_EnableStepping(bool step) { int Core_GetSteppingCounter() { return steppingCounter; } + +void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { + const char *desc = ""; + switch (type) { + case MemoryExceptionType::READ_WORD: desc = "Read Word"; break; + case MemoryExceptionType::WRITE_WORD: desc = "Write Word"; break; + case MemoryExceptionType::READ_BLOCK: desc = "Read Block"; break; + case MemoryExceptionType::WRITE_BLOCK: desc = "Read/Write Block"; break; + } + + // In jit, we only flush PC when bIgnoreBadMemAccess is off. + if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { + WARN_LOG(MEMMAP, "%s: Invalid address %08x", desc, address); + } else { + WARN_LOG(MEMMAP, "%s: Invalid address %08x PC %08x LR %08x", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); + } + + if (!g_Config.bIgnoreBadMemAccess) { + Core_EnableStepping(true); + host->SetDebugMode(true); + } +} + +void Core_Break() { + ERROR_LOG(CPU, "BREAK!"); + if (!g_Config.bIgnoreBadMemAccess) { + Core_EnableStepping(true); + host->SetDebugMode(true); + } +} diff --git a/Core/Core.h b/Core/Core.h index 69749f0d70..f5cb4ca038 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -76,3 +76,13 @@ void Core_NotifyActivity(); void Core_SetPowerSaving(bool mode); bool Core_GetPowerSaving(); + +enum class MemoryExceptionType { + READ_WORD, + WRITE_WORD, + READ_BLOCK, + WRITE_BLOCK, +}; + +void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type); +void Core_Break(); diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index 9a4e491228..63a1d57189 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -947,10 +947,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) { } case IROp::Break: - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_Break(); return mips->pc + 4; case IROp::SetCtrlVFPU: diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index 93372391c8..9ca3ee67b1 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -151,12 +151,7 @@ namespace MIPSInt void Int_Break(MIPSOpcode op) { - Reporting::ReportMessage("BREAK instruction hit"); - ERROR_LOG(CPU, "BREAK!"); - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_Break(); PC += 4; } diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index ac543e36bd..4c00281840 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -26,17 +26,7 @@ #include "Core/MIPS/MIPS.h" -namespace Memory -{ - -// ================================= -// From Memmap.cpp -// ---------------- - -// Read and write shortcuts - -// GetPointer must always return an address in the bottom 32 bits of address space, so that 64-bit -// programs don't have problems directly addressing any part of memory. +namespace Memory { u8 *GetPointer(const u32 address) { if ((address & 0x3E000000) == 0x08000000) { @@ -52,16 +42,12 @@ u8 *GetPointer(const u32 address) { // More RAM (remasters, etc.) return GetPointerUnchecked(address); } else { - ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); static bool reported = false; if (!reported) { Reporting::ReportMessage("Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); reported = true; } - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_MemoryException(address, currentMIPS->pc, MemoryExceptionType::WRITE_BLOCK); return nullptr; } } @@ -86,21 +72,12 @@ inline void ReadFromHardware(T &var, const u32 address) { // More RAM (remasters, etc.) var = *((const T*)GetPointerUnchecked(address)); } else { - // In jit, we only flush PC when bIgnoreBadMemAccess is off. - if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { - WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x", address); - } else { - WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); - } static bool reported = false; if (!reported) { Reporting::ReportMessage("ReadFromHardware: Invalid address %08x near PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); reported = true; } - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_MemoryException(address, currentMIPS->pc, MemoryExceptionType::READ_WORD); var = 0; } } @@ -122,21 +99,12 @@ inline void WriteToHardware(u32 address, const T data) { // More RAM (remasters, etc.) *(T*)GetPointerUnchecked(address) = data; } else { - // In jit, we only flush PC when bIgnoreBadMemAccess is off. - if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { - WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x", address); - } else { - WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); - } static bool reported = false; if (!reported) { Reporting::ReportMessage("WriteToHardware: Invalid address %08x near PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); reported = true; } - if (!g_Config.bIgnoreBadMemAccess) { - Core_EnableStepping(true); - host->SetDebugMode(true); - } + Core_MemoryException(address, currentMIPS->pc, MemoryExceptionType::WRITE_WORD); } } diff --git a/Core/System.cpp b/Core/System.cpp index 4b95c2bda0..9a6fcb1779 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -97,13 +97,19 @@ bool coreCollectDebugStatsForced = false; // This can be read and written from ANYWHERE. volatile CoreState coreState = CORE_STEPPING; -// Note: intentionally not used for CORE_NEXTFRAME. +// Note: intentionally not used for CORE_NEXTFRAME. << TODO: This comment is a lie, it is used! volatile bool coreStatePending = false; + static volatile CPUThreadState cpuThreadState = CPU_THREAD_NOT_RUNNING; static GPUBackend gpuBackend; static std::string gpuBackendDevice; +// Ugly! +static bool pspIsInited = false; +static bool pspIsIniting = false; +static bool pspIsQuitting = false; + void ResetUIState() { globalUIState = UISTATE_MENU; } @@ -328,11 +334,6 @@ void Core_UpdateDebugStats(bool collectStats) { gpuStats.ResetFrame(); } -// Ugly! -static bool pspIsInited = false; -static bool pspIsIniting = false; -static bool pspIsQuitting = false; - bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { if (pspIsIniting || pspIsQuitting) { return false; From 7208cf6900c6505f27fd1d51b500976848b17c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jul 2020 20:30:33 +0200 Subject: [PATCH 218/848] Some code reformatting/renaming --- Core/MemMap.h | 46 ++++----------- Core/MemMapFunctions.cpp | 118 ++++++++++----------------------------- 2 files changed, 41 insertions(+), 123 deletions(-) diff --git a/Core/MemMap.h b/Core/MemMap.h index 28c635c181..4f598961f3 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -52,8 +52,7 @@ typedef void (*readFn16)(u16&, const u32); typedef void (*readFn32)(u32&, const u32); typedef void (*readFn64)(u64&, const u32); -namespace Memory -{ +namespace Memory { // Base is a pointer to the base of the memory map. Yes, some MMU tricks // are used to set up a full GC or Wii memory map in process memory. on // 32-bit, you have to mask your offsets with 0x3FFFFFFF. This means that @@ -165,16 +164,6 @@ inline u8* GetPointerUnchecked(const u32 address) { #endif } -#ifdef SAFE_MEMORY -u32 ReadUnchecked_U32(const u32 _Address); -// ONLY for use by GUI and fast interpreter -u8 ReadUnchecked_U8(const u32 _Address); -u16 ReadUnchecked_U16(const u32 _Address); -void WriteUnchecked_U8(const u8 _Data, const u32 _Address); -void WriteUnchecked_U16(const u16 _Data, const u32 _Address); -void WriteUnchecked_U32(const u32 _Data, const u32 _Address); -#else - inline u32 ReadUnchecked_U32(const u32 address) { #ifdef MASKED_PSP_MEMORY return *(u32_le *)(base + (address & MEMVIEW32_MASK)); @@ -239,8 +228,6 @@ inline void WriteUnchecked_U8(u8 data, u32 address) { #endif } -#endif - inline float Read_Float(u32 address) { u32 ifloat = Read_U32(address); @@ -274,18 +261,15 @@ inline const char* GetCharPointer(const u32 address) { return (const char *)GetPointer(address); } -inline void MemcpyUnchecked(void *to_data, const u32 from_address, const u32 len) -{ +inline void MemcpyUnchecked(void *to_data, const u32 from_address, const u32 len) { memcpy(to_data, GetPointerUnchecked(from_address), len); } -inline void MemcpyUnchecked(const u32 to_address, const void *from_data, const u32 len) -{ +inline void MemcpyUnchecked(const u32 to_address, const void *from_data, const u32 len) { memcpy(GetPointerUnchecked(to_address), from_data, len); } -inline void MemcpyUnchecked(const u32 to_address, const u32 from_address, const u32 len) -{ +inline void MemcpyUnchecked(const u32 to_address, const u32 from_address, const u32 len) { MemcpyUnchecked(GetPointer(to_address), from_address, len); } @@ -327,7 +311,7 @@ inline bool IsValidRange(const u32 address, const u32 size) { return IsValidAddress(address) && ValidSize(address, size) == size; } -}; +} // namespace Memory template struct PSPPointer @@ -462,44 +446,36 @@ inline u32 PSP_GetKernelMemoryEnd() { return 0x08400000;} // game through sceKernelVolatileMemTryLock. inline u32 PSP_GetUserMemoryBase() { return 0x08800000;} - inline u32 PSP_GetDefaultLoadAddress() { return 0;} -//inline u32 PSP_GetDefaultLoadAddress() { return 0x0898dab0;} inline u32 PSP_GetVidMemBase() { return 0x04000000;} inline u32 PSP_GetVidMemEnd() { return 0x04800000;} template -inline bool operator==(const PSPPointer &lhs, const PSPPointer &rhs) -{ +inline bool operator==(const PSPPointer &lhs, const PSPPointer &rhs) { return lhs.ptr == rhs.ptr; } template -inline bool operator!=(const PSPPointer &lhs, const PSPPointer &rhs) -{ +inline bool operator!=(const PSPPointer &lhs, const PSPPointer &rhs) { return lhs.ptr != rhs.ptr; } template -inline bool operator<(const PSPPointer &lhs, const PSPPointer &rhs) -{ +inline bool operator<(const PSPPointer &lhs, const PSPPointer &rhs) { return lhs.ptr < rhs.ptr; } template -inline bool operator>(const PSPPointer &lhs, const PSPPointer &rhs) -{ +inline bool operator>(const PSPPointer &lhs, const PSPPointer &rhs) { return lhs.ptr > rhs.ptr; } template -inline bool operator<=(const PSPPointer &lhs, const PSPPointer &rhs) -{ +inline bool operator<=(const PSPPointer &lhs, const PSPPointer &rhs) { return lhs.ptr <= rhs.ptr; } template -inline bool operator>=(const PSPPointer &lhs, const PSPPointer &rhs) -{ +inline bool operator>=(const PSPPointer &lhs, const PSPPointer &rhs) { return lhs.ptr >= rhs.ptr; } diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index 4c00281840..07f912b198 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -55,10 +55,6 @@ u8 *GetPointer(const u32 address) { template inline void ReadFromHardware(T &var, const u32 address) { // TODO: Figure out the fastest order of tests for both read and write (they are probably different). - // TODO: Make sure this represents the mirrors in a correct way. - - // Could just do a base-relative read, too.... TODO - if ((address & 0x3E000000) == 0x08000000) { // RAM var = *((const T*)GetPointerUnchecked(address)); @@ -84,8 +80,6 @@ inline void ReadFromHardware(T &var, const u32 address) { template inline void WriteToHardware(u32 address, const T data) { - // Could just do a base-relative write, too.... TODO - if ((address & 0x3E000000) == 0x08000000) { // RAM *(T*)GetPointerUnchecked(address) = data; @@ -108,14 +102,12 @@ inline void WriteToHardware(u32 address, const T data) { } } -// ===================== - bool IsRAMAddress(const u32 address) { if ((address & 0x3E000000) == 0x08000000) { return true; - } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { + } else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) { return true; - } else { + } else { return false; } } @@ -128,102 +120,52 @@ bool IsScratchpadAddress(const u32 address) { return (address & 0xBFFF0000) == 0x00010000 && (address & 0x0000FFFF) < SCRATCHPAD_SIZE; } -u8 Read_U8(const u32 _Address) -{ - u8 _var = 0; - ReadFromHardware(_var, _Address); - return (u8)_var; +u8 Read_U8(const u32 address) { + u8 value = 0; + ReadFromHardware(value, address); + return (u8)value; } -u16 Read_U16(const u32 _Address) -{ - u16_le _var = 0; - ReadFromHardware(_var, _Address); - return (u16)_var; +u16 Read_U16(const u32 address) { + u16_le value = 0; + ReadFromHardware(value, address); + return (u16)value; } -u32 Read_U32(const u32 _Address) -{ - u32_le _var = 0; - ReadFromHardware(_var, _Address); - return _var; +u32 Read_U32(const u32 address) { + u32_le value = 0; + ReadFromHardware(value, address); + return value; } -u64 Read_U64(const u32 _Address) -{ - u64_le _var = 0; - ReadFromHardware(_var, _Address); - return _var; +u64 Read_U64(const u32 address) { + u64_le value = 0; + ReadFromHardware(value, address); + return value; } -u32 Read_U8_ZX(const u32 _Address) -{ - return (u32)Read_U8(_Address); +u32 Read_U8_ZX(const u32 address) { + return (u32)Read_U8(address); } -u32 Read_U16_ZX(const u32 _Address) -{ - return (u32)Read_U16(_Address); +u32 Read_U16_ZX(const u32 address) { + return (u32)Read_U16(address); } -void Write_U8(const u8 _Data, const u32 _Address) -{ - WriteToHardware(_Address, _Data); +void Write_U8(const u8 _Data, const u32 address) { + WriteToHardware(address, _Data); } -void Write_U16(const u16 _Data, const u32 _Address) -{ - WriteToHardware(_Address, _Data); +void Write_U16(const u16 _Data, const u32 address) { + WriteToHardware(address, _Data); } -void Write_U32(const u32 _Data, const u32 _Address) -{ - WriteToHardware(_Address, _Data); +void Write_U32(const u32 _Data, const u32 address) { + WriteToHardware(address, _Data); } -void Write_U64(const u64 _Data, const u32 _Address) -{ - WriteToHardware(_Address, _Data); +void Write_U64(const u64 _Data, const u32 address) { + WriteToHardware(address, _Data); } -#ifdef SAFE_MEMORY - -u8 ReadUnchecked_U8(const u32 _Address) -{ - u8 _var = 0; - ReadFromHardware(_var, _Address); - return _var; -} - -u16 ReadUnchecked_U16(const u32 _Address) -{ - u16_le _var = 0; - ReadFromHardware(_var, _Address); - return _var; -} - -u32 ReadUnchecked_U32(const u32 _Address) -{ - u32_le _var = 0; - ReadFromHardware(_var, _Address); - return _var; -} - -void WriteUnchecked_U8(const u8 _iValue, const u32 _Address) -{ - WriteToHardware(_Address, _iValue); -} - -void WriteUnchecked_U16(const u16 _iValue, const u32 _Address) -{ - WriteToHardware(_Address, _iValue); -} - -void WriteUnchecked_U32(const u32 _iValue, const u32 _Address) -{ - WriteToHardware(_Address, _iValue); -} - -#endif - } // namespace Memory From a722dfe0fbd60cd79a64347c60b3bfc10b52ca87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jul 2020 20:57:05 +0200 Subject: [PATCH 219/848] Formalize "core excpetions" as a concept --- Core/Config.h | 1 + Core/Core.cpp | 51 ++++++++++++++++++++++++++++---- Core/Core.h | 18 +++++++++++ Core/HLE/proAdhoc.h | 1 - Core/HLE/sceDisplay.cpp | 4 +-- Core/HW/Camera.cpp | 1 + Core/HW/Camera.h | 1 - GPU/Common/FramebufferCommon.cpp | 6 ++-- UI/EmuScreen.cpp | 40 +++++++++++++++++-------- 9 files changed, 97 insertions(+), 26 deletions(-) diff --git a/Core/Config.h b/Core/Config.h index c4ba00d2b1..1843823047 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -97,6 +97,7 @@ public: // Core bool bIgnoreBadMemAccess; + bool bFastMemory; int iCpuCore; bool bCheckForNewVersion; diff --git a/Core/Core.cpp b/Core/Core.cpp index 41e5c170c0..5445e51b86 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -64,6 +64,8 @@ static double lastKeepAwake = 0.0; static GraphicsContext *graphicsContext; static bool powerSaving = false; +static ExceptionInfo g_exceptionInfo; + void Core_SetGraphicsContext(GraphicsContext *ctx) { graphicsContext = ctx; PSP_CoreParameter().graphicsContext = graphicsContext; @@ -366,19 +368,40 @@ void Core_EnableStepping(bool step) { } } +bool Core_NextFrame() { + if (coreState == CORE_RUNNING) { + coreState = CORE_NEXTFRAME; + return true; + } else { + return false; + } +} + int Core_GetSteppingCounter() { return steppingCounter; } -void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { - const char *desc = ""; +const char *ExceptionTypeToString(ExceptionType type) { switch (type) { - case MemoryExceptionType::READ_WORD: desc = "Read Word"; break; - case MemoryExceptionType::WRITE_WORD: desc = "Write Word"; break; - case MemoryExceptionType::READ_BLOCK: desc = "Read Block"; break; - case MemoryExceptionType::WRITE_BLOCK: desc = "Read/Write Block"; break; + case ExceptionType::MEMORY: return "Memory"; + case ExceptionType::BREAK: return "Break"; + default: return "N/A"; } +} +const char *MemoryExceptionTypeToString(MemoryExceptionType type) { + switch (type) { + case MemoryExceptionType::READ_WORD: return "Read Word"; + case MemoryExceptionType::WRITE_WORD: return "Write Word"; + case MemoryExceptionType::READ_BLOCK: return "Read Block"; + case MemoryExceptionType::WRITE_BLOCK: return "Read/Write Block"; + default: + return "N/A"; + } +} + +void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { + const char *desc = MemoryExceptionTypeToString(type); // In jit, we only flush PC when bIgnoreBadMemAccess is off. if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { WARN_LOG(MEMMAP, "%s: Invalid address %08x", desc, address); @@ -386,6 +409,12 @@ void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { WARN_LOG(MEMMAP, "%s: Invalid address %08x PC %08x LR %08x", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); } + ExceptionInfo &e = g_exceptionInfo; + e = {}; + e.type = ExceptionType::MEMORY; + e.info = ""; + e.memory_type = type; + if (!g_Config.bIgnoreBadMemAccess) { Core_EnableStepping(true); host->SetDebugMode(true); @@ -394,8 +423,18 @@ void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { void Core_Break() { ERROR_LOG(CPU, "BREAK!"); + + ExceptionInfo &e = g_exceptionInfo; + e = {}; + e.type = ExceptionType::BREAK; + e.info = ""; + if (!g_Config.bIgnoreBadMemAccess) { Core_EnableStepping(true); host->SetDebugMode(true); } } + +ExceptionInfo Core_GetExceptionInfo() { + return g_exceptionInfo; +} diff --git a/Core/Core.h b/Core/Core.h index f5cb4ca038..dffdebd0d8 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -32,6 +32,8 @@ void Core_SetGraphicsContext(GraphicsContext *ctx); // called from gui void Core_EnableStepping(bool step); + +bool Core_NextFrame(); void Core_DoSingleStep(); void Core_UpdateSingleStep(); void Core_ProcessStepping(); @@ -86,3 +88,19 @@ enum class MemoryExceptionType { void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type); void Core_Break(); + +enum class ExceptionType { + NONE, + MEMORY, + BREAK, +}; + +struct ExceptionInfo { + ExceptionType type; + MemoryExceptionType memory_type; + std::string info; +}; + +ExceptionInfo Core_GetExceptionInfo(); + +const char *MemoryExceptionTypeToString(MemoryExceptionType type); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 90f5dfe4dc..1480c03026 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -24,7 +24,6 @@ #include "net/resolve.h" #include "Common/ChunkFile.h" -#include "Core/Config.h" #include "Core/CoreTiming.h" #include "Core/MemMap.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 56fcf9bfc9..362ad09ce1 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -42,6 +42,7 @@ #include "Core/CoreParameter.h" #include "Core/Host.h" #include "Core/Reporting.h" +#include "Core/Core.h" #include "Core/System.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" @@ -791,8 +792,7 @@ void __DisplayFlip(int cyclesLate) { const bool fbReallyDirty = gpu->FramebufferReallyDirty(); if (fbReallyDirty || noRecentFlip || postEffectRequiresFlip) { // Check first though, might've just quit / been paused. - if (coreState == CORE_RUNNING) { - coreState = CORE_NEXTFRAME; + if (Core_NextFrame()) { gpu->CopyDisplayToOutput(fbReallyDirty); if (fbReallyDirty) { actualFlips++; diff --git a/Core/HW/Camera.cpp b/Core/HW/Camera.cpp index 48d5210432..415ac0a190 100644 --- a/Core/HW/Camera.cpp +++ b/Core/HW/Camera.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Camera.h" +#include "Core/Config.h" void convert_frame(int inw, int inh, unsigned char *inData, AVPixelFormat inFormat, int outw, int outh, unsigned char **outData, int *outLen) { diff --git a/Core/HW/Camera.h b/Core/HW/Camera.h index fbc691bf64..4e36fbd296 100644 --- a/Core/HW/Camera.h +++ b/Core/HW/Camera.h @@ -18,7 +18,6 @@ #pragma once #include "ppsspp_config.h" -#include "Core/Config.h" #include "Core/HLE/sceUsbCam.h" #include "Log.h" diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 98a7bbd9e3..79035ba076 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -28,10 +28,10 @@ #include "Common/Common.h" #include "Core/Config.h" #include "Core/ConfigValues.h" +#include "Core/Core.h" #include "Core/CoreParameter.h" #include "Core/Host.h" #include "Core/Reporting.h" -#include "Core/System.h" #include "GPU/Common/DrawEngineCommon.h" #include "GPU/Common/FramebufferCommon.h" #include "GPU/Common/PostShader.h" @@ -831,7 +831,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { currentRenderVfb_ = 0; if (displayFramebufPtr_ == 0) { - if (coreState == CORE_STEPPING) + if (Core_IsStepping()) VERBOSE_LOG(FRAMEBUF, "Display disabled, displaying only black"); else DEBUG_LOG(FRAMEBUF, "Display disabled, displaying only black"); @@ -925,7 +925,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { displayFramebuf_ = vfb; if (vfb->fbo) { - if (coreState == CORE_STEPPING) + if (Core_IsStepping()) VERBOSE_LOG(FRAMEBUF, "Displaying FBO %08x", vfb->fb_address); else DEBUG_LOG(FRAMEBUF, "Displaying FBO %08x", vfb->fb_address); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index cc9dd9205f..e6b837cac2 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -136,7 +136,9 @@ EmuScreen::EmuScreen(const std::string &filename) frameStep_ = false; lastNumFlips = gpuStats.numFlips; startDumping = false; + // Make sure we don't leave it at powerdown after the last game. + // TODO: This really should be handled elsewhere if it isn't. if (coreState == CORE_POWERDOWN) coreState = CORE_STEPPING; @@ -1403,26 +1405,38 @@ void EmuScreen::render() { PSP_RunLoopWhileState(); // Hopefully coreState is now CORE_NEXTFRAME - if (coreState == CORE_NEXTFRAME) { - // set back to running for the next frame + switch (coreState) { + case CORE_NEXTFRAME: + // Reached the end of the frame, all good. Set back to running for the next frame coreState = CORE_RUNNING; - } else if (coreState == CORE_STEPPING) { - // If we're stepping, it's convenient not to clear the screen entirely, so we copy display to output. - // This won't work in non-buffered, but that's fine. - thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE }, "EmuScreen_Stepping"); - // Just to make sure. - if (PSP_IsInited()) { - gpu->CopyDisplayToOutput(true); + break; + case CORE_STEPPING: + case CORE_RUNTIME_ERROR: + { + // If there's an exception, display information. + ExceptionInfo info = Core_GetExceptionInfo(); + if (info.type != ExceptionType::NONE) { + // Blue screen + thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE, 0xFF900000 }, "EmuScreen_RuntimeError"); + } else { + // If we're stepping, it's convenient not to clear the screen entirely, so we copy display to output. + // This won't work in non-buffered, but that's fine. + thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE }, "EmuScreen_Stepping"); + // Just to make sure. + if (PSP_IsInited()) { + gpu->CopyDisplayToOutput(true); + } } - } else if (coreState == CORE_RUNTIME_ERROR) { - // Blue screen :) - thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE, 0xFF0000FF }, "EmuScreen_RuntimeError"); - } else { + break; + } + default: // Didn't actually reach the end of the frame, ran out of the blockTicks cycles. // In this case we need to bind and wipe the backbuffer, at least. // It's possible we never ended up outputted anything - make sure we have the backbuffer cleared thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR }, "EmuScreen_NoFrame"); + break; } + checkPowerDown(); PSP_EndHostFrame(); From 873c11d7f9661ba2510d35d69138d2d4bae8aae3 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 12 Feb 2019 13:29:37 +0100 Subject: [PATCH 220/848] Draw a minimal crash dump on the emu screen after a caught crash. --- Core/Core.cpp | 23 +++++++++-------- Core/Core.h | 11 +++++--- Core/System.h | 9 ++++++- UI/EmuScreen.cpp | 54 +++++++++++++++++++++++++++++++++++++-- UI/GameSettingsScreen.cpp | 1 + 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index 5445e51b86..e3c8273f9e 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -381,15 +381,15 @@ int Core_GetSteppingCounter() { return steppingCounter; } -const char *ExceptionTypeToString(ExceptionType type) { +const char *ExceptionTypeAsString(ExceptionType type) { switch (type) { - case ExceptionType::MEMORY: return "Memory"; + case ExceptionType::MEMORY: return "Invalid Memory Access"; case ExceptionType::BREAK: return "Break"; default: return "N/A"; } } -const char *MemoryExceptionTypeToString(MemoryExceptionType type) { +const char *MemoryExceptionTypeAsString(MemoryExceptionType type) { switch (type) { case MemoryExceptionType::READ_WORD: return "Read Word"; case MemoryExceptionType::WRITE_WORD: return "Write Word"; @@ -401,7 +401,7 @@ const char *MemoryExceptionTypeToString(MemoryExceptionType type) { } void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { - const char *desc = MemoryExceptionTypeToString(type); + const char *desc = MemoryExceptionTypeAsString(type); // In jit, we only flush PC when bIgnoreBadMemAccess is off. if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { WARN_LOG(MEMMAP, "%s: Invalid address %08x", desc, address); @@ -409,13 +409,14 @@ void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { WARN_LOG(MEMMAP, "%s: Invalid address %08x PC %08x LR %08x", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); } - ExceptionInfo &e = g_exceptionInfo; - e = {}; - e.type = ExceptionType::MEMORY; - e.info = ""; - e.memory_type = type; - if (!g_Config.bIgnoreBadMemAccess) { + ExceptionInfo &e = g_exceptionInfo; + e = {}; + e.type = ExceptionType::MEMORY; + e.info = ""; + e.memory_type = type; + e.address = address; + e.pc = pc; Core_EnableStepping(true); host->SetDebugMode(true); } @@ -435,6 +436,6 @@ void Core_Break() { } } -ExceptionInfo Core_GetExceptionInfo() { +const ExceptionInfo &Core_GetExceptionInfo() { return g_exceptionInfo; } diff --git a/Core/Core.h b/Core/Core.h index dffdebd0d8..6f210c739b 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -97,10 +97,15 @@ enum class ExceptionType { struct ExceptionInfo { ExceptionType type; - MemoryExceptionType memory_type; std::string info; + + // Memory exception info + MemoryExceptionType memory_type; + uint32_t pc; + uint32_t address; }; -ExceptionInfo Core_GetExceptionInfo(); +const ExceptionInfo &Core_GetExceptionInfo(); -const char *MemoryExceptionTypeToString(MemoryExceptionType type); +const char *ExceptionTypeAsString(ExceptionType type); +const char *MemoryExceptionTypeAsString(MemoryExceptionType type); diff --git a/Core/System.h b/Core/System.h index 4f4ffece77..0d21b0d1bb 100644 --- a/Core/System.h +++ b/Core/System.h @@ -101,12 +101,19 @@ void InitSysDirectories(); // RUNNING must be at 0, NEXTFRAME must be at 1. enum CoreState { + // Emulation is running normally. CORE_RUNNING = 0, + // Emulation was running normally, just reached the end of a frame. CORE_NEXTFRAME = 1, - CORE_STEPPING, + // Emulation is paused, CPU thread is sleeping. + CORE_STEPPING, // Can be used for recoverable runtime errors (ignored memory exceptions) + // Core is being powered up. CORE_POWERUP, + // Core is being powered down. CORE_POWERDOWN, + // An error happened at boot. CORE_BOOT_ERROR, + // Unrecoverable runtime error. Recoverable errors should use CORE_STEPPING. CORE_RUNTIME_ERROR, }; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index e6b837cac2..e7367eda92 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1265,6 +1265,44 @@ static void DrawDebugStats(DrawBuffer *draw2d, const Bounds &bounds) { draw2d->SetFontScale(1.0f, 1.0f); } +static void DrawCrashDump(DrawBuffer *draw2d) { + const ExceptionInfo &info = Core_GetExceptionInfo(); + + FontID ubuntu24("UBUNTU24"); + char statbuf[4096]; + char versionString[256]; + sprintf(versionString, "%s", PPSSPP_GIT_VERSION); + // TODO: Draw a lot more information. Full register set, and so on. + snprintf(statbuf, sizeof(statbuf), R"(%s +Game ID: %s +Game Title: %s +PPSSPP: %s +)", + ExceptionTypeAsString(info.type), + g_paramSFO.GetDiscID().c_str(), + g_paramSFO.GetValueString("TITLE").c_str(), + versionString + ); + + draw2d->SetFontScale(.7f, .7f); + int x = 20; + int y = 50; + draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + + if (info.type == ExceptionType::MEMORY) { + snprintf(statbuf, sizeof(statbuf), R"( +Access Type: % s +Address: % 08x +PC: % 08x)", + MemoryExceptionTypeAsString(info.memory_type), + info.address, + info.pc); + + y += 150; + draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + } +} + static void DrawAudioDebugStats(DrawBuffer *draw2d, const Bounds &bounds) { FontID ubuntu24("UBUNTU24"); char statbuf[4096] = { 0 }; @@ -1414,10 +1452,11 @@ void EmuScreen::render() { case CORE_RUNTIME_ERROR: { // If there's an exception, display information. - ExceptionInfo info = Core_GetExceptionInfo(); + const ExceptionInfo &info = Core_GetExceptionInfo(); if (info.type != ExceptionType::NONE) { - // Blue screen + // Clear to blue background screen thin3d->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::DONT_CARE, RPAction::DONT_CARE, 0xFF900000 }, "EmuScreen_RuntimeError"); + // The info is drawn later in renderUI } else { // If we're stepping, it's convenient not to clear the screen entirely, so we copy display to output. // This won't work in non-buffered, but that's fine. @@ -1481,6 +1520,9 @@ bool EmuScreen::hasVisibleUI() { if (g_Config.bShowDebugStats || g_Config.bShowDeveloperMenu || g_Config.bShowAudioDebug || g_Config.bShowFrameProfiler) return true; + // Exception information. + if (coreState == CORE_RUNTIME_ERROR || coreState == CORE_STEPPING) + return true; return false; } @@ -1540,6 +1582,14 @@ void EmuScreen::renderUI() { DrawProfile(*ctx); } #endif + + if (coreState == CORE_RUNTIME_ERROR || coreState == CORE_STEPPING) { + const ExceptionInfo &info = Core_GetExceptionInfo(); + if (info.type != ExceptionType::NONE) { + DrawCrashDump(draw2d); + } + } + ctx->Flush(); } diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 0fab4eb865..1099158a9c 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -779,6 +779,7 @@ void GameSettingsScreen::CreateViews() { systemSettings->Add(new ItemHeader(sy->T("Emulation"))); systemSettings->Add(new CheckBox(&g_Config.bFastMemory, sy->T("Fast Memory", "Fast Memory (Unstable)")))->OnClick.Handle(this, &GameSettingsScreen::OnJitAffectingSetting); + systemSettings->Add(new CheckBox(&g_Config.bIgnoreBadMemAccess, sy->T("Ignore bad memory accesses"))); systemSettings->Add(new CheckBox(&g_Config.bSeparateIOThread, sy->T("I/O on thread (experimental)")))->SetEnabled(!PSP_IsInited()); static const char *ioTimingMethods[] = { "Fast (lag on slow storage)", "Host (bugs, less lag)", "Simulate UMD delays" }; From 7dcd708fac1167e6e2038b91e54d8141990264b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jul 2020 23:45:03 +0200 Subject: [PATCH 221/848] Address some feedback --- Core/Core.cpp | 2 +- Core/Core.h | 1 + Core/MIPS/MIPSInt.cpp | 1 + Core/System.cpp | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index e3c8273f9e..cf851e807e 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -45,7 +45,6 @@ #include "Windows/InputDevice.h" #endif - // Time until we stop considering the core active without user input. // Should this be configurable? 2 hours currently. static const double ACTIVITY_IDLE_TIMEOUT = 2.0 * 3600.0; @@ -385,6 +384,7 @@ const char *ExceptionTypeAsString(ExceptionType type) { switch (type) { case ExceptionType::MEMORY: return "Invalid Memory Access"; case ExceptionType::BREAK: return "Break"; + case ExceptionType::BAD_EXEC_ADDR: return "Bad Execution Address"; default: return "N/A"; } } diff --git a/Core/Core.h b/Core/Core.h index 6f210c739b..ef428595bd 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -93,6 +93,7 @@ enum class ExceptionType { NONE, MEMORY, BREAK, + BAD_EXEC_ADDR, }; struct ExceptionInfo { diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index 9ca3ee67b1..b8d99c078d 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -151,6 +151,7 @@ namespace MIPSInt void Int_Break(MIPSOpcode op) { + Reporting::ReportMessage("BREAK instruction hit"); Core_Break(); PC += 4; } diff --git a/Core/System.cpp b/Core/System.cpp index 9a6fcb1779..c8a8b4c769 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -97,7 +97,7 @@ bool coreCollectDebugStatsForced = false; // This can be read and written from ANYWHERE. volatile CoreState coreState = CORE_STEPPING; -// Note: intentionally not used for CORE_NEXTFRAME. << TODO: This comment is a lie, it is used! +// If true, core state has been changed, but JIT has probably not noticed yet. volatile bool coreStatePending = false; static volatile CPUThreadState cpuThreadState = CPU_THREAD_NOT_RUNNING; From 1010a07f65aba3f42c2f51345376230784c90159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Jul 2020 16:47:53 +0200 Subject: [PATCH 222/848] Expose more information on the crash screen (current kernel thread) --- Core/HLE/sceKernel.cpp | 6 ++++++ Core/HLE/sceKernel.h | 4 ++++ Core/HLE/sceKernelThread.cpp | 24 +++++++++++++----------- Core/HLE/sceKernelThread.h | 3 +++ UI/EmuScreen.cpp | 27 ++++++++++++++++++--------- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index ae804a4520..70d1f13ca6 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -297,6 +297,12 @@ bool __KernelIsRunning() { return kernelRunning; } +std::string __KernelStateSummary() { + std::string threadSummary = __KernelThreadingSummary(); + return StringFromFormat("%s", threadSummary.c_str()); +} + + void sceKernelExitGame() { INFO_LOG(SCEKERNEL, "sceKernelExitGame"); diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 96e94cb760..692d23ec89 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include "Common/Common.h" #include "Common/Swap.h" @@ -374,6 +375,9 @@ void __KernelDoState(PointerWrap &p); bool __KernelIsRunning(); bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param); +// For crash reporting. +std::string __KernelStateSummary(); + int sceKernelLoadExec(const char *filename, u32 paramPtr); void sceKernelExitGame(); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index c125764a8f..d892b2c1eb 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -372,6 +372,8 @@ public: class PSPThread : public KernelObject { public: + PSPThread() : debug(currentMIPS, context) {} + const char *GetName() override { return nt.name; } const char *GetTypeName() override { return "Thread"; } void GetQuickInfo(char *ptr, int size) override @@ -491,10 +493,6 @@ public: return true; } - PSPThread() : debug(currentMIPS, context) { - currentStack.start = 0; - } - // Can't use a destructor since savestates will call that too. void Cleanup() { @@ -573,14 +571,14 @@ public: } } - NativeThread nt; + NativeThread nt{}; - ThreadWaitInfo waitInfo; - SceUID moduleId; + ThreadWaitInfo waitInfo{}; + SceUID moduleId = -1; - bool isProcessingCallbacks; - u32 currentMipscallId; - SceUID currentCallbackId; + bool isProcessingCallbacks = false; + u32 currentMipscallId = -1; + SceUID currentCallbackId = -1; PSPThreadContext context; KernelThreadDebugInterface debug; @@ -597,7 +595,7 @@ public: // These are stacks that aren't "active" right now, but will pop off once the func returns. std::vector pushedStacks; - StackInfo currentStack; + StackInfo currentStack{}; // For thread end. std::vector waitingThreads; @@ -1184,6 +1182,10 @@ void __KernelThreadingShutdown() { pendingDeleteThreads.clear(); } +std::string __KernelThreadingSummary() { + return StringFromFormat("Cur thread: %s", __GetCurrentThread()->GetName()); +} + const char *__KernelGetThreadName(SceUID threadID) { u32 error; diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index a3fbbf1aeb..4c3041f65a 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -155,6 +155,9 @@ void __KernelThreadingInit(); void __KernelThreadingDoState(PointerWrap &p); void __KernelThreadingDoStateLate(PointerWrap &p); void __KernelThreadingShutdown(); + +std::string __KernelThreadingSummary(); + KernelObject *__KernelThreadObject(); KernelObject *__KernelCallbackObject(); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index e7367eda92..28c2159670 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1273,34 +1273,43 @@ static void DrawCrashDump(DrawBuffer *draw2d) { char versionString[256]; sprintf(versionString, "%s", PPSSPP_GIT_VERSION); // TODO: Draw a lot more information. Full register set, and so on. + +#ifdef _DEBUG + char build[] = "Debug"; +#else + char build[] = "Release"; +#endif snprintf(statbuf, sizeof(statbuf), R"(%s -Game ID: %s -Game Title: %s -PPSSPP: %s +Game ID (Title): %s (%s) +PPSSPP build: %s (%s) )", ExceptionTypeAsString(info.type), g_paramSFO.GetDiscID().c_str(), g_paramSFO.GetValueString("TITLE").c_str(), - versionString + versionString, + build ); draw2d->SetFontScale(.7f, .7f); int x = 20; int y = 50; draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + y += 100; if (info.type == ExceptionType::MEMORY) { snprintf(statbuf, sizeof(statbuf), R"( -Access Type: % s -Address: % 08x -PC: % 08x)", +Access: %s at %08x +PC: %08x)", MemoryExceptionTypeAsString(info.memory_type), info.address, info.pc); - - y += 150; draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + y += 120; } + + std::string kernelState = __KernelStateSummary(); + + draw2d->DrawTextShadow(ubuntu24, kernelState.c_str(), x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); } static void DrawAudioDebugStats(DrawBuffer *draw2d, const Bounds &bounds) { From d81452c60ccbfbf551527d87dce01d8339791b7d Mon Sep 17 00:00:00 2001 From: iota97 Date: Sun, 12 Jul 2020 17:22:14 +0200 Subject: [PATCH 223/848] Update v1.10.3 readme link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a45b103025..c8bfcac53f 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ For game compatibility, see [community compatibility feedback](https://report.pp What's new in 1.10.3 -------------------- -* Fix for control layout editor (#13125) +* Fix for control layout editor ([#13125](https://github.com/hrydgard/ppsspp/issues/13125)) What's new in 1.10.2 -------------------- From f6dfd5bda89ce0eda8d2fbb83114fcf39f77430c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Jul 2020 08:41:56 -0700 Subject: [PATCH 224/848] Travis: Use the default macOS image. We don't need to try to build and cache bottles since brew still supports this version with new binaries. --- .travis.sh | 56 ----------------------------------------------------- .travis.yml | 20 +++++++++++-------- 2 files changed, 12 insertions(+), 64 deletions(-) diff --git a/.travis.sh b/.travis.sh index eaa0e8eaf0..bdd4baa01c 100644 --- a/.travis.sh +++ b/.travis.sh @@ -21,64 +21,8 @@ download_extract_zip() { unzip $2 2>&1 | pv > /dev/null } -brew_make_bottle() { - echo "Rebuilding $1 as bottle..." - brew uninstall -f --ignore-dependencies $1 && brew install --ignore-dependencies --build-bottle $1 || true - brew bottle $1 && brew postinstall $1 || true - rm $HOME/Library/Caches/Homebrew/$1-*.bottle.*.tar.gz || true - mv ./$1-*.bottle.*.tar.gz $HOME/Library/Caches/Homebrew/ || true -} - travis_before_install() { git submodule update --init --recursive - - if [ "$TRAVIS_OS_NAME" = osx ]; then - # Depends on Python, wastes time updating... - brew uninstall -f mercurial || true - - # To check version numbers, we want jq. Try to cache this too. - for PKG in automake oniguruma; do - if ! brew info --json $PKG | grep built_as_bottle > /dev/null; then - if [ -f $HOME/Library/Caches/Homebrew/$PKG*.bottle.*.tar.gz ]; then - brew install -f $HOME/Library/Caches/Homebrew/$PKG*.bottle.*.tar.gz || true - else - brew_make_bottle $PKG - fi - fi - done - brew install jq || true - - # Try to install as many at once as possible. - TO_UPGRADE="" - TO_UNINSTALL="" - for PKG in ccache openssl@1.1 pyenv pkg-config readline gdbm sqlite xz python sdl2; do - PKG_VER="`brew info $PKG --json | jq '.[0].versions.stable' | tr -d '"'`" - if [ -f $HOME/Library/Caches/Homebrew/$PKG--$PKG_VER*.bottle.*.tar.gz ]; then - TO_UPGRADE="$TO_UPGRADE $HOME/Library/Caches/Homebrew/$PKG--$PKG_VER*.bottle.*.tar.gz" - TO_UNINSTALL="$TO_UNINSTALL $PKG" - fi - done - - for PKG in ccache openssl@1.1 pyenv pkg-config readline gdbm sqlite xz python sdl2; do - PKG_VER="`brew info $PKG --json | jq '.[0].versions.stable' | tr -d '"'`" - if [ ! -f $HOME/Library/Caches/Homebrew/$PKG--$PKG_VER*.bottle.*.tar.gz ]; then - brew_make_bottle $PKG - fi - done - - if [ "$TO_UPGRADE" != "" ]; then - brew uninstall -f --ignore-dependencies $TO_UNINSTALL - brew install -f --ignore-dependencies $TO_UPGRADE || true - fi - - # In case there were issues with all at once, now let's try installing any others from cache. - for PKG in ccache openssl@1.1 pyenv pkg-config readline gdbm sqlite xz python sdl2; do - PKG_VER="`brew info $PKG --json | jq '.[0].versions.stable' | tr -d '"'`" - if [ -f $HOME/Library/Caches/Homebrew/$PKG--$PKG_VER*.bottle.*.tar.gz ]; then - brew upgrade $HOME/Library/Caches/Homebrew/$PKG--$PKG_VER*.bottle.*.tar.gz || brew install -f $HOME/Library/Caches/Homebrew/$PKG-*.bottle.*.tar.gz || true - fi - done - fi } travis_install() { diff --git a/.travis.yml b/.travis.yml index b4b8105a4e..a9a454f062 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,10 @@ addons: - sourceline: 'ppa:ubuntu-sdk-team/ppa' homebrew: update: true + packages: + - ccache + - python + - sdl2 cache: apt: true @@ -85,6 +89,14 @@ jobs: compiler: "clang" env: PPSSPP_BUILD_TYPE=Linux LIBRETRO=TRUE + - os: osx + osx_image: xcode9.4 + compiler: "clang" + env: PPSSPP_BUILD_TYPE=macOS + - os: osx + osx_image: xcode9.4 + compiler: "clang" + env: PPSSPP_BUILD_TYPE=iOS - os: windows compiler: "msvc2017" env: PPSSPP_BUILD_TYPE=Windows @@ -92,14 +104,6 @@ jobs: compiler: "msvc2017" env: PPSSPP_BUILD_TYPE=Windows UWP=TRUE -# - os: osx -# osx_image: xcode9 -# compiler: "clang" -# env: PPSSPP_BUILD_TYPE=macOS -# - os: osx -# osx_image: xcode9 -# compiler: "clang" -# env: PPSSPP_BUILD_TYPE=iOS before_install: - travis_retry bash .travis.sh travis_before_install From f958ed5817f7e910ce7d790c2499f9d27d61afa8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 12 Jul 2020 23:51:57 +0200 Subject: [PATCH 225/848] Add custom GLEW - interfaces with libretro get_proc_address - we need this for compatibility with DRM/KMS and Wayland contexts - otherwise we're limited to GLX context --- assets/lang | 2 +- ext/native/gfx_es2/gpu_features.cpp | 2 +- libretro/LibretroGraphicsContext.cpp | 9 +- libretro/Makefile.common | 2 +- libretro/ext/glew/glew.c | 22979 +++++++++++++++++++++++++ 5 files changed, 22990 insertions(+), 4 deletions(-) create mode 100644 libretro/ext/glew/glew.c diff --git a/assets/lang b/assets/lang index 1c64b8fbd3..942934a3d5 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 1c64b8fbd3cb6bd87935eb53f302f7de6f86e209 +Subproject commit 942934a3d55f600622fb3f3ad60ecc1f3da23b6b diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index ca4df8c26a..e22b702e21 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -315,7 +315,7 @@ void CheckGLExtensions() { ParseExtensionsString(g_all_gl_extensions, g_set_gl_extensions); } -#ifdef WIN32 +#if defined(WIN32) && !defined(__LIBRETRO__) const char *wglString = 0; if (wglGetExtensionsStringEXT) wglString = wglGetExtensionsStringEXT(); diff --git a/libretro/LibretroGraphicsContext.cpp b/libretro/LibretroGraphicsContext.cpp index 508353f6bb..b88e6893b2 100644 --- a/libretro/LibretroGraphicsContext.cpp +++ b/libretro/LibretroGraphicsContext.cpp @@ -14,13 +14,20 @@ retro_video_refresh_t LibretroGraphicsContext::video_cb; +extern "C" { + retro_hw_get_proc_address_t libretro_get_proc_address; +}; + void retro_set_video_refresh(retro_video_refresh_t cb) { LibretroGraphicsContext::video_cb = cb; } static void context_reset() { ((LibretroHWRenderContext *)Libretro::ctx)->ContextReset(); } static void context_destroy() { ((LibretroHWRenderContext *)Libretro::ctx)->ContextDestroy(); } bool LibretroHWRenderContext::Init(bool cache_context) { hw_render_.cache_context = cache_context; - return Libretro::environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render_); + if (!Libretro::environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER, &hw_render_)) + return false; + libretro_get_proc_address = hw_render_.get_proc_address; + return true; } LibretroHWRenderContext::LibretroHWRenderContext(retro_hw_context_type context_type, unsigned version_major, unsigned version_minor) { diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 6af1da0886..ab7d30ebdf 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -95,7 +95,7 @@ ifeq ($(PLATFORM_EXT), android) $(NATIVEDIR)/math/fast/fast_matrix.c endif -SOURCES_C += $(EXTDIR)/glew/glew.c +SOURCES_C += $(LIBRETRODIR)/ext/glew/glew.c SOURCES_C += \ $(EXTDIR)/libkirk/AES.c \ diff --git a/libretro/ext/glew/glew.c b/libretro/ext/glew/glew.c new file mode 100644 index 0000000000..b1da292894 --- /dev/null +++ b/libretro/ext/glew/glew.c @@ -0,0 +1,22979 @@ +/* +** The OpenGL Extension Wrangler Library +** Copyright (C) 2008-2017, Nigel Stewart +** Copyright (C) 2002-2008, Milan Ikits +** Copyright (C) 2002-2008, Marcelo E. Magallon +** Copyright (C) 2002, Lev Povalahev +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** * The name of the author may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +** THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include /* For size_t */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern retro_hw_get_proc_address_t libretro_get_proc_address; + +#ifdef __cplusplus +} +#endif + +/* + * Define GLboolean const cast. + */ +#define CONST_CAST(x) (*(GLboolean*)&x) + +/* + * Define glewGetProcAddress. + */ +#define glewGetProcAddress(name) libretro_get_proc_address((name)) + +/* + * GLEW, just like OpenGL or GLU, does not rely on the standard C library. + * These functions implement the functionality required in this file. + */ + +static GLuint _glewStrLen (const GLubyte* s) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0') i++; + return i; +} + +static GLuint _glewStrCLen (const GLubyte* s, GLubyte c) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) i++; + return i; +} + +static GLuint _glewStrCopy(char *d, const char *s, char c) +{ + GLuint i=0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) { d[i] = s[i]; i++; } + d[i] = '\0'; + return i; +} + +#if !defined(GLEW_OSMESA) +#if !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n) +{ + GLuint i=0; + if(a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; + return i == n ? GL_TRUE : GL_FALSE; +} +#endif +#endif + +static GLboolean _glewStrSame1 (const GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + while (*na > 0 && (**a == ' ' || **a == '\n' || **a == '\r' || **a == '\t')) + { + (*a)++; + (*na)--; + } + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if(i == nb) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +static GLboolean _glewStrSame2 (const GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if(i == nb) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +static GLboolean _glewStrSame3 (const GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb) +{ + if(*na >= nb) + { + GLuint i=0; + while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++; + if (i == nb && (*na == nb || (*a)[i] == ' ' || (*a)[i] == '\n' || (*a)[i] == '\r' || (*a)[i] == '\t')) + { + *a = *a + nb; + *na = *na - nb; + return GL_TRUE; + } + } + return GL_FALSE; +} + +/* + * Search for name in the extensions string. Use of strstr() + * is not sufficient because extension names can be prefixes of + * other extension names. Could use strtok() but the constant + * string returned by glGetString might be in read-only memory. + */ +#if !defined(GLEW_OSMESA) +#if !defined(__APPLE__) || defined(GLEW_APPLE_GLX) +static GLboolean _glewSearchExtension (const char* name, const GLubyte *start, const GLubyte *end) +{ + const GLubyte* p; + GLuint len = _glewStrLen((const GLubyte*)name); + p = start; + while (p < end) + { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE; + p += n+1; + } + return GL_FALSE; +} +#endif +#endif + +PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D = NULL; +PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements = NULL; +PFNGLTEXIMAGE3DPROC __glewTexImage3D = NULL; +PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D = NULL; + +PFNGLACTIVETEXTUREPROC __glewActiveTexture = NULL; +PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture = NULL; +PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage = NULL; +PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd = NULL; +PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf = NULL; +PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd = NULL; +PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf = NULL; +PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d = NULL; +PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv = NULL; +PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f = NULL; +PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv = NULL; +PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i = NULL; +PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv = NULL; +PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s = NULL; +PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv = NULL; +PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d = NULL; +PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv = NULL; +PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f = NULL; +PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv = NULL; +PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i = NULL; +PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv = NULL; +PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s = NULL; +PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv = NULL; +PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d = NULL; +PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv = NULL; +PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f = NULL; +PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv = NULL; +PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i = NULL; +PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv = NULL; +PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s = NULL; +PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv = NULL; +PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d = NULL; +PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv = NULL; +PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f = NULL; +PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv = NULL; +PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i = NULL; +PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv = NULL; +PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s = NULL; +PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv = NULL; +PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage = NULL; + +PFNGLBLENDCOLORPROC __glewBlendColor = NULL; +PFNGLBLENDEQUATIONPROC __glewBlendEquation = NULL; +PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate = NULL; +PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer = NULL; +PFNGLFOGCOORDDPROC __glewFogCoordd = NULL; +PFNGLFOGCOORDDVPROC __glewFogCoorddv = NULL; +PFNGLFOGCOORDFPROC __glewFogCoordf = NULL; +PFNGLFOGCOORDFVPROC __glewFogCoordfv = NULL; +PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays = NULL; +PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements = NULL; +PFNGLPOINTPARAMETERFPROC __glewPointParameterf = NULL; +PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv = NULL; +PFNGLPOINTPARAMETERIPROC __glewPointParameteri = NULL; +PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv = NULL; +PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b = NULL; +PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv = NULL; +PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d = NULL; +PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv = NULL; +PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f = NULL; +PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv = NULL; +PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i = NULL; +PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv = NULL; +PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s = NULL; +PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv = NULL; +PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub = NULL; +PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv = NULL; +PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui = NULL; +PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv = NULL; +PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us = NULL; +PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv = NULL; +PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer = NULL; +PFNGLWINDOWPOS2DPROC __glewWindowPos2d = NULL; +PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv = NULL; +PFNGLWINDOWPOS2FPROC __glewWindowPos2f = NULL; +PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv = NULL; +PFNGLWINDOWPOS2IPROC __glewWindowPos2i = NULL; +PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv = NULL; +PFNGLWINDOWPOS2SPROC __glewWindowPos2s = NULL; +PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv = NULL; +PFNGLWINDOWPOS3DPROC __glewWindowPos3d = NULL; +PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv = NULL; +PFNGLWINDOWPOS3FPROC __glewWindowPos3f = NULL; +PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv = NULL; +PFNGLWINDOWPOS3IPROC __glewWindowPos3i = NULL; +PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv = NULL; +PFNGLWINDOWPOS3SPROC __glewWindowPos3s = NULL; +PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv = NULL; + +PFNGLBEGINQUERYPROC __glewBeginQuery = NULL; +PFNGLBINDBUFFERPROC __glewBindBuffer = NULL; +PFNGLBUFFERDATAPROC __glewBufferData = NULL; +PFNGLBUFFERSUBDATAPROC __glewBufferSubData = NULL; +PFNGLDELETEBUFFERSPROC __glewDeleteBuffers = NULL; +PFNGLDELETEQUERIESPROC __glewDeleteQueries = NULL; +PFNGLENDQUERYPROC __glewEndQuery = NULL; +PFNGLGENBUFFERSPROC __glewGenBuffers = NULL; +PFNGLGENQUERIESPROC __glewGenQueries = NULL; +PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv = NULL; +PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv = NULL; +PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData = NULL; +PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv = NULL; +PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv = NULL; +PFNGLGETQUERYIVPROC __glewGetQueryiv = NULL; +PFNGLISBUFFERPROC __glewIsBuffer = NULL; +PFNGLISQUERYPROC __glewIsQuery = NULL; +PFNGLMAPBUFFERPROC __glewMapBuffer = NULL; +PFNGLUNMAPBUFFERPROC __glewUnmapBuffer = NULL; + +PFNGLATTACHSHADERPROC __glewAttachShader = NULL; +PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation = NULL; +PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate = NULL; +PFNGLCOMPILESHADERPROC __glewCompileShader = NULL; +PFNGLCREATEPROGRAMPROC __glewCreateProgram = NULL; +PFNGLCREATESHADERPROC __glewCreateShader = NULL; +PFNGLDELETEPROGRAMPROC __glewDeleteProgram = NULL; +PFNGLDELETESHADERPROC __glewDeleteShader = NULL; +PFNGLDETACHSHADERPROC __glewDetachShader = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray = NULL; +PFNGLDRAWBUFFERSPROC __glewDrawBuffers = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray = NULL; +PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform = NULL; +PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation = NULL; +PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog = NULL; +PFNGLGETPROGRAMIVPROC __glewGetProgramiv = NULL; +PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog = NULL; +PFNGLGETSHADERSOURCEPROC __glewGetShaderSource = NULL; +PFNGLGETSHADERIVPROC __glewGetShaderiv = NULL; +PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC __glewGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC __glewGetUniformiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv = NULL; +PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv = NULL; +PFNGLISPROGRAMPROC __glewIsProgram = NULL; +PFNGLISSHADERPROC __glewIsShader = NULL; +PFNGLLINKPROGRAMPROC __glewLinkProgram = NULL; +PFNGLSHADERSOURCEPROC __glewShaderSource = NULL; +PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate = NULL; +PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate = NULL; +PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate = NULL; +PFNGLUNIFORM1FPROC __glewUniform1f = NULL; +PFNGLUNIFORM1FVPROC __glewUniform1fv = NULL; +PFNGLUNIFORM1IPROC __glewUniform1i = NULL; +PFNGLUNIFORM1IVPROC __glewUniform1iv = NULL; +PFNGLUNIFORM2FPROC __glewUniform2f = NULL; +PFNGLUNIFORM2FVPROC __glewUniform2fv = NULL; +PFNGLUNIFORM2IPROC __glewUniform2i = NULL; +PFNGLUNIFORM2IVPROC __glewUniform2iv = NULL; +PFNGLUNIFORM3FPROC __glewUniform3f = NULL; +PFNGLUNIFORM3FVPROC __glewUniform3fv = NULL; +PFNGLUNIFORM3IPROC __glewUniform3i = NULL; +PFNGLUNIFORM3IVPROC __glewUniform3iv = NULL; +PFNGLUNIFORM4FPROC __glewUniform4f = NULL; +PFNGLUNIFORM4FVPROC __glewUniform4fv = NULL; +PFNGLUNIFORM4IPROC __glewUniform4i = NULL; +PFNGLUNIFORM4IVPROC __glewUniform4iv = NULL; +PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv = NULL; +PFNGLUSEPROGRAMPROC __glewUseProgram = NULL; +PFNGLVALIDATEPROGRAMPROC __glewValidateProgram = NULL; +PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer = NULL; + +PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv = NULL; +PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv = NULL; +PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv = NULL; +PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv = NULL; +PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv = NULL; +PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv = NULL; + +PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender = NULL; +PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback = NULL; +PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation = NULL; +PFNGLCLAMPCOLORPROC __glewClampColor = NULL; +PFNGLCLEARBUFFERFIPROC __glewClearBufferfi = NULL; +PFNGLCLEARBUFFERFVPROC __glewClearBufferfv = NULL; +PFNGLCLEARBUFFERIVPROC __glewClearBufferiv = NULL; +PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv = NULL; +PFNGLCOLORMASKIPROC __glewColorMaski = NULL; +PFNGLDISABLEIPROC __glewDisablei = NULL; +PFNGLENABLEIPROC __glewEnablei = NULL; +PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback = NULL; +PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v = NULL; +PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation = NULL; +PFNGLGETSTRINGIPROC __glewGetStringi = NULL; +PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv = NULL; +PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying = NULL; +PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv = NULL; +PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv = NULL; +PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv = NULL; +PFNGLISENABLEDIPROC __glewIsEnabledi = NULL; +PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv = NULL; +PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings = NULL; +PFNGLUNIFORM1UIPROC __glewUniform1ui = NULL; +PFNGLUNIFORM1UIVPROC __glewUniform1uiv = NULL; +PFNGLUNIFORM2UIPROC __glewUniform2ui = NULL; +PFNGLUNIFORM2UIVPROC __glewUniform2uiv = NULL; +PFNGLUNIFORM3UIPROC __glewUniform3ui = NULL; +PFNGLUNIFORM3UIVPROC __glewUniform3uiv = NULL; +PFNGLUNIFORM4UIPROC __glewUniform4ui = NULL; +PFNGLUNIFORM4UIVPROC __glewUniform4uiv = NULL; +PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i = NULL; +PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv = NULL; +PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui = NULL; +PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv = NULL; +PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i = NULL; +PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv = NULL; +PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui = NULL; +PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv = NULL; +PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i = NULL; +PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv = NULL; +PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui = NULL; +PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv = NULL; +PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv = NULL; +PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i = NULL; +PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv = NULL; +PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv = NULL; +PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv = NULL; +PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui = NULL; +PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv = NULL; +PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv = NULL; +PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer = NULL; + +PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced = NULL; +PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced = NULL; +PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex = NULL; +PFNGLTEXBUFFERPROC __glewTexBuffer = NULL; + +PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture = NULL; +PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v = NULL; +PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v = NULL; + +PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor = NULL; + +PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei = NULL; +PFNGLBLENDEQUATIONIPROC __glewBlendEquationi = NULL; +PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei = NULL; +PFNGLBLENDFUNCIPROC __glewBlendFunci = NULL; +PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading = NULL; + +PFNGLGETGRAPHICSRESETSTATUSPROC __glewGetGraphicsResetStatus = NULL; +PFNGLGETNCOMPRESSEDTEXIMAGEPROC __glewGetnCompressedTexImage = NULL; +PFNGLGETNTEXIMAGEPROC __glewGetnTexImage = NULL; +PFNGLGETNUNIFORMDVPROC __glewGetnUniformdv = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC __glewMultiDrawArraysIndirectCount = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC __glewMultiDrawElementsIndirectCount = NULL; +PFNGLSPECIALIZESHADERPROC __glewSpecializeShader = NULL; + +PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL; + +PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD = NULL; +PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD = NULL; +PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD = NULL; +PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD = NULL; + +PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD = NULL; +PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD = NULL; +PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD = NULL; +PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD = NULL; + +PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewFramebufferSamplePositionsfvAMD = NULL; +PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC __glewGetFramebufferParameterfvAMD = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC __glewGetNamedFramebufferParameterfvAMD = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC __glewNamedFramebufferSamplePositionsfvAMD = NULL; + +PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD = NULL; + +PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD = NULL; +PFNGLGENNAMESAMDPROC __glewGenNamesAMD = NULL; +PFNGLISNAMEAMDPROC __glewIsNameAMD = NULL; + +PFNGLQUERYOBJECTPARAMETERUIAMDPROC __glewQueryObjectParameteruiAMD = NULL; + +PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD = NULL; +PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD = NULL; +PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD = NULL; +PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD = NULL; +PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD = NULL; +PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD = NULL; +PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD = NULL; +PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD = NULL; +PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD = NULL; +PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD = NULL; +PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD = NULL; + +PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD = NULL; + +PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD = NULL; +PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD = NULL; + +PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD = NULL; + +PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD = NULL; +PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD = NULL; + +PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE = NULL; + +PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE = NULL; +PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE = NULL; +PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE = NULL; + +PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE = NULL; +PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE = NULL; +PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE = NULL; +PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE = NULL; +PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE = NULL; +PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE = NULL; +PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE = NULL; +PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE = NULL; +PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE = NULL; +PFNGLISQUERYANGLEPROC __glewIsQueryANGLE = NULL; +PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE = NULL; + +PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE = NULL; + +PFNGLCOPYTEXTURELEVELSAPPLEPROC __glewCopyTextureLevelsAPPLE = NULL; + +PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE = NULL; +PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE = NULL; +PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE = NULL; +PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE = NULL; +PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE = NULL; + +PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE = NULL; +PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE = NULL; +PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE = NULL; +PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE = NULL; +PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE = NULL; +PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE = NULL; +PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE = NULL; +PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE = NULL; + +PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC __glewRenderbufferStorageMultisampleAPPLE = NULL; +PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC __glewResolveMultisampleFramebufferAPPLE = NULL; + +PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE = NULL; +PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE = NULL; +PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE = NULL; + +PFNGLCLIENTWAITSYNCAPPLEPROC __glewClientWaitSyncAPPLE = NULL; +PFNGLDELETESYNCAPPLEPROC __glewDeleteSyncAPPLE = NULL; +PFNGLFENCESYNCAPPLEPROC __glewFenceSyncAPPLE = NULL; +PFNGLGETINTEGER64VAPPLEPROC __glewGetInteger64vAPPLE = NULL; +PFNGLGETSYNCIVAPPLEPROC __glewGetSyncivAPPLE = NULL; +PFNGLISSYNCAPPLEPROC __glewIsSyncAPPLE = NULL; +PFNGLWAITSYNCAPPLEPROC __glewWaitSyncAPPLE = NULL; + +PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE = NULL; +PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE = NULL; + +PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE = NULL; +PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE = NULL; +PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE = NULL; +PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE = NULL; + +PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE = NULL; +PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE = NULL; +PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE = NULL; + +PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE = NULL; +PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE = NULL; +PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE = NULL; +PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE = NULL; +PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE = NULL; +PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE = NULL; +PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE = NULL; + +PFNGLCLEARDEPTHFPROC __glewClearDepthf = NULL; +PFNGLDEPTHRANGEFPROC __glewDepthRangef = NULL; +PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat = NULL; +PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler = NULL; +PFNGLSHADERBINARYPROC __glewShaderBinary = NULL; + +PFNGLMEMORYBARRIERBYREGIONPROC __glewMemoryBarrierByRegion = NULL; + +PFNGLPRIMITIVEBOUNDINGBOXARBPROC __glewPrimitiveBoundingBoxARB = NULL; + +PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance = NULL; + +PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB = NULL; +PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB = NULL; +PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB = NULL; +PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB = NULL; +PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB = NULL; +PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB = NULL; +PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB = NULL; +PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB = NULL; +PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB = NULL; +PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB = NULL; +PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB = NULL; +PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB = NULL; +PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB = NULL; +PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB = NULL; + +PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed = NULL; +PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex = NULL; + +PFNGLBUFFERSTORAGEPROC __glewBufferStorage = NULL; + +PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB = NULL; + +PFNGLCLEARBUFFERDATAPROC __glewClearBufferData = NULL; +PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData = NULL; +PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT = NULL; +PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT = NULL; + +PFNGLCLEARTEXIMAGEPROC __glewClearTexImage = NULL; +PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage = NULL; + +PFNGLCLIPCONTROLPROC __glewClipControl = NULL; + +PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL; + +PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute = NULL; +PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect = NULL; + +PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB = NULL; + +PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData = NULL; + +PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData = NULL; + +PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB = NULL; +PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB = NULL; +PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB = NULL; +PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB = NULL; + +PFNGLBINDTEXTUREUNITPROC __glewBindTextureUnit = NULL; +PFNGLBLITNAMEDFRAMEBUFFERPROC __glewBlitNamedFramebuffer = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC __glewCheckNamedFramebufferStatus = NULL; +PFNGLCLEARNAMEDBUFFERDATAPROC __glewClearNamedBufferData = NULL; +PFNGLCLEARNAMEDBUFFERSUBDATAPROC __glewClearNamedBufferSubData = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERFIPROC __glewClearNamedFramebufferfi = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERFVPROC __glewClearNamedFramebufferfv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERIVPROC __glewClearNamedFramebufferiv = NULL; +PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC __glewClearNamedFramebufferuiv = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC __glewCompressedTextureSubImage1D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC __glewCompressedTextureSubImage2D = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC __glewCompressedTextureSubImage3D = NULL; +PFNGLCOPYNAMEDBUFFERSUBDATAPROC __glewCopyNamedBufferSubData = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DPROC __glewCopyTextureSubImage1D = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DPROC __glewCopyTextureSubImage2D = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DPROC __glewCopyTextureSubImage3D = NULL; +PFNGLCREATEBUFFERSPROC __glewCreateBuffers = NULL; +PFNGLCREATEFRAMEBUFFERSPROC __glewCreateFramebuffers = NULL; +PFNGLCREATEPROGRAMPIPELINESPROC __glewCreateProgramPipelines = NULL; +PFNGLCREATEQUERIESPROC __glewCreateQueries = NULL; +PFNGLCREATERENDERBUFFERSPROC __glewCreateRenderbuffers = NULL; +PFNGLCREATESAMPLERSPROC __glewCreateSamplers = NULL; +PFNGLCREATETEXTURESPROC __glewCreateTextures = NULL; +PFNGLCREATETRANSFORMFEEDBACKSPROC __glewCreateTransformFeedbacks = NULL; +PFNGLCREATEVERTEXARRAYSPROC __glewCreateVertexArrays = NULL; +PFNGLDISABLEVERTEXARRAYATTRIBPROC __glewDisableVertexArrayAttrib = NULL; +PFNGLENABLEVERTEXARRAYATTRIBPROC __glewEnableVertexArrayAttrib = NULL; +PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC __glewFlushMappedNamedBufferRange = NULL; +PFNGLGENERATETEXTUREMIPMAPPROC __glewGenerateTextureMipmap = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC __glewGetCompressedTextureImage = NULL; +PFNGLGETNAMEDBUFFERPARAMETERI64VPROC __glewGetNamedBufferParameteri64v = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVPROC __glewGetNamedBufferParameteriv = NULL; +PFNGLGETNAMEDBUFFERPOINTERVPROC __glewGetNamedBufferPointerv = NULL; +PFNGLGETNAMEDBUFFERSUBDATAPROC __glewGetNamedBufferSubData = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetNamedFramebufferAttachmentParameteriv = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC __glewGetNamedFramebufferParameteriv = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC __glewGetNamedRenderbufferParameteriv = NULL; +PFNGLGETQUERYBUFFEROBJECTI64VPROC __glewGetQueryBufferObjecti64v = NULL; +PFNGLGETQUERYBUFFEROBJECTIVPROC __glewGetQueryBufferObjectiv = NULL; +PFNGLGETQUERYBUFFEROBJECTUI64VPROC __glewGetQueryBufferObjectui64v = NULL; +PFNGLGETQUERYBUFFEROBJECTUIVPROC __glewGetQueryBufferObjectuiv = NULL; +PFNGLGETTEXTUREIMAGEPROC __glewGetTextureImage = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVPROC __glewGetTextureLevelParameterfv = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVPROC __glewGetTextureLevelParameteriv = NULL; +PFNGLGETTEXTUREPARAMETERIIVPROC __glewGetTextureParameterIiv = NULL; +PFNGLGETTEXTUREPARAMETERIUIVPROC __glewGetTextureParameterIuiv = NULL; +PFNGLGETTEXTUREPARAMETERFVPROC __glewGetTextureParameterfv = NULL; +PFNGLGETTEXTUREPARAMETERIVPROC __glewGetTextureParameteriv = NULL; +PFNGLGETTRANSFORMFEEDBACKI64_VPROC __glewGetTransformFeedbacki64_v = NULL; +PFNGLGETTRANSFORMFEEDBACKI_VPROC __glewGetTransformFeedbacki_v = NULL; +PFNGLGETTRANSFORMFEEDBACKIVPROC __glewGetTransformFeedbackiv = NULL; +PFNGLGETVERTEXARRAYINDEXED64IVPROC __glewGetVertexArrayIndexed64iv = NULL; +PFNGLGETVERTEXARRAYINDEXEDIVPROC __glewGetVertexArrayIndexediv = NULL; +PFNGLGETVERTEXARRAYIVPROC __glewGetVertexArrayiv = NULL; +PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC __glewInvalidateNamedFramebufferData = NULL; +PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC __glewInvalidateNamedFramebufferSubData = NULL; +PFNGLMAPNAMEDBUFFERPROC __glewMapNamedBuffer = NULL; +PFNGLMAPNAMEDBUFFERRANGEPROC __glewMapNamedBufferRange = NULL; +PFNGLNAMEDBUFFERDATAPROC __glewNamedBufferData = NULL; +PFNGLNAMEDBUFFERSTORAGEPROC __glewNamedBufferStorage = NULL; +PFNGLNAMEDBUFFERSUBDATAPROC __glewNamedBufferSubData = NULL; +PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC __glewNamedFramebufferDrawBuffer = NULL; +PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC __glewNamedFramebufferDrawBuffers = NULL; +PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC __glewNamedFramebufferParameteri = NULL; +PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC __glewNamedFramebufferReadBuffer = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC __glewNamedFramebufferRenderbuffer = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREPROC __glewNamedFramebufferTexture = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC __glewNamedFramebufferTextureLayer = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEPROC __glewNamedRenderbufferStorage = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewNamedRenderbufferStorageMultisample = NULL; +PFNGLTEXTUREBUFFERPROC __glewTextureBuffer = NULL; +PFNGLTEXTUREBUFFERRANGEPROC __glewTextureBufferRange = NULL; +PFNGLTEXTUREPARAMETERIIVPROC __glewTextureParameterIiv = NULL; +PFNGLTEXTUREPARAMETERIUIVPROC __glewTextureParameterIuiv = NULL; +PFNGLTEXTUREPARAMETERFPROC __glewTextureParameterf = NULL; +PFNGLTEXTUREPARAMETERFVPROC __glewTextureParameterfv = NULL; +PFNGLTEXTUREPARAMETERIPROC __glewTextureParameteri = NULL; +PFNGLTEXTUREPARAMETERIVPROC __glewTextureParameteriv = NULL; +PFNGLTEXTURESTORAGE1DPROC __glewTextureStorage1D = NULL; +PFNGLTEXTURESTORAGE2DPROC __glewTextureStorage2D = NULL; +PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC __glewTextureStorage2DMultisample = NULL; +PFNGLTEXTURESTORAGE3DPROC __glewTextureStorage3D = NULL; +PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC __glewTextureStorage3DMultisample = NULL; +PFNGLTEXTURESUBIMAGE1DPROC __glewTextureSubImage1D = NULL; +PFNGLTEXTURESUBIMAGE2DPROC __glewTextureSubImage2D = NULL; +PFNGLTEXTURESUBIMAGE3DPROC __glewTextureSubImage3D = NULL; +PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC __glewTransformFeedbackBufferBase = NULL; +PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC __glewTransformFeedbackBufferRange = NULL; +PFNGLUNMAPNAMEDBUFFERPROC __glewUnmapNamedBuffer = NULL; +PFNGLVERTEXARRAYATTRIBBINDINGPROC __glewVertexArrayAttribBinding = NULL; +PFNGLVERTEXARRAYATTRIBFORMATPROC __glewVertexArrayAttribFormat = NULL; +PFNGLVERTEXARRAYATTRIBIFORMATPROC __glewVertexArrayAttribIFormat = NULL; +PFNGLVERTEXARRAYATTRIBLFORMATPROC __glewVertexArrayAttribLFormat = NULL; +PFNGLVERTEXARRAYBINDINGDIVISORPROC __glewVertexArrayBindingDivisor = NULL; +PFNGLVERTEXARRAYELEMENTBUFFERPROC __glewVertexArrayElementBuffer = NULL; +PFNGLVERTEXARRAYVERTEXBUFFERPROC __glewVertexArrayVertexBuffer = NULL; +PFNGLVERTEXARRAYVERTEXBUFFERSPROC __glewVertexArrayVertexBuffers = NULL; + +PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL; + +PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB = NULL; +PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB = NULL; +PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB = NULL; +PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB = NULL; + +PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex = NULL; + +PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect = NULL; +PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect = NULL; + +PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv = NULL; +PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT = NULL; +PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT = NULL; + +PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer = NULL; +PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer = NULL; +PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus = NULL; +PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL; +PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer = NULL; +PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers = NULL; +PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers = NULL; +PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv = NULL; +PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer = NULL; +PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer = NULL; +PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample = NULL; + +PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB = NULL; +PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB = NULL; + +PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary = NULL; +PFNGLPROGRAMBINARYPROC __glewProgramBinary = NULL; +PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri = NULL; + +PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC __glewGetCompressedTextureSubImage = NULL; +PFNGLGETTEXTURESUBIMAGEPROC __glewGetTextureSubImage = NULL; + +PFNGLSPECIALIZESHADERARBPROC __glewSpecializeShaderARB = NULL; + +PFNGLGETUNIFORMDVPROC __glewGetUniformdv = NULL; +PFNGLUNIFORM1DPROC __glewUniform1d = NULL; +PFNGLUNIFORM1DVPROC __glewUniform1dv = NULL; +PFNGLUNIFORM2DPROC __glewUniform2d = NULL; +PFNGLUNIFORM2DVPROC __glewUniform2dv = NULL; +PFNGLUNIFORM3DPROC __glewUniform3d = NULL; +PFNGLUNIFORM3DVPROC __glewUniform3dv = NULL; +PFNGLUNIFORM4DPROC __glewUniform4d = NULL; +PFNGLUNIFORM4DVPROC __glewUniform4dv = NULL; +PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv = NULL; +PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv = NULL; +PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv = NULL; +PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv = NULL; +PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv = NULL; +PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv = NULL; +PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv = NULL; +PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv = NULL; +PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv = NULL; + +PFNGLGETUNIFORMI64VARBPROC __glewGetUniformi64vARB = NULL; +PFNGLGETUNIFORMUI64VARBPROC __glewGetUniformui64vARB = NULL; +PFNGLGETNUNIFORMI64VARBPROC __glewGetnUniformi64vARB = NULL; +PFNGLGETNUNIFORMUI64VARBPROC __glewGetnUniformui64vARB = NULL; +PFNGLPROGRAMUNIFORM1I64ARBPROC __glewProgramUniform1i64ARB = NULL; +PFNGLPROGRAMUNIFORM1I64VARBPROC __glewProgramUniform1i64vARB = NULL; +PFNGLPROGRAMUNIFORM1UI64ARBPROC __glewProgramUniform1ui64ARB = NULL; +PFNGLPROGRAMUNIFORM1UI64VARBPROC __glewProgramUniform1ui64vARB = NULL; +PFNGLPROGRAMUNIFORM2I64ARBPROC __glewProgramUniform2i64ARB = NULL; +PFNGLPROGRAMUNIFORM2I64VARBPROC __glewProgramUniform2i64vARB = NULL; +PFNGLPROGRAMUNIFORM2UI64ARBPROC __glewProgramUniform2ui64ARB = NULL; +PFNGLPROGRAMUNIFORM2UI64VARBPROC __glewProgramUniform2ui64vARB = NULL; +PFNGLPROGRAMUNIFORM3I64ARBPROC __glewProgramUniform3i64ARB = NULL; +PFNGLPROGRAMUNIFORM3I64VARBPROC __glewProgramUniform3i64vARB = NULL; +PFNGLPROGRAMUNIFORM3UI64ARBPROC __glewProgramUniform3ui64ARB = NULL; +PFNGLPROGRAMUNIFORM3UI64VARBPROC __glewProgramUniform3ui64vARB = NULL; +PFNGLPROGRAMUNIFORM4I64ARBPROC __glewProgramUniform4i64ARB = NULL; +PFNGLPROGRAMUNIFORM4I64VARBPROC __glewProgramUniform4i64vARB = NULL; +PFNGLPROGRAMUNIFORM4UI64ARBPROC __glewProgramUniform4ui64ARB = NULL; +PFNGLPROGRAMUNIFORM4UI64VARBPROC __glewProgramUniform4ui64vARB = NULL; +PFNGLUNIFORM1I64ARBPROC __glewUniform1i64ARB = NULL; +PFNGLUNIFORM1I64VARBPROC __glewUniform1i64vARB = NULL; +PFNGLUNIFORM1UI64ARBPROC __glewUniform1ui64ARB = NULL; +PFNGLUNIFORM1UI64VARBPROC __glewUniform1ui64vARB = NULL; +PFNGLUNIFORM2I64ARBPROC __glewUniform2i64ARB = NULL; +PFNGLUNIFORM2I64VARBPROC __glewUniform2i64vARB = NULL; +PFNGLUNIFORM2UI64ARBPROC __glewUniform2ui64ARB = NULL; +PFNGLUNIFORM2UI64VARBPROC __glewUniform2ui64vARB = NULL; +PFNGLUNIFORM3I64ARBPROC __glewUniform3i64ARB = NULL; +PFNGLUNIFORM3I64VARBPROC __glewUniform3i64vARB = NULL; +PFNGLUNIFORM3UI64ARBPROC __glewUniform3ui64ARB = NULL; +PFNGLUNIFORM3UI64VARBPROC __glewUniform3ui64vARB = NULL; +PFNGLUNIFORM4I64ARBPROC __glewUniform4i64ARB = NULL; +PFNGLUNIFORM4I64VARBPROC __glewUniform4i64vARB = NULL; +PFNGLUNIFORM4UI64ARBPROC __glewUniform4ui64ARB = NULL; +PFNGLUNIFORM4UI64VARBPROC __glewUniform4ui64vARB = NULL; + +PFNGLCOLORSUBTABLEPROC __glewColorSubTable = NULL; +PFNGLCOLORTABLEPROC __glewColorTable = NULL; +PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv = NULL; +PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv = NULL; +PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D = NULL; +PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D = NULL; +PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf = NULL; +PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv = NULL; +PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri = NULL; +PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv = NULL; +PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable = NULL; +PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D = NULL; +PFNGLGETCOLORTABLEPROC __glewGetColorTable = NULL; +PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv = NULL; +PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv = NULL; +PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv = NULL; +PFNGLGETHISTOGRAMPROC __glewGetHistogram = NULL; +PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv = NULL; +PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv = NULL; +PFNGLGETMINMAXPROC __glewGetMinmax = NULL; +PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv = NULL; +PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv = NULL; +PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter = NULL; +PFNGLHISTOGRAMPROC __glewHistogram = NULL; +PFNGLMINMAXPROC __glewMinmax = NULL; +PFNGLRESETHISTOGRAMPROC __glewResetHistogram = NULL; +PFNGLRESETMINMAXPROC __glewResetMinmax = NULL; +PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB = NULL; + +PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB = NULL; +PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB = NULL; +PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB = NULL; + +PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ = NULL; + +PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v = NULL; + +PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData = NULL; +PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData = NULL; +PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer = NULL; +PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer = NULL; +PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage = NULL; +PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage = NULL; + +PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange = NULL; +PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange = NULL; + +PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB = NULL; +PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB = NULL; +PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB = NULL; +PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB = NULL; +PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB = NULL; + +PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase = NULL; +PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange = NULL; +PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures = NULL; +PFNGLBINDSAMPLERSPROC __glewBindSamplers = NULL; +PFNGLBINDTEXTURESPROC __glewBindTextures = NULL; +PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect = NULL; + +PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB = NULL; + +PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB = NULL; +PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB = NULL; +PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB = NULL; +PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB = NULL; +PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB = NULL; +PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB = NULL; +PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB = NULL; +PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB = NULL; +PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB = NULL; +PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB = NULL; +PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB = NULL; +PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB = NULL; +PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB = NULL; +PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB = NULL; +PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB = NULL; +PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB = NULL; +PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB = NULL; +PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB = NULL; +PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB = NULL; +PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB = NULL; +PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB = NULL; +PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB = NULL; +PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB = NULL; +PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB = NULL; +PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB = NULL; +PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB = NULL; +PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB = NULL; +PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB = NULL; +PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB = NULL; +PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB = NULL; +PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB = NULL; +PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB = NULL; +PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB = NULL; +PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB = NULL; + +PFNGLBEGINQUERYARBPROC __glewBeginQueryARB = NULL; +PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB = NULL; +PFNGLENDQUERYARBPROC __glewEndQueryARB = NULL; +PFNGLGENQUERIESARBPROC __glewGenQueriesARB = NULL; +PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB = NULL; +PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB = NULL; +PFNGLGETQUERYIVARBPROC __glewGetQueryivARB = NULL; +PFNGLISQUERYARBPROC __glewIsQueryARB = NULL; + +PFNGLMAXSHADERCOMPILERTHREADSARBPROC __glewMaxShaderCompilerThreadsARB = NULL; + +PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB = NULL; +PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB = NULL; + +PFNGLPOLYGONOFFSETCLAMPPROC __glewPolygonOffsetClamp = NULL; + +PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv = NULL; +PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex = NULL; +PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName = NULL; +PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv = NULL; + +PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex = NULL; + +PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB = NULL; +PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB = NULL; +PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB = NULL; +PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB = NULL; +PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB = NULL; +PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB = NULL; +PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB = NULL; +PFNGLGETNMAPIVARBPROC __glewGetnMapivARB = NULL; +PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB = NULL; +PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB = NULL; +PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB = NULL; +PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB = NULL; +PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB = NULL; +PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB = NULL; +PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB = NULL; +PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB = NULL; +PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB = NULL; +PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB = NULL; +PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB = NULL; +PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB = NULL; + +PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewFramebufferSampleLocationsfvARB = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC __glewNamedFramebufferSampleLocationsfvARB = NULL; + +PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB = NULL; + +PFNGLBINDSAMPLERPROC __glewBindSampler = NULL; +PFNGLDELETESAMPLERSPROC __glewDeleteSamplers = NULL; +PFNGLGENSAMPLERSPROC __glewGenSamplers = NULL; +PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv = NULL; +PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv = NULL; +PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv = NULL; +PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv = NULL; +PFNGLISSAMPLERPROC __glewIsSampler = NULL; +PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv = NULL; +PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv = NULL; +PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf = NULL; +PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv = NULL; +PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri = NULL; +PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv = NULL; + +PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram = NULL; +PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline = NULL; +PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv = NULL; +PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines = NULL; +PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines = NULL; +PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog = NULL; +PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv = NULL; +PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline = NULL; +PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d = NULL; +PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv = NULL; +PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f = NULL; +PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv = NULL; +PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i = NULL; +PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv = NULL; +PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui = NULL; +PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv = NULL; +PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d = NULL; +PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv = NULL; +PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f = NULL; +PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv = NULL; +PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i = NULL; +PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv = NULL; +PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui = NULL; +PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv = NULL; +PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d = NULL; +PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv = NULL; +PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f = NULL; +PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv = NULL; +PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i = NULL; +PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv = NULL; +PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui = NULL; +PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv = NULL; +PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d = NULL; +PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv = NULL; +PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f = NULL; +PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv = NULL; +PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i = NULL; +PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv = NULL; +PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui = NULL; +PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv = NULL; +PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages = NULL; +PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline = NULL; + +PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv = NULL; + +PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture = NULL; +PFNGLMEMORYBARRIERPROC __glewMemoryBarrier = NULL; + +PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB = NULL; +PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB = NULL; +PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB = NULL; +PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB = NULL; +PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB = NULL; +PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB = NULL; +PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB = NULL; +PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB = NULL; +PFNGLGETHANDLEARBPROC __glewGetHandleARB = NULL; +PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB = NULL; +PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB = NULL; +PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB = NULL; +PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB = NULL; +PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB = NULL; +PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB = NULL; +PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB = NULL; +PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB = NULL; +PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB = NULL; +PFNGLUNIFORM1FARBPROC __glewUniform1fARB = NULL; +PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB = NULL; +PFNGLUNIFORM1IARBPROC __glewUniform1iARB = NULL; +PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB = NULL; +PFNGLUNIFORM2FARBPROC __glewUniform2fARB = NULL; +PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB = NULL; +PFNGLUNIFORM2IARBPROC __glewUniform2iARB = NULL; +PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB = NULL; +PFNGLUNIFORM3FARBPROC __glewUniform3fARB = NULL; +PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB = NULL; +PFNGLUNIFORM3IARBPROC __glewUniform3iARB = NULL; +PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB = NULL; +PFNGLUNIFORM4FARBPROC __glewUniform4fARB = NULL; +PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB = NULL; +PFNGLUNIFORM4IARBPROC __glewUniform4iARB = NULL; +PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB = NULL; +PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB = NULL; +PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB = NULL; +PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB = NULL; +PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB = NULL; +PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB = NULL; + +PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding = NULL; + +PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName = NULL; +PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv = NULL; +PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv = NULL; +PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex = NULL; +PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation = NULL; +PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv = NULL; +PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv = NULL; + +PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB = NULL; +PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB = NULL; +PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB = NULL; +PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB = NULL; +PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB = NULL; +PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB = NULL; + +PFNGLBUFFERPAGECOMMITMENTARBPROC __glewBufferPageCommitmentARB = NULL; + +PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB = NULL; + +PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync = NULL; +PFNGLDELETESYNCPROC __glewDeleteSync = NULL; +PFNGLFENCESYNCPROC __glewFenceSync = NULL; +PFNGLGETINTEGER64VPROC __glewGetInteger64v = NULL; +PFNGLGETSYNCIVPROC __glewGetSynciv = NULL; +PFNGLISSYNCPROC __glewIsSync = NULL; +PFNGLWAITSYNCPROC __glewWaitSync = NULL; + +PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv = NULL; +PFNGLPATCHPARAMETERIPROC __glewPatchParameteri = NULL; + +PFNGLTEXTUREBARRIERPROC __glewTextureBarrier = NULL; + +PFNGLTEXBUFFERARBPROC __glewTexBufferARB = NULL; + +PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange = NULL; +PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT = NULL; + +PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB = NULL; +PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL; +PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL; + +PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv = NULL; +PFNGLSAMPLEMASKIPROC __glewSampleMaski = NULL; +PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample = NULL; +PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample = NULL; + +PFNGLTEXSTORAGE1DPROC __glewTexStorage1D = NULL; +PFNGLTEXSTORAGE2DPROC __glewTexStorage2D = NULL; +PFNGLTEXSTORAGE3DPROC __glewTexStorage3D = NULL; + +PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample = NULL; +PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample = NULL; +PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT = NULL; + +PFNGLTEXTUREVIEWPROC __glewTextureView = NULL; + +PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v = NULL; +PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v = NULL; +PFNGLQUERYCOUNTERPROC __glewQueryCounter = NULL; + +PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback = NULL; +PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks = NULL; +PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback = NULL; +PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks = NULL; +PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback = NULL; +PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback = NULL; +PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback = NULL; + +PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream = NULL; +PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed = NULL; +PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv = NULL; + +PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced = NULL; +PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced = NULL; + +PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL; +PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL; +PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL; +PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL; + +PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL; +PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv = NULL; +PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex = NULL; +PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding = NULL; + +PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL; +PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL; +PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL; +PFNGLISVERTEXARRAYPROC __glewIsVertexArray = NULL; + +PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv = NULL; +PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d = NULL; +PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv = NULL; +PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d = NULL; +PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv = NULL; +PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d = NULL; +PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv = NULL; +PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d = NULL; +PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv = NULL; +PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer = NULL; + +PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer = NULL; +PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC __glewVertexArrayBindVertexBufferEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC __glewVertexArrayVertexAttribBindingEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC __glewVertexArrayVertexAttribFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC __glewVertexArrayVertexAttribIFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC __glewVertexArrayVertexAttribLFormatEXT = NULL; +PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC __glewVertexArrayVertexBindingDivisorEXT = NULL; +PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding = NULL; +PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat = NULL; +PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat = NULL; +PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat = NULL; +PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor = NULL; + +PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB = NULL; +PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB = NULL; +PFNGLWEIGHTBVARBPROC __glewWeightbvARB = NULL; +PFNGLWEIGHTDVARBPROC __glewWeightdvARB = NULL; +PFNGLWEIGHTFVARBPROC __glewWeightfvARB = NULL; +PFNGLWEIGHTIVARBPROC __glewWeightivARB = NULL; +PFNGLWEIGHTSVARBPROC __glewWeightsvARB = NULL; +PFNGLWEIGHTUBVARBPROC __glewWeightubvARB = NULL; +PFNGLWEIGHTUIVARBPROC __glewWeightuivARB = NULL; +PFNGLWEIGHTUSVARBPROC __glewWeightusvARB = NULL; + +PFNGLBINDBUFFERARBPROC __glewBindBufferARB = NULL; +PFNGLBUFFERDATAARBPROC __glewBufferDataARB = NULL; +PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB = NULL; +PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB = NULL; +PFNGLGENBUFFERSARBPROC __glewGenBuffersARB = NULL; +PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB = NULL; +PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB = NULL; +PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB = NULL; +PFNGLISBUFFERARBPROC __glewIsBufferARB = NULL; +PFNGLMAPBUFFERARBPROC __glewMapBufferARB = NULL; +PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB = NULL; + +PFNGLBINDPROGRAMARBPROC __glewBindProgramARB = NULL; +PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB = NULL; +PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB = NULL; +PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB = NULL; +PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB = NULL; +PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB = NULL; +PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB = NULL; +PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB = NULL; +PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB = NULL; +PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB = NULL; +PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB = NULL; +PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB = NULL; +PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB = NULL; +PFNGLISPROGRAMARBPROC __glewIsProgramARB = NULL; +PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB = NULL; +PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB = NULL; +PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB = NULL; +PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB = NULL; +PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB = NULL; +PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB = NULL; +PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB = NULL; +PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB = NULL; +PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB = NULL; +PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB = NULL; +PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB = NULL; +PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB = NULL; +PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB = NULL; +PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB = NULL; +PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB = NULL; +PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB = NULL; +PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB = NULL; +PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB = NULL; +PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB = NULL; +PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB = NULL; +PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB = NULL; +PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB = NULL; +PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB = NULL; +PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB = NULL; +PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB = NULL; +PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB = NULL; +PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB = NULL; +PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB = NULL; +PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB = NULL; +PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB = NULL; +PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB = NULL; +PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB = NULL; +PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB = NULL; +PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB = NULL; +PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB = NULL; +PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB = NULL; +PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB = NULL; +PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB = NULL; +PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB = NULL; +PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB = NULL; +PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB = NULL; +PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB = NULL; +PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB = NULL; + +PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB = NULL; +PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB = NULL; +PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB = NULL; + +PFNGLCOLORP3UIPROC __glewColorP3ui = NULL; +PFNGLCOLORP3UIVPROC __glewColorP3uiv = NULL; +PFNGLCOLORP4UIPROC __glewColorP4ui = NULL; +PFNGLCOLORP4UIVPROC __glewColorP4uiv = NULL; +PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui = NULL; +PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv = NULL; +PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui = NULL; +PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv = NULL; +PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui = NULL; +PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv = NULL; +PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui = NULL; +PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv = NULL; +PFNGLNORMALP3UIPROC __glewNormalP3ui = NULL; +PFNGLNORMALP3UIVPROC __glewNormalP3uiv = NULL; +PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui = NULL; +PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv = NULL; +PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui = NULL; +PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv = NULL; +PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui = NULL; +PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv = NULL; +PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui = NULL; +PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv = NULL; +PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui = NULL; +PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv = NULL; +PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui = NULL; +PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv = NULL; +PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui = NULL; +PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv = NULL; +PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui = NULL; +PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv = NULL; +PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui = NULL; +PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv = NULL; +PFNGLVERTEXP2UIPROC __glewVertexP2ui = NULL; +PFNGLVERTEXP2UIVPROC __glewVertexP2uiv = NULL; +PFNGLVERTEXP3UIPROC __glewVertexP3ui = NULL; +PFNGLVERTEXP3UIVPROC __glewVertexP3uiv = NULL; +PFNGLVERTEXP4UIPROC __glewVertexP4ui = NULL; +PFNGLVERTEXP4UIVPROC __glewVertexP4uiv = NULL; + +PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv = NULL; +PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed = NULL; +PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v = NULL; +PFNGLGETFLOATI_VPROC __glewGetFloati_v = NULL; +PFNGLSCISSORARRAYVPROC __glewScissorArrayv = NULL; +PFNGLSCISSORINDEXEDPROC __glewScissorIndexed = NULL; +PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv = NULL; +PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv = NULL; +PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf = NULL; +PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv = NULL; + +PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB = NULL; +PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB = NULL; +PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB = NULL; +PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB = NULL; +PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB = NULL; +PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB = NULL; +PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB = NULL; +PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB = NULL; +PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB = NULL; +PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB = NULL; +PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB = NULL; +PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB = NULL; +PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB = NULL; +PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB = NULL; +PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB = NULL; +PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB = NULL; + +PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI = NULL; + +PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI = NULL; +PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI = NULL; +PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI = NULL; + +PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI = NULL; +PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI = NULL; +PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI = NULL; +PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI = NULL; + +PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI = NULL; +PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI = NULL; +PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI = NULL; +PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI = NULL; +PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI = NULL; +PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI = NULL; +PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI = NULL; +PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI = NULL; +PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI = NULL; +PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI = NULL; +PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI = NULL; +PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI = NULL; +PFNGLSAMPLEMAPATIPROC __glewSampleMapATI = NULL; +PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI = NULL; + +PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI = NULL; +PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI = NULL; + +PFNGLPNTRIANGLESFATIPROC __glewPNTrianglesfATI = NULL; +PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI = NULL; + +PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI = NULL; +PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI = NULL; + +PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI = NULL; +PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI = NULL; +PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI = NULL; +PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI = NULL; +PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI = NULL; +PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI = NULL; +PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI = NULL; +PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI = NULL; +PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI = NULL; +PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI = NULL; +PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI = NULL; +PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI = NULL; + +PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI = NULL; +PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI = NULL; +PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI = NULL; + +PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI = NULL; +PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI = NULL; +PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI = NULL; +PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI = NULL; +PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI = NULL; +PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI = NULL; +PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI = NULL; +PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI = NULL; +PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI = NULL; +PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI = NULL; +PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI = NULL; +PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI = NULL; +PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI = NULL; +PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI = NULL; +PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI = NULL; +PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI = NULL; +PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI = NULL; +PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI = NULL; +PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI = NULL; +PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI = NULL; +PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI = NULL; +PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI = NULL; +PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI = NULL; +PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI = NULL; +PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI = NULL; +PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI = NULL; +PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI = NULL; +PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI = NULL; +PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI = NULL; +PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI = NULL; +PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI = NULL; +PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI = NULL; +PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI = NULL; +PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI = NULL; +PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI = NULL; +PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI = NULL; +PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI = NULL; +PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI = NULL; +PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI = NULL; +PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI = NULL; +PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI = NULL; +PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI = NULL; +PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI = NULL; +PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI = NULL; +PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI = NULL; + +PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC __glewDrawArraysInstancedBaseInstanceEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseInstanceEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC __glewDrawElementsInstancedBaseVertexBaseInstanceEXT = NULL; + +PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT = NULL; +PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT = NULL; +PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT = NULL; + +PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT = NULL; + +PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT = NULL; + +PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC __glewBindFragDataLocationIndexedEXT = NULL; +PFNGLGETFRAGDATAINDEXEXTPROC __glewGetFragDataIndexEXT = NULL; +PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC __glewGetProgramResourceLocationIndexEXT = NULL; + +PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT = NULL; + +PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT = NULL; + +PFNGLBUFFERSTORAGEEXTPROC __glewBufferStorageEXT = NULL; +PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT = NULL; + +PFNGLCLEARTEXIMAGEEXTPROC __glewClearTexImageEXT = NULL; +PFNGLCLEARTEXSUBIMAGEEXTPROC __glewClearTexSubImageEXT = NULL; + +PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT = NULL; +PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT = NULL; + +PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT = NULL; +PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT = NULL; + +PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT = NULL; +PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT = NULL; +PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT = NULL; +PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT = NULL; +PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT = NULL; +PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT = NULL; +PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT = NULL; +PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT = NULL; +PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT = NULL; + +PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT = NULL; +PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT = NULL; + +PFNGLCOPYIMAGESUBDATAEXTPROC __glewCopyImageSubDataEXT = NULL; + +PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT = NULL; +PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT = NULL; +PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT = NULL; + +PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT = NULL; +PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT = NULL; + +PFNGLGETOBJECTLABELEXTPROC __glewGetObjectLabelEXT = NULL; +PFNGLLABELOBJECTEXTPROC __glewLabelObjectEXT = NULL; + +PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT = NULL; +PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT = NULL; +PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT = NULL; + +PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT = NULL; + +PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT = NULL; +PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT = NULL; +PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT = NULL; +PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT = NULL; +PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT = NULL; +PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT = NULL; +PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT = NULL; +PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT = NULL; +PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT = NULL; +PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT = NULL; +PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT = NULL; +PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT = NULL; +PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT = NULL; +PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT = NULL; +PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT = NULL; +PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT = NULL; +PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT = NULL; +PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT = NULL; +PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT = NULL; +PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT = NULL; +PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT = NULL; +PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT = NULL; +PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT = NULL; +PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT = NULL; +PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT = NULL; +PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT = NULL; +PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT = NULL; +PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT = NULL; +PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT = NULL; +PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT = NULL; +PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT = NULL; +PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT = NULL; +PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT = NULL; +PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT = NULL; +PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT = NULL; +PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT = NULL; +PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT = NULL; +PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT = NULL; +PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT = NULL; +PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT = NULL; +PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT = NULL; +PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT = NULL; +PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT = NULL; +PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT = NULL; +PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT = NULL; +PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT = NULL; +PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT = NULL; +PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT = NULL; +PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT = NULL; +PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT = NULL; +PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT = NULL; +PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT = NULL; +PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT = NULL; +PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT = NULL; +PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT = NULL; +PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT = NULL; +PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT = NULL; +PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT = NULL; +PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT = NULL; +PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT = NULL; +PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT = NULL; +PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT = NULL; +PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT = NULL; +PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT = NULL; +PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT = NULL; +PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT = NULL; +PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT = NULL; +PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT = NULL; +PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT = NULL; +PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT = NULL; +PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT = NULL; +PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT = NULL; +PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT = NULL; +PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT = NULL; +PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT = NULL; +PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT = NULL; +PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT = NULL; +PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT = NULL; +PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT = NULL; +PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT = NULL; +PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT = NULL; +PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT = NULL; +PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT = NULL; +PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT = NULL; +PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT = NULL; +PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT = NULL; +PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT = NULL; +PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT = NULL; +PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT = NULL; +PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT = NULL; +PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT = NULL; +PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT = NULL; +PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT = NULL; +PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT = NULL; +PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT = NULL; +PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT = NULL; +PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT = NULL; +PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT = NULL; +PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT = NULL; +PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT = NULL; +PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT = NULL; +PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT = NULL; +PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT = NULL; +PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT = NULL; +PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT = NULL; +PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT = NULL; +PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT = NULL; +PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT = NULL; +PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT = NULL; +PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT = NULL; +PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT = NULL; +PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT = NULL; +PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT = NULL; +PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT = NULL; +PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT = NULL; +PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT = NULL; +PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT = NULL; +PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT = NULL; +PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT = NULL; +PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT = NULL; +PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT = NULL; +PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT = NULL; +PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT = NULL; +PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT = NULL; +PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT = NULL; +PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT = NULL; +PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT = NULL; +PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT = NULL; +PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT = NULL; +PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT = NULL; +PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT = NULL; +PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT = NULL; +PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT = NULL; +PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT = NULL; +PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT = NULL; +PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT = NULL; +PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT = NULL; +PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT = NULL; +PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT = NULL; +PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT = NULL; +PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT = NULL; +PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT = NULL; +PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT = NULL; +PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT = NULL; +PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT = NULL; +PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT = NULL; +PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT = NULL; +PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT = NULL; +PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT = NULL; +PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT = NULL; +PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT = NULL; +PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT = NULL; +PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT = NULL; +PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT = NULL; +PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT = NULL; +PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT = NULL; +PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC __glewVertexArrayVertexAttribDivisorEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT = NULL; +PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT = NULL; + +PFNGLDISCARDFRAMEBUFFEREXTPROC __glewDiscardFramebufferEXT = NULL; + +PFNGLDRAWBUFFERSEXTPROC __glewDrawBuffersEXT = NULL; + +PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT = NULL; +PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT = NULL; +PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT = NULL; +PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT = NULL; +PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT = NULL; +PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT = NULL; + +PFNGLBLENDEQUATIONSEPARATEIEXTPROC __glewBlendEquationSeparateiEXT = NULL; +PFNGLBLENDEQUATIONIEXTPROC __glewBlendEquationiEXT = NULL; +PFNGLBLENDFUNCSEPARATEIEXTPROC __glewBlendFuncSeparateiEXT = NULL; +PFNGLBLENDFUNCIEXTPROC __glewBlendFunciEXT = NULL; +PFNGLCOLORMASKIEXTPROC __glewColorMaskiEXT = NULL; +PFNGLDISABLEIEXTPROC __glewDisableiEXT = NULL; +PFNGLENABLEIEXTPROC __glewEnableiEXT = NULL; +PFNGLISENABLEDIEXTPROC __glewIsEnablediEXT = NULL; + +PFNGLDRAWELEMENTSBASEVERTEXEXTPROC __glewDrawElementsBaseVertexEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC __glewDrawElementsInstancedBaseVertexEXT = NULL; +PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC __glewDrawRangeElementsBaseVertexEXT = NULL; +PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC __glewMultiDrawElementsBaseVertexEXT = NULL; + +PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT = NULL; +PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT = NULL; + +PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT = NULL; + +PFNGLBUFFERSTORAGEEXTERNALEXTPROC __glewBufferStorageExternalEXT = NULL; +PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC __glewNamedBufferStorageExternalEXT = NULL; + +PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT = NULL; +PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT = NULL; +PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT = NULL; +PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT = NULL; +PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT = NULL; + +PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT = NULL; +PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT = NULL; +PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT = NULL; +PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT = NULL; +PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT = NULL; +PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT = NULL; +PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT = NULL; +PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT = NULL; +PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT = NULL; +PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT = NULL; +PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT = NULL; +PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT = NULL; +PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT = NULL; +PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT = NULL; +PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT = NULL; +PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT = NULL; +PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT = NULL; +PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT = NULL; + +PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT = NULL; + +PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT = NULL; +PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT = NULL; +PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT = NULL; +PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT = NULL; +PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT = NULL; +PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT = NULL; +PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT = NULL; +PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT = NULL; +PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT = NULL; + +PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT = NULL; +PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT = NULL; +PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT = NULL; + +PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT = NULL; +PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT = NULL; + +PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT = NULL; +PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT = NULL; +PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT = NULL; +PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT = NULL; +PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT = NULL; +PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT = NULL; +PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT = NULL; +PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT = NULL; +PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT = NULL; +PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT = NULL; +PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT = NULL; +PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT = NULL; +PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT = NULL; +PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT = NULL; +PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT = NULL; +PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT = NULL; +PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT = NULL; +PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT = NULL; +PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT = NULL; +PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT = NULL; +PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT = NULL; +PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT = NULL; +PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT = NULL; +PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT = NULL; +PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT = NULL; +PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT = NULL; +PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT = NULL; +PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT = NULL; +PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT = NULL; +PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT = NULL; +PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT = NULL; +PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT = NULL; +PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT = NULL; +PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT = NULL; + +PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT = NULL; +PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT = NULL; +PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT = NULL; +PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT = NULL; +PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT = NULL; +PFNGLHISTOGRAMEXTPROC __glewHistogramEXT = NULL; +PFNGLMINMAXEXTPROC __glewMinmaxEXT = NULL; +PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT = NULL; +PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT = NULL; + +PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT = NULL; + +PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT = NULL; + +PFNGLVERTEXATTRIBDIVISOREXTPROC __glewVertexAttribDivisorEXT = NULL; + +PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT = NULL; +PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT = NULL; +PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT = NULL; + +PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC __glewFlushMappedBufferRangeEXT = NULL; +PFNGLMAPBUFFERRANGEEXTPROC __glewMapBufferRangeEXT = NULL; + +PFNGLBUFFERSTORAGEMEMEXTPROC __glewBufferStorageMemEXT = NULL; +PFNGLCREATEMEMORYOBJECTSEXTPROC __glewCreateMemoryObjectsEXT = NULL; +PFNGLDELETEMEMORYOBJECTSEXTPROC __glewDeleteMemoryObjectsEXT = NULL; +PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC __glewGetMemoryObjectParameterivEXT = NULL; +PFNGLGETUNSIGNEDBYTEI_VEXTPROC __glewGetUnsignedBytei_vEXT = NULL; +PFNGLGETUNSIGNEDBYTEVEXTPROC __glewGetUnsignedBytevEXT = NULL; +PFNGLISMEMORYOBJECTEXTPROC __glewIsMemoryObjectEXT = NULL; +PFNGLMEMORYOBJECTPARAMETERIVEXTPROC __glewMemoryObjectParameterivEXT = NULL; +PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC __glewNamedBufferStorageMemEXT = NULL; +PFNGLTEXSTORAGEMEM1DEXTPROC __glewTexStorageMem1DEXT = NULL; +PFNGLTEXSTORAGEMEM2DEXTPROC __glewTexStorageMem2DEXT = NULL; +PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC __glewTexStorageMem2DMultisampleEXT = NULL; +PFNGLTEXSTORAGEMEM3DEXTPROC __glewTexStorageMem3DEXT = NULL; +PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC __glewTexStorageMem3DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGEMEM1DEXTPROC __glewTextureStorageMem1DEXT = NULL; +PFNGLTEXTURESTORAGEMEM2DEXTPROC __glewTextureStorageMem2DEXT = NULL; +PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC __glewTextureStorageMem2DMultisampleEXT = NULL; +PFNGLTEXTURESTORAGEMEM3DEXTPROC __glewTextureStorageMem3DEXT = NULL; +PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC __glewTextureStorageMem3DMultisampleEXT = NULL; + +PFNGLIMPORTMEMORYFDEXTPROC __glewImportMemoryFdEXT = NULL; + +PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC __glewImportMemoryWin32HandleEXT = NULL; +PFNGLIMPORTMEMORYWIN32NAMEEXTPROC __glewImportMemoryWin32NameEXT = NULL; + +PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT = NULL; +PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC __glewMultiDrawArraysIndirectEXT = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC __glewMultiDrawElementsIndirectEXT = NULL; + +PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT = NULL; +PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT = NULL; + +PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC __glewFramebufferTexture2DMultisampleEXT = NULL; + +PFNGLDRAWBUFFERSINDEXEDEXTPROC __glewDrawBuffersIndexedEXT = NULL; +PFNGLGETINTEGERI_VEXTPROC __glewGetIntegeri_vEXT = NULL; +PFNGLREADBUFFERINDEXEDEXTPROC __glewReadBufferIndexedEXT = NULL; + +PFNGLCOLORTABLEEXTPROC __glewColorTableEXT = NULL; +PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT = NULL; +PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT = NULL; + +PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT = NULL; +PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT = NULL; + +PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT = NULL; +PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT = NULL; + +PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT = NULL; + +PFNGLPOLYGONOFFSETCLAMPEXTPROC __glewPolygonOffsetClampEXT = NULL; + +PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT = NULL; + +PFNGLCOVERAGEMODULATIONNVPROC __glewCoverageModulationNV = NULL; +PFNGLCOVERAGEMODULATIONTABLENVPROC __glewCoverageModulationTableNV = NULL; +PFNGLGETCOVERAGEMODULATIONTABLENVPROC __glewGetCoverageModulationTableNV = NULL; +PFNGLRASTERSAMPLESEXTPROC __glewRasterSamplesEXT = NULL; + +PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT = NULL; +PFNGLENDSCENEEXTPROC __glewEndSceneEXT = NULL; + +PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT = NULL; +PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT = NULL; +PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT = NULL; +PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT = NULL; +PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT = NULL; +PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT = NULL; +PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT = NULL; +PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT = NULL; +PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT = NULL; +PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT = NULL; +PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT = NULL; +PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT = NULL; +PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT = NULL; +PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT = NULL; +PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT = NULL; +PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT = NULL; +PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT = NULL; + +PFNGLDELETESEMAPHORESEXTPROC __glewDeleteSemaphoresEXT = NULL; +PFNGLGENSEMAPHORESEXTPROC __glewGenSemaphoresEXT = NULL; +PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC __glewGetSemaphoreParameterui64vEXT = NULL; +PFNGLISSEMAPHOREEXTPROC __glewIsSemaphoreEXT = NULL; +PFNGLSEMAPHOREPARAMETERUI64VEXTPROC __glewSemaphoreParameterui64vEXT = NULL; +PFNGLSIGNALSEMAPHOREEXTPROC __glewSignalSemaphoreEXT = NULL; +PFNGLWAITSEMAPHOREEXTPROC __glewWaitSemaphoreEXT = NULL; + +PFNGLIMPORTSEMAPHOREFDEXTPROC __glewImportSemaphoreFdEXT = NULL; + +PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC __glewImportSemaphoreWin32HandleEXT = NULL; +PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC __glewImportSemaphoreWin32NameEXT = NULL; + +PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT = NULL; +PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT = NULL; +PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT = NULL; + +PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT = NULL; +PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT = NULL; + +PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC __glewClearPixelLocalStorageuiEXT = NULL; +PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewFramebufferPixelLocalStorageSizeEXT = NULL; +PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC __glewGetFramebufferPixelLocalStorageSizeEXT = NULL; + +PFNGLTEXPAGECOMMITMENTEXTPROC __glewTexPageCommitmentEXT = NULL; +PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT = NULL; + +PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL; + +PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL; +PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT = NULL; +PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT = NULL; + +PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT = NULL; + +PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT = NULL; + +PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT = NULL; + +PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT = NULL; +PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT = NULL; +PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT = NULL; +PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT = NULL; +PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT = NULL; +PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT = NULL; + +PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT = NULL; +PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT = NULL; +PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT = NULL; +PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT = NULL; +PFNGLISTEXTUREEXTPROC __glewIsTextureEXT = NULL; +PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT = NULL; + +PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT = NULL; + +PFNGLTEXSTORAGE1DEXTPROC __glewTexStorage1DEXT = NULL; +PFNGLTEXSTORAGE2DEXTPROC __glewTexStorage2DEXT = NULL; +PFNGLTEXSTORAGE3DEXTPROC __glewTexStorage3DEXT = NULL; +PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT = NULL; +PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT = NULL; +PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT = NULL; + +PFNGLTEXTUREVIEWEXTPROC __glewTextureViewEXT = NULL; + +PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT = NULL; +PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT = NULL; + +PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT = NULL; +PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT = NULL; +PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT = NULL; +PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT = NULL; +PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT = NULL; + +PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT = NULL; +PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT = NULL; +PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT = NULL; +PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT = NULL; +PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT = NULL; +PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT = NULL; +PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT = NULL; +PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT = NULL; + +PFNGLBINDARRAYSETEXTPROC __glewBindArraySetEXT = NULL; +PFNGLCREATEARRAYSETEXTPROC __glewCreateArraySetExt = NULL; +PFNGLDELETEARRAYSETSEXTPROC __glewDeleteArraySetsEXT = NULL; + +PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT = NULL; +PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT = NULL; +PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT = NULL; +PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT = NULL; +PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT = NULL; +PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT = NULL; +PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT = NULL; +PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT = NULL; +PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT = NULL; +PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT = NULL; +PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT = NULL; + +PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT = NULL; +PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT = NULL; +PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT = NULL; +PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT = NULL; +PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT = NULL; +PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT = NULL; +PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT = NULL; +PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT = NULL; +PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT = NULL; +PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT = NULL; +PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT = NULL; +PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT = NULL; +PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT = NULL; +PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT = NULL; +PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT = NULL; +PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT = NULL; +PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT = NULL; +PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT = NULL; +PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT = NULL; +PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT = NULL; +PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT = NULL; +PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT = NULL; +PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT = NULL; +PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT = NULL; +PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT = NULL; +PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT = NULL; +PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT = NULL; +PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT = NULL; +PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT = NULL; +PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT = NULL; +PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT = NULL; +PFNGLSWIZZLEEXTPROC __glewSwizzleEXT = NULL; +PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT = NULL; +PFNGLVARIANTBVEXTPROC __glewVariantbvEXT = NULL; +PFNGLVARIANTDVEXTPROC __glewVariantdvEXT = NULL; +PFNGLVARIANTFVEXTPROC __glewVariantfvEXT = NULL; +PFNGLVARIANTIVEXTPROC __glewVariantivEXT = NULL; +PFNGLVARIANTSVEXTPROC __glewVariantsvEXT = NULL; +PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT = NULL; +PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT = NULL; +PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT = NULL; +PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT = NULL; + +PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT = NULL; +PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT = NULL; +PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT = NULL; + +PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC __glewAcquireKeyedMutexWin32EXT = NULL; +PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC __glewReleaseKeyedMutexWin32EXT = NULL; + +PFNGLWINDOWRECTANGLESEXTPROC __glewWindowRectanglesEXT = NULL; + +PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT = NULL; + +PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY = NULL; + +PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY = NULL; + +PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP = NULL; +PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP = NULL; +PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP = NULL; + +PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM = NULL; +PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM = NULL; + +PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM = NULL; +PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM = NULL; +PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM = NULL; +PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM = NULL; +PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM = NULL; +PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM = NULL; +PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM = NULL; +PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM = NULL; + +PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL = NULL; +PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL = NULL; +PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL = NULL; + +PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL = NULL; +PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL = NULL; +PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL = NULL; +PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL = NULL; + +PFNGLBEGINPERFQUERYINTELPROC __glewBeginPerfQueryINTEL = NULL; +PFNGLCREATEPERFQUERYINTELPROC __glewCreatePerfQueryINTEL = NULL; +PFNGLDELETEPERFQUERYINTELPROC __glewDeletePerfQueryINTEL = NULL; +PFNGLENDPERFQUERYINTELPROC __glewEndPerfQueryINTEL = NULL; +PFNGLGETFIRSTPERFQUERYIDINTELPROC __glewGetFirstPerfQueryIdINTEL = NULL; +PFNGLGETNEXTPERFQUERYIDINTELPROC __glewGetNextPerfQueryIdINTEL = NULL; +PFNGLGETPERFCOUNTERINFOINTELPROC __glewGetPerfCounterInfoINTEL = NULL; +PFNGLGETPERFQUERYDATAINTELPROC __glewGetPerfQueryDataINTEL = NULL; +PFNGLGETPERFQUERYIDBYNAMEINTELPROC __glewGetPerfQueryIdByNameINTEL = NULL; +PFNGLGETPERFQUERYINFOINTELPROC __glewGetPerfQueryInfoINTEL = NULL; + +PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL = NULL; +PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL = NULL; + +PFNGLBLENDBARRIERKHRPROC __glewBlendBarrierKHR = NULL; + +PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback = NULL; +PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl = NULL; +PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert = NULL; +PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog = NULL; +PFNGLGETOBJECTLABELPROC __glewGetObjectLabel = NULL; +PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel = NULL; +PFNGLOBJECTLABELPROC __glewObjectLabel = NULL; +PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel = NULL; +PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup = NULL; +PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup = NULL; + +PFNGLMAXSHADERCOMPILERTHREADSKHRPROC __glewMaxShaderCompilerThreadsKHR = NULL; + +PFNGLGETNUNIFORMFVPROC __glewGetnUniformfv = NULL; +PFNGLGETNUNIFORMIVPROC __glewGetnUniformiv = NULL; +PFNGLGETNUNIFORMUIVPROC __glewGetnUniformuiv = NULL; +PFNGLREADNPIXELSPROC __glewReadnPixels = NULL; + +PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled = NULL; +PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion = NULL; +PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion = NULL; +PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion = NULL; +PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion = NULL; + +PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA = NULL; + +PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA = NULL; +PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA = NULL; +PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA = NULL; +PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA = NULL; +PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA = NULL; +PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA = NULL; +PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA = NULL; +PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA = NULL; +PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA = NULL; +PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA = NULL; +PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA = NULL; +PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA = NULL; +PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA = NULL; +PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA = NULL; +PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA = NULL; +PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA = NULL; +PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA = NULL; +PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA = NULL; +PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA = NULL; +PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA = NULL; +PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA = NULL; +PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA = NULL; +PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA = NULL; +PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA = NULL; + +PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX = NULL; +PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX = NULL; + +PFNGLLGPUCOPYIMAGESUBDATANVXPROC __glewLGPUCopyImageSubDataNVX = NULL; +PFNGLLGPUINTERLOCKNVXPROC __glewLGPUInterlockNVX = NULL; +PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC __glewLGPUNamedBufferSubDataNVX = NULL; + +PFNGLSTEREOPARAMETERFNVPROC __glewStereoParameterfNV = NULL; +PFNGLSTEREOPARAMETERINVPROC __glewStereoParameteriNV = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV = NULL; + +PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawArraysIndirectBindlessCountNV = NULL; +PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC __glewMultiDrawElementsIndirectBindlessCountNV = NULL; + +PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV = NULL; +PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV = NULL; +PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV = NULL; +PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV = NULL; +PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV = NULL; +PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV = NULL; +PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV = NULL; +PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV = NULL; +PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV = NULL; +PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV = NULL; +PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV = NULL; +PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV = NULL; + +PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV = NULL; +PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV = NULL; + +PFNGLVIEWPORTPOSITIONWSCALENVPROC __glewViewportPositionWScaleNV = NULL; + +PFNGLCALLCOMMANDLISTNVPROC __glewCallCommandListNV = NULL; +PFNGLCOMMANDLISTSEGMENTSNVPROC __glewCommandListSegmentsNV = NULL; +PFNGLCOMPILECOMMANDLISTNVPROC __glewCompileCommandListNV = NULL; +PFNGLCREATECOMMANDLISTSNVPROC __glewCreateCommandListsNV = NULL; +PFNGLCREATESTATESNVPROC __glewCreateStatesNV = NULL; +PFNGLDELETECOMMANDLISTSNVPROC __glewDeleteCommandListsNV = NULL; +PFNGLDELETESTATESNVPROC __glewDeleteStatesNV = NULL; +PFNGLDRAWCOMMANDSADDRESSNVPROC __glewDrawCommandsAddressNV = NULL; +PFNGLDRAWCOMMANDSNVPROC __glewDrawCommandsNV = NULL; +PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC __glewDrawCommandsStatesAddressNV = NULL; +PFNGLDRAWCOMMANDSSTATESNVPROC __glewDrawCommandsStatesNV = NULL; +PFNGLGETCOMMANDHEADERNVPROC __glewGetCommandHeaderNV = NULL; +PFNGLGETSTAGEINDEXNVPROC __glewGetStageIndexNV = NULL; +PFNGLISCOMMANDLISTNVPROC __glewIsCommandListNV = NULL; +PFNGLISSTATENVPROC __glewIsStateNV = NULL; +PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC __glewListDrawCommandsStatesClientNV = NULL; +PFNGLSTATECAPTURENVPROC __glewStateCaptureNV = NULL; + +PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL; +PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL; + +PFNGLSUBPIXELPRECISIONBIASNVPROC __glewSubpixelPrecisionBiasNV = NULL; + +PFNGLCONSERVATIVERASTERPARAMETERFNVPROC __glewConservativeRasterParameterfNV = NULL; + +PFNGLCONSERVATIVERASTERPARAMETERINVPROC __glewConservativeRasterParameteriNV = NULL; + +PFNGLCOPYBUFFERSUBDATANVPROC __glewCopyBufferSubDataNV = NULL; + +PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV = NULL; + +PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL; +PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV = NULL; +PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL; + +PFNGLDRAWBUFFERSNVPROC __glewDrawBuffersNV = NULL; + +PFNGLDRAWARRAYSINSTANCEDNVPROC __glewDrawArraysInstancedNV = NULL; +PFNGLDRAWELEMENTSINSTANCEDNVPROC __glewDrawElementsInstancedNV = NULL; + +PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV = NULL; + +PFNGLDRAWVKIMAGENVPROC __glewDrawVkImageNV = NULL; +PFNGLGETVKPROCADDRNVPROC __glewGetVkProcAddrNV = NULL; +PFNGLSIGNALVKFENCENVPROC __glewSignalVkFenceNV = NULL; +PFNGLSIGNALVKSEMAPHORENVPROC __glewSignalVkSemaphoreNV = NULL; +PFNGLWAITVKSEMAPHORENVPROC __glewWaitVkSemaphoreNV = NULL; + +PFNGLEVALMAPSNVPROC __glewEvalMapsNV = NULL; +PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV = NULL; +PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV = NULL; +PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV = NULL; +PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV = NULL; +PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV = NULL; +PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV = NULL; +PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV = NULL; +PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV = NULL; + +PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV = NULL; +PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV = NULL; +PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV = NULL; + +PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV = NULL; +PFNGLFINISHFENCENVPROC __glewFinishFenceNV = NULL; +PFNGLGENFENCESNVPROC __glewGenFencesNV = NULL; +PFNGLGETFENCEIVNVPROC __glewGetFenceivNV = NULL; +PFNGLISFENCENVPROC __glewIsFenceNV = NULL; +PFNGLSETFENCENVPROC __glewSetFenceNV = NULL; +PFNGLTESTFENCENVPROC __glewTestFenceNV = NULL; + +PFNGLFRAGMENTCOVERAGECOLORNVPROC __glewFragmentCoverageColorNV = NULL; + +PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV = NULL; +PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV = NULL; +PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV = NULL; + +PFNGLBLITFRAMEBUFFERNVPROC __glewBlitFramebufferNV = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC __glewRenderbufferStorageMultisampleNV = NULL; + +PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV = NULL; + +PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV = NULL; + +PFNGLMULTICASTBARRIERNVPROC __glewMulticastBarrierNV = NULL; +PFNGLMULTICASTBLITFRAMEBUFFERNVPROC __glewMulticastBlitFramebufferNV = NULL; +PFNGLMULTICASTBUFFERSUBDATANVPROC __glewMulticastBufferSubDataNV = NULL; +PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC __glewMulticastCopyBufferSubDataNV = NULL; +PFNGLMULTICASTCOPYIMAGESUBDATANVPROC __glewMulticastCopyImageSubDataNV = NULL; +PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewMulticastFramebufferSampleLocationsfvNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC __glewMulticastGetQueryObjecti64vNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTIVNVPROC __glewMulticastGetQueryObjectivNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC __glewMulticastGetQueryObjectui64vNV = NULL; +PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC __glewMulticastGetQueryObjectuivNV = NULL; +PFNGLMULTICASTWAITSYNCNVPROC __glewMulticastWaitSyncNV = NULL; +PFNGLRENDERGPUMASKNVPROC __glewRenderGpuMaskNV = NULL; + +PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV = NULL; +PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV = NULL; +PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV = NULL; +PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV = NULL; +PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV = NULL; +PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV = NULL; + +PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV = NULL; +PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV = NULL; +PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV = NULL; +PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV = NULL; +PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV = NULL; +PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV = NULL; +PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV = NULL; +PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV = NULL; +PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV = NULL; +PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV = NULL; +PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV = NULL; +PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV = NULL; +PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV = NULL; +PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV = NULL; +PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV = NULL; +PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV = NULL; +PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV = NULL; +PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV = NULL; +PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV = NULL; +PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV = NULL; +PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV = NULL; +PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV = NULL; +PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV = NULL; +PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV = NULL; +PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV = NULL; +PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV = NULL; +PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV = NULL; +PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV = NULL; +PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV = NULL; +PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV = NULL; +PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV = NULL; +PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV = NULL; +PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV = NULL; +PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV = NULL; + +PFNGLCOLOR3HNVPROC __glewColor3hNV = NULL; +PFNGLCOLOR3HVNVPROC __glewColor3hvNV = NULL; +PFNGLCOLOR4HNVPROC __glewColor4hNV = NULL; +PFNGLCOLOR4HVNVPROC __glewColor4hvNV = NULL; +PFNGLFOGCOORDHNVPROC __glewFogCoordhNV = NULL; +PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV = NULL; +PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV = NULL; +PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV = NULL; +PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV = NULL; +PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV = NULL; +PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV = NULL; +PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV = NULL; +PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV = NULL; +PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV = NULL; +PFNGLNORMAL3HNVPROC __glewNormal3hNV = NULL; +PFNGLNORMAL3HVNVPROC __glewNormal3hvNV = NULL; +PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV = NULL; +PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV = NULL; +PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV = NULL; +PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV = NULL; +PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV = NULL; +PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV = NULL; +PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV = NULL; +PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV = NULL; +PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV = NULL; +PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV = NULL; +PFNGLVERTEX2HNVPROC __glewVertex2hNV = NULL; +PFNGLVERTEX2HVNVPROC __glewVertex2hvNV = NULL; +PFNGLVERTEX3HNVPROC __glewVertex3hNV = NULL; +PFNGLVERTEX3HVNVPROC __glewVertex3hvNV = NULL; +PFNGLVERTEX4HNVPROC __glewVertex4hNV = NULL; +PFNGLVERTEX4HVNVPROC __glewVertex4hvNV = NULL; +PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV = NULL; +PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV = NULL; +PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV = NULL; +PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV = NULL; +PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV = NULL; +PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV = NULL; +PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV = NULL; +PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV = NULL; +PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV = NULL; +PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV = NULL; +PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV = NULL; +PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV = NULL; +PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV = NULL; +PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV = NULL; + +PFNGLVERTEXATTRIBDIVISORNVPROC __glewVertexAttribDivisorNV = NULL; + +PFNGLGETINTERNALFORMATSAMPLEIVNVPROC __glewGetInternalformatSampleivNV = NULL; + +PFNGLUNIFORMMATRIX2X3FVNVPROC __glewUniformMatrix2x3fvNV = NULL; +PFNGLUNIFORMMATRIX2X4FVNVPROC __glewUniformMatrix2x4fvNV = NULL; +PFNGLUNIFORMMATRIX3X2FVNVPROC __glewUniformMatrix3x2fvNV = NULL; +PFNGLUNIFORMMATRIX3X4FVNVPROC __glewUniformMatrix3x4fvNV = NULL; +PFNGLUNIFORMMATRIX4X2FVNVPROC __glewUniformMatrix4x2fvNV = NULL; +PFNGLUNIFORMMATRIX4X3FVNVPROC __glewUniformMatrix4x3fvNV = NULL; + +PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV = NULL; +PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV = NULL; +PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV = NULL; +PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV = NULL; +PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV = NULL; +PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV = NULL; +PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV = NULL; + +PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV = NULL; +PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV = NULL; + +PFNGLCOPYPATHNVPROC __glewCopyPathNV = NULL; +PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV = NULL; +PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV = NULL; +PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV = NULL; +PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV = NULL; +PFNGLDELETEPATHSNVPROC __glewDeletePathsNV = NULL; +PFNGLGENPATHSNVPROC __glewGenPathsNV = NULL; +PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV = NULL; +PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV = NULL; +PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV = NULL; +PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV = NULL; +PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV = NULL; +PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV = NULL; +PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV = NULL; +PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV = NULL; +PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV = NULL; +PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV = NULL; +PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV = NULL; +PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV = NULL; +PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV = NULL; +PFNGLGETPROGRAMRESOURCEFVNVPROC __glewGetProgramResourcefvNV = NULL; +PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV = NULL; +PFNGLISPATHNVPROC __glewIsPathNV = NULL; +PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV = NULL; +PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV = NULL; +PFNGLMATRIXLOAD3X2FNVPROC __glewMatrixLoad3x2fNV = NULL; +PFNGLMATRIXLOAD3X3FNVPROC __glewMatrixLoad3x3fNV = NULL; +PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC __glewMatrixLoadTranspose3x3fNV = NULL; +PFNGLMATRIXMULT3X2FNVPROC __glewMatrixMult3x2fNV = NULL; +PFNGLMATRIXMULT3X3FNVPROC __glewMatrixMult3x3fNV = NULL; +PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC __glewMatrixMultTranspose3x3fNV = NULL; +PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV = NULL; +PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV = NULL; +PFNGLPATHCOORDSNVPROC __glewPathCoordsNV = NULL; +PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV = NULL; +PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV = NULL; +PFNGLPATHFOGGENNVPROC __glewPathFogGenNV = NULL; +PFNGLPATHGLYPHINDEXARRAYNVPROC __glewPathGlyphIndexArrayNV = NULL; +PFNGLPATHGLYPHINDEXRANGENVPROC __glewPathGlyphIndexRangeNV = NULL; +PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV = NULL; +PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV = NULL; +PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC __glewPathMemoryGlyphIndexArrayNV = NULL; +PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV = NULL; +PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV = NULL; +PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV = NULL; +PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV = NULL; +PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV = NULL; +PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV = NULL; +PFNGLPATHSTRINGNVPROC __glewPathStringNV = NULL; +PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV = NULL; +PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV = NULL; +PFNGLPATHTEXGENNVPROC __glewPathTexGenNV = NULL; +PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV = NULL; +PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC __glewProgramPathFragmentInputGenNV = NULL; +PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV = NULL; +PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV = NULL; +PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV = NULL; +PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV = NULL; +PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC __glewStencilThenCoverFillPathInstancedNV = NULL; +PFNGLSTENCILTHENCOVERFILLPATHNVPROC __glewStencilThenCoverFillPathNV = NULL; +PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC __glewStencilThenCoverStrokePathInstancedNV = NULL; +PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC __glewStencilThenCoverStrokePathNV = NULL; +PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV = NULL; +PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV = NULL; + +PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV = NULL; +PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV = NULL; + +PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV = NULL; +PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV = NULL; + +PFNGLPOLYGONMODENVPROC __glewPolygonModeNV = NULL; + +PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV = NULL; +PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV = NULL; +PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV = NULL; +PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV = NULL; +PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV = NULL; +PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV = NULL; + +PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV = NULL; +PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV = NULL; + +PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV = NULL; +PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV = NULL; +PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV = NULL; +PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV = NULL; +PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV = NULL; +PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV = NULL; +PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV = NULL; +PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV = NULL; +PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV = NULL; +PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV = NULL; + +PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV = NULL; +PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV = NULL; + +PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewFramebufferSampleLocationsfvNV = NULL; +PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC __glewNamedFramebufferSampleLocationsfvNV = NULL; + +PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV = NULL; +PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV = NULL; +PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV = NULL; +PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV = NULL; +PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV = NULL; +PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV = NULL; +PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV = NULL; +PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV = NULL; +PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV = NULL; +PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV = NULL; +PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV = NULL; +PFNGLUNIFORMUI64NVPROC __glewUniformui64NV = NULL; +PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV = NULL; + +PFNGLCOMPRESSEDTEXIMAGE3DNVPROC __glewCompressedTexImage3DNV = NULL; +PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC __glewCompressedTexSubImage3DNV = NULL; +PFNGLCOPYTEXSUBIMAGE3DNVPROC __glewCopyTexSubImage3DNV = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERNVPROC __glewFramebufferTextureLayerNV = NULL; +PFNGLTEXIMAGE3DNVPROC __glewTexImage3DNV = NULL; +PFNGLTEXSUBIMAGE3DNVPROC __glewTexSubImage3DNV = NULL; + +PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV = NULL; + +PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV = NULL; +PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV = NULL; +PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV = NULL; +PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV = NULL; + +PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV = NULL; +PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV = NULL; +PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV = NULL; +PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV = NULL; +PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV = NULL; +PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV = NULL; +PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV = NULL; +PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV = NULL; +PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV = NULL; +PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV = NULL; + +PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV = NULL; +PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV = NULL; +PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV = NULL; +PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV = NULL; +PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV = NULL; +PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV = NULL; +PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV = NULL; + +PFNGLVDPAUFININVPROC __glewVDPAUFiniNV = NULL; +PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV = NULL; +PFNGLVDPAUINITNVPROC __glewVDPAUInitNV = NULL; +PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV = NULL; +PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV = NULL; +PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV = NULL; +PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV = NULL; +PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV = NULL; +PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV = NULL; +PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV = NULL; + +PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL; +PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL; + +PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV = NULL; +PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV = NULL; +PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV = NULL; +PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV = NULL; +PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV = NULL; +PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV = NULL; +PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV = NULL; +PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV = NULL; +PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV = NULL; +PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV = NULL; +PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV = NULL; +PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV = NULL; +PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV = NULL; +PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV = NULL; +PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV = NULL; +PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV = NULL; +PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV = NULL; +PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV = NULL; +PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV = NULL; + +PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV = NULL; +PFNGLCOLORFORMATNVPROC __glewColorFormatNV = NULL; +PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV = NULL; +PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV = NULL; +PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV = NULL; +PFNGLINDEXFORMATNVPROC __glewIndexFormatNV = NULL; +PFNGLNORMALFORMATNVPROC __glewNormalFormatNV = NULL; +PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV = NULL; +PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV = NULL; +PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV = NULL; +PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV = NULL; +PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV = NULL; + +PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV = NULL; +PFNGLBINDPROGRAMNVPROC __glewBindProgramNV = NULL; +PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV = NULL; +PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV = NULL; +PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV = NULL; +PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV = NULL; +PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV = NULL; +PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV = NULL; +PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV = NULL; +PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV = NULL; +PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV = NULL; +PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV = NULL; +PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV = NULL; +PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV = NULL; +PFNGLISPROGRAMNVPROC __glewIsProgramNV = NULL; +PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV = NULL; +PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV = NULL; +PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV = NULL; +PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV = NULL; +PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV = NULL; +PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV = NULL; +PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV = NULL; +PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV = NULL; +PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV = NULL; +PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV = NULL; +PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV = NULL; +PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV = NULL; +PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV = NULL; +PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV = NULL; +PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV = NULL; +PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV = NULL; +PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV = NULL; +PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV = NULL; +PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV = NULL; +PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV = NULL; +PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV = NULL; +PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV = NULL; +PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV = NULL; +PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV = NULL; +PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV = NULL; +PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV = NULL; +PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV = NULL; +PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV = NULL; +PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV = NULL; +PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV = NULL; +PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV = NULL; +PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV = NULL; +PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV = NULL; +PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV = NULL; +PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV = NULL; +PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV = NULL; +PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV = NULL; +PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV = NULL; +PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV = NULL; +PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV = NULL; +PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV = NULL; +PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV = NULL; +PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV = NULL; +PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV = NULL; +PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV = NULL; +PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV = NULL; +PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV = NULL; +PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV = NULL; +PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV = NULL; + +PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV = NULL; +PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV = NULL; +PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV = NULL; +PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV = NULL; +PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV = NULL; +PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV = NULL; +PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV = NULL; +PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV = NULL; + +PFNGLDEPTHRANGEARRAYFVNVPROC __glewDepthRangeArrayfvNV = NULL; +PFNGLDEPTHRANGEINDEXEDFNVPROC __glewDepthRangeIndexedfNV = NULL; +PFNGLDISABLEINVPROC __glewDisableiNV = NULL; +PFNGLENABLEINVPROC __glewEnableiNV = NULL; +PFNGLGETFLOATI_VNVPROC __glewGetFloati_vNV = NULL; +PFNGLISENABLEDINVPROC __glewIsEnablediNV = NULL; +PFNGLSCISSORARRAYVNVPROC __glewScissorArrayvNV = NULL; +PFNGLSCISSORINDEXEDNVPROC __glewScissorIndexedNV = NULL; +PFNGLSCISSORINDEXEDVNVPROC __glewScissorIndexedvNV = NULL; +PFNGLVIEWPORTARRAYVNVPROC __glewViewportArrayvNV = NULL; +PFNGLVIEWPORTINDEXEDFNVPROC __glewViewportIndexedfNV = NULL; +PFNGLVIEWPORTINDEXEDFVNVPROC __glewViewportIndexedfvNV = NULL; + +PFNGLVIEWPORTSWIZZLENVPROC __glewViewportSwizzleNV = NULL; + +PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC __glewFramebufferTextureMultiviewOVR = NULL; + +PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC __glewFramebufferTextureMultisampleMultiviewOVR = NULL; + +PFNGLALPHAFUNCQCOMPROC __glewAlphaFuncQCOM = NULL; + +PFNGLDISABLEDRIVERCONTROLQCOMPROC __glewDisableDriverControlQCOM = NULL; +PFNGLENABLEDRIVERCONTROLQCOMPROC __glewEnableDriverControlQCOM = NULL; +PFNGLGETDRIVERCONTROLSTRINGQCOMPROC __glewGetDriverControlStringQCOM = NULL; +PFNGLGETDRIVERCONTROLSQCOMPROC __glewGetDriverControlsQCOM = NULL; + +PFNGLEXTGETBUFFERPOINTERVQCOMPROC __glewExtGetBufferPointervQCOM = NULL; +PFNGLEXTGETBUFFERSQCOMPROC __glewExtGetBuffersQCOM = NULL; +PFNGLEXTGETFRAMEBUFFERSQCOMPROC __glewExtGetFramebuffersQCOM = NULL; +PFNGLEXTGETRENDERBUFFERSQCOMPROC __glewExtGetRenderbuffersQCOM = NULL; +PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC __glewExtGetTexLevelParameterivQCOM = NULL; +PFNGLEXTGETTEXSUBIMAGEQCOMPROC __glewExtGetTexSubImageQCOM = NULL; +PFNGLEXTGETTEXTURESQCOMPROC __glewExtGetTexturesQCOM = NULL; +PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC __glewExtTexObjectStateOverrideiQCOM = NULL; + +PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC __glewExtGetProgramBinarySourceQCOM = NULL; +PFNGLEXTGETPROGRAMSQCOMPROC __glewExtGetProgramsQCOM = NULL; +PFNGLEXTGETSHADERSQCOMPROC __glewExtGetShadersQCOM = NULL; +PFNGLEXTISPROGRAMBINARYQCOMPROC __glewExtIsProgramBinaryQCOM = NULL; + +PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC __glewFramebufferFoveationConfigQCOM = NULL; +PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC __glewFramebufferFoveationParametersQCOM = NULL; + +PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC __glewFramebufferFetchBarrierQCOM = NULL; + +PFNGLENDTILINGQCOMPROC __glewEndTilingQCOM = NULL; +PFNGLSTARTTILINGQCOMPROC __glewStartTilingQCOM = NULL; + +PFNGLALPHAFUNCXPROC __glewAlphaFuncx = NULL; +PFNGLCLEARCOLORXPROC __glewClearColorx = NULL; +PFNGLCLEARDEPTHXPROC __glewClearDepthx = NULL; +PFNGLCOLOR4XPROC __glewColor4x = NULL; +PFNGLDEPTHRANGEXPROC __glewDepthRangex = NULL; +PFNGLFOGXPROC __glewFogx = NULL; +PFNGLFOGXVPROC __glewFogxv = NULL; +PFNGLFRUSTUMFPROC __glewFrustumf = NULL; +PFNGLFRUSTUMXPROC __glewFrustumx = NULL; +PFNGLLIGHTMODELXPROC __glewLightModelx = NULL; +PFNGLLIGHTMODELXVPROC __glewLightModelxv = NULL; +PFNGLLIGHTXPROC __glewLightx = NULL; +PFNGLLIGHTXVPROC __glewLightxv = NULL; +PFNGLLINEWIDTHXPROC __glewLineWidthx = NULL; +PFNGLLOADMATRIXXPROC __glewLoadMatrixx = NULL; +PFNGLMATERIALXPROC __glewMaterialx = NULL; +PFNGLMATERIALXVPROC __glewMaterialxv = NULL; +PFNGLMULTMATRIXXPROC __glewMultMatrixx = NULL; +PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x = NULL; +PFNGLNORMAL3XPROC __glewNormal3x = NULL; +PFNGLORTHOFPROC __glewOrthof = NULL; +PFNGLORTHOXPROC __glewOrthox = NULL; +PFNGLPOINTSIZEXPROC __glewPointSizex = NULL; +PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx = NULL; +PFNGLROTATEXPROC __glewRotatex = NULL; +PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex = NULL; +PFNGLSCALEXPROC __glewScalex = NULL; +PFNGLTEXENVXPROC __glewTexEnvx = NULL; +PFNGLTEXENVXVPROC __glewTexEnvxv = NULL; +PFNGLTEXPARAMETERXPROC __glewTexParameterx = NULL; +PFNGLTRANSLATEXPROC __glewTranslatex = NULL; + +PFNGLCLIPPLANEFPROC __glewClipPlanef = NULL; +PFNGLCLIPPLANEXPROC __glewClipPlanex = NULL; +PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef = NULL; +PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex = NULL; +PFNGLGETFIXEDVPROC __glewGetFixedv = NULL; +PFNGLGETLIGHTXVPROC __glewGetLightxv = NULL; +PFNGLGETMATERIALXVPROC __glewGetMaterialxv = NULL; +PFNGLGETTEXENVXVPROC __glewGetTexEnvxv = NULL; +PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv = NULL; +PFNGLPOINTPARAMETERXPROC __glewPointParameterx = NULL; +PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv = NULL; +PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES = NULL; +PFNGLTEXPARAMETERXVPROC __glewTexParameterxv = NULL; + +PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL = NULL; + +PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL = NULL; +PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL = NULL; + +PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL = NULL; + +PFNGLGETPROCADDRESSREGALPROC __glewGetProcAddressREGAL = NULL; + +PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS = NULL; +PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS = NULL; + +PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS = NULL; +PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS = NULL; + +PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS = NULL; +PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS = NULL; + +PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC __glewInterleavedTextureCoordSetsSGIS = NULL; +PFNGLSELECTTEXTURECOORDSETSGISPROC __glewSelectTextureCoordSetSGIS = NULL; +PFNGLSELECTTEXTURESGISPROC __glewSelectTextureSGIS = NULL; +PFNGLSELECTTEXTURETRANSFORMSGISPROC __glewSelectTextureTransformSGIS = NULL; + +PFNGLMULTISAMPLESUBRECTPOSSGISPROC __glewMultisampleSubRectPosSGIS = NULL; + +PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS = NULL; +PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS = NULL; + +PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS = NULL; +PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS = NULL; + +PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS = NULL; +PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS = NULL; + +PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX = NULL; +PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX = NULL; +PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX = NULL; +PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX = NULL; +PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX = NULL; +PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX = NULL; + +PFNGLADDRESSSPACEPROC __glewAddressSpace = NULL; +PFNGLDATAPIPEPROC __glewDataPipe = NULL; + +PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX = NULL; + +PFNGLFOGLAYERSSGIXPROC __glewFogLayersSGIX = NULL; +PFNGLGETFOGLAYERSSGIXPROC __glewGetFogLayersSGIX = NULL; + +PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX = NULL; + +PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX = NULL; +PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX = NULL; +PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX = NULL; +PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX = NULL; +PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX = NULL; +PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX = NULL; +PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX = NULL; +PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX = NULL; +PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX = NULL; +PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX = NULL; +PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX = NULL; +PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX = NULL; +PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX = NULL; +PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX = NULL; + +PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX = NULL; + +PFNGLIGLOOINTERFACESGIXPROC __glewIglooInterfaceSGIX = NULL; + +PFNGLALLOCMPEGPREDICTORSSGIXPROC __glewAllocMPEGPredictorsSGIX = NULL; +PFNGLDELETEMPEGPREDICTORSSGIXPROC __glewDeleteMPEGPredictorsSGIX = NULL; +PFNGLGENMPEGPREDICTORSSGIXPROC __glewGenMPEGPredictorsSGIX = NULL; +PFNGLGETMPEGPARAMETERFVSGIXPROC __glewGetMPEGParameterfvSGIX = NULL; +PFNGLGETMPEGPARAMETERIVSGIXPROC __glewGetMPEGParameterivSGIX = NULL; +PFNGLGETMPEGPREDICTORSGIXPROC __glewGetMPEGPredictorSGIX = NULL; +PFNGLGETMPEGQUANTTABLEUBVPROC __glewGetMPEGQuantTableubv = NULL; +PFNGLISMPEGPREDICTORSGIXPROC __glewIsMPEGPredictorSGIX = NULL; +PFNGLMPEGPREDICTORSGIXPROC __glewMPEGPredictorSGIX = NULL; +PFNGLMPEGQUANTTABLEUBVPROC __glewMPEGQuantTableubv = NULL; +PFNGLSWAPMPEGPREDICTORSSGIXPROC __glewSwapMPEGPredictorsSGIX = NULL; + +PFNGLGETNONLINLIGHTFVSGIXPROC __glewGetNonlinLightfvSGIX = NULL; +PFNGLGETNONLINMATERIALFVSGIXPROC __glewGetNonlinMaterialfvSGIX = NULL; +PFNGLNONLINLIGHTFVSGIXPROC __glewNonlinLightfvSGIX = NULL; +PFNGLNONLINMATERIALFVSGIXPROC __glewNonlinMaterialfvSGIX = NULL; + +PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX = NULL; + +PFNGLDEFORMSGIXPROC __glewDeformSGIX = NULL; +PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC __glewLoadIdentityDeformationMapSGIX = NULL; + +PFNGLMESHBREADTHSGIXPROC __glewMeshBreadthSGIX = NULL; +PFNGLMESHSTRIDESGIXPROC __glewMeshStrideSGIX = NULL; + +PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX = NULL; + +PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX = NULL; +PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX = NULL; +PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX = NULL; +PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX = NULL; + +PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX = NULL; + +PFNGLGETVECTOROPERATIONSGIXPROC __glewGetVectorOperationSGIX = NULL; +PFNGLVECTOROPERATIONSGIXPROC __glewVectorOperationSGIX = NULL; + +PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC __glewAreVertexArraysResidentSGIX = NULL; +PFNGLBINDVERTEXARRAYSGIXPROC __glewBindVertexArraySGIX = NULL; +PFNGLDELETEVERTEXARRAYSSGIXPROC __glewDeleteVertexArraysSGIX = NULL; +PFNGLGENVERTEXARRAYSSGIXPROC __glewGenVertexArraysSGIX = NULL; +PFNGLISVERTEXARRAYSGIXPROC __glewIsVertexArraySGIX = NULL; +PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC __glewPrioritizeVertexArraysSGIX = NULL; + +PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI = NULL; +PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI = NULL; +PFNGLCOLORTABLESGIPROC __glewColorTableSGI = NULL; +PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI = NULL; +PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI = NULL; +PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI = NULL; + +PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC __glewGetPixelTransformParameterfvSGI = NULL; +PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC __glewGetPixelTransformParameterivSGI = NULL; +PFNGLPIXELTRANSFORMPARAMETERFSGIPROC __glewPixelTransformParameterfSGI = NULL; +PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC __glewPixelTransformParameterfvSGI = NULL; +PFNGLPIXELTRANSFORMPARAMETERISGIPROC __glewPixelTransformParameteriSGI = NULL; +PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC __glewPixelTransformParameterivSGI = NULL; +PFNGLPIXELTRANSFORMSGIPROC __glewPixelTransformSGI = NULL; + +PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX = NULL; + +PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN = NULL; +PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN = NULL; +PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN = NULL; +PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN = NULL; +PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN = NULL; +PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN = NULL; +PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN = NULL; +PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN = NULL; + +PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN = NULL; + +PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN = NULL; +PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN = NULL; +PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN = NULL; +PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN = NULL; +PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN = NULL; +PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN = NULL; +PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN = NULL; + +PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN = NULL; +PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN = NULL; +PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN = NULL; +PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN = NULL; +PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN = NULL; +PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN = NULL; +PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN = NULL; +PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN = NULL; +PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN = NULL; +PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN = NULL; +PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN = NULL; +PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN = NULL; +PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN = NULL; +PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN = NULL; +PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN = NULL; + +PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN = NULL; + +GLboolean __GLEW_VERSION_1_1 = GL_FALSE; +GLboolean __GLEW_VERSION_1_2 = GL_FALSE; +GLboolean __GLEW_VERSION_1_2_1 = GL_FALSE; +GLboolean __GLEW_VERSION_1_3 = GL_FALSE; +GLboolean __GLEW_VERSION_1_4 = GL_FALSE; +GLboolean __GLEW_VERSION_1_5 = GL_FALSE; +GLboolean __GLEW_VERSION_2_0 = GL_FALSE; +GLboolean __GLEW_VERSION_2_1 = GL_FALSE; +GLboolean __GLEW_VERSION_3_0 = GL_FALSE; +GLboolean __GLEW_VERSION_3_1 = GL_FALSE; +GLboolean __GLEW_VERSION_3_2 = GL_FALSE; +GLboolean __GLEW_VERSION_3_3 = GL_FALSE; +GLboolean __GLEW_VERSION_4_0 = GL_FALSE; +GLboolean __GLEW_VERSION_4_1 = GL_FALSE; +GLboolean __GLEW_VERSION_4_2 = GL_FALSE; +GLboolean __GLEW_VERSION_4_3 = GL_FALSE; +GLboolean __GLEW_VERSION_4_4 = GL_FALSE; +GLboolean __GLEW_VERSION_4_5 = GL_FALSE; +GLboolean __GLEW_VERSION_4_6 = GL_FALSE; +GLboolean __GLEW_3DFX_multisample = GL_FALSE; +GLboolean __GLEW_3DFX_tbuffer = GL_FALSE; +GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE; +GLboolean __GLEW_AMD_blend_minmax_factor = GL_FALSE; +GLboolean __GLEW_AMD_compressed_3DC_texture = GL_FALSE; +GLboolean __GLEW_AMD_compressed_ATC_texture = GL_FALSE; +GLboolean __GLEW_AMD_conservative_depth = GL_FALSE; +GLboolean __GLEW_AMD_debug_output = GL_FALSE; +GLboolean __GLEW_AMD_depth_clamp_separate = GL_FALSE; +GLboolean __GLEW_AMD_draw_buffers_blend = GL_FALSE; +GLboolean __GLEW_AMD_framebuffer_sample_positions = GL_FALSE; +GLboolean __GLEW_AMD_gcn_shader = GL_FALSE; +GLboolean __GLEW_AMD_gpu_shader_half_float = GL_FALSE; +GLboolean __GLEW_AMD_gpu_shader_int16 = GL_FALSE; +GLboolean __GLEW_AMD_gpu_shader_int64 = GL_FALSE; +GLboolean __GLEW_AMD_interleaved_elements = GL_FALSE; +GLboolean __GLEW_AMD_multi_draw_indirect = GL_FALSE; +GLboolean __GLEW_AMD_name_gen_delete = GL_FALSE; +GLboolean __GLEW_AMD_occlusion_query_event = GL_FALSE; +GLboolean __GLEW_AMD_performance_monitor = GL_FALSE; +GLboolean __GLEW_AMD_pinned_memory = GL_FALSE; +GLboolean __GLEW_AMD_program_binary_Z400 = GL_FALSE; +GLboolean __GLEW_AMD_query_buffer_object = GL_FALSE; +GLboolean __GLEW_AMD_sample_positions = GL_FALSE; +GLboolean __GLEW_AMD_seamless_cubemap_per_texture = GL_FALSE; +GLboolean __GLEW_AMD_shader_atomic_counter_ops = GL_FALSE; +GLboolean __GLEW_AMD_shader_ballot = GL_FALSE; +GLboolean __GLEW_AMD_shader_explicit_vertex_parameter = GL_FALSE; +GLboolean __GLEW_AMD_shader_stencil_export = GL_FALSE; +GLboolean __GLEW_AMD_shader_stencil_value_export = GL_FALSE; +GLboolean __GLEW_AMD_shader_trinary_minmax = GL_FALSE; +GLboolean __GLEW_AMD_sparse_texture = GL_FALSE; +GLboolean __GLEW_AMD_stencil_operation_extended = GL_FALSE; +GLboolean __GLEW_AMD_texture_gather_bias_lod = GL_FALSE; +GLboolean __GLEW_AMD_texture_texture4 = GL_FALSE; +GLboolean __GLEW_AMD_transform_feedback3_lines_triangles = GL_FALSE; +GLboolean __GLEW_AMD_transform_feedback4 = GL_FALSE; +GLboolean __GLEW_AMD_vertex_shader_layer = GL_FALSE; +GLboolean __GLEW_AMD_vertex_shader_tessellator = GL_FALSE; +GLboolean __GLEW_AMD_vertex_shader_viewport_index = GL_FALSE; +GLboolean __GLEW_ANDROID_extension_pack_es31a = GL_FALSE; +GLboolean __GLEW_ANGLE_depth_texture = GL_FALSE; +GLboolean __GLEW_ANGLE_framebuffer_blit = GL_FALSE; +GLboolean __GLEW_ANGLE_framebuffer_multisample = GL_FALSE; +GLboolean __GLEW_ANGLE_instanced_arrays = GL_FALSE; +GLboolean __GLEW_ANGLE_pack_reverse_row_order = GL_FALSE; +GLboolean __GLEW_ANGLE_program_binary = GL_FALSE; +GLboolean __GLEW_ANGLE_texture_compression_dxt1 = GL_FALSE; +GLboolean __GLEW_ANGLE_texture_compression_dxt3 = GL_FALSE; +GLboolean __GLEW_ANGLE_texture_compression_dxt5 = GL_FALSE; +GLboolean __GLEW_ANGLE_texture_usage = GL_FALSE; +GLboolean __GLEW_ANGLE_timer_query = GL_FALSE; +GLboolean __GLEW_ANGLE_translated_shader_source = GL_FALSE; +GLboolean __GLEW_APPLE_aux_depth_stencil = GL_FALSE; +GLboolean __GLEW_APPLE_client_storage = GL_FALSE; +GLboolean __GLEW_APPLE_clip_distance = GL_FALSE; +GLboolean __GLEW_APPLE_color_buffer_packed_float = GL_FALSE; +GLboolean __GLEW_APPLE_copy_texture_levels = GL_FALSE; +GLboolean __GLEW_APPLE_element_array = GL_FALSE; +GLboolean __GLEW_APPLE_fence = GL_FALSE; +GLboolean __GLEW_APPLE_float_pixels = GL_FALSE; +GLboolean __GLEW_APPLE_flush_buffer_range = GL_FALSE; +GLboolean __GLEW_APPLE_framebuffer_multisample = GL_FALSE; +GLboolean __GLEW_APPLE_object_purgeable = GL_FALSE; +GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE; +GLboolean __GLEW_APPLE_rgb_422 = GL_FALSE; +GLboolean __GLEW_APPLE_row_bytes = GL_FALSE; +GLboolean __GLEW_APPLE_specular_vector = GL_FALSE; +GLboolean __GLEW_APPLE_sync = GL_FALSE; +GLboolean __GLEW_APPLE_texture_2D_limited_npot = GL_FALSE; +GLboolean __GLEW_APPLE_texture_format_BGRA8888 = GL_FALSE; +GLboolean __GLEW_APPLE_texture_max_level = GL_FALSE; +GLboolean __GLEW_APPLE_texture_packed_float = GL_FALSE; +GLboolean __GLEW_APPLE_texture_range = GL_FALSE; +GLboolean __GLEW_APPLE_transform_hint = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_array_object = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_array_range = GL_FALSE; +GLboolean __GLEW_APPLE_vertex_program_evaluators = GL_FALSE; +GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE; +GLboolean __GLEW_ARB_ES2_compatibility = GL_FALSE; +GLboolean __GLEW_ARB_ES3_1_compatibility = GL_FALSE; +GLboolean __GLEW_ARB_ES3_2_compatibility = GL_FALSE; +GLboolean __GLEW_ARB_ES3_compatibility = GL_FALSE; +GLboolean __GLEW_ARB_arrays_of_arrays = GL_FALSE; +GLboolean __GLEW_ARB_base_instance = GL_FALSE; +GLboolean __GLEW_ARB_bindless_texture = GL_FALSE; +GLboolean __GLEW_ARB_blend_func_extended = GL_FALSE; +GLboolean __GLEW_ARB_buffer_storage = GL_FALSE; +GLboolean __GLEW_ARB_cl_event = GL_FALSE; +GLboolean __GLEW_ARB_clear_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_clear_texture = GL_FALSE; +GLboolean __GLEW_ARB_clip_control = GL_FALSE; +GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_compatibility = GL_FALSE; +GLboolean __GLEW_ARB_compressed_texture_pixel_storage = GL_FALSE; +GLboolean __GLEW_ARB_compute_shader = GL_FALSE; +GLboolean __GLEW_ARB_compute_variable_group_size = GL_FALSE; +GLboolean __GLEW_ARB_conditional_render_inverted = GL_FALSE; +GLboolean __GLEW_ARB_conservative_depth = GL_FALSE; +GLboolean __GLEW_ARB_copy_buffer = GL_FALSE; +GLboolean __GLEW_ARB_copy_image = GL_FALSE; +GLboolean __GLEW_ARB_cull_distance = GL_FALSE; +GLboolean __GLEW_ARB_debug_output = GL_FALSE; +GLboolean __GLEW_ARB_depth_buffer_float = GL_FALSE; +GLboolean __GLEW_ARB_depth_clamp = GL_FALSE; +GLboolean __GLEW_ARB_depth_texture = GL_FALSE; +GLboolean __GLEW_ARB_derivative_control = GL_FALSE; +GLboolean __GLEW_ARB_direct_state_access = GL_FALSE; +GLboolean __GLEW_ARB_draw_buffers = GL_FALSE; +GLboolean __GLEW_ARB_draw_buffers_blend = GL_FALSE; +GLboolean __GLEW_ARB_draw_elements_base_vertex = GL_FALSE; +GLboolean __GLEW_ARB_draw_indirect = GL_FALSE; +GLboolean __GLEW_ARB_draw_instanced = GL_FALSE; +GLboolean __GLEW_ARB_enhanced_layouts = GL_FALSE; +GLboolean __GLEW_ARB_explicit_attrib_location = GL_FALSE; +GLboolean __GLEW_ARB_explicit_uniform_location = GL_FALSE; +GLboolean __GLEW_ARB_fragment_coord_conventions = GL_FALSE; +GLboolean __GLEW_ARB_fragment_layer_viewport = GL_FALSE; +GLboolean __GLEW_ARB_fragment_program = GL_FALSE; +GLboolean __GLEW_ARB_fragment_program_shadow = GL_FALSE; +GLboolean __GLEW_ARB_fragment_shader = GL_FALSE; +GLboolean __GLEW_ARB_fragment_shader_interlock = GL_FALSE; +GLboolean __GLEW_ARB_framebuffer_no_attachments = GL_FALSE; +GLboolean __GLEW_ARB_framebuffer_object = GL_FALSE; +GLboolean __GLEW_ARB_framebuffer_sRGB = GL_FALSE; +GLboolean __GLEW_ARB_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_ARB_get_program_binary = GL_FALSE; +GLboolean __GLEW_ARB_get_texture_sub_image = GL_FALSE; +GLboolean __GLEW_ARB_gl_spirv = GL_FALSE; +GLboolean __GLEW_ARB_gpu_shader5 = GL_FALSE; +GLboolean __GLEW_ARB_gpu_shader_fp64 = GL_FALSE; +GLboolean __GLEW_ARB_gpu_shader_int64 = GL_FALSE; +GLboolean __GLEW_ARB_half_float_pixel = GL_FALSE; +GLboolean __GLEW_ARB_half_float_vertex = GL_FALSE; +GLboolean __GLEW_ARB_imaging = GL_FALSE; +GLboolean __GLEW_ARB_indirect_parameters = GL_FALSE; +GLboolean __GLEW_ARB_instanced_arrays = GL_FALSE; +GLboolean __GLEW_ARB_internalformat_query = GL_FALSE; +GLboolean __GLEW_ARB_internalformat_query2 = GL_FALSE; +GLboolean __GLEW_ARB_invalidate_subdata = GL_FALSE; +GLboolean __GLEW_ARB_map_buffer_alignment = GL_FALSE; +GLboolean __GLEW_ARB_map_buffer_range = GL_FALSE; +GLboolean __GLEW_ARB_matrix_palette = GL_FALSE; +GLboolean __GLEW_ARB_multi_bind = GL_FALSE; +GLboolean __GLEW_ARB_multi_draw_indirect = GL_FALSE; +GLboolean __GLEW_ARB_multisample = GL_FALSE; +GLboolean __GLEW_ARB_multitexture = GL_FALSE; +GLboolean __GLEW_ARB_occlusion_query = GL_FALSE; +GLboolean __GLEW_ARB_occlusion_query2 = GL_FALSE; +GLboolean __GLEW_ARB_parallel_shader_compile = GL_FALSE; +GLboolean __GLEW_ARB_pipeline_statistics_query = GL_FALSE; +GLboolean __GLEW_ARB_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_point_parameters = GL_FALSE; +GLboolean __GLEW_ARB_point_sprite = GL_FALSE; +GLboolean __GLEW_ARB_polygon_offset_clamp = GL_FALSE; +GLboolean __GLEW_ARB_post_depth_coverage = GL_FALSE; +GLboolean __GLEW_ARB_program_interface_query = GL_FALSE; +GLboolean __GLEW_ARB_provoking_vertex = GL_FALSE; +GLboolean __GLEW_ARB_query_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_robust_buffer_access_behavior = GL_FALSE; +GLboolean __GLEW_ARB_robustness = GL_FALSE; +GLboolean __GLEW_ARB_robustness_application_isolation = GL_FALSE; +GLboolean __GLEW_ARB_robustness_share_group_isolation = GL_FALSE; +GLboolean __GLEW_ARB_sample_locations = GL_FALSE; +GLboolean __GLEW_ARB_sample_shading = GL_FALSE; +GLboolean __GLEW_ARB_sampler_objects = GL_FALSE; +GLboolean __GLEW_ARB_seamless_cube_map = GL_FALSE; +GLboolean __GLEW_ARB_seamless_cubemap_per_texture = GL_FALSE; +GLboolean __GLEW_ARB_separate_shader_objects = GL_FALSE; +GLboolean __GLEW_ARB_shader_atomic_counter_ops = GL_FALSE; +GLboolean __GLEW_ARB_shader_atomic_counters = GL_FALSE; +GLboolean __GLEW_ARB_shader_ballot = GL_FALSE; +GLboolean __GLEW_ARB_shader_bit_encoding = GL_FALSE; +GLboolean __GLEW_ARB_shader_clock = GL_FALSE; +GLboolean __GLEW_ARB_shader_draw_parameters = GL_FALSE; +GLboolean __GLEW_ARB_shader_group_vote = GL_FALSE; +GLboolean __GLEW_ARB_shader_image_load_store = GL_FALSE; +GLboolean __GLEW_ARB_shader_image_size = GL_FALSE; +GLboolean __GLEW_ARB_shader_objects = GL_FALSE; +GLboolean __GLEW_ARB_shader_precision = GL_FALSE; +GLboolean __GLEW_ARB_shader_stencil_export = GL_FALSE; +GLboolean __GLEW_ARB_shader_storage_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_shader_subroutine = GL_FALSE; +GLboolean __GLEW_ARB_shader_texture_image_samples = GL_FALSE; +GLboolean __GLEW_ARB_shader_texture_lod = GL_FALSE; +GLboolean __GLEW_ARB_shader_viewport_layer_array = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_420pack = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_include = GL_FALSE; +GLboolean __GLEW_ARB_shading_language_packing = GL_FALSE; +GLboolean __GLEW_ARB_shadow = GL_FALSE; +GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE; +GLboolean __GLEW_ARB_sparse_buffer = GL_FALSE; +GLboolean __GLEW_ARB_sparse_texture = GL_FALSE; +GLboolean __GLEW_ARB_sparse_texture2 = GL_FALSE; +GLboolean __GLEW_ARB_sparse_texture_clamp = GL_FALSE; +GLboolean __GLEW_ARB_spirv_extensions = GL_FALSE; +GLboolean __GLEW_ARB_stencil_texturing = GL_FALSE; +GLboolean __GLEW_ARB_sync = GL_FALSE; +GLboolean __GLEW_ARB_tessellation_shader = GL_FALSE; +GLboolean __GLEW_ARB_texture_barrier = GL_FALSE; +GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_ARB_texture_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_texture_buffer_object_rgb32 = GL_FALSE; +GLboolean __GLEW_ARB_texture_buffer_range = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression_bptc = GL_FALSE; +GLboolean __GLEW_ARB_texture_compression_rgtc = GL_FALSE; +GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE; +GLboolean __GLEW_ARB_texture_cube_map_array = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_add = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_combine = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_crossbar = GL_FALSE; +GLboolean __GLEW_ARB_texture_env_dot3 = GL_FALSE; +GLboolean __GLEW_ARB_texture_filter_anisotropic = GL_FALSE; +GLboolean __GLEW_ARB_texture_filter_minmax = GL_FALSE; +GLboolean __GLEW_ARB_texture_float = GL_FALSE; +GLboolean __GLEW_ARB_texture_gather = GL_FALSE; +GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge = GL_FALSE; +GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_ARB_texture_multisample = GL_FALSE; +GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE; +GLboolean __GLEW_ARB_texture_query_levels = GL_FALSE; +GLboolean __GLEW_ARB_texture_query_lod = GL_FALSE; +GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE; +GLboolean __GLEW_ARB_texture_rg = GL_FALSE; +GLboolean __GLEW_ARB_texture_rgb10_a2ui = GL_FALSE; +GLboolean __GLEW_ARB_texture_stencil8 = GL_FALSE; +GLboolean __GLEW_ARB_texture_storage = GL_FALSE; +GLboolean __GLEW_ARB_texture_storage_multisample = GL_FALSE; +GLboolean __GLEW_ARB_texture_swizzle = GL_FALSE; +GLboolean __GLEW_ARB_texture_view = GL_FALSE; +GLboolean __GLEW_ARB_timer_query = GL_FALSE; +GLboolean __GLEW_ARB_transform_feedback2 = GL_FALSE; +GLboolean __GLEW_ARB_transform_feedback3 = GL_FALSE; +GLboolean __GLEW_ARB_transform_feedback_instanced = GL_FALSE; +GLboolean __GLEW_ARB_transform_feedback_overflow_query = GL_FALSE; +GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE; +GLboolean __GLEW_ARB_uniform_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_array_bgra = GL_FALSE; +GLboolean __GLEW_ARB_vertex_array_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_attrib_64bit = GL_FALSE; +GLboolean __GLEW_ARB_vertex_attrib_binding = GL_FALSE; +GLboolean __GLEW_ARB_vertex_blend = GL_FALSE; +GLboolean __GLEW_ARB_vertex_buffer_object = GL_FALSE; +GLboolean __GLEW_ARB_vertex_program = GL_FALSE; +GLboolean __GLEW_ARB_vertex_shader = GL_FALSE; +GLboolean __GLEW_ARB_vertex_type_10f_11f_11f_rev = GL_FALSE; +GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev = GL_FALSE; +GLboolean __GLEW_ARB_viewport_array = GL_FALSE; +GLboolean __GLEW_ARB_window_pos = GL_FALSE; +GLboolean __GLEW_ARM_mali_program_binary = GL_FALSE; +GLboolean __GLEW_ARM_mali_shader_binary = GL_FALSE; +GLboolean __GLEW_ARM_rgba8 = GL_FALSE; +GLboolean __GLEW_ARM_shader_framebuffer_fetch = GL_FALSE; +GLboolean __GLEW_ARM_shader_framebuffer_fetch_depth_stencil = GL_FALSE; +GLboolean __GLEW_ATIX_point_sprites = GL_FALSE; +GLboolean __GLEW_ATIX_texture_env_combine3 = GL_FALSE; +GLboolean __GLEW_ATIX_texture_env_route = GL_FALSE; +GLboolean __GLEW_ATIX_vertex_shader_output_point_size = GL_FALSE; +GLboolean __GLEW_ATI_draw_buffers = GL_FALSE; +GLboolean __GLEW_ATI_element_array = GL_FALSE; +GLboolean __GLEW_ATI_envmap_bumpmap = GL_FALSE; +GLboolean __GLEW_ATI_fragment_shader = GL_FALSE; +GLboolean __GLEW_ATI_map_object_buffer = GL_FALSE; +GLboolean __GLEW_ATI_meminfo = GL_FALSE; +GLboolean __GLEW_ATI_pn_triangles = GL_FALSE; +GLboolean __GLEW_ATI_separate_stencil = GL_FALSE; +GLboolean __GLEW_ATI_shader_texture_lod = GL_FALSE; +GLboolean __GLEW_ATI_text_fragment_shader = GL_FALSE; +GLboolean __GLEW_ATI_texture_compression_3dc = GL_FALSE; +GLboolean __GLEW_ATI_texture_env_combine3 = GL_FALSE; +GLboolean __GLEW_ATI_texture_float = GL_FALSE; +GLboolean __GLEW_ATI_texture_mirror_once = GL_FALSE; +GLboolean __GLEW_ATI_vertex_array_object = GL_FALSE; +GLboolean __GLEW_ATI_vertex_attrib_array_object = GL_FALSE; +GLboolean __GLEW_ATI_vertex_streams = GL_FALSE; +GLboolean __GLEW_EGL_KHR_context_flush_control = GL_FALSE; +GLboolean __GLEW_EGL_NV_robustness_video_memory_purge = GL_FALSE; +GLboolean __GLEW_EXT_422_pixels = GL_FALSE; +GLboolean __GLEW_EXT_Cg_shader = GL_FALSE; +GLboolean __GLEW_EXT_EGL_image_array = GL_FALSE; +GLboolean __GLEW_EXT_YUV_target = GL_FALSE; +GLboolean __GLEW_EXT_abgr = GL_FALSE; +GLboolean __GLEW_EXT_base_instance = GL_FALSE; +GLboolean __GLEW_EXT_bgra = GL_FALSE; +GLboolean __GLEW_EXT_bindable_uniform = GL_FALSE; +GLboolean __GLEW_EXT_blend_color = GL_FALSE; +GLboolean __GLEW_EXT_blend_equation_separate = GL_FALSE; +GLboolean __GLEW_EXT_blend_func_extended = GL_FALSE; +GLboolean __GLEW_EXT_blend_func_separate = GL_FALSE; +GLboolean __GLEW_EXT_blend_logic_op = GL_FALSE; +GLboolean __GLEW_EXT_blend_minmax = GL_FALSE; +GLboolean __GLEW_EXT_blend_subtract = GL_FALSE; +GLboolean __GLEW_EXT_buffer_storage = GL_FALSE; +GLboolean __GLEW_EXT_clear_texture = GL_FALSE; +GLboolean __GLEW_EXT_clip_cull_distance = GL_FALSE; +GLboolean __GLEW_EXT_clip_volume_hint = GL_FALSE; +GLboolean __GLEW_EXT_cmyka = GL_FALSE; +GLboolean __GLEW_EXT_color_buffer_float = GL_FALSE; +GLboolean __GLEW_EXT_color_buffer_half_float = GL_FALSE; +GLboolean __GLEW_EXT_color_subtable = GL_FALSE; +GLboolean __GLEW_EXT_compiled_vertex_array = GL_FALSE; +GLboolean __GLEW_EXT_compressed_ETC1_RGB8_sub_texture = GL_FALSE; +GLboolean __GLEW_EXT_conservative_depth = GL_FALSE; +GLboolean __GLEW_EXT_convolution = GL_FALSE; +GLboolean __GLEW_EXT_coordinate_frame = GL_FALSE; +GLboolean __GLEW_EXT_copy_image = GL_FALSE; +GLboolean __GLEW_EXT_copy_texture = GL_FALSE; +GLboolean __GLEW_EXT_cull_vertex = GL_FALSE; +GLboolean __GLEW_EXT_debug_label = GL_FALSE; +GLboolean __GLEW_EXT_debug_marker = GL_FALSE; +GLboolean __GLEW_EXT_depth_bounds_test = GL_FALSE; +GLboolean __GLEW_EXT_direct_state_access = GL_FALSE; +GLboolean __GLEW_EXT_discard_framebuffer = GL_FALSE; +GLboolean __GLEW_EXT_draw_buffers = GL_FALSE; +GLboolean __GLEW_EXT_draw_buffers2 = GL_FALSE; +GLboolean __GLEW_EXT_draw_buffers_indexed = GL_FALSE; +GLboolean __GLEW_EXT_draw_elements_base_vertex = GL_FALSE; +GLboolean __GLEW_EXT_draw_instanced = GL_FALSE; +GLboolean __GLEW_EXT_draw_range_elements = GL_FALSE; +GLboolean __GLEW_EXT_external_buffer = GL_FALSE; +GLboolean __GLEW_EXT_float_blend = GL_FALSE; +GLboolean __GLEW_EXT_fog_coord = GL_FALSE; +GLboolean __GLEW_EXT_frag_depth = GL_FALSE; +GLboolean __GLEW_EXT_fragment_lighting = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_blit = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_multisample = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_multisample_blit_scaled = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_object = GL_FALSE; +GLboolean __GLEW_EXT_framebuffer_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_geometry_point_size = GL_FALSE; +GLboolean __GLEW_EXT_geometry_shader = GL_FALSE; +GLboolean __GLEW_EXT_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_EXT_gpu_program_parameters = GL_FALSE; +GLboolean __GLEW_EXT_gpu_shader4 = GL_FALSE; +GLboolean __GLEW_EXT_gpu_shader5 = GL_FALSE; +GLboolean __GLEW_EXT_histogram = GL_FALSE; +GLboolean __GLEW_EXT_index_array_formats = GL_FALSE; +GLboolean __GLEW_EXT_index_func = GL_FALSE; +GLboolean __GLEW_EXT_index_material = GL_FALSE; +GLboolean __GLEW_EXT_index_texture = GL_FALSE; +GLboolean __GLEW_EXT_instanced_arrays = GL_FALSE; +GLboolean __GLEW_EXT_light_texture = GL_FALSE; +GLboolean __GLEW_EXT_map_buffer_range = GL_FALSE; +GLboolean __GLEW_EXT_memory_object = GL_FALSE; +GLboolean __GLEW_EXT_memory_object_fd = GL_FALSE; +GLboolean __GLEW_EXT_memory_object_win32 = GL_FALSE; +GLboolean __GLEW_EXT_misc_attribute = GL_FALSE; +GLboolean __GLEW_EXT_multi_draw_arrays = GL_FALSE; +GLboolean __GLEW_EXT_multi_draw_indirect = GL_FALSE; +GLboolean __GLEW_EXT_multiple_textures = GL_FALSE; +GLboolean __GLEW_EXT_multisample = GL_FALSE; +GLboolean __GLEW_EXT_multisample_compatibility = GL_FALSE; +GLboolean __GLEW_EXT_multisampled_render_to_texture = GL_FALSE; +GLboolean __GLEW_EXT_multisampled_render_to_texture2 = GL_FALSE; +GLboolean __GLEW_EXT_multiview_draw_buffers = GL_FALSE; +GLboolean __GLEW_EXT_packed_depth_stencil = GL_FALSE; +GLboolean __GLEW_EXT_packed_float = GL_FALSE; +GLboolean __GLEW_EXT_packed_pixels = GL_FALSE; +GLboolean __GLEW_EXT_paletted_texture = GL_FALSE; +GLboolean __GLEW_EXT_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_EXT_pixel_transform = GL_FALSE; +GLboolean __GLEW_EXT_pixel_transform_color_table = GL_FALSE; +GLboolean __GLEW_EXT_point_parameters = GL_FALSE; +GLboolean __GLEW_EXT_polygon_offset = GL_FALSE; +GLboolean __GLEW_EXT_polygon_offset_clamp = GL_FALSE; +GLboolean __GLEW_EXT_post_depth_coverage = GL_FALSE; +GLboolean __GLEW_EXT_provoking_vertex = GL_FALSE; +GLboolean __GLEW_EXT_pvrtc_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_raster_multisample = GL_FALSE; +GLboolean __GLEW_EXT_read_format_bgra = GL_FALSE; +GLboolean __GLEW_EXT_render_snorm = GL_FALSE; +GLboolean __GLEW_EXT_rescale_normal = GL_FALSE; +GLboolean __GLEW_EXT_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_sRGB_write_control = GL_FALSE; +GLboolean __GLEW_EXT_scene_marker = GL_FALSE; +GLboolean __GLEW_EXT_secondary_color = GL_FALSE; +GLboolean __GLEW_EXT_semaphore = GL_FALSE; +GLboolean __GLEW_EXT_semaphore_fd = GL_FALSE; +GLboolean __GLEW_EXT_semaphore_win32 = GL_FALSE; +GLboolean __GLEW_EXT_separate_shader_objects = GL_FALSE; +GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE; +GLboolean __GLEW_EXT_shader_framebuffer_fetch = GL_FALSE; +GLboolean __GLEW_EXT_shader_group_vote = GL_FALSE; +GLboolean __GLEW_EXT_shader_image_load_formatted = GL_FALSE; +GLboolean __GLEW_EXT_shader_image_load_store = GL_FALSE; +GLboolean __GLEW_EXT_shader_implicit_conversions = GL_FALSE; +GLboolean __GLEW_EXT_shader_integer_mix = GL_FALSE; +GLboolean __GLEW_EXT_shader_io_blocks = GL_FALSE; +GLboolean __GLEW_EXT_shader_non_constant_global_initializers = GL_FALSE; +GLboolean __GLEW_EXT_shader_pixel_local_storage = GL_FALSE; +GLboolean __GLEW_EXT_shader_pixel_local_storage2 = GL_FALSE; +GLboolean __GLEW_EXT_shader_texture_lod = GL_FALSE; +GLboolean __GLEW_EXT_shadow_funcs = GL_FALSE; +GLboolean __GLEW_EXT_shadow_samplers = GL_FALSE; +GLboolean __GLEW_EXT_shared_texture_palette = GL_FALSE; +GLboolean __GLEW_EXT_sparse_texture = GL_FALSE; +GLboolean __GLEW_EXT_sparse_texture2 = GL_FALSE; +GLboolean __GLEW_EXT_stencil_clear_tag = GL_FALSE; +GLboolean __GLEW_EXT_stencil_two_side = GL_FALSE; +GLboolean __GLEW_EXT_stencil_wrap = GL_FALSE; +GLboolean __GLEW_EXT_subtexture = GL_FALSE; +GLboolean __GLEW_EXT_texture = GL_FALSE; +GLboolean __GLEW_EXT_texture3D = GL_FALSE; +GLboolean __GLEW_EXT_texture_array = GL_FALSE; +GLboolean __GLEW_EXT_texture_buffer_object = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_astc_decode_mode = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5 = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_bptc = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_dxt1 = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_latc = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_rgtc = GL_FALSE; +GLboolean __GLEW_EXT_texture_compression_s3tc = GL_FALSE; +GLboolean __GLEW_EXT_texture_cube_map = GL_FALSE; +GLboolean __GLEW_EXT_texture_cube_map_array = GL_FALSE; +GLboolean __GLEW_EXT_texture_edge_clamp = GL_FALSE; +GLboolean __GLEW_EXT_texture_env = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_add = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_combine = GL_FALSE; +GLboolean __GLEW_EXT_texture_env_dot3 = GL_FALSE; +GLboolean __GLEW_EXT_texture_filter_anisotropic = GL_FALSE; +GLboolean __GLEW_EXT_texture_filter_minmax = GL_FALSE; +GLboolean __GLEW_EXT_texture_format_BGRA8888 = GL_FALSE; +GLboolean __GLEW_EXT_texture_integer = GL_FALSE; +GLboolean __GLEW_EXT_texture_lod_bias = GL_FALSE; +GLboolean __GLEW_EXT_texture_mirror_clamp = GL_FALSE; +GLboolean __GLEW_EXT_texture_norm16 = GL_FALSE; +GLboolean __GLEW_EXT_texture_object = GL_FALSE; +GLboolean __GLEW_EXT_texture_perturb_normal = GL_FALSE; +GLboolean __GLEW_EXT_texture_rectangle = GL_FALSE; +GLboolean __GLEW_EXT_texture_rg = GL_FALSE; +GLboolean __GLEW_EXT_texture_sRGB = GL_FALSE; +GLboolean __GLEW_EXT_texture_sRGB_R8 = GL_FALSE; +GLboolean __GLEW_EXT_texture_sRGB_RG8 = GL_FALSE; +GLboolean __GLEW_EXT_texture_sRGB_decode = GL_FALSE; +GLboolean __GLEW_EXT_texture_shared_exponent = GL_FALSE; +GLboolean __GLEW_EXT_texture_snorm = GL_FALSE; +GLboolean __GLEW_EXT_texture_storage = GL_FALSE; +GLboolean __GLEW_EXT_texture_swizzle = GL_FALSE; +GLboolean __GLEW_EXT_texture_type_2_10_10_10_REV = GL_FALSE; +GLboolean __GLEW_EXT_texture_view = GL_FALSE; +GLboolean __GLEW_EXT_timer_query = GL_FALSE; +GLboolean __GLEW_EXT_transform_feedback = GL_FALSE; +GLboolean __GLEW_EXT_unpack_subimage = GL_FALSE; +GLboolean __GLEW_EXT_vertex_array = GL_FALSE; +GLboolean __GLEW_EXT_vertex_array_bgra = GL_FALSE; +GLboolean __GLEW_EXT_vertex_array_setXXX = GL_FALSE; +GLboolean __GLEW_EXT_vertex_attrib_64bit = GL_FALSE; +GLboolean __GLEW_EXT_vertex_shader = GL_FALSE; +GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE; +GLboolean __GLEW_EXT_win32_keyed_mutex = GL_FALSE; +GLboolean __GLEW_EXT_window_rectangles = GL_FALSE; +GLboolean __GLEW_EXT_x11_sync_object = GL_FALSE; +GLboolean __GLEW_GREMEDY_frame_terminator = GL_FALSE; +GLboolean __GLEW_GREMEDY_string_marker = GL_FALSE; +GLboolean __GLEW_HP_convolution_border_modes = GL_FALSE; +GLboolean __GLEW_HP_image_transform = GL_FALSE; +GLboolean __GLEW_HP_occlusion_test = GL_FALSE; +GLboolean __GLEW_HP_texture_lighting = GL_FALSE; +GLboolean __GLEW_IBM_cull_vertex = GL_FALSE; +GLboolean __GLEW_IBM_multimode_draw_arrays = GL_FALSE; +GLboolean __GLEW_IBM_rasterpos_clip = GL_FALSE; +GLboolean __GLEW_IBM_static_data = GL_FALSE; +GLboolean __GLEW_IBM_texture_mirrored_repeat = GL_FALSE; +GLboolean __GLEW_IBM_vertex_array_lists = GL_FALSE; +GLboolean __GLEW_INGR_color_clamp = GL_FALSE; +GLboolean __GLEW_INGR_interlace_read = GL_FALSE; +GLboolean __GLEW_INTEL_conservative_rasterization = GL_FALSE; +GLboolean __GLEW_INTEL_fragment_shader_ordering = GL_FALSE; +GLboolean __GLEW_INTEL_framebuffer_CMAA = GL_FALSE; +GLboolean __GLEW_INTEL_map_texture = GL_FALSE; +GLboolean __GLEW_INTEL_parallel_arrays = GL_FALSE; +GLboolean __GLEW_INTEL_performance_query = GL_FALSE; +GLboolean __GLEW_INTEL_texture_scissor = GL_FALSE; +GLboolean __GLEW_KHR_blend_equation_advanced = GL_FALSE; +GLboolean __GLEW_KHR_blend_equation_advanced_coherent = GL_FALSE; +GLboolean __GLEW_KHR_context_flush_control = GL_FALSE; +GLboolean __GLEW_KHR_debug = GL_FALSE; +GLboolean __GLEW_KHR_no_error = GL_FALSE; +GLboolean __GLEW_KHR_parallel_shader_compile = GL_FALSE; +GLboolean __GLEW_KHR_robust_buffer_access_behavior = GL_FALSE; +GLboolean __GLEW_KHR_robustness = GL_FALSE; +GLboolean __GLEW_KHR_texture_compression_astc_hdr = GL_FALSE; +GLboolean __GLEW_KHR_texture_compression_astc_ldr = GL_FALSE; +GLboolean __GLEW_KHR_texture_compression_astc_sliced_3d = GL_FALSE; +GLboolean __GLEW_KTX_buffer_region = GL_FALSE; +GLboolean __GLEW_MESAX_texture_stack = GL_FALSE; +GLboolean __GLEW_MESA_pack_invert = GL_FALSE; +GLboolean __GLEW_MESA_resize_buffers = GL_FALSE; +GLboolean __GLEW_MESA_shader_integer_functions = GL_FALSE; +GLboolean __GLEW_MESA_window_pos = GL_FALSE; +GLboolean __GLEW_MESA_ycbcr_texture = GL_FALSE; +GLboolean __GLEW_NVX_blend_equation_advanced_multi_draw_buffers = GL_FALSE; +GLboolean __GLEW_NVX_conditional_render = GL_FALSE; +GLboolean __GLEW_NVX_gpu_memory_info = GL_FALSE; +GLboolean __GLEW_NVX_linked_gpu_multicast = GL_FALSE; +GLboolean __GLEW_NV_3dvision_settings = GL_FALSE; +GLboolean __GLEW_NV_EGL_stream_consumer_external = GL_FALSE; +GLboolean __GLEW_NV_alpha_to_coverage_dither_control = GL_FALSE; +GLboolean __GLEW_NV_bgr = GL_FALSE; +GLboolean __GLEW_NV_bindless_multi_draw_indirect = GL_FALSE; +GLboolean __GLEW_NV_bindless_multi_draw_indirect_count = GL_FALSE; +GLboolean __GLEW_NV_bindless_texture = GL_FALSE; +GLboolean __GLEW_NV_blend_equation_advanced = GL_FALSE; +GLboolean __GLEW_NV_blend_equation_advanced_coherent = GL_FALSE; +GLboolean __GLEW_NV_blend_minmax_factor = GL_FALSE; +GLboolean __GLEW_NV_blend_square = GL_FALSE; +GLboolean __GLEW_NV_clip_space_w_scaling = GL_FALSE; +GLboolean __GLEW_NV_command_list = GL_FALSE; +GLboolean __GLEW_NV_compute_program5 = GL_FALSE; +GLboolean __GLEW_NV_conditional_render = GL_FALSE; +GLboolean __GLEW_NV_conservative_raster = GL_FALSE; +GLboolean __GLEW_NV_conservative_raster_dilate = GL_FALSE; +GLboolean __GLEW_NV_conservative_raster_pre_snap_triangles = GL_FALSE; +GLboolean __GLEW_NV_copy_buffer = GL_FALSE; +GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE; +GLboolean __GLEW_NV_copy_image = GL_FALSE; +GLboolean __GLEW_NV_deep_texture3D = GL_FALSE; +GLboolean __GLEW_NV_depth_buffer_float = GL_FALSE; +GLboolean __GLEW_NV_depth_clamp = GL_FALSE; +GLboolean __GLEW_NV_depth_range_unclamped = GL_FALSE; +GLboolean __GLEW_NV_draw_buffers = GL_FALSE; +GLboolean __GLEW_NV_draw_instanced = GL_FALSE; +GLboolean __GLEW_NV_draw_texture = GL_FALSE; +GLboolean __GLEW_NV_draw_vulkan_image = GL_FALSE; +GLboolean __GLEW_NV_evaluators = GL_FALSE; +GLboolean __GLEW_NV_explicit_attrib_location = GL_FALSE; +GLboolean __GLEW_NV_explicit_multisample = GL_FALSE; +GLboolean __GLEW_NV_fbo_color_attachments = GL_FALSE; +GLboolean __GLEW_NV_fence = GL_FALSE; +GLboolean __GLEW_NV_fill_rectangle = GL_FALSE; +GLboolean __GLEW_NV_float_buffer = GL_FALSE; +GLboolean __GLEW_NV_fog_distance = GL_FALSE; +GLboolean __GLEW_NV_fragment_coverage_to_color = GL_FALSE; +GLboolean __GLEW_NV_fragment_program = GL_FALSE; +GLboolean __GLEW_NV_fragment_program2 = GL_FALSE; +GLboolean __GLEW_NV_fragment_program4 = GL_FALSE; +GLboolean __GLEW_NV_fragment_program_option = GL_FALSE; +GLboolean __GLEW_NV_fragment_shader_interlock = GL_FALSE; +GLboolean __GLEW_NV_framebuffer_blit = GL_FALSE; +GLboolean __GLEW_NV_framebuffer_mixed_samples = GL_FALSE; +GLboolean __GLEW_NV_framebuffer_multisample = GL_FALSE; +GLboolean __GLEW_NV_framebuffer_multisample_coverage = GL_FALSE; +GLboolean __GLEW_NV_generate_mipmap_sRGB = GL_FALSE; +GLboolean __GLEW_NV_geometry_program4 = GL_FALSE; +GLboolean __GLEW_NV_geometry_shader4 = GL_FALSE; +GLboolean __GLEW_NV_geometry_shader_passthrough = GL_FALSE; +GLboolean __GLEW_NV_gpu_multicast = GL_FALSE; +GLboolean __GLEW_NV_gpu_program4 = GL_FALSE; +GLboolean __GLEW_NV_gpu_program5 = GL_FALSE; +GLboolean __GLEW_NV_gpu_program5_mem_extended = GL_FALSE; +GLboolean __GLEW_NV_gpu_program_fp64 = GL_FALSE; +GLboolean __GLEW_NV_gpu_shader5 = GL_FALSE; +GLboolean __GLEW_NV_half_float = GL_FALSE; +GLboolean __GLEW_NV_image_formats = GL_FALSE; +GLboolean __GLEW_NV_instanced_arrays = GL_FALSE; +GLboolean __GLEW_NV_internalformat_sample_query = GL_FALSE; +GLboolean __GLEW_NV_light_max_exponent = GL_FALSE; +GLboolean __GLEW_NV_multisample_coverage = GL_FALSE; +GLboolean __GLEW_NV_multisample_filter_hint = GL_FALSE; +GLboolean __GLEW_NV_non_square_matrices = GL_FALSE; +GLboolean __GLEW_NV_occlusion_query = GL_FALSE; +GLboolean __GLEW_NV_pack_subimage = GL_FALSE; +GLboolean __GLEW_NV_packed_depth_stencil = GL_FALSE; +GLboolean __GLEW_NV_packed_float = GL_FALSE; +GLboolean __GLEW_NV_packed_float_linear = GL_FALSE; +GLboolean __GLEW_NV_parameter_buffer_object = GL_FALSE; +GLboolean __GLEW_NV_parameter_buffer_object2 = GL_FALSE; +GLboolean __GLEW_NV_path_rendering = GL_FALSE; +GLboolean __GLEW_NV_path_rendering_shared_edge = GL_FALSE; +GLboolean __GLEW_NV_pixel_buffer_object = GL_FALSE; +GLboolean __GLEW_NV_pixel_data_range = GL_FALSE; +GLboolean __GLEW_NV_platform_binary = GL_FALSE; +GLboolean __GLEW_NV_point_sprite = GL_FALSE; +GLboolean __GLEW_NV_polygon_mode = GL_FALSE; +GLboolean __GLEW_NV_present_video = GL_FALSE; +GLboolean __GLEW_NV_primitive_restart = GL_FALSE; +GLboolean __GLEW_NV_read_depth = GL_FALSE; +GLboolean __GLEW_NV_read_depth_stencil = GL_FALSE; +GLboolean __GLEW_NV_read_stencil = GL_FALSE; +GLboolean __GLEW_NV_register_combiners = GL_FALSE; +GLboolean __GLEW_NV_register_combiners2 = GL_FALSE; +GLboolean __GLEW_NV_robustness_video_memory_purge = GL_FALSE; +GLboolean __GLEW_NV_sRGB_formats = GL_FALSE; +GLboolean __GLEW_NV_sample_locations = GL_FALSE; +GLboolean __GLEW_NV_sample_mask_override_coverage = GL_FALSE; +GLboolean __GLEW_NV_shader_atomic_counters = GL_FALSE; +GLboolean __GLEW_NV_shader_atomic_float = GL_FALSE; +GLboolean __GLEW_NV_shader_atomic_float64 = GL_FALSE; +GLboolean __GLEW_NV_shader_atomic_fp16_vector = GL_FALSE; +GLboolean __GLEW_NV_shader_atomic_int64 = GL_FALSE; +GLboolean __GLEW_NV_shader_buffer_load = GL_FALSE; +GLboolean __GLEW_NV_shader_noperspective_interpolation = GL_FALSE; +GLboolean __GLEW_NV_shader_storage_buffer_object = GL_FALSE; +GLboolean __GLEW_NV_shader_thread_group = GL_FALSE; +GLboolean __GLEW_NV_shader_thread_shuffle = GL_FALSE; +GLboolean __GLEW_NV_shadow_samplers_array = GL_FALSE; +GLboolean __GLEW_NV_shadow_samplers_cube = GL_FALSE; +GLboolean __GLEW_NV_stereo_view_rendering = GL_FALSE; +GLboolean __GLEW_NV_tessellation_program5 = GL_FALSE; +GLboolean __GLEW_NV_texgen_emboss = GL_FALSE; +GLboolean __GLEW_NV_texgen_reflection = GL_FALSE; +GLboolean __GLEW_NV_texture_array = GL_FALSE; +GLboolean __GLEW_NV_texture_barrier = GL_FALSE; +GLboolean __GLEW_NV_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_NV_texture_compression_latc = GL_FALSE; +GLboolean __GLEW_NV_texture_compression_s3tc = GL_FALSE; +GLboolean __GLEW_NV_texture_compression_s3tc_update = GL_FALSE; +GLboolean __GLEW_NV_texture_compression_vtc = GL_FALSE; +GLboolean __GLEW_NV_texture_env_combine4 = GL_FALSE; +GLboolean __GLEW_NV_texture_expand_normal = GL_FALSE; +GLboolean __GLEW_NV_texture_multisample = GL_FALSE; +GLboolean __GLEW_NV_texture_npot_2D_mipmap = GL_FALSE; +GLboolean __GLEW_NV_texture_rectangle = GL_FALSE; +GLboolean __GLEW_NV_texture_rectangle_compressed = GL_FALSE; +GLboolean __GLEW_NV_texture_shader = GL_FALSE; +GLboolean __GLEW_NV_texture_shader2 = GL_FALSE; +GLboolean __GLEW_NV_texture_shader3 = GL_FALSE; +GLboolean __GLEW_NV_transform_feedback = GL_FALSE; +GLboolean __GLEW_NV_transform_feedback2 = GL_FALSE; +GLboolean __GLEW_NV_uniform_buffer_unified_memory = GL_FALSE; +GLboolean __GLEW_NV_vdpau_interop = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range = GL_FALSE; +GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_attrib_integer_64bit = GL_FALSE; +GLboolean __GLEW_NV_vertex_buffer_unified_memory = GL_FALSE; +GLboolean __GLEW_NV_vertex_program = GL_FALSE; +GLboolean __GLEW_NV_vertex_program1_1 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program2 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program2_option = GL_FALSE; +GLboolean __GLEW_NV_vertex_program3 = GL_FALSE; +GLboolean __GLEW_NV_vertex_program4 = GL_FALSE; +GLboolean __GLEW_NV_video_capture = GL_FALSE; +GLboolean __GLEW_NV_viewport_array = GL_FALSE; +GLboolean __GLEW_NV_viewport_array2 = GL_FALSE; +GLboolean __GLEW_NV_viewport_swizzle = GL_FALSE; +GLboolean __GLEW_OES_byte_coordinates = GL_FALSE; +GLboolean __GLEW_OML_interlace = GL_FALSE; +GLboolean __GLEW_OML_resample = GL_FALSE; +GLboolean __GLEW_OML_subsample = GL_FALSE; +GLboolean __GLEW_OVR_multiview = GL_FALSE; +GLboolean __GLEW_OVR_multiview2 = GL_FALSE; +GLboolean __GLEW_OVR_multiview_multisampled_render_to_texture = GL_FALSE; +GLboolean __GLEW_PGI_misc_hints = GL_FALSE; +GLboolean __GLEW_PGI_vertex_hints = GL_FALSE; +GLboolean __GLEW_QCOM_alpha_test = GL_FALSE; +GLboolean __GLEW_QCOM_binning_control = GL_FALSE; +GLboolean __GLEW_QCOM_driver_control = GL_FALSE; +GLboolean __GLEW_QCOM_extended_get = GL_FALSE; +GLboolean __GLEW_QCOM_extended_get2 = GL_FALSE; +GLboolean __GLEW_QCOM_framebuffer_foveated = GL_FALSE; +GLboolean __GLEW_QCOM_perfmon_global_mode = GL_FALSE; +GLboolean __GLEW_QCOM_shader_framebuffer_fetch_noncoherent = GL_FALSE; +GLboolean __GLEW_QCOM_tiled_rendering = GL_FALSE; +GLboolean __GLEW_QCOM_writeonly_rendering = GL_FALSE; +GLboolean __GLEW_REGAL_ES1_0_compatibility = GL_FALSE; +GLboolean __GLEW_REGAL_ES1_1_compatibility = GL_FALSE; +GLboolean __GLEW_REGAL_enable = GL_FALSE; +GLboolean __GLEW_REGAL_error_string = GL_FALSE; +GLboolean __GLEW_REGAL_extension_query = GL_FALSE; +GLboolean __GLEW_REGAL_log = GL_FALSE; +GLboolean __GLEW_REGAL_proc_address = GL_FALSE; +GLboolean __GLEW_REND_screen_coordinates = GL_FALSE; +GLboolean __GLEW_S3_s3tc = GL_FALSE; +GLboolean __GLEW_SGIS_clip_band_hint = GL_FALSE; +GLboolean __GLEW_SGIS_color_range = GL_FALSE; +GLboolean __GLEW_SGIS_detail_texture = GL_FALSE; +GLboolean __GLEW_SGIS_fog_function = GL_FALSE; +GLboolean __GLEW_SGIS_generate_mipmap = GL_FALSE; +GLboolean __GLEW_SGIS_line_texgen = GL_FALSE; +GLboolean __GLEW_SGIS_multisample = GL_FALSE; +GLboolean __GLEW_SGIS_multitexture = GL_FALSE; +GLboolean __GLEW_SGIS_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIS_point_line_texgen = GL_FALSE; +GLboolean __GLEW_SGIS_shared_multisample = GL_FALSE; +GLboolean __GLEW_SGIS_sharpen_texture = GL_FALSE; +GLboolean __GLEW_SGIS_texture4D = GL_FALSE; +GLboolean __GLEW_SGIS_texture_border_clamp = GL_FALSE; +GLboolean __GLEW_SGIS_texture_edge_clamp = GL_FALSE; +GLboolean __GLEW_SGIS_texture_filter4 = GL_FALSE; +GLboolean __GLEW_SGIS_texture_lod = GL_FALSE; +GLboolean __GLEW_SGIS_texture_select = GL_FALSE; +GLboolean __GLEW_SGIX_async = GL_FALSE; +GLboolean __GLEW_SGIX_async_histogram = GL_FALSE; +GLboolean __GLEW_SGIX_async_pixel = GL_FALSE; +GLboolean __GLEW_SGIX_bali_g_instruments = GL_FALSE; +GLboolean __GLEW_SGIX_bali_r_instruments = GL_FALSE; +GLboolean __GLEW_SGIX_bali_timer_instruments = GL_FALSE; +GLboolean __GLEW_SGIX_blend_alpha_minmax = GL_FALSE; +GLboolean __GLEW_SGIX_blend_cadd = GL_FALSE; +GLboolean __GLEW_SGIX_blend_cmultiply = GL_FALSE; +GLboolean __GLEW_SGIX_calligraphic_fragment = GL_FALSE; +GLboolean __GLEW_SGIX_clipmap = GL_FALSE; +GLboolean __GLEW_SGIX_color_matrix_accuracy = GL_FALSE; +GLboolean __GLEW_SGIX_color_table_index_mode = GL_FALSE; +GLboolean __GLEW_SGIX_complex_polar = GL_FALSE; +GLboolean __GLEW_SGIX_convolution_accuracy = GL_FALSE; +GLboolean __GLEW_SGIX_cube_map = GL_FALSE; +GLboolean __GLEW_SGIX_cylinder_texgen = GL_FALSE; +GLboolean __GLEW_SGIX_datapipe = GL_FALSE; +GLboolean __GLEW_SGIX_decimation = GL_FALSE; +GLboolean __GLEW_SGIX_depth_pass_instrument = GL_FALSE; +GLboolean __GLEW_SGIX_depth_texture = GL_FALSE; +GLboolean __GLEW_SGIX_dvc = GL_FALSE; +GLboolean __GLEW_SGIX_flush_raster = GL_FALSE; +GLboolean __GLEW_SGIX_fog_blend = GL_FALSE; +GLboolean __GLEW_SGIX_fog_factor_to_alpha = GL_FALSE; +GLboolean __GLEW_SGIX_fog_layers = GL_FALSE; +GLboolean __GLEW_SGIX_fog_offset = GL_FALSE; +GLboolean __GLEW_SGIX_fog_patchy = GL_FALSE; +GLboolean __GLEW_SGIX_fog_scale = GL_FALSE; +GLboolean __GLEW_SGIX_fog_texture = GL_FALSE; +GLboolean __GLEW_SGIX_fragment_lighting_space = GL_FALSE; +GLboolean __GLEW_SGIX_fragment_specular_lighting = GL_FALSE; +GLboolean __GLEW_SGIX_fragments_instrument = GL_FALSE; +GLboolean __GLEW_SGIX_framezoom = GL_FALSE; +GLboolean __GLEW_SGIX_icc_texture = GL_FALSE; +GLboolean __GLEW_SGIX_igloo_interface = GL_FALSE; +GLboolean __GLEW_SGIX_image_compression = GL_FALSE; +GLboolean __GLEW_SGIX_impact_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIX_instrument_error = GL_FALSE; +GLboolean __GLEW_SGIX_interlace = GL_FALSE; +GLboolean __GLEW_SGIX_ir_instrument1 = GL_FALSE; +GLboolean __GLEW_SGIX_line_quality_hint = GL_FALSE; +GLboolean __GLEW_SGIX_list_priority = GL_FALSE; +GLboolean __GLEW_SGIX_mpeg1 = GL_FALSE; +GLboolean __GLEW_SGIX_mpeg2 = GL_FALSE; +GLboolean __GLEW_SGIX_nonlinear_lighting_pervertex = GL_FALSE; +GLboolean __GLEW_SGIX_nurbs_eval = GL_FALSE; +GLboolean __GLEW_SGIX_occlusion_instrument = GL_FALSE; +GLboolean __GLEW_SGIX_packed_6bytes = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture_bits = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_texture_lod = GL_FALSE; +GLboolean __GLEW_SGIX_pixel_tiles = GL_FALSE; +GLboolean __GLEW_SGIX_polynomial_ffd = GL_FALSE; +GLboolean __GLEW_SGIX_quad_mesh = GL_FALSE; +GLboolean __GLEW_SGIX_reference_plane = GL_FALSE; +GLboolean __GLEW_SGIX_resample = GL_FALSE; +GLboolean __GLEW_SGIX_scalebias_hint = GL_FALSE; +GLboolean __GLEW_SGIX_shadow = GL_FALSE; +GLboolean __GLEW_SGIX_shadow_ambient = GL_FALSE; +GLboolean __GLEW_SGIX_slim = GL_FALSE; +GLboolean __GLEW_SGIX_spotlight_cutoff = GL_FALSE; +GLboolean __GLEW_SGIX_sprite = GL_FALSE; +GLboolean __GLEW_SGIX_subdiv_patch = GL_FALSE; +GLboolean __GLEW_SGIX_subsample = GL_FALSE; +GLboolean __GLEW_SGIX_tag_sample_buffer = GL_FALSE; +GLboolean __GLEW_SGIX_texture_add_env = GL_FALSE; +GLboolean __GLEW_SGIX_texture_coordinate_clamp = GL_FALSE; +GLboolean __GLEW_SGIX_texture_lod_bias = GL_FALSE; +GLboolean __GLEW_SGIX_texture_mipmap_anisotropic = GL_FALSE; +GLboolean __GLEW_SGIX_texture_multi_buffer = GL_FALSE; +GLboolean __GLEW_SGIX_texture_phase = GL_FALSE; +GLboolean __GLEW_SGIX_texture_range = GL_FALSE; +GLboolean __GLEW_SGIX_texture_scale_bias = GL_FALSE; +GLboolean __GLEW_SGIX_texture_supersample = GL_FALSE; +GLboolean __GLEW_SGIX_vector_ops = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_array_object = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_preclip = GL_FALSE; +GLboolean __GLEW_SGIX_vertex_preclip_hint = GL_FALSE; +GLboolean __GLEW_SGIX_ycrcb = GL_FALSE; +GLboolean __GLEW_SGIX_ycrcb_subsample = GL_FALSE; +GLboolean __GLEW_SGIX_ycrcba = GL_FALSE; +GLboolean __GLEW_SGI_color_matrix = GL_FALSE; +GLboolean __GLEW_SGI_color_table = GL_FALSE; +GLboolean __GLEW_SGI_complex = GL_FALSE; +GLboolean __GLEW_SGI_complex_type = GL_FALSE; +GLboolean __GLEW_SGI_fft = GL_FALSE; +GLboolean __GLEW_SGI_texture_color_table = GL_FALSE; +GLboolean __GLEW_SUNX_constant_data = GL_FALSE; +GLboolean __GLEW_SUN_convolution_border_modes = GL_FALSE; +GLboolean __GLEW_SUN_global_alpha = GL_FALSE; +GLboolean __GLEW_SUN_mesh_array = GL_FALSE; +GLboolean __GLEW_SUN_read_video_pixels = GL_FALSE; +GLboolean __GLEW_SUN_slice_accum = GL_FALSE; +GLboolean __GLEW_SUN_triangle_list = GL_FALSE; +GLboolean __GLEW_SUN_vertex = GL_FALSE; +GLboolean __GLEW_WIN_phong_shading = GL_FALSE; +GLboolean __GLEW_WIN_scene_markerXXX = GL_FALSE; +GLboolean __GLEW_WIN_specular_fog = GL_FALSE; +GLboolean __GLEW_WIN_swap_hint = GL_FALSE; + +static const char * _glewExtensionLookup[] = { +#ifdef GL_VERSION_1_2 + "GL_VERSION_1_2", +#endif +#ifdef GL_VERSION_1_2_1 + "GL_VERSION_1_2_1", +#endif +#ifdef GL_VERSION_1_3 + "GL_VERSION_1_3", +#endif +#ifdef GL_VERSION_1_4 + "GL_VERSION_1_4", +#endif +#ifdef GL_VERSION_1_5 + "GL_VERSION_1_5", +#endif +#ifdef GL_VERSION_2_0 + "GL_VERSION_2_0", +#endif +#ifdef GL_VERSION_2_1 + "GL_VERSION_2_1", +#endif +#ifdef GL_VERSION_3_0 + "GL_VERSION_3_0", +#endif +#ifdef GL_VERSION_3_1 + "GL_VERSION_3_1", +#endif +#ifdef GL_VERSION_3_2 + "GL_VERSION_3_2", +#endif +#ifdef GL_VERSION_3_3 + "GL_VERSION_3_3", +#endif +#ifdef GL_VERSION_4_0 + "GL_VERSION_4_0", +#endif +#ifdef GL_VERSION_4_1 + "GL_VERSION_4_1", +#endif +#ifdef GL_VERSION_4_2 + "GL_VERSION_4_2", +#endif +#ifdef GL_VERSION_4_3 + "GL_VERSION_4_3", +#endif +#ifdef GL_VERSION_4_4 + "GL_VERSION_4_4", +#endif +#ifdef GL_VERSION_4_5 + "GL_VERSION_4_5", +#endif +#ifdef GL_VERSION_4_6 + "GL_VERSION_4_6", +#endif +#ifdef GL_3DFX_multisample + "GL_3DFX_multisample", +#endif +#ifdef GL_3DFX_tbuffer + "GL_3DFX_tbuffer", +#endif +#ifdef GL_3DFX_texture_compression_FXT1 + "GL_3DFX_texture_compression_FXT1", +#endif +#ifdef GL_AMD_blend_minmax_factor + "GL_AMD_blend_minmax_factor", +#endif +#ifdef GL_AMD_compressed_3DC_texture + "GL_AMD_compressed_3DC_texture", +#endif +#ifdef GL_AMD_compressed_ATC_texture + "GL_AMD_compressed_ATC_texture", +#endif +#ifdef GL_AMD_conservative_depth + "GL_AMD_conservative_depth", +#endif +#ifdef GL_AMD_debug_output + "GL_AMD_debug_output", +#endif +#ifdef GL_AMD_depth_clamp_separate + "GL_AMD_depth_clamp_separate", +#endif +#ifdef GL_AMD_draw_buffers_blend + "GL_AMD_draw_buffers_blend", +#endif +#ifdef GL_AMD_framebuffer_sample_positions + "GL_AMD_framebuffer_sample_positions", +#endif +#ifdef GL_AMD_gcn_shader + "GL_AMD_gcn_shader", +#endif +#ifdef GL_AMD_gpu_shader_half_float + "GL_AMD_gpu_shader_half_float", +#endif +#ifdef GL_AMD_gpu_shader_int16 + "GL_AMD_gpu_shader_int16", +#endif +#ifdef GL_AMD_gpu_shader_int64 + "GL_AMD_gpu_shader_int64", +#endif +#ifdef GL_AMD_interleaved_elements + "GL_AMD_interleaved_elements", +#endif +#ifdef GL_AMD_multi_draw_indirect + "GL_AMD_multi_draw_indirect", +#endif +#ifdef GL_AMD_name_gen_delete + "GL_AMD_name_gen_delete", +#endif +#ifdef GL_AMD_occlusion_query_event + "GL_AMD_occlusion_query_event", +#endif +#ifdef GL_AMD_performance_monitor + "GL_AMD_performance_monitor", +#endif +#ifdef GL_AMD_pinned_memory + "GL_AMD_pinned_memory", +#endif +#ifdef GL_AMD_program_binary_Z400 + "GL_AMD_program_binary_Z400", +#endif +#ifdef GL_AMD_query_buffer_object + "GL_AMD_query_buffer_object", +#endif +#ifdef GL_AMD_sample_positions + "GL_AMD_sample_positions", +#endif +#ifdef GL_AMD_seamless_cubemap_per_texture + "GL_AMD_seamless_cubemap_per_texture", +#endif +#ifdef GL_AMD_shader_atomic_counter_ops + "GL_AMD_shader_atomic_counter_ops", +#endif +#ifdef GL_AMD_shader_ballot + "GL_AMD_shader_ballot", +#endif +#ifdef GL_AMD_shader_explicit_vertex_parameter + "GL_AMD_shader_explicit_vertex_parameter", +#endif +#ifdef GL_AMD_shader_stencil_export + "GL_AMD_shader_stencil_export", +#endif +#ifdef GL_AMD_shader_stencil_value_export + "GL_AMD_shader_stencil_value_export", +#endif +#ifdef GL_AMD_shader_trinary_minmax + "GL_AMD_shader_trinary_minmax", +#endif +#ifdef GL_AMD_sparse_texture + "GL_AMD_sparse_texture", +#endif +#ifdef GL_AMD_stencil_operation_extended + "GL_AMD_stencil_operation_extended", +#endif +#ifdef GL_AMD_texture_gather_bias_lod + "GL_AMD_texture_gather_bias_lod", +#endif +#ifdef GL_AMD_texture_texture4 + "GL_AMD_texture_texture4", +#endif +#ifdef GL_AMD_transform_feedback3_lines_triangles + "GL_AMD_transform_feedback3_lines_triangles", +#endif +#ifdef GL_AMD_transform_feedback4 + "GL_AMD_transform_feedback4", +#endif +#ifdef GL_AMD_vertex_shader_layer + "GL_AMD_vertex_shader_layer", +#endif +#ifdef GL_AMD_vertex_shader_tessellator + "GL_AMD_vertex_shader_tessellator", +#endif +#ifdef GL_AMD_vertex_shader_viewport_index + "GL_AMD_vertex_shader_viewport_index", +#endif +#ifdef GL_ANDROID_extension_pack_es31a + "GL_ANDROID_extension_pack_es31a", +#endif +#ifdef GL_ANGLE_depth_texture + "GL_ANGLE_depth_texture", +#endif +#ifdef GL_ANGLE_framebuffer_blit + "GL_ANGLE_framebuffer_blit", +#endif +#ifdef GL_ANGLE_framebuffer_multisample + "GL_ANGLE_framebuffer_multisample", +#endif +#ifdef GL_ANGLE_instanced_arrays + "GL_ANGLE_instanced_arrays", +#endif +#ifdef GL_ANGLE_pack_reverse_row_order + "GL_ANGLE_pack_reverse_row_order", +#endif +#ifdef GL_ANGLE_program_binary + "GL_ANGLE_program_binary", +#endif +#ifdef GL_ANGLE_texture_compression_dxt1 + "GL_ANGLE_texture_compression_dxt1", +#endif +#ifdef GL_ANGLE_texture_compression_dxt3 + "GL_ANGLE_texture_compression_dxt3", +#endif +#ifdef GL_ANGLE_texture_compression_dxt5 + "GL_ANGLE_texture_compression_dxt5", +#endif +#ifdef GL_ANGLE_texture_usage + "GL_ANGLE_texture_usage", +#endif +#ifdef GL_ANGLE_timer_query + "GL_ANGLE_timer_query", +#endif +#ifdef GL_ANGLE_translated_shader_source + "GL_ANGLE_translated_shader_source", +#endif +#ifdef GL_APPLE_aux_depth_stencil + "GL_APPLE_aux_depth_stencil", +#endif +#ifdef GL_APPLE_client_storage + "GL_APPLE_client_storage", +#endif +#ifdef GL_APPLE_clip_distance + "GL_APPLE_clip_distance", +#endif +#ifdef GL_APPLE_color_buffer_packed_float + "GL_APPLE_color_buffer_packed_float", +#endif +#ifdef GL_APPLE_copy_texture_levels + "GL_APPLE_copy_texture_levels", +#endif +#ifdef GL_APPLE_element_array + "GL_APPLE_element_array", +#endif +#ifdef GL_APPLE_fence + "GL_APPLE_fence", +#endif +#ifdef GL_APPLE_float_pixels + "GL_APPLE_float_pixels", +#endif +#ifdef GL_APPLE_flush_buffer_range + "GL_APPLE_flush_buffer_range", +#endif +#ifdef GL_APPLE_framebuffer_multisample + "GL_APPLE_framebuffer_multisample", +#endif +#ifdef GL_APPLE_object_purgeable + "GL_APPLE_object_purgeable", +#endif +#ifdef GL_APPLE_pixel_buffer + "GL_APPLE_pixel_buffer", +#endif +#ifdef GL_APPLE_rgb_422 + "GL_APPLE_rgb_422", +#endif +#ifdef GL_APPLE_row_bytes + "GL_APPLE_row_bytes", +#endif +#ifdef GL_APPLE_specular_vector + "GL_APPLE_specular_vector", +#endif +#ifdef GL_APPLE_sync + "GL_APPLE_sync", +#endif +#ifdef GL_APPLE_texture_2D_limited_npot + "GL_APPLE_texture_2D_limited_npot", +#endif +#ifdef GL_APPLE_texture_format_BGRA8888 + "GL_APPLE_texture_format_BGRA8888", +#endif +#ifdef GL_APPLE_texture_max_level + "GL_APPLE_texture_max_level", +#endif +#ifdef GL_APPLE_texture_packed_float + "GL_APPLE_texture_packed_float", +#endif +#ifdef GL_APPLE_texture_range + "GL_APPLE_texture_range", +#endif +#ifdef GL_APPLE_transform_hint + "GL_APPLE_transform_hint", +#endif +#ifdef GL_APPLE_vertex_array_object + "GL_APPLE_vertex_array_object", +#endif +#ifdef GL_APPLE_vertex_array_range + "GL_APPLE_vertex_array_range", +#endif +#ifdef GL_APPLE_vertex_program_evaluators + "GL_APPLE_vertex_program_evaluators", +#endif +#ifdef GL_APPLE_ycbcr_422 + "GL_APPLE_ycbcr_422", +#endif +#ifdef GL_ARB_ES2_compatibility + "GL_ARB_ES2_compatibility", +#endif +#ifdef GL_ARB_ES3_1_compatibility + "GL_ARB_ES3_1_compatibility", +#endif +#ifdef GL_ARB_ES3_2_compatibility + "GL_ARB_ES3_2_compatibility", +#endif +#ifdef GL_ARB_ES3_compatibility + "GL_ARB_ES3_compatibility", +#endif +#ifdef GL_ARB_arrays_of_arrays + "GL_ARB_arrays_of_arrays", +#endif +#ifdef GL_ARB_base_instance + "GL_ARB_base_instance", +#endif +#ifdef GL_ARB_bindless_texture + "GL_ARB_bindless_texture", +#endif +#ifdef GL_ARB_blend_func_extended + "GL_ARB_blend_func_extended", +#endif +#ifdef GL_ARB_buffer_storage + "GL_ARB_buffer_storage", +#endif +#ifdef GL_ARB_cl_event + "GL_ARB_cl_event", +#endif +#ifdef GL_ARB_clear_buffer_object + "GL_ARB_clear_buffer_object", +#endif +#ifdef GL_ARB_clear_texture + "GL_ARB_clear_texture", +#endif +#ifdef GL_ARB_clip_control + "GL_ARB_clip_control", +#endif +#ifdef GL_ARB_color_buffer_float + "GL_ARB_color_buffer_float", +#endif +#ifdef GL_ARB_compatibility + "GL_ARB_compatibility", +#endif +#ifdef GL_ARB_compressed_texture_pixel_storage + "GL_ARB_compressed_texture_pixel_storage", +#endif +#ifdef GL_ARB_compute_shader + "GL_ARB_compute_shader", +#endif +#ifdef GL_ARB_compute_variable_group_size + "GL_ARB_compute_variable_group_size", +#endif +#ifdef GL_ARB_conditional_render_inverted + "GL_ARB_conditional_render_inverted", +#endif +#ifdef GL_ARB_conservative_depth + "GL_ARB_conservative_depth", +#endif +#ifdef GL_ARB_copy_buffer + "GL_ARB_copy_buffer", +#endif +#ifdef GL_ARB_copy_image + "GL_ARB_copy_image", +#endif +#ifdef GL_ARB_cull_distance + "GL_ARB_cull_distance", +#endif +#ifdef GL_ARB_debug_output + "GL_ARB_debug_output", +#endif +#ifdef GL_ARB_depth_buffer_float + "GL_ARB_depth_buffer_float", +#endif +#ifdef GL_ARB_depth_clamp + "GL_ARB_depth_clamp", +#endif +#ifdef GL_ARB_depth_texture + "GL_ARB_depth_texture", +#endif +#ifdef GL_ARB_derivative_control + "GL_ARB_derivative_control", +#endif +#ifdef GL_ARB_direct_state_access + "GL_ARB_direct_state_access", +#endif +#ifdef GL_ARB_draw_buffers + "GL_ARB_draw_buffers", +#endif +#ifdef GL_ARB_draw_buffers_blend + "GL_ARB_draw_buffers_blend", +#endif +#ifdef GL_ARB_draw_elements_base_vertex + "GL_ARB_draw_elements_base_vertex", +#endif +#ifdef GL_ARB_draw_indirect + "GL_ARB_draw_indirect", +#endif +#ifdef GL_ARB_draw_instanced + "GL_ARB_draw_instanced", +#endif +#ifdef GL_ARB_enhanced_layouts + "GL_ARB_enhanced_layouts", +#endif +#ifdef GL_ARB_explicit_attrib_location + "GL_ARB_explicit_attrib_location", +#endif +#ifdef GL_ARB_explicit_uniform_location + "GL_ARB_explicit_uniform_location", +#endif +#ifdef GL_ARB_fragment_coord_conventions + "GL_ARB_fragment_coord_conventions", +#endif +#ifdef GL_ARB_fragment_layer_viewport + "GL_ARB_fragment_layer_viewport", +#endif +#ifdef GL_ARB_fragment_program + "GL_ARB_fragment_program", +#endif +#ifdef GL_ARB_fragment_program_shadow + "GL_ARB_fragment_program_shadow", +#endif +#ifdef GL_ARB_fragment_shader + "GL_ARB_fragment_shader", +#endif +#ifdef GL_ARB_fragment_shader_interlock + "GL_ARB_fragment_shader_interlock", +#endif +#ifdef GL_ARB_framebuffer_no_attachments + "GL_ARB_framebuffer_no_attachments", +#endif +#ifdef GL_ARB_framebuffer_object + "GL_ARB_framebuffer_object", +#endif +#ifdef GL_ARB_framebuffer_sRGB + "GL_ARB_framebuffer_sRGB", +#endif +#ifdef GL_ARB_geometry_shader4 + "GL_ARB_geometry_shader4", +#endif +#ifdef GL_ARB_get_program_binary + "GL_ARB_get_program_binary", +#endif +#ifdef GL_ARB_get_texture_sub_image + "GL_ARB_get_texture_sub_image", +#endif +#ifdef GL_ARB_gl_spirv + "GL_ARB_gl_spirv", +#endif +#ifdef GL_ARB_gpu_shader5 + "GL_ARB_gpu_shader5", +#endif +#ifdef GL_ARB_gpu_shader_fp64 + "GL_ARB_gpu_shader_fp64", +#endif +#ifdef GL_ARB_gpu_shader_int64 + "GL_ARB_gpu_shader_int64", +#endif +#ifdef GL_ARB_half_float_pixel + "GL_ARB_half_float_pixel", +#endif +#ifdef GL_ARB_half_float_vertex + "GL_ARB_half_float_vertex", +#endif +#ifdef GL_ARB_imaging + "GL_ARB_imaging", +#endif +#ifdef GL_ARB_indirect_parameters + "GL_ARB_indirect_parameters", +#endif +#ifdef GL_ARB_instanced_arrays + "GL_ARB_instanced_arrays", +#endif +#ifdef GL_ARB_internalformat_query + "GL_ARB_internalformat_query", +#endif +#ifdef GL_ARB_internalformat_query2 + "GL_ARB_internalformat_query2", +#endif +#ifdef GL_ARB_invalidate_subdata + "GL_ARB_invalidate_subdata", +#endif +#ifdef GL_ARB_map_buffer_alignment + "GL_ARB_map_buffer_alignment", +#endif +#ifdef GL_ARB_map_buffer_range + "GL_ARB_map_buffer_range", +#endif +#ifdef GL_ARB_matrix_palette + "GL_ARB_matrix_palette", +#endif +#ifdef GL_ARB_multi_bind + "GL_ARB_multi_bind", +#endif +#ifdef GL_ARB_multi_draw_indirect + "GL_ARB_multi_draw_indirect", +#endif +#ifdef GL_ARB_multisample + "GL_ARB_multisample", +#endif +#ifdef GL_ARB_multitexture + "GL_ARB_multitexture", +#endif +#ifdef GL_ARB_occlusion_query + "GL_ARB_occlusion_query", +#endif +#ifdef GL_ARB_occlusion_query2 + "GL_ARB_occlusion_query2", +#endif +#ifdef GL_ARB_parallel_shader_compile + "GL_ARB_parallel_shader_compile", +#endif +#ifdef GL_ARB_pipeline_statistics_query + "GL_ARB_pipeline_statistics_query", +#endif +#ifdef GL_ARB_pixel_buffer_object + "GL_ARB_pixel_buffer_object", +#endif +#ifdef GL_ARB_point_parameters + "GL_ARB_point_parameters", +#endif +#ifdef GL_ARB_point_sprite + "GL_ARB_point_sprite", +#endif +#ifdef GL_ARB_polygon_offset_clamp + "GL_ARB_polygon_offset_clamp", +#endif +#ifdef GL_ARB_post_depth_coverage + "GL_ARB_post_depth_coverage", +#endif +#ifdef GL_ARB_program_interface_query + "GL_ARB_program_interface_query", +#endif +#ifdef GL_ARB_provoking_vertex + "GL_ARB_provoking_vertex", +#endif +#ifdef GL_ARB_query_buffer_object + "GL_ARB_query_buffer_object", +#endif +#ifdef GL_ARB_robust_buffer_access_behavior + "GL_ARB_robust_buffer_access_behavior", +#endif +#ifdef GL_ARB_robustness + "GL_ARB_robustness", +#endif +#ifdef GL_ARB_robustness_application_isolation + "GL_ARB_robustness_application_isolation", +#endif +#ifdef GL_ARB_robustness_share_group_isolation + "GL_ARB_robustness_share_group_isolation", +#endif +#ifdef GL_ARB_sample_locations + "GL_ARB_sample_locations", +#endif +#ifdef GL_ARB_sample_shading + "GL_ARB_sample_shading", +#endif +#ifdef GL_ARB_sampler_objects + "GL_ARB_sampler_objects", +#endif +#ifdef GL_ARB_seamless_cube_map + "GL_ARB_seamless_cube_map", +#endif +#ifdef GL_ARB_seamless_cubemap_per_texture + "GL_ARB_seamless_cubemap_per_texture", +#endif +#ifdef GL_ARB_separate_shader_objects + "GL_ARB_separate_shader_objects", +#endif +#ifdef GL_ARB_shader_atomic_counter_ops + "GL_ARB_shader_atomic_counter_ops", +#endif +#ifdef GL_ARB_shader_atomic_counters + "GL_ARB_shader_atomic_counters", +#endif +#ifdef GL_ARB_shader_ballot + "GL_ARB_shader_ballot", +#endif +#ifdef GL_ARB_shader_bit_encoding + "GL_ARB_shader_bit_encoding", +#endif +#ifdef GL_ARB_shader_clock + "GL_ARB_shader_clock", +#endif +#ifdef GL_ARB_shader_draw_parameters + "GL_ARB_shader_draw_parameters", +#endif +#ifdef GL_ARB_shader_group_vote + "GL_ARB_shader_group_vote", +#endif +#ifdef GL_ARB_shader_image_load_store + "GL_ARB_shader_image_load_store", +#endif +#ifdef GL_ARB_shader_image_size + "GL_ARB_shader_image_size", +#endif +#ifdef GL_ARB_shader_objects + "GL_ARB_shader_objects", +#endif +#ifdef GL_ARB_shader_precision + "GL_ARB_shader_precision", +#endif +#ifdef GL_ARB_shader_stencil_export + "GL_ARB_shader_stencil_export", +#endif +#ifdef GL_ARB_shader_storage_buffer_object + "GL_ARB_shader_storage_buffer_object", +#endif +#ifdef GL_ARB_shader_subroutine + "GL_ARB_shader_subroutine", +#endif +#ifdef GL_ARB_shader_texture_image_samples + "GL_ARB_shader_texture_image_samples", +#endif +#ifdef GL_ARB_shader_texture_lod + "GL_ARB_shader_texture_lod", +#endif +#ifdef GL_ARB_shader_viewport_layer_array + "GL_ARB_shader_viewport_layer_array", +#endif +#ifdef GL_ARB_shading_language_100 + "GL_ARB_shading_language_100", +#endif +#ifdef GL_ARB_shading_language_420pack + "GL_ARB_shading_language_420pack", +#endif +#ifdef GL_ARB_shading_language_include + "GL_ARB_shading_language_include", +#endif +#ifdef GL_ARB_shading_language_packing + "GL_ARB_shading_language_packing", +#endif +#ifdef GL_ARB_shadow + "GL_ARB_shadow", +#endif +#ifdef GL_ARB_shadow_ambient + "GL_ARB_shadow_ambient", +#endif +#ifdef GL_ARB_sparse_buffer + "GL_ARB_sparse_buffer", +#endif +#ifdef GL_ARB_sparse_texture + "GL_ARB_sparse_texture", +#endif +#ifdef GL_ARB_sparse_texture2 + "GL_ARB_sparse_texture2", +#endif +#ifdef GL_ARB_sparse_texture_clamp + "GL_ARB_sparse_texture_clamp", +#endif +#ifdef GL_ARB_spirv_extensions + "GL_ARB_spirv_extensions", +#endif +#ifdef GL_ARB_stencil_texturing + "GL_ARB_stencil_texturing", +#endif +#ifdef GL_ARB_sync + "GL_ARB_sync", +#endif +#ifdef GL_ARB_tessellation_shader + "GL_ARB_tessellation_shader", +#endif +#ifdef GL_ARB_texture_barrier + "GL_ARB_texture_barrier", +#endif +#ifdef GL_ARB_texture_border_clamp + "GL_ARB_texture_border_clamp", +#endif +#ifdef GL_ARB_texture_buffer_object + "GL_ARB_texture_buffer_object", +#endif +#ifdef GL_ARB_texture_buffer_object_rgb32 + "GL_ARB_texture_buffer_object_rgb32", +#endif +#ifdef GL_ARB_texture_buffer_range + "GL_ARB_texture_buffer_range", +#endif +#ifdef GL_ARB_texture_compression + "GL_ARB_texture_compression", +#endif +#ifdef GL_ARB_texture_compression_bptc + "GL_ARB_texture_compression_bptc", +#endif +#ifdef GL_ARB_texture_compression_rgtc + "GL_ARB_texture_compression_rgtc", +#endif +#ifdef GL_ARB_texture_cube_map + "GL_ARB_texture_cube_map", +#endif +#ifdef GL_ARB_texture_cube_map_array + "GL_ARB_texture_cube_map_array", +#endif +#ifdef GL_ARB_texture_env_add + "GL_ARB_texture_env_add", +#endif +#ifdef GL_ARB_texture_env_combine + "GL_ARB_texture_env_combine", +#endif +#ifdef GL_ARB_texture_env_crossbar + "GL_ARB_texture_env_crossbar", +#endif +#ifdef GL_ARB_texture_env_dot3 + "GL_ARB_texture_env_dot3", +#endif +#ifdef GL_ARB_texture_filter_anisotropic + "GL_ARB_texture_filter_anisotropic", +#endif +#ifdef GL_ARB_texture_filter_minmax + "GL_ARB_texture_filter_minmax", +#endif +#ifdef GL_ARB_texture_float + "GL_ARB_texture_float", +#endif +#ifdef GL_ARB_texture_gather + "GL_ARB_texture_gather", +#endif +#ifdef GL_ARB_texture_mirror_clamp_to_edge + "GL_ARB_texture_mirror_clamp_to_edge", +#endif +#ifdef GL_ARB_texture_mirrored_repeat + "GL_ARB_texture_mirrored_repeat", +#endif +#ifdef GL_ARB_texture_multisample + "GL_ARB_texture_multisample", +#endif +#ifdef GL_ARB_texture_non_power_of_two + "GL_ARB_texture_non_power_of_two", +#endif +#ifdef GL_ARB_texture_query_levels + "GL_ARB_texture_query_levels", +#endif +#ifdef GL_ARB_texture_query_lod + "GL_ARB_texture_query_lod", +#endif +#ifdef GL_ARB_texture_rectangle + "GL_ARB_texture_rectangle", +#endif +#ifdef GL_ARB_texture_rg + "GL_ARB_texture_rg", +#endif +#ifdef GL_ARB_texture_rgb10_a2ui + "GL_ARB_texture_rgb10_a2ui", +#endif +#ifdef GL_ARB_texture_stencil8 + "GL_ARB_texture_stencil8", +#endif +#ifdef GL_ARB_texture_storage + "GL_ARB_texture_storage", +#endif +#ifdef GL_ARB_texture_storage_multisample + "GL_ARB_texture_storage_multisample", +#endif +#ifdef GL_ARB_texture_swizzle + "GL_ARB_texture_swizzle", +#endif +#ifdef GL_ARB_texture_view + "GL_ARB_texture_view", +#endif +#ifdef GL_ARB_timer_query + "GL_ARB_timer_query", +#endif +#ifdef GL_ARB_transform_feedback2 + "GL_ARB_transform_feedback2", +#endif +#ifdef GL_ARB_transform_feedback3 + "GL_ARB_transform_feedback3", +#endif +#ifdef GL_ARB_transform_feedback_instanced + "GL_ARB_transform_feedback_instanced", +#endif +#ifdef GL_ARB_transform_feedback_overflow_query + "GL_ARB_transform_feedback_overflow_query", +#endif +#ifdef GL_ARB_transpose_matrix + "GL_ARB_transpose_matrix", +#endif +#ifdef GL_ARB_uniform_buffer_object + "GL_ARB_uniform_buffer_object", +#endif +#ifdef GL_ARB_vertex_array_bgra + "GL_ARB_vertex_array_bgra", +#endif +#ifdef GL_ARB_vertex_array_object + "GL_ARB_vertex_array_object", +#endif +#ifdef GL_ARB_vertex_attrib_64bit + "GL_ARB_vertex_attrib_64bit", +#endif +#ifdef GL_ARB_vertex_attrib_binding + "GL_ARB_vertex_attrib_binding", +#endif +#ifdef GL_ARB_vertex_blend + "GL_ARB_vertex_blend", +#endif +#ifdef GL_ARB_vertex_buffer_object + "GL_ARB_vertex_buffer_object", +#endif +#ifdef GL_ARB_vertex_program + "GL_ARB_vertex_program", +#endif +#ifdef GL_ARB_vertex_shader + "GL_ARB_vertex_shader", +#endif +#ifdef GL_ARB_vertex_type_10f_11f_11f_rev + "GL_ARB_vertex_type_10f_11f_11f_rev", +#endif +#ifdef GL_ARB_vertex_type_2_10_10_10_rev + "GL_ARB_vertex_type_2_10_10_10_rev", +#endif +#ifdef GL_ARB_viewport_array + "GL_ARB_viewport_array", +#endif +#ifdef GL_ARB_window_pos + "GL_ARB_window_pos", +#endif +#ifdef GL_ARM_mali_program_binary + "GL_ARM_mali_program_binary", +#endif +#ifdef GL_ARM_mali_shader_binary + "GL_ARM_mali_shader_binary", +#endif +#ifdef GL_ARM_rgba8 + "GL_ARM_rgba8", +#endif +#ifdef GL_ARM_shader_framebuffer_fetch + "GL_ARM_shader_framebuffer_fetch", +#endif +#ifdef GL_ARM_shader_framebuffer_fetch_depth_stencil + "GL_ARM_shader_framebuffer_fetch_depth_stencil", +#endif +#ifdef GL_ATIX_point_sprites + "GL_ATIX_point_sprites", +#endif +#ifdef GL_ATIX_texture_env_combine3 + "GL_ATIX_texture_env_combine3", +#endif +#ifdef GL_ATIX_texture_env_route + "GL_ATIX_texture_env_route", +#endif +#ifdef GL_ATIX_vertex_shader_output_point_size + "GL_ATIX_vertex_shader_output_point_size", +#endif +#ifdef GL_ATI_draw_buffers + "GL_ATI_draw_buffers", +#endif +#ifdef GL_ATI_element_array + "GL_ATI_element_array", +#endif +#ifdef GL_ATI_envmap_bumpmap + "GL_ATI_envmap_bumpmap", +#endif +#ifdef GL_ATI_fragment_shader + "GL_ATI_fragment_shader", +#endif +#ifdef GL_ATI_map_object_buffer + "GL_ATI_map_object_buffer", +#endif +#ifdef GL_ATI_meminfo + "GL_ATI_meminfo", +#endif +#ifdef GL_ATI_pn_triangles + "GL_ATI_pn_triangles", +#endif +#ifdef GL_ATI_separate_stencil + "GL_ATI_separate_stencil", +#endif +#ifdef GL_ATI_shader_texture_lod + "GL_ATI_shader_texture_lod", +#endif +#ifdef GL_ATI_text_fragment_shader + "GL_ATI_text_fragment_shader", +#endif +#ifdef GL_ATI_texture_compression_3dc + "GL_ATI_texture_compression_3dc", +#endif +#ifdef GL_ATI_texture_env_combine3 + "GL_ATI_texture_env_combine3", +#endif +#ifdef GL_ATI_texture_float + "GL_ATI_texture_float", +#endif +#ifdef GL_ATI_texture_mirror_once + "GL_ATI_texture_mirror_once", +#endif +#ifdef GL_ATI_vertex_array_object + "GL_ATI_vertex_array_object", +#endif +#ifdef GL_ATI_vertex_attrib_array_object + "GL_ATI_vertex_attrib_array_object", +#endif +#ifdef GL_ATI_vertex_streams + "GL_ATI_vertex_streams", +#endif +#ifdef GL_EGL_KHR_context_flush_control + "GL_EGL_KHR_context_flush_control", +#endif +#ifdef GL_EGL_NV_robustness_video_memory_purge + "GL_EGL_NV_robustness_video_memory_purge", +#endif +#ifdef GL_EXT_422_pixels + "GL_EXT_422_pixels", +#endif +#ifdef GL_EXT_Cg_shader + "GL_EXT_Cg_shader", +#endif +#ifdef GL_EXT_EGL_image_array + "GL_EXT_EGL_image_array", +#endif +#ifdef GL_EXT_YUV_target + "GL_EXT_YUV_target", +#endif +#ifdef GL_EXT_abgr + "GL_EXT_abgr", +#endif +#ifdef GL_EXT_base_instance + "GL_EXT_base_instance", +#endif +#ifdef GL_EXT_bgra + "GL_EXT_bgra", +#endif +#ifdef GL_EXT_bindable_uniform + "GL_EXT_bindable_uniform", +#endif +#ifdef GL_EXT_blend_color + "GL_EXT_blend_color", +#endif +#ifdef GL_EXT_blend_equation_separate + "GL_EXT_blend_equation_separate", +#endif +#ifdef GL_EXT_blend_func_extended + "GL_EXT_blend_func_extended", +#endif +#ifdef GL_EXT_blend_func_separate + "GL_EXT_blend_func_separate", +#endif +#ifdef GL_EXT_blend_logic_op + "GL_EXT_blend_logic_op", +#endif +#ifdef GL_EXT_blend_minmax + "GL_EXT_blend_minmax", +#endif +#ifdef GL_EXT_blend_subtract + "GL_EXT_blend_subtract", +#endif +#ifdef GL_EXT_buffer_storage + "GL_EXT_buffer_storage", +#endif +#ifdef GL_EXT_clear_texture + "GL_EXT_clear_texture", +#endif +#ifdef GL_EXT_clip_cull_distance + "GL_EXT_clip_cull_distance", +#endif +#ifdef GL_EXT_clip_volume_hint + "GL_EXT_clip_volume_hint", +#endif +#ifdef GL_EXT_cmyka + "GL_EXT_cmyka", +#endif +#ifdef GL_EXT_color_buffer_float + "GL_EXT_color_buffer_float", +#endif +#ifdef GL_EXT_color_buffer_half_float + "GL_EXT_color_buffer_half_float", +#endif +#ifdef GL_EXT_color_subtable + "GL_EXT_color_subtable", +#endif +#ifdef GL_EXT_compiled_vertex_array + "GL_EXT_compiled_vertex_array", +#endif +#ifdef GL_EXT_compressed_ETC1_RGB8_sub_texture + "GL_EXT_compressed_ETC1_RGB8_sub_texture", +#endif +#ifdef GL_EXT_conservative_depth + "GL_EXT_conservative_depth", +#endif +#ifdef GL_EXT_convolution + "GL_EXT_convolution", +#endif +#ifdef GL_EXT_coordinate_frame + "GL_EXT_coordinate_frame", +#endif +#ifdef GL_EXT_copy_image + "GL_EXT_copy_image", +#endif +#ifdef GL_EXT_copy_texture + "GL_EXT_copy_texture", +#endif +#ifdef GL_EXT_cull_vertex + "GL_EXT_cull_vertex", +#endif +#ifdef GL_EXT_debug_label + "GL_EXT_debug_label", +#endif +#ifdef GL_EXT_debug_marker + "GL_EXT_debug_marker", +#endif +#ifdef GL_EXT_depth_bounds_test + "GL_EXT_depth_bounds_test", +#endif +#ifdef GL_EXT_direct_state_access + "GL_EXT_direct_state_access", +#endif +#ifdef GL_EXT_discard_framebuffer + "GL_EXT_discard_framebuffer", +#endif +#ifdef GL_EXT_draw_buffers + "GL_EXT_draw_buffers", +#endif +#ifdef GL_EXT_draw_buffers2 + "GL_EXT_draw_buffers2", +#endif +#ifdef GL_EXT_draw_buffers_indexed + "GL_EXT_draw_buffers_indexed", +#endif +#ifdef GL_EXT_draw_elements_base_vertex + "GL_EXT_draw_elements_base_vertex", +#endif +#ifdef GL_EXT_draw_instanced + "GL_EXT_draw_instanced", +#endif +#ifdef GL_EXT_draw_range_elements + "GL_EXT_draw_range_elements", +#endif +#ifdef GL_EXT_external_buffer + "GL_EXT_external_buffer", +#endif +#ifdef GL_EXT_float_blend + "GL_EXT_float_blend", +#endif +#ifdef GL_EXT_fog_coord + "GL_EXT_fog_coord", +#endif +#ifdef GL_EXT_frag_depth + "GL_EXT_frag_depth", +#endif +#ifdef GL_EXT_fragment_lighting + "GL_EXT_fragment_lighting", +#endif +#ifdef GL_EXT_framebuffer_blit + "GL_EXT_framebuffer_blit", +#endif +#ifdef GL_EXT_framebuffer_multisample + "GL_EXT_framebuffer_multisample", +#endif +#ifdef GL_EXT_framebuffer_multisample_blit_scaled + "GL_EXT_framebuffer_multisample_blit_scaled", +#endif +#ifdef GL_EXT_framebuffer_object + "GL_EXT_framebuffer_object", +#endif +#ifdef GL_EXT_framebuffer_sRGB + "GL_EXT_framebuffer_sRGB", +#endif +#ifdef GL_EXT_geometry_point_size + "GL_EXT_geometry_point_size", +#endif +#ifdef GL_EXT_geometry_shader + "GL_EXT_geometry_shader", +#endif +#ifdef GL_EXT_geometry_shader4 + "GL_EXT_geometry_shader4", +#endif +#ifdef GL_EXT_gpu_program_parameters + "GL_EXT_gpu_program_parameters", +#endif +#ifdef GL_EXT_gpu_shader4 + "GL_EXT_gpu_shader4", +#endif +#ifdef GL_EXT_gpu_shader5 + "GL_EXT_gpu_shader5", +#endif +#ifdef GL_EXT_histogram + "GL_EXT_histogram", +#endif +#ifdef GL_EXT_index_array_formats + "GL_EXT_index_array_formats", +#endif +#ifdef GL_EXT_index_func + "GL_EXT_index_func", +#endif +#ifdef GL_EXT_index_material + "GL_EXT_index_material", +#endif +#ifdef GL_EXT_index_texture + "GL_EXT_index_texture", +#endif +#ifdef GL_EXT_instanced_arrays + "GL_EXT_instanced_arrays", +#endif +#ifdef GL_EXT_light_texture + "GL_EXT_light_texture", +#endif +#ifdef GL_EXT_map_buffer_range + "GL_EXT_map_buffer_range", +#endif +#ifdef GL_EXT_memory_object + "GL_EXT_memory_object", +#endif +#ifdef GL_EXT_memory_object_fd + "GL_EXT_memory_object_fd", +#endif +#ifdef GL_EXT_memory_object_win32 + "GL_EXT_memory_object_win32", +#endif +#ifdef GL_EXT_misc_attribute + "GL_EXT_misc_attribute", +#endif +#ifdef GL_EXT_multi_draw_arrays + "GL_EXT_multi_draw_arrays", +#endif +#ifdef GL_EXT_multi_draw_indirect + "GL_EXT_multi_draw_indirect", +#endif +#ifdef GL_EXT_multiple_textures + "GL_EXT_multiple_textures", +#endif +#ifdef GL_EXT_multisample + "GL_EXT_multisample", +#endif +#ifdef GL_EXT_multisample_compatibility + "GL_EXT_multisample_compatibility", +#endif +#ifdef GL_EXT_multisampled_render_to_texture + "GL_EXT_multisampled_render_to_texture", +#endif +#ifdef GL_EXT_multisampled_render_to_texture2 + "GL_EXT_multisampled_render_to_texture2", +#endif +#ifdef GL_EXT_multiview_draw_buffers + "GL_EXT_multiview_draw_buffers", +#endif +#ifdef GL_EXT_packed_depth_stencil + "GL_EXT_packed_depth_stencil", +#endif +#ifdef GL_EXT_packed_float + "GL_EXT_packed_float", +#endif +#ifdef GL_EXT_packed_pixels + "GL_EXT_packed_pixels", +#endif +#ifdef GL_EXT_paletted_texture + "GL_EXT_paletted_texture", +#endif +#ifdef GL_EXT_pixel_buffer_object + "GL_EXT_pixel_buffer_object", +#endif +#ifdef GL_EXT_pixel_transform + "GL_EXT_pixel_transform", +#endif +#ifdef GL_EXT_pixel_transform_color_table + "GL_EXT_pixel_transform_color_table", +#endif +#ifdef GL_EXT_point_parameters + "GL_EXT_point_parameters", +#endif +#ifdef GL_EXT_polygon_offset + "GL_EXT_polygon_offset", +#endif +#ifdef GL_EXT_polygon_offset_clamp + "GL_EXT_polygon_offset_clamp", +#endif +#ifdef GL_EXT_post_depth_coverage + "GL_EXT_post_depth_coverage", +#endif +#ifdef GL_EXT_provoking_vertex + "GL_EXT_provoking_vertex", +#endif +#ifdef GL_EXT_pvrtc_sRGB + "GL_EXT_pvrtc_sRGB", +#endif +#ifdef GL_EXT_raster_multisample + "GL_EXT_raster_multisample", +#endif +#ifdef GL_EXT_read_format_bgra + "GL_EXT_read_format_bgra", +#endif +#ifdef GL_EXT_render_snorm + "GL_EXT_render_snorm", +#endif +#ifdef GL_EXT_rescale_normal + "GL_EXT_rescale_normal", +#endif +#ifdef GL_EXT_sRGB + "GL_EXT_sRGB", +#endif +#ifdef GL_EXT_sRGB_write_control + "GL_EXT_sRGB_write_control", +#endif +#ifdef GL_EXT_scene_marker + "GL_EXT_scene_marker", +#endif +#ifdef GL_EXT_secondary_color + "GL_EXT_secondary_color", +#endif +#ifdef GL_EXT_semaphore + "GL_EXT_semaphore", +#endif +#ifdef GL_EXT_semaphore_fd + "GL_EXT_semaphore_fd", +#endif +#ifdef GL_EXT_semaphore_win32 + "GL_EXT_semaphore_win32", +#endif +#ifdef GL_EXT_separate_shader_objects + "GL_EXT_separate_shader_objects", +#endif +#ifdef GL_EXT_separate_specular_color + "GL_EXT_separate_specular_color", +#endif +#ifdef GL_EXT_shader_framebuffer_fetch + "GL_EXT_shader_framebuffer_fetch", +#endif +#ifdef GL_EXT_shader_group_vote + "GL_EXT_shader_group_vote", +#endif +#ifdef GL_EXT_shader_image_load_formatted + "GL_EXT_shader_image_load_formatted", +#endif +#ifdef GL_EXT_shader_image_load_store + "GL_EXT_shader_image_load_store", +#endif +#ifdef GL_EXT_shader_implicit_conversions + "GL_EXT_shader_implicit_conversions", +#endif +#ifdef GL_EXT_shader_integer_mix + "GL_EXT_shader_integer_mix", +#endif +#ifdef GL_EXT_shader_io_blocks + "GL_EXT_shader_io_blocks", +#endif +#ifdef GL_EXT_shader_non_constant_global_initializers + "GL_EXT_shader_non_constant_global_initializers", +#endif +#ifdef GL_EXT_shader_pixel_local_storage + "GL_EXT_shader_pixel_local_storage", +#endif +#ifdef GL_EXT_shader_pixel_local_storage2 + "GL_EXT_shader_pixel_local_storage2", +#endif +#ifdef GL_EXT_shader_texture_lod + "GL_EXT_shader_texture_lod", +#endif +#ifdef GL_EXT_shadow_funcs + "GL_EXT_shadow_funcs", +#endif +#ifdef GL_EXT_shadow_samplers + "GL_EXT_shadow_samplers", +#endif +#ifdef GL_EXT_shared_texture_palette + "GL_EXT_shared_texture_palette", +#endif +#ifdef GL_EXT_sparse_texture + "GL_EXT_sparse_texture", +#endif +#ifdef GL_EXT_sparse_texture2 + "GL_EXT_sparse_texture2", +#endif +#ifdef GL_EXT_stencil_clear_tag + "GL_EXT_stencil_clear_tag", +#endif +#ifdef GL_EXT_stencil_two_side + "GL_EXT_stencil_two_side", +#endif +#ifdef GL_EXT_stencil_wrap + "GL_EXT_stencil_wrap", +#endif +#ifdef GL_EXT_subtexture + "GL_EXT_subtexture", +#endif +#ifdef GL_EXT_texture + "GL_EXT_texture", +#endif +#ifdef GL_EXT_texture3D + "GL_EXT_texture3D", +#endif +#ifdef GL_EXT_texture_array + "GL_EXT_texture_array", +#endif +#ifdef GL_EXT_texture_buffer_object + "GL_EXT_texture_buffer_object", +#endif +#ifdef GL_EXT_texture_compression_astc_decode_mode + "GL_EXT_texture_compression_astc_decode_mode", +#endif +#ifdef GL_EXT_texture_compression_astc_decode_mode_rgb9e5 + "GL_EXT_texture_compression_astc_decode_mode_rgb9e5", +#endif +#ifdef GL_EXT_texture_compression_bptc + "GL_EXT_texture_compression_bptc", +#endif +#ifdef GL_EXT_texture_compression_dxt1 + "GL_EXT_texture_compression_dxt1", +#endif +#ifdef GL_EXT_texture_compression_latc + "GL_EXT_texture_compression_latc", +#endif +#ifdef GL_EXT_texture_compression_rgtc + "GL_EXT_texture_compression_rgtc", +#endif +#ifdef GL_EXT_texture_compression_s3tc + "GL_EXT_texture_compression_s3tc", +#endif +#ifdef GL_EXT_texture_cube_map + "GL_EXT_texture_cube_map", +#endif +#ifdef GL_EXT_texture_cube_map_array + "GL_EXT_texture_cube_map_array", +#endif +#ifdef GL_EXT_texture_edge_clamp + "GL_EXT_texture_edge_clamp", +#endif +#ifdef GL_EXT_texture_env + "GL_EXT_texture_env", +#endif +#ifdef GL_EXT_texture_env_add + "GL_EXT_texture_env_add", +#endif +#ifdef GL_EXT_texture_env_combine + "GL_EXT_texture_env_combine", +#endif +#ifdef GL_EXT_texture_env_dot3 + "GL_EXT_texture_env_dot3", +#endif +#ifdef GL_EXT_texture_filter_anisotropic + "GL_EXT_texture_filter_anisotropic", +#endif +#ifdef GL_EXT_texture_filter_minmax + "GL_EXT_texture_filter_minmax", +#endif +#ifdef GL_EXT_texture_format_BGRA8888 + "GL_EXT_texture_format_BGRA8888", +#endif +#ifdef GL_EXT_texture_integer + "GL_EXT_texture_integer", +#endif +#ifdef GL_EXT_texture_lod_bias + "GL_EXT_texture_lod_bias", +#endif +#ifdef GL_EXT_texture_mirror_clamp + "GL_EXT_texture_mirror_clamp", +#endif +#ifdef GL_EXT_texture_norm16 + "GL_EXT_texture_norm16", +#endif +#ifdef GL_EXT_texture_object + "GL_EXT_texture_object", +#endif +#ifdef GL_EXT_texture_perturb_normal + "GL_EXT_texture_perturb_normal", +#endif +#ifdef GL_EXT_texture_rectangle + "GL_EXT_texture_rectangle", +#endif +#ifdef GL_EXT_texture_rg + "GL_EXT_texture_rg", +#endif +#ifdef GL_EXT_texture_sRGB + "GL_EXT_texture_sRGB", +#endif +#ifdef GL_EXT_texture_sRGB_R8 + "GL_EXT_texture_sRGB_R8", +#endif +#ifdef GL_EXT_texture_sRGB_RG8 + "GL_EXT_texture_sRGB_RG8", +#endif +#ifdef GL_EXT_texture_sRGB_decode + "GL_EXT_texture_sRGB_decode", +#endif +#ifdef GL_EXT_texture_shared_exponent + "GL_EXT_texture_shared_exponent", +#endif +#ifdef GL_EXT_texture_snorm + "GL_EXT_texture_snorm", +#endif +#ifdef GL_EXT_texture_storage + "GL_EXT_texture_storage", +#endif +#ifdef GL_EXT_texture_swizzle + "GL_EXT_texture_swizzle", +#endif +#ifdef GL_EXT_texture_type_2_10_10_10_REV + "GL_EXT_texture_type_2_10_10_10_REV", +#endif +#ifdef GL_EXT_texture_view + "GL_EXT_texture_view", +#endif +#ifdef GL_EXT_timer_query + "GL_EXT_timer_query", +#endif +#ifdef GL_EXT_transform_feedback + "GL_EXT_transform_feedback", +#endif +#ifdef GL_EXT_unpack_subimage + "GL_EXT_unpack_subimage", +#endif +#ifdef GL_EXT_vertex_array + "GL_EXT_vertex_array", +#endif +#ifdef GL_EXT_vertex_array_bgra + "GL_EXT_vertex_array_bgra", +#endif +#ifdef GL_EXT_vertex_array_setXXX + "GL_EXT_vertex_array_setXXX", +#endif +#ifdef GL_EXT_vertex_attrib_64bit + "GL_EXT_vertex_attrib_64bit", +#endif +#ifdef GL_EXT_vertex_shader + "GL_EXT_vertex_shader", +#endif +#ifdef GL_EXT_vertex_weighting + "GL_EXT_vertex_weighting", +#endif +#ifdef GL_EXT_win32_keyed_mutex + "GL_EXT_win32_keyed_mutex", +#endif +#ifdef GL_EXT_window_rectangles + "GL_EXT_window_rectangles", +#endif +#ifdef GL_EXT_x11_sync_object + "GL_EXT_x11_sync_object", +#endif +#ifdef GL_GREMEDY_frame_terminator + "GL_GREMEDY_frame_terminator", +#endif +#ifdef GL_GREMEDY_string_marker + "GL_GREMEDY_string_marker", +#endif +#ifdef GL_HP_convolution_border_modes + "GL_HP_convolution_border_modes", +#endif +#ifdef GL_HP_image_transform + "GL_HP_image_transform", +#endif +#ifdef GL_HP_occlusion_test + "GL_HP_occlusion_test", +#endif +#ifdef GL_HP_texture_lighting + "GL_HP_texture_lighting", +#endif +#ifdef GL_IBM_cull_vertex + "GL_IBM_cull_vertex", +#endif +#ifdef GL_IBM_multimode_draw_arrays + "GL_IBM_multimode_draw_arrays", +#endif +#ifdef GL_IBM_rasterpos_clip + "GL_IBM_rasterpos_clip", +#endif +#ifdef GL_IBM_static_data + "GL_IBM_static_data", +#endif +#ifdef GL_IBM_texture_mirrored_repeat + "GL_IBM_texture_mirrored_repeat", +#endif +#ifdef GL_IBM_vertex_array_lists + "GL_IBM_vertex_array_lists", +#endif +#ifdef GL_INGR_color_clamp + "GL_INGR_color_clamp", +#endif +#ifdef GL_INGR_interlace_read + "GL_INGR_interlace_read", +#endif +#ifdef GL_INTEL_conservative_rasterization + "GL_INTEL_conservative_rasterization", +#endif +#ifdef GL_INTEL_fragment_shader_ordering + "GL_INTEL_fragment_shader_ordering", +#endif +#ifdef GL_INTEL_framebuffer_CMAA + "GL_INTEL_framebuffer_CMAA", +#endif +#ifdef GL_INTEL_map_texture + "GL_INTEL_map_texture", +#endif +#ifdef GL_INTEL_parallel_arrays + "GL_INTEL_parallel_arrays", +#endif +#ifdef GL_INTEL_performance_query + "GL_INTEL_performance_query", +#endif +#ifdef GL_INTEL_texture_scissor + "GL_INTEL_texture_scissor", +#endif +#ifdef GL_KHR_blend_equation_advanced + "GL_KHR_blend_equation_advanced", +#endif +#ifdef GL_KHR_blend_equation_advanced_coherent + "GL_KHR_blend_equation_advanced_coherent", +#endif +#ifdef GL_KHR_context_flush_control + "GL_KHR_context_flush_control", +#endif +#ifdef GL_KHR_debug + "GL_KHR_debug", +#endif +#ifdef GL_KHR_no_error + "GL_KHR_no_error", +#endif +#ifdef GL_KHR_parallel_shader_compile + "GL_KHR_parallel_shader_compile", +#endif +#ifdef GL_KHR_robust_buffer_access_behavior + "GL_KHR_robust_buffer_access_behavior", +#endif +#ifdef GL_KHR_robustness + "GL_KHR_robustness", +#endif +#ifdef GL_KHR_texture_compression_astc_hdr + "GL_KHR_texture_compression_astc_hdr", +#endif +#ifdef GL_KHR_texture_compression_astc_ldr + "GL_KHR_texture_compression_astc_ldr", +#endif +#ifdef GL_KHR_texture_compression_astc_sliced_3d + "GL_KHR_texture_compression_astc_sliced_3d", +#endif +#ifdef GL_KTX_buffer_region + "GL_KTX_buffer_region", +#endif +#ifdef GL_MESAX_texture_stack + "GL_MESAX_texture_stack", +#endif +#ifdef GL_MESA_pack_invert + "GL_MESA_pack_invert", +#endif +#ifdef GL_MESA_resize_buffers + "GL_MESA_resize_buffers", +#endif +#ifdef GL_MESA_shader_integer_functions + "GL_MESA_shader_integer_functions", +#endif +#ifdef GL_MESA_window_pos + "GL_MESA_window_pos", +#endif +#ifdef GL_MESA_ycbcr_texture + "GL_MESA_ycbcr_texture", +#endif +#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers + "GL_NVX_blend_equation_advanced_multi_draw_buffers", +#endif +#ifdef GL_NVX_conditional_render + "GL_NVX_conditional_render", +#endif +#ifdef GL_NVX_gpu_memory_info + "GL_NVX_gpu_memory_info", +#endif +#ifdef GL_NVX_linked_gpu_multicast + "GL_NVX_linked_gpu_multicast", +#endif +#ifdef GL_NV_3dvision_settings + "GL_NV_3dvision_settings", +#endif +#ifdef GL_NV_EGL_stream_consumer_external + "GL_NV_EGL_stream_consumer_external", +#endif +#ifdef GL_NV_alpha_to_coverage_dither_control + "GL_NV_alpha_to_coverage_dither_control", +#endif +#ifdef GL_NV_bgr + "GL_NV_bgr", +#endif +#ifdef GL_NV_bindless_multi_draw_indirect + "GL_NV_bindless_multi_draw_indirect", +#endif +#ifdef GL_NV_bindless_multi_draw_indirect_count + "GL_NV_bindless_multi_draw_indirect_count", +#endif +#ifdef GL_NV_bindless_texture + "GL_NV_bindless_texture", +#endif +#ifdef GL_NV_blend_equation_advanced + "GL_NV_blend_equation_advanced", +#endif +#ifdef GL_NV_blend_equation_advanced_coherent + "GL_NV_blend_equation_advanced_coherent", +#endif +#ifdef GL_NV_blend_minmax_factor + "GL_NV_blend_minmax_factor", +#endif +#ifdef GL_NV_blend_square + "GL_NV_blend_square", +#endif +#ifdef GL_NV_clip_space_w_scaling + "GL_NV_clip_space_w_scaling", +#endif +#ifdef GL_NV_command_list + "GL_NV_command_list", +#endif +#ifdef GL_NV_compute_program5 + "GL_NV_compute_program5", +#endif +#ifdef GL_NV_conditional_render + "GL_NV_conditional_render", +#endif +#ifdef GL_NV_conservative_raster + "GL_NV_conservative_raster", +#endif +#ifdef GL_NV_conservative_raster_dilate + "GL_NV_conservative_raster_dilate", +#endif +#ifdef GL_NV_conservative_raster_pre_snap_triangles + "GL_NV_conservative_raster_pre_snap_triangles", +#endif +#ifdef GL_NV_copy_buffer + "GL_NV_copy_buffer", +#endif +#ifdef GL_NV_copy_depth_to_color + "GL_NV_copy_depth_to_color", +#endif +#ifdef GL_NV_copy_image + "GL_NV_copy_image", +#endif +#ifdef GL_NV_deep_texture3D + "GL_NV_deep_texture3D", +#endif +#ifdef GL_NV_depth_buffer_float + "GL_NV_depth_buffer_float", +#endif +#ifdef GL_NV_depth_clamp + "GL_NV_depth_clamp", +#endif +#ifdef GL_NV_depth_range_unclamped + "GL_NV_depth_range_unclamped", +#endif +#ifdef GL_NV_draw_buffers + "GL_NV_draw_buffers", +#endif +#ifdef GL_NV_draw_instanced + "GL_NV_draw_instanced", +#endif +#ifdef GL_NV_draw_texture + "GL_NV_draw_texture", +#endif +#ifdef GL_NV_draw_vulkan_image + "GL_NV_draw_vulkan_image", +#endif +#ifdef GL_NV_evaluators + "GL_NV_evaluators", +#endif +#ifdef GL_NV_explicit_attrib_location + "GL_NV_explicit_attrib_location", +#endif +#ifdef GL_NV_explicit_multisample + "GL_NV_explicit_multisample", +#endif +#ifdef GL_NV_fbo_color_attachments + "GL_NV_fbo_color_attachments", +#endif +#ifdef GL_NV_fence + "GL_NV_fence", +#endif +#ifdef GL_NV_fill_rectangle + "GL_NV_fill_rectangle", +#endif +#ifdef GL_NV_float_buffer + "GL_NV_float_buffer", +#endif +#ifdef GL_NV_fog_distance + "GL_NV_fog_distance", +#endif +#ifdef GL_NV_fragment_coverage_to_color + "GL_NV_fragment_coverage_to_color", +#endif +#ifdef GL_NV_fragment_program + "GL_NV_fragment_program", +#endif +#ifdef GL_NV_fragment_program2 + "GL_NV_fragment_program2", +#endif +#ifdef GL_NV_fragment_program4 + "GL_NV_fragment_program4", +#endif +#ifdef GL_NV_fragment_program_option + "GL_NV_fragment_program_option", +#endif +#ifdef GL_NV_fragment_shader_interlock + "GL_NV_fragment_shader_interlock", +#endif +#ifdef GL_NV_framebuffer_blit + "GL_NV_framebuffer_blit", +#endif +#ifdef GL_NV_framebuffer_mixed_samples + "GL_NV_framebuffer_mixed_samples", +#endif +#ifdef GL_NV_framebuffer_multisample + "GL_NV_framebuffer_multisample", +#endif +#ifdef GL_NV_framebuffer_multisample_coverage + "GL_NV_framebuffer_multisample_coverage", +#endif +#ifdef GL_NV_generate_mipmap_sRGB + "GL_NV_generate_mipmap_sRGB", +#endif +#ifdef GL_NV_geometry_program4 + "GL_NV_geometry_program4", +#endif +#ifdef GL_NV_geometry_shader4 + "GL_NV_geometry_shader4", +#endif +#ifdef GL_NV_geometry_shader_passthrough + "GL_NV_geometry_shader_passthrough", +#endif +#ifdef GL_NV_gpu_multicast + "GL_NV_gpu_multicast", +#endif +#ifdef GL_NV_gpu_program4 + "GL_NV_gpu_program4", +#endif +#ifdef GL_NV_gpu_program5 + "GL_NV_gpu_program5", +#endif +#ifdef GL_NV_gpu_program5_mem_extended + "GL_NV_gpu_program5_mem_extended", +#endif +#ifdef GL_NV_gpu_program_fp64 + "GL_NV_gpu_program_fp64", +#endif +#ifdef GL_NV_gpu_shader5 + "GL_NV_gpu_shader5", +#endif +#ifdef GL_NV_half_float + "GL_NV_half_float", +#endif +#ifdef GL_NV_image_formats + "GL_NV_image_formats", +#endif +#ifdef GL_NV_instanced_arrays + "GL_NV_instanced_arrays", +#endif +#ifdef GL_NV_internalformat_sample_query + "GL_NV_internalformat_sample_query", +#endif +#ifdef GL_NV_light_max_exponent + "GL_NV_light_max_exponent", +#endif +#ifdef GL_NV_multisample_coverage + "GL_NV_multisample_coverage", +#endif +#ifdef GL_NV_multisample_filter_hint + "GL_NV_multisample_filter_hint", +#endif +#ifdef GL_NV_non_square_matrices + "GL_NV_non_square_matrices", +#endif +#ifdef GL_NV_occlusion_query + "GL_NV_occlusion_query", +#endif +#ifdef GL_NV_pack_subimage + "GL_NV_pack_subimage", +#endif +#ifdef GL_NV_packed_depth_stencil + "GL_NV_packed_depth_stencil", +#endif +#ifdef GL_NV_packed_float + "GL_NV_packed_float", +#endif +#ifdef GL_NV_packed_float_linear + "GL_NV_packed_float_linear", +#endif +#ifdef GL_NV_parameter_buffer_object + "GL_NV_parameter_buffer_object", +#endif +#ifdef GL_NV_parameter_buffer_object2 + "GL_NV_parameter_buffer_object2", +#endif +#ifdef GL_NV_path_rendering + "GL_NV_path_rendering", +#endif +#ifdef GL_NV_path_rendering_shared_edge + "GL_NV_path_rendering_shared_edge", +#endif +#ifdef GL_NV_pixel_buffer_object + "GL_NV_pixel_buffer_object", +#endif +#ifdef GL_NV_pixel_data_range + "GL_NV_pixel_data_range", +#endif +#ifdef GL_NV_platform_binary + "GL_NV_platform_binary", +#endif +#ifdef GL_NV_point_sprite + "GL_NV_point_sprite", +#endif +#ifdef GL_NV_polygon_mode + "GL_NV_polygon_mode", +#endif +#ifdef GL_NV_present_video + "GL_NV_present_video", +#endif +#ifdef GL_NV_primitive_restart + "GL_NV_primitive_restart", +#endif +#ifdef GL_NV_read_depth + "GL_NV_read_depth", +#endif +#ifdef GL_NV_read_depth_stencil + "GL_NV_read_depth_stencil", +#endif +#ifdef GL_NV_read_stencil + "GL_NV_read_stencil", +#endif +#ifdef GL_NV_register_combiners + "GL_NV_register_combiners", +#endif +#ifdef GL_NV_register_combiners2 + "GL_NV_register_combiners2", +#endif +#ifdef GL_NV_robustness_video_memory_purge + "GL_NV_robustness_video_memory_purge", +#endif +#ifdef GL_NV_sRGB_formats + "GL_NV_sRGB_formats", +#endif +#ifdef GL_NV_sample_locations + "GL_NV_sample_locations", +#endif +#ifdef GL_NV_sample_mask_override_coverage + "GL_NV_sample_mask_override_coverage", +#endif +#ifdef GL_NV_shader_atomic_counters + "GL_NV_shader_atomic_counters", +#endif +#ifdef GL_NV_shader_atomic_float + "GL_NV_shader_atomic_float", +#endif +#ifdef GL_NV_shader_atomic_float64 + "GL_NV_shader_atomic_float64", +#endif +#ifdef GL_NV_shader_atomic_fp16_vector + "GL_NV_shader_atomic_fp16_vector", +#endif +#ifdef GL_NV_shader_atomic_int64 + "GL_NV_shader_atomic_int64", +#endif +#ifdef GL_NV_shader_buffer_load + "GL_NV_shader_buffer_load", +#endif +#ifdef GL_NV_shader_noperspective_interpolation + "GL_NV_shader_noperspective_interpolation", +#endif +#ifdef GL_NV_shader_storage_buffer_object + "GL_NV_shader_storage_buffer_object", +#endif +#ifdef GL_NV_shader_thread_group + "GL_NV_shader_thread_group", +#endif +#ifdef GL_NV_shader_thread_shuffle + "GL_NV_shader_thread_shuffle", +#endif +#ifdef GL_NV_shadow_samplers_array + "GL_NV_shadow_samplers_array", +#endif +#ifdef GL_NV_shadow_samplers_cube + "GL_NV_shadow_samplers_cube", +#endif +#ifdef GL_NV_stereo_view_rendering + "GL_NV_stereo_view_rendering", +#endif +#ifdef GL_NV_tessellation_program5 + "GL_NV_tessellation_program5", +#endif +#ifdef GL_NV_texgen_emboss + "GL_NV_texgen_emboss", +#endif +#ifdef GL_NV_texgen_reflection + "GL_NV_texgen_reflection", +#endif +#ifdef GL_NV_texture_array + "GL_NV_texture_array", +#endif +#ifdef GL_NV_texture_barrier + "GL_NV_texture_barrier", +#endif +#ifdef GL_NV_texture_border_clamp + "GL_NV_texture_border_clamp", +#endif +#ifdef GL_NV_texture_compression_latc + "GL_NV_texture_compression_latc", +#endif +#ifdef GL_NV_texture_compression_s3tc + "GL_NV_texture_compression_s3tc", +#endif +#ifdef GL_NV_texture_compression_s3tc_update + "GL_NV_texture_compression_s3tc_update", +#endif +#ifdef GL_NV_texture_compression_vtc + "GL_NV_texture_compression_vtc", +#endif +#ifdef GL_NV_texture_env_combine4 + "GL_NV_texture_env_combine4", +#endif +#ifdef GL_NV_texture_expand_normal + "GL_NV_texture_expand_normal", +#endif +#ifdef GL_NV_texture_multisample + "GL_NV_texture_multisample", +#endif +#ifdef GL_NV_texture_npot_2D_mipmap + "GL_NV_texture_npot_2D_mipmap", +#endif +#ifdef GL_NV_texture_rectangle + "GL_NV_texture_rectangle", +#endif +#ifdef GL_NV_texture_rectangle_compressed + "GL_NV_texture_rectangle_compressed", +#endif +#ifdef GL_NV_texture_shader + "GL_NV_texture_shader", +#endif +#ifdef GL_NV_texture_shader2 + "GL_NV_texture_shader2", +#endif +#ifdef GL_NV_texture_shader3 + "GL_NV_texture_shader3", +#endif +#ifdef GL_NV_transform_feedback + "GL_NV_transform_feedback", +#endif +#ifdef GL_NV_transform_feedback2 + "GL_NV_transform_feedback2", +#endif +#ifdef GL_NV_uniform_buffer_unified_memory + "GL_NV_uniform_buffer_unified_memory", +#endif +#ifdef GL_NV_vdpau_interop + "GL_NV_vdpau_interop", +#endif +#ifdef GL_NV_vertex_array_range + "GL_NV_vertex_array_range", +#endif +#ifdef GL_NV_vertex_array_range2 + "GL_NV_vertex_array_range2", +#endif +#ifdef GL_NV_vertex_attrib_integer_64bit + "GL_NV_vertex_attrib_integer_64bit", +#endif +#ifdef GL_NV_vertex_buffer_unified_memory + "GL_NV_vertex_buffer_unified_memory", +#endif +#ifdef GL_NV_vertex_program + "GL_NV_vertex_program", +#endif +#ifdef GL_NV_vertex_program1_1 + "GL_NV_vertex_program1_1", +#endif +#ifdef GL_NV_vertex_program2 + "GL_NV_vertex_program2", +#endif +#ifdef GL_NV_vertex_program2_option + "GL_NV_vertex_program2_option", +#endif +#ifdef GL_NV_vertex_program3 + "GL_NV_vertex_program3", +#endif +#ifdef GL_NV_vertex_program4 + "GL_NV_vertex_program4", +#endif +#ifdef GL_NV_video_capture + "GL_NV_video_capture", +#endif +#ifdef GL_NV_viewport_array + "GL_NV_viewport_array", +#endif +#ifdef GL_NV_viewport_array2 + "GL_NV_viewport_array2", +#endif +#ifdef GL_NV_viewport_swizzle + "GL_NV_viewport_swizzle", +#endif +#ifdef GL_OES_byte_coordinates + "GL_OES_byte_coordinates", +#endif +#ifdef GL_OML_interlace + "GL_OML_interlace", +#endif +#ifdef GL_OML_resample + "GL_OML_resample", +#endif +#ifdef GL_OML_subsample + "GL_OML_subsample", +#endif +#ifdef GL_OVR_multiview + "GL_OVR_multiview", +#endif +#ifdef GL_OVR_multiview2 + "GL_OVR_multiview2", +#endif +#ifdef GL_OVR_multiview_multisampled_render_to_texture + "GL_OVR_multiview_multisampled_render_to_texture", +#endif +#ifdef GL_PGI_misc_hints + "GL_PGI_misc_hints", +#endif +#ifdef GL_PGI_vertex_hints + "GL_PGI_vertex_hints", +#endif +#ifdef GL_QCOM_alpha_test + "GL_QCOM_alpha_test", +#endif +#ifdef GL_QCOM_binning_control + "GL_QCOM_binning_control", +#endif +#ifdef GL_QCOM_driver_control + "GL_QCOM_driver_control", +#endif +#ifdef GL_QCOM_extended_get + "GL_QCOM_extended_get", +#endif +#ifdef GL_QCOM_extended_get2 + "GL_QCOM_extended_get2", +#endif +#ifdef GL_QCOM_framebuffer_foveated + "GL_QCOM_framebuffer_foveated", +#endif +#ifdef GL_QCOM_perfmon_global_mode + "GL_QCOM_perfmon_global_mode", +#endif +#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent + "GL_QCOM_shader_framebuffer_fetch_noncoherent", +#endif +#ifdef GL_QCOM_tiled_rendering + "GL_QCOM_tiled_rendering", +#endif +#ifdef GL_QCOM_writeonly_rendering + "GL_QCOM_writeonly_rendering", +#endif +#ifdef GL_REGAL_ES1_0_compatibility + "GL_REGAL_ES1_0_compatibility", +#endif +#ifdef GL_REGAL_ES1_1_compatibility + "GL_REGAL_ES1_1_compatibility", +#endif +#ifdef GL_REGAL_enable + "GL_REGAL_enable", +#endif +#ifdef GL_REGAL_error_string + "GL_REGAL_error_string", +#endif +#ifdef GL_REGAL_extension_query + "GL_REGAL_extension_query", +#endif +#ifdef GL_REGAL_log + "GL_REGAL_log", +#endif +#ifdef GL_REGAL_proc_address + "GL_REGAL_proc_address", +#endif +#ifdef GL_REND_screen_coordinates + "GL_REND_screen_coordinates", +#endif +#ifdef GL_S3_s3tc + "GL_S3_s3tc", +#endif +#ifdef GL_SGIS_clip_band_hint + "GL_SGIS_clip_band_hint", +#endif +#ifdef GL_SGIS_color_range + "GL_SGIS_color_range", +#endif +#ifdef GL_SGIS_detail_texture + "GL_SGIS_detail_texture", +#endif +#ifdef GL_SGIS_fog_function + "GL_SGIS_fog_function", +#endif +#ifdef GL_SGIS_generate_mipmap + "GL_SGIS_generate_mipmap", +#endif +#ifdef GL_SGIS_line_texgen + "GL_SGIS_line_texgen", +#endif +#ifdef GL_SGIS_multisample + "GL_SGIS_multisample", +#endif +#ifdef GL_SGIS_multitexture + "GL_SGIS_multitexture", +#endif +#ifdef GL_SGIS_pixel_texture + "GL_SGIS_pixel_texture", +#endif +#ifdef GL_SGIS_point_line_texgen + "GL_SGIS_point_line_texgen", +#endif +#ifdef GL_SGIS_shared_multisample + "GL_SGIS_shared_multisample", +#endif +#ifdef GL_SGIS_sharpen_texture + "GL_SGIS_sharpen_texture", +#endif +#ifdef GL_SGIS_texture4D + "GL_SGIS_texture4D", +#endif +#ifdef GL_SGIS_texture_border_clamp + "GL_SGIS_texture_border_clamp", +#endif +#ifdef GL_SGIS_texture_edge_clamp + "GL_SGIS_texture_edge_clamp", +#endif +#ifdef GL_SGIS_texture_filter4 + "GL_SGIS_texture_filter4", +#endif +#ifdef GL_SGIS_texture_lod + "GL_SGIS_texture_lod", +#endif +#ifdef GL_SGIS_texture_select + "GL_SGIS_texture_select", +#endif +#ifdef GL_SGIX_async + "GL_SGIX_async", +#endif +#ifdef GL_SGIX_async_histogram + "GL_SGIX_async_histogram", +#endif +#ifdef GL_SGIX_async_pixel + "GL_SGIX_async_pixel", +#endif +#ifdef GL_SGIX_bali_g_instruments + "GL_SGIX_bali_g_instruments", +#endif +#ifdef GL_SGIX_bali_r_instruments + "GL_SGIX_bali_r_instruments", +#endif +#ifdef GL_SGIX_bali_timer_instruments + "GL_SGIX_bali_timer_instruments", +#endif +#ifdef GL_SGIX_blend_alpha_minmax + "GL_SGIX_blend_alpha_minmax", +#endif +#ifdef GL_SGIX_blend_cadd + "GL_SGIX_blend_cadd", +#endif +#ifdef GL_SGIX_blend_cmultiply + "GL_SGIX_blend_cmultiply", +#endif +#ifdef GL_SGIX_calligraphic_fragment + "GL_SGIX_calligraphic_fragment", +#endif +#ifdef GL_SGIX_clipmap + "GL_SGIX_clipmap", +#endif +#ifdef GL_SGIX_color_matrix_accuracy + "GL_SGIX_color_matrix_accuracy", +#endif +#ifdef GL_SGIX_color_table_index_mode + "GL_SGIX_color_table_index_mode", +#endif +#ifdef GL_SGIX_complex_polar + "GL_SGIX_complex_polar", +#endif +#ifdef GL_SGIX_convolution_accuracy + "GL_SGIX_convolution_accuracy", +#endif +#ifdef GL_SGIX_cube_map + "GL_SGIX_cube_map", +#endif +#ifdef GL_SGIX_cylinder_texgen + "GL_SGIX_cylinder_texgen", +#endif +#ifdef GL_SGIX_datapipe + "GL_SGIX_datapipe", +#endif +#ifdef GL_SGIX_decimation + "GL_SGIX_decimation", +#endif +#ifdef GL_SGIX_depth_pass_instrument + "GL_SGIX_depth_pass_instrument", +#endif +#ifdef GL_SGIX_depth_texture + "GL_SGIX_depth_texture", +#endif +#ifdef GL_SGIX_dvc + "GL_SGIX_dvc", +#endif +#ifdef GL_SGIX_flush_raster + "GL_SGIX_flush_raster", +#endif +#ifdef GL_SGIX_fog_blend + "GL_SGIX_fog_blend", +#endif +#ifdef GL_SGIX_fog_factor_to_alpha + "GL_SGIX_fog_factor_to_alpha", +#endif +#ifdef GL_SGIX_fog_layers + "GL_SGIX_fog_layers", +#endif +#ifdef GL_SGIX_fog_offset + "GL_SGIX_fog_offset", +#endif +#ifdef GL_SGIX_fog_patchy + "GL_SGIX_fog_patchy", +#endif +#ifdef GL_SGIX_fog_scale + "GL_SGIX_fog_scale", +#endif +#ifdef GL_SGIX_fog_texture + "GL_SGIX_fog_texture", +#endif +#ifdef GL_SGIX_fragment_lighting_space + "GL_SGIX_fragment_lighting_space", +#endif +#ifdef GL_SGIX_fragment_specular_lighting + "GL_SGIX_fragment_specular_lighting", +#endif +#ifdef GL_SGIX_fragments_instrument + "GL_SGIX_fragments_instrument", +#endif +#ifdef GL_SGIX_framezoom + "GL_SGIX_framezoom", +#endif +#ifdef GL_SGIX_icc_texture + "GL_SGIX_icc_texture", +#endif +#ifdef GL_SGIX_igloo_interface + "GL_SGIX_igloo_interface", +#endif +#ifdef GL_SGIX_image_compression + "GL_SGIX_image_compression", +#endif +#ifdef GL_SGIX_impact_pixel_texture + "GL_SGIX_impact_pixel_texture", +#endif +#ifdef GL_SGIX_instrument_error + "GL_SGIX_instrument_error", +#endif +#ifdef GL_SGIX_interlace + "GL_SGIX_interlace", +#endif +#ifdef GL_SGIX_ir_instrument1 + "GL_SGIX_ir_instrument1", +#endif +#ifdef GL_SGIX_line_quality_hint + "GL_SGIX_line_quality_hint", +#endif +#ifdef GL_SGIX_list_priority + "GL_SGIX_list_priority", +#endif +#ifdef GL_SGIX_mpeg1 + "GL_SGIX_mpeg1", +#endif +#ifdef GL_SGIX_mpeg2 + "GL_SGIX_mpeg2", +#endif +#ifdef GL_SGIX_nonlinear_lighting_pervertex + "GL_SGIX_nonlinear_lighting_pervertex", +#endif +#ifdef GL_SGIX_nurbs_eval + "GL_SGIX_nurbs_eval", +#endif +#ifdef GL_SGIX_occlusion_instrument + "GL_SGIX_occlusion_instrument", +#endif +#ifdef GL_SGIX_packed_6bytes + "GL_SGIX_packed_6bytes", +#endif +#ifdef GL_SGIX_pixel_texture + "GL_SGIX_pixel_texture", +#endif +#ifdef GL_SGIX_pixel_texture_bits + "GL_SGIX_pixel_texture_bits", +#endif +#ifdef GL_SGIX_pixel_texture_lod + "GL_SGIX_pixel_texture_lod", +#endif +#ifdef GL_SGIX_pixel_tiles + "GL_SGIX_pixel_tiles", +#endif +#ifdef GL_SGIX_polynomial_ffd + "GL_SGIX_polynomial_ffd", +#endif +#ifdef GL_SGIX_quad_mesh + "GL_SGIX_quad_mesh", +#endif +#ifdef GL_SGIX_reference_plane + "GL_SGIX_reference_plane", +#endif +#ifdef GL_SGIX_resample + "GL_SGIX_resample", +#endif +#ifdef GL_SGIX_scalebias_hint + "GL_SGIX_scalebias_hint", +#endif +#ifdef GL_SGIX_shadow + "GL_SGIX_shadow", +#endif +#ifdef GL_SGIX_shadow_ambient + "GL_SGIX_shadow_ambient", +#endif +#ifdef GL_SGIX_slim + "GL_SGIX_slim", +#endif +#ifdef GL_SGIX_spotlight_cutoff + "GL_SGIX_spotlight_cutoff", +#endif +#ifdef GL_SGIX_sprite + "GL_SGIX_sprite", +#endif +#ifdef GL_SGIX_subdiv_patch + "GL_SGIX_subdiv_patch", +#endif +#ifdef GL_SGIX_subsample + "GL_SGIX_subsample", +#endif +#ifdef GL_SGIX_tag_sample_buffer + "GL_SGIX_tag_sample_buffer", +#endif +#ifdef GL_SGIX_texture_add_env + "GL_SGIX_texture_add_env", +#endif +#ifdef GL_SGIX_texture_coordinate_clamp + "GL_SGIX_texture_coordinate_clamp", +#endif +#ifdef GL_SGIX_texture_lod_bias + "GL_SGIX_texture_lod_bias", +#endif +#ifdef GL_SGIX_texture_mipmap_anisotropic + "GL_SGIX_texture_mipmap_anisotropic", +#endif +#ifdef GL_SGIX_texture_multi_buffer + "GL_SGIX_texture_multi_buffer", +#endif +#ifdef GL_SGIX_texture_phase + "GL_SGIX_texture_phase", +#endif +#ifdef GL_SGIX_texture_range + "GL_SGIX_texture_range", +#endif +#ifdef GL_SGIX_texture_scale_bias + "GL_SGIX_texture_scale_bias", +#endif +#ifdef GL_SGIX_texture_supersample + "GL_SGIX_texture_supersample", +#endif +#ifdef GL_SGIX_vector_ops + "GL_SGIX_vector_ops", +#endif +#ifdef GL_SGIX_vertex_array_object + "GL_SGIX_vertex_array_object", +#endif +#ifdef GL_SGIX_vertex_preclip + "GL_SGIX_vertex_preclip", +#endif +#ifdef GL_SGIX_vertex_preclip_hint + "GL_SGIX_vertex_preclip_hint", +#endif +#ifdef GL_SGIX_ycrcb + "GL_SGIX_ycrcb", +#endif +#ifdef GL_SGIX_ycrcb_subsample + "GL_SGIX_ycrcb_subsample", +#endif +#ifdef GL_SGIX_ycrcba + "GL_SGIX_ycrcba", +#endif +#ifdef GL_SGI_color_matrix + "GL_SGI_color_matrix", +#endif +#ifdef GL_SGI_color_table + "GL_SGI_color_table", +#endif +#ifdef GL_SGI_complex + "GL_SGI_complex", +#endif +#ifdef GL_SGI_complex_type + "GL_SGI_complex_type", +#endif +#ifdef GL_SGI_fft + "GL_SGI_fft", +#endif +#ifdef GL_SGI_texture_color_table + "GL_SGI_texture_color_table", +#endif +#ifdef GL_SUNX_constant_data + "GL_SUNX_constant_data", +#endif +#ifdef GL_SUN_convolution_border_modes + "GL_SUN_convolution_border_modes", +#endif +#ifdef GL_SUN_global_alpha + "GL_SUN_global_alpha", +#endif +#ifdef GL_SUN_mesh_array + "GL_SUN_mesh_array", +#endif +#ifdef GL_SUN_read_video_pixels + "GL_SUN_read_video_pixels", +#endif +#ifdef GL_SUN_slice_accum + "GL_SUN_slice_accum", +#endif +#ifdef GL_SUN_triangle_list + "GL_SUN_triangle_list", +#endif +#ifdef GL_SUN_vertex + "GL_SUN_vertex", +#endif +#ifdef GL_WIN_phong_shading + "GL_WIN_phong_shading", +#endif +#ifdef GL_WIN_scene_markerXXX + "GL_WIN_scene_markerXXX", +#endif +#ifdef GL_WIN_specular_fog + "GL_WIN_specular_fog", +#endif +#ifdef GL_WIN_swap_hint + "GL_WIN_swap_hint", +#endif + NULL +}; + +/* Detected in the extension string or strings */ +static GLboolean _glewExtensionString[801]; +/* Detected via extension string or experimental mode */ +static GLboolean* _glewExtensionEnabled[] = { +#ifdef GL_VERSION_1_2 + &__GLEW_VERSION_1_2, +#endif +#ifdef GL_VERSION_1_2_1 + &__GLEW_VERSION_1_2_1, +#endif +#ifdef GL_VERSION_1_3 + &__GLEW_VERSION_1_3, +#endif +#ifdef GL_VERSION_1_4 + &__GLEW_VERSION_1_4, +#endif +#ifdef GL_VERSION_1_5 + &__GLEW_VERSION_1_5, +#endif +#ifdef GL_VERSION_2_0 + &__GLEW_VERSION_2_0, +#endif +#ifdef GL_VERSION_2_1 + &__GLEW_VERSION_2_1, +#endif +#ifdef GL_VERSION_3_0 + &__GLEW_VERSION_3_0, +#endif +#ifdef GL_VERSION_3_1 + &__GLEW_VERSION_3_1, +#endif +#ifdef GL_VERSION_3_2 + &__GLEW_VERSION_3_2, +#endif +#ifdef GL_VERSION_3_3 + &__GLEW_VERSION_3_3, +#endif +#ifdef GL_VERSION_4_0 + &__GLEW_VERSION_4_0, +#endif +#ifdef GL_VERSION_4_1 + &__GLEW_VERSION_4_1, +#endif +#ifdef GL_VERSION_4_2 + &__GLEW_VERSION_4_2, +#endif +#ifdef GL_VERSION_4_3 + &__GLEW_VERSION_4_3, +#endif +#ifdef GL_VERSION_4_4 + &__GLEW_VERSION_4_4, +#endif +#ifdef GL_VERSION_4_5 + &__GLEW_VERSION_4_5, +#endif +#ifdef GL_VERSION_4_6 + &__GLEW_VERSION_4_6, +#endif +#ifdef GL_3DFX_multisample + &__GLEW_3DFX_multisample, +#endif +#ifdef GL_3DFX_tbuffer + &__GLEW_3DFX_tbuffer, +#endif +#ifdef GL_3DFX_texture_compression_FXT1 + &__GLEW_3DFX_texture_compression_FXT1, +#endif +#ifdef GL_AMD_blend_minmax_factor + &__GLEW_AMD_blend_minmax_factor, +#endif +#ifdef GL_AMD_compressed_3DC_texture + &__GLEW_AMD_compressed_3DC_texture, +#endif +#ifdef GL_AMD_compressed_ATC_texture + &__GLEW_AMD_compressed_ATC_texture, +#endif +#ifdef GL_AMD_conservative_depth + &__GLEW_AMD_conservative_depth, +#endif +#ifdef GL_AMD_debug_output + &__GLEW_AMD_debug_output, +#endif +#ifdef GL_AMD_depth_clamp_separate + &__GLEW_AMD_depth_clamp_separate, +#endif +#ifdef GL_AMD_draw_buffers_blend + &__GLEW_AMD_draw_buffers_blend, +#endif +#ifdef GL_AMD_framebuffer_sample_positions + &__GLEW_AMD_framebuffer_sample_positions, +#endif +#ifdef GL_AMD_gcn_shader + &__GLEW_AMD_gcn_shader, +#endif +#ifdef GL_AMD_gpu_shader_half_float + &__GLEW_AMD_gpu_shader_half_float, +#endif +#ifdef GL_AMD_gpu_shader_int16 + &__GLEW_AMD_gpu_shader_int16, +#endif +#ifdef GL_AMD_gpu_shader_int64 + &__GLEW_AMD_gpu_shader_int64, +#endif +#ifdef GL_AMD_interleaved_elements + &__GLEW_AMD_interleaved_elements, +#endif +#ifdef GL_AMD_multi_draw_indirect + &__GLEW_AMD_multi_draw_indirect, +#endif +#ifdef GL_AMD_name_gen_delete + &__GLEW_AMD_name_gen_delete, +#endif +#ifdef GL_AMD_occlusion_query_event + &__GLEW_AMD_occlusion_query_event, +#endif +#ifdef GL_AMD_performance_monitor + &__GLEW_AMD_performance_monitor, +#endif +#ifdef GL_AMD_pinned_memory + &__GLEW_AMD_pinned_memory, +#endif +#ifdef GL_AMD_program_binary_Z400 + &__GLEW_AMD_program_binary_Z400, +#endif +#ifdef GL_AMD_query_buffer_object + &__GLEW_AMD_query_buffer_object, +#endif +#ifdef GL_AMD_sample_positions + &__GLEW_AMD_sample_positions, +#endif +#ifdef GL_AMD_seamless_cubemap_per_texture + &__GLEW_AMD_seamless_cubemap_per_texture, +#endif +#ifdef GL_AMD_shader_atomic_counter_ops + &__GLEW_AMD_shader_atomic_counter_ops, +#endif +#ifdef GL_AMD_shader_ballot + &__GLEW_AMD_shader_ballot, +#endif +#ifdef GL_AMD_shader_explicit_vertex_parameter + &__GLEW_AMD_shader_explicit_vertex_parameter, +#endif +#ifdef GL_AMD_shader_stencil_export + &__GLEW_AMD_shader_stencil_export, +#endif +#ifdef GL_AMD_shader_stencil_value_export + &__GLEW_AMD_shader_stencil_value_export, +#endif +#ifdef GL_AMD_shader_trinary_minmax + &__GLEW_AMD_shader_trinary_minmax, +#endif +#ifdef GL_AMD_sparse_texture + &__GLEW_AMD_sparse_texture, +#endif +#ifdef GL_AMD_stencil_operation_extended + &__GLEW_AMD_stencil_operation_extended, +#endif +#ifdef GL_AMD_texture_gather_bias_lod + &__GLEW_AMD_texture_gather_bias_lod, +#endif +#ifdef GL_AMD_texture_texture4 + &__GLEW_AMD_texture_texture4, +#endif +#ifdef GL_AMD_transform_feedback3_lines_triangles + &__GLEW_AMD_transform_feedback3_lines_triangles, +#endif +#ifdef GL_AMD_transform_feedback4 + &__GLEW_AMD_transform_feedback4, +#endif +#ifdef GL_AMD_vertex_shader_layer + &__GLEW_AMD_vertex_shader_layer, +#endif +#ifdef GL_AMD_vertex_shader_tessellator + &__GLEW_AMD_vertex_shader_tessellator, +#endif +#ifdef GL_AMD_vertex_shader_viewport_index + &__GLEW_AMD_vertex_shader_viewport_index, +#endif +#ifdef GL_ANDROID_extension_pack_es31a + &__GLEW_ANDROID_extension_pack_es31a, +#endif +#ifdef GL_ANGLE_depth_texture + &__GLEW_ANGLE_depth_texture, +#endif +#ifdef GL_ANGLE_framebuffer_blit + &__GLEW_ANGLE_framebuffer_blit, +#endif +#ifdef GL_ANGLE_framebuffer_multisample + &__GLEW_ANGLE_framebuffer_multisample, +#endif +#ifdef GL_ANGLE_instanced_arrays + &__GLEW_ANGLE_instanced_arrays, +#endif +#ifdef GL_ANGLE_pack_reverse_row_order + &__GLEW_ANGLE_pack_reverse_row_order, +#endif +#ifdef GL_ANGLE_program_binary + &__GLEW_ANGLE_program_binary, +#endif +#ifdef GL_ANGLE_texture_compression_dxt1 + &__GLEW_ANGLE_texture_compression_dxt1, +#endif +#ifdef GL_ANGLE_texture_compression_dxt3 + &__GLEW_ANGLE_texture_compression_dxt3, +#endif +#ifdef GL_ANGLE_texture_compression_dxt5 + &__GLEW_ANGLE_texture_compression_dxt5, +#endif +#ifdef GL_ANGLE_texture_usage + &__GLEW_ANGLE_texture_usage, +#endif +#ifdef GL_ANGLE_timer_query + &__GLEW_ANGLE_timer_query, +#endif +#ifdef GL_ANGLE_translated_shader_source + &__GLEW_ANGLE_translated_shader_source, +#endif +#ifdef GL_APPLE_aux_depth_stencil + &__GLEW_APPLE_aux_depth_stencil, +#endif +#ifdef GL_APPLE_client_storage + &__GLEW_APPLE_client_storage, +#endif +#ifdef GL_APPLE_clip_distance + &__GLEW_APPLE_clip_distance, +#endif +#ifdef GL_APPLE_color_buffer_packed_float + &__GLEW_APPLE_color_buffer_packed_float, +#endif +#ifdef GL_APPLE_copy_texture_levels + &__GLEW_APPLE_copy_texture_levels, +#endif +#ifdef GL_APPLE_element_array + &__GLEW_APPLE_element_array, +#endif +#ifdef GL_APPLE_fence + &__GLEW_APPLE_fence, +#endif +#ifdef GL_APPLE_float_pixels + &__GLEW_APPLE_float_pixels, +#endif +#ifdef GL_APPLE_flush_buffer_range + &__GLEW_APPLE_flush_buffer_range, +#endif +#ifdef GL_APPLE_framebuffer_multisample + &__GLEW_APPLE_framebuffer_multisample, +#endif +#ifdef GL_APPLE_object_purgeable + &__GLEW_APPLE_object_purgeable, +#endif +#ifdef GL_APPLE_pixel_buffer + &__GLEW_APPLE_pixel_buffer, +#endif +#ifdef GL_APPLE_rgb_422 + &__GLEW_APPLE_rgb_422, +#endif +#ifdef GL_APPLE_row_bytes + &__GLEW_APPLE_row_bytes, +#endif +#ifdef GL_APPLE_specular_vector + &__GLEW_APPLE_specular_vector, +#endif +#ifdef GL_APPLE_sync + &__GLEW_APPLE_sync, +#endif +#ifdef GL_APPLE_texture_2D_limited_npot + &__GLEW_APPLE_texture_2D_limited_npot, +#endif +#ifdef GL_APPLE_texture_format_BGRA8888 + &__GLEW_APPLE_texture_format_BGRA8888, +#endif +#ifdef GL_APPLE_texture_max_level + &__GLEW_APPLE_texture_max_level, +#endif +#ifdef GL_APPLE_texture_packed_float + &__GLEW_APPLE_texture_packed_float, +#endif +#ifdef GL_APPLE_texture_range + &__GLEW_APPLE_texture_range, +#endif +#ifdef GL_APPLE_transform_hint + &__GLEW_APPLE_transform_hint, +#endif +#ifdef GL_APPLE_vertex_array_object + &__GLEW_APPLE_vertex_array_object, +#endif +#ifdef GL_APPLE_vertex_array_range + &__GLEW_APPLE_vertex_array_range, +#endif +#ifdef GL_APPLE_vertex_program_evaluators + &__GLEW_APPLE_vertex_program_evaluators, +#endif +#ifdef GL_APPLE_ycbcr_422 + &__GLEW_APPLE_ycbcr_422, +#endif +#ifdef GL_ARB_ES2_compatibility + &__GLEW_ARB_ES2_compatibility, +#endif +#ifdef GL_ARB_ES3_1_compatibility + &__GLEW_ARB_ES3_1_compatibility, +#endif +#ifdef GL_ARB_ES3_2_compatibility + &__GLEW_ARB_ES3_2_compatibility, +#endif +#ifdef GL_ARB_ES3_compatibility + &__GLEW_ARB_ES3_compatibility, +#endif +#ifdef GL_ARB_arrays_of_arrays + &__GLEW_ARB_arrays_of_arrays, +#endif +#ifdef GL_ARB_base_instance + &__GLEW_ARB_base_instance, +#endif +#ifdef GL_ARB_bindless_texture + &__GLEW_ARB_bindless_texture, +#endif +#ifdef GL_ARB_blend_func_extended + &__GLEW_ARB_blend_func_extended, +#endif +#ifdef GL_ARB_buffer_storage + &__GLEW_ARB_buffer_storage, +#endif +#ifdef GL_ARB_cl_event + &__GLEW_ARB_cl_event, +#endif +#ifdef GL_ARB_clear_buffer_object + &__GLEW_ARB_clear_buffer_object, +#endif +#ifdef GL_ARB_clear_texture + &__GLEW_ARB_clear_texture, +#endif +#ifdef GL_ARB_clip_control + &__GLEW_ARB_clip_control, +#endif +#ifdef GL_ARB_color_buffer_float + &__GLEW_ARB_color_buffer_float, +#endif +#ifdef GL_ARB_compatibility + &__GLEW_ARB_compatibility, +#endif +#ifdef GL_ARB_compressed_texture_pixel_storage + &__GLEW_ARB_compressed_texture_pixel_storage, +#endif +#ifdef GL_ARB_compute_shader + &__GLEW_ARB_compute_shader, +#endif +#ifdef GL_ARB_compute_variable_group_size + &__GLEW_ARB_compute_variable_group_size, +#endif +#ifdef GL_ARB_conditional_render_inverted + &__GLEW_ARB_conditional_render_inverted, +#endif +#ifdef GL_ARB_conservative_depth + &__GLEW_ARB_conservative_depth, +#endif +#ifdef GL_ARB_copy_buffer + &__GLEW_ARB_copy_buffer, +#endif +#ifdef GL_ARB_copy_image + &__GLEW_ARB_copy_image, +#endif +#ifdef GL_ARB_cull_distance + &__GLEW_ARB_cull_distance, +#endif +#ifdef GL_ARB_debug_output + &__GLEW_ARB_debug_output, +#endif +#ifdef GL_ARB_depth_buffer_float + &__GLEW_ARB_depth_buffer_float, +#endif +#ifdef GL_ARB_depth_clamp + &__GLEW_ARB_depth_clamp, +#endif +#ifdef GL_ARB_depth_texture + &__GLEW_ARB_depth_texture, +#endif +#ifdef GL_ARB_derivative_control + &__GLEW_ARB_derivative_control, +#endif +#ifdef GL_ARB_direct_state_access + &__GLEW_ARB_direct_state_access, +#endif +#ifdef GL_ARB_draw_buffers + &__GLEW_ARB_draw_buffers, +#endif +#ifdef GL_ARB_draw_buffers_blend + &__GLEW_ARB_draw_buffers_blend, +#endif +#ifdef GL_ARB_draw_elements_base_vertex + &__GLEW_ARB_draw_elements_base_vertex, +#endif +#ifdef GL_ARB_draw_indirect + &__GLEW_ARB_draw_indirect, +#endif +#ifdef GL_ARB_draw_instanced + &__GLEW_ARB_draw_instanced, +#endif +#ifdef GL_ARB_enhanced_layouts + &__GLEW_ARB_enhanced_layouts, +#endif +#ifdef GL_ARB_explicit_attrib_location + &__GLEW_ARB_explicit_attrib_location, +#endif +#ifdef GL_ARB_explicit_uniform_location + &__GLEW_ARB_explicit_uniform_location, +#endif +#ifdef GL_ARB_fragment_coord_conventions + &__GLEW_ARB_fragment_coord_conventions, +#endif +#ifdef GL_ARB_fragment_layer_viewport + &__GLEW_ARB_fragment_layer_viewport, +#endif +#ifdef GL_ARB_fragment_program + &__GLEW_ARB_fragment_program, +#endif +#ifdef GL_ARB_fragment_program_shadow + &__GLEW_ARB_fragment_program_shadow, +#endif +#ifdef GL_ARB_fragment_shader + &__GLEW_ARB_fragment_shader, +#endif +#ifdef GL_ARB_fragment_shader_interlock + &__GLEW_ARB_fragment_shader_interlock, +#endif +#ifdef GL_ARB_framebuffer_no_attachments + &__GLEW_ARB_framebuffer_no_attachments, +#endif +#ifdef GL_ARB_framebuffer_object + &__GLEW_ARB_framebuffer_object, +#endif +#ifdef GL_ARB_framebuffer_sRGB + &__GLEW_ARB_framebuffer_sRGB, +#endif +#ifdef GL_ARB_geometry_shader4 + &__GLEW_ARB_geometry_shader4, +#endif +#ifdef GL_ARB_get_program_binary + &__GLEW_ARB_get_program_binary, +#endif +#ifdef GL_ARB_get_texture_sub_image + &__GLEW_ARB_get_texture_sub_image, +#endif +#ifdef GL_ARB_gl_spirv + &__GLEW_ARB_gl_spirv, +#endif +#ifdef GL_ARB_gpu_shader5 + &__GLEW_ARB_gpu_shader5, +#endif +#ifdef GL_ARB_gpu_shader_fp64 + &__GLEW_ARB_gpu_shader_fp64, +#endif +#ifdef GL_ARB_gpu_shader_int64 + &__GLEW_ARB_gpu_shader_int64, +#endif +#ifdef GL_ARB_half_float_pixel + &__GLEW_ARB_half_float_pixel, +#endif +#ifdef GL_ARB_half_float_vertex + &__GLEW_ARB_half_float_vertex, +#endif +#ifdef GL_ARB_imaging + &__GLEW_ARB_imaging, +#endif +#ifdef GL_ARB_indirect_parameters + &__GLEW_ARB_indirect_parameters, +#endif +#ifdef GL_ARB_instanced_arrays + &__GLEW_ARB_instanced_arrays, +#endif +#ifdef GL_ARB_internalformat_query + &__GLEW_ARB_internalformat_query, +#endif +#ifdef GL_ARB_internalformat_query2 + &__GLEW_ARB_internalformat_query2, +#endif +#ifdef GL_ARB_invalidate_subdata + &__GLEW_ARB_invalidate_subdata, +#endif +#ifdef GL_ARB_map_buffer_alignment + &__GLEW_ARB_map_buffer_alignment, +#endif +#ifdef GL_ARB_map_buffer_range + &__GLEW_ARB_map_buffer_range, +#endif +#ifdef GL_ARB_matrix_palette + &__GLEW_ARB_matrix_palette, +#endif +#ifdef GL_ARB_multi_bind + &__GLEW_ARB_multi_bind, +#endif +#ifdef GL_ARB_multi_draw_indirect + &__GLEW_ARB_multi_draw_indirect, +#endif +#ifdef GL_ARB_multisample + &__GLEW_ARB_multisample, +#endif +#ifdef GL_ARB_multitexture + &__GLEW_ARB_multitexture, +#endif +#ifdef GL_ARB_occlusion_query + &__GLEW_ARB_occlusion_query, +#endif +#ifdef GL_ARB_occlusion_query2 + &__GLEW_ARB_occlusion_query2, +#endif +#ifdef GL_ARB_parallel_shader_compile + &__GLEW_ARB_parallel_shader_compile, +#endif +#ifdef GL_ARB_pipeline_statistics_query + &__GLEW_ARB_pipeline_statistics_query, +#endif +#ifdef GL_ARB_pixel_buffer_object + &__GLEW_ARB_pixel_buffer_object, +#endif +#ifdef GL_ARB_point_parameters + &__GLEW_ARB_point_parameters, +#endif +#ifdef GL_ARB_point_sprite + &__GLEW_ARB_point_sprite, +#endif +#ifdef GL_ARB_polygon_offset_clamp + &__GLEW_ARB_polygon_offset_clamp, +#endif +#ifdef GL_ARB_post_depth_coverage + &__GLEW_ARB_post_depth_coverage, +#endif +#ifdef GL_ARB_program_interface_query + &__GLEW_ARB_program_interface_query, +#endif +#ifdef GL_ARB_provoking_vertex + &__GLEW_ARB_provoking_vertex, +#endif +#ifdef GL_ARB_query_buffer_object + &__GLEW_ARB_query_buffer_object, +#endif +#ifdef GL_ARB_robust_buffer_access_behavior + &__GLEW_ARB_robust_buffer_access_behavior, +#endif +#ifdef GL_ARB_robustness + &__GLEW_ARB_robustness, +#endif +#ifdef GL_ARB_robustness_application_isolation + &__GLEW_ARB_robustness_application_isolation, +#endif +#ifdef GL_ARB_robustness_share_group_isolation + &__GLEW_ARB_robustness_share_group_isolation, +#endif +#ifdef GL_ARB_sample_locations + &__GLEW_ARB_sample_locations, +#endif +#ifdef GL_ARB_sample_shading + &__GLEW_ARB_sample_shading, +#endif +#ifdef GL_ARB_sampler_objects + &__GLEW_ARB_sampler_objects, +#endif +#ifdef GL_ARB_seamless_cube_map + &__GLEW_ARB_seamless_cube_map, +#endif +#ifdef GL_ARB_seamless_cubemap_per_texture + &__GLEW_ARB_seamless_cubemap_per_texture, +#endif +#ifdef GL_ARB_separate_shader_objects + &__GLEW_ARB_separate_shader_objects, +#endif +#ifdef GL_ARB_shader_atomic_counter_ops + &__GLEW_ARB_shader_atomic_counter_ops, +#endif +#ifdef GL_ARB_shader_atomic_counters + &__GLEW_ARB_shader_atomic_counters, +#endif +#ifdef GL_ARB_shader_ballot + &__GLEW_ARB_shader_ballot, +#endif +#ifdef GL_ARB_shader_bit_encoding + &__GLEW_ARB_shader_bit_encoding, +#endif +#ifdef GL_ARB_shader_clock + &__GLEW_ARB_shader_clock, +#endif +#ifdef GL_ARB_shader_draw_parameters + &__GLEW_ARB_shader_draw_parameters, +#endif +#ifdef GL_ARB_shader_group_vote + &__GLEW_ARB_shader_group_vote, +#endif +#ifdef GL_ARB_shader_image_load_store + &__GLEW_ARB_shader_image_load_store, +#endif +#ifdef GL_ARB_shader_image_size + &__GLEW_ARB_shader_image_size, +#endif +#ifdef GL_ARB_shader_objects + &__GLEW_ARB_shader_objects, +#endif +#ifdef GL_ARB_shader_precision + &__GLEW_ARB_shader_precision, +#endif +#ifdef GL_ARB_shader_stencil_export + &__GLEW_ARB_shader_stencil_export, +#endif +#ifdef GL_ARB_shader_storage_buffer_object + &__GLEW_ARB_shader_storage_buffer_object, +#endif +#ifdef GL_ARB_shader_subroutine + &__GLEW_ARB_shader_subroutine, +#endif +#ifdef GL_ARB_shader_texture_image_samples + &__GLEW_ARB_shader_texture_image_samples, +#endif +#ifdef GL_ARB_shader_texture_lod + &__GLEW_ARB_shader_texture_lod, +#endif +#ifdef GL_ARB_shader_viewport_layer_array + &__GLEW_ARB_shader_viewport_layer_array, +#endif +#ifdef GL_ARB_shading_language_100 + &__GLEW_ARB_shading_language_100, +#endif +#ifdef GL_ARB_shading_language_420pack + &__GLEW_ARB_shading_language_420pack, +#endif +#ifdef GL_ARB_shading_language_include + &__GLEW_ARB_shading_language_include, +#endif +#ifdef GL_ARB_shading_language_packing + &__GLEW_ARB_shading_language_packing, +#endif +#ifdef GL_ARB_shadow + &__GLEW_ARB_shadow, +#endif +#ifdef GL_ARB_shadow_ambient + &__GLEW_ARB_shadow_ambient, +#endif +#ifdef GL_ARB_sparse_buffer + &__GLEW_ARB_sparse_buffer, +#endif +#ifdef GL_ARB_sparse_texture + &__GLEW_ARB_sparse_texture, +#endif +#ifdef GL_ARB_sparse_texture2 + &__GLEW_ARB_sparse_texture2, +#endif +#ifdef GL_ARB_sparse_texture_clamp + &__GLEW_ARB_sparse_texture_clamp, +#endif +#ifdef GL_ARB_spirv_extensions + &__GLEW_ARB_spirv_extensions, +#endif +#ifdef GL_ARB_stencil_texturing + &__GLEW_ARB_stencil_texturing, +#endif +#ifdef GL_ARB_sync + &__GLEW_ARB_sync, +#endif +#ifdef GL_ARB_tessellation_shader + &__GLEW_ARB_tessellation_shader, +#endif +#ifdef GL_ARB_texture_barrier + &__GLEW_ARB_texture_barrier, +#endif +#ifdef GL_ARB_texture_border_clamp + &__GLEW_ARB_texture_border_clamp, +#endif +#ifdef GL_ARB_texture_buffer_object + &__GLEW_ARB_texture_buffer_object, +#endif +#ifdef GL_ARB_texture_buffer_object_rgb32 + &__GLEW_ARB_texture_buffer_object_rgb32, +#endif +#ifdef GL_ARB_texture_buffer_range + &__GLEW_ARB_texture_buffer_range, +#endif +#ifdef GL_ARB_texture_compression + &__GLEW_ARB_texture_compression, +#endif +#ifdef GL_ARB_texture_compression_bptc + &__GLEW_ARB_texture_compression_bptc, +#endif +#ifdef GL_ARB_texture_compression_rgtc + &__GLEW_ARB_texture_compression_rgtc, +#endif +#ifdef GL_ARB_texture_cube_map + &__GLEW_ARB_texture_cube_map, +#endif +#ifdef GL_ARB_texture_cube_map_array + &__GLEW_ARB_texture_cube_map_array, +#endif +#ifdef GL_ARB_texture_env_add + &__GLEW_ARB_texture_env_add, +#endif +#ifdef GL_ARB_texture_env_combine + &__GLEW_ARB_texture_env_combine, +#endif +#ifdef GL_ARB_texture_env_crossbar + &__GLEW_ARB_texture_env_crossbar, +#endif +#ifdef GL_ARB_texture_env_dot3 + &__GLEW_ARB_texture_env_dot3, +#endif +#ifdef GL_ARB_texture_filter_anisotropic + &__GLEW_ARB_texture_filter_anisotropic, +#endif +#ifdef GL_ARB_texture_filter_minmax + &__GLEW_ARB_texture_filter_minmax, +#endif +#ifdef GL_ARB_texture_float + &__GLEW_ARB_texture_float, +#endif +#ifdef GL_ARB_texture_gather + &__GLEW_ARB_texture_gather, +#endif +#ifdef GL_ARB_texture_mirror_clamp_to_edge + &__GLEW_ARB_texture_mirror_clamp_to_edge, +#endif +#ifdef GL_ARB_texture_mirrored_repeat + &__GLEW_ARB_texture_mirrored_repeat, +#endif +#ifdef GL_ARB_texture_multisample + &__GLEW_ARB_texture_multisample, +#endif +#ifdef GL_ARB_texture_non_power_of_two + &__GLEW_ARB_texture_non_power_of_two, +#endif +#ifdef GL_ARB_texture_query_levels + &__GLEW_ARB_texture_query_levels, +#endif +#ifdef GL_ARB_texture_query_lod + &__GLEW_ARB_texture_query_lod, +#endif +#ifdef GL_ARB_texture_rectangle + &__GLEW_ARB_texture_rectangle, +#endif +#ifdef GL_ARB_texture_rg + &__GLEW_ARB_texture_rg, +#endif +#ifdef GL_ARB_texture_rgb10_a2ui + &__GLEW_ARB_texture_rgb10_a2ui, +#endif +#ifdef GL_ARB_texture_stencil8 + &__GLEW_ARB_texture_stencil8, +#endif +#ifdef GL_ARB_texture_storage + &__GLEW_ARB_texture_storage, +#endif +#ifdef GL_ARB_texture_storage_multisample + &__GLEW_ARB_texture_storage_multisample, +#endif +#ifdef GL_ARB_texture_swizzle + &__GLEW_ARB_texture_swizzle, +#endif +#ifdef GL_ARB_texture_view + &__GLEW_ARB_texture_view, +#endif +#ifdef GL_ARB_timer_query + &__GLEW_ARB_timer_query, +#endif +#ifdef GL_ARB_transform_feedback2 + &__GLEW_ARB_transform_feedback2, +#endif +#ifdef GL_ARB_transform_feedback3 + &__GLEW_ARB_transform_feedback3, +#endif +#ifdef GL_ARB_transform_feedback_instanced + &__GLEW_ARB_transform_feedback_instanced, +#endif +#ifdef GL_ARB_transform_feedback_overflow_query + &__GLEW_ARB_transform_feedback_overflow_query, +#endif +#ifdef GL_ARB_transpose_matrix + &__GLEW_ARB_transpose_matrix, +#endif +#ifdef GL_ARB_uniform_buffer_object + &__GLEW_ARB_uniform_buffer_object, +#endif +#ifdef GL_ARB_vertex_array_bgra + &__GLEW_ARB_vertex_array_bgra, +#endif +#ifdef GL_ARB_vertex_array_object + &__GLEW_ARB_vertex_array_object, +#endif +#ifdef GL_ARB_vertex_attrib_64bit + &__GLEW_ARB_vertex_attrib_64bit, +#endif +#ifdef GL_ARB_vertex_attrib_binding + &__GLEW_ARB_vertex_attrib_binding, +#endif +#ifdef GL_ARB_vertex_blend + &__GLEW_ARB_vertex_blend, +#endif +#ifdef GL_ARB_vertex_buffer_object + &__GLEW_ARB_vertex_buffer_object, +#endif +#ifdef GL_ARB_vertex_program + &__GLEW_ARB_vertex_program, +#endif +#ifdef GL_ARB_vertex_shader + &__GLEW_ARB_vertex_shader, +#endif +#ifdef GL_ARB_vertex_type_10f_11f_11f_rev + &__GLEW_ARB_vertex_type_10f_11f_11f_rev, +#endif +#ifdef GL_ARB_vertex_type_2_10_10_10_rev + &__GLEW_ARB_vertex_type_2_10_10_10_rev, +#endif +#ifdef GL_ARB_viewport_array + &__GLEW_ARB_viewport_array, +#endif +#ifdef GL_ARB_window_pos + &__GLEW_ARB_window_pos, +#endif +#ifdef GL_ARM_mali_program_binary + &__GLEW_ARM_mali_program_binary, +#endif +#ifdef GL_ARM_mali_shader_binary + &__GLEW_ARM_mali_shader_binary, +#endif +#ifdef GL_ARM_rgba8 + &__GLEW_ARM_rgba8, +#endif +#ifdef GL_ARM_shader_framebuffer_fetch + &__GLEW_ARM_shader_framebuffer_fetch, +#endif +#ifdef GL_ARM_shader_framebuffer_fetch_depth_stencil + &__GLEW_ARM_shader_framebuffer_fetch_depth_stencil, +#endif +#ifdef GL_ATIX_point_sprites + &__GLEW_ATIX_point_sprites, +#endif +#ifdef GL_ATIX_texture_env_combine3 + &__GLEW_ATIX_texture_env_combine3, +#endif +#ifdef GL_ATIX_texture_env_route + &__GLEW_ATIX_texture_env_route, +#endif +#ifdef GL_ATIX_vertex_shader_output_point_size + &__GLEW_ATIX_vertex_shader_output_point_size, +#endif +#ifdef GL_ATI_draw_buffers + &__GLEW_ATI_draw_buffers, +#endif +#ifdef GL_ATI_element_array + &__GLEW_ATI_element_array, +#endif +#ifdef GL_ATI_envmap_bumpmap + &__GLEW_ATI_envmap_bumpmap, +#endif +#ifdef GL_ATI_fragment_shader + &__GLEW_ATI_fragment_shader, +#endif +#ifdef GL_ATI_map_object_buffer + &__GLEW_ATI_map_object_buffer, +#endif +#ifdef GL_ATI_meminfo + &__GLEW_ATI_meminfo, +#endif +#ifdef GL_ATI_pn_triangles + &__GLEW_ATI_pn_triangles, +#endif +#ifdef GL_ATI_separate_stencil + &__GLEW_ATI_separate_stencil, +#endif +#ifdef GL_ATI_shader_texture_lod + &__GLEW_ATI_shader_texture_lod, +#endif +#ifdef GL_ATI_text_fragment_shader + &__GLEW_ATI_text_fragment_shader, +#endif +#ifdef GL_ATI_texture_compression_3dc + &__GLEW_ATI_texture_compression_3dc, +#endif +#ifdef GL_ATI_texture_env_combine3 + &__GLEW_ATI_texture_env_combine3, +#endif +#ifdef GL_ATI_texture_float + &__GLEW_ATI_texture_float, +#endif +#ifdef GL_ATI_texture_mirror_once + &__GLEW_ATI_texture_mirror_once, +#endif +#ifdef GL_ATI_vertex_array_object + &__GLEW_ATI_vertex_array_object, +#endif +#ifdef GL_ATI_vertex_attrib_array_object + &__GLEW_ATI_vertex_attrib_array_object, +#endif +#ifdef GL_ATI_vertex_streams + &__GLEW_ATI_vertex_streams, +#endif +#ifdef GL_EGL_KHR_context_flush_control + &__GLEW_EGL_KHR_context_flush_control, +#endif +#ifdef GL_EGL_NV_robustness_video_memory_purge + &__GLEW_EGL_NV_robustness_video_memory_purge, +#endif +#ifdef GL_EXT_422_pixels + &__GLEW_EXT_422_pixels, +#endif +#ifdef GL_EXT_Cg_shader + &__GLEW_EXT_Cg_shader, +#endif +#ifdef GL_EXT_EGL_image_array + &__GLEW_EXT_EGL_image_array, +#endif +#ifdef GL_EXT_YUV_target + &__GLEW_EXT_YUV_target, +#endif +#ifdef GL_EXT_abgr + &__GLEW_EXT_abgr, +#endif +#ifdef GL_EXT_base_instance + &__GLEW_EXT_base_instance, +#endif +#ifdef GL_EXT_bgra + &__GLEW_EXT_bgra, +#endif +#ifdef GL_EXT_bindable_uniform + &__GLEW_EXT_bindable_uniform, +#endif +#ifdef GL_EXT_blend_color + &__GLEW_EXT_blend_color, +#endif +#ifdef GL_EXT_blend_equation_separate + &__GLEW_EXT_blend_equation_separate, +#endif +#ifdef GL_EXT_blend_func_extended + &__GLEW_EXT_blend_func_extended, +#endif +#ifdef GL_EXT_blend_func_separate + &__GLEW_EXT_blend_func_separate, +#endif +#ifdef GL_EXT_blend_logic_op + &__GLEW_EXT_blend_logic_op, +#endif +#ifdef GL_EXT_blend_minmax + &__GLEW_EXT_blend_minmax, +#endif +#ifdef GL_EXT_blend_subtract + &__GLEW_EXT_blend_subtract, +#endif +#ifdef GL_EXT_buffer_storage + &__GLEW_EXT_buffer_storage, +#endif +#ifdef GL_EXT_clear_texture + &__GLEW_EXT_clear_texture, +#endif +#ifdef GL_EXT_clip_cull_distance + &__GLEW_EXT_clip_cull_distance, +#endif +#ifdef GL_EXT_clip_volume_hint + &__GLEW_EXT_clip_volume_hint, +#endif +#ifdef GL_EXT_cmyka + &__GLEW_EXT_cmyka, +#endif +#ifdef GL_EXT_color_buffer_float + &__GLEW_EXT_color_buffer_float, +#endif +#ifdef GL_EXT_color_buffer_half_float + &__GLEW_EXT_color_buffer_half_float, +#endif +#ifdef GL_EXT_color_subtable + &__GLEW_EXT_color_subtable, +#endif +#ifdef GL_EXT_compiled_vertex_array + &__GLEW_EXT_compiled_vertex_array, +#endif +#ifdef GL_EXT_compressed_ETC1_RGB8_sub_texture + &__GLEW_EXT_compressed_ETC1_RGB8_sub_texture, +#endif +#ifdef GL_EXT_conservative_depth + &__GLEW_EXT_conservative_depth, +#endif +#ifdef GL_EXT_convolution + &__GLEW_EXT_convolution, +#endif +#ifdef GL_EXT_coordinate_frame + &__GLEW_EXT_coordinate_frame, +#endif +#ifdef GL_EXT_copy_image + &__GLEW_EXT_copy_image, +#endif +#ifdef GL_EXT_copy_texture + &__GLEW_EXT_copy_texture, +#endif +#ifdef GL_EXT_cull_vertex + &__GLEW_EXT_cull_vertex, +#endif +#ifdef GL_EXT_debug_label + &__GLEW_EXT_debug_label, +#endif +#ifdef GL_EXT_debug_marker + &__GLEW_EXT_debug_marker, +#endif +#ifdef GL_EXT_depth_bounds_test + &__GLEW_EXT_depth_bounds_test, +#endif +#ifdef GL_EXT_direct_state_access + &__GLEW_EXT_direct_state_access, +#endif +#ifdef GL_EXT_discard_framebuffer + &__GLEW_EXT_discard_framebuffer, +#endif +#ifdef GL_EXT_draw_buffers + &__GLEW_EXT_draw_buffers, +#endif +#ifdef GL_EXT_draw_buffers2 + &__GLEW_EXT_draw_buffers2, +#endif +#ifdef GL_EXT_draw_buffers_indexed + &__GLEW_EXT_draw_buffers_indexed, +#endif +#ifdef GL_EXT_draw_elements_base_vertex + &__GLEW_EXT_draw_elements_base_vertex, +#endif +#ifdef GL_EXT_draw_instanced + &__GLEW_EXT_draw_instanced, +#endif +#ifdef GL_EXT_draw_range_elements + &__GLEW_EXT_draw_range_elements, +#endif +#ifdef GL_EXT_external_buffer + &__GLEW_EXT_external_buffer, +#endif +#ifdef GL_EXT_float_blend + &__GLEW_EXT_float_blend, +#endif +#ifdef GL_EXT_fog_coord + &__GLEW_EXT_fog_coord, +#endif +#ifdef GL_EXT_frag_depth + &__GLEW_EXT_frag_depth, +#endif +#ifdef GL_EXT_fragment_lighting + &__GLEW_EXT_fragment_lighting, +#endif +#ifdef GL_EXT_framebuffer_blit + &__GLEW_EXT_framebuffer_blit, +#endif +#ifdef GL_EXT_framebuffer_multisample + &__GLEW_EXT_framebuffer_multisample, +#endif +#ifdef GL_EXT_framebuffer_multisample_blit_scaled + &__GLEW_EXT_framebuffer_multisample_blit_scaled, +#endif +#ifdef GL_EXT_framebuffer_object + &__GLEW_EXT_framebuffer_object, +#endif +#ifdef GL_EXT_framebuffer_sRGB + &__GLEW_EXT_framebuffer_sRGB, +#endif +#ifdef GL_EXT_geometry_point_size + &__GLEW_EXT_geometry_point_size, +#endif +#ifdef GL_EXT_geometry_shader + &__GLEW_EXT_geometry_shader, +#endif +#ifdef GL_EXT_geometry_shader4 + &__GLEW_EXT_geometry_shader4, +#endif +#ifdef GL_EXT_gpu_program_parameters + &__GLEW_EXT_gpu_program_parameters, +#endif +#ifdef GL_EXT_gpu_shader4 + &__GLEW_EXT_gpu_shader4, +#endif +#ifdef GL_EXT_gpu_shader5 + &__GLEW_EXT_gpu_shader5, +#endif +#ifdef GL_EXT_histogram + &__GLEW_EXT_histogram, +#endif +#ifdef GL_EXT_index_array_formats + &__GLEW_EXT_index_array_formats, +#endif +#ifdef GL_EXT_index_func + &__GLEW_EXT_index_func, +#endif +#ifdef GL_EXT_index_material + &__GLEW_EXT_index_material, +#endif +#ifdef GL_EXT_index_texture + &__GLEW_EXT_index_texture, +#endif +#ifdef GL_EXT_instanced_arrays + &__GLEW_EXT_instanced_arrays, +#endif +#ifdef GL_EXT_light_texture + &__GLEW_EXT_light_texture, +#endif +#ifdef GL_EXT_map_buffer_range + &__GLEW_EXT_map_buffer_range, +#endif +#ifdef GL_EXT_memory_object + &__GLEW_EXT_memory_object, +#endif +#ifdef GL_EXT_memory_object_fd + &__GLEW_EXT_memory_object_fd, +#endif +#ifdef GL_EXT_memory_object_win32 + &__GLEW_EXT_memory_object_win32, +#endif +#ifdef GL_EXT_misc_attribute + &__GLEW_EXT_misc_attribute, +#endif +#ifdef GL_EXT_multi_draw_arrays + &__GLEW_EXT_multi_draw_arrays, +#endif +#ifdef GL_EXT_multi_draw_indirect + &__GLEW_EXT_multi_draw_indirect, +#endif +#ifdef GL_EXT_multiple_textures + &__GLEW_EXT_multiple_textures, +#endif +#ifdef GL_EXT_multisample + &__GLEW_EXT_multisample, +#endif +#ifdef GL_EXT_multisample_compatibility + &__GLEW_EXT_multisample_compatibility, +#endif +#ifdef GL_EXT_multisampled_render_to_texture + &__GLEW_EXT_multisampled_render_to_texture, +#endif +#ifdef GL_EXT_multisampled_render_to_texture2 + &__GLEW_EXT_multisampled_render_to_texture2, +#endif +#ifdef GL_EXT_multiview_draw_buffers + &__GLEW_EXT_multiview_draw_buffers, +#endif +#ifdef GL_EXT_packed_depth_stencil + &__GLEW_EXT_packed_depth_stencil, +#endif +#ifdef GL_EXT_packed_float + &__GLEW_EXT_packed_float, +#endif +#ifdef GL_EXT_packed_pixels + &__GLEW_EXT_packed_pixels, +#endif +#ifdef GL_EXT_paletted_texture + &__GLEW_EXT_paletted_texture, +#endif +#ifdef GL_EXT_pixel_buffer_object + &__GLEW_EXT_pixel_buffer_object, +#endif +#ifdef GL_EXT_pixel_transform + &__GLEW_EXT_pixel_transform, +#endif +#ifdef GL_EXT_pixel_transform_color_table + &__GLEW_EXT_pixel_transform_color_table, +#endif +#ifdef GL_EXT_point_parameters + &__GLEW_EXT_point_parameters, +#endif +#ifdef GL_EXT_polygon_offset + &__GLEW_EXT_polygon_offset, +#endif +#ifdef GL_EXT_polygon_offset_clamp + &__GLEW_EXT_polygon_offset_clamp, +#endif +#ifdef GL_EXT_post_depth_coverage + &__GLEW_EXT_post_depth_coverage, +#endif +#ifdef GL_EXT_provoking_vertex + &__GLEW_EXT_provoking_vertex, +#endif +#ifdef GL_EXT_pvrtc_sRGB + &__GLEW_EXT_pvrtc_sRGB, +#endif +#ifdef GL_EXT_raster_multisample + &__GLEW_EXT_raster_multisample, +#endif +#ifdef GL_EXT_read_format_bgra + &__GLEW_EXT_read_format_bgra, +#endif +#ifdef GL_EXT_render_snorm + &__GLEW_EXT_render_snorm, +#endif +#ifdef GL_EXT_rescale_normal + &__GLEW_EXT_rescale_normal, +#endif +#ifdef GL_EXT_sRGB + &__GLEW_EXT_sRGB, +#endif +#ifdef GL_EXT_sRGB_write_control + &__GLEW_EXT_sRGB_write_control, +#endif +#ifdef GL_EXT_scene_marker + &__GLEW_EXT_scene_marker, +#endif +#ifdef GL_EXT_secondary_color + &__GLEW_EXT_secondary_color, +#endif +#ifdef GL_EXT_semaphore + &__GLEW_EXT_semaphore, +#endif +#ifdef GL_EXT_semaphore_fd + &__GLEW_EXT_semaphore_fd, +#endif +#ifdef GL_EXT_semaphore_win32 + &__GLEW_EXT_semaphore_win32, +#endif +#ifdef GL_EXT_separate_shader_objects + &__GLEW_EXT_separate_shader_objects, +#endif +#ifdef GL_EXT_separate_specular_color + &__GLEW_EXT_separate_specular_color, +#endif +#ifdef GL_EXT_shader_framebuffer_fetch + &__GLEW_EXT_shader_framebuffer_fetch, +#endif +#ifdef GL_EXT_shader_group_vote + &__GLEW_EXT_shader_group_vote, +#endif +#ifdef GL_EXT_shader_image_load_formatted + &__GLEW_EXT_shader_image_load_formatted, +#endif +#ifdef GL_EXT_shader_image_load_store + &__GLEW_EXT_shader_image_load_store, +#endif +#ifdef GL_EXT_shader_implicit_conversions + &__GLEW_EXT_shader_implicit_conversions, +#endif +#ifdef GL_EXT_shader_integer_mix + &__GLEW_EXT_shader_integer_mix, +#endif +#ifdef GL_EXT_shader_io_blocks + &__GLEW_EXT_shader_io_blocks, +#endif +#ifdef GL_EXT_shader_non_constant_global_initializers + &__GLEW_EXT_shader_non_constant_global_initializers, +#endif +#ifdef GL_EXT_shader_pixel_local_storage + &__GLEW_EXT_shader_pixel_local_storage, +#endif +#ifdef GL_EXT_shader_pixel_local_storage2 + &__GLEW_EXT_shader_pixel_local_storage2, +#endif +#ifdef GL_EXT_shader_texture_lod + &__GLEW_EXT_shader_texture_lod, +#endif +#ifdef GL_EXT_shadow_funcs + &__GLEW_EXT_shadow_funcs, +#endif +#ifdef GL_EXT_shadow_samplers + &__GLEW_EXT_shadow_samplers, +#endif +#ifdef GL_EXT_shared_texture_palette + &__GLEW_EXT_shared_texture_palette, +#endif +#ifdef GL_EXT_sparse_texture + &__GLEW_EXT_sparse_texture, +#endif +#ifdef GL_EXT_sparse_texture2 + &__GLEW_EXT_sparse_texture2, +#endif +#ifdef GL_EXT_stencil_clear_tag + &__GLEW_EXT_stencil_clear_tag, +#endif +#ifdef GL_EXT_stencil_two_side + &__GLEW_EXT_stencil_two_side, +#endif +#ifdef GL_EXT_stencil_wrap + &__GLEW_EXT_stencil_wrap, +#endif +#ifdef GL_EXT_subtexture + &__GLEW_EXT_subtexture, +#endif +#ifdef GL_EXT_texture + &__GLEW_EXT_texture, +#endif +#ifdef GL_EXT_texture3D + &__GLEW_EXT_texture3D, +#endif +#ifdef GL_EXT_texture_array + &__GLEW_EXT_texture_array, +#endif +#ifdef GL_EXT_texture_buffer_object + &__GLEW_EXT_texture_buffer_object, +#endif +#ifdef GL_EXT_texture_compression_astc_decode_mode + &__GLEW_EXT_texture_compression_astc_decode_mode, +#endif +#ifdef GL_EXT_texture_compression_astc_decode_mode_rgb9e5 + &__GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5, +#endif +#ifdef GL_EXT_texture_compression_bptc + &__GLEW_EXT_texture_compression_bptc, +#endif +#ifdef GL_EXT_texture_compression_dxt1 + &__GLEW_EXT_texture_compression_dxt1, +#endif +#ifdef GL_EXT_texture_compression_latc + &__GLEW_EXT_texture_compression_latc, +#endif +#ifdef GL_EXT_texture_compression_rgtc + &__GLEW_EXT_texture_compression_rgtc, +#endif +#ifdef GL_EXT_texture_compression_s3tc + &__GLEW_EXT_texture_compression_s3tc, +#endif +#ifdef GL_EXT_texture_cube_map + &__GLEW_EXT_texture_cube_map, +#endif +#ifdef GL_EXT_texture_cube_map_array + &__GLEW_EXT_texture_cube_map_array, +#endif +#ifdef GL_EXT_texture_edge_clamp + &__GLEW_EXT_texture_edge_clamp, +#endif +#ifdef GL_EXT_texture_env + &__GLEW_EXT_texture_env, +#endif +#ifdef GL_EXT_texture_env_add + &__GLEW_EXT_texture_env_add, +#endif +#ifdef GL_EXT_texture_env_combine + &__GLEW_EXT_texture_env_combine, +#endif +#ifdef GL_EXT_texture_env_dot3 + &__GLEW_EXT_texture_env_dot3, +#endif +#ifdef GL_EXT_texture_filter_anisotropic + &__GLEW_EXT_texture_filter_anisotropic, +#endif +#ifdef GL_EXT_texture_filter_minmax + &__GLEW_EXT_texture_filter_minmax, +#endif +#ifdef GL_EXT_texture_format_BGRA8888 + &__GLEW_EXT_texture_format_BGRA8888, +#endif +#ifdef GL_EXT_texture_integer + &__GLEW_EXT_texture_integer, +#endif +#ifdef GL_EXT_texture_lod_bias + &__GLEW_EXT_texture_lod_bias, +#endif +#ifdef GL_EXT_texture_mirror_clamp + &__GLEW_EXT_texture_mirror_clamp, +#endif +#ifdef GL_EXT_texture_norm16 + &__GLEW_EXT_texture_norm16, +#endif +#ifdef GL_EXT_texture_object + &__GLEW_EXT_texture_object, +#endif +#ifdef GL_EXT_texture_perturb_normal + &__GLEW_EXT_texture_perturb_normal, +#endif +#ifdef GL_EXT_texture_rectangle + &__GLEW_EXT_texture_rectangle, +#endif +#ifdef GL_EXT_texture_rg + &__GLEW_EXT_texture_rg, +#endif +#ifdef GL_EXT_texture_sRGB + &__GLEW_EXT_texture_sRGB, +#endif +#ifdef GL_EXT_texture_sRGB_R8 + &__GLEW_EXT_texture_sRGB_R8, +#endif +#ifdef GL_EXT_texture_sRGB_RG8 + &__GLEW_EXT_texture_sRGB_RG8, +#endif +#ifdef GL_EXT_texture_sRGB_decode + &__GLEW_EXT_texture_sRGB_decode, +#endif +#ifdef GL_EXT_texture_shared_exponent + &__GLEW_EXT_texture_shared_exponent, +#endif +#ifdef GL_EXT_texture_snorm + &__GLEW_EXT_texture_snorm, +#endif +#ifdef GL_EXT_texture_storage + &__GLEW_EXT_texture_storage, +#endif +#ifdef GL_EXT_texture_swizzle + &__GLEW_EXT_texture_swizzle, +#endif +#ifdef GL_EXT_texture_type_2_10_10_10_REV + &__GLEW_EXT_texture_type_2_10_10_10_REV, +#endif +#ifdef GL_EXT_texture_view + &__GLEW_EXT_texture_view, +#endif +#ifdef GL_EXT_timer_query + &__GLEW_EXT_timer_query, +#endif +#ifdef GL_EXT_transform_feedback + &__GLEW_EXT_transform_feedback, +#endif +#ifdef GL_EXT_unpack_subimage + &__GLEW_EXT_unpack_subimage, +#endif +#ifdef GL_EXT_vertex_array + &__GLEW_EXT_vertex_array, +#endif +#ifdef GL_EXT_vertex_array_bgra + &__GLEW_EXT_vertex_array_bgra, +#endif +#ifdef GL_EXT_vertex_array_setXXX + &__GLEW_EXT_vertex_array_setXXX, +#endif +#ifdef GL_EXT_vertex_attrib_64bit + &__GLEW_EXT_vertex_attrib_64bit, +#endif +#ifdef GL_EXT_vertex_shader + &__GLEW_EXT_vertex_shader, +#endif +#ifdef GL_EXT_vertex_weighting + &__GLEW_EXT_vertex_weighting, +#endif +#ifdef GL_EXT_win32_keyed_mutex + &__GLEW_EXT_win32_keyed_mutex, +#endif +#ifdef GL_EXT_window_rectangles + &__GLEW_EXT_window_rectangles, +#endif +#ifdef GL_EXT_x11_sync_object + &__GLEW_EXT_x11_sync_object, +#endif +#ifdef GL_GREMEDY_frame_terminator + &__GLEW_GREMEDY_frame_terminator, +#endif +#ifdef GL_GREMEDY_string_marker + &__GLEW_GREMEDY_string_marker, +#endif +#ifdef GL_HP_convolution_border_modes + &__GLEW_HP_convolution_border_modes, +#endif +#ifdef GL_HP_image_transform + &__GLEW_HP_image_transform, +#endif +#ifdef GL_HP_occlusion_test + &__GLEW_HP_occlusion_test, +#endif +#ifdef GL_HP_texture_lighting + &__GLEW_HP_texture_lighting, +#endif +#ifdef GL_IBM_cull_vertex + &__GLEW_IBM_cull_vertex, +#endif +#ifdef GL_IBM_multimode_draw_arrays + &__GLEW_IBM_multimode_draw_arrays, +#endif +#ifdef GL_IBM_rasterpos_clip + &__GLEW_IBM_rasterpos_clip, +#endif +#ifdef GL_IBM_static_data + &__GLEW_IBM_static_data, +#endif +#ifdef GL_IBM_texture_mirrored_repeat + &__GLEW_IBM_texture_mirrored_repeat, +#endif +#ifdef GL_IBM_vertex_array_lists + &__GLEW_IBM_vertex_array_lists, +#endif +#ifdef GL_INGR_color_clamp + &__GLEW_INGR_color_clamp, +#endif +#ifdef GL_INGR_interlace_read + &__GLEW_INGR_interlace_read, +#endif +#ifdef GL_INTEL_conservative_rasterization + &__GLEW_INTEL_conservative_rasterization, +#endif +#ifdef GL_INTEL_fragment_shader_ordering + &__GLEW_INTEL_fragment_shader_ordering, +#endif +#ifdef GL_INTEL_framebuffer_CMAA + &__GLEW_INTEL_framebuffer_CMAA, +#endif +#ifdef GL_INTEL_map_texture + &__GLEW_INTEL_map_texture, +#endif +#ifdef GL_INTEL_parallel_arrays + &__GLEW_INTEL_parallel_arrays, +#endif +#ifdef GL_INTEL_performance_query + &__GLEW_INTEL_performance_query, +#endif +#ifdef GL_INTEL_texture_scissor + &__GLEW_INTEL_texture_scissor, +#endif +#ifdef GL_KHR_blend_equation_advanced + &__GLEW_KHR_blend_equation_advanced, +#endif +#ifdef GL_KHR_blend_equation_advanced_coherent + &__GLEW_KHR_blend_equation_advanced_coherent, +#endif +#ifdef GL_KHR_context_flush_control + &__GLEW_KHR_context_flush_control, +#endif +#ifdef GL_KHR_debug + &__GLEW_KHR_debug, +#endif +#ifdef GL_KHR_no_error + &__GLEW_KHR_no_error, +#endif +#ifdef GL_KHR_parallel_shader_compile + &__GLEW_KHR_parallel_shader_compile, +#endif +#ifdef GL_KHR_robust_buffer_access_behavior + &__GLEW_KHR_robust_buffer_access_behavior, +#endif +#ifdef GL_KHR_robustness + &__GLEW_KHR_robustness, +#endif +#ifdef GL_KHR_texture_compression_astc_hdr + &__GLEW_KHR_texture_compression_astc_hdr, +#endif +#ifdef GL_KHR_texture_compression_astc_ldr + &__GLEW_KHR_texture_compression_astc_ldr, +#endif +#ifdef GL_KHR_texture_compression_astc_sliced_3d + &__GLEW_KHR_texture_compression_astc_sliced_3d, +#endif +#ifdef GL_KTX_buffer_region + &__GLEW_KTX_buffer_region, +#endif +#ifdef GL_MESAX_texture_stack + &__GLEW_MESAX_texture_stack, +#endif +#ifdef GL_MESA_pack_invert + &__GLEW_MESA_pack_invert, +#endif +#ifdef GL_MESA_resize_buffers + &__GLEW_MESA_resize_buffers, +#endif +#ifdef GL_MESA_shader_integer_functions + &__GLEW_MESA_shader_integer_functions, +#endif +#ifdef GL_MESA_window_pos + &__GLEW_MESA_window_pos, +#endif +#ifdef GL_MESA_ycbcr_texture + &__GLEW_MESA_ycbcr_texture, +#endif +#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers + &__GLEW_NVX_blend_equation_advanced_multi_draw_buffers, +#endif +#ifdef GL_NVX_conditional_render + &__GLEW_NVX_conditional_render, +#endif +#ifdef GL_NVX_gpu_memory_info + &__GLEW_NVX_gpu_memory_info, +#endif +#ifdef GL_NVX_linked_gpu_multicast + &__GLEW_NVX_linked_gpu_multicast, +#endif +#ifdef GL_NV_3dvision_settings + &__GLEW_NV_3dvision_settings, +#endif +#ifdef GL_NV_EGL_stream_consumer_external + &__GLEW_NV_EGL_stream_consumer_external, +#endif +#ifdef GL_NV_alpha_to_coverage_dither_control + &__GLEW_NV_alpha_to_coverage_dither_control, +#endif +#ifdef GL_NV_bgr + &__GLEW_NV_bgr, +#endif +#ifdef GL_NV_bindless_multi_draw_indirect + &__GLEW_NV_bindless_multi_draw_indirect, +#endif +#ifdef GL_NV_bindless_multi_draw_indirect_count + &__GLEW_NV_bindless_multi_draw_indirect_count, +#endif +#ifdef GL_NV_bindless_texture + &__GLEW_NV_bindless_texture, +#endif +#ifdef GL_NV_blend_equation_advanced + &__GLEW_NV_blend_equation_advanced, +#endif +#ifdef GL_NV_blend_equation_advanced_coherent + &__GLEW_NV_blend_equation_advanced_coherent, +#endif +#ifdef GL_NV_blend_minmax_factor + &__GLEW_NV_blend_minmax_factor, +#endif +#ifdef GL_NV_blend_square + &__GLEW_NV_blend_square, +#endif +#ifdef GL_NV_clip_space_w_scaling + &__GLEW_NV_clip_space_w_scaling, +#endif +#ifdef GL_NV_command_list + &__GLEW_NV_command_list, +#endif +#ifdef GL_NV_compute_program5 + &__GLEW_NV_compute_program5, +#endif +#ifdef GL_NV_conditional_render + &__GLEW_NV_conditional_render, +#endif +#ifdef GL_NV_conservative_raster + &__GLEW_NV_conservative_raster, +#endif +#ifdef GL_NV_conservative_raster_dilate + &__GLEW_NV_conservative_raster_dilate, +#endif +#ifdef GL_NV_conservative_raster_pre_snap_triangles + &__GLEW_NV_conservative_raster_pre_snap_triangles, +#endif +#ifdef GL_NV_copy_buffer + &__GLEW_NV_copy_buffer, +#endif +#ifdef GL_NV_copy_depth_to_color + &__GLEW_NV_copy_depth_to_color, +#endif +#ifdef GL_NV_copy_image + &__GLEW_NV_copy_image, +#endif +#ifdef GL_NV_deep_texture3D + &__GLEW_NV_deep_texture3D, +#endif +#ifdef GL_NV_depth_buffer_float + &__GLEW_NV_depth_buffer_float, +#endif +#ifdef GL_NV_depth_clamp + &__GLEW_NV_depth_clamp, +#endif +#ifdef GL_NV_depth_range_unclamped + &__GLEW_NV_depth_range_unclamped, +#endif +#ifdef GL_NV_draw_buffers + &__GLEW_NV_draw_buffers, +#endif +#ifdef GL_NV_draw_instanced + &__GLEW_NV_draw_instanced, +#endif +#ifdef GL_NV_draw_texture + &__GLEW_NV_draw_texture, +#endif +#ifdef GL_NV_draw_vulkan_image + &__GLEW_NV_draw_vulkan_image, +#endif +#ifdef GL_NV_evaluators + &__GLEW_NV_evaluators, +#endif +#ifdef GL_NV_explicit_attrib_location + &__GLEW_NV_explicit_attrib_location, +#endif +#ifdef GL_NV_explicit_multisample + &__GLEW_NV_explicit_multisample, +#endif +#ifdef GL_NV_fbo_color_attachments + &__GLEW_NV_fbo_color_attachments, +#endif +#ifdef GL_NV_fence + &__GLEW_NV_fence, +#endif +#ifdef GL_NV_fill_rectangle + &__GLEW_NV_fill_rectangle, +#endif +#ifdef GL_NV_float_buffer + &__GLEW_NV_float_buffer, +#endif +#ifdef GL_NV_fog_distance + &__GLEW_NV_fog_distance, +#endif +#ifdef GL_NV_fragment_coverage_to_color + &__GLEW_NV_fragment_coverage_to_color, +#endif +#ifdef GL_NV_fragment_program + &__GLEW_NV_fragment_program, +#endif +#ifdef GL_NV_fragment_program2 + &__GLEW_NV_fragment_program2, +#endif +#ifdef GL_NV_fragment_program4 + &__GLEW_NV_fragment_program4, +#endif +#ifdef GL_NV_fragment_program_option + &__GLEW_NV_fragment_program_option, +#endif +#ifdef GL_NV_fragment_shader_interlock + &__GLEW_NV_fragment_shader_interlock, +#endif +#ifdef GL_NV_framebuffer_blit + &__GLEW_NV_framebuffer_blit, +#endif +#ifdef GL_NV_framebuffer_mixed_samples + &__GLEW_NV_framebuffer_mixed_samples, +#endif +#ifdef GL_NV_framebuffer_multisample + &__GLEW_NV_framebuffer_multisample, +#endif +#ifdef GL_NV_framebuffer_multisample_coverage + &__GLEW_NV_framebuffer_multisample_coverage, +#endif +#ifdef GL_NV_generate_mipmap_sRGB + &__GLEW_NV_generate_mipmap_sRGB, +#endif +#ifdef GL_NV_geometry_program4 + &__GLEW_NV_geometry_program4, +#endif +#ifdef GL_NV_geometry_shader4 + &__GLEW_NV_geometry_shader4, +#endif +#ifdef GL_NV_geometry_shader_passthrough + &__GLEW_NV_geometry_shader_passthrough, +#endif +#ifdef GL_NV_gpu_multicast + &__GLEW_NV_gpu_multicast, +#endif +#ifdef GL_NV_gpu_program4 + &__GLEW_NV_gpu_program4, +#endif +#ifdef GL_NV_gpu_program5 + &__GLEW_NV_gpu_program5, +#endif +#ifdef GL_NV_gpu_program5_mem_extended + &__GLEW_NV_gpu_program5_mem_extended, +#endif +#ifdef GL_NV_gpu_program_fp64 + &__GLEW_NV_gpu_program_fp64, +#endif +#ifdef GL_NV_gpu_shader5 + &__GLEW_NV_gpu_shader5, +#endif +#ifdef GL_NV_half_float + &__GLEW_NV_half_float, +#endif +#ifdef GL_NV_image_formats + &__GLEW_NV_image_formats, +#endif +#ifdef GL_NV_instanced_arrays + &__GLEW_NV_instanced_arrays, +#endif +#ifdef GL_NV_internalformat_sample_query + &__GLEW_NV_internalformat_sample_query, +#endif +#ifdef GL_NV_light_max_exponent + &__GLEW_NV_light_max_exponent, +#endif +#ifdef GL_NV_multisample_coverage + &__GLEW_NV_multisample_coverage, +#endif +#ifdef GL_NV_multisample_filter_hint + &__GLEW_NV_multisample_filter_hint, +#endif +#ifdef GL_NV_non_square_matrices + &__GLEW_NV_non_square_matrices, +#endif +#ifdef GL_NV_occlusion_query + &__GLEW_NV_occlusion_query, +#endif +#ifdef GL_NV_pack_subimage + &__GLEW_NV_pack_subimage, +#endif +#ifdef GL_NV_packed_depth_stencil + &__GLEW_NV_packed_depth_stencil, +#endif +#ifdef GL_NV_packed_float + &__GLEW_NV_packed_float, +#endif +#ifdef GL_NV_packed_float_linear + &__GLEW_NV_packed_float_linear, +#endif +#ifdef GL_NV_parameter_buffer_object + &__GLEW_NV_parameter_buffer_object, +#endif +#ifdef GL_NV_parameter_buffer_object2 + &__GLEW_NV_parameter_buffer_object2, +#endif +#ifdef GL_NV_path_rendering + &__GLEW_NV_path_rendering, +#endif +#ifdef GL_NV_path_rendering_shared_edge + &__GLEW_NV_path_rendering_shared_edge, +#endif +#ifdef GL_NV_pixel_buffer_object + &__GLEW_NV_pixel_buffer_object, +#endif +#ifdef GL_NV_pixel_data_range + &__GLEW_NV_pixel_data_range, +#endif +#ifdef GL_NV_platform_binary + &__GLEW_NV_platform_binary, +#endif +#ifdef GL_NV_point_sprite + &__GLEW_NV_point_sprite, +#endif +#ifdef GL_NV_polygon_mode + &__GLEW_NV_polygon_mode, +#endif +#ifdef GL_NV_present_video + &__GLEW_NV_present_video, +#endif +#ifdef GL_NV_primitive_restart + &__GLEW_NV_primitive_restart, +#endif +#ifdef GL_NV_read_depth + &__GLEW_NV_read_depth, +#endif +#ifdef GL_NV_read_depth_stencil + &__GLEW_NV_read_depth_stencil, +#endif +#ifdef GL_NV_read_stencil + &__GLEW_NV_read_stencil, +#endif +#ifdef GL_NV_register_combiners + &__GLEW_NV_register_combiners, +#endif +#ifdef GL_NV_register_combiners2 + &__GLEW_NV_register_combiners2, +#endif +#ifdef GL_NV_robustness_video_memory_purge + &__GLEW_NV_robustness_video_memory_purge, +#endif +#ifdef GL_NV_sRGB_formats + &__GLEW_NV_sRGB_formats, +#endif +#ifdef GL_NV_sample_locations + &__GLEW_NV_sample_locations, +#endif +#ifdef GL_NV_sample_mask_override_coverage + &__GLEW_NV_sample_mask_override_coverage, +#endif +#ifdef GL_NV_shader_atomic_counters + &__GLEW_NV_shader_atomic_counters, +#endif +#ifdef GL_NV_shader_atomic_float + &__GLEW_NV_shader_atomic_float, +#endif +#ifdef GL_NV_shader_atomic_float64 + &__GLEW_NV_shader_atomic_float64, +#endif +#ifdef GL_NV_shader_atomic_fp16_vector + &__GLEW_NV_shader_atomic_fp16_vector, +#endif +#ifdef GL_NV_shader_atomic_int64 + &__GLEW_NV_shader_atomic_int64, +#endif +#ifdef GL_NV_shader_buffer_load + &__GLEW_NV_shader_buffer_load, +#endif +#ifdef GL_NV_shader_noperspective_interpolation + &__GLEW_NV_shader_noperspective_interpolation, +#endif +#ifdef GL_NV_shader_storage_buffer_object + &__GLEW_NV_shader_storage_buffer_object, +#endif +#ifdef GL_NV_shader_thread_group + &__GLEW_NV_shader_thread_group, +#endif +#ifdef GL_NV_shader_thread_shuffle + &__GLEW_NV_shader_thread_shuffle, +#endif +#ifdef GL_NV_shadow_samplers_array + &__GLEW_NV_shadow_samplers_array, +#endif +#ifdef GL_NV_shadow_samplers_cube + &__GLEW_NV_shadow_samplers_cube, +#endif +#ifdef GL_NV_stereo_view_rendering + &__GLEW_NV_stereo_view_rendering, +#endif +#ifdef GL_NV_tessellation_program5 + &__GLEW_NV_tessellation_program5, +#endif +#ifdef GL_NV_texgen_emboss + &__GLEW_NV_texgen_emboss, +#endif +#ifdef GL_NV_texgen_reflection + &__GLEW_NV_texgen_reflection, +#endif +#ifdef GL_NV_texture_array + &__GLEW_NV_texture_array, +#endif +#ifdef GL_NV_texture_barrier + &__GLEW_NV_texture_barrier, +#endif +#ifdef GL_NV_texture_border_clamp + &__GLEW_NV_texture_border_clamp, +#endif +#ifdef GL_NV_texture_compression_latc + &__GLEW_NV_texture_compression_latc, +#endif +#ifdef GL_NV_texture_compression_s3tc + &__GLEW_NV_texture_compression_s3tc, +#endif +#ifdef GL_NV_texture_compression_s3tc_update + &__GLEW_NV_texture_compression_s3tc_update, +#endif +#ifdef GL_NV_texture_compression_vtc + &__GLEW_NV_texture_compression_vtc, +#endif +#ifdef GL_NV_texture_env_combine4 + &__GLEW_NV_texture_env_combine4, +#endif +#ifdef GL_NV_texture_expand_normal + &__GLEW_NV_texture_expand_normal, +#endif +#ifdef GL_NV_texture_multisample + &__GLEW_NV_texture_multisample, +#endif +#ifdef GL_NV_texture_npot_2D_mipmap + &__GLEW_NV_texture_npot_2D_mipmap, +#endif +#ifdef GL_NV_texture_rectangle + &__GLEW_NV_texture_rectangle, +#endif +#ifdef GL_NV_texture_rectangle_compressed + &__GLEW_NV_texture_rectangle_compressed, +#endif +#ifdef GL_NV_texture_shader + &__GLEW_NV_texture_shader, +#endif +#ifdef GL_NV_texture_shader2 + &__GLEW_NV_texture_shader2, +#endif +#ifdef GL_NV_texture_shader3 + &__GLEW_NV_texture_shader3, +#endif +#ifdef GL_NV_transform_feedback + &__GLEW_NV_transform_feedback, +#endif +#ifdef GL_NV_transform_feedback2 + &__GLEW_NV_transform_feedback2, +#endif +#ifdef GL_NV_uniform_buffer_unified_memory + &__GLEW_NV_uniform_buffer_unified_memory, +#endif +#ifdef GL_NV_vdpau_interop + &__GLEW_NV_vdpau_interop, +#endif +#ifdef GL_NV_vertex_array_range + &__GLEW_NV_vertex_array_range, +#endif +#ifdef GL_NV_vertex_array_range2 + &__GLEW_NV_vertex_array_range2, +#endif +#ifdef GL_NV_vertex_attrib_integer_64bit + &__GLEW_NV_vertex_attrib_integer_64bit, +#endif +#ifdef GL_NV_vertex_buffer_unified_memory + &__GLEW_NV_vertex_buffer_unified_memory, +#endif +#ifdef GL_NV_vertex_program + &__GLEW_NV_vertex_program, +#endif +#ifdef GL_NV_vertex_program1_1 + &__GLEW_NV_vertex_program1_1, +#endif +#ifdef GL_NV_vertex_program2 + &__GLEW_NV_vertex_program2, +#endif +#ifdef GL_NV_vertex_program2_option + &__GLEW_NV_vertex_program2_option, +#endif +#ifdef GL_NV_vertex_program3 + &__GLEW_NV_vertex_program3, +#endif +#ifdef GL_NV_vertex_program4 + &__GLEW_NV_vertex_program4, +#endif +#ifdef GL_NV_video_capture + &__GLEW_NV_video_capture, +#endif +#ifdef GL_NV_viewport_array + &__GLEW_NV_viewport_array, +#endif +#ifdef GL_NV_viewport_array2 + &__GLEW_NV_viewport_array2, +#endif +#ifdef GL_NV_viewport_swizzle + &__GLEW_NV_viewport_swizzle, +#endif +#ifdef GL_OES_byte_coordinates + &__GLEW_OES_byte_coordinates, +#endif +#ifdef GL_OML_interlace + &__GLEW_OML_interlace, +#endif +#ifdef GL_OML_resample + &__GLEW_OML_resample, +#endif +#ifdef GL_OML_subsample + &__GLEW_OML_subsample, +#endif +#ifdef GL_OVR_multiview + &__GLEW_OVR_multiview, +#endif +#ifdef GL_OVR_multiview2 + &__GLEW_OVR_multiview2, +#endif +#ifdef GL_OVR_multiview_multisampled_render_to_texture + &__GLEW_OVR_multiview_multisampled_render_to_texture, +#endif +#ifdef GL_PGI_misc_hints + &__GLEW_PGI_misc_hints, +#endif +#ifdef GL_PGI_vertex_hints + &__GLEW_PGI_vertex_hints, +#endif +#ifdef GL_QCOM_alpha_test + &__GLEW_QCOM_alpha_test, +#endif +#ifdef GL_QCOM_binning_control + &__GLEW_QCOM_binning_control, +#endif +#ifdef GL_QCOM_driver_control + &__GLEW_QCOM_driver_control, +#endif +#ifdef GL_QCOM_extended_get + &__GLEW_QCOM_extended_get, +#endif +#ifdef GL_QCOM_extended_get2 + &__GLEW_QCOM_extended_get2, +#endif +#ifdef GL_QCOM_framebuffer_foveated + &__GLEW_QCOM_framebuffer_foveated, +#endif +#ifdef GL_QCOM_perfmon_global_mode + &__GLEW_QCOM_perfmon_global_mode, +#endif +#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent + &__GLEW_QCOM_shader_framebuffer_fetch_noncoherent, +#endif +#ifdef GL_QCOM_tiled_rendering + &__GLEW_QCOM_tiled_rendering, +#endif +#ifdef GL_QCOM_writeonly_rendering + &__GLEW_QCOM_writeonly_rendering, +#endif +#ifdef GL_REGAL_ES1_0_compatibility + &__GLEW_REGAL_ES1_0_compatibility, +#endif +#ifdef GL_REGAL_ES1_1_compatibility + &__GLEW_REGAL_ES1_1_compatibility, +#endif +#ifdef GL_REGAL_enable + &__GLEW_REGAL_enable, +#endif +#ifdef GL_REGAL_error_string + &__GLEW_REGAL_error_string, +#endif +#ifdef GL_REGAL_extension_query + &__GLEW_REGAL_extension_query, +#endif +#ifdef GL_REGAL_log + &__GLEW_REGAL_log, +#endif +#ifdef GL_REGAL_proc_address + &__GLEW_REGAL_proc_address, +#endif +#ifdef GL_REND_screen_coordinates + &__GLEW_REND_screen_coordinates, +#endif +#ifdef GL_S3_s3tc + &__GLEW_S3_s3tc, +#endif +#ifdef GL_SGIS_clip_band_hint + &__GLEW_SGIS_clip_band_hint, +#endif +#ifdef GL_SGIS_color_range + &__GLEW_SGIS_color_range, +#endif +#ifdef GL_SGIS_detail_texture + &__GLEW_SGIS_detail_texture, +#endif +#ifdef GL_SGIS_fog_function + &__GLEW_SGIS_fog_function, +#endif +#ifdef GL_SGIS_generate_mipmap + &__GLEW_SGIS_generate_mipmap, +#endif +#ifdef GL_SGIS_line_texgen + &__GLEW_SGIS_line_texgen, +#endif +#ifdef GL_SGIS_multisample + &__GLEW_SGIS_multisample, +#endif +#ifdef GL_SGIS_multitexture + &__GLEW_SGIS_multitexture, +#endif +#ifdef GL_SGIS_pixel_texture + &__GLEW_SGIS_pixel_texture, +#endif +#ifdef GL_SGIS_point_line_texgen + &__GLEW_SGIS_point_line_texgen, +#endif +#ifdef GL_SGIS_shared_multisample + &__GLEW_SGIS_shared_multisample, +#endif +#ifdef GL_SGIS_sharpen_texture + &__GLEW_SGIS_sharpen_texture, +#endif +#ifdef GL_SGIS_texture4D + &__GLEW_SGIS_texture4D, +#endif +#ifdef GL_SGIS_texture_border_clamp + &__GLEW_SGIS_texture_border_clamp, +#endif +#ifdef GL_SGIS_texture_edge_clamp + &__GLEW_SGIS_texture_edge_clamp, +#endif +#ifdef GL_SGIS_texture_filter4 + &__GLEW_SGIS_texture_filter4, +#endif +#ifdef GL_SGIS_texture_lod + &__GLEW_SGIS_texture_lod, +#endif +#ifdef GL_SGIS_texture_select + &__GLEW_SGIS_texture_select, +#endif +#ifdef GL_SGIX_async + &__GLEW_SGIX_async, +#endif +#ifdef GL_SGIX_async_histogram + &__GLEW_SGIX_async_histogram, +#endif +#ifdef GL_SGIX_async_pixel + &__GLEW_SGIX_async_pixel, +#endif +#ifdef GL_SGIX_bali_g_instruments + &__GLEW_SGIX_bali_g_instruments, +#endif +#ifdef GL_SGIX_bali_r_instruments + &__GLEW_SGIX_bali_r_instruments, +#endif +#ifdef GL_SGIX_bali_timer_instruments + &__GLEW_SGIX_bali_timer_instruments, +#endif +#ifdef GL_SGIX_blend_alpha_minmax + &__GLEW_SGIX_blend_alpha_minmax, +#endif +#ifdef GL_SGIX_blend_cadd + &__GLEW_SGIX_blend_cadd, +#endif +#ifdef GL_SGIX_blend_cmultiply + &__GLEW_SGIX_blend_cmultiply, +#endif +#ifdef GL_SGIX_calligraphic_fragment + &__GLEW_SGIX_calligraphic_fragment, +#endif +#ifdef GL_SGIX_clipmap + &__GLEW_SGIX_clipmap, +#endif +#ifdef GL_SGIX_color_matrix_accuracy + &__GLEW_SGIX_color_matrix_accuracy, +#endif +#ifdef GL_SGIX_color_table_index_mode + &__GLEW_SGIX_color_table_index_mode, +#endif +#ifdef GL_SGIX_complex_polar + &__GLEW_SGIX_complex_polar, +#endif +#ifdef GL_SGIX_convolution_accuracy + &__GLEW_SGIX_convolution_accuracy, +#endif +#ifdef GL_SGIX_cube_map + &__GLEW_SGIX_cube_map, +#endif +#ifdef GL_SGIX_cylinder_texgen + &__GLEW_SGIX_cylinder_texgen, +#endif +#ifdef GL_SGIX_datapipe + &__GLEW_SGIX_datapipe, +#endif +#ifdef GL_SGIX_decimation + &__GLEW_SGIX_decimation, +#endif +#ifdef GL_SGIX_depth_pass_instrument + &__GLEW_SGIX_depth_pass_instrument, +#endif +#ifdef GL_SGIX_depth_texture + &__GLEW_SGIX_depth_texture, +#endif +#ifdef GL_SGIX_dvc + &__GLEW_SGIX_dvc, +#endif +#ifdef GL_SGIX_flush_raster + &__GLEW_SGIX_flush_raster, +#endif +#ifdef GL_SGIX_fog_blend + &__GLEW_SGIX_fog_blend, +#endif +#ifdef GL_SGIX_fog_factor_to_alpha + &__GLEW_SGIX_fog_factor_to_alpha, +#endif +#ifdef GL_SGIX_fog_layers + &__GLEW_SGIX_fog_layers, +#endif +#ifdef GL_SGIX_fog_offset + &__GLEW_SGIX_fog_offset, +#endif +#ifdef GL_SGIX_fog_patchy + &__GLEW_SGIX_fog_patchy, +#endif +#ifdef GL_SGIX_fog_scale + &__GLEW_SGIX_fog_scale, +#endif +#ifdef GL_SGIX_fog_texture + &__GLEW_SGIX_fog_texture, +#endif +#ifdef GL_SGIX_fragment_lighting_space + &__GLEW_SGIX_fragment_lighting_space, +#endif +#ifdef GL_SGIX_fragment_specular_lighting + &__GLEW_SGIX_fragment_specular_lighting, +#endif +#ifdef GL_SGIX_fragments_instrument + &__GLEW_SGIX_fragments_instrument, +#endif +#ifdef GL_SGIX_framezoom + &__GLEW_SGIX_framezoom, +#endif +#ifdef GL_SGIX_icc_texture + &__GLEW_SGIX_icc_texture, +#endif +#ifdef GL_SGIX_igloo_interface + &__GLEW_SGIX_igloo_interface, +#endif +#ifdef GL_SGIX_image_compression + &__GLEW_SGIX_image_compression, +#endif +#ifdef GL_SGIX_impact_pixel_texture + &__GLEW_SGIX_impact_pixel_texture, +#endif +#ifdef GL_SGIX_instrument_error + &__GLEW_SGIX_instrument_error, +#endif +#ifdef GL_SGIX_interlace + &__GLEW_SGIX_interlace, +#endif +#ifdef GL_SGIX_ir_instrument1 + &__GLEW_SGIX_ir_instrument1, +#endif +#ifdef GL_SGIX_line_quality_hint + &__GLEW_SGIX_line_quality_hint, +#endif +#ifdef GL_SGIX_list_priority + &__GLEW_SGIX_list_priority, +#endif +#ifdef GL_SGIX_mpeg1 + &__GLEW_SGIX_mpeg1, +#endif +#ifdef GL_SGIX_mpeg2 + &__GLEW_SGIX_mpeg2, +#endif +#ifdef GL_SGIX_nonlinear_lighting_pervertex + &__GLEW_SGIX_nonlinear_lighting_pervertex, +#endif +#ifdef GL_SGIX_nurbs_eval + &__GLEW_SGIX_nurbs_eval, +#endif +#ifdef GL_SGIX_occlusion_instrument + &__GLEW_SGIX_occlusion_instrument, +#endif +#ifdef GL_SGIX_packed_6bytes + &__GLEW_SGIX_packed_6bytes, +#endif +#ifdef GL_SGIX_pixel_texture + &__GLEW_SGIX_pixel_texture, +#endif +#ifdef GL_SGIX_pixel_texture_bits + &__GLEW_SGIX_pixel_texture_bits, +#endif +#ifdef GL_SGIX_pixel_texture_lod + &__GLEW_SGIX_pixel_texture_lod, +#endif +#ifdef GL_SGIX_pixel_tiles + &__GLEW_SGIX_pixel_tiles, +#endif +#ifdef GL_SGIX_polynomial_ffd + &__GLEW_SGIX_polynomial_ffd, +#endif +#ifdef GL_SGIX_quad_mesh + &__GLEW_SGIX_quad_mesh, +#endif +#ifdef GL_SGIX_reference_plane + &__GLEW_SGIX_reference_plane, +#endif +#ifdef GL_SGIX_resample + &__GLEW_SGIX_resample, +#endif +#ifdef GL_SGIX_scalebias_hint + &__GLEW_SGIX_scalebias_hint, +#endif +#ifdef GL_SGIX_shadow + &__GLEW_SGIX_shadow, +#endif +#ifdef GL_SGIX_shadow_ambient + &__GLEW_SGIX_shadow_ambient, +#endif +#ifdef GL_SGIX_slim + &__GLEW_SGIX_slim, +#endif +#ifdef GL_SGIX_spotlight_cutoff + &__GLEW_SGIX_spotlight_cutoff, +#endif +#ifdef GL_SGIX_sprite + &__GLEW_SGIX_sprite, +#endif +#ifdef GL_SGIX_subdiv_patch + &__GLEW_SGIX_subdiv_patch, +#endif +#ifdef GL_SGIX_subsample + &__GLEW_SGIX_subsample, +#endif +#ifdef GL_SGIX_tag_sample_buffer + &__GLEW_SGIX_tag_sample_buffer, +#endif +#ifdef GL_SGIX_texture_add_env + &__GLEW_SGIX_texture_add_env, +#endif +#ifdef GL_SGIX_texture_coordinate_clamp + &__GLEW_SGIX_texture_coordinate_clamp, +#endif +#ifdef GL_SGIX_texture_lod_bias + &__GLEW_SGIX_texture_lod_bias, +#endif +#ifdef GL_SGIX_texture_mipmap_anisotropic + &__GLEW_SGIX_texture_mipmap_anisotropic, +#endif +#ifdef GL_SGIX_texture_multi_buffer + &__GLEW_SGIX_texture_multi_buffer, +#endif +#ifdef GL_SGIX_texture_phase + &__GLEW_SGIX_texture_phase, +#endif +#ifdef GL_SGIX_texture_range + &__GLEW_SGIX_texture_range, +#endif +#ifdef GL_SGIX_texture_scale_bias + &__GLEW_SGIX_texture_scale_bias, +#endif +#ifdef GL_SGIX_texture_supersample + &__GLEW_SGIX_texture_supersample, +#endif +#ifdef GL_SGIX_vector_ops + &__GLEW_SGIX_vector_ops, +#endif +#ifdef GL_SGIX_vertex_array_object + &__GLEW_SGIX_vertex_array_object, +#endif +#ifdef GL_SGIX_vertex_preclip + &__GLEW_SGIX_vertex_preclip, +#endif +#ifdef GL_SGIX_vertex_preclip_hint + &__GLEW_SGIX_vertex_preclip_hint, +#endif +#ifdef GL_SGIX_ycrcb + &__GLEW_SGIX_ycrcb, +#endif +#ifdef GL_SGIX_ycrcb_subsample + &__GLEW_SGIX_ycrcb_subsample, +#endif +#ifdef GL_SGIX_ycrcba + &__GLEW_SGIX_ycrcba, +#endif +#ifdef GL_SGI_color_matrix + &__GLEW_SGI_color_matrix, +#endif +#ifdef GL_SGI_color_table + &__GLEW_SGI_color_table, +#endif +#ifdef GL_SGI_complex + &__GLEW_SGI_complex, +#endif +#ifdef GL_SGI_complex_type + &__GLEW_SGI_complex_type, +#endif +#ifdef GL_SGI_fft + &__GLEW_SGI_fft, +#endif +#ifdef GL_SGI_texture_color_table + &__GLEW_SGI_texture_color_table, +#endif +#ifdef GL_SUNX_constant_data + &__GLEW_SUNX_constant_data, +#endif +#ifdef GL_SUN_convolution_border_modes + &__GLEW_SUN_convolution_border_modes, +#endif +#ifdef GL_SUN_global_alpha + &__GLEW_SUN_global_alpha, +#endif +#ifdef GL_SUN_mesh_array + &__GLEW_SUN_mesh_array, +#endif +#ifdef GL_SUN_read_video_pixels + &__GLEW_SUN_read_video_pixels, +#endif +#ifdef GL_SUN_slice_accum + &__GLEW_SUN_slice_accum, +#endif +#ifdef GL_SUN_triangle_list + &__GLEW_SUN_triangle_list, +#endif +#ifdef GL_SUN_vertex + &__GLEW_SUN_vertex, +#endif +#ifdef GL_WIN_phong_shading + &__GLEW_WIN_phong_shading, +#endif +#ifdef GL_WIN_scene_markerXXX + &__GLEW_WIN_scene_markerXXX, +#endif +#ifdef GL_WIN_specular_fog + &__GLEW_WIN_specular_fog, +#endif +#ifdef GL_WIN_swap_hint + &__GLEW_WIN_swap_hint, +#endif + NULL +}; +static GLboolean _glewInit_GL_VERSION_1_2 (); +static GLboolean _glewInit_GL_VERSION_1_3 (); +static GLboolean _glewInit_GL_VERSION_1_4 (); +static GLboolean _glewInit_GL_VERSION_1_5 (); +static GLboolean _glewInit_GL_VERSION_2_0 (); +static GLboolean _glewInit_GL_VERSION_2_1 (); +static GLboolean _glewInit_GL_VERSION_3_0 (); +static GLboolean _glewInit_GL_VERSION_3_1 (); +static GLboolean _glewInit_GL_VERSION_3_2 (); +static GLboolean _glewInit_GL_VERSION_3_3 (); +static GLboolean _glewInit_GL_VERSION_4_0 (); +static GLboolean _glewInit_GL_VERSION_4_5 (); +static GLboolean _glewInit_GL_VERSION_4_6 (); +static GLboolean _glewInit_GL_3DFX_tbuffer (); +static GLboolean _glewInit_GL_AMD_debug_output (); +static GLboolean _glewInit_GL_AMD_draw_buffers_blend (); +static GLboolean _glewInit_GL_AMD_framebuffer_sample_positions (); +static GLboolean _glewInit_GL_AMD_interleaved_elements (); +static GLboolean _glewInit_GL_AMD_multi_draw_indirect (); +static GLboolean _glewInit_GL_AMD_name_gen_delete (); +static GLboolean _glewInit_GL_AMD_occlusion_query_event (); +static GLboolean _glewInit_GL_AMD_performance_monitor (); +static GLboolean _glewInit_GL_AMD_sample_positions (); +static GLboolean _glewInit_GL_AMD_sparse_texture (); +static GLboolean _glewInit_GL_AMD_stencil_operation_extended (); +static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator (); +static GLboolean _glewInit_GL_ANGLE_framebuffer_blit (); +static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample (); +static GLboolean _glewInit_GL_ANGLE_instanced_arrays (); +static GLboolean _glewInit_GL_ANGLE_timer_query (); +static GLboolean _glewInit_GL_ANGLE_translated_shader_source (); +static GLboolean _glewInit_GL_APPLE_copy_texture_levels (); +static GLboolean _glewInit_GL_APPLE_element_array (); +static GLboolean _glewInit_GL_APPLE_fence (); +static GLboolean _glewInit_GL_APPLE_flush_buffer_range (); +static GLboolean _glewInit_GL_APPLE_framebuffer_multisample (); +static GLboolean _glewInit_GL_APPLE_object_purgeable (); +static GLboolean _glewInit_GL_APPLE_sync (); +static GLboolean _glewInit_GL_APPLE_texture_range (); +static GLboolean _glewInit_GL_APPLE_vertex_array_object (); +static GLboolean _glewInit_GL_APPLE_vertex_array_range (); +static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators (); +static GLboolean _glewInit_GL_ARB_ES2_compatibility (); +static GLboolean _glewInit_GL_ARB_ES3_1_compatibility (); +static GLboolean _glewInit_GL_ARB_ES3_2_compatibility (); +static GLboolean _glewInit_GL_ARB_base_instance (); +static GLboolean _glewInit_GL_ARB_bindless_texture (); +static GLboolean _glewInit_GL_ARB_blend_func_extended (); +static GLboolean _glewInit_GL_ARB_buffer_storage (); +static GLboolean _glewInit_GL_ARB_cl_event (); +static GLboolean _glewInit_GL_ARB_clear_buffer_object (); +static GLboolean _glewInit_GL_ARB_clear_texture (); +static GLboolean _glewInit_GL_ARB_clip_control (); +static GLboolean _glewInit_GL_ARB_color_buffer_float (); +static GLboolean _glewInit_GL_ARB_compute_shader (); +static GLboolean _glewInit_GL_ARB_compute_variable_group_size (); +static GLboolean _glewInit_GL_ARB_copy_buffer (); +static GLboolean _glewInit_GL_ARB_copy_image (); +static GLboolean _glewInit_GL_ARB_debug_output (); +static GLboolean _glewInit_GL_ARB_direct_state_access (); +static GLboolean _glewInit_GL_ARB_draw_buffers (); +static GLboolean _glewInit_GL_ARB_draw_buffers_blend (); +static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex (); +static GLboolean _glewInit_GL_ARB_draw_indirect (); +static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments (); +static GLboolean _glewInit_GL_ARB_framebuffer_object (); +static GLboolean _glewInit_GL_ARB_geometry_shader4 (); +static GLboolean _glewInit_GL_ARB_get_program_binary (); +static GLboolean _glewInit_GL_ARB_get_texture_sub_image (); +static GLboolean _glewInit_GL_ARB_gl_spirv (); +static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 (); +static GLboolean _glewInit_GL_ARB_gpu_shader_int64 (); +static GLboolean _glewInit_GL_ARB_imaging (); +static GLboolean _glewInit_GL_ARB_indirect_parameters (); +static GLboolean _glewInit_GL_ARB_instanced_arrays (); +static GLboolean _glewInit_GL_ARB_internalformat_query (); +static GLboolean _glewInit_GL_ARB_internalformat_query2 (); +static GLboolean _glewInit_GL_ARB_invalidate_subdata (); +static GLboolean _glewInit_GL_ARB_map_buffer_range (); +static GLboolean _glewInit_GL_ARB_matrix_palette (); +static GLboolean _glewInit_GL_ARB_multi_bind (); +static GLboolean _glewInit_GL_ARB_multi_draw_indirect (); +static GLboolean _glewInit_GL_ARB_multisample (); +static GLboolean _glewInit_GL_ARB_multitexture (); +static GLboolean _glewInit_GL_ARB_occlusion_query (); +static GLboolean _glewInit_GL_ARB_parallel_shader_compile (); +static GLboolean _glewInit_GL_ARB_point_parameters (); +static GLboolean _glewInit_GL_ARB_polygon_offset_clamp (); +static GLboolean _glewInit_GL_ARB_program_interface_query (); +static GLboolean _glewInit_GL_ARB_provoking_vertex (); +static GLboolean _glewInit_GL_ARB_robustness (); +static GLboolean _glewInit_GL_ARB_sample_locations (); +static GLboolean _glewInit_GL_ARB_sample_shading (); +static GLboolean _glewInit_GL_ARB_sampler_objects (); +static GLboolean _glewInit_GL_ARB_separate_shader_objects (); +static GLboolean _glewInit_GL_ARB_shader_atomic_counters (); +static GLboolean _glewInit_GL_ARB_shader_image_load_store (); +static GLboolean _glewInit_GL_ARB_shader_objects (); +static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object (); +static GLboolean _glewInit_GL_ARB_shader_subroutine (); +static GLboolean _glewInit_GL_ARB_shading_language_include (); +static GLboolean _glewInit_GL_ARB_sparse_buffer (); +static GLboolean _glewInit_GL_ARB_sparse_texture (); +static GLboolean _glewInit_GL_ARB_sync (); +static GLboolean _glewInit_GL_ARB_tessellation_shader (); +static GLboolean _glewInit_GL_ARB_texture_barrier (); +static GLboolean _glewInit_GL_ARB_texture_buffer_object (); +static GLboolean _glewInit_GL_ARB_texture_buffer_range (); +static GLboolean _glewInit_GL_ARB_texture_compression (); +static GLboolean _glewInit_GL_ARB_texture_multisample (); +static GLboolean _glewInit_GL_ARB_texture_storage (); +static GLboolean _glewInit_GL_ARB_texture_storage_multisample (); +static GLboolean _glewInit_GL_ARB_texture_view (); +static GLboolean _glewInit_GL_ARB_timer_query (); +static GLboolean _glewInit_GL_ARB_transform_feedback2 (); +static GLboolean _glewInit_GL_ARB_transform_feedback3 (); +static GLboolean _glewInit_GL_ARB_transform_feedback_instanced (); +static GLboolean _glewInit_GL_ARB_transpose_matrix (); +static GLboolean _glewInit_GL_ARB_uniform_buffer_object (); +static GLboolean _glewInit_GL_ARB_vertex_array_object (); +static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit (); +static GLboolean _glewInit_GL_ARB_vertex_attrib_binding (); +static GLboolean _glewInit_GL_ARB_vertex_blend (); +static GLboolean _glewInit_GL_ARB_vertex_buffer_object (); +static GLboolean _glewInit_GL_ARB_vertex_program (); +static GLboolean _glewInit_GL_ARB_vertex_shader (); +static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev (); +static GLboolean _glewInit_GL_ARB_viewport_array (); +static GLboolean _glewInit_GL_ARB_window_pos (); +static GLboolean _glewInit_GL_ATI_draw_buffers (); +static GLboolean _glewInit_GL_ATI_element_array (); +static GLboolean _glewInit_GL_ATI_envmap_bumpmap (); +static GLboolean _glewInit_GL_ATI_fragment_shader (); +static GLboolean _glewInit_GL_ATI_map_object_buffer (); +static GLboolean _glewInit_GL_ATI_pn_triangles (); +static GLboolean _glewInit_GL_ATI_separate_stencil (); +static GLboolean _glewInit_GL_ATI_vertex_array_object (); +static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object (); +static GLboolean _glewInit_GL_ATI_vertex_streams (); +static GLboolean _glewInit_GL_EXT_base_instance (); +static GLboolean _glewInit_GL_EXT_bindable_uniform (); +static GLboolean _glewInit_GL_EXT_blend_color (); +static GLboolean _glewInit_GL_EXT_blend_equation_separate (); +static GLboolean _glewInit_GL_EXT_blend_func_extended (); +static GLboolean _glewInit_GL_EXT_blend_func_separate (); +static GLboolean _glewInit_GL_EXT_blend_minmax (); +static GLboolean _glewInit_GL_EXT_buffer_storage (); +static GLboolean _glewInit_GL_EXT_clear_texture (); +static GLboolean _glewInit_GL_EXT_color_subtable (); +static GLboolean _glewInit_GL_EXT_compiled_vertex_array (); +static GLboolean _glewInit_GL_EXT_convolution (); +static GLboolean _glewInit_GL_EXT_coordinate_frame (); +static GLboolean _glewInit_GL_EXT_copy_image (); +static GLboolean _glewInit_GL_EXT_copy_texture (); +static GLboolean _glewInit_GL_EXT_cull_vertex (); +static GLboolean _glewInit_GL_EXT_debug_label (); +static GLboolean _glewInit_GL_EXT_debug_marker (); +static GLboolean _glewInit_GL_EXT_depth_bounds_test (); +static GLboolean _glewInit_GL_EXT_direct_state_access (); +static GLboolean _glewInit_GL_EXT_discard_framebuffer (); +static GLboolean _glewInit_GL_EXT_draw_buffers (); +static GLboolean _glewInit_GL_EXT_draw_buffers2 (); +static GLboolean _glewInit_GL_EXT_draw_buffers_indexed (); +static GLboolean _glewInit_GL_EXT_draw_elements_base_vertex (); +static GLboolean _glewInit_GL_EXT_draw_instanced (); +static GLboolean _glewInit_GL_EXT_draw_range_elements (); +static GLboolean _glewInit_GL_EXT_external_buffer (); +static GLboolean _glewInit_GL_EXT_fog_coord (); +static GLboolean _glewInit_GL_EXT_fragment_lighting (); +static GLboolean _glewInit_GL_EXT_framebuffer_blit (); +static GLboolean _glewInit_GL_EXT_framebuffer_multisample (); +static GLboolean _glewInit_GL_EXT_framebuffer_object (); +static GLboolean _glewInit_GL_EXT_geometry_shader4 (); +static GLboolean _glewInit_GL_EXT_gpu_program_parameters (); +static GLboolean _glewInit_GL_EXT_gpu_shader4 (); +static GLboolean _glewInit_GL_EXT_histogram (); +static GLboolean _glewInit_GL_EXT_index_func (); +static GLboolean _glewInit_GL_EXT_index_material (); +static GLboolean _glewInit_GL_EXT_instanced_arrays (); +static GLboolean _glewInit_GL_EXT_light_texture (); +static GLboolean _glewInit_GL_EXT_map_buffer_range (); +static GLboolean _glewInit_GL_EXT_memory_object (); +static GLboolean _glewInit_GL_EXT_memory_object_fd (); +static GLboolean _glewInit_GL_EXT_memory_object_win32 (); +static GLboolean _glewInit_GL_EXT_multi_draw_arrays (); +static GLboolean _glewInit_GL_EXT_multi_draw_indirect (); +static GLboolean _glewInit_GL_EXT_multisample (); +static GLboolean _glewInit_GL_EXT_multisampled_render_to_texture (); +static GLboolean _glewInit_GL_EXT_multiview_draw_buffers (); +static GLboolean _glewInit_GL_EXT_paletted_texture (); +static GLboolean _glewInit_GL_EXT_pixel_transform (); +static GLboolean _glewInit_GL_EXT_point_parameters (); +static GLboolean _glewInit_GL_EXT_polygon_offset (); +static GLboolean _glewInit_GL_EXT_polygon_offset_clamp (); +static GLboolean _glewInit_GL_EXT_provoking_vertex (); +static GLboolean _glewInit_GL_EXT_raster_multisample (); +static GLboolean _glewInit_GL_EXT_scene_marker (); +static GLboolean _glewInit_GL_EXT_secondary_color (); +static GLboolean _glewInit_GL_EXT_semaphore (); +static GLboolean _glewInit_GL_EXT_semaphore_fd (); +static GLboolean _glewInit_GL_EXT_semaphore_win32 (); +static GLboolean _glewInit_GL_EXT_separate_shader_objects (); +static GLboolean _glewInit_GL_EXT_shader_image_load_store (); +static GLboolean _glewInit_GL_EXT_shader_pixel_local_storage2 (); +static GLboolean _glewInit_GL_EXT_sparse_texture (); +static GLboolean _glewInit_GL_EXT_stencil_two_side (); +static GLboolean _glewInit_GL_EXT_subtexture (); +static GLboolean _glewInit_GL_EXT_texture3D (); +static GLboolean _glewInit_GL_EXT_texture_array (); +static GLboolean _glewInit_GL_EXT_texture_buffer_object (); +static GLboolean _glewInit_GL_EXT_texture_integer (); +static GLboolean _glewInit_GL_EXT_texture_object (); +static GLboolean _glewInit_GL_EXT_texture_perturb_normal (); +static GLboolean _glewInit_GL_EXT_texture_storage (); +static GLboolean _glewInit_GL_EXT_texture_view (); +static GLboolean _glewInit_GL_EXT_timer_query (); +static GLboolean _glewInit_GL_EXT_transform_feedback (); +static GLboolean _glewInit_GL_EXT_vertex_array (); +static GLboolean _glewInit_GL_EXT_vertex_array_setXXX (); +static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit (); +static GLboolean _glewInit_GL_EXT_vertex_shader (); +static GLboolean _glewInit_GL_EXT_vertex_weighting (); +static GLboolean _glewInit_GL_EXT_win32_keyed_mutex (); +static GLboolean _glewInit_GL_EXT_window_rectangles (); +static GLboolean _glewInit_GL_EXT_x11_sync_object (); +static GLboolean _glewInit_GL_GREMEDY_frame_terminator (); +static GLboolean _glewInit_GL_GREMEDY_string_marker (); +static GLboolean _glewInit_GL_HP_image_transform (); +static GLboolean _glewInit_GL_IBM_multimode_draw_arrays (); +static GLboolean _glewInit_GL_IBM_vertex_array_lists (); +static GLboolean _glewInit_GL_INTEL_map_texture (); +static GLboolean _glewInit_GL_INTEL_parallel_arrays (); +static GLboolean _glewInit_GL_INTEL_performance_query (); +static GLboolean _glewInit_GL_INTEL_texture_scissor (); +static GLboolean _glewInit_GL_KHR_blend_equation_advanced (); +static GLboolean _glewInit_GL_KHR_debug (); +static GLboolean _glewInit_GL_KHR_parallel_shader_compile (); +static GLboolean _glewInit_GL_KHR_robustness (); +static GLboolean _glewInit_GL_KTX_buffer_region (); +static GLboolean _glewInit_GL_MESA_resize_buffers (); +static GLboolean _glewInit_GL_MESA_window_pos (); +static GLboolean _glewInit_GL_NVX_conditional_render (); +static GLboolean _glewInit_GL_NVX_linked_gpu_multicast (); +static GLboolean _glewInit_GL_NV_3dvision_settings (); +static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect (); +static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect_count (); +static GLboolean _glewInit_GL_NV_bindless_texture (); +static GLboolean _glewInit_GL_NV_blend_equation_advanced (); +static GLboolean _glewInit_GL_NV_clip_space_w_scaling (); +static GLboolean _glewInit_GL_NV_command_list (); +static GLboolean _glewInit_GL_NV_conditional_render (); +static GLboolean _glewInit_GL_NV_conservative_raster (); +static GLboolean _glewInit_GL_NV_conservative_raster_dilate (); +static GLboolean _glewInit_GL_NV_conservative_raster_pre_snap_triangles (); +static GLboolean _glewInit_GL_NV_copy_buffer (); +static GLboolean _glewInit_GL_NV_copy_image (); +static GLboolean _glewInit_GL_NV_depth_buffer_float (); +static GLboolean _glewInit_GL_NV_draw_buffers (); +static GLboolean _glewInit_GL_NV_draw_instanced (); +static GLboolean _glewInit_GL_NV_draw_texture (); +static GLboolean _glewInit_GL_NV_draw_vulkan_image (); +static GLboolean _glewInit_GL_NV_evaluators (); +static GLboolean _glewInit_GL_NV_explicit_multisample (); +static GLboolean _glewInit_GL_NV_fence (); +static GLboolean _glewInit_GL_NV_fragment_coverage_to_color (); +static GLboolean _glewInit_GL_NV_fragment_program (); +static GLboolean _glewInit_GL_NV_framebuffer_blit (); +static GLboolean _glewInit_GL_NV_framebuffer_multisample (); +static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage (); +static GLboolean _glewInit_GL_NV_geometry_program4 (); +static GLboolean _glewInit_GL_NV_gpu_multicast (); +static GLboolean _glewInit_GL_NV_gpu_program4 (); +static GLboolean _glewInit_GL_NV_gpu_shader5 (); +static GLboolean _glewInit_GL_NV_half_float (); +static GLboolean _glewInit_GL_NV_instanced_arrays (); +static GLboolean _glewInit_GL_NV_internalformat_sample_query (); +static GLboolean _glewInit_GL_NV_non_square_matrices (); +static GLboolean _glewInit_GL_NV_occlusion_query (); +static GLboolean _glewInit_GL_NV_parameter_buffer_object (); +static GLboolean _glewInit_GL_NV_path_rendering (); +static GLboolean _glewInit_GL_NV_pixel_data_range (); +static GLboolean _glewInit_GL_NV_point_sprite (); +static GLboolean _glewInit_GL_NV_polygon_mode (); +static GLboolean _glewInit_GL_NV_present_video (); +static GLboolean _glewInit_GL_NV_primitive_restart (); +static GLboolean _glewInit_GL_NV_register_combiners (); +static GLboolean _glewInit_GL_NV_register_combiners2 (); +static GLboolean _glewInit_GL_NV_sample_locations (); +static GLboolean _glewInit_GL_NV_shader_buffer_load (); +static GLboolean _glewInit_GL_NV_texture_array (); +static GLboolean _glewInit_GL_NV_texture_barrier (); +static GLboolean _glewInit_GL_NV_texture_multisample (); +static GLboolean _glewInit_GL_NV_transform_feedback (); +static GLboolean _glewInit_GL_NV_transform_feedback2 (); +static GLboolean _glewInit_GL_NV_vdpau_interop (); +static GLboolean _glewInit_GL_NV_vertex_array_range (); +static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit (); +static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory (); +static GLboolean _glewInit_GL_NV_vertex_program (); +static GLboolean _glewInit_GL_NV_video_capture (); +static GLboolean _glewInit_GL_NV_viewport_array (); +static GLboolean _glewInit_GL_NV_viewport_swizzle (); +static GLboolean _glewInit_GL_OVR_multiview (); +static GLboolean _glewInit_GL_OVR_multiview_multisampled_render_to_texture (); +static GLboolean _glewInit_GL_QCOM_alpha_test (); +static GLboolean _glewInit_GL_QCOM_driver_control (); +static GLboolean _glewInit_GL_QCOM_extended_get (); +static GLboolean _glewInit_GL_QCOM_extended_get2 (); +static GLboolean _glewInit_GL_QCOM_framebuffer_foveated (); +static GLboolean _glewInit_GL_QCOM_shader_framebuffer_fetch_noncoherent (); +static GLboolean _glewInit_GL_QCOM_tiled_rendering (); +static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility (); +static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility (); +static GLboolean _glewInit_GL_REGAL_error_string (); +static GLboolean _glewInit_GL_REGAL_extension_query (); +static GLboolean _glewInit_GL_REGAL_log (); +static GLboolean _glewInit_GL_REGAL_proc_address (); +static GLboolean _glewInit_GL_SGIS_detail_texture (); +static GLboolean _glewInit_GL_SGIS_fog_function (); +static GLboolean _glewInit_GL_SGIS_multisample (); +static GLboolean _glewInit_GL_SGIS_multitexture (); +static GLboolean _glewInit_GL_SGIS_shared_multisample (); +static GLboolean _glewInit_GL_SGIS_sharpen_texture (); +static GLboolean _glewInit_GL_SGIS_texture4D (); +static GLboolean _glewInit_GL_SGIS_texture_filter4 (); +static GLboolean _glewInit_GL_SGIX_async (); +static GLboolean _glewInit_GL_SGIX_datapipe (); +static GLboolean _glewInit_GL_SGIX_flush_raster (); +static GLboolean _glewInit_GL_SGIX_fog_layers (); +static GLboolean _glewInit_GL_SGIX_fog_texture (); +static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting (); +static GLboolean _glewInit_GL_SGIX_framezoom (); +static GLboolean _glewInit_GL_SGIX_igloo_interface (); +static GLboolean _glewInit_GL_SGIX_mpeg1 (); +static GLboolean _glewInit_GL_SGIX_nonlinear_lighting_pervertex (); +static GLboolean _glewInit_GL_SGIX_pixel_texture (); +static GLboolean _glewInit_GL_SGIX_polynomial_ffd (); +static GLboolean _glewInit_GL_SGIX_quad_mesh (); +static GLboolean _glewInit_GL_SGIX_reference_plane (); +static GLboolean _glewInit_GL_SGIX_sprite (); +static GLboolean _glewInit_GL_SGIX_tag_sample_buffer (); +static GLboolean _glewInit_GL_SGIX_vector_ops (); +static GLboolean _glewInit_GL_SGIX_vertex_array_object (); +static GLboolean _glewInit_GL_SGI_color_table (); +static GLboolean _glewInit_GL_SGI_fft (); +static GLboolean _glewInit_GL_SUNX_constant_data (); +static GLboolean _glewInit_GL_SUN_global_alpha (); +static GLboolean _glewInit_GL_SUN_read_video_pixels (); +static GLboolean _glewInit_GL_SUN_triangle_list (); +static GLboolean _glewInit_GL_SUN_vertex (); +static GLboolean _glewInit_GL_WIN_swap_hint (); + +#ifdef GL_VERSION_1_2 + +static GLboolean _glewInit_GL_VERSION_1_2 () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3D")) == NULL) || r; + r = ((glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElements")) == NULL) || r; + r = ((glTexImage3D = (PFNGLTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexImage3D")) == NULL) || r; + r = ((glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3D")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_2 */ + +#ifdef GL_VERSION_1_3 + +static GLboolean _glewInit_GL_VERSION_1_3 () +{ + GLboolean r = GL_FALSE; + + r = ((glActiveTexture = (PFNGLACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glActiveTexture")) == NULL) || r; + r = ((glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTexture")) == NULL) || r; + r = ((glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1D")) == NULL) || r; + r = ((glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2D")) == NULL) || r; + r = ((glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3D")) == NULL) || r; + r = ((glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1D")) == NULL) || r; + r = ((glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2D")) == NULL) || r; + r = ((glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3D")) == NULL) || r; + r = ((glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImage")) == NULL) || r; + r = ((glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixd")) == NULL) || r; + r = ((glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixf")) == NULL) || r; + r = ((glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixd")) == NULL) || r; + r = ((glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixf")) == NULL) || r; + r = ((glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1d")) == NULL) || r; + r = ((glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dv")) == NULL) || r; + r = ((glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1f")) == NULL) || r; + r = ((glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fv")) == NULL) || r; + r = ((glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1i")) == NULL) || r; + r = ((glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iv")) == NULL) || r; + r = ((glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1s")) == NULL) || r; + r = ((glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sv")) == NULL) || r; + r = ((glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2d")) == NULL) || r; + r = ((glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dv")) == NULL) || r; + r = ((glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2f")) == NULL) || r; + r = ((glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fv")) == NULL) || r; + r = ((glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2i")) == NULL) || r; + r = ((glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iv")) == NULL) || r; + r = ((glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2s")) == NULL) || r; + r = ((glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sv")) == NULL) || r; + r = ((glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3d")) == NULL) || r; + r = ((glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dv")) == NULL) || r; + r = ((glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3f")) == NULL) || r; + r = ((glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fv")) == NULL) || r; + r = ((glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3i")) == NULL) || r; + r = ((glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iv")) == NULL) || r; + r = ((glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3s")) == NULL) || r; + r = ((glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sv")) == NULL) || r; + r = ((glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4d")) == NULL) || r; + r = ((glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dv")) == NULL) || r; + r = ((glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4f")) == NULL) || r; + r = ((glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fv")) == NULL) || r; + r = ((glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4i")) == NULL) || r; + r = ((glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iv")) == NULL) || r; + r = ((glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4s")) == NULL) || r; + r = ((glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sv")) == NULL) || r; + r = ((glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverage")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_3 */ + +#ifdef GL_VERSION_1_4 + +static GLboolean _glewInit_GL_VERSION_1_4 () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendColor = (PFNGLBLENDCOLORPROC)glewGetProcAddress((const GLubyte*)"glBlendColor")) == NULL) || r; + r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; + r = ((glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparate")) == NULL) || r; + r = ((glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointer")) == NULL) || r; + r = ((glFogCoordd = (PFNGLFOGCOORDDPROC)glewGetProcAddress((const GLubyte*)"glFogCoordd")) == NULL) || r; + r = ((glFogCoorddv = (PFNGLFOGCOORDDVPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddv")) == NULL) || r; + r = ((glFogCoordf = (PFNGLFOGCOORDFPROC)glewGetProcAddress((const GLubyte*)"glFogCoordf")) == NULL) || r; + r = ((glFogCoordfv = (PFNGLFOGCOORDFVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfv")) == NULL) || r; + r = ((glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArrays")) == NULL) || r; + r = ((glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElements")) == NULL) || r; + r = ((glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glPointParameterf")) == NULL) || r; + r = ((glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfv")) == NULL) || r; + r = ((glPointParameteri = (PFNGLPOINTPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPointParameteri")) == NULL) || r; + r = ((glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriv")) == NULL) || r; + r = ((glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3b")) == NULL) || r; + r = ((glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bv")) == NULL) || r; + r = ((glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3d")) == NULL) || r; + r = ((glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dv")) == NULL) || r; + r = ((glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3f")) == NULL) || r; + r = ((glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fv")) == NULL) || r; + r = ((glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3i")) == NULL) || r; + r = ((glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iv")) == NULL) || r; + r = ((glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3s")) == NULL) || r; + r = ((glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sv")) == NULL) || r; + r = ((glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ub")) == NULL) || r; + r = ((glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubv")) == NULL) || r; + r = ((glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ui")) == NULL) || r; + r = ((glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiv")) == NULL) || r; + r = ((glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3us")) == NULL) || r; + r = ((glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usv")) == NULL) || r; + r = ((glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointer")) == NULL) || r; + r = ((glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2d")) == NULL) || r; + r = ((glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dv")) == NULL) || r; + r = ((glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2f")) == NULL) || r; + r = ((glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fv")) == NULL) || r; + r = ((glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2i")) == NULL) || r; + r = ((glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iv")) == NULL) || r; + r = ((glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2s")) == NULL) || r; + r = ((glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sv")) == NULL) || r; + r = ((glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3d")) == NULL) || r; + r = ((glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dv")) == NULL) || r; + r = ((glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3f")) == NULL) || r; + r = ((glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fv")) == NULL) || r; + r = ((glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3i")) == NULL) || r; + r = ((glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iv")) == NULL) || r; + r = ((glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3s")) == NULL) || r; + r = ((glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sv")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_4 */ + +#ifdef GL_VERSION_1_5 + +static GLboolean _glewInit_GL_VERSION_1_5 () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQuery = (PFNGLBEGINQUERYPROC)glewGetProcAddress((const GLubyte*)"glBeginQuery")) == NULL) || r; + r = ((glBindBuffer = (PFNGLBINDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindBuffer")) == NULL) || r; + r = ((glBufferData = (PFNGLBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferData")) == NULL) || r; + r = ((glBufferSubData = (PFNGLBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferSubData")) == NULL) || r; + r = ((glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffers")) == NULL) || r; + r = ((glDeleteQueries = (PFNGLDELETEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueries")) == NULL) || r; + r = ((glEndQuery = (PFNGLENDQUERYPROC)glewGetProcAddress((const GLubyte*)"glEndQuery")) == NULL) || r; + r = ((glGenBuffers = (PFNGLGENBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenBuffers")) == NULL) || r; + r = ((glGenQueries = (PFNGLGENQUERIESPROC)glewGetProcAddress((const GLubyte*)"glGenQueries")) == NULL) || r; + r = ((glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteriv")) == NULL) || r; + r = ((glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointerv")) == NULL) || r; + r = ((glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubData")) == NULL) || r; + r = ((glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectiv")) == NULL) || r; + r = ((glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuiv")) == NULL) || r; + r = ((glGetQueryiv = (PFNGLGETQUERYIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryiv")) == NULL) || r; + r = ((glIsBuffer = (PFNGLISBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsBuffer")) == NULL) || r; + r = ((glIsQuery = (PFNGLISQUERYPROC)glewGetProcAddress((const GLubyte*)"glIsQuery")) == NULL) || r; + r = ((glMapBuffer = (PFNGLMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapBuffer")) == NULL) || r; + r = ((glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapBuffer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_1_5 */ + +#ifdef GL_VERSION_2_0 + +static GLboolean _glewInit_GL_VERSION_2_0 () +{ + GLboolean r = GL_FALSE; + + r = ((glAttachShader = (PFNGLATTACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glAttachShader")) == NULL) || r; + r = ((glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocation")) == NULL) || r; + r = ((glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparate")) == NULL) || r; + r = ((glCompileShader = (PFNGLCOMPILESHADERPROC)glewGetProcAddress((const GLubyte*)"glCompileShader")) == NULL) || r; + r = ((glCreateProgram = (PFNGLCREATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glCreateProgram")) == NULL) || r; + r = ((glCreateShader = (PFNGLCREATESHADERPROC)glewGetProcAddress((const GLubyte*)"glCreateShader")) == NULL) || r; + r = ((glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgram")) == NULL) || r; + r = ((glDeleteShader = (PFNGLDELETESHADERPROC)glewGetProcAddress((const GLubyte*)"glDeleteShader")) == NULL) || r; + r = ((glDetachShader = (PFNGLDETACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glDetachShader")) == NULL) || r; + r = ((glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArray")) == NULL) || r; + r = ((glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffers")) == NULL) || r; + r = ((glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArray")) == NULL) || r; + r = ((glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttrib")) == NULL) || r; + r = ((glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniform")) == NULL) || r; + r = ((glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedShaders")) == NULL) || r; + r = ((glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocation")) == NULL) || r; + r = ((glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInfoLog")) == NULL) || r; + r = ((glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramiv")) == NULL) || r; + r = ((glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetShaderInfoLog")) == NULL) || r; + r = ((glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSource")) == NULL) || r; + r = ((glGetShaderiv = (PFNGLGETSHADERIVPROC)glewGetProcAddress((const GLubyte*)"glGetShaderiv")) == NULL) || r; + r = ((glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocation")) == NULL) || r; + r = ((glGetUniformfv = (PFNGLGETUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfv")) == NULL) || r; + r = ((glGetUniformiv = (PFNGLGETUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformiv")) == NULL) || r; + r = ((glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointerv")) == NULL) || r; + r = ((glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdv")) == NULL) || r; + r = ((glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfv")) == NULL) || r; + r = ((glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribiv")) == NULL) || r; + r = ((glIsProgram = (PFNGLISPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glIsProgram")) == NULL) || r; + r = ((glIsShader = (PFNGLISSHADERPROC)glewGetProcAddress((const GLubyte*)"glIsShader")) == NULL) || r; + r = ((glLinkProgram = (PFNGLLINKPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glLinkProgram")) == NULL) || r; + r = ((glShaderSource = (PFNGLSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glShaderSource")) == NULL) || r; + r = ((glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparate")) == NULL) || r; + r = ((glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilMaskSeparate")) == NULL) || r; + r = ((glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparate")) == NULL) || r; + r = ((glUniform1f = (PFNGLUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glUniform1f")) == NULL) || r; + r = ((glUniform1fv = (PFNGLUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glUniform1fv")) == NULL) || r; + r = ((glUniform1i = (PFNGLUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glUniform1i")) == NULL) || r; + r = ((glUniform1iv = (PFNGLUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glUniform1iv")) == NULL) || r; + r = ((glUniform2f = (PFNGLUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glUniform2f")) == NULL) || r; + r = ((glUniform2fv = (PFNGLUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glUniform2fv")) == NULL) || r; + r = ((glUniform2i = (PFNGLUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glUniform2i")) == NULL) || r; + r = ((glUniform2iv = (PFNGLUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glUniform2iv")) == NULL) || r; + r = ((glUniform3f = (PFNGLUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glUniform3f")) == NULL) || r; + r = ((glUniform3fv = (PFNGLUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glUniform3fv")) == NULL) || r; + r = ((glUniform3i = (PFNGLUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glUniform3i")) == NULL) || r; + r = ((glUniform3iv = (PFNGLUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glUniform3iv")) == NULL) || r; + r = ((glUniform4f = (PFNGLUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glUniform4f")) == NULL) || r; + r = ((glUniform4fv = (PFNGLUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glUniform4fv")) == NULL) || r; + r = ((glUniform4i = (PFNGLUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glUniform4i")) == NULL) || r; + r = ((glUniform4iv = (PFNGLUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glUniform4iv")) == NULL) || r; + r = ((glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fv")) == NULL) || r; + r = ((glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fv")) == NULL) || r; + r = ((glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fv")) == NULL) || r; + r = ((glUseProgram = (PFNGLUSEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glUseProgram")) == NULL) || r; + r = ((glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glValidateProgram")) == NULL) || r; + r = ((glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1d")) == NULL) || r; + r = ((glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dv")) == NULL) || r; + r = ((glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1f")) == NULL) || r; + r = ((glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fv")) == NULL) || r; + r = ((glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1s")) == NULL) || r; + r = ((glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sv")) == NULL) || r; + r = ((glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2d")) == NULL) || r; + r = ((glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dv")) == NULL) || r; + r = ((glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2f")) == NULL) || r; + r = ((glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fv")) == NULL) || r; + r = ((glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2s")) == NULL) || r; + r = ((glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sv")) == NULL) || r; + r = ((glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3d")) == NULL) || r; + r = ((glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dv")) == NULL) || r; + r = ((glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3f")) == NULL) || r; + r = ((glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fv")) == NULL) || r; + r = ((glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3s")) == NULL) || r; + r = ((glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sv")) == NULL) || r; + r = ((glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nbv")) == NULL) || r; + r = ((glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Niv")) == NULL) || r; + r = ((glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nsv")) == NULL) || r; + r = ((glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nub")) == NULL) || r; + r = ((glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nubv")) == NULL) || r; + r = ((glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nuiv")) == NULL) || r; + r = ((glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nusv")) == NULL) || r; + r = ((glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bv")) == NULL) || r; + r = ((glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4d")) == NULL) || r; + r = ((glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dv")) == NULL) || r; + r = ((glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4f")) == NULL) || r; + r = ((glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fv")) == NULL) || r; + r = ((glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4iv")) == NULL) || r; + r = ((glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4s")) == NULL) || r; + r = ((glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sv")) == NULL) || r; + r = ((glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubv")) == NULL) || r; + r = ((glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uiv")) == NULL) || r; + r = ((glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usv")) == NULL) || r; + r = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_2_0 */ + +#ifdef GL_VERSION_2_1 + +static GLboolean _glewInit_GL_VERSION_2_1 () +{ + GLboolean r = GL_FALSE; + + r = ((glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3fv")) == NULL) || r; + r = ((glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4fv")) == NULL) || r; + r = ((glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2fv")) == NULL) || r; + r = ((glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4fv")) == NULL) || r; + r = ((glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2fv")) == NULL) || r; + r = ((glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3fv")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_2_1 */ + +#ifdef GL_VERSION_3_0 + +static GLboolean _glewInit_GL_VERSION_3_0 () +{ + GLboolean r = GL_FALSE; + + r = _glewInit_GL_ARB_framebuffer_object() || r; + r = _glewInit_GL_ARB_map_buffer_range() || r; + r = _glewInit_GL_ARB_uniform_buffer_object() || r; + r = _glewInit_GL_ARB_vertex_array_object() || r; + + r = ((glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRender")) == NULL) || r; + r = ((glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedback")) == NULL) || r; + r = ((glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocation")) == NULL) || r; + r = ((glClampColor = (PFNGLCLAMPCOLORPROC)glewGetProcAddress((const GLubyte*)"glClampColor")) == NULL) || r; + r = ((glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfi")) == NULL) || r; + r = ((glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfv")) == NULL) || r; + r = ((glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferiv")) == NULL) || r; + r = ((glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferuiv")) == NULL) || r; + r = ((glColorMaski = (PFNGLCOLORMASKIPROC)glewGetProcAddress((const GLubyte*)"glColorMaski")) == NULL) || r; + r = ((glDisablei = (PFNGLDISABLEIPROC)glewGetProcAddress((const GLubyte*)"glDisablei")) == NULL) || r; + r = ((glEnablei = (PFNGLENABLEIPROC)glewGetProcAddress((const GLubyte*)"glEnablei")) == NULL) || r; + r = ((glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRender")) == NULL) || r; + r = ((glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedback")) == NULL) || r; + r = ((glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)glewGetProcAddress((const GLubyte*)"glGetBooleani_v")) == NULL) || r; + r = ((glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocation")) == NULL) || r; + r = ((glGetStringi = (PFNGLGETSTRINGIPROC)glewGetProcAddress((const GLubyte*)"glGetStringi")) == NULL) || r; + r = ((glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIiv")) == NULL) || r; + r = ((glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuiv")) == NULL) || r; + r = ((glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVarying")) == NULL) || r; + r = ((glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuiv")) == NULL) || r; + r = ((glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIiv")) == NULL) || r; + r = ((glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuiv")) == NULL) || r; + r = ((glIsEnabledi = (PFNGLISENABLEDIPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledi")) == NULL) || r; + r = ((glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIiv")) == NULL) || r; + r = ((glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuiv")) == NULL) || r; + r = ((glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryings")) == NULL) || r; + r = ((glUniform1ui = (PFNGLUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui")) == NULL) || r; + r = ((glUniform1uiv = (PFNGLUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiv")) == NULL) || r; + r = ((glUniform2ui = (PFNGLUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui")) == NULL) || r; + r = ((glUniform2uiv = (PFNGLUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiv")) == NULL) || r; + r = ((glUniform3ui = (PFNGLUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui")) == NULL) || r; + r = ((glUniform3uiv = (PFNGLUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiv")) == NULL) || r; + r = ((glUniform4ui = (PFNGLUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui")) == NULL) || r; + r = ((glUniform4uiv = (PFNGLUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiv")) == NULL) || r; + r = ((glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1i")) == NULL) || r; + r = ((glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iv")) == NULL) || r; + r = ((glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ui")) == NULL) || r; + r = ((glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiv")) == NULL) || r; + r = ((glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2i")) == NULL) || r; + r = ((glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iv")) == NULL) || r; + r = ((glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ui")) == NULL) || r; + r = ((glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiv")) == NULL) || r; + r = ((glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3i")) == NULL) || r; + r = ((glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iv")) == NULL) || r; + r = ((glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ui")) == NULL) || r; + r = ((glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiv")) == NULL) || r; + r = ((glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bv")) == NULL) || r; + r = ((glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4i")) == NULL) || r; + r = ((glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iv")) == NULL) || r; + r = ((glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4sv")) == NULL) || r; + r = ((glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubv")) == NULL) || r; + r = ((glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ui")) == NULL) || r; + r = ((glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiv")) == NULL) || r; + r = ((glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usv")) == NULL) || r; + r = ((glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_0 */ + +#ifdef GL_VERSION_3_1 + +static GLboolean _glewInit_GL_VERSION_3_1 () +{ + GLboolean r = GL_FALSE; + + r = _glewInit_GL_ARB_copy_buffer() || r; + + r = ((glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstanced")) == NULL) || r; + r = ((glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstanced")) == NULL) || r; + r = ((glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndex")) == NULL) || r; + r = ((glTexBuffer = (PFNGLTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glTexBuffer")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_1 */ + +#ifdef GL_VERSION_3_2 + +static GLboolean _glewInit_GL_VERSION_3_2 () +{ + GLboolean r = GL_FALSE; + + r = _glewInit_GL_ARB_draw_elements_base_vertex() || r; + r = _glewInit_GL_ARB_provoking_vertex() || r; + r = _glewInit_GL_ARB_sync() || r; + r = _glewInit_GL_ARB_texture_multisample() || r; + + r = ((glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture")) == NULL) || r; + r = ((glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteri64v")) == NULL) || r; + r = ((glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64i_v")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_2 */ + +#ifdef GL_VERSION_3_3 + +static GLboolean _glewInit_GL_VERSION_3_3 () +{ + GLboolean r = GL_FALSE; + + r = ((glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisor")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_3_3 */ + +#ifdef GL_VERSION_4_0 + +static GLboolean _glewInit_GL_VERSION_4_0 () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparatei")) == NULL) || r; + r = ((glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationi")) == NULL) || r; + r = ((glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparatei")) == NULL) || r; + r = ((glBlendFunci = (PFNGLBLENDFUNCIPROC)glewGetProcAddress((const GLubyte*)"glBlendFunci")) == NULL) || r; + r = ((glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShading")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_4_0 */ + +#ifdef GL_VERSION_4_5 + +static GLboolean _glewInit_GL_VERSION_4_5 () +{ + GLboolean r = GL_FALSE; + + r = ((glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC)glewGetProcAddress((const GLubyte*)"glGetGraphicsResetStatus")) == NULL) || r; + r = ((glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetnCompressedTexImage")) == NULL) || r; + r = ((glGetnTexImage = (PFNGLGETNTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetnTexImage")) == NULL) || r; + r = ((glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformdv")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_4_5 */ + +#ifdef GL_VERSION_4_6 + +static GLboolean _glewInit_GL_VERSION_4_6 () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectCount")) == NULL) || r; + r = ((glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectCount")) == NULL) || r; + r = ((glSpecializeShader = (PFNGLSPECIALIZESHADERPROC)glewGetProcAddress((const GLubyte*)"glSpecializeShader")) == NULL) || r; + + return r; +} + +#endif /* GL_VERSION_4_6 */ + +#ifdef GL_3DFX_tbuffer + +static GLboolean _glewInit_GL_3DFX_tbuffer () +{ + GLboolean r = GL_FALSE; + + r = ((glTbufferMask3DFX = (PFNGLTBUFFERMASK3DFXPROC)glewGetProcAddress((const GLubyte*)"glTbufferMask3DFX")) == NULL) || r; + + return r; +} + +#endif /* GL_3DFX_tbuffer */ + +#ifdef GL_AMD_debug_output + +static GLboolean _glewInit_GL_AMD_debug_output () +{ + GLboolean r = GL_FALSE; + + r = ((glDebugMessageCallbackAMD = (PFNGLDEBUGMESSAGECALLBACKAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallbackAMD")) == NULL) || r; + r = ((glDebugMessageEnableAMD = (PFNGLDEBUGMESSAGEENABLEAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageEnableAMD")) == NULL) || r; + r = ((glDebugMessageInsertAMD = (PFNGLDEBUGMESSAGEINSERTAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsertAMD")) == NULL) || r; + r = ((glGetDebugMessageLogAMD = (PFNGLGETDEBUGMESSAGELOGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLogAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_debug_output */ + +#ifdef GL_AMD_draw_buffers_blend + +static GLboolean _glewInit_GL_AMD_draw_buffers_blend () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationIndexedAMD")) == NULL) || r; + r = ((glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateIndexedAMD")) == NULL) || r; + r = ((glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncIndexedAMD")) == NULL) || r; + r = ((glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateIndexedAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_draw_buffers_blend */ + +#ifdef GL_AMD_framebuffer_sample_positions + +static GLboolean _glewInit_GL_AMD_framebuffer_sample_positions () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)glewGetProcAddress((const GLubyte*)"glFramebufferSamplePositionsfvAMD")) == NULL) || r; + r = ((glGetFramebufferParameterfvAMD = (PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterfvAMD")) == NULL) || r; + r = ((glGetNamedFramebufferParameterfvAMD = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferParameterfvAMD")) == NULL) || r; + r = ((glNamedFramebufferSamplePositionsfvAMD = (PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferSamplePositionsfvAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_framebuffer_sample_positions */ + +#ifdef GL_AMD_interleaved_elements + +static GLboolean _glewInit_GL_AMD_interleaved_elements () +{ + GLboolean r = GL_FALSE; + + r = ((glVertexAttribParameteriAMD = (PFNGLVERTEXATTRIBPARAMETERIAMDPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribParameteriAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_interleaved_elements */ + +#ifdef GL_AMD_multi_draw_indirect + +static GLboolean _glewInit_GL_AMD_multi_draw_indirect () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectAMD = (PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectAMD")) == NULL) || r; + r = ((glMultiDrawElementsIndirectAMD = (PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_multi_draw_indirect */ + +#ifdef GL_AMD_name_gen_delete + +static GLboolean _glewInit_GL_AMD_name_gen_delete () +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteNamesAMD = (PFNGLDELETENAMESAMDPROC)glewGetProcAddress((const GLubyte*)"glDeleteNamesAMD")) == NULL) || r; + r = ((glGenNamesAMD = (PFNGLGENNAMESAMDPROC)glewGetProcAddress((const GLubyte*)"glGenNamesAMD")) == NULL) || r; + r = ((glIsNameAMD = (PFNGLISNAMEAMDPROC)glewGetProcAddress((const GLubyte*)"glIsNameAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_name_gen_delete */ + +#ifdef GL_AMD_occlusion_query_event + +static GLboolean _glewInit_GL_AMD_occlusion_query_event () +{ + GLboolean r = GL_FALSE; + + r = ((glQueryObjectParameteruiAMD = (PFNGLQUERYOBJECTPARAMETERUIAMDPROC)glewGetProcAddress((const GLubyte*)"glQueryObjectParameteruiAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_occlusion_query_event */ + +#ifdef GL_AMD_performance_monitor + +static GLboolean _glewInit_GL_AMD_performance_monitor () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginPerfMonitorAMD = (PFNGLBEGINPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glBeginPerfMonitorAMD")) == NULL) || r; + r = ((glDeletePerfMonitorsAMD = (PFNGLDELETEPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glDeletePerfMonitorsAMD")) == NULL) || r; + r = ((glEndPerfMonitorAMD = (PFNGLENDPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glEndPerfMonitorAMD")) == NULL) || r; + r = ((glGenPerfMonitorsAMD = (PFNGLGENPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glGenPerfMonitorsAMD")) == NULL) || r; + r = ((glGetPerfMonitorCounterDataAMD = (PFNGLGETPERFMONITORCOUNTERDATAAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterDataAMD")) == NULL) || r; + r = ((glGetPerfMonitorCounterInfoAMD = (PFNGLGETPERFMONITORCOUNTERINFOAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterInfoAMD")) == NULL) || r; + r = ((glGetPerfMonitorCounterStringAMD = (PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterStringAMD")) == NULL) || r; + r = ((glGetPerfMonitorCountersAMD = (PFNGLGETPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCountersAMD")) == NULL) || r; + r = ((glGetPerfMonitorGroupStringAMD = (PFNGLGETPERFMONITORGROUPSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupStringAMD")) == NULL) || r; + r = ((glGetPerfMonitorGroupsAMD = (PFNGLGETPERFMONITORGROUPSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupsAMD")) == NULL) || r; + r = ((glSelectPerfMonitorCountersAMD = (PFNGLSELECTPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glSelectPerfMonitorCountersAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_performance_monitor */ + +#ifdef GL_AMD_sample_positions + +static GLboolean _glewInit_GL_AMD_sample_positions () +{ + GLboolean r = GL_FALSE; + + r = ((glSetMultisamplefvAMD = (PFNGLSETMULTISAMPLEFVAMDPROC)glewGetProcAddress((const GLubyte*)"glSetMultisamplefvAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_sample_positions */ + +#ifdef GL_AMD_sparse_texture + +static GLboolean _glewInit_GL_AMD_sparse_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glTexStorageSparseAMD = (PFNGLTEXSTORAGESPARSEAMDPROC)glewGetProcAddress((const GLubyte*)"glTexStorageSparseAMD")) == NULL) || r; + r = ((glTextureStorageSparseAMD = (PFNGLTEXTURESTORAGESPARSEAMDPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageSparseAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_sparse_texture */ + +#ifdef GL_AMD_stencil_operation_extended + +static GLboolean _glewInit_GL_AMD_stencil_operation_extended () +{ + GLboolean r = GL_FALSE; + + r = ((glStencilOpValueAMD = (PFNGLSTENCILOPVALUEAMDPROC)glewGetProcAddress((const GLubyte*)"glStencilOpValueAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_stencil_operation_extended */ + +#ifdef GL_AMD_vertex_shader_tessellator + +static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator () +{ + GLboolean r = GL_FALSE; + + r = ((glTessellationFactorAMD = (PFNGLTESSELLATIONFACTORAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationFactorAMD")) == NULL) || r; + r = ((glTessellationModeAMD = (PFNGLTESSELLATIONMODEAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationModeAMD")) == NULL) || r; + + return r; +} + +#endif /* GL_AMD_vertex_shader_tessellator */ + +#ifdef GL_ANGLE_framebuffer_blit + +static GLboolean _glewInit_GL_ANGLE_framebuffer_blit () +{ + GLboolean r = GL_FALSE; + + r = ((glBlitFramebufferANGLE = (PFNGLBLITFRAMEBUFFERANGLEPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_framebuffer_blit */ + +#ifdef GL_ANGLE_framebuffer_multisample + +static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_framebuffer_multisample */ + +#ifdef GL_ANGLE_instanced_arrays + +static GLboolean _glewInit_GL_ANGLE_instanced_arrays () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedANGLE")) == NULL) || r; + r = ((glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedANGLE")) == NULL) || r; + r = ((glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_instanced_arrays */ + +#ifdef GL_ANGLE_timer_query + +static GLboolean _glewInit_GL_ANGLE_timer_query () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQueryANGLE = (PFNGLBEGINQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryANGLE")) == NULL) || r; + r = ((glDeleteQueriesANGLE = (PFNGLDELETEQUERIESANGLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesANGLE")) == NULL) || r; + r = ((glEndQueryANGLE = (PFNGLENDQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glEndQueryANGLE")) == NULL) || r; + r = ((glGenQueriesANGLE = (PFNGLGENQUERIESANGLEPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesANGLE")) == NULL) || r; + r = ((glGetQueryObjecti64vANGLE = (PFNGLGETQUERYOBJECTI64VANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vANGLE")) == NULL) || r; + r = ((glGetQueryObjectivANGLE = (PFNGLGETQUERYOBJECTIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivANGLE")) == NULL) || r; + r = ((glGetQueryObjectui64vANGLE = (PFNGLGETQUERYOBJECTUI64VANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vANGLE")) == NULL) || r; + r = ((glGetQueryObjectuivANGLE = (PFNGLGETQUERYOBJECTUIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivANGLE")) == NULL) || r; + r = ((glGetQueryivANGLE = (PFNGLGETQUERYIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivANGLE")) == NULL) || r; + r = ((glIsQueryANGLE = (PFNGLISQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glIsQueryANGLE")) == NULL) || r; + r = ((glQueryCounterANGLE = (PFNGLQUERYCOUNTERANGLEPROC)glewGetProcAddress((const GLubyte*)"glQueryCounterANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_timer_query */ + +#ifdef GL_ANGLE_translated_shader_source + +static GLboolean _glewInit_GL_ANGLE_translated_shader_source () +{ + GLboolean r = GL_FALSE; + + r = ((glGetTranslatedShaderSourceANGLE = (PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetTranslatedShaderSourceANGLE")) == NULL) || r; + + return r; +} + +#endif /* GL_ANGLE_translated_shader_source */ + +#ifdef GL_APPLE_copy_texture_levels + +static GLboolean _glewInit_GL_APPLE_copy_texture_levels () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTextureLevelsAPPLE = (PFNGLCOPYTEXTURELEVELSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureLevelsAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_copy_texture_levels */ + +#ifdef GL_APPLE_element_array + +static GLboolean _glewInit_GL_APPLE_element_array () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementArrayAPPLE = (PFNGLDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayAPPLE")) == NULL) || r; + r = ((glDrawRangeElementArrayAPPLE = (PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayAPPLE")) == NULL) || r; + r = ((glElementPointerAPPLE = (PFNGLELEMENTPOINTERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glElementPointerAPPLE")) == NULL) || r; + r = ((glMultiDrawElementArrayAPPLE = (PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementArrayAPPLE")) == NULL) || r; + r = ((glMultiDrawRangeElementArrayAPPLE = (PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawRangeElementArrayAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_element_array */ + +#ifdef GL_APPLE_fence + +static GLboolean _glewInit_GL_APPLE_fence () +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteFencesAPPLE = (PFNGLDELETEFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesAPPLE")) == NULL) || r; + r = ((glFinishFenceAPPLE = (PFNGLFINISHFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceAPPLE")) == NULL) || r; + r = ((glFinishObjectAPPLE = (PFNGLFINISHOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishObjectAPPLE")) == NULL) || r; + r = ((glGenFencesAPPLE = (PFNGLGENFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenFencesAPPLE")) == NULL) || r; + r = ((glIsFenceAPPLE = (PFNGLISFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsFenceAPPLE")) == NULL) || r; + r = ((glSetFenceAPPLE = (PFNGLSETFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glSetFenceAPPLE")) == NULL) || r; + r = ((glTestFenceAPPLE = (PFNGLTESTFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestFenceAPPLE")) == NULL) || r; + r = ((glTestObjectAPPLE = (PFNGLTESTOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestObjectAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_fence */ + +#ifdef GL_APPLE_flush_buffer_range + +static GLboolean _glewInit_GL_APPLE_flush_buffer_range () +{ + GLboolean r = GL_FALSE; + + r = ((glBufferParameteriAPPLE = (PFNGLBUFFERPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBufferParameteriAPPLE")) == NULL) || r; + r = ((glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_flush_buffer_range */ + +#ifdef GL_APPLE_framebuffer_multisample + +static GLboolean _glewInit_GL_APPLE_framebuffer_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleAPPLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleAPPLE")) == NULL) || r; + r = ((glResolveMultisampleFramebufferAPPLE = (PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glResolveMultisampleFramebufferAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_framebuffer_multisample */ + +#ifdef GL_APPLE_object_purgeable + +static GLboolean _glewInit_GL_APPLE_object_purgeable () +{ + GLboolean r = GL_FALSE; + + r = ((glGetObjectParameterivAPPLE = (PFNGLGETOBJECTPARAMETERIVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivAPPLE")) == NULL) || r; + r = ((glObjectPurgeableAPPLE = (PFNGLOBJECTPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectPurgeableAPPLE")) == NULL) || r; + r = ((glObjectUnpurgeableAPPLE = (PFNGLOBJECTUNPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectUnpurgeableAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_object_purgeable */ + +#ifdef GL_APPLE_sync + +static GLboolean _glewInit_GL_APPLE_sync () +{ + GLboolean r = GL_FALSE; + + r = ((glClientWaitSyncAPPLE = (PFNGLCLIENTWAITSYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glClientWaitSyncAPPLE")) == NULL) || r; + r = ((glDeleteSyncAPPLE = (PFNGLDELETESYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteSyncAPPLE")) == NULL) || r; + r = ((glFenceSyncAPPLE = (PFNGLFENCESYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFenceSyncAPPLE")) == NULL) || r; + r = ((glGetInteger64vAPPLE = (PFNGLGETINTEGER64VAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64vAPPLE")) == NULL) || r; + r = ((glGetSyncivAPPLE = (PFNGLGETSYNCIVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetSyncivAPPLE")) == NULL) || r; + r = ((glIsSyncAPPLE = (PFNGLISSYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsSyncAPPLE")) == NULL) || r; + r = ((glWaitSyncAPPLE = (PFNGLWAITSYNCAPPLEPROC)glewGetProcAddress((const GLubyte*)"glWaitSyncAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_sync */ + +#ifdef GL_APPLE_texture_range + +static GLboolean _glewInit_GL_APPLE_texture_range () +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexParameterPointervAPPLE = (PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterPointervAPPLE")) == NULL) || r; + r = ((glTextureRangeAPPLE = (PFNGLTEXTURERANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_texture_range */ + +#ifdef GL_APPLE_vertex_array_object + +static GLboolean _glewInit_GL_APPLE_vertex_array_object () +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexArrayAPPLE = (PFNGLBINDVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArrayAPPLE")) == NULL) || r; + r = ((glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysAPPLE")) == NULL) || r; + r = ((glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysAPPLE")) == NULL) || r; + r = ((glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArrayAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_array_object */ + +#ifdef GL_APPLE_vertex_array_range + +static GLboolean _glewInit_GL_APPLE_vertex_array_range () +{ + GLboolean r = GL_FALSE; + + r = ((glFlushVertexArrayRangeAPPLE = (PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeAPPLE")) == NULL) || r; + r = ((glVertexArrayParameteriAPPLE = (PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayParameteriAPPLE")) == NULL) || r; + r = ((glVertexArrayRangeAPPLE = (PFNGLVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_array_range */ + +#ifdef GL_APPLE_vertex_program_evaluators + +static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators () +{ + GLboolean r = GL_FALSE; + + r = ((glDisableVertexAttribAPPLE = (PFNGLDISABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribAPPLE")) == NULL) || r; + r = ((glEnableVertexAttribAPPLE = (PFNGLENABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribAPPLE")) == NULL) || r; + r = ((glIsVertexAttribEnabledAPPLE = (PFNGLISVERTEXATTRIBENABLEDAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexAttribEnabledAPPLE")) == NULL) || r; + r = ((glMapVertexAttrib1dAPPLE = (PFNGLMAPVERTEXATTRIB1DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1dAPPLE")) == NULL) || r; + r = ((glMapVertexAttrib1fAPPLE = (PFNGLMAPVERTEXATTRIB1FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1fAPPLE")) == NULL) || r; + r = ((glMapVertexAttrib2dAPPLE = (PFNGLMAPVERTEXATTRIB2DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2dAPPLE")) == NULL) || r; + r = ((glMapVertexAttrib2fAPPLE = (PFNGLMAPVERTEXATTRIB2FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2fAPPLE")) == NULL) || r; + + return r; +} + +#endif /* GL_APPLE_vertex_program_evaluators */ + +#ifdef GL_ARB_ES2_compatibility + +static GLboolean _glewInit_GL_ARB_ES2_compatibility () +{ + GLboolean r = GL_FALSE; + + r = ((glClearDepthf = (PFNGLCLEARDEPTHFPROC)glewGetProcAddress((const GLubyte*)"glClearDepthf")) == NULL) || r; + r = ((glDepthRangef = (PFNGLDEPTHRANGEFPROC)glewGetProcAddress((const GLubyte*)"glDepthRangef")) == NULL) || r; + r = ((glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)glewGetProcAddress((const GLubyte*)"glGetShaderPrecisionFormat")) == NULL) || r; + r = ((glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)glewGetProcAddress((const GLubyte*)"glReleaseShaderCompiler")) == NULL) || r; + r = ((glShaderBinary = (PFNGLSHADERBINARYPROC)glewGetProcAddress((const GLubyte*)"glShaderBinary")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_ES2_compatibility */ + +#ifdef GL_ARB_ES3_1_compatibility + +static GLboolean _glewInit_GL_ARB_ES3_1_compatibility () +{ + GLboolean r = GL_FALSE; + + r = ((glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrierByRegion")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_ES3_1_compatibility */ + +#ifdef GL_ARB_ES3_2_compatibility + +static GLboolean _glewInit_GL_ARB_ES3_2_compatibility () +{ + GLboolean r = GL_FALSE; + + r = ((glPrimitiveBoundingBoxARB = (PFNGLPRIMITIVEBOUNDINGBOXARBPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveBoundingBoxARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_ES3_2_compatibility */ + +#ifdef GL_ARB_base_instance + +static GLboolean _glewInit_GL_ARB_base_instance () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedBaseInstance")) == NULL) || r; + r = ((glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseInstance")) == NULL) || r; + r = ((glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertexBaseInstance")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_base_instance */ + +#ifdef GL_ARB_bindless_texture + +static GLboolean _glewInit_GL_ARB_bindless_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glGetImageHandleARB = (PFNGLGETIMAGEHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetImageHandleARB")) == NULL) || r; + r = ((glGetTextureHandleARB = (PFNGLGETTEXTUREHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetTextureHandleARB")) == NULL) || r; + r = ((glGetTextureSamplerHandleARB = (PFNGLGETTEXTURESAMPLERHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSamplerHandleARB")) == NULL) || r; + r = ((glGetVertexAttribLui64vARB = (PFNGLGETVERTEXATTRIBLUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLui64vARB")) == NULL) || r; + r = ((glIsImageHandleResidentARB = (PFNGLISIMAGEHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glIsImageHandleResidentARB")) == NULL) || r; + r = ((glIsTextureHandleResidentARB = (PFNGLISTEXTUREHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glIsTextureHandleResidentARB")) == NULL) || r; + r = ((glMakeImageHandleNonResidentARB = (PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleNonResidentARB")) == NULL) || r; + r = ((glMakeImageHandleResidentARB = (PFNGLMAKEIMAGEHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleResidentARB")) == NULL) || r; + r = ((glMakeTextureHandleNonResidentARB = (PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleNonResidentARB")) == NULL) || r; + r = ((glMakeTextureHandleResidentARB = (PFNGLMAKETEXTUREHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleResidentARB")) == NULL) || r; + r = ((glProgramUniformHandleui64ARB = (PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64ARB")) == NULL) || r; + r = ((glProgramUniformHandleui64vARB = (PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64vARB")) == NULL) || r; + r = ((glUniformHandleui64ARB = (PFNGLUNIFORMHANDLEUI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64ARB")) == NULL) || r; + r = ((glUniformHandleui64vARB = (PFNGLUNIFORMHANDLEUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64vARB")) == NULL) || r; + r = ((glVertexAttribL1ui64ARB = (PFNGLVERTEXATTRIBL1UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64ARB")) == NULL) || r; + r = ((glVertexAttribL1ui64vARB = (PFNGLVERTEXATTRIBL1UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64vARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_bindless_texture */ + +#ifdef GL_ARB_blend_func_extended + +static GLboolean _glewInit_GL_ARB_blend_func_extended () +{ + GLboolean r = GL_FALSE; + + r = ((glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationIndexed")) == NULL) || r; + r = ((glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataIndex")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_blend_func_extended */ + +#ifdef GL_ARB_buffer_storage + +static GLboolean _glewInit_GL_ARB_buffer_storage () +{ + GLboolean r = GL_FALSE; + + r = ((glBufferStorage = (PFNGLBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glBufferStorage")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_buffer_storage */ + +#ifdef GL_ARB_cl_event + +static GLboolean _glewInit_GL_ARB_cl_event () +{ + GLboolean r = GL_FALSE; + + r = ((glCreateSyncFromCLeventARB = (PFNGLCREATESYNCFROMCLEVENTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateSyncFromCLeventARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_cl_event */ + +#ifdef GL_ARB_clear_buffer_object + +static GLboolean _glewInit_GL_ARB_clear_buffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glClearBufferData")) == NULL) || r; + r = ((glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glClearBufferSubData")) == NULL) || r; + r = ((glClearNamedBufferDataEXT = (PFNGLCLEARNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferDataEXT")) == NULL) || r; + r = ((glClearNamedBufferSubDataEXT = (PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferSubDataEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_clear_buffer_object */ + +#ifdef GL_ARB_clear_texture + +static GLboolean _glewInit_GL_ARB_clear_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glClearTexImage")) == NULL) || r; + r = ((glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glClearTexSubImage")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_clear_texture */ + +#ifdef GL_ARB_clip_control + +static GLboolean _glewInit_GL_ARB_clip_control () +{ + GLboolean r = GL_FALSE; + + r = ((glClipControl = (PFNGLCLIPCONTROLPROC)glewGetProcAddress((const GLubyte*)"glClipControl")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_clip_control */ + +#ifdef GL_ARB_color_buffer_float + +static GLboolean _glewInit_GL_ARB_color_buffer_float () +{ + GLboolean r = GL_FALSE; + + r = ((glClampColorARB = (PFNGLCLAMPCOLORARBPROC)glewGetProcAddress((const GLubyte*)"glClampColorARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_color_buffer_float */ + +#ifdef GL_ARB_compute_shader + +static GLboolean _glewInit_GL_ARB_compute_shader () +{ + GLboolean r = GL_FALSE; + + r = ((glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)glewGetProcAddress((const GLubyte*)"glDispatchCompute")) == NULL) || r; + r = ((glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDispatchComputeIndirect")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_compute_shader */ + +#ifdef GL_ARB_compute_variable_group_size + +static GLboolean _glewInit_GL_ARB_compute_variable_group_size () +{ + GLboolean r = GL_FALSE; + + r = ((glDispatchComputeGroupSizeARB = (PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC)glewGetProcAddress((const GLubyte*)"glDispatchComputeGroupSizeARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_compute_variable_group_size */ + +#ifdef GL_ARB_copy_buffer + +static GLboolean _glewInit_GL_ARB_copy_buffer () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyBufferSubData")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_copy_buffer */ + +#ifdef GL_ARB_copy_image + +static GLboolean _glewInit_GL_ARB_copy_image () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubData")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_copy_image */ + +#ifdef GL_ARB_debug_output + +static GLboolean _glewInit_GL_ARB_debug_output () +{ + GLboolean r = GL_FALSE; + + r = ((glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallbackARB")) == NULL) || r; + r = ((glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageControlARB")) == NULL) || r; + r = ((glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsertARB")) == NULL) || r; + r = ((glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLogARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_debug_output */ + +#ifdef GL_ARB_direct_state_access + +static GLboolean _glewInit_GL_ARB_direct_state_access () +{ + GLboolean r = GL_FALSE; + + r = ((glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnit")) == NULL) || r; + r = ((glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBlitNamedFramebuffer")) == NULL) || r; + r = ((glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)glewGetProcAddress((const GLubyte*)"glCheckNamedFramebufferStatus")) == NULL) || r; + r = ((glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferData")) == NULL) || r; + r = ((glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferSubData")) == NULL) || r; + r = ((glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearNamedFramebufferfi")) == NULL) || r; + r = ((glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)glewGetProcAddress((const GLubyte*)"glClearNamedFramebufferfv")) == NULL) || r; + r = ((glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glClearNamedFramebufferiv")) == NULL) || r; + r = ((glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)glewGetProcAddress((const GLubyte*)"glClearNamedFramebufferuiv")) == NULL) || r; + r = ((glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage1D")) == NULL) || r; + r = ((glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage2D")) == NULL) || r; + r = ((glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage3D")) == NULL) || r; + r = ((glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyNamedBufferSubData")) == NULL) || r; + r = ((glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage1D")) == NULL) || r; + r = ((glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2D")) == NULL) || r; + r = ((glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3D")) == NULL) || r; + r = ((glCreateBuffers = (PFNGLCREATEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glCreateBuffers")) == NULL) || r; + r = ((glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glCreateFramebuffers")) == NULL) || r; + r = ((glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramPipelines")) == NULL) || r; + r = ((glCreateQueries = (PFNGLCREATEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glCreateQueries")) == NULL) || r; + r = ((glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glCreateRenderbuffers")) == NULL) || r; + r = ((glCreateSamplers = (PFNGLCREATESAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glCreateSamplers")) == NULL) || r; + r = ((glCreateTextures = (PFNGLCREATETEXTURESPROC)glewGetProcAddress((const GLubyte*)"glCreateTextures")) == NULL) || r; + r = ((glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glCreateTransformFeedbacks")) == NULL) || r; + r = ((glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glCreateVertexArrays")) == NULL) || r; + r = ((glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayAttrib")) == NULL) || r; + r = ((glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayAttrib")) == NULL) || r; + r = ((glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedNamedBufferRange")) == NULL) || r; + r = ((glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateTextureMipmap")) == NULL) || r; + r = ((glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImage")) == NULL) || r; + r = ((glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameteri64v")) == NULL) || r; + r = ((glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameteriv")) == NULL) || r; + r = ((glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferPointerv")) == NULL) || r; + r = ((glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferSubData")) == NULL) || r; + r = ((glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferAttachmentParameteriv")) == NULL) || r; + r = ((glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferParameteriv")) == NULL) || r; + r = ((glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameteriv")) == NULL) || r; + r = ((glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryBufferObjecti64v")) == NULL) || r; + r = ((glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryBufferObjectiv")) == NULL) || r; + r = ((glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryBufferObjectui64v")) == NULL) || r; + r = ((glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryBufferObjectuiv")) == NULL) || r; + r = ((glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImage")) == NULL) || r; + r = ((glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfv")) == NULL) || r; + r = ((glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameteriv")) == NULL) || r; + r = ((glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIiv")) == NULL) || r; + r = ((glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuiv")) == NULL) || r; + r = ((glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfv")) == NULL) || r; + r = ((glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameteriv")) == NULL) || r; + r = ((glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbacki64_v")) == NULL) || r; + r = ((glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbacki_v")) == NULL) || r; + r = ((glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackiv")) == NULL) || r; + r = ((glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIndexed64iv")) == NULL) || r; + r = ((glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIndexediv")) == NULL) || r; + r = ((glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayiv")) == NULL) || r; + r = ((glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateNamedFramebufferData")) == NULL) || r; + r = ((glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateNamedFramebufferSubData")) == NULL) || r; + r = ((glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBuffer")) == NULL) || r; + r = ((glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferRange")) == NULL) || r; + r = ((glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferData")) == NULL) || r; + r = ((glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorage")) == NULL) || r; + r = ((glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubData")) == NULL) || r; + r = ((glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferDrawBuffer")) == NULL) || r; + r = ((glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferDrawBuffers")) == NULL) || r; + r = ((glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferParameteri")) == NULL) || r; + r = ((glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferReadBuffer")) == NULL) || r; + r = ((glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbuffer")) == NULL) || r; + r = ((glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture")) == NULL) || r; + r = ((glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureLayer")) == NULL) || r; + r = ((glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorage")) == NULL) || r; + r = ((glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisample")) == NULL) || r; + r = ((glTextureBuffer = (PFNGLTEXTUREBUFFERPROC)glewGetProcAddress((const GLubyte*)"glTextureBuffer")) == NULL) || r; + r = ((glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferRange")) == NULL) || r; + r = ((glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIiv")) == NULL) || r; + r = ((glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIuiv")) == NULL) || r; + r = ((glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterf")) == NULL) || r; + r = ((glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfv")) == NULL) || r; + r = ((glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteri")) == NULL) || r; + r = ((glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteriv")) == NULL) || r; + r = ((glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage1D")) == NULL) || r; + r = ((glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2D")) == NULL) || r; + r = ((glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DMultisample")) == NULL) || r; + r = ((glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3D")) == NULL) || r; + r = ((glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DMultisample")) == NULL) || r; + r = ((glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage1D")) == NULL) || r; + r = ((glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2D")) == NULL) || r; + r = ((glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3D")) == NULL) || r; + r = ((glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackBufferBase")) == NULL) || r; + r = ((glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackBufferRange")) == NULL) || r; + r = ((glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBuffer")) == NULL) || r; + r = ((glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayAttribBinding")) == NULL) || r; + r = ((glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayAttribFormat")) == NULL) || r; + r = ((glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayAttribIFormat")) == NULL) || r; + r = ((glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayAttribLFormat")) == NULL) || r; + r = ((glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayBindingDivisor")) == NULL) || r; + r = ((glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayElementBuffer")) == NULL) || r; + r = ((glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexBuffer")) == NULL) || r; + r = ((glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexBuffers")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_direct_state_access */ + +#ifdef GL_ARB_draw_buffers + +static GLboolean _glewInit_GL_ARB_draw_buffers () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_buffers */ + +#ifdef GL_ARB_draw_buffers_blend + +static GLboolean _glewInit_GL_ARB_draw_buffers_blend () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateiARB")) == NULL) || r; + r = ((glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationiARB")) == NULL) || r; + r = ((glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateiARB")) == NULL) || r; + r = ((glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFunciARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_buffers_blend */ + +#ifdef GL_ARB_draw_elements_base_vertex + +static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsBaseVertex")) == NULL) || r; + r = ((glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertex")) == NULL) || r; + r = ((glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsBaseVertex")) == NULL) || r; + r = ((glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsBaseVertex")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_elements_base_vertex */ + +#ifdef GL_ARB_draw_indirect + +static GLboolean _glewInit_GL_ARB_draw_indirect () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysIndirect")) == NULL) || r; + r = ((glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsIndirect")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_draw_indirect */ + +#ifdef GL_ARB_framebuffer_no_attachments + +static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glFramebufferParameteri")) == NULL) || r; + r = ((glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameteriv")) == NULL) || r; + r = ((glGetNamedFramebufferParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferParameterivEXT")) == NULL) || r; + r = ((glNamedFramebufferParameteriEXT = (PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferParameteriEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_framebuffer_no_attachments */ + +#ifdef GL_ARB_framebuffer_object + +static GLboolean _glewInit_GL_ARB_framebuffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindFramebuffer")) == NULL) || r; + r = ((glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbuffer")) == NULL) || r; + r = ((glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebuffer")) == NULL) || r; + r = ((glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatus")) == NULL) || r; + r = ((glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffers")) == NULL) || r; + r = ((glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffers")) == NULL) || r; + r = ((glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbuffer")) == NULL) || r; + r = ((glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1D")) == NULL) || r; + r = ((glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2D")) == NULL) || r; + r = ((glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3D")) == NULL) || r; + r = ((glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayer")) == NULL) || r; + r = ((glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffers")) == NULL) || r; + r = ((glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffers")) == NULL) || r; + r = ((glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmap")) == NULL) || r; + r = ((glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameteriv")) == NULL) || r; + r = ((glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameteriv")) == NULL) || r; + r = ((glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsFramebuffer")) == NULL) || r; + r = ((glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbuffer")) == NULL) || r; + r = ((glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorage")) == NULL) || r; + r = ((glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisample")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_framebuffer_object */ + +#ifdef GL_ARB_geometry_shader4 + +static GLboolean _glewInit_GL_ARB_geometry_shader4 () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureARB")) == NULL) || r; + r = ((glFramebufferTextureFaceARB = (PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceARB")) == NULL) || r; + r = ((glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerARB")) == NULL) || r; + r = ((glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_geometry_shader4 */ + +#ifdef GL_ARB_get_program_binary + +static GLboolean _glewInit_GL_ARB_get_program_binary () +{ + GLboolean r = GL_FALSE; + + r = ((glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)glewGetProcAddress((const GLubyte*)"glGetProgramBinary")) == NULL) || r; + r = ((glProgramBinary = (PFNGLPROGRAMBINARYPROC)glewGetProcAddress((const GLubyte*)"glProgramBinary")) == NULL) || r; + r = ((glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteri")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_get_program_binary */ + +#ifdef GL_ARB_get_texture_sub_image + +static GLboolean _glewInit_GL_ARB_get_texture_sub_image () +{ + GLboolean r = GL_FALSE; + + r = ((glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureSubImage")) == NULL) || r; + r = ((glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSubImage")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_get_texture_sub_image */ + +#ifdef GL_ARB_gl_spirv + +static GLboolean _glewInit_GL_ARB_gl_spirv () +{ + GLboolean r = GL_FALSE; + + r = ((glSpecializeShaderARB = (PFNGLSPECIALIZESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glSpecializeShaderARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_gl_spirv */ + +#ifdef GL_ARB_gpu_shader_fp64 + +static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 () +{ + GLboolean r = GL_FALSE; + + r = ((glGetUniformdv = (PFNGLGETUNIFORMDVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformdv")) == NULL) || r; + r = ((glUniform1d = (PFNGLUNIFORM1DPROC)glewGetProcAddress((const GLubyte*)"glUniform1d")) == NULL) || r; + r = ((glUniform1dv = (PFNGLUNIFORM1DVPROC)glewGetProcAddress((const GLubyte*)"glUniform1dv")) == NULL) || r; + r = ((glUniform2d = (PFNGLUNIFORM2DPROC)glewGetProcAddress((const GLubyte*)"glUniform2d")) == NULL) || r; + r = ((glUniform2dv = (PFNGLUNIFORM2DVPROC)glewGetProcAddress((const GLubyte*)"glUniform2dv")) == NULL) || r; + r = ((glUniform3d = (PFNGLUNIFORM3DPROC)glewGetProcAddress((const GLubyte*)"glUniform3d")) == NULL) || r; + r = ((glUniform3dv = (PFNGLUNIFORM3DVPROC)glewGetProcAddress((const GLubyte*)"glUniform3dv")) == NULL) || r; + r = ((glUniform4d = (PFNGLUNIFORM4DPROC)glewGetProcAddress((const GLubyte*)"glUniform4d")) == NULL) || r; + r = ((glUniform4dv = (PFNGLUNIFORM4DVPROC)glewGetProcAddress((const GLubyte*)"glUniform4dv")) == NULL) || r; + r = ((glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2dv")) == NULL) || r; + r = ((glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3dv")) == NULL) || r; + r = ((glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4dv")) == NULL) || r; + r = ((glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3dv")) == NULL) || r; + r = ((glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2dv")) == NULL) || r; + r = ((glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4dv")) == NULL) || r; + r = ((glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4dv")) == NULL) || r; + r = ((glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2dv")) == NULL) || r; + r = ((glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3dv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_gpu_shader_fp64 */ + +#ifdef GL_ARB_gpu_shader_int64 + +static GLboolean _glewInit_GL_ARB_gpu_shader_int64 () +{ + GLboolean r = GL_FALSE; + + r = ((glGetUniformi64vARB = (PFNGLGETUNIFORMI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformi64vARB")) == NULL) || r; + r = ((glGetUniformui64vARB = (PFNGLGETUNIFORMUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformui64vARB")) == NULL) || r; + r = ((glGetnUniformi64vARB = (PFNGLGETNUNIFORMI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformi64vARB")) == NULL) || r; + r = ((glGetnUniformui64vARB = (PFNGLGETNUNIFORMUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformui64vARB")) == NULL) || r; + r = ((glProgramUniform1i64ARB = (PFNGLPROGRAMUNIFORM1I64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64ARB")) == NULL) || r; + r = ((glProgramUniform1i64vARB = (PFNGLPROGRAMUNIFORM1I64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64vARB")) == NULL) || r; + r = ((glProgramUniform1ui64ARB = (PFNGLPROGRAMUNIFORM1UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64ARB")) == NULL) || r; + r = ((glProgramUniform1ui64vARB = (PFNGLPROGRAMUNIFORM1UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64vARB")) == NULL) || r; + r = ((glProgramUniform2i64ARB = (PFNGLPROGRAMUNIFORM2I64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64ARB")) == NULL) || r; + r = ((glProgramUniform2i64vARB = (PFNGLPROGRAMUNIFORM2I64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64vARB")) == NULL) || r; + r = ((glProgramUniform2ui64ARB = (PFNGLPROGRAMUNIFORM2UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64ARB")) == NULL) || r; + r = ((glProgramUniform2ui64vARB = (PFNGLPROGRAMUNIFORM2UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64vARB")) == NULL) || r; + r = ((glProgramUniform3i64ARB = (PFNGLPROGRAMUNIFORM3I64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64ARB")) == NULL) || r; + r = ((glProgramUniform3i64vARB = (PFNGLPROGRAMUNIFORM3I64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64vARB")) == NULL) || r; + r = ((glProgramUniform3ui64ARB = (PFNGLPROGRAMUNIFORM3UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64ARB")) == NULL) || r; + r = ((glProgramUniform3ui64vARB = (PFNGLPROGRAMUNIFORM3UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64vARB")) == NULL) || r; + r = ((glProgramUniform4i64ARB = (PFNGLPROGRAMUNIFORM4I64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64ARB")) == NULL) || r; + r = ((glProgramUniform4i64vARB = (PFNGLPROGRAMUNIFORM4I64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64vARB")) == NULL) || r; + r = ((glProgramUniform4ui64ARB = (PFNGLPROGRAMUNIFORM4UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64ARB")) == NULL) || r; + r = ((glProgramUniform4ui64vARB = (PFNGLPROGRAMUNIFORM4UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64vARB")) == NULL) || r; + r = ((glUniform1i64ARB = (PFNGLUNIFORM1I64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64ARB")) == NULL) || r; + r = ((glUniform1i64vARB = (PFNGLUNIFORM1I64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64vARB")) == NULL) || r; + r = ((glUniform1ui64ARB = (PFNGLUNIFORM1UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64ARB")) == NULL) || r; + r = ((glUniform1ui64vARB = (PFNGLUNIFORM1UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64vARB")) == NULL) || r; + r = ((glUniform2i64ARB = (PFNGLUNIFORM2I64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64ARB")) == NULL) || r; + r = ((glUniform2i64vARB = (PFNGLUNIFORM2I64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64vARB")) == NULL) || r; + r = ((glUniform2ui64ARB = (PFNGLUNIFORM2UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64ARB")) == NULL) || r; + r = ((glUniform2ui64vARB = (PFNGLUNIFORM2UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64vARB")) == NULL) || r; + r = ((glUniform3i64ARB = (PFNGLUNIFORM3I64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64ARB")) == NULL) || r; + r = ((glUniform3i64vARB = (PFNGLUNIFORM3I64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64vARB")) == NULL) || r; + r = ((glUniform3ui64ARB = (PFNGLUNIFORM3UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64ARB")) == NULL) || r; + r = ((glUniform3ui64vARB = (PFNGLUNIFORM3UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64vARB")) == NULL) || r; + r = ((glUniform4i64ARB = (PFNGLUNIFORM4I64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64ARB")) == NULL) || r; + r = ((glUniform4i64vARB = (PFNGLUNIFORM4I64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64vARB")) == NULL) || r; + r = ((glUniform4ui64ARB = (PFNGLUNIFORM4UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64ARB")) == NULL) || r; + r = ((glUniform4ui64vARB = (PFNGLUNIFORM4UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64vARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_gpu_shader_int64 */ + +#ifdef GL_ARB_imaging + +static GLboolean _glewInit_GL_ARB_imaging () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r; + r = ((glColorSubTable = (PFNGLCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorSubTable")) == NULL) || r; + r = ((glColorTable = (PFNGLCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorTable")) == NULL) || r; + r = ((glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfv")) == NULL) || r; + r = ((glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameteriv")) == NULL) || r; + r = ((glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1D")) == NULL) || r; + r = ((glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2D")) == NULL) || r; + r = ((glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterf")) == NULL) || r; + r = ((glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfv")) == NULL) || r; + r = ((glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteri")) == NULL) || r; + r = ((glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriv")) == NULL) || r; + r = ((glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTable")) == NULL) || r; + r = ((glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTable")) == NULL) || r; + r = ((glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1D")) == NULL) || r; + r = ((glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2D")) == NULL) || r; + r = ((glGetColorTable = (PFNGLGETCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glGetColorTable")) == NULL) || r; + r = ((glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfv")) == NULL) || r; + r = ((glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameteriv")) == NULL) || r; + r = ((glGetConvolutionFilter = (PFNGLGETCONVOLUTIONFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilter")) == NULL) || r; + r = ((glGetConvolutionParameterfv = (PFNGLGETCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfv")) == NULL) || r; + r = ((glGetConvolutionParameteriv = (PFNGLGETCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameteriv")) == NULL) || r; + r = ((glGetHistogram = (PFNGLGETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glGetHistogram")) == NULL) || r; + r = ((glGetHistogramParameterfv = (PFNGLGETHISTOGRAMPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfv")) == NULL) || r; + r = ((glGetHistogramParameteriv = (PFNGLGETHISTOGRAMPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameteriv")) == NULL) || r; + r = ((glGetMinmax = (PFNGLGETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glGetMinmax")) == NULL) || r; + r = ((glGetMinmaxParameterfv = (PFNGLGETMINMAXPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfv")) == NULL) || r; + r = ((glGetMinmaxParameteriv = (PFNGLGETMINMAXPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameteriv")) == NULL) || r; + r = ((glGetSeparableFilter = (PFNGLGETSEPARABLEFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilter")) == NULL) || r; + r = ((glHistogram = (PFNGLHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glHistogram")) == NULL) || r; + r = ((glMinmax = (PFNGLMINMAXPROC)glewGetProcAddress((const GLubyte*)"glMinmax")) == NULL) || r; + r = ((glResetHistogram = (PFNGLRESETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glResetHistogram")) == NULL) || r; + r = ((glResetMinmax = (PFNGLRESETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glResetMinmax")) == NULL) || r; + r = ((glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2D")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_imaging */ + +#ifdef GL_ARB_indirect_parameters + +static GLboolean _glewInit_GL_ARB_indirect_parameters () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectCountARB = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectCountARB")) == NULL) || r; + r = ((glMultiDrawElementsIndirectCountARB = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectCountARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_indirect_parameters */ + +#ifdef GL_ARB_instanced_arrays + +static GLboolean _glewInit_GL_ARB_instanced_arrays () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedARB")) == NULL) || r; + r = ((glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedARB")) == NULL) || r; + r = ((glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_instanced_arrays */ + +#ifdef GL_ARB_internalformat_query + +static GLboolean _glewInit_GL_ARB_internalformat_query () +{ + GLboolean r = GL_FALSE; + + r = ((glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformativ")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_internalformat_query */ + +#ifdef GL_ARB_internalformat_query2 + +static GLboolean _glewInit_GL_ARB_internalformat_query2 () +{ + GLboolean r = GL_FALSE; + + r = ((glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformati64v")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_internalformat_query2 */ + +#ifdef GL_ARB_invalidate_subdata + +static GLboolean _glewInit_GL_ARB_invalidate_subdata () +{ + GLboolean r = GL_FALSE; + + r = ((glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateBufferData")) == NULL) || r; + r = ((glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateBufferSubData")) == NULL) || r; + r = ((glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glInvalidateFramebuffer")) == NULL) || r; + r = ((glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glInvalidateSubFramebuffer")) == NULL) || r; + r = ((glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glInvalidateTexImage")) == NULL) || r; + r = ((glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glInvalidateTexSubImage")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_invalidate_subdata */ + +#ifdef GL_ARB_map_buffer_range + +static GLboolean _glewInit_GL_ARB_map_buffer_range () +{ + GLboolean r = GL_FALSE; + + r = ((glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRange")) == NULL) || r; + r = ((glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glMapBufferRange")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_map_buffer_range */ + +#ifdef GL_ARB_matrix_palette + +static GLboolean _glewInit_GL_ARB_matrix_palette () +{ + GLboolean r = GL_FALSE; + + r = ((glCurrentPaletteMatrixARB = (PFNGLCURRENTPALETTEMATRIXARBPROC)glewGetProcAddress((const GLubyte*)"glCurrentPaletteMatrixARB")) == NULL) || r; + r = ((glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexPointerARB")) == NULL) || r; + r = ((glMatrixIndexubvARB = (PFNGLMATRIXINDEXUBVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexubvARB")) == NULL) || r; + r = ((glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexuivARB")) == NULL) || r; + r = ((glMatrixIndexusvARB = (PFNGLMATRIXINDEXUSVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexusvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_matrix_palette */ + +#ifdef GL_ARB_multi_bind + +static GLboolean _glewInit_GL_ARB_multi_bind () +{ + GLboolean r = GL_FALSE; + + r = ((glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBuffersBase")) == NULL) || r; + r = ((glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBuffersRange")) == NULL) || r; + r = ((glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)glewGetProcAddress((const GLubyte*)"glBindImageTextures")) == NULL) || r; + r = ((glBindSamplers = (PFNGLBINDSAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glBindSamplers")) == NULL) || r; + r = ((glBindTextures = (PFNGLBINDTEXTURESPROC)glewGetProcAddress((const GLubyte*)"glBindTextures")) == NULL) || r; + r = ((glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glBindVertexBuffers")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multi_bind */ + +#ifdef GL_ARB_multi_draw_indirect + +static GLboolean _glewInit_GL_ARB_multi_draw_indirect () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirect")) == NULL) || r; + r = ((glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirect")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multi_draw_indirect */ + +#ifdef GL_ARB_multisample + +static GLboolean _glewInit_GL_ARB_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverageARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multisample */ + +#ifdef GL_ARB_multitexture + +static GLboolean _glewInit_GL_ARB_multitexture () +{ + GLboolean r = GL_FALSE; + + r = ((glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glActiveTextureARB")) == NULL) || r; + r = ((glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTextureARB")) == NULL) || r; + r = ((glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dARB")) == NULL) || r; + r = ((glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dvARB")) == NULL) || r; + r = ((glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fARB")) == NULL) || r; + r = ((glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fvARB")) == NULL) || r; + r = ((glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iARB")) == NULL) || r; + r = ((glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1ivARB")) == NULL) || r; + r = ((glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sARB")) == NULL) || r; + r = ((glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1svARB")) == NULL) || r; + r = ((glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dARB")) == NULL) || r; + r = ((glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dvARB")) == NULL) || r; + r = ((glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fARB")) == NULL) || r; + r = ((glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fvARB")) == NULL) || r; + r = ((glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iARB")) == NULL) || r; + r = ((glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2ivARB")) == NULL) || r; + r = ((glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sARB")) == NULL) || r; + r = ((glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2svARB")) == NULL) || r; + r = ((glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dARB")) == NULL) || r; + r = ((glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dvARB")) == NULL) || r; + r = ((glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fARB")) == NULL) || r; + r = ((glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fvARB")) == NULL) || r; + r = ((glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iARB")) == NULL) || r; + r = ((glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3ivARB")) == NULL) || r; + r = ((glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sARB")) == NULL) || r; + r = ((glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3svARB")) == NULL) || r; + r = ((glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dARB")) == NULL) || r; + r = ((glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dvARB")) == NULL) || r; + r = ((glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fARB")) == NULL) || r; + r = ((glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fvARB")) == NULL) || r; + r = ((glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iARB")) == NULL) || r; + r = ((glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4ivARB")) == NULL) || r; + r = ((glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sARB")) == NULL) || r; + r = ((glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4svARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_multitexture */ + +#ifdef GL_ARB_occlusion_query + +static GLboolean _glewInit_GL_ARB_occlusion_query () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryARB")) == NULL) || r; + r = ((glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesARB")) == NULL) || r; + r = ((glEndQueryARB = (PFNGLENDQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glEndQueryARB")) == NULL) || r; + r = ((glGenQueriesARB = (PFNGLGENQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesARB")) == NULL) || r; + r = ((glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivARB")) == NULL) || r; + r = ((glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivARB")) == NULL) || r; + r = ((glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivARB")) == NULL) || r; + r = ((glIsQueryARB = (PFNGLISQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glIsQueryARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_occlusion_query */ + +#ifdef GL_ARB_parallel_shader_compile + +static GLboolean _glewInit_GL_ARB_parallel_shader_compile () +{ + GLboolean r = GL_FALSE; + + r = ((glMaxShaderCompilerThreadsARB = (PFNGLMAXSHADERCOMPILERTHREADSARBPROC)glewGetProcAddress((const GLubyte*)"glMaxShaderCompilerThreadsARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_parallel_shader_compile */ + +#ifdef GL_ARB_point_parameters + +static GLboolean _glewInit_GL_ARB_point_parameters () +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfARB")) == NULL) || r; + r = ((glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_point_parameters */ + +#ifdef GL_ARB_polygon_offset_clamp + +static GLboolean _glewInit_GL_ARB_polygon_offset_clamp () +{ + GLboolean r = GL_FALSE; + + r = ((glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetClamp")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_polygon_offset_clamp */ + +#ifdef GL_ARB_program_interface_query + +static GLboolean _glewInit_GL_ARB_program_interface_query () +{ + GLboolean r = GL_FALSE; + + r = ((glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInterfaceiv")) == NULL) || r; + r = ((glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceIndex")) == NULL) || r; + r = ((glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocation")) == NULL) || r; + r = ((glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocationIndex")) == NULL) || r; + r = ((glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceName")) == NULL) || r; + r = ((glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceiv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_program_interface_query */ + +#ifdef GL_ARB_provoking_vertex + +static GLboolean _glewInit_GL_ARB_provoking_vertex () +{ + GLboolean r = GL_FALSE; + + r = ((glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertex")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_provoking_vertex */ + +#ifdef GL_ARB_robustness + +static GLboolean _glewInit_GL_ARB_robustness () +{ + GLboolean r = GL_FALSE; + + r = ((glGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC)glewGetProcAddress((const GLubyte*)"glGetGraphicsResetStatusARB")) == NULL) || r; + r = ((glGetnColorTableARB = (PFNGLGETNCOLORTABLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnColorTableARB")) == NULL) || r; + r = ((glGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnCompressedTexImageARB")) == NULL) || r; + r = ((glGetnConvolutionFilterARB = (PFNGLGETNCONVOLUTIONFILTERARBPROC)glewGetProcAddress((const GLubyte*)"glGetnConvolutionFilterARB")) == NULL) || r; + r = ((glGetnHistogramARB = (PFNGLGETNHISTOGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glGetnHistogramARB")) == NULL) || r; + r = ((glGetnMapdvARB = (PFNGLGETNMAPDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapdvARB")) == NULL) || r; + r = ((glGetnMapfvARB = (PFNGLGETNMAPFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapfvARB")) == NULL) || r; + r = ((glGetnMapivARB = (PFNGLGETNMAPIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapivARB")) == NULL) || r; + r = ((glGetnMinmaxARB = (PFNGLGETNMINMAXARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMinmaxARB")) == NULL) || r; + r = ((glGetnPixelMapfvARB = (PFNGLGETNPIXELMAPFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapfvARB")) == NULL) || r; + r = ((glGetnPixelMapuivARB = (PFNGLGETNPIXELMAPUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapuivARB")) == NULL) || r; + r = ((glGetnPixelMapusvARB = (PFNGLGETNPIXELMAPUSVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapusvARB")) == NULL) || r; + r = ((glGetnPolygonStippleARB = (PFNGLGETNPOLYGONSTIPPLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPolygonStippleARB")) == NULL) || r; + r = ((glGetnSeparableFilterARB = (PFNGLGETNSEPARABLEFILTERARBPROC)glewGetProcAddress((const GLubyte*)"glGetnSeparableFilterARB")) == NULL) || r; + r = ((glGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnTexImageARB")) == NULL) || r; + r = ((glGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformdvARB")) == NULL) || r; + r = ((glGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformfvARB")) == NULL) || r; + r = ((glGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformivARB")) == NULL) || r; + r = ((glGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformuivARB")) == NULL) || r; + r = ((glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC)glewGetProcAddress((const GLubyte*)"glReadnPixelsARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_robustness */ + +#ifdef GL_ARB_sample_locations + +static GLboolean _glewInit_GL_ARB_sample_locations () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferSampleLocationsfvARB = (PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferSampleLocationsfvARB")) == NULL) || r; + r = ((glNamedFramebufferSampleLocationsfvARB = (PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferSampleLocationsfvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sample_locations */ + +#ifdef GL_ARB_sample_shading + +static GLboolean _glewInit_GL_ARB_sample_shading () +{ + GLboolean r = GL_FALSE; + + r = ((glMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShadingARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sample_shading */ + +#ifdef GL_ARB_sampler_objects + +static GLboolean _glewInit_GL_ARB_sampler_objects () +{ + GLboolean r = GL_FALSE; + + r = ((glBindSampler = (PFNGLBINDSAMPLERPROC)glewGetProcAddress((const GLubyte*)"glBindSampler")) == NULL) || r; + r = ((glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteSamplers")) == NULL) || r; + r = ((glGenSamplers = (PFNGLGENSAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glGenSamplers")) == NULL) || r; + r = ((glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterIiv")) == NULL) || r; + r = ((glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterIuiv")) == NULL) || r; + r = ((glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterfv")) == NULL) || r; + r = ((glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameteriv")) == NULL) || r; + r = ((glIsSampler = (PFNGLISSAMPLERPROC)glewGetProcAddress((const GLubyte*)"glIsSampler")) == NULL) || r; + r = ((glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterIiv")) == NULL) || r; + r = ((glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterIuiv")) == NULL) || r; + r = ((glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterf")) == NULL) || r; + r = ((glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterfv")) == NULL) || r; + r = ((glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameteri")) == NULL) || r; + r = ((glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameteriv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sampler_objects */ + +#ifdef GL_ARB_separate_shader_objects + +static GLboolean _glewInit_GL_ARB_separate_shader_objects () +{ + GLboolean r = GL_FALSE; + + r = ((glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glActiveShaderProgram")) == NULL) || r; + r = ((glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glBindProgramPipeline")) == NULL) || r; + r = ((glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramv")) == NULL) || r; + r = ((glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramPipelines")) == NULL) || r; + r = ((glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glGenProgramPipelines")) == NULL) || r; + r = ((glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramPipelineInfoLog")) == NULL) || r; + r = ((glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramPipelineiv")) == NULL) || r; + r = ((glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glIsProgramPipeline")) == NULL) || r; + r = ((glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1d")) == NULL) || r; + r = ((glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1dv")) == NULL) || r; + r = ((glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1f")) == NULL) || r; + r = ((glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fv")) == NULL) || r; + r = ((glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i")) == NULL) || r; + r = ((glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iv")) == NULL) || r; + r = ((glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui")) == NULL) || r; + r = ((glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiv")) == NULL) || r; + r = ((glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2d")) == NULL) || r; + r = ((glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2dv")) == NULL) || r; + r = ((glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2f")) == NULL) || r; + r = ((glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fv")) == NULL) || r; + r = ((glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i")) == NULL) || r; + r = ((glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iv")) == NULL) || r; + r = ((glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui")) == NULL) || r; + r = ((glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiv")) == NULL) || r; + r = ((glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3d")) == NULL) || r; + r = ((glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3dv")) == NULL) || r; + r = ((glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3f")) == NULL) || r; + r = ((glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fv")) == NULL) || r; + r = ((glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i")) == NULL) || r; + r = ((glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iv")) == NULL) || r; + r = ((glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui")) == NULL) || r; + r = ((glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiv")) == NULL) || r; + r = ((glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4d")) == NULL) || r; + r = ((glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4dv")) == NULL) || r; + r = ((glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4f")) == NULL) || r; + r = ((glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fv")) == NULL) || r; + r = ((glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i")) == NULL) || r; + r = ((glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iv")) == NULL) || r; + r = ((glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui")) == NULL) || r; + r = ((glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiv")) == NULL) || r; + r = ((glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2dv")) == NULL) || r; + r = ((glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fv")) == NULL) || r; + r = ((glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3dv")) == NULL) || r; + r = ((glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fv")) == NULL) || r; + r = ((glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4dv")) == NULL) || r; + r = ((glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fv")) == NULL) || r; + r = ((glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3dv")) == NULL) || r; + r = ((glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fv")) == NULL) || r; + r = ((glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2dv")) == NULL) || r; + r = ((glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fv")) == NULL) || r; + r = ((glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4dv")) == NULL) || r; + r = ((glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fv")) == NULL) || r; + r = ((glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4dv")) == NULL) || r; + r = ((glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fv")) == NULL) || r; + r = ((glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2dv")) == NULL) || r; + r = ((glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fv")) == NULL) || r; + r = ((glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3dv")) == NULL) || r; + r = ((glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fv")) == NULL) || r; + r = ((glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)glewGetProcAddress((const GLubyte*)"glUseProgramStages")) == NULL) || r; + r = ((glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramPipeline")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_separate_shader_objects */ + +#ifdef GL_ARB_shader_atomic_counters + +static GLboolean _glewInit_GL_ARB_shader_atomic_counters () +{ + GLboolean r = GL_FALSE; + + r = ((glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAtomicCounterBufferiv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_atomic_counters */ + +#ifdef GL_ARB_shader_image_load_store + +static GLboolean _glewInit_GL_ARB_shader_image_load_store () +{ + GLboolean r = GL_FALSE; + + r = ((glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glBindImageTexture")) == NULL) || r; + r = ((glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrier")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_image_load_store */ + +#ifdef GL_ARB_shader_objects + +static GLboolean _glewInit_GL_ARB_shader_objects () +{ + GLboolean r = GL_FALSE; + + r = ((glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glAttachObjectARB")) == NULL) || r; + r = ((glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderARB")) == NULL) || r; + r = ((glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramObjectARB")) == NULL) || r; + r = ((glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderObjectARB")) == NULL) || r; + r = ((glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteObjectARB")) == NULL) || r; + r = ((glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDetachObjectARB")) == NULL) || r; + r = ((glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformARB")) == NULL) || r; + r = ((glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedObjectsARB")) == NULL) || r; + r = ((glGetHandleARB = (PFNGLGETHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetHandleARB")) == NULL) || r; + r = ((glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetInfoLogARB")) == NULL) || r; + r = ((glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterfvARB")) == NULL) || r; + r = ((glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivARB")) == NULL) || r; + r = ((glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSourceARB")) == NULL) || r; + r = ((glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocationARB")) == NULL) || r; + r = ((glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfvARB")) == NULL) || r; + r = ((glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformivARB")) == NULL) || r; + r = ((glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glLinkProgramARB")) == NULL) || r; + r = ((glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glShaderSourceARB")) == NULL) || r; + r = ((glUniform1fARB = (PFNGLUNIFORM1FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fARB")) == NULL) || r; + r = ((glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fvARB")) == NULL) || r; + r = ((glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1iARB")) == NULL) || r; + r = ((glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ivARB")) == NULL) || r; + r = ((glUniform2fARB = (PFNGLUNIFORM2FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fARB")) == NULL) || r; + r = ((glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fvARB")) == NULL) || r; + r = ((glUniform2iARB = (PFNGLUNIFORM2IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2iARB")) == NULL) || r; + r = ((glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ivARB")) == NULL) || r; + r = ((glUniform3fARB = (PFNGLUNIFORM3FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fARB")) == NULL) || r; + r = ((glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fvARB")) == NULL) || r; + r = ((glUniform3iARB = (PFNGLUNIFORM3IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3iARB")) == NULL) || r; + r = ((glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ivARB")) == NULL) || r; + r = ((glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fARB")) == NULL) || r; + r = ((glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fvARB")) == NULL) || r; + r = ((glUniform4iARB = (PFNGLUNIFORM4IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4iARB")) == NULL) || r; + r = ((glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ivARB")) == NULL) || r; + r = ((glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fvARB")) == NULL) || r; + r = ((glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fvARB")) == NULL) || r; + r = ((glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fvARB")) == NULL) || r; + r = ((glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glUseProgramObjectARB")) == NULL) || r; + r = ((glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_objects */ + +#ifdef GL_ARB_shader_storage_buffer_object + +static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glShaderStorageBlockBinding")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_storage_buffer_object */ + +#ifdef GL_ARB_shader_subroutine + +static GLboolean _glewInit_GL_ARB_shader_subroutine () +{ + GLboolean r = GL_FALSE; + + r = ((glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineName")) == NULL) || r; + r = ((glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineUniformName")) == NULL) || r; + r = ((glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineUniformiv")) == NULL) || r; + r = ((glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStageiv")) == NULL) || r; + r = ((glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetSubroutineIndex")) == NULL) || r; + r = ((glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetSubroutineUniformLocation")) == NULL) || r; + r = ((glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformSubroutineuiv")) == NULL) || r; + r = ((glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)glewGetProcAddress((const GLubyte*)"glUniformSubroutinesuiv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shader_subroutine */ + +#ifdef GL_ARB_shading_language_include + +static GLboolean _glewInit_GL_ARB_shading_language_include () +{ + GLboolean r = GL_FALSE; + + r = ((glCompileShaderIncludeARB = (PFNGLCOMPILESHADERINCLUDEARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderIncludeARB")) == NULL) || r; + r = ((glDeleteNamedStringARB = (PFNGLDELETENAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteNamedStringARB")) == NULL) || r; + r = ((glGetNamedStringARB = (PFNGLGETNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetNamedStringARB")) == NULL) || r; + r = ((glGetNamedStringivARB = (PFNGLGETNAMEDSTRINGIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetNamedStringivARB")) == NULL) || r; + r = ((glIsNamedStringARB = (PFNGLISNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glIsNamedStringARB")) == NULL) || r; + r = ((glNamedStringARB = (PFNGLNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glNamedStringARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_shading_language_include */ + +#ifdef GL_ARB_sparse_buffer + +static GLboolean _glewInit_GL_ARB_sparse_buffer () +{ + GLboolean r = GL_FALSE; + + r = ((glBufferPageCommitmentARB = (PFNGLBUFFERPAGECOMMITMENTARBPROC)glewGetProcAddress((const GLubyte*)"glBufferPageCommitmentARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sparse_buffer */ + +#ifdef GL_ARB_sparse_texture + +static GLboolean _glewInit_GL_ARB_sparse_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glTexPageCommitmentARB = (PFNGLTEXPAGECOMMITMENTARBPROC)glewGetProcAddress((const GLubyte*)"glTexPageCommitmentARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sparse_texture */ + +#ifdef GL_ARB_sync + +static GLboolean _glewInit_GL_ARB_sync () +{ + GLboolean r = GL_FALSE; + + r = ((glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glClientWaitSync")) == NULL) || r; + r = ((glDeleteSync = (PFNGLDELETESYNCPROC)glewGetProcAddress((const GLubyte*)"glDeleteSync")) == NULL) || r; + r = ((glFenceSync = (PFNGLFENCESYNCPROC)glewGetProcAddress((const GLubyte*)"glFenceSync")) == NULL) || r; + r = ((glGetInteger64v = (PFNGLGETINTEGER64VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64v")) == NULL) || r; + r = ((glGetSynciv = (PFNGLGETSYNCIVPROC)glewGetProcAddress((const GLubyte*)"glGetSynciv")) == NULL) || r; + r = ((glIsSync = (PFNGLISSYNCPROC)glewGetProcAddress((const GLubyte*)"glIsSync")) == NULL) || r; + r = ((glWaitSync = (PFNGLWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glWaitSync")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_sync */ + +#ifdef GL_ARB_tessellation_shader + +static GLboolean _glewInit_GL_ARB_tessellation_shader () +{ + GLboolean r = GL_FALSE; + + r = ((glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPatchParameterfv")) == NULL) || r; + r = ((glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPatchParameteri")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_tessellation_shader */ + +#ifdef GL_ARB_texture_barrier + +static GLboolean _glewInit_GL_ARB_texture_barrier () +{ + GLboolean r = GL_FALSE; + + r = ((glTextureBarrier = (PFNGLTEXTUREBARRIERPROC)glewGetProcAddress((const GLubyte*)"glTextureBarrier")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_barrier */ + +#ifdef GL_ARB_texture_buffer_object + +static GLboolean _glewInit_GL_ARB_texture_buffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glTexBufferARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_buffer_object */ + +#ifdef GL_ARB_texture_buffer_range + +static GLboolean _glewInit_GL_ARB_texture_buffer_range () +{ + GLboolean r = GL_FALSE; + + r = ((glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glTexBufferRange")) == NULL) || r; + r = ((glTextureBufferRangeEXT = (PFNGLTEXTUREBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferRangeEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_buffer_range */ + +#ifdef GL_ARB_texture_compression + +static GLboolean _glewInit_GL_ARB_texture_compression () +{ + GLboolean r = GL_FALSE; + + r = ((glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1DARB")) == NULL) || r; + r = ((glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2DARB")) == NULL) || r; + r = ((glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DARB")) == NULL) || r; + r = ((glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1DARB")) == NULL) || r; + r = ((glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2DARB")) == NULL) || r; + r = ((glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DARB")) == NULL) || r; + r = ((glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImageARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_compression */ + +#ifdef GL_ARB_texture_multisample + +static GLboolean _glewInit_GL_ARB_texture_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefv")) == NULL) || r; + r = ((glSampleMaski = (PFNGLSAMPLEMASKIPROC)glewGetProcAddress((const GLubyte*)"glSampleMaski")) == NULL) || r; + r = ((glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisample")) == NULL) || r; + r = ((glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisample")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_multisample */ + +#ifdef GL_ARB_texture_storage + +static GLboolean _glewInit_GL_ARB_texture_storage () +{ + GLboolean r = GL_FALSE; + + r = ((glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage1D")) == NULL) || r; + r = ((glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2D")) == NULL) || r; + r = ((glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3D")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_storage */ + +#ifdef GL_ARB_texture_storage_multisample + +static GLboolean _glewInit_GL_ARB_texture_storage_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2DMultisample")) == NULL) || r; + r = ((glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3DMultisample")) == NULL) || r; + r = ((glTextureStorage2DMultisampleEXT = (PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DMultisampleEXT")) == NULL) || r; + r = ((glTextureStorage3DMultisampleEXT = (PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DMultisampleEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_storage_multisample */ + +#ifdef GL_ARB_texture_view + +static GLboolean _glewInit_GL_ARB_texture_view () +{ + GLboolean r = GL_FALSE; + + r = ((glTextureView = (PFNGLTEXTUREVIEWPROC)glewGetProcAddress((const GLubyte*)"glTextureView")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_texture_view */ + +#ifdef GL_ARB_timer_query + +static GLboolean _glewInit_GL_ARB_timer_query () +{ + GLboolean r = GL_FALSE; + + r = ((glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64v")) == NULL) || r; + r = ((glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64v")) == NULL) || r; + r = ((glQueryCounter = (PFNGLQUERYCOUNTERPROC)glewGetProcAddress((const GLubyte*)"glQueryCounter")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_timer_query */ + +#ifdef GL_ARB_transform_feedback2 + +static GLboolean _glewInit_GL_ARB_transform_feedback2 () +{ + GLboolean r = GL_FALSE; + + r = ((glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedback")) == NULL) || r; + r = ((glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacks")) == NULL) || r; + r = ((glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedback")) == NULL) || r; + r = ((glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacks")) == NULL) || r; + r = ((glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedback")) == NULL) || r; + r = ((glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedback")) == NULL) || r; + r = ((glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedback")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transform_feedback2 */ + +#ifdef GL_ARB_transform_feedback3 + +static GLboolean _glewInit_GL_ARB_transform_feedback3 () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryIndexed")) == NULL) || r; + r = ((glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackStream")) == NULL) || r; + r = ((glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glEndQueryIndexed")) == NULL) || r; + r = ((glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryIndexediv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transform_feedback3 */ + +#ifdef GL_ARB_transform_feedback_instanced + +static GLboolean _glewInit_GL_ARB_transform_feedback_instanced () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackInstanced")) == NULL) || r; + r = ((glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackStreamInstanced")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transform_feedback_instanced */ + +#ifdef GL_ARB_transpose_matrix + +static GLboolean _glewInit_GL_ARB_transpose_matrix () +{ + GLboolean r = GL_FALSE; + + r = ((glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixdARB")) == NULL) || r; + r = ((glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixfARB")) == NULL) || r; + r = ((glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixdARB")) == NULL) || r; + r = ((glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixfARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_transpose_matrix */ + +#ifdef GL_ARB_uniform_buffer_object + +static GLboolean _glewInit_GL_ARB_uniform_buffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r; + r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r; + r = ((glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockName")) == NULL) || r; + r = ((glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockiv")) == NULL) || r; + r = ((glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformName")) == NULL) || r; + r = ((glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformsiv")) == NULL) || r; + r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r; + r = ((glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBlockIndex")) == NULL) || r; + r = ((glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)glewGetProcAddress((const GLubyte*)"glGetUniformIndices")) == NULL) || r; + r = ((glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glUniformBlockBinding")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_uniform_buffer_object */ + +#ifdef GL_ARB_vertex_array_object + +static GLboolean _glewInit_GL_ARB_vertex_array_object () +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArray")) == NULL) || r; + r = ((glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArrays")) == NULL) || r; + r = ((glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArrays")) == NULL) || r; + r = ((glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArray")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_array_object */ + +#ifdef GL_ARB_vertex_attrib_64bit + +static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit () +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLdv")) == NULL) || r; + r = ((glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1d")) == NULL) || r; + r = ((glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dv")) == NULL) || r; + r = ((glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2d")) == NULL) || r; + r = ((glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dv")) == NULL) || r; + r = ((glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3d")) == NULL) || r; + r = ((glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dv")) == NULL) || r; + r = ((glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4d")) == NULL) || r; + r = ((glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dv")) == NULL) || r; + r = ((glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLPointer")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_attrib_64bit */ + +#ifdef GL_ARB_vertex_attrib_binding + +static GLboolean _glewInit_GL_ARB_vertex_attrib_binding () +{ + GLboolean r = GL_FALSE; + + r = ((glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindVertexBuffer")) == NULL) || r; + r = ((glVertexArrayBindVertexBufferEXT = (PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayBindVertexBufferEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribBindingEXT = (PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribBindingEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribFormatEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribIFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribIFormatEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribLFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribLFormatEXT")) == NULL) || r; + r = ((glVertexArrayVertexBindingDivisorEXT = (PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexBindingDivisorEXT")) == NULL) || r; + r = ((glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribBinding")) == NULL) || r; + r = ((glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormat")) == NULL) || r; + r = ((glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormat")) == NULL) || r; + r = ((glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLFormat")) == NULL) || r; + r = ((glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexBindingDivisor")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_attrib_binding */ + +#ifdef GL_ARB_vertex_blend + +static GLboolean _glewInit_GL_ARB_vertex_blend () +{ + GLboolean r = GL_FALSE; + + r = ((glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendARB")) == NULL) || r; + r = ((glWeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glWeightPointerARB")) == NULL) || r; + r = ((glWeightbvARB = (PFNGLWEIGHTBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightbvARB")) == NULL) || r; + r = ((glWeightdvARB = (PFNGLWEIGHTDVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightdvARB")) == NULL) || r; + r = ((glWeightfvARB = (PFNGLWEIGHTFVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightfvARB")) == NULL) || r; + r = ((glWeightivARB = (PFNGLWEIGHTIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightivARB")) == NULL) || r; + r = ((glWeightsvARB = (PFNGLWEIGHTSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightsvARB")) == NULL) || r; + r = ((glWeightubvARB = (PFNGLWEIGHTUBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightubvARB")) == NULL) || r; + r = ((glWeightuivARB = (PFNGLWEIGHTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightuivARB")) == NULL) || r; + r = ((glWeightusvARB = (PFNGLWEIGHTUSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightusvARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_blend */ + +#ifdef GL_ARB_vertex_buffer_object + +static GLboolean _glewInit_GL_ARB_vertex_buffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glBindBufferARB = (PFNGLBINDBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glBindBufferARB")) == NULL) || r; + r = ((glBufferDataARB = (PFNGLBUFFERDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferDataARB")) == NULL) || r; + r = ((glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferSubDataARB")) == NULL) || r; + r = ((glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffersARB")) == NULL) || r; + r = ((glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glGenBuffersARB")) == NULL) || r; + r = ((glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterivARB")) == NULL) || r; + r = ((glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointervARB")) == NULL) || r; + r = ((glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubDataARB")) == NULL) || r; + r = ((glIsBufferARB = (PFNGLISBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glIsBufferARB")) == NULL) || r; + r = ((glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glMapBufferARB")) == NULL) || r; + r = ((glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glUnmapBufferARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_buffer_object */ + +#ifdef GL_ARB_vertex_program + +static GLboolean _glewInit_GL_ARB_vertex_program () +{ + GLboolean r = GL_FALSE; + + r = ((glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glBindProgramARB")) == NULL) || r; + r = ((glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsARB")) == NULL) || r; + r = ((glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArrayARB")) == NULL) || r; + r = ((glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArrayARB")) == NULL) || r; + r = ((glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsARB")) == NULL) || r; + r = ((glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterdvARB")) == NULL) || r; + r = ((glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterfvARB")) == NULL) || r; + r = ((glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterdvARB")) == NULL) || r; + r = ((glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterfvARB")) == NULL) || r; + r = ((glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringARB")) == NULL) || r; + r = ((glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivARB")) == NULL) || r; + r = ((glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervARB")) == NULL) || r; + r = ((glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvARB")) == NULL) || r; + r = ((glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvARB")) == NULL) || r; + r = ((glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivARB")) == NULL) || r; + r = ((glIsProgramARB = (PFNGLISPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glIsProgramARB")) == NULL) || r; + r = ((glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dARB")) == NULL) || r; + r = ((glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dvARB")) == NULL) || r; + r = ((glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fARB")) == NULL) || r; + r = ((glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fvARB")) == NULL) || r; + r = ((glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dARB")) == NULL) || r; + r = ((glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dvARB")) == NULL) || r; + r = ((glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fARB")) == NULL) || r; + r = ((glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fvARB")) == NULL) || r; + r = ((glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glProgramStringARB")) == NULL) || r; + r = ((glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dARB")) == NULL) || r; + r = ((glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvARB")) == NULL) || r; + r = ((glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fARB")) == NULL) || r; + r = ((glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvARB")) == NULL) || r; + r = ((glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sARB")) == NULL) || r; + r = ((glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svARB")) == NULL) || r; + r = ((glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dARB")) == NULL) || r; + r = ((glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvARB")) == NULL) || r; + r = ((glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fARB")) == NULL) || r; + r = ((glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvARB")) == NULL) || r; + r = ((glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sARB")) == NULL) || r; + r = ((glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svARB")) == NULL) || r; + r = ((glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dARB")) == NULL) || r; + r = ((glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvARB")) == NULL) || r; + r = ((glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fARB")) == NULL) || r; + r = ((glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvARB")) == NULL) || r; + r = ((glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sARB")) == NULL) || r; + r = ((glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svARB")) == NULL) || r; + r = ((glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NbvARB")) == NULL) || r; + r = ((glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NivARB")) == NULL) || r; + r = ((glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NsvARB")) == NULL) || r; + r = ((glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubARB")) == NULL) || r; + r = ((glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubvARB")) == NULL) || r; + r = ((glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NuivARB")) == NULL) || r; + r = ((glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NusvARB")) == NULL) || r; + r = ((glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bvARB")) == NULL) || r; + r = ((glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dARB")) == NULL) || r; + r = ((glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvARB")) == NULL) || r; + r = ((glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fARB")) == NULL) || r; + r = ((glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvARB")) == NULL) || r; + r = ((glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ivARB")) == NULL) || r; + r = ((glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sARB")) == NULL) || r; + r = ((glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svARB")) == NULL) || r; + r = ((glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvARB")) == NULL) || r; + r = ((glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uivARB")) == NULL) || r; + r = ((glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usvARB")) == NULL) || r; + r = ((glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_program */ + +#ifdef GL_ARB_vertex_shader + +static GLboolean _glewInit_GL_ARB_vertex_shader () +{ + GLboolean r = GL_FALSE; + + r = ((glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocationARB")) == NULL) || r; + r = ((glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttribARB")) == NULL) || r; + r = ((glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocationARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_shader */ + +#ifdef GL_ARB_vertex_type_2_10_10_10_rev + +static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev () +{ + GLboolean r = GL_FALSE; + + r = ((glColorP3ui = (PFNGLCOLORP3UIPROC)glewGetProcAddress((const GLubyte*)"glColorP3ui")) == NULL) || r; + r = ((glColorP3uiv = (PFNGLCOLORP3UIVPROC)glewGetProcAddress((const GLubyte*)"glColorP3uiv")) == NULL) || r; + r = ((glColorP4ui = (PFNGLCOLORP4UIPROC)glewGetProcAddress((const GLubyte*)"glColorP4ui")) == NULL) || r; + r = ((glColorP4uiv = (PFNGLCOLORP4UIVPROC)glewGetProcAddress((const GLubyte*)"glColorP4uiv")) == NULL) || r; + r = ((glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP1ui")) == NULL) || r; + r = ((glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP1uiv")) == NULL) || r; + r = ((glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP2ui")) == NULL) || r; + r = ((glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP2uiv")) == NULL) || r; + r = ((glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP3ui")) == NULL) || r; + r = ((glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP3uiv")) == NULL) || r; + r = ((glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP4ui")) == NULL) || r; + r = ((glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP4uiv")) == NULL) || r; + r = ((glNormalP3ui = (PFNGLNORMALP3UIPROC)glewGetProcAddress((const GLubyte*)"glNormalP3ui")) == NULL) || r; + r = ((glNormalP3uiv = (PFNGLNORMALP3UIVPROC)glewGetProcAddress((const GLubyte*)"glNormalP3uiv")) == NULL) || r; + r = ((glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorP3ui")) == NULL) || r; + r = ((glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorP3uiv")) == NULL) || r; + r = ((glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP1ui")) == NULL) || r; + r = ((glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP1uiv")) == NULL) || r; + r = ((glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP2ui")) == NULL) || r; + r = ((glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP2uiv")) == NULL) || r; + r = ((glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP3ui")) == NULL) || r; + r = ((glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP3uiv")) == NULL) || r; + r = ((glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP4ui")) == NULL) || r; + r = ((glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP4uiv")) == NULL) || r; + r = ((glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP1ui")) == NULL) || r; + r = ((glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP1uiv")) == NULL) || r; + r = ((glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP2ui")) == NULL) || r; + r = ((glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP2uiv")) == NULL) || r; + r = ((glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP3ui")) == NULL) || r; + r = ((glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP3uiv")) == NULL) || r; + r = ((glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP4ui")) == NULL) || r; + r = ((glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP4uiv")) == NULL) || r; + r = ((glVertexP2ui = (PFNGLVERTEXP2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP2ui")) == NULL) || r; + r = ((glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP2uiv")) == NULL) || r; + r = ((glVertexP3ui = (PFNGLVERTEXP3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP3ui")) == NULL) || r; + r = ((glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP3uiv")) == NULL) || r; + r = ((glVertexP4ui = (PFNGLVERTEXP4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP4ui")) == NULL) || r; + r = ((glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP4uiv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ + +#ifdef GL_ARB_viewport_array + +static GLboolean _glewInit_GL_ARB_viewport_array () +{ + GLboolean r = GL_FALSE; + + r = ((glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeArrayv")) == NULL) || r; + r = ((glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeIndexed")) == NULL) || r; + r = ((glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_v")) == NULL) || r; + r = ((glGetFloati_v = (PFNGLGETFLOATI_VPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_v")) == NULL) || r; + r = ((glScissorArrayv = (PFNGLSCISSORARRAYVPROC)glewGetProcAddress((const GLubyte*)"glScissorArrayv")) == NULL) || r; + r = ((glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexed")) == NULL) || r; + r = ((glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexedv")) == NULL) || r; + r = ((glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)glewGetProcAddress((const GLubyte*)"glViewportArrayv")) == NULL) || r; + r = ((glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedf")) == NULL) || r; + r = ((glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedfv")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_viewport_array */ + +#ifdef GL_ARB_window_pos + +static GLboolean _glewInit_GL_ARB_window_pos () +{ + GLboolean r = GL_FALSE; + + r = ((glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dARB")) == NULL) || r; + r = ((glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvARB")) == NULL) || r; + r = ((glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fARB")) == NULL) || r; + r = ((glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvARB")) == NULL) || r; + r = ((glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iARB")) == NULL) || r; + r = ((glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivARB")) == NULL) || r; + r = ((glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sARB")) == NULL) || r; + r = ((glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svARB")) == NULL) || r; + r = ((glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dARB")) == NULL) || r; + r = ((glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvARB")) == NULL) || r; + r = ((glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fARB")) == NULL) || r; + r = ((glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvARB")) == NULL) || r; + r = ((glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iARB")) == NULL) || r; + r = ((glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivARB")) == NULL) || r; + r = ((glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sARB")) == NULL) || r; + r = ((glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svARB")) == NULL) || r; + + return r; +} + +#endif /* GL_ARB_window_pos */ + +#ifdef GL_ATI_draw_buffers + +static GLboolean _glewInit_GL_ATI_draw_buffers () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_draw_buffers */ + +#ifdef GL_ATI_element_array + +static GLboolean _glewInit_GL_ATI_element_array () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementArrayATI = (PFNGLDRAWELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayATI")) == NULL) || r; + r = ((glDrawRangeElementArrayATI = (PFNGLDRAWRANGEELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayATI")) == NULL) || r; + r = ((glElementPointerATI = (PFNGLELEMENTPOINTERATIPROC)glewGetProcAddress((const GLubyte*)"glElementPointerATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_element_array */ + +#ifdef GL_ATI_envmap_bumpmap + +static GLboolean _glewInit_GL_ATI_envmap_bumpmap () +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexBumpParameterfvATI = (PFNGLGETTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterfvATI")) == NULL) || r; + r = ((glGetTexBumpParameterivATI = (PFNGLGETTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterivATI")) == NULL) || r; + r = ((glTexBumpParameterfvATI = (PFNGLTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterfvATI")) == NULL) || r; + r = ((glTexBumpParameterivATI = (PFNGLTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterivATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_envmap_bumpmap */ + +#ifdef GL_ATI_fragment_shader + +static GLboolean _glewInit_GL_ATI_fragment_shader () +{ + GLboolean r = GL_FALSE; + + r = ((glAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp1ATI")) == NULL) || r; + r = ((glAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp2ATI")) == NULL) || r; + r = ((glAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp3ATI")) == NULL) || r; + r = ((glBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBeginFragmentShaderATI")) == NULL) || r; + r = ((glBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBindFragmentShaderATI")) == NULL) || r; + r = ((glColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp1ATI")) == NULL) || r; + r = ((glColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp2ATI")) == NULL) || r; + r = ((glColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp3ATI")) == NULL) || r; + r = ((glDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glDeleteFragmentShaderATI")) == NULL) || r; + r = ((glEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glEndFragmentShaderATI")) == NULL) || r; + r = ((glGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)glewGetProcAddress((const GLubyte*)"glGenFragmentShadersATI")) == NULL) || r; + r = ((glPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)glewGetProcAddress((const GLubyte*)"glPassTexCoordATI")) == NULL) || r; + r = ((glSampleMapATI = (PFNGLSAMPLEMAPATIPROC)glewGetProcAddress((const GLubyte*)"glSampleMapATI")) == NULL) || r; + r = ((glSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)glewGetProcAddress((const GLubyte*)"glSetFragmentShaderConstantATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_fragment_shader */ + +#ifdef GL_ATI_map_object_buffer + +static GLboolean _glewInit_GL_ATI_map_object_buffer () +{ + GLboolean r = GL_FALSE; + + r = ((glMapObjectBufferATI = (PFNGLMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glMapObjectBufferATI")) == NULL) || r; + r = ((glUnmapObjectBufferATI = (PFNGLUNMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUnmapObjectBufferATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_map_object_buffer */ + +#ifdef GL_ATI_pn_triangles + +static GLboolean _glewInit_GL_ATI_pn_triangles () +{ + GLboolean r = GL_FALSE; + + r = ((glPNTrianglesfATI = (PFNGLPNTRIANGLESFATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesfATI")) == NULL) || r; + r = ((glPNTrianglesiATI = (PFNGLPNTRIANGLESIATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesiATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_pn_triangles */ + +#ifdef GL_ATI_separate_stencil + +static GLboolean _glewInit_GL_ATI_separate_stencil () +{ + GLboolean r = GL_FALSE; + + r = ((glStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparateATI")) == NULL) || r; + r = ((glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparateATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_separate_stencil */ + +#ifdef GL_ATI_vertex_array_object + +static GLboolean _glewInit_GL_ATI_vertex_array_object () +{ + GLboolean r = GL_FALSE; + + r = ((glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glArrayObjectATI")) == NULL) || r; + r = ((glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glFreeObjectBufferATI")) == NULL) || r; + r = ((glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectfvATI")) == NULL) || r; + r = ((glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectivATI")) == NULL) || r; + r = ((glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferfvATI")) == NULL) || r; + r = ((glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferivATI")) == NULL) || r; + r = ((glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectfvATI")) == NULL) || r; + r = ((glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectivATI")) == NULL) || r; + r = ((glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glIsObjectBufferATI")) == NULL) || r; + r = ((glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glNewObjectBufferATI")) == NULL) || r; + r = ((glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUpdateObjectBufferATI")) == NULL) || r; + r = ((glVariantArrayObjectATI = (PFNGLVARIANTARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVariantArrayObjectATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_array_object */ + +#ifdef GL_ATI_vertex_attrib_array_object + +static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object () +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribArrayObjectfvATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectfvATI")) == NULL) || r; + r = ((glGetVertexAttribArrayObjectivATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectivATI")) == NULL) || r; + r = ((glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribArrayObjectATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_attrib_array_object */ + +#ifdef GL_ATI_vertex_streams + +static GLboolean _glewInit_GL_ATI_vertex_streams () +{ + GLboolean r = GL_FALSE; + + r = ((glClientActiveVertexStreamATI = (PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC)glewGetProcAddress((const GLubyte*)"glClientActiveVertexStreamATI")) == NULL) || r; + r = ((glNormalStream3bATI = (PFNGLNORMALSTREAM3BATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bATI")) == NULL) || r; + r = ((glNormalStream3bvATI = (PFNGLNORMALSTREAM3BVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bvATI")) == NULL) || r; + r = ((glNormalStream3dATI = (PFNGLNORMALSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dATI")) == NULL) || r; + r = ((glNormalStream3dvATI = (PFNGLNORMALSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dvATI")) == NULL) || r; + r = ((glNormalStream3fATI = (PFNGLNORMALSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fATI")) == NULL) || r; + r = ((glNormalStream3fvATI = (PFNGLNORMALSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fvATI")) == NULL) || r; + r = ((glNormalStream3iATI = (PFNGLNORMALSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3iATI")) == NULL) || r; + r = ((glNormalStream3ivATI = (PFNGLNORMALSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3ivATI")) == NULL) || r; + r = ((glNormalStream3sATI = (PFNGLNORMALSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3sATI")) == NULL) || r; + r = ((glNormalStream3svATI = (PFNGLNORMALSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3svATI")) == NULL) || r; + r = ((glVertexBlendEnvfATI = (PFNGLVERTEXBLENDENVFATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnvfATI")) == NULL) || r; + r = ((glVertexBlendEnviATI = (PFNGLVERTEXBLENDENVIATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnviATI")) == NULL) || r; + r = ((glVertexStream1dATI = (PFNGLVERTEXSTREAM1DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1dATI")) == NULL) || r; + r = ((glVertexStream1dvATI = (PFNGLVERTEXSTREAM1DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1dvATI")) == NULL) || r; + r = ((glVertexStream1fATI = (PFNGLVERTEXSTREAM1FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1fATI")) == NULL) || r; + r = ((glVertexStream1fvATI = (PFNGLVERTEXSTREAM1FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1fvATI")) == NULL) || r; + r = ((glVertexStream1iATI = (PFNGLVERTEXSTREAM1IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1iATI")) == NULL) || r; + r = ((glVertexStream1ivATI = (PFNGLVERTEXSTREAM1IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1ivATI")) == NULL) || r; + r = ((glVertexStream1sATI = (PFNGLVERTEXSTREAM1SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1sATI")) == NULL) || r; + r = ((glVertexStream1svATI = (PFNGLVERTEXSTREAM1SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1svATI")) == NULL) || r; + r = ((glVertexStream2dATI = (PFNGLVERTEXSTREAM2DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dATI")) == NULL) || r; + r = ((glVertexStream2dvATI = (PFNGLVERTEXSTREAM2DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dvATI")) == NULL) || r; + r = ((glVertexStream2fATI = (PFNGLVERTEXSTREAM2FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fATI")) == NULL) || r; + r = ((glVertexStream2fvATI = (PFNGLVERTEXSTREAM2FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fvATI")) == NULL) || r; + r = ((glVertexStream2iATI = (PFNGLVERTEXSTREAM2IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2iATI")) == NULL) || r; + r = ((glVertexStream2ivATI = (PFNGLVERTEXSTREAM2IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2ivATI")) == NULL) || r; + r = ((glVertexStream2sATI = (PFNGLVERTEXSTREAM2SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2sATI")) == NULL) || r; + r = ((glVertexStream2svATI = (PFNGLVERTEXSTREAM2SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2svATI")) == NULL) || r; + r = ((glVertexStream3dATI = (PFNGLVERTEXSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dATI")) == NULL) || r; + r = ((glVertexStream3dvATI = (PFNGLVERTEXSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dvATI")) == NULL) || r; + r = ((glVertexStream3fATI = (PFNGLVERTEXSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fATI")) == NULL) || r; + r = ((glVertexStream3fvATI = (PFNGLVERTEXSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fvATI")) == NULL) || r; + r = ((glVertexStream3iATI = (PFNGLVERTEXSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3iATI")) == NULL) || r; + r = ((glVertexStream3ivATI = (PFNGLVERTEXSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3ivATI")) == NULL) || r; + r = ((glVertexStream3sATI = (PFNGLVERTEXSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3sATI")) == NULL) || r; + r = ((glVertexStream3svATI = (PFNGLVERTEXSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3svATI")) == NULL) || r; + r = ((glVertexStream4dATI = (PFNGLVERTEXSTREAM4DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dATI")) == NULL) || r; + r = ((glVertexStream4dvATI = (PFNGLVERTEXSTREAM4DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dvATI")) == NULL) || r; + r = ((glVertexStream4fATI = (PFNGLVERTEXSTREAM4FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fATI")) == NULL) || r; + r = ((glVertexStream4fvATI = (PFNGLVERTEXSTREAM4FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fvATI")) == NULL) || r; + r = ((glVertexStream4iATI = (PFNGLVERTEXSTREAM4IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4iATI")) == NULL) || r; + r = ((glVertexStream4ivATI = (PFNGLVERTEXSTREAM4IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4ivATI")) == NULL) || r; + r = ((glVertexStream4sATI = (PFNGLVERTEXSTREAM4SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4sATI")) == NULL) || r; + r = ((glVertexStream4svATI = (PFNGLVERTEXSTREAM4SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4svATI")) == NULL) || r; + + return r; +} + +#endif /* GL_ATI_vertex_streams */ + +#ifdef GL_EXT_base_instance + +static GLboolean _glewInit_GL_EXT_base_instance () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedBaseInstanceEXT = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedBaseInstanceEXT")) == NULL) || r; + r = ((glDrawElementsInstancedBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseInstanceEXT")) == NULL) || r; + r = ((glDrawElementsInstancedBaseVertexBaseInstanceEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertexBaseInstanceEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_base_instance */ + +#ifdef GL_EXT_bindable_uniform + +static GLboolean _glewInit_GL_EXT_bindable_uniform () +{ + GLboolean r = GL_FALSE; + + r = ((glGetUniformBufferSizeEXT = (PFNGLGETUNIFORMBUFFERSIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBufferSizeEXT")) == NULL) || r; + r = ((glGetUniformOffsetEXT = (PFNGLGETUNIFORMOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformOffsetEXT")) == NULL) || r; + r = ((glUniformBufferEXT = (PFNGLUNIFORMBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUniformBufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_bindable_uniform */ + +#ifdef GL_EXT_blend_color + +static GLboolean _glewInit_GL_EXT_blend_color () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC)glewGetProcAddress((const GLubyte*)"glBlendColorEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_color */ + +#ifdef GL_EXT_blend_equation_separate + +static GLboolean _glewInit_GL_EXT_blend_equation_separate () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_equation_separate */ + +#ifdef GL_EXT_blend_func_extended + +static GLboolean _glewInit_GL_EXT_blend_func_extended () +{ + GLboolean r = GL_FALSE; + + r = ((glBindFragDataLocationIndexedEXT = (PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationIndexedEXT")) == NULL) || r; + r = ((glGetFragDataIndexEXT = (PFNGLGETFRAGDATAINDEXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataIndexEXT")) == NULL) || r; + r = ((glGetProgramResourceLocationIndexEXT = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocationIndexEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_func_extended */ + +#ifdef GL_EXT_blend_func_separate + +static GLboolean _glewInit_GL_EXT_blend_func_separate () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_func_separate */ + +#ifdef GL_EXT_blend_minmax + +static GLboolean _glewInit_GL_EXT_blend_minmax () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_blend_minmax */ + +#ifdef GL_EXT_buffer_storage + +static GLboolean _glewInit_GL_EXT_buffer_storage () +{ + GLboolean r = GL_FALSE; + + r = ((glBufferStorageEXT = (PFNGLBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferStorageEXT")) == NULL) || r; + r = ((glNamedBufferStorageEXT = (PFNGLNAMEDBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorageEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_buffer_storage */ + +#ifdef GL_EXT_clear_texture + +static GLboolean _glewInit_GL_EXT_clear_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glClearTexImageEXT = (PFNGLCLEARTEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glClearTexImageEXT")) == NULL) || r; + r = ((glClearTexSubImageEXT = (PFNGLCLEARTEXSUBIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glClearTexSubImageEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_clear_texture */ + +#ifdef GL_EXT_color_subtable + +static GLboolean _glewInit_GL_EXT_color_subtable () +{ + GLboolean r = GL_FALSE; + + r = ((glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorSubTableEXT")) == NULL) || r; + r = ((glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTableEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_color_subtable */ + +#ifdef GL_EXT_compiled_vertex_array + +static GLboolean _glewInit_GL_EXT_compiled_vertex_array () +{ + GLboolean r = GL_FALSE; + + r = ((glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glLockArraysEXT")) == NULL) || r; + r = ((glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glUnlockArraysEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_compiled_vertex_array */ + +#ifdef GL_EXT_convolution + +static GLboolean _glewInit_GL_EXT_convolution () +{ + GLboolean r = GL_FALSE; + + r = ((glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1DEXT")) == NULL) || r; + r = ((glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2DEXT")) == NULL) || r; + r = ((glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfEXT")) == NULL) || r; + r = ((glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfvEXT")) == NULL) || r; + r = ((glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriEXT")) == NULL) || r; + r = ((glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterivEXT")) == NULL) || r; + r = ((glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1DEXT")) == NULL) || r; + r = ((glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2DEXT")) == NULL) || r; + r = ((glGetConvolutionFilterEXT = (PFNGLGETCONVOLUTIONFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilterEXT")) == NULL) || r; + r = ((glGetConvolutionParameterfvEXT = (PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfvEXT")) == NULL) || r; + r = ((glGetConvolutionParameterivEXT = (PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterivEXT")) == NULL) || r; + r = ((glGetSeparableFilterEXT = (PFNGLGETSEPARABLEFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilterEXT")) == NULL) || r; + r = ((glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_convolution */ + +#ifdef GL_EXT_coordinate_frame + +static GLboolean _glewInit_GL_EXT_coordinate_frame () +{ + GLboolean r = GL_FALSE; + + r = ((glBinormalPointerEXT = (PFNGLBINORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glBinormalPointerEXT")) == NULL) || r; + r = ((glTangentPointerEXT = (PFNGLTANGENTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTangentPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_coordinate_frame */ + +#ifdef GL_EXT_copy_image + +static GLboolean _glewInit_GL_EXT_copy_image () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyImageSubDataEXT = (PFNGLCOPYIMAGESUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubDataEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_copy_image */ + +#ifdef GL_EXT_copy_texture + +static GLboolean _glewInit_GL_EXT_copy_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage1DEXT")) == NULL) || r; + r = ((glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage2DEXT")) == NULL) || r; + r = ((glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage1DEXT")) == NULL) || r; + r = ((glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage2DEXT")) == NULL) || r; + r = ((glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_copy_texture */ + +#ifdef GL_EXT_cull_vertex + +static GLboolean _glewInit_GL_EXT_cull_vertex () +{ + GLboolean r = GL_FALSE; + + r = ((glCullParameterdvEXT = (PFNGLCULLPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterdvEXT")) == NULL) || r; + r = ((glCullParameterfvEXT = (PFNGLCULLPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_cull_vertex */ + +#ifdef GL_EXT_debug_label + +static GLboolean _glewInit_GL_EXT_debug_label () +{ + GLboolean r = GL_FALSE; + + r = ((glGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC)glewGetProcAddress((const GLubyte*)"glGetObjectLabelEXT")) == NULL) || r; + r = ((glLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC)glewGetProcAddress((const GLubyte*)"glLabelObjectEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_debug_label */ + +#ifdef GL_EXT_debug_marker + +static GLboolean _glewInit_GL_EXT_debug_marker () +{ + GLboolean r = GL_FALSE; + + r = ((glInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glInsertEventMarkerEXT")) == NULL) || r; + r = ((glPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glPopGroupMarkerEXT")) == NULL) || r; + r = ((glPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glPushGroupMarkerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_debug_marker */ + +#ifdef GL_EXT_depth_bounds_test + +static GLboolean _glewInit_GL_EXT_depth_bounds_test () +{ + GLboolean r = GL_FALSE; + + r = ((glDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_depth_bounds_test */ + +#ifdef GL_EXT_direct_state_access + +static GLboolean _glewInit_GL_EXT_direct_state_access () +{ + GLboolean r = GL_FALSE; + + r = ((glBindMultiTextureEXT = (PFNGLBINDMULTITEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindMultiTextureEXT")) == NULL) || r; + r = ((glCheckNamedFramebufferStatusEXT = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckNamedFramebufferStatusEXT")) == NULL) || r; + r = ((glClientAttribDefaultEXT = (PFNGLCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glClientAttribDefaultEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage1DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage1DEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage2DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage2DEXT")) == NULL) || r; + r = ((glCompressedMultiTexImage3DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage3DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage1DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage2DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glCompressedMultiTexSubImage3DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glCompressedTextureImage1DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage1DEXT")) == NULL) || r; + r = ((glCompressedTextureImage2DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage2DEXT")) == NULL) || r; + r = ((glCompressedTextureImage3DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage3DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage1DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage1DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage2DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage2DEXT")) == NULL) || r; + r = ((glCompressedTextureSubImage3DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage3DEXT")) == NULL) || r; + r = ((glCopyMultiTexImage1DEXT = (PFNGLCOPYMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage1DEXT")) == NULL) || r; + r = ((glCopyMultiTexImage2DEXT = (PFNGLCOPYMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage2DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage1DEXT = (PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage2DEXT = (PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glCopyMultiTexSubImage3DEXT = (PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glCopyTextureImage1DEXT = (PFNGLCOPYTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage1DEXT")) == NULL) || r; + r = ((glCopyTextureImage2DEXT = (PFNGLCOPYTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage2DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage1DEXT = (PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage1DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2DEXT")) == NULL) || r; + r = ((glCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3DEXT")) == NULL) || r; + r = ((glDisableClientStateIndexedEXT = (PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateIndexedEXT")) == NULL) || r; + r = ((glDisableClientStateiEXT = (PFNGLDISABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateiEXT")) == NULL) || r; + r = ((glDisableVertexArrayAttribEXT = (PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayAttribEXT")) == NULL) || r; + r = ((glDisableVertexArrayEXT = (PFNGLDISABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayEXT")) == NULL) || r; + r = ((glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateIndexedEXT")) == NULL) || r; + r = ((glEnableClientStateiEXT = (PFNGLENABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateiEXT")) == NULL) || r; + r = ((glEnableVertexArrayAttribEXT = (PFNGLENABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayAttribEXT")) == NULL) || r; + r = ((glEnableVertexArrayEXT = (PFNGLENABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayEXT")) == NULL) || r; + r = ((glFlushMappedNamedBufferRangeEXT = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedNamedBufferRangeEXT")) == NULL) || r; + r = ((glFramebufferDrawBufferEXT = (PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBufferEXT")) == NULL) || r; + r = ((glFramebufferDrawBuffersEXT = (PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBuffersEXT")) == NULL) || r; + r = ((glFramebufferReadBufferEXT = (PFNGLFRAMEBUFFERREADBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferReadBufferEXT")) == NULL) || r; + r = ((glGenerateMultiTexMipmapEXT = (PFNGLGENERATEMULTITEXMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMultiTexMipmapEXT")) == NULL) || r; + r = ((glGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateTextureMipmapEXT")) == NULL) || r; + r = ((glGetCompressedMultiTexImageEXT = (PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedMultiTexImageEXT")) == NULL) || r; + r = ((glGetCompressedTextureImageEXT = (PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImageEXT")) == NULL) || r; + r = ((glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoubleIndexedvEXT")) == NULL) || r; + r = ((glGetDoublei_vEXT = (PFNGLGETDOUBLEI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_vEXT")) == NULL) || r; + r = ((glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloatIndexedvEXT")) == NULL) || r; + r = ((glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_vEXT")) == NULL) || r; + r = ((glGetFramebufferParameterivEXT = (PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterivEXT")) == NULL) || r; + r = ((glGetMultiTexEnvfvEXT = (PFNGLGETMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvfvEXT")) == NULL) || r; + r = ((glGetMultiTexEnvivEXT = (PFNGLGETMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvivEXT")) == NULL) || r; + r = ((glGetMultiTexGendvEXT = (PFNGLGETMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGendvEXT")) == NULL) || r; + r = ((glGetMultiTexGenfvEXT = (PFNGLGETMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenfvEXT")) == NULL) || r; + r = ((glGetMultiTexGenivEXT = (PFNGLGETMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenivEXT")) == NULL) || r; + r = ((glGetMultiTexImageEXT = (PFNGLGETMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexImageEXT")) == NULL) || r; + r = ((glGetMultiTexLevelParameterfvEXT = (PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterfvEXT")) == NULL) || r; + r = ((glGetMultiTexLevelParameterivEXT = (PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterIivEXT = (PFNGLGETMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterIuivEXT = (PFNGLGETMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIuivEXT")) == NULL) || r; + r = ((glGetMultiTexParameterfvEXT = (PFNGLGETMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterfvEXT")) == NULL) || r; + r = ((glGetMultiTexParameterivEXT = (PFNGLGETMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterivEXT")) == NULL) || r; + r = ((glGetNamedBufferParameterivEXT = (PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterivEXT")) == NULL) || r; + r = ((glGetNamedBufferPointervEXT = (PFNGLGETNAMEDBUFFERPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferPointervEXT")) == NULL) || r; + r = ((glGetNamedBufferSubDataEXT = (PFNGLGETNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferSubDataEXT")) == NULL) || r; + r = ((glGetNamedFramebufferAttachmentParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferAttachmentParameterivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterIivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterIuivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIuivEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterdvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterdvEXT")) == NULL) || r; + r = ((glGetNamedProgramLocalParameterfvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterfvEXT")) == NULL) || r; + r = ((glGetNamedProgramStringEXT = (PFNGLGETNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramStringEXT")) == NULL) || r; + r = ((glGetNamedProgramivEXT = (PFNGLGETNAMEDPROGRAMIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramivEXT")) == NULL) || r; + r = ((glGetNamedRenderbufferParameterivEXT = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameterivEXT")) == NULL) || r; + r = ((glGetPointerIndexedvEXT = (PFNGLGETPOINTERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointerIndexedvEXT")) == NULL) || r; + r = ((glGetPointeri_vEXT = (PFNGLGETPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointeri_vEXT")) == NULL) || r; + r = ((glGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImageEXT")) == NULL) || r; + r = ((glGetTextureLevelParameterfvEXT = (PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfvEXT")) == NULL) || r; + r = ((glGetTextureLevelParameterivEXT = (PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterivEXT")) == NULL) || r; + r = ((glGetTextureParameterIivEXT = (PFNGLGETTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIivEXT")) == NULL) || r; + r = ((glGetTextureParameterIuivEXT = (PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuivEXT")) == NULL) || r; + r = ((glGetTextureParameterfvEXT = (PFNGLGETTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfvEXT")) == NULL) || r; + r = ((glGetTextureParameterivEXT = (PFNGLGETTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterivEXT")) == NULL) || r; + r = ((glGetVertexArrayIntegeri_vEXT = (PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegeri_vEXT")) == NULL) || r; + r = ((glGetVertexArrayIntegervEXT = (PFNGLGETVERTEXARRAYINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegervEXT")) == NULL) || r; + r = ((glGetVertexArrayPointeri_vEXT = (PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointeri_vEXT")) == NULL) || r; + r = ((glGetVertexArrayPointervEXT = (PFNGLGETVERTEXARRAYPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointervEXT")) == NULL) || r; + r = ((glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferEXT")) == NULL) || r; + r = ((glMapNamedBufferRangeEXT = (PFNGLMAPNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferRangeEXT")) == NULL) || r; + r = ((glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixFrustumEXT")) == NULL) || r; + r = ((glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadIdentityEXT")) == NULL) || r; + r = ((glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposedEXT")) == NULL) || r; + r = ((glMatrixLoadTransposefEXT = (PFNGLMATRIXLOADTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposefEXT")) == NULL) || r; + r = ((glMatrixLoaddEXT = (PFNGLMATRIXLOADDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoaddEXT")) == NULL) || r; + r = ((glMatrixLoadfEXT = (PFNGLMATRIXLOADFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadfEXT")) == NULL) || r; + r = ((glMatrixMultTransposedEXT = (PFNGLMATRIXMULTTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposedEXT")) == NULL) || r; + r = ((glMatrixMultTransposefEXT = (PFNGLMATRIXMULTTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposefEXT")) == NULL) || r; + r = ((glMatrixMultdEXT = (PFNGLMATRIXMULTDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultdEXT")) == NULL) || r; + r = ((glMatrixMultfEXT = (PFNGLMATRIXMULTFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultfEXT")) == NULL) || r; + r = ((glMatrixOrthoEXT = (PFNGLMATRIXORTHOEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixOrthoEXT")) == NULL) || r; + r = ((glMatrixPopEXT = (PFNGLMATRIXPOPEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPopEXT")) == NULL) || r; + r = ((glMatrixPushEXT = (PFNGLMATRIXPUSHEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPushEXT")) == NULL) || r; + r = ((glMatrixRotatedEXT = (PFNGLMATRIXROTATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatedEXT")) == NULL) || r; + r = ((glMatrixRotatefEXT = (PFNGLMATRIXROTATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatefEXT")) == NULL) || r; + r = ((glMatrixScaledEXT = (PFNGLMATRIXSCALEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScaledEXT")) == NULL) || r; + r = ((glMatrixScalefEXT = (PFNGLMATRIXSCALEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScalefEXT")) == NULL) || r; + r = ((glMatrixTranslatedEXT = (PFNGLMATRIXTRANSLATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatedEXT")) == NULL) || r; + r = ((glMatrixTranslatefEXT = (PFNGLMATRIXTRANSLATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatefEXT")) == NULL) || r; + r = ((glMultiTexBufferEXT = (PFNGLMULTITEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexBufferEXT")) == NULL) || r; + r = ((glMultiTexCoordPointerEXT = (PFNGLMULTITEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordPointerEXT")) == NULL) || r; + r = ((glMultiTexEnvfEXT = (PFNGLMULTITEXENVFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfEXT")) == NULL) || r; + r = ((glMultiTexEnvfvEXT = (PFNGLMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfvEXT")) == NULL) || r; + r = ((glMultiTexEnviEXT = (PFNGLMULTITEXENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnviEXT")) == NULL) || r; + r = ((glMultiTexEnvivEXT = (PFNGLMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvivEXT")) == NULL) || r; + r = ((glMultiTexGendEXT = (PFNGLMULTITEXGENDEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendEXT")) == NULL) || r; + r = ((glMultiTexGendvEXT = (PFNGLMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendvEXT")) == NULL) || r; + r = ((glMultiTexGenfEXT = (PFNGLMULTITEXGENFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfEXT")) == NULL) || r; + r = ((glMultiTexGenfvEXT = (PFNGLMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfvEXT")) == NULL) || r; + r = ((glMultiTexGeniEXT = (PFNGLMULTITEXGENIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGeniEXT")) == NULL) || r; + r = ((glMultiTexGenivEXT = (PFNGLMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenivEXT")) == NULL) || r; + r = ((glMultiTexImage1DEXT = (PFNGLMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage1DEXT")) == NULL) || r; + r = ((glMultiTexImage2DEXT = (PFNGLMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage2DEXT")) == NULL) || r; + r = ((glMultiTexImage3DEXT = (PFNGLMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage3DEXT")) == NULL) || r; + r = ((glMultiTexParameterIivEXT = (PFNGLMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIivEXT")) == NULL) || r; + r = ((glMultiTexParameterIuivEXT = (PFNGLMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIuivEXT")) == NULL) || r; + r = ((glMultiTexParameterfEXT = (PFNGLMULTITEXPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfEXT")) == NULL) || r; + r = ((glMultiTexParameterfvEXT = (PFNGLMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfvEXT")) == NULL) || r; + r = ((glMultiTexParameteriEXT = (PFNGLMULTITEXPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameteriEXT")) == NULL) || r; + r = ((glMultiTexParameterivEXT = (PFNGLMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterivEXT")) == NULL) || r; + r = ((glMultiTexRenderbufferEXT = (PFNGLMULTITEXRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexRenderbufferEXT")) == NULL) || r; + r = ((glMultiTexSubImage1DEXT = (PFNGLMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage1DEXT")) == NULL) || r; + r = ((glMultiTexSubImage2DEXT = (PFNGLMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage2DEXT")) == NULL) || r; + r = ((glMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage3DEXT")) == NULL) || r; + r = ((glNamedBufferDataEXT = (PFNGLNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferDataEXT")) == NULL) || r; + r = ((glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubDataEXT")) == NULL) || r; + r = ((glNamedCopyBufferSubDataEXT = (PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedCopyBufferSubDataEXT")) == NULL) || r; + r = ((glNamedFramebufferRenderbufferEXT = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbufferEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture1DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture1DEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture2DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture2DEXT")) == NULL) || r; + r = ((glNamedFramebufferTexture3DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture3DEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureFaceEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureFaceEXT")) == NULL) || r; + r = ((glNamedFramebufferTextureLayerEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureLayerEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4dEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4dvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4fEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameter4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4iEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4iEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4ivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4uiEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uiEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameterI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParameters4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameters4fvEXT")) == NULL) || r; + r = ((glNamedProgramLocalParametersI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4ivEXT")) == NULL) || r; + r = ((glNamedProgramLocalParametersI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4uivEXT")) == NULL) || r; + r = ((glNamedProgramStringEXT = (PFNGLNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramStringEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageMultisampleCoverageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleCoverageEXT")) == NULL) || r; + r = ((glNamedRenderbufferStorageMultisampleEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleEXT")) == NULL) || r; + r = ((glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fEXT")) == NULL) || r; + r = ((glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fvEXT")) == NULL) || r; + r = ((glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iEXT")) == NULL) || r; + r = ((glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ivEXT")) == NULL) || r; + r = ((glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiEXT")) == NULL) || r; + r = ((glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uivEXT")) == NULL) || r; + r = ((glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fEXT")) == NULL) || r; + r = ((glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fvEXT")) == NULL) || r; + r = ((glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iEXT")) == NULL) || r; + r = ((glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ivEXT")) == NULL) || r; + r = ((glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiEXT")) == NULL) || r; + r = ((glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uivEXT")) == NULL) || r; + r = ((glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fEXT")) == NULL) || r; + r = ((glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fvEXT")) == NULL) || r; + r = ((glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iEXT")) == NULL) || r; + r = ((glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ivEXT")) == NULL) || r; + r = ((glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiEXT")) == NULL) || r; + r = ((glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uivEXT")) == NULL) || r; + r = ((glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fEXT")) == NULL) || r; + r = ((glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fvEXT")) == NULL) || r; + r = ((glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iEXT")) == NULL) || r; + r = ((glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ivEXT")) == NULL) || r; + r = ((glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiEXT")) == NULL) || r; + r = ((glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uivEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fvEXT")) == NULL) || r; + r = ((glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fvEXT")) == NULL) || r; + r = ((glPushClientAttribDefaultEXT = (PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glPushClientAttribDefaultEXT")) == NULL) || r; + r = ((glTextureBufferEXT = (PFNGLTEXTUREBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferEXT")) == NULL) || r; + r = ((glTextureImage1DEXT = (PFNGLTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage1DEXT")) == NULL) || r; + r = ((glTextureImage2DEXT = (PFNGLTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DEXT")) == NULL) || r; + r = ((glTextureImage3DEXT = (PFNGLTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DEXT")) == NULL) || r; + r = ((glTextureParameterIivEXT = (PFNGLTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIivEXT")) == NULL) || r; + r = ((glTextureParameterIuivEXT = (PFNGLTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIuivEXT")) == NULL) || r; + r = ((glTextureParameterfEXT = (PFNGLTEXTUREPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfEXT")) == NULL) || r; + r = ((glTextureParameterfvEXT = (PFNGLTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfvEXT")) == NULL) || r; + r = ((glTextureParameteriEXT = (PFNGLTEXTUREPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteriEXT")) == NULL) || r; + r = ((glTextureParameterivEXT = (PFNGLTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterivEXT")) == NULL) || r; + r = ((glTextureRenderbufferEXT = (PFNGLTEXTURERENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureRenderbufferEXT")) == NULL) || r; + r = ((glTextureSubImage1DEXT = (PFNGLTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage1DEXT")) == NULL) || r; + r = ((glTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2DEXT")) == NULL) || r; + r = ((glTextureSubImage3DEXT = (PFNGLTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3DEXT")) == NULL) || r; + r = ((glUnmapNamedBufferEXT = (PFNGLUNMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBufferEXT")) == NULL) || r; + r = ((glVertexArrayColorOffsetEXT = (PFNGLVERTEXARRAYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayColorOffsetEXT")) == NULL) || r; + r = ((glVertexArrayEdgeFlagOffsetEXT = (PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayEdgeFlagOffsetEXT")) == NULL) || r; + r = ((glVertexArrayFogCoordOffsetEXT = (PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayFogCoordOffsetEXT")) == NULL) || r; + r = ((glVertexArrayIndexOffsetEXT = (PFNGLVERTEXARRAYINDEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayIndexOffsetEXT")) == NULL) || r; + r = ((glVertexArrayMultiTexCoordOffsetEXT = (PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayMultiTexCoordOffsetEXT")) == NULL) || r; + r = ((glVertexArrayNormalOffsetEXT = (PFNGLVERTEXARRAYNORMALOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayNormalOffsetEXT")) == NULL) || r; + r = ((glVertexArraySecondaryColorOffsetEXT = (PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArraySecondaryColorOffsetEXT")) == NULL) || r; + r = ((glVertexArrayTexCoordOffsetEXT = (PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayTexCoordOffsetEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribDivisorEXT = (PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribDivisorEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribIOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribIOffsetEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribOffsetEXT")) == NULL) || r; + r = ((glVertexArrayVertexOffsetEXT = (PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexOffsetEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_direct_state_access */ + +#ifdef GL_EXT_discard_framebuffer + +static GLboolean _glewInit_GL_EXT_discard_framebuffer () +{ + GLboolean r = GL_FALSE; + + r = ((glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glDiscardFramebufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_discard_framebuffer */ + +#ifdef GL_EXT_draw_buffers + +static GLboolean _glewInit_GL_EXT_draw_buffers () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersEXT = (PFNGLDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_buffers */ + +#ifdef GL_EXT_draw_buffers2 + +static GLboolean _glewInit_GL_EXT_draw_buffers2 () +{ + GLboolean r = GL_FALSE; + + r = ((glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glColorMaskIndexedEXT")) == NULL) || r; + r = ((glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableIndexedEXT")) == NULL) || r; + r = ((glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableIndexedEXT")) == NULL) || r; + r = ((glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetBooleanIndexedvEXT")) == NULL) || r; + r = ((glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerIndexedvEXT")) == NULL) || r; + r = ((glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledIndexedEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_buffers2 */ + +#ifdef GL_EXT_draw_buffers_indexed + +static GLboolean _glewInit_GL_EXT_draw_buffers_indexed () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendEquationSeparateiEXT = (PFNGLBLENDEQUATIONSEPARATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateiEXT")) == NULL) || r; + r = ((glBlendEquationiEXT = (PFNGLBLENDEQUATIONIEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationiEXT")) == NULL) || r; + r = ((glBlendFuncSeparateiEXT = (PFNGLBLENDFUNCSEPARATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateiEXT")) == NULL) || r; + r = ((glBlendFunciEXT = (PFNGLBLENDFUNCIEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFunciEXT")) == NULL) || r; + r = ((glColorMaskiEXT = (PFNGLCOLORMASKIEXTPROC)glewGetProcAddress((const GLubyte*)"glColorMaskiEXT")) == NULL) || r; + r = ((glDisableiEXT = (PFNGLDISABLEIEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableiEXT")) == NULL) || r; + r = ((glEnableiEXT = (PFNGLENABLEIEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableiEXT")) == NULL) || r; + r = ((glIsEnablediEXT = (PFNGLISENABLEDIEXTPROC)glewGetProcAddress((const GLubyte*)"glIsEnablediEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_buffers_indexed */ + +#ifdef GL_EXT_draw_elements_base_vertex + +static GLboolean _glewInit_GL_EXT_draw_elements_base_vertex () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawElementsBaseVertexEXT = (PFNGLDRAWELEMENTSBASEVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsBaseVertexEXT")) == NULL) || r; + r = ((glDrawElementsInstancedBaseVertexEXT = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertexEXT")) == NULL) || r; + r = ((glDrawRangeElementsBaseVertexEXT = (PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsBaseVertexEXT")) == NULL) || r; + r = ((glMultiDrawElementsBaseVertexEXT = (PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsBaseVertexEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_elements_base_vertex */ + +#ifdef GL_EXT_draw_instanced + +static GLboolean _glewInit_GL_EXT_draw_instanced () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedEXT")) == NULL) || r; + r = ((glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_instanced */ + +#ifdef GL_EXT_draw_range_elements + +static GLboolean _glewInit_GL_EXT_draw_range_elements () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_draw_range_elements */ + +#ifdef GL_EXT_external_buffer + +static GLboolean _glewInit_GL_EXT_external_buffer () +{ + GLboolean r = GL_FALSE; + + r = ((glBufferStorageExternalEXT = (PFNGLBUFFERSTORAGEEXTERNALEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferStorageExternalEXT")) == NULL) || r; + r = ((glNamedBufferStorageExternalEXT = (PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorageExternalEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_external_buffer */ + +#ifdef GL_EXT_fog_coord + +static GLboolean _glewInit_GL_EXT_fog_coord () +{ + GLboolean r = GL_FALSE; + + r = ((glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerEXT")) == NULL) || r; + r = ((glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddEXT")) == NULL) || r; + r = ((glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddvEXT")) == NULL) || r; + r = ((glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfEXT")) == NULL) || r; + r = ((glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_fog_coord */ + +#ifdef GL_EXT_fragment_lighting + +static GLboolean _glewInit_GL_EXT_fragment_lighting () +{ + GLboolean r = GL_FALSE; + + r = ((glFragmentColorMaterialEXT = (PFNGLFRAGMENTCOLORMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialEXT")) == NULL) || r; + r = ((glFragmentLightModelfEXT = (PFNGLFRAGMENTLIGHTMODELFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfEXT")) == NULL) || r; + r = ((glFragmentLightModelfvEXT = (PFNGLFRAGMENTLIGHTMODELFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvEXT")) == NULL) || r; + r = ((glFragmentLightModeliEXT = (PFNGLFRAGMENTLIGHTMODELIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliEXT")) == NULL) || r; + r = ((glFragmentLightModelivEXT = (PFNGLFRAGMENTLIGHTMODELIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivEXT")) == NULL) || r; + r = ((glFragmentLightfEXT = (PFNGLFRAGMENTLIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfEXT")) == NULL) || r; + r = ((glFragmentLightfvEXT = (PFNGLFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvEXT")) == NULL) || r; + r = ((glFragmentLightiEXT = (PFNGLFRAGMENTLIGHTIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiEXT")) == NULL) || r; + r = ((glFragmentLightivEXT = (PFNGLFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivEXT")) == NULL) || r; + r = ((glFragmentMaterialfEXT = (PFNGLFRAGMENTMATERIALFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfEXT")) == NULL) || r; + r = ((glFragmentMaterialfvEXT = (PFNGLFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvEXT")) == NULL) || r; + r = ((glFragmentMaterialiEXT = (PFNGLFRAGMENTMATERIALIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiEXT")) == NULL) || r; + r = ((glFragmentMaterialivEXT = (PFNGLFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivEXT")) == NULL) || r; + r = ((glGetFragmentLightfvEXT = (PFNGLGETFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvEXT")) == NULL) || r; + r = ((glGetFragmentLightivEXT = (PFNGLGETFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivEXT")) == NULL) || r; + r = ((glGetFragmentMaterialfvEXT = (PFNGLGETFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvEXT")) == NULL) || r; + r = ((glGetFragmentMaterialivEXT = (PFNGLGETFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivEXT")) == NULL) || r; + r = ((glLightEnviEXT = (PFNGLLIGHTENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glLightEnviEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_fragment_lighting */ + +#ifdef GL_EXT_framebuffer_blit + +static GLboolean _glewInit_GL_EXT_framebuffer_blit () +{ + GLboolean r = GL_FALSE; + + r = ((glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_blit */ + +#ifdef GL_EXT_framebuffer_multisample + +static GLboolean _glewInit_GL_EXT_framebuffer_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_multisample */ + +#ifdef GL_EXT_framebuffer_object + +static GLboolean _glewInit_GL_EXT_framebuffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindFramebufferEXT")) == NULL) || r; + r = ((glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbufferEXT")) == NULL) || r; + r = ((glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatusEXT")) == NULL) || r; + r = ((glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffersEXT")) == NULL) || r; + r = ((glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffersEXT")) == NULL) || r; + r = ((glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbufferEXT")) == NULL) || r; + r = ((glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1DEXT")) == NULL) || r; + r = ((glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DEXT")) == NULL) || r; + r = ((glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3DEXT")) == NULL) || r; + r = ((glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffersEXT")) == NULL) || r; + r = ((glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffersEXT")) == NULL) || r; + r = ((glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmapEXT")) == NULL) || r; + r = ((glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameterivEXT")) == NULL) || r; + r = ((glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameterivEXT")) == NULL) || r; + r = ((glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsFramebufferEXT")) == NULL) || r; + r = ((glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbufferEXT")) == NULL) || r; + r = ((glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_framebuffer_object */ + +#ifdef GL_EXT_geometry_shader4 + +static GLboolean _glewInit_GL_EXT_geometry_shader4 () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureEXT")) == NULL) || r; + r = ((glFramebufferTextureFaceEXT = (PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceEXT")) == NULL) || r; + r = ((glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_geometry_shader4 */ + +#ifdef GL_EXT_gpu_program_parameters + +static GLboolean _glewInit_GL_EXT_gpu_program_parameters () +{ + GLboolean r = GL_FALSE; + + r = ((glProgramEnvParameters4fvEXT = (PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameters4fvEXT")) == NULL) || r; + r = ((glProgramLocalParameters4fvEXT = (PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameters4fvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_gpu_program_parameters */ + +#ifdef GL_EXT_gpu_shader4 + +static GLboolean _glewInit_GL_EXT_gpu_shader4 () +{ + GLboolean r = GL_FALSE; + + r = ((glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationEXT")) == NULL) || r; + r = ((glGetFragDataLocationEXT = (PFNGLGETFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocationEXT")) == NULL) || r; + r = ((glGetUniformuivEXT = (PFNGLGETUNIFORMUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuivEXT")) == NULL) || r; + r = ((glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIivEXT")) == NULL) || r; + r = ((glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuivEXT")) == NULL) || r; + r = ((glUniform1uiEXT = (PFNGLUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiEXT")) == NULL) || r; + r = ((glUniform1uivEXT = (PFNGLUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uivEXT")) == NULL) || r; + r = ((glUniform2uiEXT = (PFNGLUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiEXT")) == NULL) || r; + r = ((glUniform2uivEXT = (PFNGLUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uivEXT")) == NULL) || r; + r = ((glUniform3uiEXT = (PFNGLUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiEXT")) == NULL) || r; + r = ((glUniform3uivEXT = (PFNGLUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uivEXT")) == NULL) || r; + r = ((glUniform4uiEXT = (PFNGLUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiEXT")) == NULL) || r; + r = ((glUniform4uivEXT = (PFNGLUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uivEXT")) == NULL) || r; + r = ((glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iEXT")) == NULL) || r; + r = ((glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ivEXT")) == NULL) || r; + r = ((glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiEXT")) == NULL) || r; + r = ((glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uivEXT")) == NULL) || r; + r = ((glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iEXT")) == NULL) || r; + r = ((glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ivEXT")) == NULL) || r; + r = ((glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiEXT")) == NULL) || r; + r = ((glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uivEXT")) == NULL) || r; + r = ((glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iEXT")) == NULL) || r; + r = ((glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ivEXT")) == NULL) || r; + r = ((glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiEXT")) == NULL) || r; + r = ((glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uivEXT")) == NULL) || r; + r = ((glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bvEXT")) == NULL) || r; + r = ((glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iEXT")) == NULL) || r; + r = ((glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ivEXT")) == NULL) || r; + r = ((glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4svEXT")) == NULL) || r; + r = ((glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubvEXT")) == NULL) || r; + r = ((glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiEXT")) == NULL) || r; + r = ((glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uivEXT")) == NULL) || r; + r = ((glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usvEXT")) == NULL) || r; + r = ((glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_gpu_shader4 */ + +#ifdef GL_EXT_histogram + +static GLboolean _glewInit_GL_EXT_histogram () +{ + GLboolean r = GL_FALSE; + + r = ((glGetHistogramEXT = (PFNGLGETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramEXT")) == NULL) || r; + r = ((glGetHistogramParameterfvEXT = (PFNGLGETHISTOGRAMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfvEXT")) == NULL) || r; + r = ((glGetHistogramParameterivEXT = (PFNGLGETHISTOGRAMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterivEXT")) == NULL) || r; + r = ((glGetMinmaxEXT = (PFNGLGETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxEXT")) == NULL) || r; + r = ((glGetMinmaxParameterfvEXT = (PFNGLGETMINMAXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfvEXT")) == NULL) || r; + r = ((glGetMinmaxParameterivEXT = (PFNGLGETMINMAXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterivEXT")) == NULL) || r; + r = ((glHistogramEXT = (PFNGLHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glHistogramEXT")) == NULL) || r; + r = ((glMinmaxEXT = (PFNGLMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glMinmaxEXT")) == NULL) || r; + r = ((glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glResetHistogramEXT")) == NULL) || r; + r = ((glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glResetMinmaxEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_histogram */ + +#ifdef GL_EXT_index_func + +static GLboolean _glewInit_GL_EXT_index_func () +{ + GLboolean r = GL_FALSE; + + r = ((glIndexFuncEXT = (PFNGLINDEXFUNCEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexFuncEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_index_func */ + +#ifdef GL_EXT_index_material + +static GLboolean _glewInit_GL_EXT_index_material () +{ + GLboolean r = GL_FALSE; + + r = ((glIndexMaterialEXT = (PFNGLINDEXMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexMaterialEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_index_material */ + +#ifdef GL_EXT_instanced_arrays + +static GLboolean _glewInit_GL_EXT_instanced_arrays () +{ + GLboolean r = GL_FALSE; + + r = ((glVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_instanced_arrays */ + +#ifdef GL_EXT_light_texture + +static GLboolean _glewInit_GL_EXT_light_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glApplyTextureEXT = (PFNGLAPPLYTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glApplyTextureEXT")) == NULL) || r; + r = ((glTextureLightEXT = (PFNGLTEXTURELIGHTEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureLightEXT")) == NULL) || r; + r = ((glTextureMaterialEXT = (PFNGLTEXTUREMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureMaterialEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_light_texture */ + +#ifdef GL_EXT_map_buffer_range + +static GLboolean _glewInit_GL_EXT_map_buffer_range () +{ + GLboolean r = GL_FALSE; + + r = ((glFlushMappedBufferRangeEXT = (PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRangeEXT")) == NULL) || r; + r = ((glMapBufferRangeEXT = (PFNGLMAPBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glMapBufferRangeEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_map_buffer_range */ + +#ifdef GL_EXT_memory_object + +static GLboolean _glewInit_GL_EXT_memory_object () +{ + GLboolean r = GL_FALSE; + + r = ((glBufferStorageMemEXT = (PFNGLBUFFERSTORAGEMEMEXTPROC)glewGetProcAddress((const GLubyte*)"glBufferStorageMemEXT")) == NULL) || r; + r = ((glCreateMemoryObjectsEXT = (PFNGLCREATEMEMORYOBJECTSEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateMemoryObjectsEXT")) == NULL) || r; + r = ((glDeleteMemoryObjectsEXT = (PFNGLDELETEMEMORYOBJECTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteMemoryObjectsEXT")) == NULL) || r; + r = ((glGetMemoryObjectParameterivEXT = (PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMemoryObjectParameterivEXT")) == NULL) || r; + r = ((glGetUnsignedBytei_vEXT = (PFNGLGETUNSIGNEDBYTEI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUnsignedBytei_vEXT")) == NULL) || r; + r = ((glGetUnsignedBytevEXT = (PFNGLGETUNSIGNEDBYTEVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUnsignedBytevEXT")) == NULL) || r; + r = ((glIsMemoryObjectEXT = (PFNGLISMEMORYOBJECTEXTPROC)glewGetProcAddress((const GLubyte*)"glIsMemoryObjectEXT")) == NULL) || r; + r = ((glMemoryObjectParameterivEXT = (PFNGLMEMORYOBJECTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMemoryObjectParameterivEXT")) == NULL) || r; + r = ((glNamedBufferStorageMemEXT = (PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorageMemEXT")) == NULL) || r; + r = ((glTexStorageMem1DEXT = (PFNGLTEXSTORAGEMEM1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem1DEXT")) == NULL) || r; + r = ((glTexStorageMem2DEXT = (PFNGLTEXSTORAGEMEM2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem2DEXT")) == NULL) || r; + r = ((glTexStorageMem2DMultisampleEXT = (PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem2DMultisampleEXT")) == NULL) || r; + r = ((glTexStorageMem3DEXT = (PFNGLTEXSTORAGEMEM3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem3DEXT")) == NULL) || r; + r = ((glTexStorageMem3DMultisampleEXT = (PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorageMem3DMultisampleEXT")) == NULL) || r; + r = ((glTextureStorageMem1DEXT = (PFNGLTEXTURESTORAGEMEM1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem1DEXT")) == NULL) || r; + r = ((glTextureStorageMem2DEXT = (PFNGLTEXTURESTORAGEMEM2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem2DEXT")) == NULL) || r; + r = ((glTextureStorageMem2DMultisampleEXT = (PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem2DMultisampleEXT")) == NULL) || r; + r = ((glTextureStorageMem3DEXT = (PFNGLTEXTURESTORAGEMEM3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem3DEXT")) == NULL) || r; + r = ((glTextureStorageMem3DMultisampleEXT = (PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageMem3DMultisampleEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_memory_object */ + +#ifdef GL_EXT_memory_object_fd + +static GLboolean _glewInit_GL_EXT_memory_object_fd () +{ + GLboolean r = GL_FALSE; + + r = ((glImportMemoryFdEXT = (PFNGLIMPORTMEMORYFDEXTPROC)glewGetProcAddress((const GLubyte*)"glImportMemoryFdEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_memory_object_fd */ + +#ifdef GL_EXT_memory_object_win32 + +static GLboolean _glewInit_GL_EXT_memory_object_win32 () +{ + GLboolean r = GL_FALSE; + + r = ((glImportMemoryWin32HandleEXT = (PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC)glewGetProcAddress((const GLubyte*)"glImportMemoryWin32HandleEXT")) == NULL) || r; + r = ((glImportMemoryWin32NameEXT = (PFNGLIMPORTMEMORYWIN32NAMEEXTPROC)glewGetProcAddress((const GLubyte*)"glImportMemoryWin32NameEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_memory_object_win32 */ + +#ifdef GL_EXT_multi_draw_arrays + +static GLboolean _glewInit_GL_EXT_multi_draw_arrays () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysEXT")) == NULL) || r; + r = ((glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multi_draw_arrays */ + +#ifdef GL_EXT_multi_draw_indirect + +static GLboolean _glewInit_GL_EXT_multi_draw_indirect () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectEXT = (PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectEXT")) == NULL) || r; + r = ((glMultiDrawElementsIndirectEXT = (PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multi_draw_indirect */ + +#ifdef GL_EXT_multisample + +static GLboolean _glewInit_GL_EXT_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskEXT")) == NULL) || r; + r = ((glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multisample */ + +#ifdef GL_EXT_multisampled_render_to_texture + +static GLboolean _glewInit_GL_EXT_multisampled_render_to_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DMultisampleEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multisampled_render_to_texture */ + +#ifdef GL_EXT_multiview_draw_buffers + +static GLboolean _glewInit_GL_EXT_multiview_draw_buffers () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersIndexedEXT = (PFNGLDRAWBUFFERSINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersIndexedEXT")) == NULL) || r; + r = ((glGetIntegeri_vEXT = (PFNGLGETINTEGERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_vEXT")) == NULL) || r; + r = ((glReadBufferIndexedEXT = (PFNGLREADBUFFERINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glReadBufferIndexedEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_multiview_draw_buffers */ + +#ifdef GL_EXT_paletted_texture + +static GLboolean _glewInit_GL_EXT_paletted_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorTableEXT")) == NULL) || r; + r = ((glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableEXT")) == NULL) || r; + r = ((glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvEXT")) == NULL) || r; + r = ((glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_paletted_texture */ + +#ifdef GL_EXT_pixel_transform + +static GLboolean _glewInit_GL_EXT_pixel_transform () +{ + GLboolean r = GL_FALSE; + + r = ((glGetPixelTransformParameterfvEXT = (PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvEXT")) == NULL) || r; + r = ((glGetPixelTransformParameterivEXT = (PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivEXT")) == NULL) || r; + r = ((glPixelTransformParameterfEXT = (PFNGLPIXELTRANSFORMPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfEXT")) == NULL) || r; + r = ((glPixelTransformParameterfvEXT = (PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvEXT")) == NULL) || r; + r = ((glPixelTransformParameteriEXT = (PFNGLPIXELTRANSFORMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriEXT")) == NULL) || r; + r = ((glPixelTransformParameterivEXT = (PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_pixel_transform */ + +#ifdef GL_EXT_point_parameters + +static GLboolean _glewInit_GL_EXT_point_parameters () +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfEXT")) == NULL) || r; + r = ((glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_point_parameters */ + +#ifdef GL_EXT_polygon_offset + +static GLboolean _glewInit_GL_EXT_polygon_offset () +{ + GLboolean r = GL_FALSE; + + r = ((glPolygonOffsetEXT = (PFNGLPOLYGONOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_polygon_offset */ + +#ifdef GL_EXT_polygon_offset_clamp + +static GLboolean _glewInit_GL_EXT_polygon_offset_clamp () +{ + GLboolean r = GL_FALSE; + + r = ((glPolygonOffsetClampEXT = (PFNGLPOLYGONOFFSETCLAMPEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetClampEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_polygon_offset_clamp */ + +#ifdef GL_EXT_provoking_vertex + +static GLboolean _glewInit_GL_EXT_provoking_vertex () +{ + GLboolean r = GL_FALSE; + + r = ((glProvokingVertexEXT = (PFNGLPROVOKINGVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertexEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_provoking_vertex */ + +#ifdef GL_EXT_raster_multisample + +static GLboolean _glewInit_GL_EXT_raster_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glCoverageModulationNV = (PFNGLCOVERAGEMODULATIONNVPROC)glewGetProcAddress((const GLubyte*)"glCoverageModulationNV")) == NULL) || r; + r = ((glCoverageModulationTableNV = (PFNGLCOVERAGEMODULATIONTABLENVPROC)glewGetProcAddress((const GLubyte*)"glCoverageModulationTableNV")) == NULL) || r; + r = ((glGetCoverageModulationTableNV = (PFNGLGETCOVERAGEMODULATIONTABLENVPROC)glewGetProcAddress((const GLubyte*)"glGetCoverageModulationTableNV")) == NULL) || r; + r = ((glRasterSamplesEXT = (PFNGLRASTERSAMPLESEXTPROC)glewGetProcAddress((const GLubyte*)"glRasterSamplesEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_raster_multisample */ + +#ifdef GL_EXT_scene_marker + +static GLboolean _glewInit_GL_EXT_scene_marker () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginSceneEXT = (PFNGLBEGINSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginSceneEXT")) == NULL) || r; + r = ((glEndSceneEXT = (PFNGLENDSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glEndSceneEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_scene_marker */ + +#ifdef GL_EXT_secondary_color + +static GLboolean _glewInit_GL_EXT_secondary_color () +{ + GLboolean r = GL_FALSE; + + r = ((glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bEXT")) == NULL) || r; + r = ((glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bvEXT")) == NULL) || r; + r = ((glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dEXT")) == NULL) || r; + r = ((glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dvEXT")) == NULL) || r; + r = ((glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fEXT")) == NULL) || r; + r = ((glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fvEXT")) == NULL) || r; + r = ((glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iEXT")) == NULL) || r; + r = ((glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ivEXT")) == NULL) || r; + r = ((glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sEXT")) == NULL) || r; + r = ((glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3svEXT")) == NULL) || r; + r = ((glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubEXT")) == NULL) || r; + r = ((glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubvEXT")) == NULL) || r; + r = ((glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiEXT")) == NULL) || r; + r = ((glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uivEXT")) == NULL) || r; + r = ((glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usEXT")) == NULL) || r; + r = ((glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usvEXT")) == NULL) || r; + r = ((glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_secondary_color */ + +#ifdef GL_EXT_semaphore + +static GLboolean _glewInit_GL_EXT_semaphore () +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteSemaphoresEXT = (PFNGLDELETESEMAPHORESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteSemaphoresEXT")) == NULL) || r; + r = ((glGenSemaphoresEXT = (PFNGLGENSEMAPHORESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSemaphoresEXT")) == NULL) || r; + r = ((glGetSemaphoreParameterui64vEXT = (PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetSemaphoreParameterui64vEXT")) == NULL) || r; + r = ((glIsSemaphoreEXT = (PFNGLISSEMAPHOREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsSemaphoreEXT")) == NULL) || r; + r = ((glSemaphoreParameterui64vEXT = (PFNGLSEMAPHOREPARAMETERUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glSemaphoreParameterui64vEXT")) == NULL) || r; + r = ((glSignalSemaphoreEXT = (PFNGLSIGNALSEMAPHOREEXTPROC)glewGetProcAddress((const GLubyte*)"glSignalSemaphoreEXT")) == NULL) || r; + r = ((glWaitSemaphoreEXT = (PFNGLWAITSEMAPHOREEXTPROC)glewGetProcAddress((const GLubyte*)"glWaitSemaphoreEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_semaphore */ + +#ifdef GL_EXT_semaphore_fd + +static GLboolean _glewInit_GL_EXT_semaphore_fd () +{ + GLboolean r = GL_FALSE; + + r = ((glImportSemaphoreFdEXT = (PFNGLIMPORTSEMAPHOREFDEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSemaphoreFdEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_semaphore_fd */ + +#ifdef GL_EXT_semaphore_win32 + +static GLboolean _glewInit_GL_EXT_semaphore_win32 () +{ + GLboolean r = GL_FALSE; + + r = ((glImportSemaphoreWin32HandleEXT = (PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSemaphoreWin32HandleEXT")) == NULL) || r; + r = ((glImportSemaphoreWin32NameEXT = (PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSemaphoreWin32NameEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_semaphore_win32 */ + +#ifdef GL_EXT_separate_shader_objects + +static GLboolean _glewInit_GL_EXT_separate_shader_objects () +{ + GLboolean r = GL_FALSE; + + r = ((glActiveProgramEXT = (PFNGLACTIVEPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveProgramEXT")) == NULL) || r; + r = ((glCreateShaderProgramEXT = (PFNGLCREATESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramEXT")) == NULL) || r; + r = ((glUseShaderProgramEXT = (PFNGLUSESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glUseShaderProgramEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_separate_shader_objects */ + +#ifdef GL_EXT_shader_image_load_store + +static GLboolean _glewInit_GL_EXT_shader_image_load_store () +{ + GLboolean r = GL_FALSE; + + r = ((glBindImageTextureEXT = (PFNGLBINDIMAGETEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindImageTextureEXT")) == NULL) || r; + r = ((glMemoryBarrierEXT = (PFNGLMEMORYBARRIEREXTPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrierEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_shader_image_load_store */ + +#ifdef GL_EXT_shader_pixel_local_storage2 + +static GLboolean _glewInit_GL_EXT_shader_pixel_local_storage2 () +{ + GLboolean r = GL_FALSE; + + r = ((glClearPixelLocalStorageuiEXT = (PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearPixelLocalStorageuiEXT")) == NULL) || r; + r = ((glFramebufferPixelLocalStorageSizeEXT = (PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferPixelLocalStorageSizeEXT")) == NULL) || r; + r = ((glGetFramebufferPixelLocalStorageSizeEXT = (PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferPixelLocalStorageSizeEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_shader_pixel_local_storage2 */ + +#ifdef GL_EXT_sparse_texture + +static GLboolean _glewInit_GL_EXT_sparse_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glTexPageCommitmentEXT = (PFNGLTEXPAGECOMMITMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glTexPageCommitmentEXT")) == NULL) || r; + r = ((glTexturePageCommitmentEXT = (PFNGLTEXTUREPAGECOMMITMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glTexturePageCommitmentEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_sparse_texture */ + +#ifdef GL_EXT_stencil_two_side + +static GLboolean _glewInit_GL_EXT_stencil_two_side () +{ + GLboolean r = GL_FALSE; + + r = ((glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveStencilFaceEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_stencil_two_side */ + +#ifdef GL_EXT_subtexture + +static GLboolean _glewInit_GL_EXT_subtexture () +{ + GLboolean r = GL_FALSE; + + r = ((glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage1DEXT")) == NULL) || r; + r = ((glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage2DEXT")) == NULL) || r; + r = ((glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_subtexture */ + +#ifdef GL_EXT_texture3D + +static GLboolean _glewInit_GL_EXT_texture3D () +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture3D */ + +#ifdef GL_EXT_texture_array + +static GLboolean _glewInit_GL_EXT_texture_array () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_array */ + +#ifdef GL_EXT_texture_buffer_object + +static GLboolean _glewInit_GL_EXT_texture_buffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexBufferEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_buffer_object */ + +#ifdef GL_EXT_texture_integer + +static GLboolean _glewInit_GL_EXT_texture_integer () +{ + GLboolean r = GL_FALSE; + + r = ((glClearColorIiEXT = (PFNGLCLEARCOLORIIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIiEXT")) == NULL) || r; + r = ((glClearColorIuiEXT = (PFNGLCLEARCOLORIUIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIuiEXT")) == NULL) || r; + r = ((glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIivEXT")) == NULL) || r; + r = ((glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuivEXT")) == NULL) || r; + r = ((glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIivEXT")) == NULL) || r; + r = ((glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuivEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_integer */ + +#ifdef GL_EXT_texture_object + +static GLboolean _glewInit_GL_EXT_texture_object () +{ + GLboolean r = GL_FALSE; + + r = ((glAreTexturesResidentEXT = (PFNGLARETEXTURESRESIDENTEXTPROC)glewGetProcAddress((const GLubyte*)"glAreTexturesResidentEXT")) == NULL) || r; + r = ((glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureEXT")) == NULL) || r; + r = ((glDeleteTexturesEXT = (PFNGLDELETETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteTexturesEXT")) == NULL) || r; + r = ((glGenTexturesEXT = (PFNGLGENTEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenTexturesEXT")) == NULL) || r; + r = ((glIsTextureEXT = (PFNGLISTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsTextureEXT")) == NULL) || r; + r = ((glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeTexturesEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_object */ + +#ifdef GL_EXT_texture_perturb_normal + +static GLboolean _glewInit_GL_EXT_texture_perturb_normal () +{ + GLboolean r = GL_FALSE; + + r = ((glTextureNormalEXT = (PFNGLTEXTURENORMALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureNormalEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_perturb_normal */ + +#ifdef GL_EXT_texture_storage + +static GLboolean _glewInit_GL_EXT_texture_storage () +{ + GLboolean r = GL_FALSE; + + r = ((glTexStorage1DEXT = (PFNGLTEXSTORAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorage1DEXT")) == NULL) || r; + r = ((glTexStorage2DEXT = (PFNGLTEXSTORAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2DEXT")) == NULL) || r; + r = ((glTexStorage3DEXT = (PFNGLTEXSTORAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3DEXT")) == NULL) || r; + r = ((glTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage1DEXT")) == NULL) || r; + r = ((glTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DEXT")) == NULL) || r; + r = ((glTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_storage */ + +#ifdef GL_EXT_texture_view + +static GLboolean _glewInit_GL_EXT_texture_view () +{ + GLboolean r = GL_FALSE; + + r = ((glTextureViewEXT = (PFNGLTEXTUREVIEWEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureViewEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_texture_view */ + +#ifdef GL_EXT_timer_query + +static GLboolean _glewInit_GL_EXT_timer_query () +{ + GLboolean r = GL_FALSE; + + r = ((glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vEXT")) == NULL) || r; + r = ((glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_timer_query */ + +#ifdef GL_EXT_transform_feedback + +static GLboolean _glewInit_GL_EXT_transform_feedback () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackEXT")) == NULL) || r; + r = ((glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseEXT")) == NULL) || r; + r = ((glBindBufferOffsetEXT = (PFNGLBINDBUFFEROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetEXT")) == NULL) || r; + r = ((glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeEXT")) == NULL) || r; + r = ((glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackEXT")) == NULL) || r; + r = ((glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingEXT")) == NULL) || r; + r = ((glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_transform_feedback */ + +#ifdef GL_EXT_vertex_array + +static GLboolean _glewInit_GL_EXT_vertex_array () +{ + GLboolean r = GL_FALSE; + + r = ((glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glArrayElementEXT")) == NULL) || r; + r = ((glColorPointerEXT = (PFNGLCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glColorPointerEXT")) == NULL) || r; + r = ((glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysEXT")) == NULL) || r; + r = ((glEdgeFlagPointerEXT = (PFNGLEDGEFLAGPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerEXT")) == NULL) || r; + r = ((glIndexPointerEXT = (PFNGLINDEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerEXT")) == NULL) || r; + r = ((glNormalPointerEXT = (PFNGLNORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerEXT")) == NULL) || r; + r = ((glTexCoordPointerEXT = (PFNGLTEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerEXT")) == NULL) || r; + r = ((glVertexPointerEXT = (PFNGLVERTEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_array */ + +#ifdef GL_EXT_vertex_array_setXXX + +static GLboolean _glewInit_GL_EXT_vertex_array_setXXX () +{ + GLboolean r = GL_FALSE; + + r = ((glBindArraySetEXT = (PFNGLBINDARRAYSETEXTPROC)glewGetProcAddress((const GLubyte*)"glBindArraySetEXT")) == NULL) || r; + r = ((glCreateArraySetExt = (PFNGLCREATEARRAYSETEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateArraySetExt")) == NULL) || r; + r = ((glDeleteArraySetsEXT = (PFNGLDELETEARRAYSETSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteArraySetsEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_array_setXXX */ + +#ifdef GL_EXT_vertex_attrib_64bit + +static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit () +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribLdvEXT = (PFNGLGETVERTEXATTRIBLDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLdvEXT")) == NULL) || r; + r = ((glVertexArrayVertexAttribLOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribLOffsetEXT")) == NULL) || r; + r = ((glVertexAttribL1dEXT = (PFNGLVERTEXATTRIBL1DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dEXT")) == NULL) || r; + r = ((glVertexAttribL1dvEXT = (PFNGLVERTEXATTRIBL1DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dvEXT")) == NULL) || r; + r = ((glVertexAttribL2dEXT = (PFNGLVERTEXATTRIBL2DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dEXT")) == NULL) || r; + r = ((glVertexAttribL2dvEXT = (PFNGLVERTEXATTRIBL2DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dvEXT")) == NULL) || r; + r = ((glVertexAttribL3dEXT = (PFNGLVERTEXATTRIBL3DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dEXT")) == NULL) || r; + r = ((glVertexAttribL3dvEXT = (PFNGLVERTEXATTRIBL3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dvEXT")) == NULL) || r; + r = ((glVertexAttribL4dEXT = (PFNGLVERTEXATTRIBL4DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dEXT")) == NULL) || r; + r = ((glVertexAttribL4dvEXT = (PFNGLVERTEXATTRIBL4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dvEXT")) == NULL) || r; + r = ((glVertexAttribLPointerEXT = (PFNGLVERTEXATTRIBLPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLPointerEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_attrib_64bit */ + +#ifdef GL_EXT_vertex_shader + +static GLboolean _glewInit_GL_EXT_vertex_shader () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginVertexShaderEXT = (PFNGLBEGINVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBeginVertexShaderEXT")) == NULL) || r; + r = ((glBindLightParameterEXT = (PFNGLBINDLIGHTPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindLightParameterEXT")) == NULL) || r; + r = ((glBindMaterialParameterEXT = (PFNGLBINDMATERIALPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindMaterialParameterEXT")) == NULL) || r; + r = ((glBindParameterEXT = (PFNGLBINDPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindParameterEXT")) == NULL) || r; + r = ((glBindTexGenParameterEXT = (PFNGLBINDTEXGENPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTexGenParameterEXT")) == NULL) || r; + r = ((glBindTextureUnitParameterEXT = (PFNGLBINDTEXTUREUNITPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnitParameterEXT")) == NULL) || r; + r = ((glBindVertexShaderEXT = (PFNGLBINDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindVertexShaderEXT")) == NULL) || r; + r = ((glDeleteVertexShaderEXT = (PFNGLDELETEVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexShaderEXT")) == NULL) || r; + r = ((glDisableVariantClientStateEXT = (PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVariantClientStateEXT")) == NULL) || r; + r = ((glEnableVariantClientStateEXT = (PFNGLENABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVariantClientStateEXT")) == NULL) || r; + r = ((glEndVertexShaderEXT = (PFNGLENDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glEndVertexShaderEXT")) == NULL) || r; + r = ((glExtractComponentEXT = (PFNGLEXTRACTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glExtractComponentEXT")) == NULL) || r; + r = ((glGenSymbolsEXT = (PFNGLGENSYMBOLSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSymbolsEXT")) == NULL) || r; + r = ((glGenVertexShadersEXT = (PFNGLGENVERTEXSHADERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenVertexShadersEXT")) == NULL) || r; + r = ((glGetInvariantBooleanvEXT = (PFNGLGETINVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantBooleanvEXT")) == NULL) || r; + r = ((glGetInvariantFloatvEXT = (PFNGLGETINVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantFloatvEXT")) == NULL) || r; + r = ((glGetInvariantIntegervEXT = (PFNGLGETINVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantIntegervEXT")) == NULL) || r; + r = ((glGetLocalConstantBooleanvEXT = (PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantBooleanvEXT")) == NULL) || r; + r = ((glGetLocalConstantFloatvEXT = (PFNGLGETLOCALCONSTANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantFloatvEXT")) == NULL) || r; + r = ((glGetLocalConstantIntegervEXT = (PFNGLGETLOCALCONSTANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantIntegervEXT")) == NULL) || r; + r = ((glGetVariantBooleanvEXT = (PFNGLGETVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantBooleanvEXT")) == NULL) || r; + r = ((glGetVariantFloatvEXT = (PFNGLGETVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantFloatvEXT")) == NULL) || r; + r = ((glGetVariantIntegervEXT = (PFNGLGETVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantIntegervEXT")) == NULL) || r; + r = ((glGetVariantPointervEXT = (PFNGLGETVARIANTPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantPointervEXT")) == NULL) || r; + r = ((glInsertComponentEXT = (PFNGLINSERTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glInsertComponentEXT")) == NULL) || r; + r = ((glIsVariantEnabledEXT = (PFNGLISVARIANTENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsVariantEnabledEXT")) == NULL) || r; + r = ((glSetInvariantEXT = (PFNGLSETINVARIANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetInvariantEXT")) == NULL) || r; + r = ((glSetLocalConstantEXT = (PFNGLSETLOCALCONSTANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetLocalConstantEXT")) == NULL) || r; + r = ((glShaderOp1EXT = (PFNGLSHADEROP1EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp1EXT")) == NULL) || r; + r = ((glShaderOp2EXT = (PFNGLSHADEROP2EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp2EXT")) == NULL) || r; + r = ((glShaderOp3EXT = (PFNGLSHADEROP3EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp3EXT")) == NULL) || r; + r = ((glSwizzleEXT = (PFNGLSWIZZLEEXTPROC)glewGetProcAddress((const GLubyte*)"glSwizzleEXT")) == NULL) || r; + r = ((glVariantPointerEXT = (PFNGLVARIANTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVariantPointerEXT")) == NULL) || r; + r = ((glVariantbvEXT = (PFNGLVARIANTBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantbvEXT")) == NULL) || r; + r = ((glVariantdvEXT = (PFNGLVARIANTDVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantdvEXT")) == NULL) || r; + r = ((glVariantfvEXT = (PFNGLVARIANTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantfvEXT")) == NULL) || r; + r = ((glVariantivEXT = (PFNGLVARIANTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantivEXT")) == NULL) || r; + r = ((glVariantsvEXT = (PFNGLVARIANTSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantsvEXT")) == NULL) || r; + r = ((glVariantubvEXT = (PFNGLVARIANTUBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantubvEXT")) == NULL) || r; + r = ((glVariantuivEXT = (PFNGLVARIANTUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantuivEXT")) == NULL) || r; + r = ((glVariantusvEXT = (PFNGLVARIANTUSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantusvEXT")) == NULL) || r; + r = ((glWriteMaskEXT = (PFNGLWRITEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glWriteMaskEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_shader */ + +#ifdef GL_EXT_vertex_weighting + +static GLboolean _glewInit_GL_EXT_vertex_weighting () +{ + GLboolean r = GL_FALSE; + + r = ((glVertexWeightPointerEXT = (PFNGLVERTEXWEIGHTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightPointerEXT")) == NULL) || r; + r = ((glVertexWeightfEXT = (PFNGLVERTEXWEIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfEXT")) == NULL) || r; + r = ((glVertexWeightfvEXT = (PFNGLVERTEXWEIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfvEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_vertex_weighting */ + +#ifdef GL_EXT_win32_keyed_mutex + +static GLboolean _glewInit_GL_EXT_win32_keyed_mutex () +{ + GLboolean r = GL_FALSE; + + r = ((glAcquireKeyedMutexWin32EXT = (PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC)glewGetProcAddress((const GLubyte*)"glAcquireKeyedMutexWin32EXT")) == NULL) || r; + r = ((glReleaseKeyedMutexWin32EXT = (PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC)glewGetProcAddress((const GLubyte*)"glReleaseKeyedMutexWin32EXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_win32_keyed_mutex */ + +#ifdef GL_EXT_window_rectangles + +static GLboolean _glewInit_GL_EXT_window_rectangles () +{ + GLboolean r = GL_FALSE; + + r = ((glWindowRectanglesEXT = (PFNGLWINDOWRECTANGLESEXTPROC)glewGetProcAddress((const GLubyte*)"glWindowRectanglesEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_window_rectangles */ + +#ifdef GL_EXT_x11_sync_object + +static GLboolean _glewInit_GL_EXT_x11_sync_object () +{ + GLboolean r = GL_FALSE; + + r = ((glImportSyncEXT = (PFNGLIMPORTSYNCEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSyncEXT")) == NULL) || r; + + return r; +} + +#endif /* GL_EXT_x11_sync_object */ + +#ifdef GL_GREMEDY_frame_terminator + +static GLboolean _glewInit_GL_GREMEDY_frame_terminator () +{ + GLboolean r = GL_FALSE; + + r = ((glFrameTerminatorGREMEDY = (PFNGLFRAMETERMINATORGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glFrameTerminatorGREMEDY")) == NULL) || r; + + return r; +} + +#endif /* GL_GREMEDY_frame_terminator */ + +#ifdef GL_GREMEDY_string_marker + +static GLboolean _glewInit_GL_GREMEDY_string_marker () +{ + GLboolean r = GL_FALSE; + + r = ((glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glStringMarkerGREMEDY")) == NULL) || r; + + return r; +} + +#endif /* GL_GREMEDY_string_marker */ + +#ifdef GL_HP_image_transform + +static GLboolean _glewInit_GL_HP_image_transform () +{ + GLboolean r = GL_FALSE; + + r = ((glGetImageTransformParameterfvHP = (PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterfvHP")) == NULL) || r; + r = ((glGetImageTransformParameterivHP = (PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterivHP")) == NULL) || r; + r = ((glImageTransformParameterfHP = (PFNGLIMAGETRANSFORMPARAMETERFHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfHP")) == NULL) || r; + r = ((glImageTransformParameterfvHP = (PFNGLIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfvHP")) == NULL) || r; + r = ((glImageTransformParameteriHP = (PFNGLIMAGETRANSFORMPARAMETERIHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameteriHP")) == NULL) || r; + r = ((glImageTransformParameterivHP = (PFNGLIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterivHP")) == NULL) || r; + + return r; +} + +#endif /* GL_HP_image_transform */ + +#ifdef GL_IBM_multimode_draw_arrays + +static GLboolean _glewInit_GL_IBM_multimode_draw_arrays () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiModeDrawArraysIBM = (PFNGLMULTIMODEDRAWARRAYSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawArraysIBM")) == NULL) || r; + r = ((glMultiModeDrawElementsIBM = (PFNGLMULTIMODEDRAWELEMENTSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawElementsIBM")) == NULL) || r; + + return r; +} + +#endif /* GL_IBM_multimode_draw_arrays */ + +#ifdef GL_IBM_vertex_array_lists + +static GLboolean _glewInit_GL_IBM_vertex_array_lists () +{ + GLboolean r = GL_FALSE; + + r = ((glColorPointerListIBM = (PFNGLCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glColorPointerListIBM")) == NULL) || r; + r = ((glEdgeFlagPointerListIBM = (PFNGLEDGEFLAGPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerListIBM")) == NULL) || r; + r = ((glFogCoordPointerListIBM = (PFNGLFOGCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerListIBM")) == NULL) || r; + r = ((glIndexPointerListIBM = (PFNGLINDEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerListIBM")) == NULL) || r; + r = ((glNormalPointerListIBM = (PFNGLNORMALPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerListIBM")) == NULL) || r; + r = ((glSecondaryColorPointerListIBM = (PFNGLSECONDARYCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerListIBM")) == NULL) || r; + r = ((glTexCoordPointerListIBM = (PFNGLTEXCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerListIBM")) == NULL) || r; + r = ((glVertexPointerListIBM = (PFNGLVERTEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerListIBM")) == NULL) || r; + + return r; +} + +#endif /* GL_IBM_vertex_array_lists */ + +#ifdef GL_INTEL_map_texture + +static GLboolean _glewInit_GL_INTEL_map_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glMapTexture2DINTEL = (PFNGLMAPTEXTURE2DINTELPROC)glewGetProcAddress((const GLubyte*)"glMapTexture2DINTEL")) == NULL) || r; + r = ((glSyncTextureINTEL = (PFNGLSYNCTEXTUREINTELPROC)glewGetProcAddress((const GLubyte*)"glSyncTextureINTEL")) == NULL) || r; + r = ((glUnmapTexture2DINTEL = (PFNGLUNMAPTEXTURE2DINTELPROC)glewGetProcAddress((const GLubyte*)"glUnmapTexture2DINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_map_texture */ + +#ifdef GL_INTEL_parallel_arrays + +static GLboolean _glewInit_GL_INTEL_parallel_arrays () +{ + GLboolean r = GL_FALSE; + + r = ((glColorPointervINTEL = (PFNGLCOLORPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glColorPointervINTEL")) == NULL) || r; + r = ((glNormalPointervINTEL = (PFNGLNORMALPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glNormalPointervINTEL")) == NULL) || r; + r = ((glTexCoordPointervINTEL = (PFNGLTEXCOORDPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointervINTEL")) == NULL) || r; + r = ((glVertexPointervINTEL = (PFNGLVERTEXPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glVertexPointervINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_parallel_arrays */ + +#ifdef GL_INTEL_performance_query + +static GLboolean _glewInit_GL_INTEL_performance_query () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginPerfQueryINTEL = (PFNGLBEGINPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glBeginPerfQueryINTEL")) == NULL) || r; + r = ((glCreatePerfQueryINTEL = (PFNGLCREATEPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glCreatePerfQueryINTEL")) == NULL) || r; + r = ((glDeletePerfQueryINTEL = (PFNGLDELETEPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glDeletePerfQueryINTEL")) == NULL) || r; + r = ((glEndPerfQueryINTEL = (PFNGLENDPERFQUERYINTELPROC)glewGetProcAddress((const GLubyte*)"glEndPerfQueryINTEL")) == NULL) || r; + r = ((glGetFirstPerfQueryIdINTEL = (PFNGLGETFIRSTPERFQUERYIDINTELPROC)glewGetProcAddress((const GLubyte*)"glGetFirstPerfQueryIdINTEL")) == NULL) || r; + r = ((glGetNextPerfQueryIdINTEL = (PFNGLGETNEXTPERFQUERYIDINTELPROC)glewGetProcAddress((const GLubyte*)"glGetNextPerfQueryIdINTEL")) == NULL) || r; + r = ((glGetPerfCounterInfoINTEL = (PFNGLGETPERFCOUNTERINFOINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfCounterInfoINTEL")) == NULL) || r; + r = ((glGetPerfQueryDataINTEL = (PFNGLGETPERFQUERYDATAINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryDataINTEL")) == NULL) || r; + r = ((glGetPerfQueryIdByNameINTEL = (PFNGLGETPERFQUERYIDBYNAMEINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryIdByNameINTEL")) == NULL) || r; + r = ((glGetPerfQueryInfoINTEL = (PFNGLGETPERFQUERYINFOINTELPROC)glewGetProcAddress((const GLubyte*)"glGetPerfQueryInfoINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_performance_query */ + +#ifdef GL_INTEL_texture_scissor + +static GLboolean _glewInit_GL_INTEL_texture_scissor () +{ + GLboolean r = GL_FALSE; + + r = ((glTexScissorFuncINTEL = (PFNGLTEXSCISSORFUNCINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorFuncINTEL")) == NULL) || r; + r = ((glTexScissorINTEL = (PFNGLTEXSCISSORINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorINTEL")) == NULL) || r; + + return r; +} + +#endif /* GL_INTEL_texture_scissor */ + +#ifdef GL_KHR_blend_equation_advanced + +static GLboolean _glewInit_GL_KHR_blend_equation_advanced () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendBarrierKHR = (PFNGLBLENDBARRIERKHRPROC)glewGetProcAddress((const GLubyte*)"glBlendBarrierKHR")) == NULL) || r; + + return r; +} + +#endif /* GL_KHR_blend_equation_advanced */ + +#ifdef GL_KHR_debug + +static GLboolean _glewInit_GL_KHR_debug () +{ + GLboolean r = GL_FALSE; + + r = ((glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallback")) == NULL) || r; + r = ((glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageControl")) == NULL) || r; + r = ((glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsert")) == NULL) || r; + r = ((glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLog")) == NULL) || r; + r = ((glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)glewGetProcAddress((const GLubyte*)"glGetObjectLabel")) == NULL) || r; + r = ((glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)glewGetProcAddress((const GLubyte*)"glGetObjectPtrLabel")) == NULL) || r; + r = ((glObjectLabel = (PFNGLOBJECTLABELPROC)glewGetProcAddress((const GLubyte*)"glObjectLabel")) == NULL) || r; + r = ((glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)glewGetProcAddress((const GLubyte*)"glObjectPtrLabel")) == NULL) || r; + r = ((glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)glewGetProcAddress((const GLubyte*)"glPopDebugGroup")) == NULL) || r; + r = ((glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)glewGetProcAddress((const GLubyte*)"glPushDebugGroup")) == NULL) || r; + + return r; +} + +#endif /* GL_KHR_debug */ + +#ifdef GL_KHR_parallel_shader_compile + +static GLboolean _glewInit_GL_KHR_parallel_shader_compile () +{ + GLboolean r = GL_FALSE; + + r = ((glMaxShaderCompilerThreadsKHR = (PFNGLMAXSHADERCOMPILERTHREADSKHRPROC)glewGetProcAddress((const GLubyte*)"glMaxShaderCompilerThreadsKHR")) == NULL) || r; + + return r; +} + +#endif /* GL_KHR_parallel_shader_compile */ + +#ifdef GL_KHR_robustness + +static GLboolean _glewInit_GL_KHR_robustness () +{ + GLboolean r = GL_FALSE; + + r = ((glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformfv")) == NULL) || r; + r = ((glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformiv")) == NULL) || r; + r = ((glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformuiv")) == NULL) || r; + r = ((glReadnPixels = (PFNGLREADNPIXELSPROC)glewGetProcAddress((const GLubyte*)"glReadnPixels")) == NULL) || r; + + return r; +} + +#endif /* GL_KHR_robustness */ + +#ifdef GL_KTX_buffer_region + +static GLboolean _glewInit_GL_KTX_buffer_region () +{ + GLboolean r = GL_FALSE; + + r = ((glBufferRegionEnabled = (PFNGLBUFFERREGIONENABLEDPROC)glewGetProcAddress((const GLubyte*)"glBufferRegionEnabled")) == NULL) || r; + r = ((glDeleteBufferRegion = (PFNGLDELETEBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glDeleteBufferRegion")) == NULL) || r; + r = ((glDrawBufferRegion = (PFNGLDRAWBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glDrawBufferRegion")) == NULL) || r; + r = ((glNewBufferRegion = (PFNGLNEWBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glNewBufferRegion")) == NULL) || r; + r = ((glReadBufferRegion = (PFNGLREADBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glReadBufferRegion")) == NULL) || r; + + return r; +} + +#endif /* GL_KTX_buffer_region */ + +#ifdef GL_MESA_resize_buffers + +static GLboolean _glewInit_GL_MESA_resize_buffers () +{ + GLboolean r = GL_FALSE; + + r = ((glResizeBuffersMESA = (PFNGLRESIZEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glResizeBuffersMESA")) == NULL) || r; + + return r; +} + +#endif /* GL_MESA_resize_buffers */ + +#ifdef GL_MESA_window_pos + +static GLboolean _glewInit_GL_MESA_window_pos () +{ + GLboolean r = GL_FALSE; + + r = ((glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dMESA")) == NULL) || r; + r = ((glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvMESA")) == NULL) || r; + r = ((glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fMESA")) == NULL) || r; + r = ((glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvMESA")) == NULL) || r; + r = ((glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iMESA")) == NULL) || r; + r = ((glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivMESA")) == NULL) || r; + r = ((glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sMESA")) == NULL) || r; + r = ((glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svMESA")) == NULL) || r; + r = ((glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dMESA")) == NULL) || r; + r = ((glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvMESA")) == NULL) || r; + r = ((glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fMESA")) == NULL) || r; + r = ((glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvMESA")) == NULL) || r; + r = ((glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iMESA")) == NULL) || r; + r = ((glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivMESA")) == NULL) || r; + r = ((glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sMESA")) == NULL) || r; + r = ((glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svMESA")) == NULL) || r; + r = ((glWindowPos4dMESA = (PFNGLWINDOWPOS4DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dMESA")) == NULL) || r; + r = ((glWindowPos4dvMESA = (PFNGLWINDOWPOS4DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dvMESA")) == NULL) || r; + r = ((glWindowPos4fMESA = (PFNGLWINDOWPOS4FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fMESA")) == NULL) || r; + r = ((glWindowPos4fvMESA = (PFNGLWINDOWPOS4FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fvMESA")) == NULL) || r; + r = ((glWindowPos4iMESA = (PFNGLWINDOWPOS4IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4iMESA")) == NULL) || r; + r = ((glWindowPos4ivMESA = (PFNGLWINDOWPOS4IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4ivMESA")) == NULL) || r; + r = ((glWindowPos4sMESA = (PFNGLWINDOWPOS4SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4sMESA")) == NULL) || r; + r = ((glWindowPos4svMESA = (PFNGLWINDOWPOS4SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4svMESA")) == NULL) || r; + + return r; +} + +#endif /* GL_MESA_window_pos */ + +#ifdef GL_NVX_conditional_render + +static GLboolean _glewInit_GL_NVX_conditional_render () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginConditionalRenderNVX = (PFNGLBEGINCONDITIONALRENDERNVXPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNVX")) == NULL) || r; + r = ((glEndConditionalRenderNVX = (PFNGLENDCONDITIONALRENDERNVXPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNVX")) == NULL) || r; + + return r; +} + +#endif /* GL_NVX_conditional_render */ + +#ifdef GL_NVX_linked_gpu_multicast + +static GLboolean _glewInit_GL_NVX_linked_gpu_multicast () +{ + GLboolean r = GL_FALSE; + + r = ((glLGPUCopyImageSubDataNVX = (PFNGLLGPUCOPYIMAGESUBDATANVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUCopyImageSubDataNVX")) == NULL) || r; + r = ((glLGPUInterlockNVX = (PFNGLLGPUINTERLOCKNVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUInterlockNVX")) == NULL) || r; + r = ((glLGPUNamedBufferSubDataNVX = (PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC)glewGetProcAddress((const GLubyte*)"glLGPUNamedBufferSubDataNVX")) == NULL) || r; + + return r; +} + +#endif /* GL_NVX_linked_gpu_multicast */ + +#ifdef GL_NV_3dvision_settings + +static GLboolean _glewInit_GL_NV_3dvision_settings () +{ + GLboolean r = GL_FALSE; + + r = ((glStereoParameterfNV = (PFNGLSTEREOPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glStereoParameterfNV")) == NULL) || r; + r = ((glStereoParameteriNV = (PFNGLSTEREOPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glStereoParameteriNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_3dvision_settings */ + +#ifdef GL_NV_bindless_multi_draw_indirect + +static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectBindlessNV = (PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectBindlessNV")) == NULL) || r; + r = ((glMultiDrawElementsIndirectBindlessNV = (PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectBindlessNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_bindless_multi_draw_indirect */ + +#ifdef GL_NV_bindless_multi_draw_indirect_count + +static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect_count () +{ + GLboolean r = GL_FALSE; + + r = ((glMultiDrawArraysIndirectBindlessCountNV = (PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectBindlessCountNV")) == NULL) || r; + r = ((glMultiDrawElementsIndirectBindlessCountNV = (PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectBindlessCountNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_bindless_multi_draw_indirect_count */ + +#ifdef GL_NV_bindless_texture + +static GLboolean _glewInit_GL_NV_bindless_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glGetImageHandleNV = (PFNGLGETIMAGEHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetImageHandleNV")) == NULL) || r; + r = ((glGetTextureHandleNV = (PFNGLGETTEXTUREHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureHandleNV")) == NULL) || r; + r = ((glGetTextureSamplerHandleNV = (PFNGLGETTEXTURESAMPLERHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSamplerHandleNV")) == NULL) || r; + r = ((glIsImageHandleResidentNV = (PFNGLISIMAGEHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsImageHandleResidentNV")) == NULL) || r; + r = ((glIsTextureHandleResidentNV = (PFNGLISTEXTUREHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsTextureHandleResidentNV")) == NULL) || r; + r = ((glMakeImageHandleNonResidentNV = (PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleNonResidentNV")) == NULL) || r; + r = ((glMakeImageHandleResidentNV = (PFNGLMAKEIMAGEHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleResidentNV")) == NULL) || r; + r = ((glMakeTextureHandleNonResidentNV = (PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleNonResidentNV")) == NULL) || r; + r = ((glMakeTextureHandleResidentNV = (PFNGLMAKETEXTUREHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleResidentNV")) == NULL) || r; + r = ((glProgramUniformHandleui64NV = (PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64NV")) == NULL) || r; + r = ((glProgramUniformHandleui64vNV = (PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64vNV")) == NULL) || r; + r = ((glUniformHandleui64NV = (PFNGLUNIFORMHANDLEUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64NV")) == NULL) || r; + r = ((glUniformHandleui64vNV = (PFNGLUNIFORMHANDLEUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64vNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_bindless_texture */ + +#ifdef GL_NV_blend_equation_advanced + +static GLboolean _glewInit_GL_NV_blend_equation_advanced () +{ + GLboolean r = GL_FALSE; + + r = ((glBlendBarrierNV = (PFNGLBLENDBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glBlendBarrierNV")) == NULL) || r; + r = ((glBlendParameteriNV = (PFNGLBLENDPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glBlendParameteriNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_blend_equation_advanced */ + +#ifdef GL_NV_clip_space_w_scaling + +static GLboolean _glewInit_GL_NV_clip_space_w_scaling () +{ + GLboolean r = GL_FALSE; + + r = ((glViewportPositionWScaleNV = (PFNGLVIEWPORTPOSITIONWSCALENVPROC)glewGetProcAddress((const GLubyte*)"glViewportPositionWScaleNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_clip_space_w_scaling */ + +#ifdef GL_NV_command_list + +static GLboolean _glewInit_GL_NV_command_list () +{ + GLboolean r = GL_FALSE; + + r = ((glCallCommandListNV = (PFNGLCALLCOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glCallCommandListNV")) == NULL) || r; + r = ((glCommandListSegmentsNV = (PFNGLCOMMANDLISTSEGMENTSNVPROC)glewGetProcAddress((const GLubyte*)"glCommandListSegmentsNV")) == NULL) || r; + r = ((glCompileCommandListNV = (PFNGLCOMPILECOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glCompileCommandListNV")) == NULL) || r; + r = ((glCreateCommandListsNV = (PFNGLCREATECOMMANDLISTSNVPROC)glewGetProcAddress((const GLubyte*)"glCreateCommandListsNV")) == NULL) || r; + r = ((glCreateStatesNV = (PFNGLCREATESTATESNVPROC)glewGetProcAddress((const GLubyte*)"glCreateStatesNV")) == NULL) || r; + r = ((glDeleteCommandListsNV = (PFNGLDELETECOMMANDLISTSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteCommandListsNV")) == NULL) || r; + r = ((glDeleteStatesNV = (PFNGLDELETESTATESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteStatesNV")) == NULL) || r; + r = ((glDrawCommandsAddressNV = (PFNGLDRAWCOMMANDSADDRESSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsAddressNV")) == NULL) || r; + r = ((glDrawCommandsNV = (PFNGLDRAWCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsNV")) == NULL) || r; + r = ((glDrawCommandsStatesAddressNV = (PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsStatesAddressNV")) == NULL) || r; + r = ((glDrawCommandsStatesNV = (PFNGLDRAWCOMMANDSSTATESNVPROC)glewGetProcAddress((const GLubyte*)"glDrawCommandsStatesNV")) == NULL) || r; + r = ((glGetCommandHeaderNV = (PFNGLGETCOMMANDHEADERNVPROC)glewGetProcAddress((const GLubyte*)"glGetCommandHeaderNV")) == NULL) || r; + r = ((glGetStageIndexNV = (PFNGLGETSTAGEINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glGetStageIndexNV")) == NULL) || r; + r = ((glIsCommandListNV = (PFNGLISCOMMANDLISTNVPROC)glewGetProcAddress((const GLubyte*)"glIsCommandListNV")) == NULL) || r; + r = ((glIsStateNV = (PFNGLISSTATENVPROC)glewGetProcAddress((const GLubyte*)"glIsStateNV")) == NULL) || r; + r = ((glListDrawCommandsStatesClientNV = (PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC)glewGetProcAddress((const GLubyte*)"glListDrawCommandsStatesClientNV")) == NULL) || r; + r = ((glStateCaptureNV = (PFNGLSTATECAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glStateCaptureNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_command_list */ + +#ifdef GL_NV_conditional_render + +static GLboolean _glewInit_GL_NV_conditional_render () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginConditionalRenderNV = (PFNGLBEGINCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNV")) == NULL) || r; + r = ((glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_conditional_render */ + +#ifdef GL_NV_conservative_raster + +static GLboolean _glewInit_GL_NV_conservative_raster () +{ + GLboolean r = GL_FALSE; + + r = ((glSubpixelPrecisionBiasNV = (PFNGLSUBPIXELPRECISIONBIASNVPROC)glewGetProcAddress((const GLubyte*)"glSubpixelPrecisionBiasNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_conservative_raster */ + +#ifdef GL_NV_conservative_raster_dilate + +static GLboolean _glewInit_GL_NV_conservative_raster_dilate () +{ + GLboolean r = GL_FALSE; + + r = ((glConservativeRasterParameterfNV = (PFNGLCONSERVATIVERASTERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glConservativeRasterParameterfNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_conservative_raster_dilate */ + +#ifdef GL_NV_conservative_raster_pre_snap_triangles + +static GLboolean _glewInit_GL_NV_conservative_raster_pre_snap_triangles () +{ + GLboolean r = GL_FALSE; + + r = ((glConservativeRasterParameteriNV = (PFNGLCONSERVATIVERASTERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glConservativeRasterParameteriNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_conservative_raster_pre_snap_triangles */ + +#ifdef GL_NV_copy_buffer + +static GLboolean _glewInit_GL_NV_copy_buffer () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyBufferSubDataNV = (PFNGLCOPYBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glCopyBufferSubDataNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_copy_buffer */ + +#ifdef GL_NV_copy_image + +static GLboolean _glewInit_GL_NV_copy_image () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubDataNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_copy_image */ + +#ifdef GL_NV_depth_buffer_float + +static GLboolean _glewInit_GL_NV_depth_buffer_float () +{ + GLboolean r = GL_FALSE; + + r = ((glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)glewGetProcAddress((const GLubyte*)"glClearDepthdNV")) == NULL) || r; + r = ((glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsdNV")) == NULL) || r; + r = ((glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangedNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_depth_buffer_float */ + +#ifdef GL_NV_draw_buffers + +static GLboolean _glewInit_GL_NV_draw_buffers () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawBuffersNV = (PFNGLDRAWBUFFERSNVPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_draw_buffers */ + +#ifdef GL_NV_draw_instanced + +static GLboolean _glewInit_GL_NV_draw_instanced () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedNV")) == NULL) || r; + r = ((glDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_draw_instanced */ + +#ifdef GL_NV_draw_texture + +static GLboolean _glewInit_GL_NV_draw_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawTextureNV = (PFNGLDRAWTEXTURENVPROC)glewGetProcAddress((const GLubyte*)"glDrawTextureNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_draw_texture */ + +#ifdef GL_NV_draw_vulkan_image + +static GLboolean _glewInit_GL_NV_draw_vulkan_image () +{ + GLboolean r = GL_FALSE; + + r = ((glDrawVkImageNV = (PFNGLDRAWVKIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glDrawVkImageNV")) == NULL) || r; + r = ((glGetVkProcAddrNV = (PFNGLGETVKPROCADDRNVPROC)glewGetProcAddress((const GLubyte*)"glGetVkProcAddrNV")) == NULL) || r; + r = ((glSignalVkFenceNV = (PFNGLSIGNALVKFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSignalVkFenceNV")) == NULL) || r; + r = ((glSignalVkSemaphoreNV = (PFNGLSIGNALVKSEMAPHORENVPROC)glewGetProcAddress((const GLubyte*)"glSignalVkSemaphoreNV")) == NULL) || r; + r = ((glWaitVkSemaphoreNV = (PFNGLWAITVKSEMAPHORENVPROC)glewGetProcAddress((const GLubyte*)"glWaitVkSemaphoreNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_draw_vulkan_image */ + +#ifdef GL_NV_evaluators + +static GLboolean _glewInit_GL_NV_evaluators () +{ + GLboolean r = GL_FALSE; + + r = ((glEvalMapsNV = (PFNGLEVALMAPSNVPROC)glewGetProcAddress((const GLubyte*)"glEvalMapsNV")) == NULL) || r; + r = ((glGetMapAttribParameterfvNV = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterfvNV")) == NULL) || r; + r = ((glGetMapAttribParameterivNV = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterivNV")) == NULL) || r; + r = ((glGetMapControlPointsNV = (PFNGLGETMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapControlPointsNV")) == NULL) || r; + r = ((glGetMapParameterfvNV = (PFNGLGETMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterfvNV")) == NULL) || r; + r = ((glGetMapParameterivNV = (PFNGLGETMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterivNV")) == NULL) || r; + r = ((glMapControlPointsNV = (PFNGLMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glMapControlPointsNV")) == NULL) || r; + r = ((glMapParameterfvNV = (PFNGLMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterfvNV")) == NULL) || r; + r = ((glMapParameterivNV = (PFNGLMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_evaluators */ + +#ifdef GL_NV_explicit_multisample + +static GLboolean _glewInit_GL_NV_explicit_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glGetMultisamplefvNV = (PFNGLGETMULTISAMPLEFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefvNV")) == NULL) || r; + r = ((glSampleMaskIndexedNV = (PFNGLSAMPLEMASKINDEXEDNVPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskIndexedNV")) == NULL) || r; + r = ((glTexRenderbufferNV = (PFNGLTEXRENDERBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glTexRenderbufferNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_explicit_multisample */ + +#ifdef GL_NV_fence + +static GLboolean _glewInit_GL_NV_fence () +{ + GLboolean r = GL_FALSE; + + r = ((glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesNV")) == NULL) || r; + r = ((glFinishFenceNV = (PFNGLFINISHFENCENVPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceNV")) == NULL) || r; + r = ((glGenFencesNV = (PFNGLGENFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glGenFencesNV")) == NULL) || r; + r = ((glGetFenceivNV = (PFNGLGETFENCEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFenceivNV")) == NULL) || r; + r = ((glIsFenceNV = (PFNGLISFENCENVPROC)glewGetProcAddress((const GLubyte*)"glIsFenceNV")) == NULL) || r; + r = ((glSetFenceNV = (PFNGLSETFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSetFenceNV")) == NULL) || r; + r = ((glTestFenceNV = (PFNGLTESTFENCENVPROC)glewGetProcAddress((const GLubyte*)"glTestFenceNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fence */ + +#ifdef GL_NV_fragment_coverage_to_color + +static GLboolean _glewInit_GL_NV_fragment_coverage_to_color () +{ + GLboolean r = GL_FALSE; + + r = ((glFragmentCoverageColorNV = (PFNGLFRAGMENTCOVERAGECOLORNVPROC)glewGetProcAddress((const GLubyte*)"glFragmentCoverageColorNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fragment_coverage_to_color */ + +#ifdef GL_NV_fragment_program + +static GLboolean _glewInit_GL_NV_fragment_program () +{ + GLboolean r = GL_FALSE; + + r = ((glGetProgramNamedParameterdvNV = (PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterdvNV")) == NULL) || r; + r = ((glGetProgramNamedParameterfvNV = (PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterfvNV")) == NULL) || r; + r = ((glProgramNamedParameter4dNV = (PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dNV")) == NULL) || r; + r = ((glProgramNamedParameter4dvNV = (PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dvNV")) == NULL) || r; + r = ((glProgramNamedParameter4fNV = (PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fNV")) == NULL) || r; + r = ((glProgramNamedParameter4fvNV = (PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_fragment_program */ + +#ifdef GL_NV_framebuffer_blit + +static GLboolean _glewInit_GL_NV_framebuffer_blit () +{ + GLboolean r = GL_FALSE; + + r = ((glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_framebuffer_blit */ + +#ifdef GL_NV_framebuffer_multisample + +static GLboolean _glewInit_GL_NV_framebuffer_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_framebuffer_multisample */ + +#ifdef GL_NV_framebuffer_multisample_coverage + +static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage () +{ + GLboolean r = GL_FALSE; + + r = ((glRenderbufferStorageMultisampleCoverageNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleCoverageNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_framebuffer_multisample_coverage */ + +#ifdef GL_NV_geometry_program4 + +static GLboolean _glewInit_GL_NV_geometry_program4 () +{ + GLboolean r = GL_FALSE; + + r = ((glProgramVertexLimitNV = (PFNGLPROGRAMVERTEXLIMITNVPROC)glewGetProcAddress((const GLubyte*)"glProgramVertexLimitNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_geometry_program4 */ + +#ifdef GL_NV_gpu_multicast + +static GLboolean _glewInit_GL_NV_gpu_multicast () +{ + GLboolean r = GL_FALSE; + + r = ((glMulticastBarrierNV = (PFNGLMULTICASTBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBarrierNV")) == NULL) || r; + r = ((glMulticastBlitFramebufferNV = (PFNGLMULTICASTBLITFRAMEBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBlitFramebufferNV")) == NULL) || r; + r = ((glMulticastBufferSubDataNV = (PFNGLMULTICASTBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastBufferSubDataNV")) == NULL) || r; + r = ((glMulticastCopyBufferSubDataNV = (PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastCopyBufferSubDataNV")) == NULL) || r; + r = ((glMulticastCopyImageSubDataNV = (PFNGLMULTICASTCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glMulticastCopyImageSubDataNV")) == NULL) || r; + r = ((glMulticastFramebufferSampleLocationsfvNV = (PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastFramebufferSampleLocationsfvNV")) == NULL) || r; + r = ((glMulticastGetQueryObjecti64vNV = (PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjecti64vNV")) == NULL) || r; + r = ((glMulticastGetQueryObjectivNV = (PFNGLMULTICASTGETQUERYOBJECTIVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectivNV")) == NULL) || r; + r = ((glMulticastGetQueryObjectui64vNV = (PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectui64vNV")) == NULL) || r; + r = ((glMulticastGetQueryObjectuivNV = (PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastGetQueryObjectuivNV")) == NULL) || r; + r = ((glMulticastWaitSyncNV = (PFNGLMULTICASTWAITSYNCNVPROC)glewGetProcAddress((const GLubyte*)"glMulticastWaitSyncNV")) == NULL) || r; + r = ((glRenderGpuMaskNV = (PFNGLRENDERGPUMASKNVPROC)glewGetProcAddress((const GLubyte*)"glRenderGpuMaskNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_gpu_multicast */ + +#ifdef GL_NV_gpu_program4 + +static GLboolean _glewInit_GL_NV_gpu_program4 () +{ + GLboolean r = GL_FALSE; + + r = ((glProgramEnvParameterI4iNV = (PFNGLPROGRAMENVPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4iNV")) == NULL) || r; + r = ((glProgramEnvParameterI4ivNV = (PFNGLPROGRAMENVPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4ivNV")) == NULL) || r; + r = ((glProgramEnvParameterI4uiNV = (PFNGLPROGRAMENVPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uiNV")) == NULL) || r; + r = ((glProgramEnvParameterI4uivNV = (PFNGLPROGRAMENVPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uivNV")) == NULL) || r; + r = ((glProgramEnvParametersI4ivNV = (PFNGLPROGRAMENVPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4ivNV")) == NULL) || r; + r = ((glProgramEnvParametersI4uivNV = (PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4uivNV")) == NULL) || r; + r = ((glProgramLocalParameterI4iNV = (PFNGLPROGRAMLOCALPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4iNV")) == NULL) || r; + r = ((glProgramLocalParameterI4ivNV = (PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4ivNV")) == NULL) || r; + r = ((glProgramLocalParameterI4uiNV = (PFNGLPROGRAMLOCALPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uiNV")) == NULL) || r; + r = ((glProgramLocalParameterI4uivNV = (PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uivNV")) == NULL) || r; + r = ((glProgramLocalParametersI4ivNV = (PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4ivNV")) == NULL) || r; + r = ((glProgramLocalParametersI4uivNV = (PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4uivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_gpu_program4 */ + +#ifdef GL_NV_gpu_shader5 + +static GLboolean _glewInit_GL_NV_gpu_shader5 () +{ + GLboolean r = GL_FALSE; + + r = ((glGetUniformi64vNV = (PFNGLGETUNIFORMI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformi64vNV")) == NULL) || r; + r = ((glGetUniformui64vNV = (PFNGLGETUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformui64vNV")) == NULL) || r; + r = ((glProgramUniform1i64NV = (PFNGLPROGRAMUNIFORM1I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64NV")) == NULL) || r; + r = ((glProgramUniform1i64vNV = (PFNGLPROGRAMUNIFORM1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64vNV")) == NULL) || r; + r = ((glProgramUniform1ui64NV = (PFNGLPROGRAMUNIFORM1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64NV")) == NULL) || r; + r = ((glProgramUniform1ui64vNV = (PFNGLPROGRAMUNIFORM1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64vNV")) == NULL) || r; + r = ((glProgramUniform2i64NV = (PFNGLPROGRAMUNIFORM2I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64NV")) == NULL) || r; + r = ((glProgramUniform2i64vNV = (PFNGLPROGRAMUNIFORM2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64vNV")) == NULL) || r; + r = ((glProgramUniform2ui64NV = (PFNGLPROGRAMUNIFORM2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64NV")) == NULL) || r; + r = ((glProgramUniform2ui64vNV = (PFNGLPROGRAMUNIFORM2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64vNV")) == NULL) || r; + r = ((glProgramUniform3i64NV = (PFNGLPROGRAMUNIFORM3I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64NV")) == NULL) || r; + r = ((glProgramUniform3i64vNV = (PFNGLPROGRAMUNIFORM3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64vNV")) == NULL) || r; + r = ((glProgramUniform3ui64NV = (PFNGLPROGRAMUNIFORM3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64NV")) == NULL) || r; + r = ((glProgramUniform3ui64vNV = (PFNGLPROGRAMUNIFORM3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64vNV")) == NULL) || r; + r = ((glProgramUniform4i64NV = (PFNGLPROGRAMUNIFORM4I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64NV")) == NULL) || r; + r = ((glProgramUniform4i64vNV = (PFNGLPROGRAMUNIFORM4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64vNV")) == NULL) || r; + r = ((glProgramUniform4ui64NV = (PFNGLPROGRAMUNIFORM4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64NV")) == NULL) || r; + r = ((glProgramUniform4ui64vNV = (PFNGLPROGRAMUNIFORM4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64vNV")) == NULL) || r; + r = ((glUniform1i64NV = (PFNGLUNIFORM1I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64NV")) == NULL) || r; + r = ((glUniform1i64vNV = (PFNGLUNIFORM1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64vNV")) == NULL) || r; + r = ((glUniform1ui64NV = (PFNGLUNIFORM1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64NV")) == NULL) || r; + r = ((glUniform1ui64vNV = (PFNGLUNIFORM1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64vNV")) == NULL) || r; + r = ((glUniform2i64NV = (PFNGLUNIFORM2I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64NV")) == NULL) || r; + r = ((glUniform2i64vNV = (PFNGLUNIFORM2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64vNV")) == NULL) || r; + r = ((glUniform2ui64NV = (PFNGLUNIFORM2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64NV")) == NULL) || r; + r = ((glUniform2ui64vNV = (PFNGLUNIFORM2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64vNV")) == NULL) || r; + r = ((glUniform3i64NV = (PFNGLUNIFORM3I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64NV")) == NULL) || r; + r = ((glUniform3i64vNV = (PFNGLUNIFORM3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64vNV")) == NULL) || r; + r = ((glUniform3ui64NV = (PFNGLUNIFORM3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64NV")) == NULL) || r; + r = ((glUniform3ui64vNV = (PFNGLUNIFORM3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64vNV")) == NULL) || r; + r = ((glUniform4i64NV = (PFNGLUNIFORM4I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64NV")) == NULL) || r; + r = ((glUniform4i64vNV = (PFNGLUNIFORM4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64vNV")) == NULL) || r; + r = ((glUniform4ui64NV = (PFNGLUNIFORM4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64NV")) == NULL) || r; + r = ((glUniform4ui64vNV = (PFNGLUNIFORM4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64vNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_gpu_shader5 */ + +#ifdef GL_NV_half_float + +static GLboolean _glewInit_GL_NV_half_float () +{ + GLboolean r = GL_FALSE; + + r = ((glColor3hNV = (PFNGLCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hNV")) == NULL) || r; + r = ((glColor3hvNV = (PFNGLCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hvNV")) == NULL) || r; + r = ((glColor4hNV = (PFNGLCOLOR4HNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hNV")) == NULL) || r; + r = ((glColor4hvNV = (PFNGLCOLOR4HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hvNV")) == NULL) || r; + r = ((glFogCoordhNV = (PFNGLFOGCOORDHNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhNV")) == NULL) || r; + r = ((glFogCoordhvNV = (PFNGLFOGCOORDHVNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhvNV")) == NULL) || r; + r = ((glMultiTexCoord1hNV = (PFNGLMULTITEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hNV")) == NULL) || r; + r = ((glMultiTexCoord1hvNV = (PFNGLMULTITEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hvNV")) == NULL) || r; + r = ((glMultiTexCoord2hNV = (PFNGLMULTITEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hNV")) == NULL) || r; + r = ((glMultiTexCoord2hvNV = (PFNGLMULTITEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hvNV")) == NULL) || r; + r = ((glMultiTexCoord3hNV = (PFNGLMULTITEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hNV")) == NULL) || r; + r = ((glMultiTexCoord3hvNV = (PFNGLMULTITEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hvNV")) == NULL) || r; + r = ((glMultiTexCoord4hNV = (PFNGLMULTITEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hNV")) == NULL) || r; + r = ((glMultiTexCoord4hvNV = (PFNGLMULTITEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hvNV")) == NULL) || r; + r = ((glNormal3hNV = (PFNGLNORMAL3HNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hNV")) == NULL) || r; + r = ((glNormal3hvNV = (PFNGLNORMAL3HVNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hvNV")) == NULL) || r; + r = ((glSecondaryColor3hNV = (PFNGLSECONDARYCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hNV")) == NULL) || r; + r = ((glSecondaryColor3hvNV = (PFNGLSECONDARYCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hvNV")) == NULL) || r; + r = ((glTexCoord1hNV = (PFNGLTEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hNV")) == NULL) || r; + r = ((glTexCoord1hvNV = (PFNGLTEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hvNV")) == NULL) || r; + r = ((glTexCoord2hNV = (PFNGLTEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hNV")) == NULL) || r; + r = ((glTexCoord2hvNV = (PFNGLTEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hvNV")) == NULL) || r; + r = ((glTexCoord3hNV = (PFNGLTEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hNV")) == NULL) || r; + r = ((glTexCoord3hvNV = (PFNGLTEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hvNV")) == NULL) || r; + r = ((glTexCoord4hNV = (PFNGLTEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hNV")) == NULL) || r; + r = ((glTexCoord4hvNV = (PFNGLTEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hvNV")) == NULL) || r; + r = ((glVertex2hNV = (PFNGLVERTEX2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hNV")) == NULL) || r; + r = ((glVertex2hvNV = (PFNGLVERTEX2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hvNV")) == NULL) || r; + r = ((glVertex3hNV = (PFNGLVERTEX3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hNV")) == NULL) || r; + r = ((glVertex3hvNV = (PFNGLVERTEX3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hvNV")) == NULL) || r; + r = ((glVertex4hNV = (PFNGLVERTEX4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hNV")) == NULL) || r; + r = ((glVertex4hvNV = (PFNGLVERTEX4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hvNV")) == NULL) || r; + r = ((glVertexAttrib1hNV = (PFNGLVERTEXATTRIB1HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hNV")) == NULL) || r; + r = ((glVertexAttrib1hvNV = (PFNGLVERTEXATTRIB1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hvNV")) == NULL) || r; + r = ((glVertexAttrib2hNV = (PFNGLVERTEXATTRIB2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hNV")) == NULL) || r; + r = ((glVertexAttrib2hvNV = (PFNGLVERTEXATTRIB2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hvNV")) == NULL) || r; + r = ((glVertexAttrib3hNV = (PFNGLVERTEXATTRIB3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hNV")) == NULL) || r; + r = ((glVertexAttrib3hvNV = (PFNGLVERTEXATTRIB3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hvNV")) == NULL) || r; + r = ((glVertexAttrib4hNV = (PFNGLVERTEXATTRIB4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hNV")) == NULL) || r; + r = ((glVertexAttrib4hvNV = (PFNGLVERTEXATTRIB4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hvNV")) == NULL) || r; + r = ((glVertexAttribs1hvNV = (PFNGLVERTEXATTRIBS1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1hvNV")) == NULL) || r; + r = ((glVertexAttribs2hvNV = (PFNGLVERTEXATTRIBS2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2hvNV")) == NULL) || r; + r = ((glVertexAttribs3hvNV = (PFNGLVERTEXATTRIBS3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3hvNV")) == NULL) || r; + r = ((glVertexAttribs4hvNV = (PFNGLVERTEXATTRIBS4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4hvNV")) == NULL) || r; + r = ((glVertexWeighthNV = (PFNGLVERTEXWEIGHTHNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthNV")) == NULL) || r; + r = ((glVertexWeighthvNV = (PFNGLVERTEXWEIGHTHVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_half_float */ + +#ifdef GL_NV_instanced_arrays + +static GLboolean _glewInit_GL_NV_instanced_arrays () +{ + GLboolean r = GL_FALSE; + + r = ((glVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_instanced_arrays */ + +#ifdef GL_NV_internalformat_sample_query + +static GLboolean _glewInit_GL_NV_internalformat_sample_query () +{ + GLboolean r = GL_FALSE; + + r = ((glGetInternalformatSampleivNV = (PFNGLGETINTERNALFORMATSAMPLEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformatSampleivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_internalformat_sample_query */ + +#ifdef GL_NV_non_square_matrices + +static GLboolean _glewInit_GL_NV_non_square_matrices () +{ + GLboolean r = GL_FALSE; + + r = ((glUniformMatrix2x3fvNV = (PFNGLUNIFORMMATRIX2X3FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3fvNV")) == NULL) || r; + r = ((glUniformMatrix2x4fvNV = (PFNGLUNIFORMMATRIX2X4FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4fvNV")) == NULL) || r; + r = ((glUniformMatrix3x2fvNV = (PFNGLUNIFORMMATRIX3X2FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2fvNV")) == NULL) || r; + r = ((glUniformMatrix3x4fvNV = (PFNGLUNIFORMMATRIX3X4FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4fvNV")) == NULL) || r; + r = ((glUniformMatrix4x2fvNV = (PFNGLUNIFORMMATRIX4X2FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2fvNV")) == NULL) || r; + r = ((glUniformMatrix4x3fvNV = (PFNGLUNIFORMMATRIX4X3FVNVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3fvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_non_square_matrices */ + +#ifdef GL_NV_occlusion_query + +static GLboolean _glewInit_GL_NV_occlusion_query () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glBeginOcclusionQueryNV")) == NULL) || r; + r = ((glDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteOcclusionQueriesNV")) == NULL) || r; + r = ((glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glEndOcclusionQueryNV")) == NULL) || r; + r = ((glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glGenOcclusionQueriesNV")) == NULL) || r; + r = ((glGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryivNV")) == NULL) || r; + r = ((glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryuivNV")) == NULL) || r; + r = ((glIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glIsOcclusionQueryNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_occlusion_query */ + +#ifdef GL_NV_parameter_buffer_object + +static GLboolean _glewInit_GL_NV_parameter_buffer_object () +{ + GLboolean r = GL_FALSE; + + r = ((glProgramBufferParametersIivNV = (PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIivNV")) == NULL) || r; + r = ((glProgramBufferParametersIuivNV = (PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIuivNV")) == NULL) || r; + r = ((glProgramBufferParametersfvNV = (PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_parameter_buffer_object */ + +#ifdef GL_NV_path_rendering + +static GLboolean _glewInit_GL_NV_path_rendering () +{ + GLboolean r = GL_FALSE; + + r = ((glCopyPathNV = (PFNGLCOPYPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCopyPathNV")) == NULL) || r; + r = ((glCoverFillPathInstancedNV = (PFNGLCOVERFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glCoverFillPathInstancedNV")) == NULL) || r; + r = ((glCoverFillPathNV = (PFNGLCOVERFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCoverFillPathNV")) == NULL) || r; + r = ((glCoverStrokePathInstancedNV = (PFNGLCOVERSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glCoverStrokePathInstancedNV")) == NULL) || r; + r = ((glCoverStrokePathNV = (PFNGLCOVERSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCoverStrokePathNV")) == NULL) || r; + r = ((glDeletePathsNV = (PFNGLDELETEPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glDeletePathsNV")) == NULL) || r; + r = ((glGenPathsNV = (PFNGLGENPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glGenPathsNV")) == NULL) || r; + r = ((glGetPathColorGenfvNV = (PFNGLGETPATHCOLORGENFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathColorGenfvNV")) == NULL) || r; + r = ((glGetPathColorGenivNV = (PFNGLGETPATHCOLORGENIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathColorGenivNV")) == NULL) || r; + r = ((glGetPathCommandsNV = (PFNGLGETPATHCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathCommandsNV")) == NULL) || r; + r = ((glGetPathCoordsNV = (PFNGLGETPATHCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathCoordsNV")) == NULL) || r; + r = ((glGetPathDashArrayNV = (PFNGLGETPATHDASHARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathDashArrayNV")) == NULL) || r; + r = ((glGetPathLengthNV = (PFNGLGETPATHLENGTHNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathLengthNV")) == NULL) || r; + r = ((glGetPathMetricRangeNV = (PFNGLGETPATHMETRICRANGENVPROC)glewGetProcAddress((const GLubyte*)"glGetPathMetricRangeNV")) == NULL) || r; + r = ((glGetPathMetricsNV = (PFNGLGETPATHMETRICSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathMetricsNV")) == NULL) || r; + r = ((glGetPathParameterfvNV = (PFNGLGETPATHPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathParameterfvNV")) == NULL) || r; + r = ((glGetPathParameterivNV = (PFNGLGETPATHPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathParameterivNV")) == NULL) || r; + r = ((glGetPathSpacingNV = (PFNGLGETPATHSPACINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathSpacingNV")) == NULL) || r; + r = ((glGetPathTexGenfvNV = (PFNGLGETPATHTEXGENFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathTexGenfvNV")) == NULL) || r; + r = ((glGetPathTexGenivNV = (PFNGLGETPATHTEXGENIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathTexGenivNV")) == NULL) || r; + r = ((glGetProgramResourcefvNV = (PFNGLGETPROGRAMRESOURCEFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourcefvNV")) == NULL) || r; + r = ((glInterpolatePathsNV = (PFNGLINTERPOLATEPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glInterpolatePathsNV")) == NULL) || r; + r = ((glIsPathNV = (PFNGLISPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPathNV")) == NULL) || r; + r = ((glIsPointInFillPathNV = (PFNGLISPOINTINFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPointInFillPathNV")) == NULL) || r; + r = ((glIsPointInStrokePathNV = (PFNGLISPOINTINSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPointInStrokePathNV")) == NULL) || r; + r = ((glMatrixLoad3x2fNV = (PFNGLMATRIXLOAD3X2FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoad3x2fNV")) == NULL) || r; + r = ((glMatrixLoad3x3fNV = (PFNGLMATRIXLOAD3X3FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoad3x3fNV")) == NULL) || r; + r = ((glMatrixLoadTranspose3x3fNV = (PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTranspose3x3fNV")) == NULL) || r; + r = ((glMatrixMult3x2fNV = (PFNGLMATRIXMULT3X2FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixMult3x2fNV")) == NULL) || r; + r = ((glMatrixMult3x3fNV = (PFNGLMATRIXMULT3X3FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixMult3x3fNV")) == NULL) || r; + r = ((glMatrixMultTranspose3x3fNV = (PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTranspose3x3fNV")) == NULL) || r; + r = ((glPathColorGenNV = (PFNGLPATHCOLORGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathColorGenNV")) == NULL) || r; + r = ((glPathCommandsNV = (PFNGLPATHCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathCommandsNV")) == NULL) || r; + r = ((glPathCoordsNV = (PFNGLPATHCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathCoordsNV")) == NULL) || r; + r = ((glPathCoverDepthFuncNV = (PFNGLPATHCOVERDEPTHFUNCNVPROC)glewGetProcAddress((const GLubyte*)"glPathCoverDepthFuncNV")) == NULL) || r; + r = ((glPathDashArrayNV = (PFNGLPATHDASHARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glPathDashArrayNV")) == NULL) || r; + r = ((glPathFogGenNV = (PFNGLPATHFOGGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathFogGenNV")) == NULL) || r; + r = ((glPathGlyphIndexArrayNV = (PFNGLPATHGLYPHINDEXARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphIndexArrayNV")) == NULL) || r; + r = ((glPathGlyphIndexRangeNV = (PFNGLPATHGLYPHINDEXRANGENVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphIndexRangeNV")) == NULL) || r; + r = ((glPathGlyphRangeNV = (PFNGLPATHGLYPHRANGENVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphRangeNV")) == NULL) || r; + r = ((glPathGlyphsNV = (PFNGLPATHGLYPHSNVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphsNV")) == NULL) || r; + r = ((glPathMemoryGlyphIndexArrayNV = (PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glPathMemoryGlyphIndexArrayNV")) == NULL) || r; + r = ((glPathParameterfNV = (PFNGLPATHPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterfNV")) == NULL) || r; + r = ((glPathParameterfvNV = (PFNGLPATHPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterfvNV")) == NULL) || r; + r = ((glPathParameteriNV = (PFNGLPATHPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPathParameteriNV")) == NULL) || r; + r = ((glPathParameterivNV = (PFNGLPATHPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterivNV")) == NULL) || r; + r = ((glPathStencilDepthOffsetNV = (PFNGLPATHSTENCILDEPTHOFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glPathStencilDepthOffsetNV")) == NULL) || r; + r = ((glPathStencilFuncNV = (PFNGLPATHSTENCILFUNCNVPROC)glewGetProcAddress((const GLubyte*)"glPathStencilFuncNV")) == NULL) || r; + r = ((glPathStringNV = (PFNGLPATHSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glPathStringNV")) == NULL) || r; + r = ((glPathSubCommandsNV = (PFNGLPATHSUBCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathSubCommandsNV")) == NULL) || r; + r = ((glPathSubCoordsNV = (PFNGLPATHSUBCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathSubCoordsNV")) == NULL) || r; + r = ((glPathTexGenNV = (PFNGLPATHTEXGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathTexGenNV")) == NULL) || r; + r = ((glPointAlongPathNV = (PFNGLPOINTALONGPATHNVPROC)glewGetProcAddress((const GLubyte*)"glPointAlongPathNV")) == NULL) || r; + r = ((glProgramPathFragmentInputGenNV = (PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC)glewGetProcAddress((const GLubyte*)"glProgramPathFragmentInputGenNV")) == NULL) || r; + r = ((glStencilFillPathInstancedNV = (PFNGLSTENCILFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilFillPathInstancedNV")) == NULL) || r; + r = ((glStencilFillPathNV = (PFNGLSTENCILFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilFillPathNV")) == NULL) || r; + r = ((glStencilStrokePathInstancedNV = (PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilStrokePathInstancedNV")) == NULL) || r; + r = ((glStencilStrokePathNV = (PFNGLSTENCILSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilStrokePathNV")) == NULL) || r; + r = ((glStencilThenCoverFillPathInstancedNV = (PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilThenCoverFillPathInstancedNV")) == NULL) || r; + r = ((glStencilThenCoverFillPathNV = (PFNGLSTENCILTHENCOVERFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilThenCoverFillPathNV")) == NULL) || r; + r = ((glStencilThenCoverStrokePathInstancedNV = (PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilThenCoverStrokePathInstancedNV")) == NULL) || r; + r = ((glStencilThenCoverStrokePathNV = (PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilThenCoverStrokePathNV")) == NULL) || r; + r = ((glTransformPathNV = (PFNGLTRANSFORMPATHNVPROC)glewGetProcAddress((const GLubyte*)"glTransformPathNV")) == NULL) || r; + r = ((glWeightPathsNV = (PFNGLWEIGHTPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glWeightPathsNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_path_rendering */ + +#ifdef GL_NV_pixel_data_range + +static GLboolean _glewInit_GL_NV_pixel_data_range () +{ + GLboolean r = GL_FALSE; + + r = ((glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushPixelDataRangeNV")) == NULL) || r; + r = ((glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glPixelDataRangeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_pixel_data_range */ + +#ifdef GL_NV_point_sprite + +static GLboolean _glewInit_GL_NV_point_sprite () +{ + GLboolean r = GL_FALSE; + + r = ((glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriNV")) == NULL) || r; + r = ((glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_point_sprite */ + +#ifdef GL_NV_polygon_mode + +static GLboolean _glewInit_GL_NV_polygon_mode () +{ + GLboolean r = GL_FALSE; + + r = ((glPolygonModeNV = (PFNGLPOLYGONMODENVPROC)glewGetProcAddress((const GLubyte*)"glPolygonModeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_polygon_mode */ + +#ifdef GL_NV_present_video + +static GLboolean _glewInit_GL_NV_present_video () +{ + GLboolean r = GL_FALSE; + + r = ((glGetVideoi64vNV = (PFNGLGETVIDEOI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoi64vNV")) == NULL) || r; + r = ((glGetVideoivNV = (PFNGLGETVIDEOIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoivNV")) == NULL) || r; + r = ((glGetVideoui64vNV = (PFNGLGETVIDEOUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoui64vNV")) == NULL) || r; + r = ((glGetVideouivNV = (PFNGLGETVIDEOUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideouivNV")) == NULL) || r; + r = ((glPresentFrameDualFillNV = (PFNGLPRESENTFRAMEDUALFILLNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameDualFillNV")) == NULL) || r; + r = ((glPresentFrameKeyedNV = (PFNGLPRESENTFRAMEKEYEDNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameKeyedNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_present_video */ + +#ifdef GL_NV_primitive_restart + +static GLboolean _glewInit_GL_NV_primitive_restart () +{ + GLboolean r = GL_FALSE; + + r = ((glPrimitiveRestartIndexNV = (PFNGLPRIMITIVERESTARTINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndexNV")) == NULL) || r; + r = ((glPrimitiveRestartNV = (PFNGLPRIMITIVERESTARTNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_primitive_restart */ + +#ifdef GL_NV_register_combiners + +static GLboolean _glewInit_GL_NV_register_combiners () +{ + GLboolean r = GL_FALSE; + + r = ((glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerInputNV")) == NULL) || r; + r = ((glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerOutputNV")) == NULL) || r; + r = ((glCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfNV")) == NULL) || r; + r = ((glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfvNV")) == NULL) || r; + r = ((glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameteriNV")) == NULL) || r; + r = ((glCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterivNV")) == NULL) || r; + r = ((glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glFinalCombinerInputNV")) == NULL) || r; + r = ((glGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterfvNV")) == NULL) || r; + r = ((glGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterivNV")) == NULL) || r; + r = ((glGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterfvNV")) == NULL) || r; + r = ((glGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterivNV")) == NULL) || r; + r = ((glGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterfvNV")) == NULL) || r; + r = ((glGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_register_combiners */ + +#ifdef GL_NV_register_combiners2 + +static GLboolean _glewInit_GL_NV_register_combiners2 () +{ + GLboolean r = GL_FALSE; + + r = ((glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerStageParameterfvNV")) == NULL) || r; + r = ((glGetCombinerStageParameterfvNV = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerStageParameterfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_register_combiners2 */ + +#ifdef GL_NV_sample_locations + +static GLboolean _glewInit_GL_NV_sample_locations () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferSampleLocationsfvNV = (PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)glewGetProcAddress((const GLubyte*)"glFramebufferSampleLocationsfvNV")) == NULL) || r; + r = ((glNamedFramebufferSampleLocationsfvNV = (PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferSampleLocationsfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_sample_locations */ + +#ifdef GL_NV_shader_buffer_load + +static GLboolean _glewInit_GL_NV_shader_buffer_load () +{ + GLboolean r = GL_FALSE; + + r = ((glGetBufferParameterui64vNV = (PFNGLGETBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterui64vNV")) == NULL) || r; + r = ((glGetIntegerui64vNV = (PFNGLGETINTEGERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64vNV")) == NULL) || r; + r = ((glGetNamedBufferParameterui64vNV = (PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterui64vNV")) == NULL) || r; + r = ((glIsBufferResidentNV = (PFNGLISBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsBufferResidentNV")) == NULL) || r; + r = ((glIsNamedBufferResidentNV = (PFNGLISNAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsNamedBufferResidentNV")) == NULL) || r; + r = ((glMakeBufferNonResidentNV = (PFNGLMAKEBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferNonResidentNV")) == NULL) || r; + r = ((glMakeBufferResidentNV = (PFNGLMAKEBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferResidentNV")) == NULL) || r; + r = ((glMakeNamedBufferNonResidentNV = (PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferNonResidentNV")) == NULL) || r; + r = ((glMakeNamedBufferResidentNV = (PFNGLMAKENAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferResidentNV")) == NULL) || r; + r = ((glProgramUniformui64NV = (PFNGLPROGRAMUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64NV")) == NULL) || r; + r = ((glProgramUniformui64vNV = (PFNGLPROGRAMUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64vNV")) == NULL) || r; + r = ((glUniformui64NV = (PFNGLUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64NV")) == NULL) || r; + r = ((glUniformui64vNV = (PFNGLUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64vNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_shader_buffer_load */ + +#ifdef GL_NV_texture_array + +static GLboolean _glewInit_GL_NV_texture_array () +{ + GLboolean r = GL_FALSE; + + r = ((glCompressedTexImage3DNV = (PFNGLCOMPRESSEDTEXIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DNV")) == NULL) || r; + r = ((glCompressedTexSubImage3DNV = (PFNGLCOMPRESSEDTEXSUBIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DNV")) == NULL) || r; + r = ((glCopyTexSubImage3DNV = (PFNGLCOPYTEXSUBIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DNV")) == NULL) || r; + r = ((glFramebufferTextureLayerNV = (PFNGLFRAMEBUFFERTEXTURELAYERNVPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerNV")) == NULL) || r; + r = ((glTexImage3DNV = (PFNGLTEXIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DNV")) == NULL) || r; + r = ((glTexSubImage3DNV = (PFNGLTEXSUBIMAGE3DNVPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_texture_array */ + +#ifdef GL_NV_texture_barrier + +static GLboolean _glewInit_GL_NV_texture_barrier () +{ + GLboolean r = GL_FALSE; + + r = ((glTextureBarrierNV = (PFNGLTEXTUREBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glTextureBarrierNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_texture_barrier */ + +#ifdef GL_NV_texture_multisample + +static GLboolean _glewInit_GL_NV_texture_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage2DMultisampleCoverageNV = (PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisampleCoverageNV")) == NULL) || r; + r = ((glTexImage3DMultisampleCoverageNV = (PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisampleCoverageNV")) == NULL) || r; + r = ((glTextureImage2DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DMultisampleCoverageNV")) == NULL) || r; + r = ((glTextureImage2DMultisampleNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DMultisampleNV")) == NULL) || r; + r = ((glTextureImage3DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DMultisampleCoverageNV")) == NULL) || r; + r = ((glTextureImage3DMultisampleNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DMultisampleNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_texture_multisample */ + +#ifdef GL_NV_transform_feedback + +static GLboolean _glewInit_GL_NV_transform_feedback () +{ + GLboolean r = GL_FALSE; + + r = ((glActiveVaryingNV = (PFNGLACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glActiveVaryingNV")) == NULL) || r; + r = ((glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackNV")) == NULL) || r; + r = ((glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseNV")) == NULL) || r; + r = ((glBindBufferOffsetNV = (PFNGLBINDBUFFEROFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetNV")) == NULL) || r; + r = ((glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeNV")) == NULL) || r; + r = ((glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackNV")) == NULL) || r; + r = ((glGetActiveVaryingNV = (PFNGLGETACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveVaryingNV")) == NULL) || r; + r = ((glGetTransformFeedbackVaryingNV = (PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingNV")) == NULL) || r; + r = ((glGetVaryingLocationNV = (PFNGLGETVARYINGLOCATIONNVPROC)glewGetProcAddress((const GLubyte*)"glGetVaryingLocationNV")) == NULL) || r; + r = ((glTransformFeedbackAttribsNV = (PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackAttribsNV")) == NULL) || r; + r = ((glTransformFeedbackVaryingsNV = (PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_transform_feedback */ + +#ifdef GL_NV_transform_feedback2 + +static GLboolean _glewInit_GL_NV_transform_feedback2 () +{ + GLboolean r = GL_FALSE; + + r = ((glBindTransformFeedbackNV = (PFNGLBINDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedbackNV")) == NULL) || r; + r = ((glDeleteTransformFeedbacksNV = (PFNGLDELETETRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacksNV")) == NULL) || r; + r = ((glDrawTransformFeedbackNV = (PFNGLDRAWTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackNV")) == NULL) || r; + r = ((glGenTransformFeedbacksNV = (PFNGLGENTRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacksNV")) == NULL) || r; + r = ((glIsTransformFeedbackNV = (PFNGLISTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedbackNV")) == NULL) || r; + r = ((glPauseTransformFeedbackNV = (PFNGLPAUSETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedbackNV")) == NULL) || r; + r = ((glResumeTransformFeedbackNV = (PFNGLRESUMETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedbackNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_transform_feedback2 */ + +#ifdef GL_NV_vdpau_interop + +static GLboolean _glewInit_GL_NV_vdpau_interop () +{ + GLboolean r = GL_FALSE; + + r = ((glVDPAUFiniNV = (PFNGLVDPAUFININVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUFiniNV")) == NULL) || r; + r = ((glVDPAUGetSurfaceivNV = (PFNGLVDPAUGETSURFACEIVNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUGetSurfaceivNV")) == NULL) || r; + r = ((glVDPAUInitNV = (PFNGLVDPAUINITNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUInitNV")) == NULL) || r; + r = ((glVDPAUIsSurfaceNV = (PFNGLVDPAUISSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUIsSurfaceNV")) == NULL) || r; + r = ((glVDPAUMapSurfacesNV = (PFNGLVDPAUMAPSURFACESNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUMapSurfacesNV")) == NULL) || r; + r = ((glVDPAURegisterOutputSurfaceNV = (PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAURegisterOutputSurfaceNV")) == NULL) || r; + r = ((glVDPAURegisterVideoSurfaceNV = (PFNGLVDPAUREGISTERVIDEOSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAURegisterVideoSurfaceNV")) == NULL) || r; + r = ((glVDPAUSurfaceAccessNV = (PFNGLVDPAUSURFACEACCESSNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUSurfaceAccessNV")) == NULL) || r; + r = ((glVDPAUUnmapSurfacesNV = (PFNGLVDPAUUNMAPSURFACESNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUUnmapSurfacesNV")) == NULL) || r; + r = ((glVDPAUUnregisterSurfaceNV = (PFNGLVDPAUUNREGISTERSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUUnregisterSurfaceNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vdpau_interop */ + +#ifdef GL_NV_vertex_array_range + +static GLboolean _glewInit_GL_NV_vertex_array_range () +{ + GLboolean r = GL_FALSE; + + r = ((glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeNV")) == NULL) || r; + r = ((glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_array_range */ + +#ifdef GL_NV_vertex_attrib_integer_64bit + +static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit () +{ + GLboolean r = GL_FALSE; + + r = ((glGetVertexAttribLi64vNV = (PFNGLGETVERTEXATTRIBLI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLi64vNV")) == NULL) || r; + r = ((glGetVertexAttribLui64vNV = (PFNGLGETVERTEXATTRIBLUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLui64vNV")) == NULL) || r; + r = ((glVertexAttribL1i64NV = (PFNGLVERTEXATTRIBL1I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1i64NV")) == NULL) || r; + r = ((glVertexAttribL1i64vNV = (PFNGLVERTEXATTRIBL1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1i64vNV")) == NULL) || r; + r = ((glVertexAttribL1ui64NV = (PFNGLVERTEXATTRIBL1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64NV")) == NULL) || r; + r = ((glVertexAttribL1ui64vNV = (PFNGLVERTEXATTRIBL1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64vNV")) == NULL) || r; + r = ((glVertexAttribL2i64NV = (PFNGLVERTEXATTRIBL2I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2i64NV")) == NULL) || r; + r = ((glVertexAttribL2i64vNV = (PFNGLVERTEXATTRIBL2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2i64vNV")) == NULL) || r; + r = ((glVertexAttribL2ui64NV = (PFNGLVERTEXATTRIBL2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2ui64NV")) == NULL) || r; + r = ((glVertexAttribL2ui64vNV = (PFNGLVERTEXATTRIBL2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2ui64vNV")) == NULL) || r; + r = ((glVertexAttribL3i64NV = (PFNGLVERTEXATTRIBL3I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3i64NV")) == NULL) || r; + r = ((glVertexAttribL3i64vNV = (PFNGLVERTEXATTRIBL3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3i64vNV")) == NULL) || r; + r = ((glVertexAttribL3ui64NV = (PFNGLVERTEXATTRIBL3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3ui64NV")) == NULL) || r; + r = ((glVertexAttribL3ui64vNV = (PFNGLVERTEXATTRIBL3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3ui64vNV")) == NULL) || r; + r = ((glVertexAttribL4i64NV = (PFNGLVERTEXATTRIBL4I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4i64NV")) == NULL) || r; + r = ((glVertexAttribL4i64vNV = (PFNGLVERTEXATTRIBL4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4i64vNV")) == NULL) || r; + r = ((glVertexAttribL4ui64NV = (PFNGLVERTEXATTRIBL4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4ui64NV")) == NULL) || r; + r = ((glVertexAttribL4ui64vNV = (PFNGLVERTEXATTRIBL4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4ui64vNV")) == NULL) || r; + r = ((glVertexAttribLFormatNV = (PFNGLVERTEXATTRIBLFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLFormatNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_attrib_integer_64bit */ + +#ifdef GL_NV_vertex_buffer_unified_memory + +static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory () +{ + GLboolean r = GL_FALSE; + + r = ((glBufferAddressRangeNV = (PFNGLBUFFERADDRESSRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBufferAddressRangeNV")) == NULL) || r; + r = ((glColorFormatNV = (PFNGLCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glColorFormatNV")) == NULL) || r; + r = ((glEdgeFlagFormatNV = (PFNGLEDGEFLAGFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagFormatNV")) == NULL) || r; + r = ((glFogCoordFormatNV = (PFNGLFOGCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordFormatNV")) == NULL) || r; + r = ((glGetIntegerui64i_vNV = (PFNGLGETINTEGERUI64I_VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64i_vNV")) == NULL) || r; + r = ((glIndexFormatNV = (PFNGLINDEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glIndexFormatNV")) == NULL) || r; + r = ((glNormalFormatNV = (PFNGLNORMALFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glNormalFormatNV")) == NULL) || r; + r = ((glSecondaryColorFormatNV = (PFNGLSECONDARYCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorFormatNV")) == NULL) || r; + r = ((glTexCoordFormatNV = (PFNGLTEXCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordFormatNV")) == NULL) || r; + r = ((glVertexAttribFormatNV = (PFNGLVERTEXATTRIBFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormatNV")) == NULL) || r; + r = ((glVertexAttribIFormatNV = (PFNGLVERTEXATTRIBIFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormatNV")) == NULL) || r; + r = ((glVertexFormatNV = (PFNGLVERTEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexFormatNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_buffer_unified_memory */ + +#ifdef GL_NV_vertex_program + +static GLboolean _glewInit_GL_NV_vertex_program () +{ + GLboolean r = GL_FALSE; + + r = ((glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glAreProgramsResidentNV")) == NULL) || r; + r = ((glBindProgramNV = (PFNGLBINDPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glBindProgramNV")) == NULL) || r; + r = ((glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsNV")) == NULL) || r; + r = ((glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glExecuteProgramNV")) == NULL) || r; + r = ((glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsNV")) == NULL) || r; + r = ((glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterdvNV")) == NULL) || r; + r = ((glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterfvNV")) == NULL) || r; + r = ((glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringNV")) == NULL) || r; + r = ((glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivNV")) == NULL) || r; + r = ((glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetTrackMatrixivNV")) == NULL) || r; + r = ((glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervNV")) == NULL) || r; + r = ((glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvNV")) == NULL) || r; + r = ((glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvNV")) == NULL) || r; + r = ((glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivNV")) == NULL) || r; + r = ((glIsProgramNV = (PFNGLISPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glIsProgramNV")) == NULL) || r; + r = ((glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glLoadProgramNV")) == NULL) || r; + r = ((glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dNV")) == NULL) || r; + r = ((glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dvNV")) == NULL) || r; + r = ((glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fNV")) == NULL) || r; + r = ((glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fvNV")) == NULL) || r; + r = ((glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4dvNV")) == NULL) || r; + r = ((glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4fvNV")) == NULL) || r; + r = ((glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glRequestResidentProgramsNV")) == NULL) || r; + r = ((glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC)glewGetProcAddress((const GLubyte*)"glTrackMatrixNV")) == NULL) || r; + r = ((glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dNV")) == NULL) || r; + r = ((glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvNV")) == NULL) || r; + r = ((glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fNV")) == NULL) || r; + r = ((glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvNV")) == NULL) || r; + r = ((glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sNV")) == NULL) || r; + r = ((glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svNV")) == NULL) || r; + r = ((glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dNV")) == NULL) || r; + r = ((glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvNV")) == NULL) || r; + r = ((glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fNV")) == NULL) || r; + r = ((glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvNV")) == NULL) || r; + r = ((glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sNV")) == NULL) || r; + r = ((glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svNV")) == NULL) || r; + r = ((glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dNV")) == NULL) || r; + r = ((glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvNV")) == NULL) || r; + r = ((glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fNV")) == NULL) || r; + r = ((glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvNV")) == NULL) || r; + r = ((glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sNV")) == NULL) || r; + r = ((glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svNV")) == NULL) || r; + r = ((glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dNV")) == NULL) || r; + r = ((glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvNV")) == NULL) || r; + r = ((glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fNV")) == NULL) || r; + r = ((glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvNV")) == NULL) || r; + r = ((glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sNV")) == NULL) || r; + r = ((glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svNV")) == NULL) || r; + r = ((glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubNV")) == NULL) || r; + r = ((glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvNV")) == NULL) || r; + r = ((glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerNV")) == NULL) || r; + r = ((glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1dvNV")) == NULL) || r; + r = ((glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1fvNV")) == NULL) || r; + r = ((glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1svNV")) == NULL) || r; + r = ((glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2dvNV")) == NULL) || r; + r = ((glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2fvNV")) == NULL) || r; + r = ((glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2svNV")) == NULL) || r; + r = ((glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3dvNV")) == NULL) || r; + r = ((glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3fvNV")) == NULL) || r; + r = ((glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3svNV")) == NULL) || r; + r = ((glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4dvNV")) == NULL) || r; + r = ((glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4fvNV")) == NULL) || r; + r = ((glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4svNV")) == NULL) || r; + r = ((glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4ubvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_vertex_program */ + +#ifdef GL_NV_video_capture + +static GLboolean _glewInit_GL_NV_video_capture () +{ + GLboolean r = GL_FALSE; + + r = ((glBeginVideoCaptureNV = (PFNGLBEGINVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glBeginVideoCaptureNV")) == NULL) || r; + r = ((glBindVideoCaptureStreamBufferNV = (PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glBindVideoCaptureStreamBufferNV")) == NULL) || r; + r = ((glBindVideoCaptureStreamTextureNV = (PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC)glewGetProcAddress((const GLubyte*)"glBindVideoCaptureStreamTextureNV")) == NULL) || r; + r = ((glEndVideoCaptureNV = (PFNGLENDVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glEndVideoCaptureNV")) == NULL) || r; + r = ((glGetVideoCaptureStreamdvNV = (PFNGLGETVIDEOCAPTURESTREAMDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamdvNV")) == NULL) || r; + r = ((glGetVideoCaptureStreamfvNV = (PFNGLGETVIDEOCAPTURESTREAMFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamfvNV")) == NULL) || r; + r = ((glGetVideoCaptureStreamivNV = (PFNGLGETVIDEOCAPTURESTREAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamivNV")) == NULL) || r; + r = ((glGetVideoCaptureivNV = (PFNGLGETVIDEOCAPTUREIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureivNV")) == NULL) || r; + r = ((glVideoCaptureNV = (PFNGLVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureNV")) == NULL) || r; + r = ((glVideoCaptureStreamParameterdvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterdvNV")) == NULL) || r; + r = ((glVideoCaptureStreamParameterfvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterfvNV")) == NULL) || r; + r = ((glVideoCaptureStreamParameterivNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterivNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_video_capture */ + +#ifdef GL_NV_viewport_array + +static GLboolean _glewInit_GL_NV_viewport_array () +{ + GLboolean r = GL_FALSE; + + r = ((glDepthRangeArrayfvNV = (PFNGLDEPTHRANGEARRAYFVNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeArrayfvNV")) == NULL) || r; + r = ((glDepthRangeIndexedfNV = (PFNGLDEPTHRANGEINDEXEDFNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeIndexedfNV")) == NULL) || r; + r = ((glDisableiNV = (PFNGLDISABLEINVPROC)glewGetProcAddress((const GLubyte*)"glDisableiNV")) == NULL) || r; + r = ((glEnableiNV = (PFNGLENABLEINVPROC)glewGetProcAddress((const GLubyte*)"glEnableiNV")) == NULL) || r; + r = ((glGetFloati_vNV = (PFNGLGETFLOATI_VNVPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_vNV")) == NULL) || r; + r = ((glIsEnablediNV = (PFNGLISENABLEDINVPROC)glewGetProcAddress((const GLubyte*)"glIsEnablediNV")) == NULL) || r; + r = ((glScissorArrayvNV = (PFNGLSCISSORARRAYVNVPROC)glewGetProcAddress((const GLubyte*)"glScissorArrayvNV")) == NULL) || r; + r = ((glScissorIndexedNV = (PFNGLSCISSORINDEXEDNVPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexedNV")) == NULL) || r; + r = ((glScissorIndexedvNV = (PFNGLSCISSORINDEXEDVNVPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexedvNV")) == NULL) || r; + r = ((glViewportArrayvNV = (PFNGLVIEWPORTARRAYVNVPROC)glewGetProcAddress((const GLubyte*)"glViewportArrayvNV")) == NULL) || r; + r = ((glViewportIndexedfNV = (PFNGLVIEWPORTINDEXEDFNVPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedfNV")) == NULL) || r; + r = ((glViewportIndexedfvNV = (PFNGLVIEWPORTINDEXEDFVNVPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedfvNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_viewport_array */ + +#ifdef GL_NV_viewport_swizzle + +static GLboolean _glewInit_GL_NV_viewport_swizzle () +{ + GLboolean r = GL_FALSE; + + r = ((glViewportSwizzleNV = (PFNGLVIEWPORTSWIZZLENVPROC)glewGetProcAddress((const GLubyte*)"glViewportSwizzleNV")) == NULL) || r; + + return r; +} + +#endif /* GL_NV_viewport_swizzle */ + +#ifdef GL_OVR_multiview + +static GLboolean _glewInit_GL_OVR_multiview () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureMultiviewOVR")) == NULL) || r; + + return r; +} + +#endif /* GL_OVR_multiview */ + +#ifdef GL_OVR_multiview_multisampled_render_to_texture + +static GLboolean _glewInit_GL_OVR_multiview_multisampled_render_to_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferTextureMultisampleMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureMultisampleMultiviewOVR")) == NULL) || r; + + return r; +} + +#endif /* GL_OVR_multiview_multisampled_render_to_texture */ + +#ifdef GL_QCOM_alpha_test + +static GLboolean _glewInit_GL_QCOM_alpha_test () +{ + GLboolean r = GL_FALSE; + + r = ((glAlphaFuncQCOM = (PFNGLALPHAFUNCQCOMPROC)glewGetProcAddress((const GLubyte*)"glAlphaFuncQCOM")) == NULL) || r; + + return r; +} + +#endif /* GL_QCOM_alpha_test */ + +#ifdef GL_QCOM_driver_control + +static GLboolean _glewInit_GL_QCOM_driver_control () +{ + GLboolean r = GL_FALSE; + + r = ((glDisableDriverControlQCOM = (PFNGLDISABLEDRIVERCONTROLQCOMPROC)glewGetProcAddress((const GLubyte*)"glDisableDriverControlQCOM")) == NULL) || r; + r = ((glEnableDriverControlQCOM = (PFNGLENABLEDRIVERCONTROLQCOMPROC)glewGetProcAddress((const GLubyte*)"glEnableDriverControlQCOM")) == NULL) || r; + r = ((glGetDriverControlStringQCOM = (PFNGLGETDRIVERCONTROLSTRINGQCOMPROC)glewGetProcAddress((const GLubyte*)"glGetDriverControlStringQCOM")) == NULL) || r; + r = ((glGetDriverControlsQCOM = (PFNGLGETDRIVERCONTROLSQCOMPROC)glewGetProcAddress((const GLubyte*)"glGetDriverControlsQCOM")) == NULL) || r; + + return r; +} + +#endif /* GL_QCOM_driver_control */ + +#ifdef GL_QCOM_extended_get + +static GLboolean _glewInit_GL_QCOM_extended_get () +{ + GLboolean r = GL_FALSE; + + r = ((glExtGetBufferPointervQCOM = (PFNGLEXTGETBUFFERPOINTERVQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetBufferPointervQCOM")) == NULL) || r; + r = ((glExtGetBuffersQCOM = (PFNGLEXTGETBUFFERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetBuffersQCOM")) == NULL) || r; + r = ((glExtGetFramebuffersQCOM = (PFNGLEXTGETFRAMEBUFFERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetFramebuffersQCOM")) == NULL) || r; + r = ((glExtGetRenderbuffersQCOM = (PFNGLEXTGETRENDERBUFFERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetRenderbuffersQCOM")) == NULL) || r; + r = ((glExtGetTexLevelParameterivQCOM = (PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetTexLevelParameterivQCOM")) == NULL) || r; + r = ((glExtGetTexSubImageQCOM = (PFNGLEXTGETTEXSUBIMAGEQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetTexSubImageQCOM")) == NULL) || r; + r = ((glExtGetTexturesQCOM = (PFNGLEXTGETTEXTURESQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetTexturesQCOM")) == NULL) || r; + r = ((glExtTexObjectStateOverrideiQCOM = (PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtTexObjectStateOverrideiQCOM")) == NULL) || r; + + return r; +} + +#endif /* GL_QCOM_extended_get */ + +#ifdef GL_QCOM_extended_get2 + +static GLboolean _glewInit_GL_QCOM_extended_get2 () +{ + GLboolean r = GL_FALSE; + + r = ((glExtGetProgramBinarySourceQCOM = (PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetProgramBinarySourceQCOM")) == NULL) || r; + r = ((glExtGetProgramsQCOM = (PFNGLEXTGETPROGRAMSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetProgramsQCOM")) == NULL) || r; + r = ((glExtGetShadersQCOM = (PFNGLEXTGETSHADERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtGetShadersQCOM")) == NULL) || r; + r = ((glExtIsProgramBinaryQCOM = (PFNGLEXTISPROGRAMBINARYQCOMPROC)glewGetProcAddress((const GLubyte*)"glExtIsProgramBinaryQCOM")) == NULL) || r; + + return r; +} + +#endif /* GL_QCOM_extended_get2 */ + +#ifdef GL_QCOM_framebuffer_foveated + +static GLboolean _glewInit_GL_QCOM_framebuffer_foveated () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferFoveationConfigQCOM = (PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC)glewGetProcAddress((const GLubyte*)"glFramebufferFoveationConfigQCOM")) == NULL) || r; + r = ((glFramebufferFoveationParametersQCOM = (PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC)glewGetProcAddress((const GLubyte*)"glFramebufferFoveationParametersQCOM")) == NULL) || r; + + return r; +} + +#endif /* GL_QCOM_framebuffer_foveated */ + +#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent + +static GLboolean _glewInit_GL_QCOM_shader_framebuffer_fetch_noncoherent () +{ + GLboolean r = GL_FALSE; + + r = ((glFramebufferFetchBarrierQCOM = (PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC)glewGetProcAddress((const GLubyte*)"glFramebufferFetchBarrierQCOM")) == NULL) || r; + + return r; +} + +#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */ + +#ifdef GL_QCOM_tiled_rendering + +static GLboolean _glewInit_GL_QCOM_tiled_rendering () +{ + GLboolean r = GL_FALSE; + + r = ((glEndTilingQCOM = (PFNGLENDTILINGQCOMPROC)glewGetProcAddress((const GLubyte*)"glEndTilingQCOM")) == NULL) || r; + r = ((glStartTilingQCOM = (PFNGLSTARTTILINGQCOMPROC)glewGetProcAddress((const GLubyte*)"glStartTilingQCOM")) == NULL) || r; + + return r; +} + +#endif /* GL_QCOM_tiled_rendering */ + +#ifdef GL_REGAL_ES1_0_compatibility + +static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility () +{ + GLboolean r = GL_FALSE; + + r = ((glAlphaFuncx = (PFNGLALPHAFUNCXPROC)glewGetProcAddress((const GLubyte*)"glAlphaFuncx")) == NULL) || r; + r = ((glClearColorx = (PFNGLCLEARCOLORXPROC)glewGetProcAddress((const GLubyte*)"glClearColorx")) == NULL) || r; + r = ((glClearDepthx = (PFNGLCLEARDEPTHXPROC)glewGetProcAddress((const GLubyte*)"glClearDepthx")) == NULL) || r; + r = ((glColor4x = (PFNGLCOLOR4XPROC)glewGetProcAddress((const GLubyte*)"glColor4x")) == NULL) || r; + r = ((glDepthRangex = (PFNGLDEPTHRANGEXPROC)glewGetProcAddress((const GLubyte*)"glDepthRangex")) == NULL) || r; + r = ((glFogx = (PFNGLFOGXPROC)glewGetProcAddress((const GLubyte*)"glFogx")) == NULL) || r; + r = ((glFogxv = (PFNGLFOGXVPROC)glewGetProcAddress((const GLubyte*)"glFogxv")) == NULL) || r; + r = ((glFrustumf = (PFNGLFRUSTUMFPROC)glewGetProcAddress((const GLubyte*)"glFrustumf")) == NULL) || r; + r = ((glFrustumx = (PFNGLFRUSTUMXPROC)glewGetProcAddress((const GLubyte*)"glFrustumx")) == NULL) || r; + r = ((glLightModelx = (PFNGLLIGHTMODELXPROC)glewGetProcAddress((const GLubyte*)"glLightModelx")) == NULL) || r; + r = ((glLightModelxv = (PFNGLLIGHTMODELXVPROC)glewGetProcAddress((const GLubyte*)"glLightModelxv")) == NULL) || r; + r = ((glLightx = (PFNGLLIGHTXPROC)glewGetProcAddress((const GLubyte*)"glLightx")) == NULL) || r; + r = ((glLightxv = (PFNGLLIGHTXVPROC)glewGetProcAddress((const GLubyte*)"glLightxv")) == NULL) || r; + r = ((glLineWidthx = (PFNGLLINEWIDTHXPROC)glewGetProcAddress((const GLubyte*)"glLineWidthx")) == NULL) || r; + r = ((glLoadMatrixx = (PFNGLLOADMATRIXXPROC)glewGetProcAddress((const GLubyte*)"glLoadMatrixx")) == NULL) || r; + r = ((glMaterialx = (PFNGLMATERIALXPROC)glewGetProcAddress((const GLubyte*)"glMaterialx")) == NULL) || r; + r = ((glMaterialxv = (PFNGLMATERIALXVPROC)glewGetProcAddress((const GLubyte*)"glMaterialxv")) == NULL) || r; + r = ((glMultMatrixx = (PFNGLMULTMATRIXXPROC)glewGetProcAddress((const GLubyte*)"glMultMatrixx")) == NULL) || r; + r = ((glMultiTexCoord4x = (PFNGLMULTITEXCOORD4XPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4x")) == NULL) || r; + r = ((glNormal3x = (PFNGLNORMAL3XPROC)glewGetProcAddress((const GLubyte*)"glNormal3x")) == NULL) || r; + r = ((glOrthof = (PFNGLORTHOFPROC)glewGetProcAddress((const GLubyte*)"glOrthof")) == NULL) || r; + r = ((glOrthox = (PFNGLORTHOXPROC)glewGetProcAddress((const GLubyte*)"glOrthox")) == NULL) || r; + r = ((glPointSizex = (PFNGLPOINTSIZEXPROC)glewGetProcAddress((const GLubyte*)"glPointSizex")) == NULL) || r; + r = ((glPolygonOffsetx = (PFNGLPOLYGONOFFSETXPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetx")) == NULL) || r; + r = ((glRotatex = (PFNGLROTATEXPROC)glewGetProcAddress((const GLubyte*)"glRotatex")) == NULL) || r; + r = ((glSampleCoveragex = (PFNGLSAMPLECOVERAGEXPROC)glewGetProcAddress((const GLubyte*)"glSampleCoveragex")) == NULL) || r; + r = ((glScalex = (PFNGLSCALEXPROC)glewGetProcAddress((const GLubyte*)"glScalex")) == NULL) || r; + r = ((glTexEnvx = (PFNGLTEXENVXPROC)glewGetProcAddress((const GLubyte*)"glTexEnvx")) == NULL) || r; + r = ((glTexEnvxv = (PFNGLTEXENVXVPROC)glewGetProcAddress((const GLubyte*)"glTexEnvxv")) == NULL) || r; + r = ((glTexParameterx = (PFNGLTEXPARAMETERXPROC)glewGetProcAddress((const GLubyte*)"glTexParameterx")) == NULL) || r; + r = ((glTranslatex = (PFNGLTRANSLATEXPROC)glewGetProcAddress((const GLubyte*)"glTranslatex")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_ES1_0_compatibility */ + +#ifdef GL_REGAL_ES1_1_compatibility + +static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility () +{ + GLboolean r = GL_FALSE; + + r = ((glClipPlanef = (PFNGLCLIPPLANEFPROC)glewGetProcAddress((const GLubyte*)"glClipPlanef")) == NULL) || r; + r = ((glClipPlanex = (PFNGLCLIPPLANEXPROC)glewGetProcAddress((const GLubyte*)"glClipPlanex")) == NULL) || r; + r = ((glGetClipPlanef = (PFNGLGETCLIPPLANEFPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanef")) == NULL) || r; + r = ((glGetClipPlanex = (PFNGLGETCLIPPLANEXPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanex")) == NULL) || r; + r = ((glGetFixedv = (PFNGLGETFIXEDVPROC)glewGetProcAddress((const GLubyte*)"glGetFixedv")) == NULL) || r; + r = ((glGetLightxv = (PFNGLGETLIGHTXVPROC)glewGetProcAddress((const GLubyte*)"glGetLightxv")) == NULL) || r; + r = ((glGetMaterialxv = (PFNGLGETMATERIALXVPROC)glewGetProcAddress((const GLubyte*)"glGetMaterialxv")) == NULL) || r; + r = ((glGetTexEnvxv = (PFNGLGETTEXENVXVPROC)glewGetProcAddress((const GLubyte*)"glGetTexEnvxv")) == NULL) || r; + r = ((glGetTexParameterxv = (PFNGLGETTEXPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterxv")) == NULL) || r; + r = ((glPointParameterx = (PFNGLPOINTPARAMETERXPROC)glewGetProcAddress((const GLubyte*)"glPointParameterx")) == NULL) || r; + r = ((glPointParameterxv = (PFNGLPOINTPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterxv")) == NULL) || r; + r = ((glPointSizePointerOES = (PFNGLPOINTSIZEPOINTEROESPROC)glewGetProcAddress((const GLubyte*)"glPointSizePointerOES")) == NULL) || r; + r = ((glTexParameterxv = (PFNGLTEXPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterxv")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_ES1_1_compatibility */ + +#ifdef GL_REGAL_error_string + +static GLboolean _glewInit_GL_REGAL_error_string () +{ + GLboolean r = GL_FALSE; + + r = ((glErrorStringREGAL = (PFNGLERRORSTRINGREGALPROC)glewGetProcAddress((const GLubyte*)"glErrorStringREGAL")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_error_string */ + +#ifdef GL_REGAL_extension_query + +static GLboolean _glewInit_GL_REGAL_extension_query () +{ + GLboolean r = GL_FALSE; + + r = ((glGetExtensionREGAL = (PFNGLGETEXTENSIONREGALPROC)glewGetProcAddress((const GLubyte*)"glGetExtensionREGAL")) == NULL) || r; + r = ((glIsSupportedREGAL = (PFNGLISSUPPORTEDREGALPROC)glewGetProcAddress((const GLubyte*)"glIsSupportedREGAL")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_extension_query */ + +#ifdef GL_REGAL_log + +static GLboolean _glewInit_GL_REGAL_log () +{ + GLboolean r = GL_FALSE; + + r = ((glLogMessageCallbackREGAL = (PFNGLLOGMESSAGECALLBACKREGALPROC)glewGetProcAddress((const GLubyte*)"glLogMessageCallbackREGAL")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_log */ + +#ifdef GL_REGAL_proc_address + +static GLboolean _glewInit_GL_REGAL_proc_address () +{ + GLboolean r = GL_FALSE; + + r = ((glGetProcAddressREGAL = (PFNGLGETPROCADDRESSREGALPROC)glewGetProcAddress((const GLubyte*)"glGetProcAddressREGAL")) == NULL) || r; + + return r; +} + +#endif /* GL_REGAL_proc_address */ + +#ifdef GL_SGIS_detail_texture + +static GLboolean _glewInit_GL_SGIS_detail_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glDetailTexFuncSGIS = (PFNGLDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glDetailTexFuncSGIS")) == NULL) || r; + r = ((glGetDetailTexFuncSGIS = (PFNGLGETDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetDetailTexFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_detail_texture */ + +#ifdef GL_SGIS_fog_function + +static GLboolean _glewInit_GL_SGIS_fog_function () +{ + GLboolean r = GL_FALSE; + + r = ((glFogFuncSGIS = (PFNGLFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glFogFuncSGIS")) == NULL) || r; + r = ((glGetFogFuncSGIS = (PFNGLGETFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetFogFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_fog_function */ + +#ifdef GL_SGIS_multisample + +static GLboolean _glewInit_GL_SGIS_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskSGIS")) == NULL) || r; + r = ((glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_multisample */ + +#ifdef GL_SGIS_multitexture + +static GLboolean _glewInit_GL_SGIS_multitexture () +{ + GLboolean r = GL_FALSE; + + r = ((glInterleavedTextureCoordSetsSGIS = (PFNGLINTERLEAVEDTEXTURECOORDSETSSGISPROC)glewGetProcAddress((const GLubyte*)"glInterleavedTextureCoordSetsSGIS")) == NULL) || r; + r = ((glSelectTextureCoordSetSGIS = (PFNGLSELECTTEXTURECOORDSETSGISPROC)glewGetProcAddress((const GLubyte*)"glSelectTextureCoordSetSGIS")) == NULL) || r; + r = ((glSelectTextureSGIS = (PFNGLSELECTTEXTURESGISPROC)glewGetProcAddress((const GLubyte*)"glSelectTextureSGIS")) == NULL) || r; + r = ((glSelectTextureTransformSGIS = (PFNGLSELECTTEXTURETRANSFORMSGISPROC)glewGetProcAddress((const GLubyte*)"glSelectTextureTransformSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_multitexture */ + +#ifdef GL_SGIS_shared_multisample + +static GLboolean _glewInit_GL_SGIS_shared_multisample () +{ + GLboolean r = GL_FALSE; + + r = ((glMultisampleSubRectPosSGIS = (PFNGLMULTISAMPLESUBRECTPOSSGISPROC)glewGetProcAddress((const GLubyte*)"glMultisampleSubRectPosSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_shared_multisample */ + +#ifdef GL_SGIS_sharpen_texture + +static GLboolean _glewInit_GL_SGIS_sharpen_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glGetSharpenTexFuncSGIS = (PFNGLGETSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetSharpenTexFuncSGIS")) == NULL) || r; + r = ((glSharpenTexFuncSGIS = (PFNGLSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glSharpenTexFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_sharpen_texture */ + +#ifdef GL_SGIS_texture4D + +static GLboolean _glewInit_GL_SGIS_texture4D () +{ + GLboolean r = GL_FALSE; + + r = ((glTexImage4DSGIS = (PFNGLTEXIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexImage4DSGIS")) == NULL) || r; + r = ((glTexSubImage4DSGIS = (PFNGLTEXSUBIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage4DSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_texture4D */ + +#ifdef GL_SGIS_texture_filter4 + +static GLboolean _glewInit_GL_SGIS_texture_filter4 () +{ + GLboolean r = GL_FALSE; + + r = ((glGetTexFilterFuncSGIS = (PFNGLGETTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetTexFilterFuncSGIS")) == NULL) || r; + r = ((glTexFilterFuncSGIS = (PFNGLTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glTexFilterFuncSGIS")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIS_texture_filter4 */ + +#ifdef GL_SGIX_async + +static GLboolean _glewInit_GL_SGIX_async () +{ + GLboolean r = GL_FALSE; + + r = ((glAsyncMarkerSGIX = (PFNGLASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glAsyncMarkerSGIX")) == NULL) || r; + r = ((glDeleteAsyncMarkersSGIX = (PFNGLDELETEASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteAsyncMarkersSGIX")) == NULL) || r; + r = ((glFinishAsyncSGIX = (PFNGLFINISHASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glFinishAsyncSGIX")) == NULL) || r; + r = ((glGenAsyncMarkersSGIX = (PFNGLGENASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenAsyncMarkersSGIX")) == NULL) || r; + r = ((glIsAsyncMarkerSGIX = (PFNGLISASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsAsyncMarkerSGIX")) == NULL) || r; + r = ((glPollAsyncSGIX = (PFNGLPOLLASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glPollAsyncSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_async */ + +#ifdef GL_SGIX_datapipe + +static GLboolean _glewInit_GL_SGIX_datapipe () +{ + GLboolean r = GL_FALSE; + + r = ((glAddressSpace = (PFNGLADDRESSSPACEPROC)glewGetProcAddress((const GLubyte*)"glAddressSpace")) == NULL) || r; + r = ((glDataPipe = (PFNGLDATAPIPEPROC)glewGetProcAddress((const GLubyte*)"glDataPipe")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_datapipe */ + +#ifdef GL_SGIX_flush_raster + +static GLboolean _glewInit_GL_SGIX_flush_raster () +{ + GLboolean r = GL_FALSE; + + r = ((glFlushRasterSGIX = (PFNGLFLUSHRASTERSGIXPROC)glewGetProcAddress((const GLubyte*)"glFlushRasterSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_flush_raster */ + +#ifdef GL_SGIX_fog_layers + +static GLboolean _glewInit_GL_SGIX_fog_layers () +{ + GLboolean r = GL_FALSE; + + r = ((glFogLayersSGIX = (PFNGLFOGLAYERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glFogLayersSGIX")) == NULL) || r; + r = ((glGetFogLayersSGIX = (PFNGLGETFOGLAYERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFogLayersSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_fog_layers */ + +#ifdef GL_SGIX_fog_texture + +static GLboolean _glewInit_GL_SGIX_fog_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glTextureFogSGIX = (PFNGLTEXTUREFOGSGIXPROC)glewGetProcAddress((const GLubyte*)"glTextureFogSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_fog_texture */ + +#ifdef GL_SGIX_fragment_specular_lighting + +static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting () +{ + GLboolean r = GL_FALSE; + + r = ((glFragmentColorMaterialSGIX = (PFNGLFRAGMENTCOLORMATERIALSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialSGIX")) == NULL) || r; + r = ((glFragmentLightModelfSGIX = (PFNGLFRAGMENTLIGHTMODELFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfSGIX")) == NULL) || r; + r = ((glFragmentLightModelfvSGIX = (PFNGLFRAGMENTLIGHTMODELFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvSGIX")) == NULL) || r; + r = ((glFragmentLightModeliSGIX = (PFNGLFRAGMENTLIGHTMODELISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliSGIX")) == NULL) || r; + r = ((glFragmentLightModelivSGIX = (PFNGLFRAGMENTLIGHTMODELIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivSGIX")) == NULL) || r; + r = ((glFragmentLightfSGIX = (PFNGLFRAGMENTLIGHTFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfSGIX")) == NULL) || r; + r = ((glFragmentLightfvSGIX = (PFNGLFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvSGIX")) == NULL) || r; + r = ((glFragmentLightiSGIX = (PFNGLFRAGMENTLIGHTISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiSGIX")) == NULL) || r; + r = ((glFragmentLightivSGIX = (PFNGLFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivSGIX")) == NULL) || r; + r = ((glFragmentMaterialfSGIX = (PFNGLFRAGMENTMATERIALFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfSGIX")) == NULL) || r; + r = ((glFragmentMaterialfvSGIX = (PFNGLFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvSGIX")) == NULL) || r; + r = ((glFragmentMaterialiSGIX = (PFNGLFRAGMENTMATERIALISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiSGIX")) == NULL) || r; + r = ((glFragmentMaterialivSGIX = (PFNGLFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivSGIX")) == NULL) || r; + r = ((glGetFragmentLightfvSGIX = (PFNGLGETFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvSGIX")) == NULL) || r; + r = ((glGetFragmentLightivSGIX = (PFNGLGETFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivSGIX")) == NULL) || r; + r = ((glGetFragmentMaterialfvSGIX = (PFNGLGETFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvSGIX")) == NULL) || r; + r = ((glGetFragmentMaterialivSGIX = (PFNGLGETFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_fragment_specular_lighting */ + +#ifdef GL_SGIX_framezoom + +static GLboolean _glewInit_GL_SGIX_framezoom () +{ + GLboolean r = GL_FALSE; + + r = ((glFrameZoomSGIX = (PFNGLFRAMEZOOMSGIXPROC)glewGetProcAddress((const GLubyte*)"glFrameZoomSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_framezoom */ + +#ifdef GL_SGIX_igloo_interface + +static GLboolean _glewInit_GL_SGIX_igloo_interface () +{ + GLboolean r = GL_FALSE; + + r = ((glIglooInterfaceSGIX = (PFNGLIGLOOINTERFACESGIXPROC)glewGetProcAddress((const GLubyte*)"glIglooInterfaceSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_igloo_interface */ + +#ifdef GL_SGIX_mpeg1 + +static GLboolean _glewInit_GL_SGIX_mpeg1 () +{ + GLboolean r = GL_FALSE; + + r = ((glAllocMPEGPredictorsSGIX = (PFNGLALLOCMPEGPREDICTORSSGIXPROC)glewGetProcAddress((const GLubyte*)"glAllocMPEGPredictorsSGIX")) == NULL) || r; + r = ((glDeleteMPEGPredictorsSGIX = (PFNGLDELETEMPEGPREDICTORSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteMPEGPredictorsSGIX")) == NULL) || r; + r = ((glGenMPEGPredictorsSGIX = (PFNGLGENMPEGPREDICTORSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenMPEGPredictorsSGIX")) == NULL) || r; + r = ((glGetMPEGParameterfvSGIX = (PFNGLGETMPEGPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetMPEGParameterfvSGIX")) == NULL) || r; + r = ((glGetMPEGParameterivSGIX = (PFNGLGETMPEGPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetMPEGParameterivSGIX")) == NULL) || r; + r = ((glGetMPEGPredictorSGIX = (PFNGLGETMPEGPREDICTORSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetMPEGPredictorSGIX")) == NULL) || r; + r = ((glGetMPEGQuantTableubv = (PFNGLGETMPEGQUANTTABLEUBVPROC)glewGetProcAddress((const GLubyte*)"glGetMPEGQuantTableubv")) == NULL) || r; + r = ((glIsMPEGPredictorSGIX = (PFNGLISMPEGPREDICTORSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsMPEGPredictorSGIX")) == NULL) || r; + r = ((glMPEGPredictorSGIX = (PFNGLMPEGPREDICTORSGIXPROC)glewGetProcAddress((const GLubyte*)"glMPEGPredictorSGIX")) == NULL) || r; + r = ((glMPEGQuantTableubv = (PFNGLMPEGQUANTTABLEUBVPROC)glewGetProcAddress((const GLubyte*)"glMPEGQuantTableubv")) == NULL) || r; + r = ((glSwapMPEGPredictorsSGIX = (PFNGLSWAPMPEGPREDICTORSSGIXPROC)glewGetProcAddress((const GLubyte*)"glSwapMPEGPredictorsSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_mpeg1 */ + +#ifdef GL_SGIX_nonlinear_lighting_pervertex + +static GLboolean _glewInit_GL_SGIX_nonlinear_lighting_pervertex () +{ + GLboolean r = GL_FALSE; + + r = ((glGetNonlinLightfvSGIX = (PFNGLGETNONLINLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetNonlinLightfvSGIX")) == NULL) || r; + r = ((glGetNonlinMaterialfvSGIX = (PFNGLGETNONLINMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetNonlinMaterialfvSGIX")) == NULL) || r; + r = ((glNonlinLightfvSGIX = (PFNGLNONLINLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glNonlinLightfvSGIX")) == NULL) || r; + r = ((glNonlinMaterialfvSGIX = (PFNGLNONLINMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glNonlinMaterialfvSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_nonlinear_lighting_pervertex */ + +#ifdef GL_SGIX_pixel_texture + +static GLboolean _glewInit_GL_SGIX_pixel_texture () +{ + GLboolean r = GL_FALSE; + + r = ((glPixelTexGenSGIX = (PFNGLPIXELTEXGENSGIXPROC)glewGetProcAddress((const GLubyte*)"glPixelTexGenSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_pixel_texture */ + +#ifdef GL_SGIX_polynomial_ffd + +static GLboolean _glewInit_GL_SGIX_polynomial_ffd () +{ + GLboolean r = GL_FALSE; + + r = ((glDeformSGIX = (PFNGLDEFORMSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeformSGIX")) == NULL) || r; + r = ((glLoadIdentityDeformationMapSGIX = (PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC)glewGetProcAddress((const GLubyte*)"glLoadIdentityDeformationMapSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_polynomial_ffd */ + +#ifdef GL_SGIX_quad_mesh + +static GLboolean _glewInit_GL_SGIX_quad_mesh () +{ + GLboolean r = GL_FALSE; + + r = ((glMeshBreadthSGIX = (PFNGLMESHBREADTHSGIXPROC)glewGetProcAddress((const GLubyte*)"glMeshBreadthSGIX")) == NULL) || r; + r = ((glMeshStrideSGIX = (PFNGLMESHSTRIDESGIXPROC)glewGetProcAddress((const GLubyte*)"glMeshStrideSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_quad_mesh */ + +#ifdef GL_SGIX_reference_plane + +static GLboolean _glewInit_GL_SGIX_reference_plane () +{ + GLboolean r = GL_FALSE; + + r = ((glReferencePlaneSGIX = (PFNGLREFERENCEPLANESGIXPROC)glewGetProcAddress((const GLubyte*)"glReferencePlaneSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_reference_plane */ + +#ifdef GL_SGIX_sprite + +static GLboolean _glewInit_GL_SGIX_sprite () +{ + GLboolean r = GL_FALSE; + + r = ((glSpriteParameterfSGIX = (PFNGLSPRITEPARAMETERFSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfSGIX")) == NULL) || r; + r = ((glSpriteParameterfvSGIX = (PFNGLSPRITEPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfvSGIX")) == NULL) || r; + r = ((glSpriteParameteriSGIX = (PFNGLSPRITEPARAMETERISGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameteriSGIX")) == NULL) || r; + r = ((glSpriteParameterivSGIX = (PFNGLSPRITEPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterivSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_sprite */ + +#ifdef GL_SGIX_tag_sample_buffer + +static GLboolean _glewInit_GL_SGIX_tag_sample_buffer () +{ + GLboolean r = GL_FALSE; + + r = ((glTagSampleBufferSGIX = (PFNGLTAGSAMPLEBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glTagSampleBufferSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_tag_sample_buffer */ + +#ifdef GL_SGIX_vector_ops + +static GLboolean _glewInit_GL_SGIX_vector_ops () +{ + GLboolean r = GL_FALSE; + + r = ((glGetVectorOperationSGIX = (PFNGLGETVECTOROPERATIONSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetVectorOperationSGIX")) == NULL) || r; + r = ((glVectorOperationSGIX = (PFNGLVECTOROPERATIONSGIXPROC)glewGetProcAddress((const GLubyte*)"glVectorOperationSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_vector_ops */ + +#ifdef GL_SGIX_vertex_array_object + +static GLboolean _glewInit_GL_SGIX_vertex_array_object () +{ + GLboolean r = GL_FALSE; + + r = ((glAreVertexArraysResidentSGIX = (PFNGLAREVERTEXARRAYSRESIDENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glAreVertexArraysResidentSGIX")) == NULL) || r; + r = ((glBindVertexArraySGIX = (PFNGLBINDVERTEXARRAYSGIXPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArraySGIX")) == NULL) || r; + r = ((glDeleteVertexArraysSGIX = (PFNGLDELETEVERTEXARRAYSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysSGIX")) == NULL) || r; + r = ((glGenVertexArraysSGIX = (PFNGLGENVERTEXARRAYSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysSGIX")) == NULL) || r; + r = ((glIsVertexArraySGIX = (PFNGLISVERTEXARRAYSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArraySGIX")) == NULL) || r; + r = ((glPrioritizeVertexArraysSGIX = (PFNGLPRIORITIZEVERTEXARRAYSSGIXPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeVertexArraysSGIX")) == NULL) || r; + + return r; +} + +#endif /* GL_SGIX_vertex_array_object */ + +#ifdef GL_SGI_color_table + +static GLboolean _glewInit_GL_SGI_color_table () +{ + GLboolean r = GL_FALSE; + + r = ((glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfvSGI")) == NULL) || r; + r = ((glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterivSGI")) == NULL) || r; + r = ((glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableSGI")) == NULL) || r; + r = ((glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTableSGI")) == NULL) || r; + r = ((glGetColorTableParameterfvSGI = (PFNGLGETCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvSGI")) == NULL) || r; + r = ((glGetColorTableParameterivSGI = (PFNGLGETCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivSGI")) == NULL) || r; + r = ((glGetColorTableSGI = (PFNGLGETCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableSGI")) == NULL) || r; + + return r; +} + +#endif /* GL_SGI_color_table */ + +#ifdef GL_SGI_fft + +static GLboolean _glewInit_GL_SGI_fft () +{ + GLboolean r = GL_FALSE; + + r = ((glGetPixelTransformParameterfvSGI = (PFNGLGETPIXELTRANSFORMPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvSGI")) == NULL) || r; + r = ((glGetPixelTransformParameterivSGI = (PFNGLGETPIXELTRANSFORMPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivSGI")) == NULL) || r; + r = ((glPixelTransformParameterfSGI = (PFNGLPIXELTRANSFORMPARAMETERFSGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfSGI")) == NULL) || r; + r = ((glPixelTransformParameterfvSGI = (PFNGLPIXELTRANSFORMPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvSGI")) == NULL) || r; + r = ((glPixelTransformParameteriSGI = (PFNGLPIXELTRANSFORMPARAMETERISGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriSGI")) == NULL) || r; + r = ((glPixelTransformParameterivSGI = (PFNGLPIXELTRANSFORMPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivSGI")) == NULL) || r; + r = ((glPixelTransformSGI = (PFNGLPIXELTRANSFORMSGIPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformSGI")) == NULL) || r; + + return r; +} + +#endif /* GL_SGI_fft */ + +#ifdef GL_SUNX_constant_data + +static GLboolean _glewInit_GL_SUNX_constant_data () +{ + GLboolean r = GL_FALSE; + + r = ((glFinishTextureSUNX = (PFNGLFINISHTEXTURESUNXPROC)glewGetProcAddress((const GLubyte*)"glFinishTextureSUNX")) == NULL) || r; + + return r; +} + +#endif /* GL_SUNX_constant_data */ + +#ifdef GL_SUN_global_alpha + +static GLboolean _glewInit_GL_SUN_global_alpha () +{ + GLboolean r = GL_FALSE; + + r = ((glGlobalAlphaFactorbSUN = (PFNGLGLOBALALPHAFACTORBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorbSUN")) == NULL) || r; + r = ((glGlobalAlphaFactordSUN = (PFNGLGLOBALALPHAFACTORDSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactordSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorfSUN = (PFNGLGLOBALALPHAFACTORFSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorfSUN")) == NULL) || r; + r = ((glGlobalAlphaFactoriSUN = (PFNGLGLOBALALPHAFACTORISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoriSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorsSUN = (PFNGLGLOBALALPHAFACTORSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorsSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorubSUN = (PFNGLGLOBALALPHAFACTORUBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorubSUN")) == NULL) || r; + r = ((glGlobalAlphaFactoruiSUN = (PFNGLGLOBALALPHAFACTORUISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoruiSUN")) == NULL) || r; + r = ((glGlobalAlphaFactorusSUN = (PFNGLGLOBALALPHAFACTORUSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorusSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_global_alpha */ + +#ifdef GL_SUN_read_video_pixels + +static GLboolean _glewInit_GL_SUN_read_video_pixels () +{ + GLboolean r = GL_FALSE; + + r = ((glReadVideoPixelsSUN = (PFNGLREADVIDEOPIXELSSUNPROC)glewGetProcAddress((const GLubyte*)"glReadVideoPixelsSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_read_video_pixels */ + +#ifdef GL_SUN_triangle_list + +static GLboolean _glewInit_GL_SUN_triangle_list () +{ + GLboolean r = GL_FALSE; + + r = ((glReplacementCodePointerSUN = (PFNGLREPLACEMENTCODEPOINTERSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodePointerSUN")) == NULL) || r; + r = ((glReplacementCodeubSUN = (PFNGLREPLACEMENTCODEUBSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubSUN")) == NULL) || r; + r = ((glReplacementCodeubvSUN = (PFNGLREPLACEMENTCODEUBVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubvSUN")) == NULL) || r; + r = ((glReplacementCodeuiSUN = (PFNGLREPLACEMENTCODEUISUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiSUN")) == NULL) || r; + r = ((glReplacementCodeuivSUN = (PFNGLREPLACEMENTCODEUIVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuivSUN")) == NULL) || r; + r = ((glReplacementCodeusSUN = (PFNGLREPLACEMENTCODEUSSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusSUN")) == NULL) || r; + r = ((glReplacementCodeusvSUN = (PFNGLREPLACEMENTCODEUSVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusvSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_triangle_list */ + +#ifdef GL_SUN_vertex + +static GLboolean _glewInit_GL_SUN_vertex () +{ + GLboolean r = GL_FALSE; + + r = ((glColor3fVertex3fSUN = (PFNGLCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fSUN")) == NULL) || r; + r = ((glColor3fVertex3fvSUN = (PFNGLCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fvSUN")) == NULL) || r; + r = ((glColor4fNormal3fVertex3fSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glColor4fNormal3fVertex3fvSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glColor4ubVertex2fSUN = (PFNGLCOLOR4UBVERTEX2FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fSUN")) == NULL) || r; + r = ((glColor4ubVertex2fvSUN = (PFNGLCOLOR4UBVERTEX2FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fvSUN")) == NULL) || r; + r = ((glColor4ubVertex3fSUN = (PFNGLCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fSUN")) == NULL) || r; + r = ((glColor4ubVertex3fvSUN = (PFNGLCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glNormal3fVertex3fSUN = (PFNGLNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fSUN")) == NULL) || r; + r = ((glNormal3fVertex3fvSUN = (PFNGLNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4ubVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiColor4ubVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiTexCoord2fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fvSUN")) == NULL) || r; + r = ((glReplacementCodeuiVertex3fSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fSUN")) == NULL) || r; + r = ((glReplacementCodeuiVertex3fvSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fColor4ubVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fColor4ubVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord2fVertex3fSUN = (PFNGLTEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fSUN")) == NULL) || r; + r = ((glTexCoord2fVertex3fvSUN = (PFNGLTEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fvSUN")) == NULL) || r; + r = ((glTexCoord4fColor4fNormal3fVertex4fSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fSUN")) == NULL) || r; + r = ((glTexCoord4fColor4fNormal3fVertex4fvSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fvSUN")) == NULL) || r; + r = ((glTexCoord4fVertex4fSUN = (PFNGLTEXCOORD4FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fSUN")) == NULL) || r; + r = ((glTexCoord4fVertex4fvSUN = (PFNGLTEXCOORD4FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fvSUN")) == NULL) || r; + + return r; +} + +#endif /* GL_SUN_vertex */ + +#ifdef GL_WIN_swap_hint + +static GLboolean _glewInit_GL_WIN_swap_hint () +{ + GLboolean r = GL_FALSE; + + r = ((glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC)glewGetProcAddress((const GLubyte*)"glAddSwapHintRectWIN")) == NULL) || r; + + return r; +} + +#endif /* GL_WIN_swap_hint */ + +/* ------------------------------------------------------------------------- */ + +static int _glewExtensionCompare(const char *s1, const char *s2) +{ + /* http://www.chanduthedev.com/2012/07/strcmp-implementation-in-c.html */ + while (*s1 || *s2) + { + if (*s1 > *s2) + return 1; + if (*s1 < *s2) + return -1; + s1++; + s2++; + } + return 0; +} + +static ptrdiff_t _glewBsearchExtension(const char* name) +{ + ptrdiff_t lo = 0, hi = sizeof(_glewExtensionLookup) / sizeof(char*) - 2; + + while (lo <= hi) + { + ptrdiff_t mid = (lo + hi) / 2; + const int cmp = _glewExtensionCompare(name, _glewExtensionLookup[mid]); + if (cmp < 0) hi = mid - 1; + else if (cmp > 0) lo = mid + 1; + else return mid; + } + return -1; +} + +static GLboolean *_glewGetExtensionString(const char *name) +{ + ptrdiff_t n = _glewBsearchExtension(name); + if (n >= 0) return &_glewExtensionString[n]; + return NULL; +} + +static GLboolean *_glewGetExtensionEnable(const char *name) +{ + ptrdiff_t n = _glewBsearchExtension(name); + if (n >= 0) return _glewExtensionEnabled[n]; + return NULL; +} + +static const char *_glewNextSpace(const char *i) +{ + const char *j = i; + if (j) + while (*j!=' ' && *j) ++j; + return j; +} + +static const char *_glewNextNonSpace(const char *i) +{ + const char *j = i; + if (j) + while (*j==' ') ++j; + return j; +} + +GLboolean GLEWAPIENTRY glewGetExtension (const char* name) +{ + GLboolean *enable = _glewGetExtensionString(name); + if (enable) + return *enable; + return GL_FALSE; +} + +/* ------------------------------------------------------------------------- */ + +typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGPROC) (GLenum name); +typedef void (GLAPIENTRY * PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params); + +static GLenum GLEWAPIENTRY glewContextInit () +{ + PFNGLGETSTRINGPROC getString; + const GLubyte* s; + GLuint dot; + GLint major, minor; + size_t n; + + getString = (PFNGLGETSTRINGPROC) glewGetProcAddress((const GLubyte*)"glGetString"); + if (!getString) + return GLEW_ERROR_NO_GL_VERSION; + + /* query opengl version */ + s = getString(GL_VERSION); + dot = _glewStrCLen(s, '.'); + if (dot == 0) + return GLEW_ERROR_NO_GL_VERSION; + + major = s[dot-1]-'0'; + minor = s[dot+1]-'0'; + + if (minor < 0 || minor > 9) + minor = 0; + if (major<0 || major>9) + return GLEW_ERROR_NO_GL_VERSION; + + if (major == 1 && minor == 0) + { + return GLEW_ERROR_GL_VERSION_10_ONLY; + } + else + { + CONST_CAST(GLEW_VERSION_4_6) = ( major > 4 ) || ( major == 4 && minor >= 6 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_4_5) = GLEW_VERSION_4_4 == GL_TRUE || ( major == 4 && minor >= 5 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_4_4) = GLEW_VERSION_4_5 == GL_TRUE || ( major == 4 && minor >= 4 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_4_3) = GLEW_VERSION_4_4 == GL_TRUE || ( major == 4 && minor >= 3 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_4_2) = GLEW_VERSION_4_3 == GL_TRUE || ( major == 4 && minor >= 2 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_4_1) = GLEW_VERSION_4_2 == GL_TRUE || ( major == 4 && minor >= 1 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_4_0) = GLEW_VERSION_4_1 == GL_TRUE || ( major == 4 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_3_3) = GLEW_VERSION_4_0 == GL_TRUE || ( major == 3 && minor >= 3 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_3_2) = GLEW_VERSION_3_3 == GL_TRUE || ( major == 3 && minor >= 2 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_3_1) = GLEW_VERSION_3_2 == GL_TRUE || ( major == 3 && minor >= 1 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_3_0) = GLEW_VERSION_3_1 == GL_TRUE || ( major == 3 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_2_1) = GLEW_VERSION_3_0 == GL_TRUE || ( major == 2 && minor >= 1 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_2_0) = GLEW_VERSION_2_1 == GL_TRUE || ( major == 2 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_1_5) = GLEW_VERSION_2_0 == GL_TRUE || ( major == 1 && minor >= 5 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_1_4) = GLEW_VERSION_1_5 == GL_TRUE || ( major == 1 && minor >= 4 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_1_3) = GLEW_VERSION_1_4 == GL_TRUE || ( major == 1 && minor >= 3 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_1_2_1) = GLEW_VERSION_1_3 == GL_TRUE ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_1_2) = GLEW_VERSION_1_2_1 == GL_TRUE || ( major == 1 && minor >= 2 ) ? GL_TRUE : GL_FALSE; + CONST_CAST(GLEW_VERSION_1_1) = GLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE; + } + + for (n = 0; n < sizeof(_glewExtensionString) / sizeof(_glewExtensionString[0]); ++n) + _glewExtensionString[n] = GL_FALSE; + + if (GLEW_VERSION_3_0) + { + GLint n = 0; + GLint i; + PFNGLGETINTEGERVPROC getIntegerv; + PFNGLGETSTRINGIPROC getStringi; + const char *ext; + GLboolean *enable; + + getIntegerv = (PFNGLGETINTEGERVPROC) glewGetProcAddress((const GLubyte*)"glGetIntegerv"); + + if (getIntegerv) + getIntegerv(GL_NUM_EXTENSIONS, &n); + + /* glGetStringi is OpenGL 3.0 */ + getStringi = (PFNGLGETSTRINGIPROC) glewGetProcAddress((const GLubyte*)"glGetStringi"); + if (getStringi) + for (i = 0; i= (ptrdiff_t) sizeof(ext)) + continue; + _glewStrCopy(ext, i, ' '); + + /* Based on extension string(s), glewGetExtension purposes */ + enable = _glewGetExtensionString(ext); + if (enable) + *enable = GL_TRUE; + + /* Based on extension string(s), experimental mode, glewIsSupported purposes */ + enable = _glewGetExtensionEnable(ext); + if (enable) + *enable = GL_TRUE; + } + } + } + +#ifdef GL_VERSION_1_2 + if (glewExperimental || GLEW_VERSION_1_2) CONST_CAST(GLEW_VERSION_1_2) = !_glewInit_GL_VERSION_1_2(); +#endif /* GL_VERSION_1_2 */ +#ifdef GL_VERSION_1_3 + if (glewExperimental || GLEW_VERSION_1_3) CONST_CAST(GLEW_VERSION_1_3) = !_glewInit_GL_VERSION_1_3(); +#endif /* GL_VERSION_1_3 */ +#ifdef GL_VERSION_1_4 + if (glewExperimental || GLEW_VERSION_1_4) CONST_CAST(GLEW_VERSION_1_4) = !_glewInit_GL_VERSION_1_4(); +#endif /* GL_VERSION_1_4 */ +#ifdef GL_VERSION_1_5 + if (glewExperimental || GLEW_VERSION_1_5) CONST_CAST(GLEW_VERSION_1_5) = !_glewInit_GL_VERSION_1_5(); +#endif /* GL_VERSION_1_5 */ +#ifdef GL_VERSION_2_0 + if (glewExperimental || GLEW_VERSION_2_0) CONST_CAST(GLEW_VERSION_2_0) = !_glewInit_GL_VERSION_2_0(); +#endif /* GL_VERSION_2_0 */ +#ifdef GL_VERSION_2_1 + if (glewExperimental || GLEW_VERSION_2_1) CONST_CAST(GLEW_VERSION_2_1) = !_glewInit_GL_VERSION_2_1(); +#endif /* GL_VERSION_2_1 */ +#ifdef GL_VERSION_3_0 + if (glewExperimental || GLEW_VERSION_3_0) CONST_CAST(GLEW_VERSION_3_0) = !_glewInit_GL_VERSION_3_0(); +#endif /* GL_VERSION_3_0 */ +#ifdef GL_VERSION_3_1 + if (glewExperimental || GLEW_VERSION_3_1) CONST_CAST(GLEW_VERSION_3_1) = !_glewInit_GL_VERSION_3_1(); +#endif /* GL_VERSION_3_1 */ +#ifdef GL_VERSION_3_2 + if (glewExperimental || GLEW_VERSION_3_2) CONST_CAST(GLEW_VERSION_3_2) = !_glewInit_GL_VERSION_3_2(); +#endif /* GL_VERSION_3_2 */ +#ifdef GL_VERSION_3_3 + if (glewExperimental || GLEW_VERSION_3_3) CONST_CAST(GLEW_VERSION_3_3) = !_glewInit_GL_VERSION_3_3(); +#endif /* GL_VERSION_3_3 */ +#ifdef GL_VERSION_4_0 + if (glewExperimental || GLEW_VERSION_4_0) CONST_CAST(GLEW_VERSION_4_0) = !_glewInit_GL_VERSION_4_0(); +#endif /* GL_VERSION_4_0 */ +#ifdef GL_VERSION_4_5 + if (glewExperimental || GLEW_VERSION_4_5) CONST_CAST(GLEW_VERSION_4_5) = !_glewInit_GL_VERSION_4_5(); +#endif /* GL_VERSION_4_5 */ +#ifdef GL_VERSION_4_6 + if (glewExperimental || GLEW_VERSION_4_6) CONST_CAST(GLEW_VERSION_4_6) = !_glewInit_GL_VERSION_4_6(); +#endif /* GL_VERSION_4_6 */ +#ifdef GL_3DFX_tbuffer + if (glewExperimental || GLEW_3DFX_tbuffer) CONST_CAST(GLEW_3DFX_tbuffer) = !_glewInit_GL_3DFX_tbuffer(); +#endif /* GL_3DFX_tbuffer */ +#ifdef GL_AMD_debug_output + if (glewExperimental || GLEW_AMD_debug_output) CONST_CAST(GLEW_AMD_debug_output) = !_glewInit_GL_AMD_debug_output(); +#endif /* GL_AMD_debug_output */ +#ifdef GL_AMD_draw_buffers_blend + if (glewExperimental || GLEW_AMD_draw_buffers_blend) CONST_CAST(GLEW_AMD_draw_buffers_blend) = !_glewInit_GL_AMD_draw_buffers_blend(); +#endif /* GL_AMD_draw_buffers_blend */ +#ifdef GL_AMD_framebuffer_sample_positions + if (glewExperimental || GLEW_AMD_framebuffer_sample_positions) CONST_CAST(GLEW_AMD_framebuffer_sample_positions) = !_glewInit_GL_AMD_framebuffer_sample_positions(); +#endif /* GL_AMD_framebuffer_sample_positions */ +#ifdef GL_AMD_interleaved_elements + if (glewExperimental || GLEW_AMD_interleaved_elements) CONST_CAST(GLEW_AMD_interleaved_elements) = !_glewInit_GL_AMD_interleaved_elements(); +#endif /* GL_AMD_interleaved_elements */ +#ifdef GL_AMD_multi_draw_indirect + if (glewExperimental || GLEW_AMD_multi_draw_indirect) CONST_CAST(GLEW_AMD_multi_draw_indirect) = !_glewInit_GL_AMD_multi_draw_indirect(); +#endif /* GL_AMD_multi_draw_indirect */ +#ifdef GL_AMD_name_gen_delete + if (glewExperimental || GLEW_AMD_name_gen_delete) CONST_CAST(GLEW_AMD_name_gen_delete) = !_glewInit_GL_AMD_name_gen_delete(); +#endif /* GL_AMD_name_gen_delete */ +#ifdef GL_AMD_occlusion_query_event + if (glewExperimental || GLEW_AMD_occlusion_query_event) CONST_CAST(GLEW_AMD_occlusion_query_event) = !_glewInit_GL_AMD_occlusion_query_event(); +#endif /* GL_AMD_occlusion_query_event */ +#ifdef GL_AMD_performance_monitor + if (glewExperimental || GLEW_AMD_performance_monitor) CONST_CAST(GLEW_AMD_performance_monitor) = !_glewInit_GL_AMD_performance_monitor(); +#endif /* GL_AMD_performance_monitor */ +#ifdef GL_AMD_sample_positions + if (glewExperimental || GLEW_AMD_sample_positions) CONST_CAST(GLEW_AMD_sample_positions) = !_glewInit_GL_AMD_sample_positions(); +#endif /* GL_AMD_sample_positions */ +#ifdef GL_AMD_sparse_texture + if (glewExperimental || GLEW_AMD_sparse_texture) CONST_CAST(GLEW_AMD_sparse_texture) = !_glewInit_GL_AMD_sparse_texture(); +#endif /* GL_AMD_sparse_texture */ +#ifdef GL_AMD_stencil_operation_extended + if (glewExperimental || GLEW_AMD_stencil_operation_extended) CONST_CAST(GLEW_AMD_stencil_operation_extended) = !_glewInit_GL_AMD_stencil_operation_extended(); +#endif /* GL_AMD_stencil_operation_extended */ +#ifdef GL_AMD_vertex_shader_tessellator + if (glewExperimental || GLEW_AMD_vertex_shader_tessellator) CONST_CAST(GLEW_AMD_vertex_shader_tessellator) = !_glewInit_GL_AMD_vertex_shader_tessellator(); +#endif /* GL_AMD_vertex_shader_tessellator */ +#ifdef GL_ANGLE_framebuffer_blit + if (glewExperimental || GLEW_ANGLE_framebuffer_blit) CONST_CAST(GLEW_ANGLE_framebuffer_blit) = !_glewInit_GL_ANGLE_framebuffer_blit(); +#endif /* GL_ANGLE_framebuffer_blit */ +#ifdef GL_ANGLE_framebuffer_multisample + if (glewExperimental || GLEW_ANGLE_framebuffer_multisample) CONST_CAST(GLEW_ANGLE_framebuffer_multisample) = !_glewInit_GL_ANGLE_framebuffer_multisample(); +#endif /* GL_ANGLE_framebuffer_multisample */ +#ifdef GL_ANGLE_instanced_arrays + if (glewExperimental || GLEW_ANGLE_instanced_arrays) CONST_CAST(GLEW_ANGLE_instanced_arrays) = !_glewInit_GL_ANGLE_instanced_arrays(); +#endif /* GL_ANGLE_instanced_arrays */ +#ifdef GL_ANGLE_timer_query + if (glewExperimental || GLEW_ANGLE_timer_query) CONST_CAST(GLEW_ANGLE_timer_query) = !_glewInit_GL_ANGLE_timer_query(); +#endif /* GL_ANGLE_timer_query */ +#ifdef GL_ANGLE_translated_shader_source + if (glewExperimental || GLEW_ANGLE_translated_shader_source) CONST_CAST(GLEW_ANGLE_translated_shader_source) = !_glewInit_GL_ANGLE_translated_shader_source(); +#endif /* GL_ANGLE_translated_shader_source */ +#ifdef GL_APPLE_copy_texture_levels + if (glewExperimental || GLEW_APPLE_copy_texture_levels) CONST_CAST(GLEW_APPLE_copy_texture_levels) = !_glewInit_GL_APPLE_copy_texture_levels(); +#endif /* GL_APPLE_copy_texture_levels */ +#ifdef GL_APPLE_element_array + if (glewExperimental || GLEW_APPLE_element_array) CONST_CAST(GLEW_APPLE_element_array) = !_glewInit_GL_APPLE_element_array(); +#endif /* GL_APPLE_element_array */ +#ifdef GL_APPLE_fence + if (glewExperimental || GLEW_APPLE_fence) CONST_CAST(GLEW_APPLE_fence) = !_glewInit_GL_APPLE_fence(); +#endif /* GL_APPLE_fence */ +#ifdef GL_APPLE_flush_buffer_range + if (glewExperimental || GLEW_APPLE_flush_buffer_range) CONST_CAST(GLEW_APPLE_flush_buffer_range) = !_glewInit_GL_APPLE_flush_buffer_range(); +#endif /* GL_APPLE_flush_buffer_range */ +#ifdef GL_APPLE_framebuffer_multisample + if (glewExperimental || GLEW_APPLE_framebuffer_multisample) CONST_CAST(GLEW_APPLE_framebuffer_multisample) = !_glewInit_GL_APPLE_framebuffer_multisample(); +#endif /* GL_APPLE_framebuffer_multisample */ +#ifdef GL_APPLE_object_purgeable + if (glewExperimental || GLEW_APPLE_object_purgeable) CONST_CAST(GLEW_APPLE_object_purgeable) = !_glewInit_GL_APPLE_object_purgeable(); +#endif /* GL_APPLE_object_purgeable */ +#ifdef GL_APPLE_sync + if (glewExperimental || GLEW_APPLE_sync) CONST_CAST(GLEW_APPLE_sync) = !_glewInit_GL_APPLE_sync(); +#endif /* GL_APPLE_sync */ +#ifdef GL_APPLE_texture_range + if (glewExperimental || GLEW_APPLE_texture_range) CONST_CAST(GLEW_APPLE_texture_range) = !_glewInit_GL_APPLE_texture_range(); +#endif /* GL_APPLE_texture_range */ +#ifdef GL_APPLE_vertex_array_object + if (glewExperimental || GLEW_APPLE_vertex_array_object) CONST_CAST(GLEW_APPLE_vertex_array_object) = !_glewInit_GL_APPLE_vertex_array_object(); +#endif /* GL_APPLE_vertex_array_object */ +#ifdef GL_APPLE_vertex_array_range + if (glewExperimental || GLEW_APPLE_vertex_array_range) CONST_CAST(GLEW_APPLE_vertex_array_range) = !_glewInit_GL_APPLE_vertex_array_range(); +#endif /* GL_APPLE_vertex_array_range */ +#ifdef GL_APPLE_vertex_program_evaluators + if (glewExperimental || GLEW_APPLE_vertex_program_evaluators) CONST_CAST(GLEW_APPLE_vertex_program_evaluators) = !_glewInit_GL_APPLE_vertex_program_evaluators(); +#endif /* GL_APPLE_vertex_program_evaluators */ +#ifdef GL_ARB_ES2_compatibility + if (glewExperimental || GLEW_ARB_ES2_compatibility) CONST_CAST(GLEW_ARB_ES2_compatibility) = !_glewInit_GL_ARB_ES2_compatibility(); +#endif /* GL_ARB_ES2_compatibility */ +#ifdef GL_ARB_ES3_1_compatibility + if (glewExperimental || GLEW_ARB_ES3_1_compatibility) CONST_CAST(GLEW_ARB_ES3_1_compatibility) = !_glewInit_GL_ARB_ES3_1_compatibility(); +#endif /* GL_ARB_ES3_1_compatibility */ +#ifdef GL_ARB_ES3_2_compatibility + if (glewExperimental || GLEW_ARB_ES3_2_compatibility) CONST_CAST(GLEW_ARB_ES3_2_compatibility) = !_glewInit_GL_ARB_ES3_2_compatibility(); +#endif /* GL_ARB_ES3_2_compatibility */ +#ifdef GL_ARB_base_instance + if (glewExperimental || GLEW_ARB_base_instance) CONST_CAST(GLEW_ARB_base_instance) = !_glewInit_GL_ARB_base_instance(); +#endif /* GL_ARB_base_instance */ +#ifdef GL_ARB_bindless_texture + if (glewExperimental || GLEW_ARB_bindless_texture) CONST_CAST(GLEW_ARB_bindless_texture) = !_glewInit_GL_ARB_bindless_texture(); +#endif /* GL_ARB_bindless_texture */ +#ifdef GL_ARB_blend_func_extended + if (glewExperimental || GLEW_ARB_blend_func_extended) CONST_CAST(GLEW_ARB_blend_func_extended) = !_glewInit_GL_ARB_blend_func_extended(); +#endif /* GL_ARB_blend_func_extended */ +#ifdef GL_ARB_buffer_storage + if (glewExperimental || GLEW_ARB_buffer_storage) CONST_CAST(GLEW_ARB_buffer_storage) = !_glewInit_GL_ARB_buffer_storage(); +#endif /* GL_ARB_buffer_storage */ +#ifdef GL_ARB_cl_event + if (glewExperimental || GLEW_ARB_cl_event) CONST_CAST(GLEW_ARB_cl_event) = !_glewInit_GL_ARB_cl_event(); +#endif /* GL_ARB_cl_event */ +#ifdef GL_ARB_clear_buffer_object + if (glewExperimental || GLEW_ARB_clear_buffer_object) CONST_CAST(GLEW_ARB_clear_buffer_object) = !_glewInit_GL_ARB_clear_buffer_object(); +#endif /* GL_ARB_clear_buffer_object */ +#ifdef GL_ARB_clear_texture + if (glewExperimental || GLEW_ARB_clear_texture) CONST_CAST(GLEW_ARB_clear_texture) = !_glewInit_GL_ARB_clear_texture(); +#endif /* GL_ARB_clear_texture */ +#ifdef GL_ARB_clip_control + if (glewExperimental || GLEW_ARB_clip_control) CONST_CAST(GLEW_ARB_clip_control) = !_glewInit_GL_ARB_clip_control(); +#endif /* GL_ARB_clip_control */ +#ifdef GL_ARB_color_buffer_float + if (glewExperimental || GLEW_ARB_color_buffer_float) CONST_CAST(GLEW_ARB_color_buffer_float) = !_glewInit_GL_ARB_color_buffer_float(); +#endif /* GL_ARB_color_buffer_float */ +#ifdef GL_ARB_compute_shader + if (glewExperimental || GLEW_ARB_compute_shader) CONST_CAST(GLEW_ARB_compute_shader) = !_glewInit_GL_ARB_compute_shader(); +#endif /* GL_ARB_compute_shader */ +#ifdef GL_ARB_compute_variable_group_size + if (glewExperimental || GLEW_ARB_compute_variable_group_size) CONST_CAST(GLEW_ARB_compute_variable_group_size) = !_glewInit_GL_ARB_compute_variable_group_size(); +#endif /* GL_ARB_compute_variable_group_size */ +#ifdef GL_ARB_copy_buffer + if (glewExperimental || GLEW_ARB_copy_buffer) CONST_CAST(GLEW_ARB_copy_buffer) = !_glewInit_GL_ARB_copy_buffer(); +#endif /* GL_ARB_copy_buffer */ +#ifdef GL_ARB_copy_image + if (glewExperimental || GLEW_ARB_copy_image) CONST_CAST(GLEW_ARB_copy_image) = !_glewInit_GL_ARB_copy_image(); +#endif /* GL_ARB_copy_image */ +#ifdef GL_ARB_debug_output + if (glewExperimental || GLEW_ARB_debug_output) CONST_CAST(GLEW_ARB_debug_output) = !_glewInit_GL_ARB_debug_output(); +#endif /* GL_ARB_debug_output */ +#ifdef GL_ARB_direct_state_access + if (glewExperimental || GLEW_ARB_direct_state_access) CONST_CAST(GLEW_ARB_direct_state_access) = !_glewInit_GL_ARB_direct_state_access(); +#endif /* GL_ARB_direct_state_access */ +#ifdef GL_ARB_draw_buffers + if (glewExperimental || GLEW_ARB_draw_buffers) CONST_CAST(GLEW_ARB_draw_buffers) = !_glewInit_GL_ARB_draw_buffers(); +#endif /* GL_ARB_draw_buffers */ +#ifdef GL_ARB_draw_buffers_blend + if (glewExperimental || GLEW_ARB_draw_buffers_blend) CONST_CAST(GLEW_ARB_draw_buffers_blend) = !_glewInit_GL_ARB_draw_buffers_blend(); +#endif /* GL_ARB_draw_buffers_blend */ +#ifdef GL_ARB_draw_elements_base_vertex + if (glewExperimental || GLEW_ARB_draw_elements_base_vertex) CONST_CAST(GLEW_ARB_draw_elements_base_vertex) = !_glewInit_GL_ARB_draw_elements_base_vertex(); +#endif /* GL_ARB_draw_elements_base_vertex */ +#ifdef GL_ARB_draw_indirect + if (glewExperimental || GLEW_ARB_draw_indirect) CONST_CAST(GLEW_ARB_draw_indirect) = !_glewInit_GL_ARB_draw_indirect(); +#endif /* GL_ARB_draw_indirect */ +#ifdef GL_ARB_framebuffer_no_attachments + if (glewExperimental || GLEW_ARB_framebuffer_no_attachments) CONST_CAST(GLEW_ARB_framebuffer_no_attachments) = !_glewInit_GL_ARB_framebuffer_no_attachments(); +#endif /* GL_ARB_framebuffer_no_attachments */ +#ifdef GL_ARB_framebuffer_object + if (glewExperimental || GLEW_ARB_framebuffer_object) CONST_CAST(GLEW_ARB_framebuffer_object) = !_glewInit_GL_ARB_framebuffer_object(); +#endif /* GL_ARB_framebuffer_object */ +#ifdef GL_ARB_geometry_shader4 + if (glewExperimental || GLEW_ARB_geometry_shader4) CONST_CAST(GLEW_ARB_geometry_shader4) = !_glewInit_GL_ARB_geometry_shader4(); +#endif /* GL_ARB_geometry_shader4 */ +#ifdef GL_ARB_get_program_binary + if (glewExperimental || GLEW_ARB_get_program_binary) CONST_CAST(GLEW_ARB_get_program_binary) = !_glewInit_GL_ARB_get_program_binary(); +#endif /* GL_ARB_get_program_binary */ +#ifdef GL_ARB_get_texture_sub_image + if (glewExperimental || GLEW_ARB_get_texture_sub_image) CONST_CAST(GLEW_ARB_get_texture_sub_image) = !_glewInit_GL_ARB_get_texture_sub_image(); +#endif /* GL_ARB_get_texture_sub_image */ +#ifdef GL_ARB_gl_spirv + if (glewExperimental || GLEW_ARB_gl_spirv) CONST_CAST(GLEW_ARB_gl_spirv) = !_glewInit_GL_ARB_gl_spirv(); +#endif /* GL_ARB_gl_spirv */ +#ifdef GL_ARB_gpu_shader_fp64 + if (glewExperimental || GLEW_ARB_gpu_shader_fp64) CONST_CAST(GLEW_ARB_gpu_shader_fp64) = !_glewInit_GL_ARB_gpu_shader_fp64(); +#endif /* GL_ARB_gpu_shader_fp64 */ +#ifdef GL_ARB_gpu_shader_int64 + if (glewExperimental || GLEW_ARB_gpu_shader_int64) CONST_CAST(GLEW_ARB_gpu_shader_int64) = !_glewInit_GL_ARB_gpu_shader_int64(); +#endif /* GL_ARB_gpu_shader_int64 */ +#ifdef GL_ARB_imaging + if (glewExperimental || GLEW_ARB_imaging) CONST_CAST(GLEW_ARB_imaging) = !_glewInit_GL_ARB_imaging(); +#endif /* GL_ARB_imaging */ +#ifdef GL_ARB_indirect_parameters + if (glewExperimental || GLEW_ARB_indirect_parameters) CONST_CAST(GLEW_ARB_indirect_parameters) = !_glewInit_GL_ARB_indirect_parameters(); +#endif /* GL_ARB_indirect_parameters */ +#ifdef GL_ARB_instanced_arrays + if (glewExperimental || GLEW_ARB_instanced_arrays) CONST_CAST(GLEW_ARB_instanced_arrays) = !_glewInit_GL_ARB_instanced_arrays(); +#endif /* GL_ARB_instanced_arrays */ +#ifdef GL_ARB_internalformat_query + if (glewExperimental || GLEW_ARB_internalformat_query) CONST_CAST(GLEW_ARB_internalformat_query) = !_glewInit_GL_ARB_internalformat_query(); +#endif /* GL_ARB_internalformat_query */ +#ifdef GL_ARB_internalformat_query2 + if (glewExperimental || GLEW_ARB_internalformat_query2) CONST_CAST(GLEW_ARB_internalformat_query2) = !_glewInit_GL_ARB_internalformat_query2(); +#endif /* GL_ARB_internalformat_query2 */ +#ifdef GL_ARB_invalidate_subdata + if (glewExperimental || GLEW_ARB_invalidate_subdata) CONST_CAST(GLEW_ARB_invalidate_subdata) = !_glewInit_GL_ARB_invalidate_subdata(); +#endif /* GL_ARB_invalidate_subdata */ +#ifdef GL_ARB_map_buffer_range + if (glewExperimental || GLEW_ARB_map_buffer_range) CONST_CAST(GLEW_ARB_map_buffer_range) = !_glewInit_GL_ARB_map_buffer_range(); +#endif /* GL_ARB_map_buffer_range */ +#ifdef GL_ARB_matrix_palette + if (glewExperimental || GLEW_ARB_matrix_palette) CONST_CAST(GLEW_ARB_matrix_palette) = !_glewInit_GL_ARB_matrix_palette(); +#endif /* GL_ARB_matrix_palette */ +#ifdef GL_ARB_multi_bind + if (glewExperimental || GLEW_ARB_multi_bind) CONST_CAST(GLEW_ARB_multi_bind) = !_glewInit_GL_ARB_multi_bind(); +#endif /* GL_ARB_multi_bind */ +#ifdef GL_ARB_multi_draw_indirect + if (glewExperimental || GLEW_ARB_multi_draw_indirect) CONST_CAST(GLEW_ARB_multi_draw_indirect) = !_glewInit_GL_ARB_multi_draw_indirect(); +#endif /* GL_ARB_multi_draw_indirect */ +#ifdef GL_ARB_multisample + if (glewExperimental || GLEW_ARB_multisample) CONST_CAST(GLEW_ARB_multisample) = !_glewInit_GL_ARB_multisample(); +#endif /* GL_ARB_multisample */ +#ifdef GL_ARB_multitexture + if (glewExperimental || GLEW_ARB_multitexture) CONST_CAST(GLEW_ARB_multitexture) = !_glewInit_GL_ARB_multitexture(); +#endif /* GL_ARB_multitexture */ +#ifdef GL_ARB_occlusion_query + if (glewExperimental || GLEW_ARB_occlusion_query) CONST_CAST(GLEW_ARB_occlusion_query) = !_glewInit_GL_ARB_occlusion_query(); +#endif /* GL_ARB_occlusion_query */ +#ifdef GL_ARB_parallel_shader_compile + if (glewExperimental || GLEW_ARB_parallel_shader_compile) CONST_CAST(GLEW_ARB_parallel_shader_compile) = !_glewInit_GL_ARB_parallel_shader_compile(); +#endif /* GL_ARB_parallel_shader_compile */ +#ifdef GL_ARB_point_parameters + if (glewExperimental || GLEW_ARB_point_parameters) CONST_CAST(GLEW_ARB_point_parameters) = !_glewInit_GL_ARB_point_parameters(); +#endif /* GL_ARB_point_parameters */ +#ifdef GL_ARB_polygon_offset_clamp + if (glewExperimental || GLEW_ARB_polygon_offset_clamp) CONST_CAST(GLEW_ARB_polygon_offset_clamp) = !_glewInit_GL_ARB_polygon_offset_clamp(); +#endif /* GL_ARB_polygon_offset_clamp */ +#ifdef GL_ARB_program_interface_query + if (glewExperimental || GLEW_ARB_program_interface_query) CONST_CAST(GLEW_ARB_program_interface_query) = !_glewInit_GL_ARB_program_interface_query(); +#endif /* GL_ARB_program_interface_query */ +#ifdef GL_ARB_provoking_vertex + if (glewExperimental || GLEW_ARB_provoking_vertex) CONST_CAST(GLEW_ARB_provoking_vertex) = !_glewInit_GL_ARB_provoking_vertex(); +#endif /* GL_ARB_provoking_vertex */ +#ifdef GL_ARB_robustness + if (glewExperimental || GLEW_ARB_robustness) CONST_CAST(GLEW_ARB_robustness) = !_glewInit_GL_ARB_robustness(); +#endif /* GL_ARB_robustness */ +#ifdef GL_ARB_sample_locations + if (glewExperimental || GLEW_ARB_sample_locations) CONST_CAST(GLEW_ARB_sample_locations) = !_glewInit_GL_ARB_sample_locations(); +#endif /* GL_ARB_sample_locations */ +#ifdef GL_ARB_sample_shading + if (glewExperimental || GLEW_ARB_sample_shading) CONST_CAST(GLEW_ARB_sample_shading) = !_glewInit_GL_ARB_sample_shading(); +#endif /* GL_ARB_sample_shading */ +#ifdef GL_ARB_sampler_objects + if (glewExperimental || GLEW_ARB_sampler_objects) CONST_CAST(GLEW_ARB_sampler_objects) = !_glewInit_GL_ARB_sampler_objects(); +#endif /* GL_ARB_sampler_objects */ +#ifdef GL_ARB_separate_shader_objects + if (glewExperimental || GLEW_ARB_separate_shader_objects) CONST_CAST(GLEW_ARB_separate_shader_objects) = !_glewInit_GL_ARB_separate_shader_objects(); +#endif /* GL_ARB_separate_shader_objects */ +#ifdef GL_ARB_shader_atomic_counters + if (glewExperimental || GLEW_ARB_shader_atomic_counters) CONST_CAST(GLEW_ARB_shader_atomic_counters) = !_glewInit_GL_ARB_shader_atomic_counters(); +#endif /* GL_ARB_shader_atomic_counters */ +#ifdef GL_ARB_shader_image_load_store + if (glewExperimental || GLEW_ARB_shader_image_load_store) CONST_CAST(GLEW_ARB_shader_image_load_store) = !_glewInit_GL_ARB_shader_image_load_store(); +#endif /* GL_ARB_shader_image_load_store */ +#ifdef GL_ARB_shader_objects + if (glewExperimental || GLEW_ARB_shader_objects) CONST_CAST(GLEW_ARB_shader_objects) = !_glewInit_GL_ARB_shader_objects(); +#endif /* GL_ARB_shader_objects */ +#ifdef GL_ARB_shader_storage_buffer_object + if (glewExperimental || GLEW_ARB_shader_storage_buffer_object) CONST_CAST(GLEW_ARB_shader_storage_buffer_object) = !_glewInit_GL_ARB_shader_storage_buffer_object(); +#endif /* GL_ARB_shader_storage_buffer_object */ +#ifdef GL_ARB_shader_subroutine + if (glewExperimental || GLEW_ARB_shader_subroutine) CONST_CAST(GLEW_ARB_shader_subroutine) = !_glewInit_GL_ARB_shader_subroutine(); +#endif /* GL_ARB_shader_subroutine */ +#ifdef GL_ARB_shading_language_include + if (glewExperimental || GLEW_ARB_shading_language_include) CONST_CAST(GLEW_ARB_shading_language_include) = !_glewInit_GL_ARB_shading_language_include(); +#endif /* GL_ARB_shading_language_include */ +#ifdef GL_ARB_sparse_buffer + if (glewExperimental || GLEW_ARB_sparse_buffer) CONST_CAST(GLEW_ARB_sparse_buffer) = !_glewInit_GL_ARB_sparse_buffer(); +#endif /* GL_ARB_sparse_buffer */ +#ifdef GL_ARB_sparse_texture + if (glewExperimental || GLEW_ARB_sparse_texture) CONST_CAST(GLEW_ARB_sparse_texture) = !_glewInit_GL_ARB_sparse_texture(); +#endif /* GL_ARB_sparse_texture */ +#ifdef GL_ARB_sync + if (glewExperimental || GLEW_ARB_sync) CONST_CAST(GLEW_ARB_sync) = !_glewInit_GL_ARB_sync(); +#endif /* GL_ARB_sync */ +#ifdef GL_ARB_tessellation_shader + if (glewExperimental || GLEW_ARB_tessellation_shader) CONST_CAST(GLEW_ARB_tessellation_shader) = !_glewInit_GL_ARB_tessellation_shader(); +#endif /* GL_ARB_tessellation_shader */ +#ifdef GL_ARB_texture_barrier + if (glewExperimental || GLEW_ARB_texture_barrier) CONST_CAST(GLEW_ARB_texture_barrier) = !_glewInit_GL_ARB_texture_barrier(); +#endif /* GL_ARB_texture_barrier */ +#ifdef GL_ARB_texture_buffer_object + if (glewExperimental || GLEW_ARB_texture_buffer_object) CONST_CAST(GLEW_ARB_texture_buffer_object) = !_glewInit_GL_ARB_texture_buffer_object(); +#endif /* GL_ARB_texture_buffer_object */ +#ifdef GL_ARB_texture_buffer_range + if (glewExperimental || GLEW_ARB_texture_buffer_range) CONST_CAST(GLEW_ARB_texture_buffer_range) = !_glewInit_GL_ARB_texture_buffer_range(); +#endif /* GL_ARB_texture_buffer_range */ +#ifdef GL_ARB_texture_compression + if (glewExperimental || GLEW_ARB_texture_compression) CONST_CAST(GLEW_ARB_texture_compression) = !_glewInit_GL_ARB_texture_compression(); +#endif /* GL_ARB_texture_compression */ +#ifdef GL_ARB_texture_multisample + if (glewExperimental || GLEW_ARB_texture_multisample) CONST_CAST(GLEW_ARB_texture_multisample) = !_glewInit_GL_ARB_texture_multisample(); +#endif /* GL_ARB_texture_multisample */ +#ifdef GL_ARB_texture_storage + if (glewExperimental || GLEW_ARB_texture_storage) CONST_CAST(GLEW_ARB_texture_storage) = !_glewInit_GL_ARB_texture_storage(); +#endif /* GL_ARB_texture_storage */ +#ifdef GL_ARB_texture_storage_multisample + if (glewExperimental || GLEW_ARB_texture_storage_multisample) CONST_CAST(GLEW_ARB_texture_storage_multisample) = !_glewInit_GL_ARB_texture_storage_multisample(); +#endif /* GL_ARB_texture_storage_multisample */ +#ifdef GL_ARB_texture_view + if (glewExperimental || GLEW_ARB_texture_view) CONST_CAST(GLEW_ARB_texture_view) = !_glewInit_GL_ARB_texture_view(); +#endif /* GL_ARB_texture_view */ +#ifdef GL_ARB_timer_query + if (glewExperimental || GLEW_ARB_timer_query) CONST_CAST(GLEW_ARB_timer_query) = !_glewInit_GL_ARB_timer_query(); +#endif /* GL_ARB_timer_query */ +#ifdef GL_ARB_transform_feedback2 + if (glewExperimental || GLEW_ARB_transform_feedback2) CONST_CAST(GLEW_ARB_transform_feedback2) = !_glewInit_GL_ARB_transform_feedback2(); +#endif /* GL_ARB_transform_feedback2 */ +#ifdef GL_ARB_transform_feedback3 + if (glewExperimental || GLEW_ARB_transform_feedback3) CONST_CAST(GLEW_ARB_transform_feedback3) = !_glewInit_GL_ARB_transform_feedback3(); +#endif /* GL_ARB_transform_feedback3 */ +#ifdef GL_ARB_transform_feedback_instanced + if (glewExperimental || GLEW_ARB_transform_feedback_instanced) CONST_CAST(GLEW_ARB_transform_feedback_instanced) = !_glewInit_GL_ARB_transform_feedback_instanced(); +#endif /* GL_ARB_transform_feedback_instanced */ +#ifdef GL_ARB_transpose_matrix + if (glewExperimental || GLEW_ARB_transpose_matrix) CONST_CAST(GLEW_ARB_transpose_matrix) = !_glewInit_GL_ARB_transpose_matrix(); +#endif /* GL_ARB_transpose_matrix */ +#ifdef GL_ARB_uniform_buffer_object + if (glewExperimental || GLEW_ARB_uniform_buffer_object) CONST_CAST(GLEW_ARB_uniform_buffer_object) = !_glewInit_GL_ARB_uniform_buffer_object(); +#endif /* GL_ARB_uniform_buffer_object */ +#ifdef GL_ARB_vertex_array_object + if (glewExperimental || GLEW_ARB_vertex_array_object) CONST_CAST(GLEW_ARB_vertex_array_object) = !_glewInit_GL_ARB_vertex_array_object(); +#endif /* GL_ARB_vertex_array_object */ +#ifdef GL_ARB_vertex_attrib_64bit + if (glewExperimental || GLEW_ARB_vertex_attrib_64bit) CONST_CAST(GLEW_ARB_vertex_attrib_64bit) = !_glewInit_GL_ARB_vertex_attrib_64bit(); +#endif /* GL_ARB_vertex_attrib_64bit */ +#ifdef GL_ARB_vertex_attrib_binding + if (glewExperimental || GLEW_ARB_vertex_attrib_binding) CONST_CAST(GLEW_ARB_vertex_attrib_binding) = !_glewInit_GL_ARB_vertex_attrib_binding(); +#endif /* GL_ARB_vertex_attrib_binding */ +#ifdef GL_ARB_vertex_blend + if (glewExperimental || GLEW_ARB_vertex_blend) CONST_CAST(GLEW_ARB_vertex_blend) = !_glewInit_GL_ARB_vertex_blend(); +#endif /* GL_ARB_vertex_blend */ +#ifdef GL_ARB_vertex_buffer_object + if (glewExperimental || GLEW_ARB_vertex_buffer_object) CONST_CAST(GLEW_ARB_vertex_buffer_object) = !_glewInit_GL_ARB_vertex_buffer_object(); +#endif /* GL_ARB_vertex_buffer_object */ +#ifdef GL_ARB_vertex_program + if (glewExperimental || GLEW_ARB_vertex_program) CONST_CAST(GLEW_ARB_vertex_program) = !_glewInit_GL_ARB_vertex_program(); +#endif /* GL_ARB_vertex_program */ +#ifdef GL_ARB_vertex_shader + if (glewExperimental || GLEW_ARB_vertex_shader) { CONST_CAST(GLEW_ARB_vertex_shader) = !_glewInit_GL_ARB_vertex_shader(); _glewInit_GL_ARB_vertex_program(); } +#endif /* GL_ARB_vertex_shader */ +#ifdef GL_ARB_vertex_type_2_10_10_10_rev + if (glewExperimental || GLEW_ARB_vertex_type_2_10_10_10_rev) CONST_CAST(GLEW_ARB_vertex_type_2_10_10_10_rev) = !_glewInit_GL_ARB_vertex_type_2_10_10_10_rev(); +#endif /* GL_ARB_vertex_type_2_10_10_10_rev */ +#ifdef GL_ARB_viewport_array + if (glewExperimental || GLEW_ARB_viewport_array) CONST_CAST(GLEW_ARB_viewport_array) = !_glewInit_GL_ARB_viewport_array(); +#endif /* GL_ARB_viewport_array */ +#ifdef GL_ARB_window_pos + if (glewExperimental || GLEW_ARB_window_pos) CONST_CAST(GLEW_ARB_window_pos) = !_glewInit_GL_ARB_window_pos(); +#endif /* GL_ARB_window_pos */ +#ifdef GL_ATI_draw_buffers + if (glewExperimental || GLEW_ATI_draw_buffers) CONST_CAST(GLEW_ATI_draw_buffers) = !_glewInit_GL_ATI_draw_buffers(); +#endif /* GL_ATI_draw_buffers */ +#ifdef GL_ATI_element_array + if (glewExperimental || GLEW_ATI_element_array) CONST_CAST(GLEW_ATI_element_array) = !_glewInit_GL_ATI_element_array(); +#endif /* GL_ATI_element_array */ +#ifdef GL_ATI_envmap_bumpmap + if (glewExperimental || GLEW_ATI_envmap_bumpmap) CONST_CAST(GLEW_ATI_envmap_bumpmap) = !_glewInit_GL_ATI_envmap_bumpmap(); +#endif /* GL_ATI_envmap_bumpmap */ +#ifdef GL_ATI_fragment_shader + if (glewExperimental || GLEW_ATI_fragment_shader) CONST_CAST(GLEW_ATI_fragment_shader) = !_glewInit_GL_ATI_fragment_shader(); +#endif /* GL_ATI_fragment_shader */ +#ifdef GL_ATI_map_object_buffer + if (glewExperimental || GLEW_ATI_map_object_buffer) CONST_CAST(GLEW_ATI_map_object_buffer) = !_glewInit_GL_ATI_map_object_buffer(); +#endif /* GL_ATI_map_object_buffer */ +#ifdef GL_ATI_pn_triangles + if (glewExperimental || GLEW_ATI_pn_triangles) CONST_CAST(GLEW_ATI_pn_triangles) = !_glewInit_GL_ATI_pn_triangles(); +#endif /* GL_ATI_pn_triangles */ +#ifdef GL_ATI_separate_stencil + if (glewExperimental || GLEW_ATI_separate_stencil) CONST_CAST(GLEW_ATI_separate_stencil) = !_glewInit_GL_ATI_separate_stencil(); +#endif /* GL_ATI_separate_stencil */ +#ifdef GL_ATI_vertex_array_object + if (glewExperimental || GLEW_ATI_vertex_array_object) CONST_CAST(GLEW_ATI_vertex_array_object) = !_glewInit_GL_ATI_vertex_array_object(); +#endif /* GL_ATI_vertex_array_object */ +#ifdef GL_ATI_vertex_attrib_array_object + if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = !_glewInit_GL_ATI_vertex_attrib_array_object(); +#endif /* GL_ATI_vertex_attrib_array_object */ +#ifdef GL_ATI_vertex_streams + if (glewExperimental || GLEW_ATI_vertex_streams) CONST_CAST(GLEW_ATI_vertex_streams) = !_glewInit_GL_ATI_vertex_streams(); +#endif /* GL_ATI_vertex_streams */ +#ifdef GL_EXT_base_instance + if (glewExperimental || GLEW_EXT_base_instance) CONST_CAST(GLEW_EXT_base_instance) = !_glewInit_GL_EXT_base_instance(); +#endif /* GL_EXT_base_instance */ +#ifdef GL_EXT_bindable_uniform + if (glewExperimental || GLEW_EXT_bindable_uniform) CONST_CAST(GLEW_EXT_bindable_uniform) = !_glewInit_GL_EXT_bindable_uniform(); +#endif /* GL_EXT_bindable_uniform */ +#ifdef GL_EXT_blend_color + if (glewExperimental || GLEW_EXT_blend_color) CONST_CAST(GLEW_EXT_blend_color) = !_glewInit_GL_EXT_blend_color(); +#endif /* GL_EXT_blend_color */ +#ifdef GL_EXT_blend_equation_separate + if (glewExperimental || GLEW_EXT_blend_equation_separate) CONST_CAST(GLEW_EXT_blend_equation_separate) = !_glewInit_GL_EXT_blend_equation_separate(); +#endif /* GL_EXT_blend_equation_separate */ +#ifdef GL_EXT_blend_func_extended + if (glewExperimental || GLEW_EXT_blend_func_extended) CONST_CAST(GLEW_EXT_blend_func_extended) = !_glewInit_GL_EXT_blend_func_extended(); +#endif /* GL_EXT_blend_func_extended */ +#ifdef GL_EXT_blend_func_separate + if (glewExperimental || GLEW_EXT_blend_func_separate) CONST_CAST(GLEW_EXT_blend_func_separate) = !_glewInit_GL_EXT_blend_func_separate(); +#endif /* GL_EXT_blend_func_separate */ +#ifdef GL_EXT_blend_minmax + if (glewExperimental || GLEW_EXT_blend_minmax) CONST_CAST(GLEW_EXT_blend_minmax) = !_glewInit_GL_EXT_blend_minmax(); +#endif /* GL_EXT_blend_minmax */ +#ifdef GL_EXT_buffer_storage + if (glewExperimental || GLEW_EXT_buffer_storage) CONST_CAST(GLEW_EXT_buffer_storage) = !_glewInit_GL_EXT_buffer_storage(); +#endif /* GL_EXT_buffer_storage */ +#ifdef GL_EXT_clear_texture + if (glewExperimental || GLEW_EXT_clear_texture) CONST_CAST(GLEW_EXT_clear_texture) = !_glewInit_GL_EXT_clear_texture(); +#endif /* GL_EXT_clear_texture */ +#ifdef GL_EXT_color_subtable + if (glewExperimental || GLEW_EXT_color_subtable) CONST_CAST(GLEW_EXT_color_subtable) = !_glewInit_GL_EXT_color_subtable(); +#endif /* GL_EXT_color_subtable */ +#ifdef GL_EXT_compiled_vertex_array + if (glewExperimental || GLEW_EXT_compiled_vertex_array) CONST_CAST(GLEW_EXT_compiled_vertex_array) = !_glewInit_GL_EXT_compiled_vertex_array(); +#endif /* GL_EXT_compiled_vertex_array */ +#ifdef GL_EXT_convolution + if (glewExperimental || GLEW_EXT_convolution) CONST_CAST(GLEW_EXT_convolution) = !_glewInit_GL_EXT_convolution(); +#endif /* GL_EXT_convolution */ +#ifdef GL_EXT_coordinate_frame + if (glewExperimental || GLEW_EXT_coordinate_frame) CONST_CAST(GLEW_EXT_coordinate_frame) = !_glewInit_GL_EXT_coordinate_frame(); +#endif /* GL_EXT_coordinate_frame */ +#ifdef GL_EXT_copy_image + if (glewExperimental || GLEW_EXT_copy_image) CONST_CAST(GLEW_EXT_copy_image) = !_glewInit_GL_EXT_copy_image(); +#endif /* GL_EXT_copy_image */ +#ifdef GL_EXT_copy_texture + if (glewExperimental || GLEW_EXT_copy_texture) CONST_CAST(GLEW_EXT_copy_texture) = !_glewInit_GL_EXT_copy_texture(); +#endif /* GL_EXT_copy_texture */ +#ifdef GL_EXT_cull_vertex + if (glewExperimental || GLEW_EXT_cull_vertex) CONST_CAST(GLEW_EXT_cull_vertex) = !_glewInit_GL_EXT_cull_vertex(); +#endif /* GL_EXT_cull_vertex */ +#ifdef GL_EXT_debug_label + if (glewExperimental || GLEW_EXT_debug_label) CONST_CAST(GLEW_EXT_debug_label) = !_glewInit_GL_EXT_debug_label(); +#endif /* GL_EXT_debug_label */ +#ifdef GL_EXT_debug_marker + if (glewExperimental || GLEW_EXT_debug_marker) CONST_CAST(GLEW_EXT_debug_marker) = !_glewInit_GL_EXT_debug_marker(); +#endif /* GL_EXT_debug_marker */ +#ifdef GL_EXT_depth_bounds_test + if (glewExperimental || GLEW_EXT_depth_bounds_test) CONST_CAST(GLEW_EXT_depth_bounds_test) = !_glewInit_GL_EXT_depth_bounds_test(); +#endif /* GL_EXT_depth_bounds_test */ +#ifdef GL_EXT_direct_state_access + if (glewExperimental || GLEW_EXT_direct_state_access) CONST_CAST(GLEW_EXT_direct_state_access) = !_glewInit_GL_EXT_direct_state_access(); +#endif /* GL_EXT_direct_state_access */ +#ifdef GL_EXT_discard_framebuffer + if (glewExperimental || GLEW_EXT_discard_framebuffer) CONST_CAST(GLEW_EXT_discard_framebuffer) = !_glewInit_GL_EXT_discard_framebuffer(); +#endif /* GL_EXT_discard_framebuffer */ +#ifdef GL_EXT_draw_buffers + if (glewExperimental || GLEW_EXT_draw_buffers) CONST_CAST(GLEW_EXT_draw_buffers) = !_glewInit_GL_EXT_draw_buffers(); +#endif /* GL_EXT_draw_buffers */ +#ifdef GL_EXT_draw_buffers2 + if (glewExperimental || GLEW_EXT_draw_buffers2) CONST_CAST(GLEW_EXT_draw_buffers2) = !_glewInit_GL_EXT_draw_buffers2(); +#endif /* GL_EXT_draw_buffers2 */ +#ifdef GL_EXT_draw_buffers_indexed + if (glewExperimental || GLEW_EXT_draw_buffers_indexed) CONST_CAST(GLEW_EXT_draw_buffers_indexed) = !_glewInit_GL_EXT_draw_buffers_indexed(); +#endif /* GL_EXT_draw_buffers_indexed */ +#ifdef GL_EXT_draw_elements_base_vertex + if (glewExperimental || GLEW_EXT_draw_elements_base_vertex) CONST_CAST(GLEW_EXT_draw_elements_base_vertex) = !_glewInit_GL_EXT_draw_elements_base_vertex(); +#endif /* GL_EXT_draw_elements_base_vertex */ +#ifdef GL_EXT_draw_instanced + if (glewExperimental || GLEW_EXT_draw_instanced) CONST_CAST(GLEW_EXT_draw_instanced) = !_glewInit_GL_EXT_draw_instanced(); +#endif /* GL_EXT_draw_instanced */ +#ifdef GL_EXT_draw_range_elements + if (glewExperimental || GLEW_EXT_draw_range_elements) CONST_CAST(GLEW_EXT_draw_range_elements) = !_glewInit_GL_EXT_draw_range_elements(); +#endif /* GL_EXT_draw_range_elements */ +#ifdef GL_EXT_external_buffer + if (glewExperimental || GLEW_EXT_external_buffer) CONST_CAST(GLEW_EXT_external_buffer) = !_glewInit_GL_EXT_external_buffer(); +#endif /* GL_EXT_external_buffer */ +#ifdef GL_EXT_fog_coord + if (glewExperimental || GLEW_EXT_fog_coord) CONST_CAST(GLEW_EXT_fog_coord) = !_glewInit_GL_EXT_fog_coord(); +#endif /* GL_EXT_fog_coord */ +#ifdef GL_EXT_fragment_lighting + if (glewExperimental || GLEW_EXT_fragment_lighting) CONST_CAST(GLEW_EXT_fragment_lighting) = !_glewInit_GL_EXT_fragment_lighting(); +#endif /* GL_EXT_fragment_lighting */ +#ifdef GL_EXT_framebuffer_blit + if (glewExperimental || GLEW_EXT_framebuffer_blit) CONST_CAST(GLEW_EXT_framebuffer_blit) = !_glewInit_GL_EXT_framebuffer_blit(); +#endif /* GL_EXT_framebuffer_blit */ +#ifdef GL_EXT_framebuffer_multisample + if (glewExperimental || GLEW_EXT_framebuffer_multisample) CONST_CAST(GLEW_EXT_framebuffer_multisample) = !_glewInit_GL_EXT_framebuffer_multisample(); +#endif /* GL_EXT_framebuffer_multisample */ +#ifdef GL_EXT_framebuffer_object + if (glewExperimental || GLEW_EXT_framebuffer_object) CONST_CAST(GLEW_EXT_framebuffer_object) = !_glewInit_GL_EXT_framebuffer_object(); +#endif /* GL_EXT_framebuffer_object */ +#ifdef GL_EXT_geometry_shader4 + if (glewExperimental || GLEW_EXT_geometry_shader4) CONST_CAST(GLEW_EXT_geometry_shader4) = !_glewInit_GL_EXT_geometry_shader4(); +#endif /* GL_EXT_geometry_shader4 */ +#ifdef GL_EXT_gpu_program_parameters + if (glewExperimental || GLEW_EXT_gpu_program_parameters) CONST_CAST(GLEW_EXT_gpu_program_parameters) = !_glewInit_GL_EXT_gpu_program_parameters(); +#endif /* GL_EXT_gpu_program_parameters */ +#ifdef GL_EXT_gpu_shader4 + if (glewExperimental || GLEW_EXT_gpu_shader4) CONST_CAST(GLEW_EXT_gpu_shader4) = !_glewInit_GL_EXT_gpu_shader4(); +#endif /* GL_EXT_gpu_shader4 */ +#ifdef GL_EXT_histogram + if (glewExperimental || GLEW_EXT_histogram) CONST_CAST(GLEW_EXT_histogram) = !_glewInit_GL_EXT_histogram(); +#endif /* GL_EXT_histogram */ +#ifdef GL_EXT_index_func + if (glewExperimental || GLEW_EXT_index_func) CONST_CAST(GLEW_EXT_index_func) = !_glewInit_GL_EXT_index_func(); +#endif /* GL_EXT_index_func */ +#ifdef GL_EXT_index_material + if (glewExperimental || GLEW_EXT_index_material) CONST_CAST(GLEW_EXT_index_material) = !_glewInit_GL_EXT_index_material(); +#endif /* GL_EXT_index_material */ +#ifdef GL_EXT_instanced_arrays + if (glewExperimental || GLEW_EXT_instanced_arrays) CONST_CAST(GLEW_EXT_instanced_arrays) = !_glewInit_GL_EXT_instanced_arrays(); +#endif /* GL_EXT_instanced_arrays */ +#ifdef GL_EXT_light_texture + if (glewExperimental || GLEW_EXT_light_texture) CONST_CAST(GLEW_EXT_light_texture) = !_glewInit_GL_EXT_light_texture(); +#endif /* GL_EXT_light_texture */ +#ifdef GL_EXT_map_buffer_range + if (glewExperimental || GLEW_EXT_map_buffer_range) CONST_CAST(GLEW_EXT_map_buffer_range) = !_glewInit_GL_EXT_map_buffer_range(); +#endif /* GL_EXT_map_buffer_range */ +#ifdef GL_EXT_memory_object + if (glewExperimental || GLEW_EXT_memory_object) CONST_CAST(GLEW_EXT_memory_object) = !_glewInit_GL_EXT_memory_object(); +#endif /* GL_EXT_memory_object */ +#ifdef GL_EXT_memory_object_fd + if (glewExperimental || GLEW_EXT_memory_object_fd) CONST_CAST(GLEW_EXT_memory_object_fd) = !_glewInit_GL_EXT_memory_object_fd(); +#endif /* GL_EXT_memory_object_fd */ +#ifdef GL_EXT_memory_object_win32 + if (glewExperimental || GLEW_EXT_memory_object_win32) CONST_CAST(GLEW_EXT_memory_object_win32) = !_glewInit_GL_EXT_memory_object_win32(); +#endif /* GL_EXT_memory_object_win32 */ +#ifdef GL_EXT_multi_draw_arrays + if (glewExperimental || GLEW_EXT_multi_draw_arrays) CONST_CAST(GLEW_EXT_multi_draw_arrays) = !_glewInit_GL_EXT_multi_draw_arrays(); +#endif /* GL_EXT_multi_draw_arrays */ +#ifdef GL_EXT_multi_draw_indirect + if (glewExperimental || GLEW_EXT_multi_draw_indirect) CONST_CAST(GLEW_EXT_multi_draw_indirect) = !_glewInit_GL_EXT_multi_draw_indirect(); +#endif /* GL_EXT_multi_draw_indirect */ +#ifdef GL_EXT_multisample + if (glewExperimental || GLEW_EXT_multisample) CONST_CAST(GLEW_EXT_multisample) = !_glewInit_GL_EXT_multisample(); +#endif /* GL_EXT_multisample */ +#ifdef GL_EXT_multisampled_render_to_texture + if (glewExperimental || GLEW_EXT_multisampled_render_to_texture) CONST_CAST(GLEW_EXT_multisampled_render_to_texture) = !_glewInit_GL_EXT_multisampled_render_to_texture(); +#endif /* GL_EXT_multisampled_render_to_texture */ +#ifdef GL_EXT_multiview_draw_buffers + if (glewExperimental || GLEW_EXT_multiview_draw_buffers) CONST_CAST(GLEW_EXT_multiview_draw_buffers) = !_glewInit_GL_EXT_multiview_draw_buffers(); +#endif /* GL_EXT_multiview_draw_buffers */ +#ifdef GL_EXT_paletted_texture + if (glewExperimental || GLEW_EXT_paletted_texture) CONST_CAST(GLEW_EXT_paletted_texture) = !_glewInit_GL_EXT_paletted_texture(); +#endif /* GL_EXT_paletted_texture */ +#ifdef GL_EXT_pixel_transform + if (glewExperimental || GLEW_EXT_pixel_transform) CONST_CAST(GLEW_EXT_pixel_transform) = !_glewInit_GL_EXT_pixel_transform(); +#endif /* GL_EXT_pixel_transform */ +#ifdef GL_EXT_point_parameters + if (glewExperimental || GLEW_EXT_point_parameters) CONST_CAST(GLEW_EXT_point_parameters) = !_glewInit_GL_EXT_point_parameters(); +#endif /* GL_EXT_point_parameters */ +#ifdef GL_EXT_polygon_offset + if (glewExperimental || GLEW_EXT_polygon_offset) CONST_CAST(GLEW_EXT_polygon_offset) = !_glewInit_GL_EXT_polygon_offset(); +#endif /* GL_EXT_polygon_offset */ +#ifdef GL_EXT_polygon_offset_clamp + if (glewExperimental || GLEW_EXT_polygon_offset_clamp) CONST_CAST(GLEW_EXT_polygon_offset_clamp) = !_glewInit_GL_EXT_polygon_offset_clamp(); +#endif /* GL_EXT_polygon_offset_clamp */ +#ifdef GL_EXT_provoking_vertex + if (glewExperimental || GLEW_EXT_provoking_vertex) CONST_CAST(GLEW_EXT_provoking_vertex) = !_glewInit_GL_EXT_provoking_vertex(); +#endif /* GL_EXT_provoking_vertex */ +#ifdef GL_EXT_raster_multisample + if (glewExperimental || GLEW_EXT_raster_multisample) CONST_CAST(GLEW_EXT_raster_multisample) = !_glewInit_GL_EXT_raster_multisample(); +#endif /* GL_EXT_raster_multisample */ +#ifdef GL_EXT_scene_marker + if (glewExperimental || GLEW_EXT_scene_marker) CONST_CAST(GLEW_EXT_scene_marker) = !_glewInit_GL_EXT_scene_marker(); +#endif /* GL_EXT_scene_marker */ +#ifdef GL_EXT_secondary_color + if (glewExperimental || GLEW_EXT_secondary_color) CONST_CAST(GLEW_EXT_secondary_color) = !_glewInit_GL_EXT_secondary_color(); +#endif /* GL_EXT_secondary_color */ +#ifdef GL_EXT_semaphore + if (glewExperimental || GLEW_EXT_semaphore) CONST_CAST(GLEW_EXT_semaphore) = !_glewInit_GL_EXT_semaphore(); +#endif /* GL_EXT_semaphore */ +#ifdef GL_EXT_semaphore_fd + if (glewExperimental || GLEW_EXT_semaphore_fd) CONST_CAST(GLEW_EXT_semaphore_fd) = !_glewInit_GL_EXT_semaphore_fd(); +#endif /* GL_EXT_semaphore_fd */ +#ifdef GL_EXT_semaphore_win32 + if (glewExperimental || GLEW_EXT_semaphore_win32) CONST_CAST(GLEW_EXT_semaphore_win32) = !_glewInit_GL_EXT_semaphore_win32(); +#endif /* GL_EXT_semaphore_win32 */ +#ifdef GL_EXT_separate_shader_objects + if (glewExperimental || GLEW_EXT_separate_shader_objects) CONST_CAST(GLEW_EXT_separate_shader_objects) = !_glewInit_GL_EXT_separate_shader_objects(); +#endif /* GL_EXT_separate_shader_objects */ +#ifdef GL_EXT_shader_image_load_store + if (glewExperimental || GLEW_EXT_shader_image_load_store) CONST_CAST(GLEW_EXT_shader_image_load_store) = !_glewInit_GL_EXT_shader_image_load_store(); +#endif /* GL_EXT_shader_image_load_store */ +#ifdef GL_EXT_shader_pixel_local_storage2 + if (glewExperimental || GLEW_EXT_shader_pixel_local_storage2) CONST_CAST(GLEW_EXT_shader_pixel_local_storage2) = !_glewInit_GL_EXT_shader_pixel_local_storage2(); +#endif /* GL_EXT_shader_pixel_local_storage2 */ +#ifdef GL_EXT_sparse_texture + if (glewExperimental || GLEW_EXT_sparse_texture) CONST_CAST(GLEW_EXT_sparse_texture) = !_glewInit_GL_EXT_sparse_texture(); +#endif /* GL_EXT_sparse_texture */ +#ifdef GL_EXT_stencil_two_side + if (glewExperimental || GLEW_EXT_stencil_two_side) CONST_CAST(GLEW_EXT_stencil_two_side) = !_glewInit_GL_EXT_stencil_two_side(); +#endif /* GL_EXT_stencil_two_side */ +#ifdef GL_EXT_subtexture + if (glewExperimental || GLEW_EXT_subtexture) CONST_CAST(GLEW_EXT_subtexture) = !_glewInit_GL_EXT_subtexture(); +#endif /* GL_EXT_subtexture */ +#ifdef GL_EXT_texture3D + if (glewExperimental || GLEW_EXT_texture3D) CONST_CAST(GLEW_EXT_texture3D) = !_glewInit_GL_EXT_texture3D(); +#endif /* GL_EXT_texture3D */ +#ifdef GL_EXT_texture_array + if (glewExperimental || GLEW_EXT_texture_array) CONST_CAST(GLEW_EXT_texture_array) = !_glewInit_GL_EXT_texture_array(); +#endif /* GL_EXT_texture_array */ +#ifdef GL_EXT_texture_buffer_object + if (glewExperimental || GLEW_EXT_texture_buffer_object) CONST_CAST(GLEW_EXT_texture_buffer_object) = !_glewInit_GL_EXT_texture_buffer_object(); +#endif /* GL_EXT_texture_buffer_object */ +#ifdef GL_EXT_texture_integer + if (glewExperimental || GLEW_EXT_texture_integer) CONST_CAST(GLEW_EXT_texture_integer) = !_glewInit_GL_EXT_texture_integer(); +#endif /* GL_EXT_texture_integer */ +#ifdef GL_EXT_texture_object + if (glewExperimental || GLEW_EXT_texture_object) CONST_CAST(GLEW_EXT_texture_object) = !_glewInit_GL_EXT_texture_object(); +#endif /* GL_EXT_texture_object */ +#ifdef GL_EXT_texture_perturb_normal + if (glewExperimental || GLEW_EXT_texture_perturb_normal) CONST_CAST(GLEW_EXT_texture_perturb_normal) = !_glewInit_GL_EXT_texture_perturb_normal(); +#endif /* GL_EXT_texture_perturb_normal */ +#ifdef GL_EXT_texture_storage + if (glewExperimental || GLEW_EXT_texture_storage) CONST_CAST(GLEW_EXT_texture_storage) = !_glewInit_GL_EXT_texture_storage(); +#endif /* GL_EXT_texture_storage */ +#ifdef GL_EXT_texture_view + if (glewExperimental || GLEW_EXT_texture_view) CONST_CAST(GLEW_EXT_texture_view) = !_glewInit_GL_EXT_texture_view(); +#endif /* GL_EXT_texture_view */ +#ifdef GL_EXT_timer_query + if (glewExperimental || GLEW_EXT_timer_query) CONST_CAST(GLEW_EXT_timer_query) = !_glewInit_GL_EXT_timer_query(); +#endif /* GL_EXT_timer_query */ +#ifdef GL_EXT_transform_feedback + if (glewExperimental || GLEW_EXT_transform_feedback) CONST_CAST(GLEW_EXT_transform_feedback) = !_glewInit_GL_EXT_transform_feedback(); +#endif /* GL_EXT_transform_feedback */ +#ifdef GL_EXT_vertex_array + if (glewExperimental || GLEW_EXT_vertex_array) CONST_CAST(GLEW_EXT_vertex_array) = !_glewInit_GL_EXT_vertex_array(); +#endif /* GL_EXT_vertex_array */ +#ifdef GL_EXT_vertex_array_setXXX + if (glewExperimental || GLEW_EXT_vertex_array_setXXX) CONST_CAST(GLEW_EXT_vertex_array_setXXX) = !_glewInit_GL_EXT_vertex_array_setXXX(); +#endif /* GL_EXT_vertex_array_setXXX */ +#ifdef GL_EXT_vertex_attrib_64bit + if (glewExperimental || GLEW_EXT_vertex_attrib_64bit) CONST_CAST(GLEW_EXT_vertex_attrib_64bit) = !_glewInit_GL_EXT_vertex_attrib_64bit(); +#endif /* GL_EXT_vertex_attrib_64bit */ +#ifdef GL_EXT_vertex_shader + if (glewExperimental || GLEW_EXT_vertex_shader) CONST_CAST(GLEW_EXT_vertex_shader) = !_glewInit_GL_EXT_vertex_shader(); +#endif /* GL_EXT_vertex_shader */ +#ifdef GL_EXT_vertex_weighting + if (glewExperimental || GLEW_EXT_vertex_weighting) CONST_CAST(GLEW_EXT_vertex_weighting) = !_glewInit_GL_EXT_vertex_weighting(); +#endif /* GL_EXT_vertex_weighting */ +#ifdef GL_EXT_win32_keyed_mutex + if (glewExperimental || GLEW_EXT_win32_keyed_mutex) CONST_CAST(GLEW_EXT_win32_keyed_mutex) = !_glewInit_GL_EXT_win32_keyed_mutex(); +#endif /* GL_EXT_win32_keyed_mutex */ +#ifdef GL_EXT_window_rectangles + if (glewExperimental || GLEW_EXT_window_rectangles) CONST_CAST(GLEW_EXT_window_rectangles) = !_glewInit_GL_EXT_window_rectangles(); +#endif /* GL_EXT_window_rectangles */ +#ifdef GL_EXT_x11_sync_object + if (glewExperimental || GLEW_EXT_x11_sync_object) CONST_CAST(GLEW_EXT_x11_sync_object) = !_glewInit_GL_EXT_x11_sync_object(); +#endif /* GL_EXT_x11_sync_object */ +#ifdef GL_GREMEDY_frame_terminator + if (glewExperimental || GLEW_GREMEDY_frame_terminator) CONST_CAST(GLEW_GREMEDY_frame_terminator) = !_glewInit_GL_GREMEDY_frame_terminator(); +#endif /* GL_GREMEDY_frame_terminator */ +#ifdef GL_GREMEDY_string_marker + if (glewExperimental || GLEW_GREMEDY_string_marker) CONST_CAST(GLEW_GREMEDY_string_marker) = !_glewInit_GL_GREMEDY_string_marker(); +#endif /* GL_GREMEDY_string_marker */ +#ifdef GL_HP_image_transform + if (glewExperimental || GLEW_HP_image_transform) CONST_CAST(GLEW_HP_image_transform) = !_glewInit_GL_HP_image_transform(); +#endif /* GL_HP_image_transform */ +#ifdef GL_IBM_multimode_draw_arrays + if (glewExperimental || GLEW_IBM_multimode_draw_arrays) CONST_CAST(GLEW_IBM_multimode_draw_arrays) = !_glewInit_GL_IBM_multimode_draw_arrays(); +#endif /* GL_IBM_multimode_draw_arrays */ +#ifdef GL_IBM_vertex_array_lists + if (glewExperimental || GLEW_IBM_vertex_array_lists) CONST_CAST(GLEW_IBM_vertex_array_lists) = !_glewInit_GL_IBM_vertex_array_lists(); +#endif /* GL_IBM_vertex_array_lists */ +#ifdef GL_INTEL_map_texture + if (glewExperimental || GLEW_INTEL_map_texture) CONST_CAST(GLEW_INTEL_map_texture) = !_glewInit_GL_INTEL_map_texture(); +#endif /* GL_INTEL_map_texture */ +#ifdef GL_INTEL_parallel_arrays + if (glewExperimental || GLEW_INTEL_parallel_arrays) CONST_CAST(GLEW_INTEL_parallel_arrays) = !_glewInit_GL_INTEL_parallel_arrays(); +#endif /* GL_INTEL_parallel_arrays */ +#ifdef GL_INTEL_performance_query + if (glewExperimental || GLEW_INTEL_performance_query) CONST_CAST(GLEW_INTEL_performance_query) = !_glewInit_GL_INTEL_performance_query(); +#endif /* GL_INTEL_performance_query */ +#ifdef GL_INTEL_texture_scissor + if (glewExperimental || GLEW_INTEL_texture_scissor) CONST_CAST(GLEW_INTEL_texture_scissor) = !_glewInit_GL_INTEL_texture_scissor(); +#endif /* GL_INTEL_texture_scissor */ +#ifdef GL_KHR_blend_equation_advanced + if (glewExperimental || GLEW_KHR_blend_equation_advanced) CONST_CAST(GLEW_KHR_blend_equation_advanced) = !_glewInit_GL_KHR_blend_equation_advanced(); +#endif /* GL_KHR_blend_equation_advanced */ +#ifdef GL_KHR_debug + if (glewExperimental || GLEW_KHR_debug) CONST_CAST(GLEW_KHR_debug) = !_glewInit_GL_KHR_debug(); +#endif /* GL_KHR_debug */ +#ifdef GL_KHR_parallel_shader_compile + if (glewExperimental || GLEW_KHR_parallel_shader_compile) CONST_CAST(GLEW_KHR_parallel_shader_compile) = !_glewInit_GL_KHR_parallel_shader_compile(); +#endif /* GL_KHR_parallel_shader_compile */ +#ifdef GL_KHR_robustness + if (glewExperimental || GLEW_KHR_robustness) CONST_CAST(GLEW_KHR_robustness) = !_glewInit_GL_KHR_robustness(); +#endif /* GL_KHR_robustness */ +#ifdef GL_KTX_buffer_region + if (glewExperimental || GLEW_KTX_buffer_region) CONST_CAST(GLEW_KTX_buffer_region) = !_glewInit_GL_KTX_buffer_region(); +#endif /* GL_KTX_buffer_region */ +#ifdef GL_MESA_resize_buffers + if (glewExperimental || GLEW_MESA_resize_buffers) CONST_CAST(GLEW_MESA_resize_buffers) = !_glewInit_GL_MESA_resize_buffers(); +#endif /* GL_MESA_resize_buffers */ +#ifdef GL_MESA_window_pos + if (glewExperimental || GLEW_MESA_window_pos) CONST_CAST(GLEW_MESA_window_pos) = !_glewInit_GL_MESA_window_pos(); +#endif /* GL_MESA_window_pos */ +#ifdef GL_NVX_conditional_render + if (glewExperimental || GLEW_NVX_conditional_render) CONST_CAST(GLEW_NVX_conditional_render) = !_glewInit_GL_NVX_conditional_render(); +#endif /* GL_NVX_conditional_render */ +#ifdef GL_NVX_linked_gpu_multicast + if (glewExperimental || GLEW_NVX_linked_gpu_multicast) CONST_CAST(GLEW_NVX_linked_gpu_multicast) = !_glewInit_GL_NVX_linked_gpu_multicast(); +#endif /* GL_NVX_linked_gpu_multicast */ +#ifdef GL_NV_3dvision_settings + if (glewExperimental || GLEW_NV_3dvision_settings) CONST_CAST(GLEW_NV_3dvision_settings) = !_glewInit_GL_NV_3dvision_settings(); +#endif /* GL_NV_3dvision_settings */ +#ifdef GL_NV_bindless_multi_draw_indirect + if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect) CONST_CAST(GLEW_NV_bindless_multi_draw_indirect) = !_glewInit_GL_NV_bindless_multi_draw_indirect(); +#endif /* GL_NV_bindless_multi_draw_indirect */ +#ifdef GL_NV_bindless_multi_draw_indirect_count + if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect_count) CONST_CAST(GLEW_NV_bindless_multi_draw_indirect_count) = !_glewInit_GL_NV_bindless_multi_draw_indirect_count(); +#endif /* GL_NV_bindless_multi_draw_indirect_count */ +#ifdef GL_NV_bindless_texture + if (glewExperimental || GLEW_NV_bindless_texture) CONST_CAST(GLEW_NV_bindless_texture) = !_glewInit_GL_NV_bindless_texture(); +#endif /* GL_NV_bindless_texture */ +#ifdef GL_NV_blend_equation_advanced + if (glewExperimental || GLEW_NV_blend_equation_advanced) CONST_CAST(GLEW_NV_blend_equation_advanced) = !_glewInit_GL_NV_blend_equation_advanced(); +#endif /* GL_NV_blend_equation_advanced */ +#ifdef GL_NV_clip_space_w_scaling + if (glewExperimental || GLEW_NV_clip_space_w_scaling) CONST_CAST(GLEW_NV_clip_space_w_scaling) = !_glewInit_GL_NV_clip_space_w_scaling(); +#endif /* GL_NV_clip_space_w_scaling */ +#ifdef GL_NV_command_list + if (glewExperimental || GLEW_NV_command_list) CONST_CAST(GLEW_NV_command_list) = !_glewInit_GL_NV_command_list(); +#endif /* GL_NV_command_list */ +#ifdef GL_NV_conditional_render + if (glewExperimental || GLEW_NV_conditional_render) CONST_CAST(GLEW_NV_conditional_render) = !_glewInit_GL_NV_conditional_render(); +#endif /* GL_NV_conditional_render */ +#ifdef GL_NV_conservative_raster + if (glewExperimental || GLEW_NV_conservative_raster) CONST_CAST(GLEW_NV_conservative_raster) = !_glewInit_GL_NV_conservative_raster(); +#endif /* GL_NV_conservative_raster */ +#ifdef GL_NV_conservative_raster_dilate + if (glewExperimental || GLEW_NV_conservative_raster_dilate) CONST_CAST(GLEW_NV_conservative_raster_dilate) = !_glewInit_GL_NV_conservative_raster_dilate(); +#endif /* GL_NV_conservative_raster_dilate */ +#ifdef GL_NV_conservative_raster_pre_snap_triangles + if (glewExperimental || GLEW_NV_conservative_raster_pre_snap_triangles) CONST_CAST(GLEW_NV_conservative_raster_pre_snap_triangles) = !_glewInit_GL_NV_conservative_raster_pre_snap_triangles(); +#endif /* GL_NV_conservative_raster_pre_snap_triangles */ +#ifdef GL_NV_copy_buffer + if (glewExperimental || GLEW_NV_copy_buffer) CONST_CAST(GLEW_NV_copy_buffer) = !_glewInit_GL_NV_copy_buffer(); +#endif /* GL_NV_copy_buffer */ +#ifdef GL_NV_copy_image + if (glewExperimental || GLEW_NV_copy_image) CONST_CAST(GLEW_NV_copy_image) = !_glewInit_GL_NV_copy_image(); +#endif /* GL_NV_copy_image */ +#ifdef GL_NV_depth_buffer_float + if (glewExperimental || GLEW_NV_depth_buffer_float) CONST_CAST(GLEW_NV_depth_buffer_float) = !_glewInit_GL_NV_depth_buffer_float(); +#endif /* GL_NV_depth_buffer_float */ +#ifdef GL_NV_draw_buffers + if (glewExperimental || GLEW_NV_draw_buffers) CONST_CAST(GLEW_NV_draw_buffers) = !_glewInit_GL_NV_draw_buffers(); +#endif /* GL_NV_draw_buffers */ +#ifdef GL_NV_draw_instanced + if (glewExperimental || GLEW_NV_draw_instanced) CONST_CAST(GLEW_NV_draw_instanced) = !_glewInit_GL_NV_draw_instanced(); +#endif /* GL_NV_draw_instanced */ +#ifdef GL_NV_draw_texture + if (glewExperimental || GLEW_NV_draw_texture) CONST_CAST(GLEW_NV_draw_texture) = !_glewInit_GL_NV_draw_texture(); +#endif /* GL_NV_draw_texture */ +#ifdef GL_NV_draw_vulkan_image + if (glewExperimental || GLEW_NV_draw_vulkan_image) CONST_CAST(GLEW_NV_draw_vulkan_image) = !_glewInit_GL_NV_draw_vulkan_image(); +#endif /* GL_NV_draw_vulkan_image */ +#ifdef GL_NV_evaluators + if (glewExperimental || GLEW_NV_evaluators) CONST_CAST(GLEW_NV_evaluators) = !_glewInit_GL_NV_evaluators(); +#endif /* GL_NV_evaluators */ +#ifdef GL_NV_explicit_multisample + if (glewExperimental || GLEW_NV_explicit_multisample) CONST_CAST(GLEW_NV_explicit_multisample) = !_glewInit_GL_NV_explicit_multisample(); +#endif /* GL_NV_explicit_multisample */ +#ifdef GL_NV_fence + if (glewExperimental || GLEW_NV_fence) CONST_CAST(GLEW_NV_fence) = !_glewInit_GL_NV_fence(); +#endif /* GL_NV_fence */ +#ifdef GL_NV_fragment_coverage_to_color + if (glewExperimental || GLEW_NV_fragment_coverage_to_color) CONST_CAST(GLEW_NV_fragment_coverage_to_color) = !_glewInit_GL_NV_fragment_coverage_to_color(); +#endif /* GL_NV_fragment_coverage_to_color */ +#ifdef GL_NV_fragment_program + if (glewExperimental || GLEW_NV_fragment_program) CONST_CAST(GLEW_NV_fragment_program) = !_glewInit_GL_NV_fragment_program(); +#endif /* GL_NV_fragment_program */ +#ifdef GL_NV_framebuffer_blit + if (glewExperimental || GLEW_NV_framebuffer_blit) CONST_CAST(GLEW_NV_framebuffer_blit) = !_glewInit_GL_NV_framebuffer_blit(); +#endif /* GL_NV_framebuffer_blit */ +#ifdef GL_NV_framebuffer_multisample + if (glewExperimental || GLEW_NV_framebuffer_multisample) CONST_CAST(GLEW_NV_framebuffer_multisample) = !_glewInit_GL_NV_framebuffer_multisample(); +#endif /* GL_NV_framebuffer_multisample */ +#ifdef GL_NV_framebuffer_multisample_coverage + if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = !_glewInit_GL_NV_framebuffer_multisample_coverage(); +#endif /* GL_NV_framebuffer_multisample_coverage */ +#ifdef GL_NV_geometry_program4 + if (glewExperimental || GLEW_NV_geometry_program4) CONST_CAST(GLEW_NV_geometry_program4) = !_glewInit_GL_NV_geometry_program4(); +#endif /* GL_NV_geometry_program4 */ +#ifdef GL_NV_gpu_multicast + if (glewExperimental || GLEW_NV_gpu_multicast) CONST_CAST(GLEW_NV_gpu_multicast) = !_glewInit_GL_NV_gpu_multicast(); +#endif /* GL_NV_gpu_multicast */ +#ifdef GL_NV_gpu_program4 + if (glewExperimental || GLEW_NV_gpu_program4) CONST_CAST(GLEW_NV_gpu_program4) = !_glewInit_GL_NV_gpu_program4(); +#endif /* GL_NV_gpu_program4 */ +#ifdef GL_NV_gpu_shader5 + if (glewExperimental || GLEW_NV_gpu_shader5) CONST_CAST(GLEW_NV_gpu_shader5) = !_glewInit_GL_NV_gpu_shader5(); +#endif /* GL_NV_gpu_shader5 */ +#ifdef GL_NV_half_float + if (glewExperimental || GLEW_NV_half_float) CONST_CAST(GLEW_NV_half_float) = !_glewInit_GL_NV_half_float(); +#endif /* GL_NV_half_float */ +#ifdef GL_NV_instanced_arrays + if (glewExperimental || GLEW_NV_instanced_arrays) CONST_CAST(GLEW_NV_instanced_arrays) = !_glewInit_GL_NV_instanced_arrays(); +#endif /* GL_NV_instanced_arrays */ +#ifdef GL_NV_internalformat_sample_query + if (glewExperimental || GLEW_NV_internalformat_sample_query) CONST_CAST(GLEW_NV_internalformat_sample_query) = !_glewInit_GL_NV_internalformat_sample_query(); +#endif /* GL_NV_internalformat_sample_query */ +#ifdef GL_NV_non_square_matrices + if (glewExperimental || GLEW_NV_non_square_matrices) CONST_CAST(GLEW_NV_non_square_matrices) = !_glewInit_GL_NV_non_square_matrices(); +#endif /* GL_NV_non_square_matrices */ +#ifdef GL_NV_occlusion_query + if (glewExperimental || GLEW_NV_occlusion_query) CONST_CAST(GLEW_NV_occlusion_query) = !_glewInit_GL_NV_occlusion_query(); +#endif /* GL_NV_occlusion_query */ +#ifdef GL_NV_parameter_buffer_object + if (glewExperimental || GLEW_NV_parameter_buffer_object) CONST_CAST(GLEW_NV_parameter_buffer_object) = !_glewInit_GL_NV_parameter_buffer_object(); +#endif /* GL_NV_parameter_buffer_object */ +#ifdef GL_NV_path_rendering + if (glewExperimental || GLEW_NV_path_rendering) CONST_CAST(GLEW_NV_path_rendering) = !_glewInit_GL_NV_path_rendering(); +#endif /* GL_NV_path_rendering */ +#ifdef GL_NV_pixel_data_range + if (glewExperimental || GLEW_NV_pixel_data_range) CONST_CAST(GLEW_NV_pixel_data_range) = !_glewInit_GL_NV_pixel_data_range(); +#endif /* GL_NV_pixel_data_range */ +#ifdef GL_NV_point_sprite + if (glewExperimental || GLEW_NV_point_sprite) CONST_CAST(GLEW_NV_point_sprite) = !_glewInit_GL_NV_point_sprite(); +#endif /* GL_NV_point_sprite */ +#ifdef GL_NV_polygon_mode + if (glewExperimental || GLEW_NV_polygon_mode) CONST_CAST(GLEW_NV_polygon_mode) = !_glewInit_GL_NV_polygon_mode(); +#endif /* GL_NV_polygon_mode */ +#ifdef GL_NV_present_video + if (glewExperimental || GLEW_NV_present_video) CONST_CAST(GLEW_NV_present_video) = !_glewInit_GL_NV_present_video(); +#endif /* GL_NV_present_video */ +#ifdef GL_NV_primitive_restart + if (glewExperimental || GLEW_NV_primitive_restart) CONST_CAST(GLEW_NV_primitive_restart) = !_glewInit_GL_NV_primitive_restart(); +#endif /* GL_NV_primitive_restart */ +#ifdef GL_NV_register_combiners + if (glewExperimental || GLEW_NV_register_combiners) CONST_CAST(GLEW_NV_register_combiners) = !_glewInit_GL_NV_register_combiners(); +#endif /* GL_NV_register_combiners */ +#ifdef GL_NV_register_combiners2 + if (glewExperimental || GLEW_NV_register_combiners2) CONST_CAST(GLEW_NV_register_combiners2) = !_glewInit_GL_NV_register_combiners2(); +#endif /* GL_NV_register_combiners2 */ +#ifdef GL_NV_sample_locations + if (glewExperimental || GLEW_NV_sample_locations) CONST_CAST(GLEW_NV_sample_locations) = !_glewInit_GL_NV_sample_locations(); +#endif /* GL_NV_sample_locations */ +#ifdef GL_NV_shader_buffer_load + if (glewExperimental || GLEW_NV_shader_buffer_load) CONST_CAST(GLEW_NV_shader_buffer_load) = !_glewInit_GL_NV_shader_buffer_load(); +#endif /* GL_NV_shader_buffer_load */ +#ifdef GL_NV_texture_array + if (glewExperimental || GLEW_NV_texture_array) CONST_CAST(GLEW_NV_texture_array) = !_glewInit_GL_NV_texture_array(); +#endif /* GL_NV_texture_array */ +#ifdef GL_NV_texture_barrier + if (glewExperimental || GLEW_NV_texture_barrier) CONST_CAST(GLEW_NV_texture_barrier) = !_glewInit_GL_NV_texture_barrier(); +#endif /* GL_NV_texture_barrier */ +#ifdef GL_NV_texture_multisample + if (glewExperimental || GLEW_NV_texture_multisample) CONST_CAST(GLEW_NV_texture_multisample) = !_glewInit_GL_NV_texture_multisample(); +#endif /* GL_NV_texture_multisample */ +#ifdef GL_NV_transform_feedback + if (glewExperimental || GLEW_NV_transform_feedback) CONST_CAST(GLEW_NV_transform_feedback) = !_glewInit_GL_NV_transform_feedback(); +#endif /* GL_NV_transform_feedback */ +#ifdef GL_NV_transform_feedback2 + if (glewExperimental || GLEW_NV_transform_feedback2) CONST_CAST(GLEW_NV_transform_feedback2) = !_glewInit_GL_NV_transform_feedback2(); +#endif /* GL_NV_transform_feedback2 */ +#ifdef GL_NV_vdpau_interop + if (glewExperimental || GLEW_NV_vdpau_interop) CONST_CAST(GLEW_NV_vdpau_interop) = !_glewInit_GL_NV_vdpau_interop(); +#endif /* GL_NV_vdpau_interop */ +#ifdef GL_NV_vertex_array_range + if (glewExperimental || GLEW_NV_vertex_array_range) CONST_CAST(GLEW_NV_vertex_array_range) = !_glewInit_GL_NV_vertex_array_range(); +#endif /* GL_NV_vertex_array_range */ +#ifdef GL_NV_vertex_attrib_integer_64bit + if (glewExperimental || GLEW_NV_vertex_attrib_integer_64bit) CONST_CAST(GLEW_NV_vertex_attrib_integer_64bit) = !_glewInit_GL_NV_vertex_attrib_integer_64bit(); +#endif /* GL_NV_vertex_attrib_integer_64bit */ +#ifdef GL_NV_vertex_buffer_unified_memory + if (glewExperimental || GLEW_NV_vertex_buffer_unified_memory) CONST_CAST(GLEW_NV_vertex_buffer_unified_memory) = !_glewInit_GL_NV_vertex_buffer_unified_memory(); +#endif /* GL_NV_vertex_buffer_unified_memory */ +#ifdef GL_NV_vertex_program + if (glewExperimental || GLEW_NV_vertex_program) CONST_CAST(GLEW_NV_vertex_program) = !_glewInit_GL_NV_vertex_program(); +#endif /* GL_NV_vertex_program */ +#ifdef GL_NV_video_capture + if (glewExperimental || GLEW_NV_video_capture) CONST_CAST(GLEW_NV_video_capture) = !_glewInit_GL_NV_video_capture(); +#endif /* GL_NV_video_capture */ +#ifdef GL_NV_viewport_array + if (glewExperimental || GLEW_NV_viewport_array) CONST_CAST(GLEW_NV_viewport_array) = !_glewInit_GL_NV_viewport_array(); +#endif /* GL_NV_viewport_array */ +#ifdef GL_NV_viewport_swizzle + if (glewExperimental || GLEW_NV_viewport_swizzle) CONST_CAST(GLEW_NV_viewport_swizzle) = !_glewInit_GL_NV_viewport_swizzle(); +#endif /* GL_NV_viewport_swizzle */ +#ifdef GL_OVR_multiview + if (glewExperimental || GLEW_OVR_multiview) CONST_CAST(GLEW_OVR_multiview) = !_glewInit_GL_OVR_multiview(); +#endif /* GL_OVR_multiview */ +#ifdef GL_OVR_multiview_multisampled_render_to_texture + if (glewExperimental || GLEW_OVR_multiview_multisampled_render_to_texture) CONST_CAST(GLEW_OVR_multiview_multisampled_render_to_texture) = !_glewInit_GL_OVR_multiview_multisampled_render_to_texture(); +#endif /* GL_OVR_multiview_multisampled_render_to_texture */ +#ifdef GL_QCOM_alpha_test + if (glewExperimental || GLEW_QCOM_alpha_test) CONST_CAST(GLEW_QCOM_alpha_test) = !_glewInit_GL_QCOM_alpha_test(); +#endif /* GL_QCOM_alpha_test */ +#ifdef GL_QCOM_driver_control + if (glewExperimental || GLEW_QCOM_driver_control) CONST_CAST(GLEW_QCOM_driver_control) = !_glewInit_GL_QCOM_driver_control(); +#endif /* GL_QCOM_driver_control */ +#ifdef GL_QCOM_extended_get + if (glewExperimental || GLEW_QCOM_extended_get) CONST_CAST(GLEW_QCOM_extended_get) = !_glewInit_GL_QCOM_extended_get(); +#endif /* GL_QCOM_extended_get */ +#ifdef GL_QCOM_extended_get2 + if (glewExperimental || GLEW_QCOM_extended_get2) CONST_CAST(GLEW_QCOM_extended_get2) = !_glewInit_GL_QCOM_extended_get2(); +#endif /* GL_QCOM_extended_get2 */ +#ifdef GL_QCOM_framebuffer_foveated + if (glewExperimental || GLEW_QCOM_framebuffer_foveated) CONST_CAST(GLEW_QCOM_framebuffer_foveated) = !_glewInit_GL_QCOM_framebuffer_foveated(); +#endif /* GL_QCOM_framebuffer_foveated */ +#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent + if (glewExperimental || GLEW_QCOM_shader_framebuffer_fetch_noncoherent) CONST_CAST(GLEW_QCOM_shader_framebuffer_fetch_noncoherent) = !_glewInit_GL_QCOM_shader_framebuffer_fetch_noncoherent(); +#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */ +#ifdef GL_QCOM_tiled_rendering + if (glewExperimental || GLEW_QCOM_tiled_rendering) CONST_CAST(GLEW_QCOM_tiled_rendering) = !_glewInit_GL_QCOM_tiled_rendering(); +#endif /* GL_QCOM_tiled_rendering */ +#ifdef GL_REGAL_ES1_0_compatibility + if (glewExperimental || GLEW_REGAL_ES1_0_compatibility) CONST_CAST(GLEW_REGAL_ES1_0_compatibility) = !_glewInit_GL_REGAL_ES1_0_compatibility(); +#endif /* GL_REGAL_ES1_0_compatibility */ +#ifdef GL_REGAL_ES1_1_compatibility + if (glewExperimental || GLEW_REGAL_ES1_1_compatibility) CONST_CAST(GLEW_REGAL_ES1_1_compatibility) = !_glewInit_GL_REGAL_ES1_1_compatibility(); +#endif /* GL_REGAL_ES1_1_compatibility */ +#ifdef GL_REGAL_error_string + if (glewExperimental || GLEW_REGAL_error_string) CONST_CAST(GLEW_REGAL_error_string) = !_glewInit_GL_REGAL_error_string(); +#endif /* GL_REGAL_error_string */ +#ifdef GL_REGAL_extension_query + if (glewExperimental || GLEW_REGAL_extension_query) CONST_CAST(GLEW_REGAL_extension_query) = !_glewInit_GL_REGAL_extension_query(); +#endif /* GL_REGAL_extension_query */ +#ifdef GL_REGAL_log + if (glewExperimental || GLEW_REGAL_log) CONST_CAST(GLEW_REGAL_log) = !_glewInit_GL_REGAL_log(); +#endif /* GL_REGAL_log */ +#ifdef GL_REGAL_proc_address + if (glewExperimental || GLEW_REGAL_proc_address) CONST_CAST(GLEW_REGAL_proc_address) = !_glewInit_GL_REGAL_proc_address(); +#endif /* GL_REGAL_proc_address */ +#ifdef GL_SGIS_detail_texture + if (glewExperimental || GLEW_SGIS_detail_texture) CONST_CAST(GLEW_SGIS_detail_texture) = !_glewInit_GL_SGIS_detail_texture(); +#endif /* GL_SGIS_detail_texture */ +#ifdef GL_SGIS_fog_function + if (glewExperimental || GLEW_SGIS_fog_function) CONST_CAST(GLEW_SGIS_fog_function) = !_glewInit_GL_SGIS_fog_function(); +#endif /* GL_SGIS_fog_function */ +#ifdef GL_SGIS_multisample + if (glewExperimental || GLEW_SGIS_multisample) CONST_CAST(GLEW_SGIS_multisample) = !_glewInit_GL_SGIS_multisample(); +#endif /* GL_SGIS_multisample */ +#ifdef GL_SGIS_multitexture + if (glewExperimental || GLEW_SGIS_multitexture) CONST_CAST(GLEW_SGIS_multitexture) = !_glewInit_GL_SGIS_multitexture(); +#endif /* GL_SGIS_multitexture */ +#ifdef GL_SGIS_shared_multisample + if (glewExperimental || GLEW_SGIS_shared_multisample) CONST_CAST(GLEW_SGIS_shared_multisample) = !_glewInit_GL_SGIS_shared_multisample(); +#endif /* GL_SGIS_shared_multisample */ +#ifdef GL_SGIS_sharpen_texture + if (glewExperimental || GLEW_SGIS_sharpen_texture) CONST_CAST(GLEW_SGIS_sharpen_texture) = !_glewInit_GL_SGIS_sharpen_texture(); +#endif /* GL_SGIS_sharpen_texture */ +#ifdef GL_SGIS_texture4D + if (glewExperimental || GLEW_SGIS_texture4D) CONST_CAST(GLEW_SGIS_texture4D) = !_glewInit_GL_SGIS_texture4D(); +#endif /* GL_SGIS_texture4D */ +#ifdef GL_SGIS_texture_filter4 + if (glewExperimental || GLEW_SGIS_texture_filter4) CONST_CAST(GLEW_SGIS_texture_filter4) = !_glewInit_GL_SGIS_texture_filter4(); +#endif /* GL_SGIS_texture_filter4 */ +#ifdef GL_SGIX_async + if (glewExperimental || GLEW_SGIX_async) CONST_CAST(GLEW_SGIX_async) = !_glewInit_GL_SGIX_async(); +#endif /* GL_SGIX_async */ +#ifdef GL_SGIX_datapipe + if (glewExperimental || GLEW_SGIX_datapipe) CONST_CAST(GLEW_SGIX_datapipe) = !_glewInit_GL_SGIX_datapipe(); +#endif /* GL_SGIX_datapipe */ +#ifdef GL_SGIX_flush_raster + if (glewExperimental || GLEW_SGIX_flush_raster) CONST_CAST(GLEW_SGIX_flush_raster) = !_glewInit_GL_SGIX_flush_raster(); +#endif /* GL_SGIX_flush_raster */ +#ifdef GL_SGIX_fog_layers + if (glewExperimental || GLEW_SGIX_fog_layers) CONST_CAST(GLEW_SGIX_fog_layers) = !_glewInit_GL_SGIX_fog_layers(); +#endif /* GL_SGIX_fog_layers */ +#ifdef GL_SGIX_fog_texture + if (glewExperimental || GLEW_SGIX_fog_texture) CONST_CAST(GLEW_SGIX_fog_texture) = !_glewInit_GL_SGIX_fog_texture(); +#endif /* GL_SGIX_fog_texture */ +#ifdef GL_SGIX_fragment_specular_lighting + if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = !_glewInit_GL_SGIX_fragment_specular_lighting(); +#endif /* GL_SGIX_fragment_specular_lighting */ +#ifdef GL_SGIX_framezoom + if (glewExperimental || GLEW_SGIX_framezoom) CONST_CAST(GLEW_SGIX_framezoom) = !_glewInit_GL_SGIX_framezoom(); +#endif /* GL_SGIX_framezoom */ +#ifdef GL_SGIX_igloo_interface + if (glewExperimental || GLEW_SGIX_igloo_interface) CONST_CAST(GLEW_SGIX_igloo_interface) = !_glewInit_GL_SGIX_igloo_interface(); +#endif /* GL_SGIX_igloo_interface */ +#ifdef GL_SGIX_mpeg1 + if (glewExperimental || GLEW_SGIX_mpeg1) CONST_CAST(GLEW_SGIX_mpeg1) = !_glewInit_GL_SGIX_mpeg1(); +#endif /* GL_SGIX_mpeg1 */ +#ifdef GL_SGIX_nonlinear_lighting_pervertex + if (glewExperimental || GLEW_SGIX_nonlinear_lighting_pervertex) CONST_CAST(GLEW_SGIX_nonlinear_lighting_pervertex) = !_glewInit_GL_SGIX_nonlinear_lighting_pervertex(); +#endif /* GL_SGIX_nonlinear_lighting_pervertex */ +#ifdef GL_SGIX_pixel_texture + if (glewExperimental || GLEW_SGIX_pixel_texture) CONST_CAST(GLEW_SGIX_pixel_texture) = !_glewInit_GL_SGIX_pixel_texture(); +#endif /* GL_SGIX_pixel_texture */ +#ifdef GL_SGIX_polynomial_ffd + if (glewExperimental || GLEW_SGIX_polynomial_ffd) CONST_CAST(GLEW_SGIX_polynomial_ffd) = !_glewInit_GL_SGIX_polynomial_ffd(); +#endif /* GL_SGIX_polynomial_ffd */ +#ifdef GL_SGIX_quad_mesh + if (glewExperimental || GLEW_SGIX_quad_mesh) CONST_CAST(GLEW_SGIX_quad_mesh) = !_glewInit_GL_SGIX_quad_mesh(); +#endif /* GL_SGIX_quad_mesh */ +#ifdef GL_SGIX_reference_plane + if (glewExperimental || GLEW_SGIX_reference_plane) CONST_CAST(GLEW_SGIX_reference_plane) = !_glewInit_GL_SGIX_reference_plane(); +#endif /* GL_SGIX_reference_plane */ +#ifdef GL_SGIX_sprite + if (glewExperimental || GLEW_SGIX_sprite) CONST_CAST(GLEW_SGIX_sprite) = !_glewInit_GL_SGIX_sprite(); +#endif /* GL_SGIX_sprite */ +#ifdef GL_SGIX_tag_sample_buffer + if (glewExperimental || GLEW_SGIX_tag_sample_buffer) CONST_CAST(GLEW_SGIX_tag_sample_buffer) = !_glewInit_GL_SGIX_tag_sample_buffer(); +#endif /* GL_SGIX_tag_sample_buffer */ +#ifdef GL_SGIX_vector_ops + if (glewExperimental || GLEW_SGIX_vector_ops) CONST_CAST(GLEW_SGIX_vector_ops) = !_glewInit_GL_SGIX_vector_ops(); +#endif /* GL_SGIX_vector_ops */ +#ifdef GL_SGIX_vertex_array_object + if (glewExperimental || GLEW_SGIX_vertex_array_object) CONST_CAST(GLEW_SGIX_vertex_array_object) = !_glewInit_GL_SGIX_vertex_array_object(); +#endif /* GL_SGIX_vertex_array_object */ +#ifdef GL_SGI_color_table + if (glewExperimental || GLEW_SGI_color_table) CONST_CAST(GLEW_SGI_color_table) = !_glewInit_GL_SGI_color_table(); +#endif /* GL_SGI_color_table */ +#ifdef GL_SGI_fft + if (glewExperimental || GLEW_SGI_fft) CONST_CAST(GLEW_SGI_fft) = !_glewInit_GL_SGI_fft(); +#endif /* GL_SGI_fft */ +#ifdef GL_SUNX_constant_data + if (glewExperimental || GLEW_SUNX_constant_data) CONST_CAST(GLEW_SUNX_constant_data) = !_glewInit_GL_SUNX_constant_data(); +#endif /* GL_SUNX_constant_data */ +#ifdef GL_SUN_global_alpha + if (glewExperimental || GLEW_SUN_global_alpha) CONST_CAST(GLEW_SUN_global_alpha) = !_glewInit_GL_SUN_global_alpha(); +#endif /* GL_SUN_global_alpha */ +#ifdef GL_SUN_read_video_pixels + if (glewExperimental || GLEW_SUN_read_video_pixels) CONST_CAST(GLEW_SUN_read_video_pixels) = !_glewInit_GL_SUN_read_video_pixels(); +#endif /* GL_SUN_read_video_pixels */ +#ifdef GL_SUN_triangle_list + if (glewExperimental || GLEW_SUN_triangle_list) CONST_CAST(GLEW_SUN_triangle_list) = !_glewInit_GL_SUN_triangle_list(); +#endif /* GL_SUN_triangle_list */ +#ifdef GL_SUN_vertex + if (glewExperimental || GLEW_SUN_vertex) CONST_CAST(GLEW_SUN_vertex) = !_glewInit_GL_SUN_vertex(); +#endif /* GL_SUN_vertex */ +#ifdef GL_WIN_swap_hint + if (glewExperimental || GLEW_WIN_swap_hint) CONST_CAST(GLEW_WIN_swap_hint) = !_glewInit_GL_WIN_swap_hint(); +#endif /* GL_WIN_swap_hint */ +#ifdef GL_NV_fragment_program4 + CONST_CAST(GLEW_NV_fragment_program4) = GLEW_NV_gpu_program4; +#endif /* GL_NV_fragment_program4 */ +#ifdef GL_NV_geometry_program4 + CONST_CAST(GLEW_NV_geometry_program4) = GLEW_NV_gpu_program4; +#endif /* GL_NV_geometry_program4 */ +#ifdef GL_NV_tessellation_program5 + CONST_CAST(GLEW_NV_tessellation_program5) = GLEW_NV_gpu_program5; +#endif /* GL_NV_tessellation_program5 */ +#ifdef GL_NV_vertex_program4 + CONST_CAST(GLEW_NV_vertex_program4) = GLEW_NV_gpu_program4; +#endif /* GL_NV_vertex_program4 */ + + return GLEW_OK; +} + +/* ------------------------------------------------------------------------ */ + +const GLubyte * GLEWAPIENTRY glewGetErrorString (GLenum error) +{ + static const GLubyte* _glewErrorString[] = + { + (const GLubyte*)"No error", + (const GLubyte*)"Missing GL version", + (const GLubyte*)"GL 1.1 and up are not supported", + (const GLubyte*)"GLX 1.2 and up are not supported", + (const GLubyte*)"Unknown error" + }; + const size_t max_error = sizeof(_glewErrorString)/sizeof(*_glewErrorString) - 1; + return _glewErrorString[(size_t)error > max_error ? max_error : (size_t)error]; +} + +const GLubyte * GLEWAPIENTRY glewGetString (GLenum name) +{ + static const GLubyte* _glewString[] = + { + (const GLubyte*)NULL, + (const GLubyte*)"2.1.0", + (const GLubyte*)"2", + (const GLubyte*)"1", + (const GLubyte*)"0" + }; + const size_t max_string = sizeof(_glewString)/sizeof(*_glewString) - 1; + return _glewString[(size_t)name > max_string ? 0 : (size_t)name]; +} + +/* ------------------------------------------------------------------------ */ + +GLboolean glewExperimental = GL_FALSE; + +GLenum GLEWAPIENTRY glewInit (void) +{ + return glewContextInit(); +} + +GLboolean GLEWAPIENTRY glewIsSupported (const char* name) +{ + const GLubyte* pos = (const GLubyte*)name; + GLuint len = _glewStrLen(pos); + GLboolean ret = GL_TRUE; + while (ret && len > 0) + { + if (_glewStrSame1(&pos, &len, (const GLubyte*)"GL_", 3)) + { + if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8)) + { +#ifdef GL_VERSION_1_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3)) + { + ret = GLEW_VERSION_1_2; + continue; + } +#endif +#ifdef GL_VERSION_1_2_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2_1", 5)) + { + ret = GLEW_VERSION_1_2_1; + continue; + } +#endif +#ifdef GL_VERSION_1_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3)) + { + ret = GLEW_VERSION_1_3; + continue; + } +#endif +#ifdef GL_VERSION_1_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3)) + { + ret = GLEW_VERSION_1_4; + continue; + } +#endif +#ifdef GL_VERSION_1_5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3)) + { + ret = GLEW_VERSION_1_5; + continue; + } +#endif +#ifdef GL_VERSION_2_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_0", 3)) + { + ret = GLEW_VERSION_2_0; + continue; + } +#endif +#ifdef GL_VERSION_2_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_1", 3)) + { + ret = GLEW_VERSION_2_1; + continue; + } +#endif +#ifdef GL_VERSION_3_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_0", 3)) + { + ret = GLEW_VERSION_3_0; + continue; + } +#endif +#ifdef GL_VERSION_3_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_1", 3)) + { + ret = GLEW_VERSION_3_1; + continue; + } +#endif +#ifdef GL_VERSION_3_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_2", 3)) + { + ret = GLEW_VERSION_3_2; + continue; + } +#endif +#ifdef GL_VERSION_3_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_3", 3)) + { + ret = GLEW_VERSION_3_3; + continue; + } +#endif +#ifdef GL_VERSION_4_0 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_0", 3)) + { + ret = GLEW_VERSION_4_0; + continue; + } +#endif +#ifdef GL_VERSION_4_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_1", 3)) + { + ret = GLEW_VERSION_4_1; + continue; + } +#endif +#ifdef GL_VERSION_4_2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_2", 3)) + { + ret = GLEW_VERSION_4_2; + continue; + } +#endif +#ifdef GL_VERSION_4_3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_3", 3)) + { + ret = GLEW_VERSION_4_3; + continue; + } +#endif +#ifdef GL_VERSION_4_4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_4", 3)) + { + ret = GLEW_VERSION_4_4; + continue; + } +#endif +#ifdef GL_VERSION_4_5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_5", 3)) + { + ret = GLEW_VERSION_4_5; + continue; + } +#endif +#ifdef GL_VERSION_4_6 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_6", 3)) + { + ret = GLEW_VERSION_4_6; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5)) + { +#ifdef GL_3DFX_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_3DFX_multisample; + continue; + } +#endif +#ifdef GL_3DFX_tbuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tbuffer", 7)) + { + ret = GLEW_3DFX_tbuffer; + continue; + } +#endif +#ifdef GL_3DFX_texture_compression_FXT1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_FXT1", 24)) + { + ret = GLEW_3DFX_texture_compression_FXT1; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4)) + { +#ifdef GL_AMD_blend_minmax_factor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax_factor", 19)) + { + ret = GLEW_AMD_blend_minmax_factor; + continue; + } +#endif +#ifdef GL_AMD_compressed_3DC_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_3DC_texture", 22)) + { + ret = GLEW_AMD_compressed_3DC_texture; + continue; + } +#endif +#ifdef GL_AMD_compressed_ATC_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_ATC_texture", 22)) + { + ret = GLEW_AMD_compressed_ATC_texture; + continue; + } +#endif +#ifdef GL_AMD_conservative_depth + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18)) + { + ret = GLEW_AMD_conservative_depth; + continue; + } +#endif +#ifdef GL_AMD_debug_output + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_output", 12)) + { + ret = GLEW_AMD_debug_output; + continue; + } +#endif +#ifdef GL_AMD_depth_clamp_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp_separate", 20)) + { + ret = GLEW_AMD_depth_clamp_separate; + continue; + } +#endif +#ifdef GL_AMD_draw_buffers_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18)) + { + ret = GLEW_AMD_draw_buffers_blend; + continue; + } +#endif +#ifdef GL_AMD_framebuffer_sample_positions + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sample_positions", 28)) + { + ret = GLEW_AMD_framebuffer_sample_positions; + continue; + } +#endif +#ifdef GL_AMD_gcn_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gcn_shader", 10)) + { + ret = GLEW_AMD_gcn_shader; + continue; + } +#endif +#ifdef GL_AMD_gpu_shader_half_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_half_float", 21)) + { + ret = GLEW_AMD_gpu_shader_half_float; + continue; + } +#endif +#ifdef GL_AMD_gpu_shader_int16 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_int16", 16)) + { + ret = GLEW_AMD_gpu_shader_int16; + continue; + } +#endif +#ifdef GL_AMD_gpu_shader_int64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_int64", 16)) + { + ret = GLEW_AMD_gpu_shader_int64; + continue; + } +#endif +#ifdef GL_AMD_interleaved_elements + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interleaved_elements", 20)) + { + ret = GLEW_AMD_interleaved_elements; + continue; + } +#endif +#ifdef GL_AMD_multi_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19)) + { + ret = GLEW_AMD_multi_draw_indirect; + continue; + } +#endif +#ifdef GL_AMD_name_gen_delete + if (_glewStrSame3(&pos, &len, (const GLubyte*)"name_gen_delete", 15)) + { + ret = GLEW_AMD_name_gen_delete; + continue; + } +#endif +#ifdef GL_AMD_occlusion_query_event + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query_event", 21)) + { + ret = GLEW_AMD_occlusion_query_event; + continue; + } +#endif +#ifdef GL_AMD_performance_monitor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"performance_monitor", 19)) + { + ret = GLEW_AMD_performance_monitor; + continue; + } +#endif +#ifdef GL_AMD_pinned_memory + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pinned_memory", 13)) + { + ret = GLEW_AMD_pinned_memory; + continue; + } +#endif +#ifdef GL_AMD_program_binary_Z400 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_binary_Z400", 19)) + { + ret = GLEW_AMD_program_binary_Z400; + continue; + } +#endif +#ifdef GL_AMD_query_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_buffer_object", 19)) + { + ret = GLEW_AMD_query_buffer_object; + continue; + } +#endif +#ifdef GL_AMD_sample_positions + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_positions", 16)) + { + ret = GLEW_AMD_sample_positions; + continue; + } +#endif +#ifdef GL_AMD_seamless_cubemap_per_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cubemap_per_texture", 28)) + { + ret = GLEW_AMD_seamless_cubemap_per_texture; + continue; + } +#endif +#ifdef GL_AMD_shader_atomic_counter_ops + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counter_ops", 25)) + { + ret = GLEW_AMD_shader_atomic_counter_ops; + continue; + } +#endif +#ifdef GL_AMD_shader_ballot + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_ballot", 13)) + { + ret = GLEW_AMD_shader_ballot; + continue; + } +#endif +#ifdef GL_AMD_shader_explicit_vertex_parameter + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_explicit_vertex_parameter", 32)) + { + ret = GLEW_AMD_shader_explicit_vertex_parameter; + continue; + } +#endif +#ifdef GL_AMD_shader_stencil_export + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21)) + { + ret = GLEW_AMD_shader_stencil_export; + continue; + } +#endif +#ifdef GL_AMD_shader_stencil_value_export + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_value_export", 27)) + { + ret = GLEW_AMD_shader_stencil_value_export; + continue; + } +#endif +#ifdef GL_AMD_shader_trinary_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_trinary_minmax", 21)) + { + ret = GLEW_AMD_shader_trinary_minmax; + continue; + } +#endif +#ifdef GL_AMD_sparse_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14)) + { + ret = GLEW_AMD_sparse_texture; + continue; + } +#endif +#ifdef GL_AMD_stencil_operation_extended + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_operation_extended", 26)) + { + ret = GLEW_AMD_stencil_operation_extended; + continue; + } +#endif +#ifdef GL_AMD_texture_gather_bias_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_gather_bias_lod", 23)) + { + ret = GLEW_AMD_texture_gather_bias_lod; + continue; + } +#endif +#ifdef GL_AMD_texture_texture4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_texture4", 16)) + { + ret = GLEW_AMD_texture_texture4; + continue; + } +#endif +#ifdef GL_AMD_transform_feedback3_lines_triangles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback3_lines_triangles", 35)) + { + ret = GLEW_AMD_transform_feedback3_lines_triangles; + continue; + } +#endif +#ifdef GL_AMD_transform_feedback4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback4", 19)) + { + ret = GLEW_AMD_transform_feedback4; + continue; + } +#endif +#ifdef GL_AMD_vertex_shader_layer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_layer", 19)) + { + ret = GLEW_AMD_vertex_shader_layer; + continue; + } +#endif +#ifdef GL_AMD_vertex_shader_tessellator + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_tessellator", 25)) + { + ret = GLEW_AMD_vertex_shader_tessellator; + continue; + } +#endif +#ifdef GL_AMD_vertex_shader_viewport_index + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_viewport_index", 28)) + { + ret = GLEW_AMD_vertex_shader_viewport_index; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANDROID_", 8)) + { +#ifdef GL_ANDROID_extension_pack_es31a + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extension_pack_es31a", 20)) + { + ret = GLEW_ANDROID_extension_pack_es31a; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANGLE_", 6)) + { +#ifdef GL_ANGLE_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_ANGLE_depth_texture; + continue; + } +#endif +#ifdef GL_ANGLE_framebuffer_blit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16)) + { + ret = GLEW_ANGLE_framebuffer_blit; + continue; + } +#endif +#ifdef GL_ANGLE_framebuffer_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) + { + ret = GLEW_ANGLE_framebuffer_multisample; + continue; + } +#endif +#ifdef GL_ANGLE_instanced_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16)) + { + ret = GLEW_ANGLE_instanced_arrays; + continue; + } +#endif +#ifdef GL_ANGLE_pack_reverse_row_order + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_reverse_row_order", 22)) + { + ret = GLEW_ANGLE_pack_reverse_row_order; + continue; + } +#endif +#ifdef GL_ANGLE_program_binary + if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_binary", 14)) + { + ret = GLEW_ANGLE_program_binary; + continue; + } +#endif +#ifdef GL_ANGLE_texture_compression_dxt1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24)) + { + ret = GLEW_ANGLE_texture_compression_dxt1; + continue; + } +#endif +#ifdef GL_ANGLE_texture_compression_dxt3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt3", 24)) + { + ret = GLEW_ANGLE_texture_compression_dxt3; + continue; + } +#endif +#ifdef GL_ANGLE_texture_compression_dxt5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt5", 24)) + { + ret = GLEW_ANGLE_texture_compression_dxt5; + continue; + } +#endif +#ifdef GL_ANGLE_texture_usage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_usage", 13)) + { + ret = GLEW_ANGLE_texture_usage; + continue; + } +#endif +#ifdef GL_ANGLE_timer_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11)) + { + ret = GLEW_ANGLE_timer_query; + continue; + } +#endif +#ifdef GL_ANGLE_translated_shader_source + if (_glewStrSame3(&pos, &len, (const GLubyte*)"translated_shader_source", 24)) + { + ret = GLEW_ANGLE_translated_shader_source; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6)) + { +#ifdef GL_APPLE_aux_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"aux_depth_stencil", 17)) + { + ret = GLEW_APPLE_aux_depth_stencil; + continue; + } +#endif +#ifdef GL_APPLE_client_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_storage", 14)) + { + ret = GLEW_APPLE_client_storage; + continue; + } +#endif +#ifdef GL_APPLE_clip_distance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_distance", 13)) + { + ret = GLEW_APPLE_clip_distance; + continue; + } +#endif +#ifdef GL_APPLE_color_buffer_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_packed_float", 25)) + { + ret = GLEW_APPLE_color_buffer_packed_float; + continue; + } +#endif +#ifdef GL_APPLE_copy_texture_levels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture_levels", 19)) + { + ret = GLEW_APPLE_copy_texture_levels; + continue; + } +#endif +#ifdef GL_APPLE_element_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) + { + ret = GLEW_APPLE_element_array; + continue; + } +#endif +#ifdef GL_APPLE_fence + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) + { + ret = GLEW_APPLE_fence; + continue; + } +#endif +#ifdef GL_APPLE_float_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_pixels", 12)) + { + ret = GLEW_APPLE_float_pixels; + continue; + } +#endif +#ifdef GL_APPLE_flush_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_buffer_range", 18)) + { + ret = GLEW_APPLE_flush_buffer_range; + continue; + } +#endif +#ifdef GL_APPLE_framebuffer_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) + { + ret = GLEW_APPLE_framebuffer_multisample; + continue; + } +#endif +#ifdef GL_APPLE_object_purgeable + if (_glewStrSame3(&pos, &len, (const GLubyte*)"object_purgeable", 16)) + { + ret = GLEW_APPLE_object_purgeable; + continue; + } +#endif +#ifdef GL_APPLE_pixel_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer", 12)) + { + ret = GLEW_APPLE_pixel_buffer; + continue; + } +#endif +#ifdef GL_APPLE_rgb_422 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rgb_422", 7)) + { + ret = GLEW_APPLE_rgb_422; + continue; + } +#endif +#ifdef GL_APPLE_row_bytes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"row_bytes", 9)) + { + ret = GLEW_APPLE_row_bytes; + continue; + } +#endif +#ifdef GL_APPLE_specular_vector + if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_vector", 15)) + { + ret = GLEW_APPLE_specular_vector; + continue; + } +#endif +#ifdef GL_APPLE_sync + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4)) + { + ret = GLEW_APPLE_sync; + continue; + } +#endif +#ifdef GL_APPLE_texture_2D_limited_npot + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_2D_limited_npot", 23)) + { + ret = GLEW_APPLE_texture_2D_limited_npot; + continue; + } +#endif +#ifdef GL_APPLE_texture_format_BGRA8888 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_format_BGRA8888", 23)) + { + ret = GLEW_APPLE_texture_format_BGRA8888; + continue; + } +#endif +#ifdef GL_APPLE_texture_max_level + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_max_level", 17)) + { + ret = GLEW_APPLE_texture_max_level; + continue; + } +#endif +#ifdef GL_APPLE_texture_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_packed_float", 20)) + { + ret = GLEW_APPLE_texture_packed_float; + continue; + } +#endif +#ifdef GL_APPLE_texture_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) + { + ret = GLEW_APPLE_texture_range; + continue; + } +#endif +#ifdef GL_APPLE_transform_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_hint", 14)) + { + ret = GLEW_APPLE_transform_hint; + continue; + } +#endif +#ifdef GL_APPLE_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_APPLE_vertex_array_object; + continue; + } +#endif +#ifdef GL_APPLE_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLEW_APPLE_vertex_array_range; + continue; + } +#endif +#ifdef GL_APPLE_vertex_program_evaluators + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program_evaluators", 25)) + { + ret = GLEW_APPLE_vertex_program_evaluators; + continue; + } +#endif +#ifdef GL_APPLE_ycbcr_422 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_422", 9)) + { + ret = GLEW_APPLE_ycbcr_422; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4)) + { +#ifdef GL_ARB_ES2_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES2_compatibility", 17)) + { + ret = GLEW_ARB_ES2_compatibility; + continue; + } +#endif +#ifdef GL_ARB_ES3_1_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES3_1_compatibility", 19)) + { + ret = GLEW_ARB_ES3_1_compatibility; + continue; + } +#endif +#ifdef GL_ARB_ES3_2_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES3_2_compatibility", 19)) + { + ret = GLEW_ARB_ES3_2_compatibility; + continue; + } +#endif +#ifdef GL_ARB_ES3_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES3_compatibility", 17)) + { + ret = GLEW_ARB_ES3_compatibility; + continue; + } +#endif +#ifdef GL_ARB_arrays_of_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"arrays_of_arrays", 16)) + { + ret = GLEW_ARB_arrays_of_arrays; + continue; + } +#endif +#ifdef GL_ARB_base_instance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"base_instance", 13)) + { + ret = GLEW_ARB_base_instance; + continue; + } +#endif +#ifdef GL_ARB_bindless_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_texture", 16)) + { + ret = GLEW_ARB_bindless_texture; + continue; + } +#endif +#ifdef GL_ARB_blend_func_extended + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_extended", 19)) + { + ret = GLEW_ARB_blend_func_extended; + continue; + } +#endif +#ifdef GL_ARB_buffer_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_storage", 14)) + { + ret = GLEW_ARB_buffer_storage; + continue; + } +#endif +#ifdef GL_ARB_cl_event + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cl_event", 8)) + { + ret = GLEW_ARB_cl_event; + continue; + } +#endif +#ifdef GL_ARB_clear_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_buffer_object", 19)) + { + ret = GLEW_ARB_clear_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_clear_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_texture", 13)) + { + ret = GLEW_ARB_clear_texture; + continue; + } +#endif +#ifdef GL_ARB_clip_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_control", 12)) + { + ret = GLEW_ARB_clip_control; + continue; + } +#endif +#ifdef GL_ARB_color_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18)) + { + ret = GLEW_ARB_color_buffer_float; + continue; + } +#endif +#ifdef GL_ARB_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compatibility", 13)) + { + ret = GLEW_ARB_compatibility; + continue; + } +#endif +#ifdef GL_ARB_compressed_texture_pixel_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_texture_pixel_storage", 32)) + { + ret = GLEW_ARB_compressed_texture_pixel_storage; + continue; + } +#endif +#ifdef GL_ARB_compute_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_shader", 14)) + { + ret = GLEW_ARB_compute_shader; + continue; + } +#endif +#ifdef GL_ARB_compute_variable_group_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_variable_group_size", 27)) + { + ret = GLEW_ARB_compute_variable_group_size; + continue; + } +#endif +#ifdef GL_ARB_conditional_render_inverted + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render_inverted", 27)) + { + ret = GLEW_ARB_conditional_render_inverted; + continue; + } +#endif +#ifdef GL_ARB_conservative_depth + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18)) + { + ret = GLEW_ARB_conservative_depth; + continue; + } +#endif +#ifdef GL_ARB_copy_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_buffer", 11)) + { + ret = GLEW_ARB_copy_buffer; + continue; + } +#endif +#ifdef GL_ARB_copy_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10)) + { + ret = GLEW_ARB_copy_image; + continue; + } +#endif +#ifdef GL_ARB_cull_distance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_distance", 13)) + { + ret = GLEW_ARB_cull_distance; + continue; + } +#endif +#ifdef GL_ARB_debug_output + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_output", 12)) + { + ret = GLEW_ARB_debug_output; + continue; + } +#endif +#ifdef GL_ARB_depth_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18)) + { + ret = GLEW_ARB_depth_buffer_float; + continue; + } +#endif +#ifdef GL_ARB_depth_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11)) + { + ret = GLEW_ARB_depth_clamp; + continue; + } +#endif +#ifdef GL_ARB_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_ARB_depth_texture; + continue; + } +#endif +#ifdef GL_ARB_derivative_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"derivative_control", 18)) + { + ret = GLEW_ARB_derivative_control; + continue; + } +#endif +#ifdef GL_ARB_direct_state_access + if (_glewStrSame3(&pos, &len, (const GLubyte*)"direct_state_access", 19)) + { + ret = GLEW_ARB_direct_state_access; + continue; + } +#endif +#ifdef GL_ARB_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_ARB_draw_buffers; + continue; + } +#endif +#ifdef GL_ARB_draw_buffers_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18)) + { + ret = GLEW_ARB_draw_buffers_blend; + continue; + } +#endif +#ifdef GL_ARB_draw_elements_base_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_elements_base_vertex", 25)) + { + ret = GLEW_ARB_draw_elements_base_vertex; + continue; + } +#endif +#ifdef GL_ARB_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_indirect", 13)) + { + ret = GLEW_ARB_draw_indirect; + continue; + } +#endif +#ifdef GL_ARB_draw_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) + { + ret = GLEW_ARB_draw_instanced; + continue; + } +#endif +#ifdef GL_ARB_enhanced_layouts + if (_glewStrSame3(&pos, &len, (const GLubyte*)"enhanced_layouts", 16)) + { + ret = GLEW_ARB_enhanced_layouts; + continue; + } +#endif +#ifdef GL_ARB_explicit_attrib_location + if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_attrib_location", 24)) + { + ret = GLEW_ARB_explicit_attrib_location; + continue; + } +#endif +#ifdef GL_ARB_explicit_uniform_location + if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_uniform_location", 25)) + { + ret = GLEW_ARB_explicit_uniform_location; + continue; + } +#endif +#ifdef GL_ARB_fragment_coord_conventions + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_coord_conventions", 26)) + { + ret = GLEW_ARB_fragment_coord_conventions; + continue; + } +#endif +#ifdef GL_ARB_fragment_layer_viewport + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_layer_viewport", 23)) + { + ret = GLEW_ARB_fragment_layer_viewport; + continue; + } +#endif +#ifdef GL_ARB_fragment_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) + { + ret = GLEW_ARB_fragment_program; + continue; + } +#endif +#ifdef GL_ARB_fragment_program_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_shadow", 23)) + { + ret = GLEW_ARB_fragment_program_shadow; + continue; + } +#endif +#ifdef GL_ARB_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) + { + ret = GLEW_ARB_fragment_shader; + continue; + } +#endif +#ifdef GL_ARB_fragment_shader_interlock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader_interlock", 25)) + { + ret = GLEW_ARB_fragment_shader_interlock; + continue; + } +#endif +#ifdef GL_ARB_framebuffer_no_attachments + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_no_attachments", 26)) + { + ret = GLEW_ARB_framebuffer_no_attachments; + continue; + } +#endif +#ifdef GL_ARB_framebuffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) + { + ret = GLEW_ARB_framebuffer_object; + continue; + } +#endif +#ifdef GL_ARB_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLEW_ARB_framebuffer_sRGB; + continue; + } +#endif +#ifdef GL_ARB_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_ARB_geometry_shader4; + continue; + } +#endif +#ifdef GL_ARB_get_program_binary + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_program_binary", 18)) + { + ret = GLEW_ARB_get_program_binary; + continue; + } +#endif +#ifdef GL_ARB_get_texture_sub_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_texture_sub_image", 21)) + { + ret = GLEW_ARB_get_texture_sub_image; + continue; + } +#endif +#ifdef GL_ARB_gl_spirv + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gl_spirv", 8)) + { + ret = GLEW_ARB_gl_spirv; + continue; + } +#endif +#ifdef GL_ARB_gpu_shader5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11)) + { + ret = GLEW_ARB_gpu_shader5; + continue; + } +#endif +#ifdef GL_ARB_gpu_shader_fp64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_fp64", 15)) + { + ret = GLEW_ARB_gpu_shader_fp64; + continue; + } +#endif +#ifdef GL_ARB_gpu_shader_int64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_int64", 16)) + { + ret = GLEW_ARB_gpu_shader_int64; + continue; + } +#endif +#ifdef GL_ARB_half_float_pixel + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_pixel", 16)) + { + ret = GLEW_ARB_half_float_pixel; + continue; + } +#endif +#ifdef GL_ARB_half_float_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_vertex", 17)) + { + ret = GLEW_ARB_half_float_vertex; + continue; + } +#endif +#ifdef GL_ARB_imaging + if (_glewStrSame3(&pos, &len, (const GLubyte*)"imaging", 7)) + { + ret = GLEW_ARB_imaging; + continue; + } +#endif +#ifdef GL_ARB_indirect_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"indirect_parameters", 19)) + { + ret = GLEW_ARB_indirect_parameters; + continue; + } +#endif +#ifdef GL_ARB_instanced_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16)) + { + ret = GLEW_ARB_instanced_arrays; + continue; + } +#endif +#ifdef GL_ARB_internalformat_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_query", 20)) + { + ret = GLEW_ARB_internalformat_query; + continue; + } +#endif +#ifdef GL_ARB_internalformat_query2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_query2", 21)) + { + ret = GLEW_ARB_internalformat_query2; + continue; + } +#endif +#ifdef GL_ARB_invalidate_subdata + if (_glewStrSame3(&pos, &len, (const GLubyte*)"invalidate_subdata", 18)) + { + ret = GLEW_ARB_invalidate_subdata; + continue; + } +#endif +#ifdef GL_ARB_map_buffer_alignment + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_alignment", 20)) + { + ret = GLEW_ARB_map_buffer_alignment; + continue; + } +#endif +#ifdef GL_ARB_map_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_range", 16)) + { + ret = GLEW_ARB_map_buffer_range; + continue; + } +#endif +#ifdef GL_ARB_matrix_palette + if (_glewStrSame3(&pos, &len, (const GLubyte*)"matrix_palette", 14)) + { + ret = GLEW_ARB_matrix_palette; + continue; + } +#endif +#ifdef GL_ARB_multi_bind + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_bind", 10)) + { + ret = GLEW_ARB_multi_bind; + continue; + } +#endif +#ifdef GL_ARB_multi_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19)) + { + ret = GLEW_ARB_multi_draw_indirect; + continue; + } +#endif +#ifdef GL_ARB_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_ARB_multisample; + continue; + } +#endif +#ifdef GL_ARB_multitexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12)) + { + ret = GLEW_ARB_multitexture; + continue; + } +#endif +#ifdef GL_ARB_occlusion_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) + { + ret = GLEW_ARB_occlusion_query; + continue; + } +#endif +#ifdef GL_ARB_occlusion_query2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query2", 16)) + { + ret = GLEW_ARB_occlusion_query2; + continue; + } +#endif +#ifdef GL_ARB_parallel_shader_compile + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_shader_compile", 23)) + { + ret = GLEW_ARB_parallel_shader_compile; + continue; + } +#endif +#ifdef GL_ARB_pipeline_statistics_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pipeline_statistics_query", 25)) + { + ret = GLEW_ARB_pipeline_statistics_query; + continue; + } +#endif +#ifdef GL_ARB_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_ARB_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_point_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) + { + ret = GLEW_ARB_point_parameters; + continue; + } +#endif +#ifdef GL_ARB_point_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) + { + ret = GLEW_ARB_point_sprite; + continue; + } +#endif +#ifdef GL_ARB_polygon_offset_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset_clamp", 20)) + { + ret = GLEW_ARB_polygon_offset_clamp; + continue; + } +#endif +#ifdef GL_ARB_post_depth_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"post_depth_coverage", 19)) + { + ret = GLEW_ARB_post_depth_coverage; + continue; + } +#endif +#ifdef GL_ARB_program_interface_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_interface_query", 23)) + { + ret = GLEW_ARB_program_interface_query; + continue; + } +#endif +#ifdef GL_ARB_provoking_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16)) + { + ret = GLEW_ARB_provoking_vertex; + continue; + } +#endif +#ifdef GL_ARB_query_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_buffer_object", 19)) + { + ret = GLEW_ARB_query_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_robust_buffer_access_behavior + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robust_buffer_access_behavior", 29)) + { + ret = GLEW_ARB_robust_buffer_access_behavior; + continue; + } +#endif +#ifdef GL_ARB_robustness + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness", 10)) + { + ret = GLEW_ARB_robustness; + continue; + } +#endif +#ifdef GL_ARB_robustness_application_isolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32)) + { + ret = GLEW_ARB_robustness_application_isolation; + continue; + } +#endif +#ifdef GL_ARB_robustness_share_group_isolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32)) + { + ret = GLEW_ARB_robustness_share_group_isolation; + continue; + } +#endif +#ifdef GL_ARB_sample_locations + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_locations", 16)) + { + ret = GLEW_ARB_sample_locations; + continue; + } +#endif +#ifdef GL_ARB_sample_shading + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_shading", 14)) + { + ret = GLEW_ARB_sample_shading; + continue; + } +#endif +#ifdef GL_ARB_sampler_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sampler_objects", 15)) + { + ret = GLEW_ARB_sampler_objects; + continue; + } +#endif +#ifdef GL_ARB_seamless_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cube_map", 17)) + { + ret = GLEW_ARB_seamless_cube_map; + continue; + } +#endif +#ifdef GL_ARB_seamless_cubemap_per_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cubemap_per_texture", 28)) + { + ret = GLEW_ARB_seamless_cubemap_per_texture; + continue; + } +#endif +#ifdef GL_ARB_separate_shader_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23)) + { + ret = GLEW_ARB_separate_shader_objects; + continue; + } +#endif +#ifdef GL_ARB_shader_atomic_counter_ops + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counter_ops", 25)) + { + ret = GLEW_ARB_shader_atomic_counter_ops; + continue; + } +#endif +#ifdef GL_ARB_shader_atomic_counters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counters", 22)) + { + ret = GLEW_ARB_shader_atomic_counters; + continue; + } +#endif +#ifdef GL_ARB_shader_ballot + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_ballot", 13)) + { + ret = GLEW_ARB_shader_ballot; + continue; + } +#endif +#ifdef GL_ARB_shader_bit_encoding + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_bit_encoding", 19)) + { + ret = GLEW_ARB_shader_bit_encoding; + continue; + } +#endif +#ifdef GL_ARB_shader_clock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_clock", 12)) + { + ret = GLEW_ARB_shader_clock; + continue; + } +#endif +#ifdef GL_ARB_shader_draw_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_draw_parameters", 22)) + { + ret = GLEW_ARB_shader_draw_parameters; + continue; + } +#endif +#ifdef GL_ARB_shader_group_vote + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_group_vote", 17)) + { + ret = GLEW_ARB_shader_group_vote; + continue; + } +#endif +#ifdef GL_ARB_shader_image_load_store + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_store", 23)) + { + ret = GLEW_ARB_shader_image_load_store; + continue; + } +#endif +#ifdef GL_ARB_shader_image_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_size", 17)) + { + ret = GLEW_ARB_shader_image_size; + continue; + } +#endif +#ifdef GL_ARB_shader_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_objects", 14)) + { + ret = GLEW_ARB_shader_objects; + continue; + } +#endif +#ifdef GL_ARB_shader_precision + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_precision", 16)) + { + ret = GLEW_ARB_shader_precision; + continue; + } +#endif +#ifdef GL_ARB_shader_stencil_export + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21)) + { + ret = GLEW_ARB_shader_stencil_export; + continue; + } +#endif +#ifdef GL_ARB_shader_storage_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_storage_buffer_object", 28)) + { + ret = GLEW_ARB_shader_storage_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_shader_subroutine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_subroutine", 17)) + { + ret = GLEW_ARB_shader_subroutine; + continue; + } +#endif +#ifdef GL_ARB_shader_texture_image_samples + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_image_samples", 28)) + { + ret = GLEW_ARB_shader_texture_image_samples; + continue; + } +#endif +#ifdef GL_ARB_shader_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18)) + { + ret = GLEW_ARB_shader_texture_lod; + continue; + } +#endif +#ifdef GL_ARB_shader_viewport_layer_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_viewport_layer_array", 27)) + { + ret = GLEW_ARB_shader_viewport_layer_array; + continue; + } +#endif +#ifdef GL_ARB_shading_language_100 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_100", 20)) + { + ret = GLEW_ARB_shading_language_100; + continue; + } +#endif +#ifdef GL_ARB_shading_language_420pack + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_420pack", 24)) + { + ret = GLEW_ARB_shading_language_420pack; + continue; + } +#endif +#ifdef GL_ARB_shading_language_include + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_include", 24)) + { + ret = GLEW_ARB_shading_language_include; + continue; + } +#endif +#ifdef GL_ARB_shading_language_packing + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_packing", 24)) + { + ret = GLEW_ARB_shading_language_packing; + continue; + } +#endif +#ifdef GL_ARB_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) + { + ret = GLEW_ARB_shadow; + continue; + } +#endif +#ifdef GL_ARB_shadow_ambient + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) + { + ret = GLEW_ARB_shadow_ambient; + continue; + } +#endif +#ifdef GL_ARB_sparse_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_buffer", 13)) + { + ret = GLEW_ARB_sparse_buffer; + continue; + } +#endif +#ifdef GL_ARB_sparse_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14)) + { + ret = GLEW_ARB_sparse_texture; + continue; + } +#endif +#ifdef GL_ARB_sparse_texture2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture2", 15)) + { + ret = GLEW_ARB_sparse_texture2; + continue; + } +#endif +#ifdef GL_ARB_sparse_texture_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture_clamp", 20)) + { + ret = GLEW_ARB_sparse_texture_clamp; + continue; + } +#endif +#ifdef GL_ARB_spirv_extensions + if (_glewStrSame3(&pos, &len, (const GLubyte*)"spirv_extensions", 16)) + { + ret = GLEW_ARB_spirv_extensions; + continue; + } +#endif +#ifdef GL_ARB_stencil_texturing + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_texturing", 17)) + { + ret = GLEW_ARB_stencil_texturing; + continue; + } +#endif +#ifdef GL_ARB_sync + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4)) + { + ret = GLEW_ARB_sync; + continue; + } +#endif +#ifdef GL_ARB_tessellation_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_shader", 19)) + { + ret = GLEW_ARB_tessellation_shader; + continue; + } +#endif +#ifdef GL_ARB_texture_barrier + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_barrier", 15)) + { + ret = GLEW_ARB_texture_barrier; + continue; + } +#endif +#ifdef GL_ARB_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_ARB_texture_border_clamp; + continue; + } +#endif +#ifdef GL_ARB_texture_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21)) + { + ret = GLEW_ARB_texture_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_texture_buffer_object_rgb32 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object_rgb32", 27)) + { + ret = GLEW_ARB_texture_buffer_object_rgb32; + continue; + } +#endif +#ifdef GL_ARB_texture_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_range", 20)) + { + ret = GLEW_ARB_texture_buffer_range; + continue; + } +#endif +#ifdef GL_ARB_texture_compression + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression", 19)) + { + ret = GLEW_ARB_texture_compression; + continue; + } +#endif +#ifdef GL_ARB_texture_compression_bptc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_bptc", 24)) + { + ret = GLEW_ARB_texture_compression_bptc; + continue; + } +#endif +#ifdef GL_ARB_texture_compression_rgtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24)) + { + ret = GLEW_ARB_texture_compression_rgtc; + continue; + } +#endif +#ifdef GL_ARB_texture_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) + { + ret = GLEW_ARB_texture_cube_map; + continue; + } +#endif +#ifdef GL_ARB_texture_cube_map_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map_array", 22)) + { + ret = GLEW_ARB_texture_cube_map_array; + continue; + } +#endif +#ifdef GL_ARB_texture_env_add + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) + { + ret = GLEW_ARB_texture_env_add; + continue; + } +#endif +#ifdef GL_ARB_texture_env_combine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) + { + ret = GLEW_ARB_texture_env_combine; + continue; + } +#endif +#ifdef GL_ARB_texture_env_crossbar + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_crossbar", 20)) + { + ret = GLEW_ARB_texture_env_crossbar; + continue; + } +#endif +#ifdef GL_ARB_texture_env_dot3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) + { + ret = GLEW_ARB_texture_env_dot3; + continue; + } +#endif +#ifdef GL_ARB_texture_filter_anisotropic + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26)) + { + ret = GLEW_ARB_texture_filter_anisotropic; + continue; + } +#endif +#ifdef GL_ARB_texture_filter_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_minmax", 21)) + { + ret = GLEW_ARB_texture_filter_minmax; + continue; + } +#endif +#ifdef GL_ARB_texture_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) + { + ret = GLEW_ARB_texture_float; + continue; + } +#endif +#ifdef GL_ARB_texture_gather + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_gather", 14)) + { + ret = GLEW_ARB_texture_gather; + continue; + } +#endif +#ifdef GL_ARB_texture_mirror_clamp_to_edge + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp_to_edge", 28)) + { + ret = GLEW_ARB_texture_mirror_clamp_to_edge; + continue; + } +#endif +#ifdef GL_ARB_texture_mirrored_repeat + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) + { + ret = GLEW_ARB_texture_mirrored_repeat; + continue; + } +#endif +#ifdef GL_ARB_texture_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19)) + { + ret = GLEW_ARB_texture_multisample; + continue; + } +#endif +#ifdef GL_ARB_texture_non_power_of_two + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_non_power_of_two", 24)) + { + ret = GLEW_ARB_texture_non_power_of_two; + continue; + } +#endif +#ifdef GL_ARB_texture_query_levels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_levels", 20)) + { + ret = GLEW_ARB_texture_query_levels; + continue; + } +#endif +#ifdef GL_ARB_texture_query_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_lod", 17)) + { + ret = GLEW_ARB_texture_query_lod; + continue; + } +#endif +#ifdef GL_ARB_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_ARB_texture_rectangle; + continue; + } +#endif +#ifdef GL_ARB_texture_rg + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rg", 10)) + { + ret = GLEW_ARB_texture_rg; + continue; + } +#endif +#ifdef GL_ARB_texture_rgb10_a2ui + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rgb10_a2ui", 18)) + { + ret = GLEW_ARB_texture_rgb10_a2ui; + continue; + } +#endif +#ifdef GL_ARB_texture_stencil8 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stencil8", 16)) + { + ret = GLEW_ARB_texture_stencil8; + continue; + } +#endif +#ifdef GL_ARB_texture_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage", 15)) + { + ret = GLEW_ARB_texture_storage; + continue; + } +#endif +#ifdef GL_ARB_texture_storage_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage_multisample", 27)) + { + ret = GLEW_ARB_texture_storage_multisample; + continue; + } +#endif +#ifdef GL_ARB_texture_swizzle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15)) + { + ret = GLEW_ARB_texture_swizzle; + continue; + } +#endif +#ifdef GL_ARB_texture_view + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_view", 12)) + { + ret = GLEW_ARB_texture_view; + continue; + } +#endif +#ifdef GL_ARB_timer_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11)) + { + ret = GLEW_ARB_timer_query; + continue; + } +#endif +#ifdef GL_ARB_transform_feedback2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19)) + { + ret = GLEW_ARB_transform_feedback2; + continue; + } +#endif +#ifdef GL_ARB_transform_feedback3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback3", 19)) + { + ret = GLEW_ARB_transform_feedback3; + continue; + } +#endif +#ifdef GL_ARB_transform_feedback_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback_instanced", 28)) + { + ret = GLEW_ARB_transform_feedback_instanced; + continue; + } +#endif +#ifdef GL_ARB_transform_feedback_overflow_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback_overflow_query", 33)) + { + ret = GLEW_ARB_transform_feedback_overflow_query; + continue; + } +#endif +#ifdef GL_ARB_transpose_matrix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transpose_matrix", 16)) + { + ret = GLEW_ARB_transpose_matrix; + continue; + } +#endif +#ifdef GL_ARB_uniform_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"uniform_buffer_object", 21)) + { + ret = GLEW_ARB_uniform_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_array_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17)) + { + ret = GLEW_ARB_vertex_array_bgra; + continue; + } +#endif +#ifdef GL_ARB_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_ARB_vertex_array_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_attrib_64bit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_64bit", 19)) + { + ret = GLEW_ARB_vertex_attrib_64bit; + continue; + } +#endif +#ifdef GL_ARB_vertex_attrib_binding + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_binding", 21)) + { + ret = GLEW_ARB_vertex_attrib_binding; + continue; + } +#endif +#ifdef GL_ARB_vertex_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_blend", 12)) + { + ret = GLEW_ARB_vertex_blend; + continue; + } +#endif +#ifdef GL_ARB_vertex_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20)) + { + ret = GLEW_ARB_vertex_buffer_object; + continue; + } +#endif +#ifdef GL_ARB_vertex_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) + { + ret = GLEW_ARB_vertex_program; + continue; + } +#endif +#ifdef GL_ARB_vertex_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) + { + ret = GLEW_ARB_vertex_shader; + continue; + } +#endif +#ifdef GL_ARB_vertex_type_10f_11f_11f_rev + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_type_10f_11f_11f_rev", 27)) + { + ret = GLEW_ARB_vertex_type_10f_11f_11f_rev; + continue; + } +#endif +#ifdef GL_ARB_vertex_type_2_10_10_10_rev + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_type_2_10_10_10_rev", 26)) + { + ret = GLEW_ARB_vertex_type_2_10_10_10_rev; + continue; + } +#endif +#ifdef GL_ARB_viewport_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_array", 14)) + { + ret = GLEW_ARB_viewport_array; + continue; + } +#endif +#ifdef GL_ARB_window_pos + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) + { + ret = GLEW_ARB_window_pos; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARM_", 4)) + { +#ifdef GL_ARM_mali_program_binary + if (_glewStrSame3(&pos, &len, (const GLubyte*)"mali_program_binary", 19)) + { + ret = GLEW_ARM_mali_program_binary; + continue; + } +#endif +#ifdef GL_ARM_mali_shader_binary + if (_glewStrSame3(&pos, &len, (const GLubyte*)"mali_shader_binary", 18)) + { + ret = GLEW_ARM_mali_shader_binary; + continue; + } +#endif +#ifdef GL_ARM_rgba8 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rgba8", 5)) + { + ret = GLEW_ARM_rgba8; + continue; + } +#endif +#ifdef GL_ARM_shader_framebuffer_fetch + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_framebuffer_fetch", 24)) + { + ret = GLEW_ARM_shader_framebuffer_fetch; + continue; + } +#endif +#ifdef GL_ARM_shader_framebuffer_fetch_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_framebuffer_fetch_depth_stencil", 38)) + { + ret = GLEW_ARM_shader_framebuffer_fetch_depth_stencil; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATIX_", 5)) + { +#ifdef GL_ATIX_point_sprites + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprites", 13)) + { + ret = GLEW_ATIX_point_sprites; + continue; + } +#endif +#ifdef GL_ATIX_texture_env_combine3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) + { + ret = GLEW_ATIX_texture_env_combine3; + continue; + } +#endif +#ifdef GL_ATIX_texture_env_route + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_route", 17)) + { + ret = GLEW_ATIX_texture_env_route; + continue; + } +#endif +#ifdef GL_ATIX_vertex_shader_output_point_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_output_point_size", 31)) + { + ret = GLEW_ATIX_vertex_shader_output_point_size; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4)) + { +#ifdef GL_ATI_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_ATI_draw_buffers; + continue; + } +#endif +#ifdef GL_ATI_element_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13)) + { + ret = GLEW_ATI_element_array; + continue; + } +#endif +#ifdef GL_ATI_envmap_bumpmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"envmap_bumpmap", 14)) + { + ret = GLEW_ATI_envmap_bumpmap; + continue; + } +#endif +#ifdef GL_ATI_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15)) + { + ret = GLEW_ATI_fragment_shader; + continue; + } +#endif +#ifdef GL_ATI_map_object_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_object_buffer", 17)) + { + ret = GLEW_ATI_map_object_buffer; + continue; + } +#endif +#ifdef GL_ATI_meminfo + if (_glewStrSame3(&pos, &len, (const GLubyte*)"meminfo", 7)) + { + ret = GLEW_ATI_meminfo; + continue; + } +#endif +#ifdef GL_ATI_pn_triangles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pn_triangles", 12)) + { + ret = GLEW_ATI_pn_triangles; + continue; + } +#endif +#ifdef GL_ATI_separate_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_stencil", 16)) + { + ret = GLEW_ATI_separate_stencil; + continue; + } +#endif +#ifdef GL_ATI_shader_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18)) + { + ret = GLEW_ATI_shader_texture_lod; + continue; + } +#endif +#ifdef GL_ATI_text_fragment_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"text_fragment_shader", 20)) + { + ret = GLEW_ATI_text_fragment_shader; + continue; + } +#endif +#ifdef GL_ATI_texture_compression_3dc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_3dc", 23)) + { + ret = GLEW_ATI_texture_compression_3dc; + continue; + } +#endif +#ifdef GL_ATI_texture_env_combine3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20)) + { + ret = GLEW_ATI_texture_env_combine3; + continue; + } +#endif +#ifdef GL_ATI_texture_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13)) + { + ret = GLEW_ATI_texture_float; + continue; + } +#endif +#ifdef GL_ATI_texture_mirror_once + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_once", 19)) + { + ret = GLEW_ATI_texture_mirror_once; + continue; + } +#endif +#ifdef GL_ATI_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_ATI_vertex_array_object; + continue; + } +#endif +#ifdef GL_ATI_vertex_attrib_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_array_object", 26)) + { + ret = GLEW_ATI_vertex_attrib_array_object; + continue; + } +#endif +#ifdef GL_ATI_vertex_streams + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_streams", 14)) + { + ret = GLEW_ATI_vertex_streams; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EGL_", 4)) + { +#ifdef GL_EGL_KHR_context_flush_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"KHR_context_flush_control", 25)) + { + ret = GLEW_EGL_KHR_context_flush_control; + continue; + } +#endif +#ifdef GL_EGL_NV_robustness_video_memory_purge + if (_glewStrSame3(&pos, &len, (const GLubyte*)"NV_robustness_video_memory_purge", 32)) + { + ret = GLEW_EGL_NV_robustness_video_memory_purge; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4)) + { +#ifdef GL_EXT_422_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"422_pixels", 10)) + { + ret = GLEW_EXT_422_pixels; + continue; + } +#endif +#ifdef GL_EXT_Cg_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"Cg_shader", 9)) + { + ret = GLEW_EXT_Cg_shader; + continue; + } +#endif +#ifdef GL_EXT_EGL_image_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"EGL_image_array", 15)) + { + ret = GLEW_EXT_EGL_image_array; + continue; + } +#endif +#ifdef GL_EXT_YUV_target + if (_glewStrSame3(&pos, &len, (const GLubyte*)"YUV_target", 10)) + { + ret = GLEW_EXT_YUV_target; + continue; + } +#endif +#ifdef GL_EXT_abgr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"abgr", 4)) + { + ret = GLEW_EXT_abgr; + continue; + } +#endif +#ifdef GL_EXT_base_instance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"base_instance", 13)) + { + ret = GLEW_EXT_base_instance; + continue; + } +#endif +#ifdef GL_EXT_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgra", 4)) + { + ret = GLEW_EXT_bgra; + continue; + } +#endif +#ifdef GL_EXT_bindable_uniform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindable_uniform", 16)) + { + ret = GLEW_EXT_bindable_uniform; + continue; + } +#endif +#ifdef GL_EXT_blend_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_color", 11)) + { + ret = GLEW_EXT_blend_color; + continue; + } +#endif +#ifdef GL_EXT_blend_equation_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_separate", 23)) + { + ret = GLEW_EXT_blend_equation_separate; + continue; + } +#endif +#ifdef GL_EXT_blend_func_extended + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_extended", 19)) + { + ret = GLEW_EXT_blend_func_extended; + continue; + } +#endif +#ifdef GL_EXT_blend_func_separate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_separate", 19)) + { + ret = GLEW_EXT_blend_func_separate; + continue; + } +#endif +#ifdef GL_EXT_blend_logic_op + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_logic_op", 14)) + { + ret = GLEW_EXT_blend_logic_op; + continue; + } +#endif +#ifdef GL_EXT_blend_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax", 12)) + { + ret = GLEW_EXT_blend_minmax; + continue; + } +#endif +#ifdef GL_EXT_blend_subtract + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_subtract", 14)) + { + ret = GLEW_EXT_blend_subtract; + continue; + } +#endif +#ifdef GL_EXT_buffer_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_storage", 14)) + { + ret = GLEW_EXT_buffer_storage; + continue; + } +#endif +#ifdef GL_EXT_clear_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_texture", 13)) + { + ret = GLEW_EXT_clear_texture; + continue; + } +#endif +#ifdef GL_EXT_clip_cull_distance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_cull_distance", 18)) + { + ret = GLEW_EXT_clip_cull_distance; + continue; + } +#endif +#ifdef GL_EXT_clip_volume_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_volume_hint", 16)) + { + ret = GLEW_EXT_clip_volume_hint; + continue; + } +#endif +#ifdef GL_EXT_cmyka + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cmyka", 5)) + { + ret = GLEW_EXT_cmyka; + continue; + } +#endif +#ifdef GL_EXT_color_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18)) + { + ret = GLEW_EXT_color_buffer_float; + continue; + } +#endif +#ifdef GL_EXT_color_buffer_half_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_half_float", 23)) + { + ret = GLEW_EXT_color_buffer_half_float; + continue; + } +#endif +#ifdef GL_EXT_color_subtable + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_subtable", 14)) + { + ret = GLEW_EXT_color_subtable; + continue; + } +#endif +#ifdef GL_EXT_compiled_vertex_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compiled_vertex_array", 21)) + { + ret = GLEW_EXT_compiled_vertex_array; + continue; + } +#endif +#ifdef GL_EXT_compressed_ETC1_RGB8_sub_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_ETC1_RGB8_sub_texture", 32)) + { + ret = GLEW_EXT_compressed_ETC1_RGB8_sub_texture; + continue; + } +#endif +#ifdef GL_EXT_conservative_depth + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18)) + { + ret = GLEW_EXT_conservative_depth; + continue; + } +#endif +#ifdef GL_EXT_convolution + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution", 11)) + { + ret = GLEW_EXT_convolution; + continue; + } +#endif +#ifdef GL_EXT_coordinate_frame + if (_glewStrSame3(&pos, &len, (const GLubyte*)"coordinate_frame", 16)) + { + ret = GLEW_EXT_coordinate_frame; + continue; + } +#endif +#ifdef GL_EXT_copy_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10)) + { + ret = GLEW_EXT_copy_image; + continue; + } +#endif +#ifdef GL_EXT_copy_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture", 12)) + { + ret = GLEW_EXT_copy_texture; + continue; + } +#endif +#ifdef GL_EXT_cull_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) + { + ret = GLEW_EXT_cull_vertex; + continue; + } +#endif +#ifdef GL_EXT_debug_label + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_label", 11)) + { + ret = GLEW_EXT_debug_label; + continue; + } +#endif +#ifdef GL_EXT_debug_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_marker", 12)) + { + ret = GLEW_EXT_debug_marker; + continue; + } +#endif +#ifdef GL_EXT_depth_bounds_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_bounds_test", 17)) + { + ret = GLEW_EXT_depth_bounds_test; + continue; + } +#endif +#ifdef GL_EXT_direct_state_access + if (_glewStrSame3(&pos, &len, (const GLubyte*)"direct_state_access", 19)) + { + ret = GLEW_EXT_direct_state_access; + continue; + } +#endif +#ifdef GL_EXT_discard_framebuffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"discard_framebuffer", 19)) + { + ret = GLEW_EXT_discard_framebuffer; + continue; + } +#endif +#ifdef GL_EXT_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_EXT_draw_buffers; + continue; + } +#endif +#ifdef GL_EXT_draw_buffers2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers2", 13)) + { + ret = GLEW_EXT_draw_buffers2; + continue; + } +#endif +#ifdef GL_EXT_draw_buffers_indexed + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_indexed", 20)) + { + ret = GLEW_EXT_draw_buffers_indexed; + continue; + } +#endif +#ifdef GL_EXT_draw_elements_base_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_elements_base_vertex", 25)) + { + ret = GLEW_EXT_draw_elements_base_vertex; + continue; + } +#endif +#ifdef GL_EXT_draw_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) + { + ret = GLEW_EXT_draw_instanced; + continue; + } +#endif +#ifdef GL_EXT_draw_range_elements + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_range_elements", 19)) + { + ret = GLEW_EXT_draw_range_elements; + continue; + } +#endif +#ifdef GL_EXT_external_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"external_buffer", 15)) + { + ret = GLEW_EXT_external_buffer; + continue; + } +#endif +#ifdef GL_EXT_float_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_blend", 11)) + { + ret = GLEW_EXT_float_blend; + continue; + } +#endif +#ifdef GL_EXT_fog_coord + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_coord", 9)) + { + ret = GLEW_EXT_fog_coord; + continue; + } +#endif +#ifdef GL_EXT_frag_depth + if (_glewStrSame3(&pos, &len, (const GLubyte*)"frag_depth", 10)) + { + ret = GLEW_EXT_frag_depth; + continue; + } +#endif +#ifdef GL_EXT_fragment_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting", 17)) + { + ret = GLEW_EXT_fragment_lighting; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_blit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16)) + { + ret = GLEW_EXT_framebuffer_blit; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) + { + ret = GLEW_EXT_framebuffer_multisample; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_multisample_blit_scaled + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_blit_scaled", 35)) + { + ret = GLEW_EXT_framebuffer_multisample_blit_scaled; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18)) + { + ret = GLEW_EXT_framebuffer_object; + continue; + } +#endif +#ifdef GL_EXT_framebuffer_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16)) + { + ret = GLEW_EXT_framebuffer_sRGB; + continue; + } +#endif +#ifdef GL_EXT_geometry_point_size + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_point_size", 19)) + { + ret = GLEW_EXT_geometry_point_size; + continue; + } +#endif +#ifdef GL_EXT_geometry_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader", 15)) + { + ret = GLEW_EXT_geometry_shader; + continue; + } +#endif +#ifdef GL_EXT_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_EXT_geometry_shader4; + continue; + } +#endif +#ifdef GL_EXT_gpu_program_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_parameters", 22)) + { + ret = GLEW_EXT_gpu_program_parameters; + continue; + } +#endif +#ifdef GL_EXT_gpu_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader4", 11)) + { + ret = GLEW_EXT_gpu_shader4; + continue; + } +#endif +#ifdef GL_EXT_gpu_shader5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11)) + { + ret = GLEW_EXT_gpu_shader5; + continue; + } +#endif +#ifdef GL_EXT_histogram + if (_glewStrSame3(&pos, &len, (const GLubyte*)"histogram", 9)) + { + ret = GLEW_EXT_histogram; + continue; + } +#endif +#ifdef GL_EXT_index_array_formats + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_array_formats", 19)) + { + ret = GLEW_EXT_index_array_formats; + continue; + } +#endif +#ifdef GL_EXT_index_func + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_func", 10)) + { + ret = GLEW_EXT_index_func; + continue; + } +#endif +#ifdef GL_EXT_index_material + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_material", 14)) + { + ret = GLEW_EXT_index_material; + continue; + } +#endif +#ifdef GL_EXT_index_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_texture", 13)) + { + ret = GLEW_EXT_index_texture; + continue; + } +#endif +#ifdef GL_EXT_instanced_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16)) + { + ret = GLEW_EXT_instanced_arrays; + continue; + } +#endif +#ifdef GL_EXT_light_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_texture", 13)) + { + ret = GLEW_EXT_light_texture; + continue; + } +#endif +#ifdef GL_EXT_map_buffer_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_range", 16)) + { + ret = GLEW_EXT_map_buffer_range; + continue; + } +#endif +#ifdef GL_EXT_memory_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"memory_object", 13)) + { + ret = GLEW_EXT_memory_object; + continue; + } +#endif +#ifdef GL_EXT_memory_object_fd + if (_glewStrSame3(&pos, &len, (const GLubyte*)"memory_object_fd", 16)) + { + ret = GLEW_EXT_memory_object_fd; + continue; + } +#endif +#ifdef GL_EXT_memory_object_win32 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"memory_object_win32", 19)) + { + ret = GLEW_EXT_memory_object_win32; + continue; + } +#endif +#ifdef GL_EXT_misc_attribute + if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_attribute", 14)) + { + ret = GLEW_EXT_misc_attribute; + continue; + } +#endif +#ifdef GL_EXT_multi_draw_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_arrays", 17)) + { + ret = GLEW_EXT_multi_draw_arrays; + continue; + } +#endif +#ifdef GL_EXT_multi_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19)) + { + ret = GLEW_EXT_multi_draw_indirect; + continue; + } +#endif +#ifdef GL_EXT_multiple_textures + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiple_textures", 17)) + { + ret = GLEW_EXT_multiple_textures; + continue; + } +#endif +#ifdef GL_EXT_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_EXT_multisample; + continue; + } +#endif +#ifdef GL_EXT_multisample_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_compatibility", 25)) + { + ret = GLEW_EXT_multisample_compatibility; + continue; + } +#endif +#ifdef GL_EXT_multisampled_render_to_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisampled_render_to_texture", 30)) + { + ret = GLEW_EXT_multisampled_render_to_texture; + continue; + } +#endif +#ifdef GL_EXT_multisampled_render_to_texture2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisampled_render_to_texture2", 31)) + { + ret = GLEW_EXT_multisampled_render_to_texture2; + continue; + } +#endif +#ifdef GL_EXT_multiview_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview_draw_buffers", 22)) + { + ret = GLEW_EXT_multiview_draw_buffers; + continue; + } +#endif +#ifdef GL_EXT_packed_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) + { + ret = GLEW_EXT_packed_depth_stencil; + continue; + } +#endif +#ifdef GL_EXT_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float", 12)) + { + ret = GLEW_EXT_packed_float; + continue; + } +#endif +#ifdef GL_EXT_packed_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_pixels", 13)) + { + ret = GLEW_EXT_packed_pixels; + continue; + } +#endif +#ifdef GL_EXT_paletted_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"paletted_texture", 16)) + { + ret = GLEW_EXT_paletted_texture; + continue; + } +#endif +#ifdef GL_EXT_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_EXT_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_EXT_pixel_transform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform", 15)) + { + ret = GLEW_EXT_pixel_transform; + continue; + } +#endif +#ifdef GL_EXT_pixel_transform_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform_color_table", 27)) + { + ret = GLEW_EXT_pixel_transform_color_table; + continue; + } +#endif +#ifdef GL_EXT_point_parameters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16)) + { + ret = GLEW_EXT_point_parameters; + continue; + } +#endif +#ifdef GL_EXT_polygon_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset", 14)) + { + ret = GLEW_EXT_polygon_offset; + continue; + } +#endif +#ifdef GL_EXT_polygon_offset_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset_clamp", 20)) + { + ret = GLEW_EXT_polygon_offset_clamp; + continue; + } +#endif +#ifdef GL_EXT_post_depth_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"post_depth_coverage", 19)) + { + ret = GLEW_EXT_post_depth_coverage; + continue; + } +#endif +#ifdef GL_EXT_provoking_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16)) + { + ret = GLEW_EXT_provoking_vertex; + continue; + } +#endif +#ifdef GL_EXT_pvrtc_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pvrtc_sRGB", 10)) + { + ret = GLEW_EXT_pvrtc_sRGB; + continue; + } +#endif +#ifdef GL_EXT_raster_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"raster_multisample", 18)) + { + ret = GLEW_EXT_raster_multisample; + continue; + } +#endif +#ifdef GL_EXT_read_format_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_format_bgra", 16)) + { + ret = GLEW_EXT_read_format_bgra; + continue; + } +#endif +#ifdef GL_EXT_render_snorm + if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_snorm", 12)) + { + ret = GLEW_EXT_render_snorm; + continue; + } +#endif +#ifdef GL_EXT_rescale_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rescale_normal", 14)) + { + ret = GLEW_EXT_rescale_normal; + continue; + } +#endif +#ifdef GL_EXT_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sRGB", 4)) + { + ret = GLEW_EXT_sRGB; + continue; + } +#endif +#ifdef GL_EXT_sRGB_write_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sRGB_write_control", 18)) + { + ret = GLEW_EXT_sRGB_write_control; + continue; + } +#endif +#ifdef GL_EXT_scene_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12)) + { + ret = GLEW_EXT_scene_marker; + continue; + } +#endif +#ifdef GL_EXT_secondary_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"secondary_color", 15)) + { + ret = GLEW_EXT_secondary_color; + continue; + } +#endif +#ifdef GL_EXT_semaphore + if (_glewStrSame3(&pos, &len, (const GLubyte*)"semaphore", 9)) + { + ret = GLEW_EXT_semaphore; + continue; + } +#endif +#ifdef GL_EXT_semaphore_fd + if (_glewStrSame3(&pos, &len, (const GLubyte*)"semaphore_fd", 12)) + { + ret = GLEW_EXT_semaphore_fd; + continue; + } +#endif +#ifdef GL_EXT_semaphore_win32 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"semaphore_win32", 15)) + { + ret = GLEW_EXT_semaphore_win32; + continue; + } +#endif +#ifdef GL_EXT_separate_shader_objects + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23)) + { + ret = GLEW_EXT_separate_shader_objects; + continue; + } +#endif +#ifdef GL_EXT_separate_specular_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_specular_color", 23)) + { + ret = GLEW_EXT_separate_specular_color; + continue; + } +#endif +#ifdef GL_EXT_shader_framebuffer_fetch + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_framebuffer_fetch", 24)) + { + ret = GLEW_EXT_shader_framebuffer_fetch; + continue; + } +#endif +#ifdef GL_EXT_shader_group_vote + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_group_vote", 17)) + { + ret = GLEW_EXT_shader_group_vote; + continue; + } +#endif +#ifdef GL_EXT_shader_image_load_formatted + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_formatted", 27)) + { + ret = GLEW_EXT_shader_image_load_formatted; + continue; + } +#endif +#ifdef GL_EXT_shader_image_load_store + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_store", 23)) + { + ret = GLEW_EXT_shader_image_load_store; + continue; + } +#endif +#ifdef GL_EXT_shader_implicit_conversions + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_implicit_conversions", 27)) + { + ret = GLEW_EXT_shader_implicit_conversions; + continue; + } +#endif +#ifdef GL_EXT_shader_integer_mix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_integer_mix", 18)) + { + ret = GLEW_EXT_shader_integer_mix; + continue; + } +#endif +#ifdef GL_EXT_shader_io_blocks + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_io_blocks", 16)) + { + ret = GLEW_EXT_shader_io_blocks; + continue; + } +#endif +#ifdef GL_EXT_shader_non_constant_global_initializers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_non_constant_global_initializers", 39)) + { + ret = GLEW_EXT_shader_non_constant_global_initializers; + continue; + } +#endif +#ifdef GL_EXT_shader_pixel_local_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_pixel_local_storage", 26)) + { + ret = GLEW_EXT_shader_pixel_local_storage; + continue; + } +#endif +#ifdef GL_EXT_shader_pixel_local_storage2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_pixel_local_storage2", 27)) + { + ret = GLEW_EXT_shader_pixel_local_storage2; + continue; + } +#endif +#ifdef GL_EXT_shader_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18)) + { + ret = GLEW_EXT_shader_texture_lod; + continue; + } +#endif +#ifdef GL_EXT_shadow_funcs + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_funcs", 12)) + { + ret = GLEW_EXT_shadow_funcs; + continue; + } +#endif +#ifdef GL_EXT_shadow_samplers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_samplers", 15)) + { + ret = GLEW_EXT_shadow_samplers; + continue; + } +#endif +#ifdef GL_EXT_shared_texture_palette + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_texture_palette", 22)) + { + ret = GLEW_EXT_shared_texture_palette; + continue; + } +#endif +#ifdef GL_EXT_sparse_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14)) + { + ret = GLEW_EXT_sparse_texture; + continue; + } +#endif +#ifdef GL_EXT_sparse_texture2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture2", 15)) + { + ret = GLEW_EXT_sparse_texture2; + continue; + } +#endif +#ifdef GL_EXT_stencil_clear_tag + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_clear_tag", 17)) + { + ret = GLEW_EXT_stencil_clear_tag; + continue; + } +#endif +#ifdef GL_EXT_stencil_two_side + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_two_side", 16)) + { + ret = GLEW_EXT_stencil_two_side; + continue; + } +#endif +#ifdef GL_EXT_stencil_wrap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_wrap", 12)) + { + ret = GLEW_EXT_stencil_wrap; + continue; + } +#endif +#ifdef GL_EXT_subtexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subtexture", 10)) + { + ret = GLEW_EXT_subtexture; + continue; + } +#endif +#ifdef GL_EXT_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture", 7)) + { + ret = GLEW_EXT_texture; + continue; + } +#endif +#ifdef GL_EXT_texture3D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture3D", 9)) + { + ret = GLEW_EXT_texture3D; + continue; + } +#endif +#ifdef GL_EXT_texture_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_array", 13)) + { + ret = GLEW_EXT_texture_array; + continue; + } +#endif +#ifdef GL_EXT_texture_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21)) + { + ret = GLEW_EXT_texture_buffer_object; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_astc_decode_mode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_decode_mode", 36)) + { + ret = GLEW_EXT_texture_compression_astc_decode_mode; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_astc_decode_mode_rgb9e5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_decode_mode_rgb9e5", 43)) + { + ret = GLEW_EXT_texture_compression_astc_decode_mode_rgb9e5; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_bptc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_bptc", 24)) + { + ret = GLEW_EXT_texture_compression_bptc; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_dxt1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24)) + { + ret = GLEW_EXT_texture_compression_dxt1; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_latc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_latc", 24)) + { + ret = GLEW_EXT_texture_compression_latc; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_rgtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24)) + { + ret = GLEW_EXT_texture_compression_rgtc; + continue; + } +#endif +#ifdef GL_EXT_texture_compression_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24)) + { + ret = GLEW_EXT_texture_compression_s3tc; + continue; + } +#endif +#ifdef GL_EXT_texture_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16)) + { + ret = GLEW_EXT_texture_cube_map; + continue; + } +#endif +#ifdef GL_EXT_texture_cube_map_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map_array", 22)) + { + ret = GLEW_EXT_texture_cube_map_array; + continue; + } +#endif +#ifdef GL_EXT_texture_edge_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) + { + ret = GLEW_EXT_texture_edge_clamp; + continue; + } +#endif +#ifdef GL_EXT_texture_env + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env", 11)) + { + ret = GLEW_EXT_texture_env; + continue; + } +#endif +#ifdef GL_EXT_texture_env_add + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15)) + { + ret = GLEW_EXT_texture_env_add; + continue; + } +#endif +#ifdef GL_EXT_texture_env_combine + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19)) + { + ret = GLEW_EXT_texture_env_combine; + continue; + } +#endif +#ifdef GL_EXT_texture_env_dot3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16)) + { + ret = GLEW_EXT_texture_env_dot3; + continue; + } +#endif +#ifdef GL_EXT_texture_filter_anisotropic + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26)) + { + ret = GLEW_EXT_texture_filter_anisotropic; + continue; + } +#endif +#ifdef GL_EXT_texture_filter_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_minmax", 21)) + { + ret = GLEW_EXT_texture_filter_minmax; + continue; + } +#endif +#ifdef GL_EXT_texture_format_BGRA8888 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_format_BGRA8888", 23)) + { + ret = GLEW_EXT_texture_format_BGRA8888; + continue; + } +#endif +#ifdef GL_EXT_texture_integer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_integer", 15)) + { + ret = GLEW_EXT_texture_integer; + continue; + } +#endif +#ifdef GL_EXT_texture_lod_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) + { + ret = GLEW_EXT_texture_lod_bias; + continue; + } +#endif +#ifdef GL_EXT_texture_mirror_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp", 20)) + { + ret = GLEW_EXT_texture_mirror_clamp; + continue; + } +#endif +#ifdef GL_EXT_texture_norm16 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_norm16", 14)) + { + ret = GLEW_EXT_texture_norm16; + continue; + } +#endif +#ifdef GL_EXT_texture_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_object", 14)) + { + ret = GLEW_EXT_texture_object; + continue; + } +#endif +#ifdef GL_EXT_texture_perturb_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_perturb_normal", 22)) + { + ret = GLEW_EXT_texture_perturb_normal; + continue; + } +#endif +#ifdef GL_EXT_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_EXT_texture_rectangle; + continue; + } +#endif +#ifdef GL_EXT_texture_rg + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rg", 10)) + { + ret = GLEW_EXT_texture_rg; + continue; + } +#endif +#ifdef GL_EXT_texture_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB", 12)) + { + ret = GLEW_EXT_texture_sRGB; + continue; + } +#endif +#ifdef GL_EXT_texture_sRGB_R8 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB_R8", 15)) + { + ret = GLEW_EXT_texture_sRGB_R8; + continue; + } +#endif +#ifdef GL_EXT_texture_sRGB_RG8 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB_RG8", 16)) + { + ret = GLEW_EXT_texture_sRGB_RG8; + continue; + } +#endif +#ifdef GL_EXT_texture_sRGB_decode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB_decode", 19)) + { + ret = GLEW_EXT_texture_sRGB_decode; + continue; + } +#endif +#ifdef GL_EXT_texture_shared_exponent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shared_exponent", 23)) + { + ret = GLEW_EXT_texture_shared_exponent; + continue; + } +#endif +#ifdef GL_EXT_texture_snorm + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_snorm", 13)) + { + ret = GLEW_EXT_texture_snorm; + continue; + } +#endif +#ifdef GL_EXT_texture_storage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage", 15)) + { + ret = GLEW_EXT_texture_storage; + continue; + } +#endif +#ifdef GL_EXT_texture_swizzle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15)) + { + ret = GLEW_EXT_texture_swizzle; + continue; + } +#endif +#ifdef GL_EXT_texture_type_2_10_10_10_REV + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_type_2_10_10_10_REV", 27)) + { + ret = GLEW_EXT_texture_type_2_10_10_10_REV; + continue; + } +#endif +#ifdef GL_EXT_texture_view + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_view", 12)) + { + ret = GLEW_EXT_texture_view; + continue; + } +#endif +#ifdef GL_EXT_timer_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11)) + { + ret = GLEW_EXT_timer_query; + continue; + } +#endif +#ifdef GL_EXT_transform_feedback + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18)) + { + ret = GLEW_EXT_transform_feedback; + continue; + } +#endif +#ifdef GL_EXT_unpack_subimage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"unpack_subimage", 15)) + { + ret = GLEW_EXT_unpack_subimage; + continue; + } +#endif +#ifdef GL_EXT_vertex_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array", 12)) + { + ret = GLEW_EXT_vertex_array; + continue; + } +#endif +#ifdef GL_EXT_vertex_array_bgra + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17)) + { + ret = GLEW_EXT_vertex_array_bgra; + continue; + } +#endif +#ifdef GL_EXT_vertex_array_setXXX + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_setXXX", 19)) + { + ret = GLEW_EXT_vertex_array_setXXX; + continue; + } +#endif +#ifdef GL_EXT_vertex_attrib_64bit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_64bit", 19)) + { + ret = GLEW_EXT_vertex_attrib_64bit; + continue; + } +#endif +#ifdef GL_EXT_vertex_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13)) + { + ret = GLEW_EXT_vertex_shader; + continue; + } +#endif +#ifdef GL_EXT_vertex_weighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_weighting", 16)) + { + ret = GLEW_EXT_vertex_weighting; + continue; + } +#endif +#ifdef GL_EXT_win32_keyed_mutex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"win32_keyed_mutex", 17)) + { + ret = GLEW_EXT_win32_keyed_mutex; + continue; + } +#endif +#ifdef GL_EXT_window_rectangles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_rectangles", 17)) + { + ret = GLEW_EXT_window_rectangles; + continue; + } +#endif +#ifdef GL_EXT_x11_sync_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"x11_sync_object", 15)) + { + ret = GLEW_EXT_x11_sync_object; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"GREMEDY_", 8)) + { +#ifdef GL_GREMEDY_frame_terminator + if (_glewStrSame3(&pos, &len, (const GLubyte*)"frame_terminator", 16)) + { + ret = GLEW_GREMEDY_frame_terminator; + continue; + } +#endif +#ifdef GL_GREMEDY_string_marker + if (_glewStrSame3(&pos, &len, (const GLubyte*)"string_marker", 13)) + { + ret = GLEW_GREMEDY_string_marker; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"HP_", 3)) + { +#ifdef GL_HP_convolution_border_modes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) + { + ret = GLEW_HP_convolution_border_modes; + continue; + } +#endif +#ifdef GL_HP_image_transform + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_transform", 15)) + { + ret = GLEW_HP_image_transform; + continue; + } +#endif +#ifdef GL_HP_occlusion_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_test", 14)) + { + ret = GLEW_HP_occlusion_test; + continue; + } +#endif +#ifdef GL_HP_texture_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lighting", 16)) + { + ret = GLEW_HP_texture_lighting; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"IBM_", 4)) + { +#ifdef GL_IBM_cull_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11)) + { + ret = GLEW_IBM_cull_vertex; + continue; + } +#endif +#ifdef GL_IBM_multimode_draw_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multimode_draw_arrays", 21)) + { + ret = GLEW_IBM_multimode_draw_arrays; + continue; + } +#endif +#ifdef GL_IBM_rasterpos_clip + if (_glewStrSame3(&pos, &len, (const GLubyte*)"rasterpos_clip", 14)) + { + ret = GLEW_IBM_rasterpos_clip; + continue; + } +#endif +#ifdef GL_IBM_static_data + if (_glewStrSame3(&pos, &len, (const GLubyte*)"static_data", 11)) + { + ret = GLEW_IBM_static_data; + continue; + } +#endif +#ifdef GL_IBM_texture_mirrored_repeat + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23)) + { + ret = GLEW_IBM_texture_mirrored_repeat; + continue; + } +#endif +#ifdef GL_IBM_vertex_array_lists + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_lists", 18)) + { + ret = GLEW_IBM_vertex_array_lists; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"INGR_", 5)) + { +#ifdef GL_INGR_color_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_clamp", 11)) + { + ret = GLEW_INGR_color_clamp; + continue; + } +#endif +#ifdef GL_INGR_interlace_read + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace_read", 14)) + { + ret = GLEW_INGR_interlace_read; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6)) + { +#ifdef GL_INTEL_conservative_rasterization + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_rasterization", 26)) + { + ret = GLEW_INTEL_conservative_rasterization; + continue; + } +#endif +#ifdef GL_INTEL_fragment_shader_ordering + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader_ordering", 24)) + { + ret = GLEW_INTEL_fragment_shader_ordering; + continue; + } +#endif +#ifdef GL_INTEL_framebuffer_CMAA + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_CMAA", 16)) + { + ret = GLEW_INTEL_framebuffer_CMAA; + continue; + } +#endif +#ifdef GL_INTEL_map_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_texture", 11)) + { + ret = GLEW_INTEL_map_texture; + continue; + } +#endif +#ifdef GL_INTEL_parallel_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_arrays", 15)) + { + ret = GLEW_INTEL_parallel_arrays; + continue; + } +#endif +#ifdef GL_INTEL_performance_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"performance_query", 17)) + { + ret = GLEW_INTEL_performance_query; + continue; + } +#endif +#ifdef GL_INTEL_texture_scissor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scissor", 15)) + { + ret = GLEW_INTEL_texture_scissor; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"KHR_", 4)) + { +#ifdef GL_KHR_blend_equation_advanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced", 23)) + { + ret = GLEW_KHR_blend_equation_advanced; + continue; + } +#endif +#ifdef GL_KHR_blend_equation_advanced_coherent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_coherent", 32)) + { + ret = GLEW_KHR_blend_equation_advanced_coherent; + continue; + } +#endif +#ifdef GL_KHR_context_flush_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"context_flush_control", 21)) + { + ret = GLEW_KHR_context_flush_control; + continue; + } +#endif +#ifdef GL_KHR_debug + if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug", 5)) + { + ret = GLEW_KHR_debug; + continue; + } +#endif +#ifdef GL_KHR_no_error + if (_glewStrSame3(&pos, &len, (const GLubyte*)"no_error", 8)) + { + ret = GLEW_KHR_no_error; + continue; + } +#endif +#ifdef GL_KHR_parallel_shader_compile + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_shader_compile", 23)) + { + ret = GLEW_KHR_parallel_shader_compile; + continue; + } +#endif +#ifdef GL_KHR_robust_buffer_access_behavior + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robust_buffer_access_behavior", 29)) + { + ret = GLEW_KHR_robust_buffer_access_behavior; + continue; + } +#endif +#ifdef GL_KHR_robustness + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness", 10)) + { + ret = GLEW_KHR_robustness; + continue; + } +#endif +#ifdef GL_KHR_texture_compression_astc_hdr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_hdr", 28)) + { + ret = GLEW_KHR_texture_compression_astc_hdr; + continue; + } +#endif +#ifdef GL_KHR_texture_compression_astc_ldr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_ldr", 28)) + { + ret = GLEW_KHR_texture_compression_astc_ldr; + continue; + } +#endif +#ifdef GL_KHR_texture_compression_astc_sliced_3d + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_sliced_3d", 34)) + { + ret = GLEW_KHR_texture_compression_astc_sliced_3d; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"KTX_", 4)) + { +#ifdef GL_KTX_buffer_region + if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13)) + { + ret = GLEW_KTX_buffer_region; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESAX_", 6)) + { +#ifdef GL_MESAX_texture_stack + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stack", 13)) + { + ret = GLEW_MESAX_texture_stack; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5)) + { +#ifdef GL_MESA_pack_invert + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_invert", 11)) + { + ret = GLEW_MESA_pack_invert; + continue; + } +#endif +#ifdef GL_MESA_resize_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resize_buffers", 14)) + { + ret = GLEW_MESA_resize_buffers; + continue; + } +#endif +#ifdef GL_MESA_shader_integer_functions + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_integer_functions", 24)) + { + ret = GLEW_MESA_shader_integer_functions; + continue; + } +#endif +#ifdef GL_MESA_window_pos + if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10)) + { + ret = GLEW_MESA_window_pos; + continue; + } +#endif +#ifdef GL_MESA_ycbcr_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_texture", 13)) + { + ret = GLEW_MESA_ycbcr_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NVX_", 4)) + { +#ifdef GL_NVX_blend_equation_advanced_multi_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_multi_draw_buffers", 42)) + { + ret = GLEW_NVX_blend_equation_advanced_multi_draw_buffers; + continue; + } +#endif +#ifdef GL_NVX_conditional_render + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18)) + { + ret = GLEW_NVX_conditional_render; + continue; + } +#endif +#ifdef GL_NVX_gpu_memory_info + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_memory_info", 15)) + { + ret = GLEW_NVX_gpu_memory_info; + continue; + } +#endif +#ifdef GL_NVX_linked_gpu_multicast + if (_glewStrSame3(&pos, &len, (const GLubyte*)"linked_gpu_multicast", 20)) + { + ret = GLEW_NVX_linked_gpu_multicast; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3)) + { +#ifdef GL_NV_3dvision_settings + if (_glewStrSame3(&pos, &len, (const GLubyte*)"3dvision_settings", 17)) + { + ret = GLEW_NV_3dvision_settings; + continue; + } +#endif +#ifdef GL_NV_EGL_stream_consumer_external + if (_glewStrSame3(&pos, &len, (const GLubyte*)"EGL_stream_consumer_external", 28)) + { + ret = GLEW_NV_EGL_stream_consumer_external; + continue; + } +#endif +#ifdef GL_NV_alpha_to_coverage_dither_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"alpha_to_coverage_dither_control", 32)) + { + ret = GLEW_NV_alpha_to_coverage_dither_control; + continue; + } +#endif +#ifdef GL_NV_bgr + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgr", 3)) + { + ret = GLEW_NV_bgr; + continue; + } +#endif +#ifdef GL_NV_bindless_multi_draw_indirect + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_multi_draw_indirect", 28)) + { + ret = GLEW_NV_bindless_multi_draw_indirect; + continue; + } +#endif +#ifdef GL_NV_bindless_multi_draw_indirect_count + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_multi_draw_indirect_count", 34)) + { + ret = GLEW_NV_bindless_multi_draw_indirect_count; + continue; + } +#endif +#ifdef GL_NV_bindless_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_texture", 16)) + { + ret = GLEW_NV_bindless_texture; + continue; + } +#endif +#ifdef GL_NV_blend_equation_advanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced", 23)) + { + ret = GLEW_NV_blend_equation_advanced; + continue; + } +#endif +#ifdef GL_NV_blend_equation_advanced_coherent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_coherent", 32)) + { + ret = GLEW_NV_blend_equation_advanced_coherent; + continue; + } +#endif +#ifdef GL_NV_blend_minmax_factor + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax_factor", 19)) + { + ret = GLEW_NV_blend_minmax_factor; + continue; + } +#endif +#ifdef GL_NV_blend_square + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_square", 12)) + { + ret = GLEW_NV_blend_square; + continue; + } +#endif +#ifdef GL_NV_clip_space_w_scaling + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_space_w_scaling", 20)) + { + ret = GLEW_NV_clip_space_w_scaling; + continue; + } +#endif +#ifdef GL_NV_command_list + if (_glewStrSame3(&pos, &len, (const GLubyte*)"command_list", 12)) + { + ret = GLEW_NV_command_list; + continue; + } +#endif +#ifdef GL_NV_compute_program5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_program5", 16)) + { + ret = GLEW_NV_compute_program5; + continue; + } +#endif +#ifdef GL_NV_conditional_render + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18)) + { + ret = GLEW_NV_conditional_render; + continue; + } +#endif +#ifdef GL_NV_conservative_raster + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_raster", 19)) + { + ret = GLEW_NV_conservative_raster; + continue; + } +#endif +#ifdef GL_NV_conservative_raster_dilate + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_raster_dilate", 26)) + { + ret = GLEW_NV_conservative_raster_dilate; + continue; + } +#endif +#ifdef GL_NV_conservative_raster_pre_snap_triangles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_raster_pre_snap_triangles", 38)) + { + ret = GLEW_NV_conservative_raster_pre_snap_triangles; + continue; + } +#endif +#ifdef GL_NV_copy_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_buffer", 11)) + { + ret = GLEW_NV_copy_buffer; + continue; + } +#endif +#ifdef GL_NV_copy_depth_to_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_depth_to_color", 19)) + { + ret = GLEW_NV_copy_depth_to_color; + continue; + } +#endif +#ifdef GL_NV_copy_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10)) + { + ret = GLEW_NV_copy_image; + continue; + } +#endif +#ifdef GL_NV_deep_texture3D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"deep_texture3D", 14)) + { + ret = GLEW_NV_deep_texture3D; + continue; + } +#endif +#ifdef GL_NV_depth_buffer_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18)) + { + ret = GLEW_NV_depth_buffer_float; + continue; + } +#endif +#ifdef GL_NV_depth_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11)) + { + ret = GLEW_NV_depth_clamp; + continue; + } +#endif +#ifdef GL_NV_depth_range_unclamped + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_range_unclamped", 21)) + { + ret = GLEW_NV_depth_range_unclamped; + continue; + } +#endif +#ifdef GL_NV_draw_buffers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12)) + { + ret = GLEW_NV_draw_buffers; + continue; + } +#endif +#ifdef GL_NV_draw_instanced + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14)) + { + ret = GLEW_NV_draw_instanced; + continue; + } +#endif +#ifdef GL_NV_draw_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_texture", 12)) + { + ret = GLEW_NV_draw_texture; + continue; + } +#endif +#ifdef GL_NV_draw_vulkan_image + if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_vulkan_image", 17)) + { + ret = GLEW_NV_draw_vulkan_image; + continue; + } +#endif +#ifdef GL_NV_evaluators + if (_glewStrSame3(&pos, &len, (const GLubyte*)"evaluators", 10)) + { + ret = GLEW_NV_evaluators; + continue; + } +#endif +#ifdef GL_NV_explicit_attrib_location + if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_attrib_location", 24)) + { + ret = GLEW_NV_explicit_attrib_location; + continue; + } +#endif +#ifdef GL_NV_explicit_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_multisample", 20)) + { + ret = GLEW_NV_explicit_multisample; + continue; + } +#endif +#ifdef GL_NV_fbo_color_attachments + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbo_color_attachments", 21)) + { + ret = GLEW_NV_fbo_color_attachments; + continue; + } +#endif +#ifdef GL_NV_fence + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5)) + { + ret = GLEW_NV_fence; + continue; + } +#endif +#ifdef GL_NV_fill_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fill_rectangle", 14)) + { + ret = GLEW_NV_fill_rectangle; + continue; + } +#endif +#ifdef GL_NV_float_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12)) + { + ret = GLEW_NV_float_buffer; + continue; + } +#endif +#ifdef GL_NV_fog_distance + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_distance", 12)) + { + ret = GLEW_NV_fog_distance; + continue; + } +#endif +#ifdef GL_NV_fragment_coverage_to_color + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_coverage_to_color", 26)) + { + ret = GLEW_NV_fragment_coverage_to_color; + continue; + } +#endif +#ifdef GL_NV_fragment_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16)) + { + ret = GLEW_NV_fragment_program; + continue; + } +#endif +#ifdef GL_NV_fragment_program2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program2", 17)) + { + ret = GLEW_NV_fragment_program2; + continue; + } +#endif +#ifdef GL_NV_fragment_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program4", 17)) + { + ret = GLEW_NV_fragment_program4; + continue; + } +#endif +#ifdef GL_NV_fragment_program_option + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_option", 23)) + { + ret = GLEW_NV_fragment_program_option; + continue; + } +#endif +#ifdef GL_NV_fragment_shader_interlock + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader_interlock", 25)) + { + ret = GLEW_NV_fragment_shader_interlock; + continue; + } +#endif +#ifdef GL_NV_framebuffer_blit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16)) + { + ret = GLEW_NV_framebuffer_blit; + continue; + } +#endif +#ifdef GL_NV_framebuffer_mixed_samples + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_mixed_samples", 25)) + { + ret = GLEW_NV_framebuffer_mixed_samples; + continue; + } +#endif +#ifdef GL_NV_framebuffer_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23)) + { + ret = GLEW_NV_framebuffer_multisample; + continue; + } +#endif +#ifdef GL_NV_framebuffer_multisample_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_coverage", 32)) + { + ret = GLEW_NV_framebuffer_multisample_coverage; + continue; + } +#endif +#ifdef GL_NV_generate_mipmap_sRGB + if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap_sRGB", 20)) + { + ret = GLEW_NV_generate_mipmap_sRGB; + continue; + } +#endif +#ifdef GL_NV_geometry_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_program4", 17)) + { + ret = GLEW_NV_geometry_program4; + continue; + } +#endif +#ifdef GL_NV_geometry_shader4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16)) + { + ret = GLEW_NV_geometry_shader4; + continue; + } +#endif +#ifdef GL_NV_geometry_shader_passthrough + if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader_passthrough", 27)) + { + ret = GLEW_NV_geometry_shader_passthrough; + continue; + } +#endif +#ifdef GL_NV_gpu_multicast + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_multicast", 13)) + { + ret = GLEW_NV_gpu_multicast; + continue; + } +#endif +#ifdef GL_NV_gpu_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program4", 12)) + { + ret = GLEW_NV_gpu_program4; + continue; + } +#endif +#ifdef GL_NV_gpu_program5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program5", 12)) + { + ret = GLEW_NV_gpu_program5; + continue; + } +#endif +#ifdef GL_NV_gpu_program5_mem_extended + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program5_mem_extended", 25)) + { + ret = GLEW_NV_gpu_program5_mem_extended; + continue; + } +#endif +#ifdef GL_NV_gpu_program_fp64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_fp64", 16)) + { + ret = GLEW_NV_gpu_program_fp64; + continue; + } +#endif +#ifdef GL_NV_gpu_shader5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11)) + { + ret = GLEW_NV_gpu_shader5; + continue; + } +#endif +#ifdef GL_NV_half_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float", 10)) + { + ret = GLEW_NV_half_float; + continue; + } +#endif +#ifdef GL_NV_image_formats + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_formats", 13)) + { + ret = GLEW_NV_image_formats; + continue; + } +#endif +#ifdef GL_NV_instanced_arrays + if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16)) + { + ret = GLEW_NV_instanced_arrays; + continue; + } +#endif +#ifdef GL_NV_internalformat_sample_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_sample_query", 27)) + { + ret = GLEW_NV_internalformat_sample_query; + continue; + } +#endif +#ifdef GL_NV_light_max_exponent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_max_exponent", 18)) + { + ret = GLEW_NV_light_max_exponent; + continue; + } +#endif +#ifdef GL_NV_multisample_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20)) + { + ret = GLEW_NV_multisample_coverage; + continue; + } +#endif +#ifdef GL_NV_multisample_filter_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_filter_hint", 23)) + { + ret = GLEW_NV_multisample_filter_hint; + continue; + } +#endif +#ifdef GL_NV_non_square_matrices + if (_glewStrSame3(&pos, &len, (const GLubyte*)"non_square_matrices", 19)) + { + ret = GLEW_NV_non_square_matrices; + continue; + } +#endif +#ifdef GL_NV_occlusion_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15)) + { + ret = GLEW_NV_occlusion_query; + continue; + } +#endif +#ifdef GL_NV_pack_subimage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_subimage", 13)) + { + ret = GLEW_NV_pack_subimage; + continue; + } +#endif +#ifdef GL_NV_packed_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20)) + { + ret = GLEW_NV_packed_depth_stencil; + continue; + } +#endif +#ifdef GL_NV_packed_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float", 12)) + { + ret = GLEW_NV_packed_float; + continue; + } +#endif +#ifdef GL_NV_packed_float_linear + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float_linear", 19)) + { + ret = GLEW_NV_packed_float_linear; + continue; + } +#endif +#ifdef GL_NV_parameter_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object", 23)) + { + ret = GLEW_NV_parameter_buffer_object; + continue; + } +#endif +#ifdef GL_NV_parameter_buffer_object2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object2", 24)) + { + ret = GLEW_NV_parameter_buffer_object2; + continue; + } +#endif +#ifdef GL_NV_path_rendering + if (_glewStrSame3(&pos, &len, (const GLubyte*)"path_rendering", 14)) + { + ret = GLEW_NV_path_rendering; + continue; + } +#endif +#ifdef GL_NV_path_rendering_shared_edge + if (_glewStrSame3(&pos, &len, (const GLubyte*)"path_rendering_shared_edge", 26)) + { + ret = GLEW_NV_path_rendering_shared_edge; + continue; + } +#endif +#ifdef GL_NV_pixel_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19)) + { + ret = GLEW_NV_pixel_buffer_object; + continue; + } +#endif +#ifdef GL_NV_pixel_data_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_data_range", 16)) + { + ret = GLEW_NV_pixel_data_range; + continue; + } +#endif +#ifdef GL_NV_platform_binary + if (_glewStrSame3(&pos, &len, (const GLubyte*)"platform_binary", 15)) + { + ret = GLEW_NV_platform_binary; + continue; + } +#endif +#ifdef GL_NV_point_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12)) + { + ret = GLEW_NV_point_sprite; + continue; + } +#endif +#ifdef GL_NV_polygon_mode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_mode", 12)) + { + ret = GLEW_NV_polygon_mode; + continue; + } +#endif +#ifdef GL_NV_present_video + if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13)) + { + ret = GLEW_NV_present_video; + continue; + } +#endif +#ifdef GL_NV_primitive_restart + if (_glewStrSame3(&pos, &len, (const GLubyte*)"primitive_restart", 17)) + { + ret = GLEW_NV_primitive_restart; + continue; + } +#endif +#ifdef GL_NV_read_depth + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_depth", 10)) + { + ret = GLEW_NV_read_depth; + continue; + } +#endif +#ifdef GL_NV_read_depth_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_depth_stencil", 18)) + { + ret = GLEW_NV_read_depth_stencil; + continue; + } +#endif +#ifdef GL_NV_read_stencil + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_stencil", 12)) + { + ret = GLEW_NV_read_stencil; + continue; + } +#endif +#ifdef GL_NV_register_combiners + if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners", 18)) + { + ret = GLEW_NV_register_combiners; + continue; + } +#endif +#ifdef GL_NV_register_combiners2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners2", 19)) + { + ret = GLEW_NV_register_combiners2; + continue; + } +#endif +#ifdef GL_NV_robustness_video_memory_purge + if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_video_memory_purge", 29)) + { + ret = GLEW_NV_robustness_video_memory_purge; + continue; + } +#endif +#ifdef GL_NV_sRGB_formats + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sRGB_formats", 12)) + { + ret = GLEW_NV_sRGB_formats; + continue; + } +#endif +#ifdef GL_NV_sample_locations + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_locations", 16)) + { + ret = GLEW_NV_sample_locations; + continue; + } +#endif +#ifdef GL_NV_sample_mask_override_coverage + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_mask_override_coverage", 29)) + { + ret = GLEW_NV_sample_mask_override_coverage; + continue; + } +#endif +#ifdef GL_NV_shader_atomic_counters + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counters", 22)) + { + ret = GLEW_NV_shader_atomic_counters; + continue; + } +#endif +#ifdef GL_NV_shader_atomic_float + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_float", 19)) + { + ret = GLEW_NV_shader_atomic_float; + continue; + } +#endif +#ifdef GL_NV_shader_atomic_float64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_float64", 21)) + { + ret = GLEW_NV_shader_atomic_float64; + continue; + } +#endif +#ifdef GL_NV_shader_atomic_fp16_vector + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_fp16_vector", 25)) + { + ret = GLEW_NV_shader_atomic_fp16_vector; + continue; + } +#endif +#ifdef GL_NV_shader_atomic_int64 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_int64", 19)) + { + ret = GLEW_NV_shader_atomic_int64; + continue; + } +#endif +#ifdef GL_NV_shader_buffer_load + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_buffer_load", 18)) + { + ret = GLEW_NV_shader_buffer_load; + continue; + } +#endif +#ifdef GL_NV_shader_noperspective_interpolation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_noperspective_interpolation", 34)) + { + ret = GLEW_NV_shader_noperspective_interpolation; + continue; + } +#endif +#ifdef GL_NV_shader_storage_buffer_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_storage_buffer_object", 28)) + { + ret = GLEW_NV_shader_storage_buffer_object; + continue; + } +#endif +#ifdef GL_NV_shader_thread_group + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_thread_group", 19)) + { + ret = GLEW_NV_shader_thread_group; + continue; + } +#endif +#ifdef GL_NV_shader_thread_shuffle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_thread_shuffle", 21)) + { + ret = GLEW_NV_shader_thread_shuffle; + continue; + } +#endif +#ifdef GL_NV_shadow_samplers_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_samplers_array", 21)) + { + ret = GLEW_NV_shadow_samplers_array; + continue; + } +#endif +#ifdef GL_NV_shadow_samplers_cube + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_samplers_cube", 20)) + { + ret = GLEW_NV_shadow_samplers_cube; + continue; + } +#endif +#ifdef GL_NV_stereo_view_rendering + if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_view_rendering", 21)) + { + ret = GLEW_NV_stereo_view_rendering; + continue; + } +#endif +#ifdef GL_NV_tessellation_program5 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_program5", 21)) + { + ret = GLEW_NV_tessellation_program5; + continue; + } +#endif +#ifdef GL_NV_texgen_emboss + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_emboss", 13)) + { + ret = GLEW_NV_texgen_emboss; + continue; + } +#endif +#ifdef GL_NV_texgen_reflection + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_reflection", 17)) + { + ret = GLEW_NV_texgen_reflection; + continue; + } +#endif +#ifdef GL_NV_texture_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_array", 13)) + { + ret = GLEW_NV_texture_array; + continue; + } +#endif +#ifdef GL_NV_texture_barrier + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_barrier", 15)) + { + ret = GLEW_NV_texture_barrier; + continue; + } +#endif +#ifdef GL_NV_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_NV_texture_border_clamp; + continue; + } +#endif +#ifdef GL_NV_texture_compression_latc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_latc", 24)) + { + ret = GLEW_NV_texture_compression_latc; + continue; + } +#endif +#ifdef GL_NV_texture_compression_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24)) + { + ret = GLEW_NV_texture_compression_s3tc; + continue; + } +#endif +#ifdef GL_NV_texture_compression_s3tc_update + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc_update", 31)) + { + ret = GLEW_NV_texture_compression_s3tc_update; + continue; + } +#endif +#ifdef GL_NV_texture_compression_vtc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_vtc", 23)) + { + ret = GLEW_NV_texture_compression_vtc; + continue; + } +#endif +#ifdef GL_NV_texture_env_combine4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine4", 20)) + { + ret = GLEW_NV_texture_env_combine4; + continue; + } +#endif +#ifdef GL_NV_texture_expand_normal + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_expand_normal", 21)) + { + ret = GLEW_NV_texture_expand_normal; + continue; + } +#endif +#ifdef GL_NV_texture_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19)) + { + ret = GLEW_NV_texture_multisample; + continue; + } +#endif +#ifdef GL_NV_texture_npot_2D_mipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_npot_2D_mipmap", 22)) + { + ret = GLEW_NV_texture_npot_2D_mipmap; + continue; + } +#endif +#ifdef GL_NV_texture_rectangle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17)) + { + ret = GLEW_NV_texture_rectangle; + continue; + } +#endif +#ifdef GL_NV_texture_rectangle_compressed + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle_compressed", 28)) + { + ret = GLEW_NV_texture_rectangle_compressed; + continue; + } +#endif +#ifdef GL_NV_texture_shader + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader", 14)) + { + ret = GLEW_NV_texture_shader; + continue; + } +#endif +#ifdef GL_NV_texture_shader2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader2", 15)) + { + ret = GLEW_NV_texture_shader2; + continue; + } +#endif +#ifdef GL_NV_texture_shader3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader3", 15)) + { + ret = GLEW_NV_texture_shader3; + continue; + } +#endif +#ifdef GL_NV_transform_feedback + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18)) + { + ret = GLEW_NV_transform_feedback; + continue; + } +#endif +#ifdef GL_NV_transform_feedback2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19)) + { + ret = GLEW_NV_transform_feedback2; + continue; + } +#endif +#ifdef GL_NV_uniform_buffer_unified_memory + if (_glewStrSame3(&pos, &len, (const GLubyte*)"uniform_buffer_unified_memory", 29)) + { + ret = GLEW_NV_uniform_buffer_unified_memory; + continue; + } +#endif +#ifdef GL_NV_vdpau_interop + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vdpau_interop", 13)) + { + ret = GLEW_NV_vdpau_interop; + continue; + } +#endif +#ifdef GL_NV_vertex_array_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18)) + { + ret = GLEW_NV_vertex_array_range; + continue; + } +#endif +#ifdef GL_NV_vertex_array_range2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range2", 19)) + { + ret = GLEW_NV_vertex_array_range2; + continue; + } +#endif +#ifdef GL_NV_vertex_attrib_integer_64bit + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_integer_64bit", 27)) + { + ret = GLEW_NV_vertex_attrib_integer_64bit; + continue; + } +#endif +#ifdef GL_NV_vertex_buffer_unified_memory + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_unified_memory", 28)) + { + ret = GLEW_NV_vertex_buffer_unified_memory; + continue; + } +#endif +#ifdef GL_NV_vertex_program + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14)) + { + ret = GLEW_NV_vertex_program; + continue; + } +#endif +#ifdef GL_NV_vertex_program1_1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program1_1", 17)) + { + ret = GLEW_NV_vertex_program1_1; + continue; + } +#endif +#ifdef GL_NV_vertex_program2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2", 15)) + { + ret = GLEW_NV_vertex_program2; + continue; + } +#endif +#ifdef GL_NV_vertex_program2_option + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2_option", 22)) + { + ret = GLEW_NV_vertex_program2_option; + continue; + } +#endif +#ifdef GL_NV_vertex_program3 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program3", 15)) + { + ret = GLEW_NV_vertex_program3; + continue; + } +#endif +#ifdef GL_NV_vertex_program4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program4", 15)) + { + ret = GLEW_NV_vertex_program4; + continue; + } +#endif +#ifdef GL_NV_video_capture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13)) + { + ret = GLEW_NV_video_capture; + continue; + } +#endif +#ifdef GL_NV_viewport_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_array", 14)) + { + ret = GLEW_NV_viewport_array; + continue; + } +#endif +#ifdef GL_NV_viewport_array2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_array2", 15)) + { + ret = GLEW_NV_viewport_array2; + continue; + } +#endif +#ifdef GL_NV_viewport_swizzle + if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_swizzle", 16)) + { + ret = GLEW_NV_viewport_swizzle; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OES_", 4)) + { +#ifdef GL_OES_byte_coordinates + if (_glewStrSame3(&pos, &len, (const GLubyte*)"byte_coordinates", 16)) + { + ret = GLEW_OES_byte_coordinates; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4)) + { +#ifdef GL_OML_interlace + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) + { + ret = GLEW_OML_interlace; + continue; + } +#endif +#ifdef GL_OML_resample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) + { + ret = GLEW_OML_resample; + continue; + } +#endif +#ifdef GL_OML_subsample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9)) + { + ret = GLEW_OML_subsample; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"OVR_", 4)) + { +#ifdef GL_OVR_multiview + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview", 9)) + { + ret = GLEW_OVR_multiview; + continue; + } +#endif +#ifdef GL_OVR_multiview2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview2", 10)) + { + ret = GLEW_OVR_multiview2; + continue; + } +#endif +#ifdef GL_OVR_multiview_multisampled_render_to_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multiview_multisampled_render_to_texture", 40)) + { + ret = GLEW_OVR_multiview_multisampled_render_to_texture; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"PGI_", 4)) + { +#ifdef GL_PGI_misc_hints + if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_hints", 10)) + { + ret = GLEW_PGI_misc_hints; + continue; + } +#endif +#ifdef GL_PGI_vertex_hints + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_hints", 12)) + { + ret = GLEW_PGI_vertex_hints; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"QCOM_", 5)) + { +#ifdef GL_QCOM_alpha_test + if (_glewStrSame3(&pos, &len, (const GLubyte*)"alpha_test", 10)) + { + ret = GLEW_QCOM_alpha_test; + continue; + } +#endif +#ifdef GL_QCOM_binning_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"binning_control", 15)) + { + ret = GLEW_QCOM_binning_control; + continue; + } +#endif +#ifdef GL_QCOM_driver_control + if (_glewStrSame3(&pos, &len, (const GLubyte*)"driver_control", 14)) + { + ret = GLEW_QCOM_driver_control; + continue; + } +#endif +#ifdef GL_QCOM_extended_get + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extended_get", 12)) + { + ret = GLEW_QCOM_extended_get; + continue; + } +#endif +#ifdef GL_QCOM_extended_get2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extended_get2", 13)) + { + ret = GLEW_QCOM_extended_get2; + continue; + } +#endif +#ifdef GL_QCOM_framebuffer_foveated + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_foveated", 20)) + { + ret = GLEW_QCOM_framebuffer_foveated; + continue; + } +#endif +#ifdef GL_QCOM_perfmon_global_mode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"perfmon_global_mode", 19)) + { + ret = GLEW_QCOM_perfmon_global_mode; + continue; + } +#endif +#ifdef GL_QCOM_shader_framebuffer_fetch_noncoherent + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_framebuffer_fetch_noncoherent", 36)) + { + ret = GLEW_QCOM_shader_framebuffer_fetch_noncoherent; + continue; + } +#endif +#ifdef GL_QCOM_tiled_rendering + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tiled_rendering", 15)) + { + ret = GLEW_QCOM_tiled_rendering; + continue; + } +#endif +#ifdef GL_QCOM_writeonly_rendering + if (_glewStrSame3(&pos, &len, (const GLubyte*)"writeonly_rendering", 19)) + { + ret = GLEW_QCOM_writeonly_rendering; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"REGAL_", 6)) + { +#ifdef GL_REGAL_ES1_0_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES1_0_compatibility", 19)) + { + ret = GLEW_REGAL_ES1_0_compatibility; + continue; + } +#endif +#ifdef GL_REGAL_ES1_1_compatibility + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES1_1_compatibility", 19)) + { + ret = GLEW_REGAL_ES1_1_compatibility; + continue; + } +#endif +#ifdef GL_REGAL_enable + if (_glewStrSame3(&pos, &len, (const GLubyte*)"enable", 6)) + { + ret = GLEW_REGAL_enable; + continue; + } +#endif +#ifdef GL_REGAL_error_string + if (_glewStrSame3(&pos, &len, (const GLubyte*)"error_string", 12)) + { + ret = GLEW_REGAL_error_string; + continue; + } +#endif +#ifdef GL_REGAL_extension_query + if (_glewStrSame3(&pos, &len, (const GLubyte*)"extension_query", 15)) + { + ret = GLEW_REGAL_extension_query; + continue; + } +#endif +#ifdef GL_REGAL_log + if (_glewStrSame3(&pos, &len, (const GLubyte*)"log", 3)) + { + ret = GLEW_REGAL_log; + continue; + } +#endif +#ifdef GL_REGAL_proc_address + if (_glewStrSame3(&pos, &len, (const GLubyte*)"proc_address", 12)) + { + ret = GLEW_REGAL_proc_address; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"REND_", 5)) + { +#ifdef GL_REND_screen_coordinates + if (_glewStrSame3(&pos, &len, (const GLubyte*)"screen_coordinates", 18)) + { + ret = GLEW_REND_screen_coordinates; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"S3_", 3)) + { +#ifdef GL_S3_s3tc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"s3tc", 4)) + { + ret = GLEW_S3_s3tc; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5)) + { +#ifdef GL_SGIS_clip_band_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_band_hint", 14)) + { + ret = GLEW_SGIS_clip_band_hint; + continue; + } +#endif +#ifdef GL_SGIS_color_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11)) + { + ret = GLEW_SGIS_color_range; + continue; + } +#endif +#ifdef GL_SGIS_detail_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"detail_texture", 14)) + { + ret = GLEW_SGIS_detail_texture; + continue; + } +#endif +#ifdef GL_SGIS_fog_function + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_function", 12)) + { + ret = GLEW_SGIS_fog_function; + continue; + } +#endif +#ifdef GL_SGIS_generate_mipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap", 15)) + { + ret = GLEW_SGIS_generate_mipmap; + continue; + } +#endif +#ifdef GL_SGIS_line_texgen + if (_glewStrSame3(&pos, &len, (const GLubyte*)"line_texgen", 11)) + { + ret = GLEW_SGIS_line_texgen; + continue; + } +#endif +#ifdef GL_SGIS_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11)) + { + ret = GLEW_SGIS_multisample; + continue; + } +#endif +#ifdef GL_SGIS_multitexture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12)) + { + ret = GLEW_SGIS_multitexture; + continue; + } +#endif +#ifdef GL_SGIS_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) + { + ret = GLEW_SGIS_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIS_point_line_texgen + if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_line_texgen", 17)) + { + ret = GLEW_SGIS_point_line_texgen; + continue; + } +#endif +#ifdef GL_SGIS_shared_multisample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_multisample", 18)) + { + ret = GLEW_SGIS_shared_multisample; + continue; + } +#endif +#ifdef GL_SGIS_sharpen_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sharpen_texture", 15)) + { + ret = GLEW_SGIS_sharpen_texture; + continue; + } +#endif +#ifdef GL_SGIS_texture4D + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture4D", 9)) + { + ret = GLEW_SGIS_texture4D; + continue; + } +#endif +#ifdef GL_SGIS_texture_border_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20)) + { + ret = GLEW_SGIS_texture_border_clamp; + continue; + } +#endif +#ifdef GL_SGIS_texture_edge_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18)) + { + ret = GLEW_SGIS_texture_edge_clamp; + continue; + } +#endif +#ifdef GL_SGIS_texture_filter4 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter4", 15)) + { + ret = GLEW_SGIS_texture_filter4; + continue; + } +#endif +#ifdef GL_SGIS_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod", 11)) + { + ret = GLEW_SGIS_texture_lod; + continue; + } +#endif +#ifdef GL_SGIS_texture_select + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_select", 14)) + { + ret = GLEW_SGIS_texture_select; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5)) + { +#ifdef GL_SGIX_async + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async", 5)) + { + ret = GLEW_SGIX_async; + continue; + } +#endif +#ifdef GL_SGIX_async_histogram + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_histogram", 15)) + { + ret = GLEW_SGIX_async_histogram; + continue; + } +#endif +#ifdef GL_SGIX_async_pixel + if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_pixel", 11)) + { + ret = GLEW_SGIX_async_pixel; + continue; + } +#endif +#ifdef GL_SGIX_bali_g_instruments + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bali_g_instruments", 18)) + { + ret = GLEW_SGIX_bali_g_instruments; + continue; + } +#endif +#ifdef GL_SGIX_bali_r_instruments + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bali_r_instruments", 18)) + { + ret = GLEW_SGIX_bali_r_instruments; + continue; + } +#endif +#ifdef GL_SGIX_bali_timer_instruments + if (_glewStrSame3(&pos, &len, (const GLubyte*)"bali_timer_instruments", 22)) + { + ret = GLEW_SGIX_bali_timer_instruments; + continue; + } +#endif +#ifdef GL_SGIX_blend_alpha_minmax + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_alpha_minmax", 18)) + { + ret = GLEW_SGIX_blend_alpha_minmax; + continue; + } +#endif +#ifdef GL_SGIX_blend_cadd + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_cadd", 10)) + { + ret = GLEW_SGIX_blend_cadd; + continue; + } +#endif +#ifdef GL_SGIX_blend_cmultiply + if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_cmultiply", 15)) + { + ret = GLEW_SGIX_blend_cmultiply; + continue; + } +#endif +#ifdef GL_SGIX_calligraphic_fragment + if (_glewStrSame3(&pos, &len, (const GLubyte*)"calligraphic_fragment", 21)) + { + ret = GLEW_SGIX_calligraphic_fragment; + continue; + } +#endif +#ifdef GL_SGIX_clipmap + if (_glewStrSame3(&pos, &len, (const GLubyte*)"clipmap", 7)) + { + ret = GLEW_SGIX_clipmap; + continue; + } +#endif +#ifdef GL_SGIX_color_matrix_accuracy + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix_accuracy", 21)) + { + ret = GLEW_SGIX_color_matrix_accuracy; + continue; + } +#endif +#ifdef GL_SGIX_color_table_index_mode + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table_index_mode", 22)) + { + ret = GLEW_SGIX_color_table_index_mode; + continue; + } +#endif +#ifdef GL_SGIX_complex_polar + if (_glewStrSame3(&pos, &len, (const GLubyte*)"complex_polar", 13)) + { + ret = GLEW_SGIX_complex_polar; + continue; + } +#endif +#ifdef GL_SGIX_convolution_accuracy + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_accuracy", 20)) + { + ret = GLEW_SGIX_convolution_accuracy; + continue; + } +#endif +#ifdef GL_SGIX_cube_map + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cube_map", 8)) + { + ret = GLEW_SGIX_cube_map; + continue; + } +#endif +#ifdef GL_SGIX_cylinder_texgen + if (_glewStrSame3(&pos, &len, (const GLubyte*)"cylinder_texgen", 15)) + { + ret = GLEW_SGIX_cylinder_texgen; + continue; + } +#endif +#ifdef GL_SGIX_datapipe + if (_glewStrSame3(&pos, &len, (const GLubyte*)"datapipe", 8)) + { + ret = GLEW_SGIX_datapipe; + continue; + } +#endif +#ifdef GL_SGIX_decimation + if (_glewStrSame3(&pos, &len, (const GLubyte*)"decimation", 10)) + { + ret = GLEW_SGIX_decimation; + continue; + } +#endif +#ifdef GL_SGIX_depth_pass_instrument + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_pass_instrument", 21)) + { + ret = GLEW_SGIX_depth_pass_instrument; + continue; + } +#endif +#ifdef GL_SGIX_depth_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13)) + { + ret = GLEW_SGIX_depth_texture; + continue; + } +#endif +#ifdef GL_SGIX_dvc + if (_glewStrSame3(&pos, &len, (const GLubyte*)"dvc", 3)) + { + ret = GLEW_SGIX_dvc; + continue; + } +#endif +#ifdef GL_SGIX_flush_raster + if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_raster", 12)) + { + ret = GLEW_SGIX_flush_raster; + continue; + } +#endif +#ifdef GL_SGIX_fog_blend + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_blend", 9)) + { + ret = GLEW_SGIX_fog_blend; + continue; + } +#endif +#ifdef GL_SGIX_fog_factor_to_alpha + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_factor_to_alpha", 19)) + { + ret = GLEW_SGIX_fog_factor_to_alpha; + continue; + } +#endif +#ifdef GL_SGIX_fog_layers + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_layers", 10)) + { + ret = GLEW_SGIX_fog_layers; + continue; + } +#endif +#ifdef GL_SGIX_fog_offset + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_offset", 10)) + { + ret = GLEW_SGIX_fog_offset; + continue; + } +#endif +#ifdef GL_SGIX_fog_patchy + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_patchy", 10)) + { + ret = GLEW_SGIX_fog_patchy; + continue; + } +#endif +#ifdef GL_SGIX_fog_scale + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_scale", 9)) + { + ret = GLEW_SGIX_fog_scale; + continue; + } +#endif +#ifdef GL_SGIX_fog_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_texture", 11)) + { + ret = GLEW_SGIX_fog_texture; + continue; + } +#endif +#ifdef GL_SGIX_fragment_lighting_space + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting_space", 23)) + { + ret = GLEW_SGIX_fragment_lighting_space; + continue; + } +#endif +#ifdef GL_SGIX_fragment_specular_lighting + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_specular_lighting", 26)) + { + ret = GLEW_SGIX_fragment_specular_lighting; + continue; + } +#endif +#ifdef GL_SGIX_fragments_instrument + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragments_instrument", 20)) + { + ret = GLEW_SGIX_fragments_instrument; + continue; + } +#endif +#ifdef GL_SGIX_framezoom + if (_glewStrSame3(&pos, &len, (const GLubyte*)"framezoom", 9)) + { + ret = GLEW_SGIX_framezoom; + continue; + } +#endif +#ifdef GL_SGIX_icc_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"icc_texture", 11)) + { + ret = GLEW_SGIX_icc_texture; + continue; + } +#endif +#ifdef GL_SGIX_igloo_interface + if (_glewStrSame3(&pos, &len, (const GLubyte*)"igloo_interface", 15)) + { + ret = GLEW_SGIX_igloo_interface; + continue; + } +#endif +#ifdef GL_SGIX_image_compression + if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_compression", 17)) + { + ret = GLEW_SGIX_image_compression; + continue; + } +#endif +#ifdef GL_SGIX_impact_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"impact_pixel_texture", 20)) + { + ret = GLEW_SGIX_impact_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIX_instrument_error + if (_glewStrSame3(&pos, &len, (const GLubyte*)"instrument_error", 16)) + { + ret = GLEW_SGIX_instrument_error; + continue; + } +#endif +#ifdef GL_SGIX_interlace + if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9)) + { + ret = GLEW_SGIX_interlace; + continue; + } +#endif +#ifdef GL_SGIX_ir_instrument1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ir_instrument1", 14)) + { + ret = GLEW_SGIX_ir_instrument1; + continue; + } +#endif +#ifdef GL_SGIX_line_quality_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"line_quality_hint", 17)) + { + ret = GLEW_SGIX_line_quality_hint; + continue; + } +#endif +#ifdef GL_SGIX_list_priority + if (_glewStrSame3(&pos, &len, (const GLubyte*)"list_priority", 13)) + { + ret = GLEW_SGIX_list_priority; + continue; + } +#endif +#ifdef GL_SGIX_mpeg1 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"mpeg1", 5)) + { + ret = GLEW_SGIX_mpeg1; + continue; + } +#endif +#ifdef GL_SGIX_mpeg2 + if (_glewStrSame3(&pos, &len, (const GLubyte*)"mpeg2", 5)) + { + ret = GLEW_SGIX_mpeg2; + continue; + } +#endif +#ifdef GL_SGIX_nonlinear_lighting_pervertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"nonlinear_lighting_pervertex", 28)) + { + ret = GLEW_SGIX_nonlinear_lighting_pervertex; + continue; + } +#endif +#ifdef GL_SGIX_nurbs_eval + if (_glewStrSame3(&pos, &len, (const GLubyte*)"nurbs_eval", 10)) + { + ret = GLEW_SGIX_nurbs_eval; + continue; + } +#endif +#ifdef GL_SGIX_occlusion_instrument + if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_instrument", 20)) + { + ret = GLEW_SGIX_occlusion_instrument; + continue; + } +#endif +#ifdef GL_SGIX_packed_6bytes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_6bytes", 13)) + { + ret = GLEW_SGIX_packed_6bytes; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13)) + { + ret = GLEW_SGIX_pixel_texture; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture_bits + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_bits", 18)) + { + ret = GLEW_SGIX_pixel_texture_bits; + continue; + } +#endif +#ifdef GL_SGIX_pixel_texture_lod + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_lod", 17)) + { + ret = GLEW_SGIX_pixel_texture_lod; + continue; + } +#endif +#ifdef GL_SGIX_pixel_tiles + if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_tiles", 11)) + { + ret = GLEW_SGIX_pixel_tiles; + continue; + } +#endif +#ifdef GL_SGIX_polynomial_ffd + if (_glewStrSame3(&pos, &len, (const GLubyte*)"polynomial_ffd", 14)) + { + ret = GLEW_SGIX_polynomial_ffd; + continue; + } +#endif +#ifdef GL_SGIX_quad_mesh + if (_glewStrSame3(&pos, &len, (const GLubyte*)"quad_mesh", 9)) + { + ret = GLEW_SGIX_quad_mesh; + continue; + } +#endif +#ifdef GL_SGIX_reference_plane + if (_glewStrSame3(&pos, &len, (const GLubyte*)"reference_plane", 15)) + { + ret = GLEW_SGIX_reference_plane; + continue; + } +#endif +#ifdef GL_SGIX_resample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8)) + { + ret = GLEW_SGIX_resample; + continue; + } +#endif +#ifdef GL_SGIX_scalebias_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scalebias_hint", 14)) + { + ret = GLEW_SGIX_scalebias_hint; + continue; + } +#endif +#ifdef GL_SGIX_shadow + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6)) + { + ret = GLEW_SGIX_shadow; + continue; + } +#endif +#ifdef GL_SGIX_shadow_ambient + if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14)) + { + ret = GLEW_SGIX_shadow_ambient; + continue; + } +#endif +#ifdef GL_SGIX_slim + if (_glewStrSame3(&pos, &len, (const GLubyte*)"slim", 4)) + { + ret = GLEW_SGIX_slim; + continue; + } +#endif +#ifdef GL_SGIX_spotlight_cutoff + if (_glewStrSame3(&pos, &len, (const GLubyte*)"spotlight_cutoff", 16)) + { + ret = GLEW_SGIX_spotlight_cutoff; + continue; + } +#endif +#ifdef GL_SGIX_sprite + if (_glewStrSame3(&pos, &len, (const GLubyte*)"sprite", 6)) + { + ret = GLEW_SGIX_sprite; + continue; + } +#endif +#ifdef GL_SGIX_subdiv_patch + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subdiv_patch", 12)) + { + ret = GLEW_SGIX_subdiv_patch; + continue; + } +#endif +#ifdef GL_SGIX_subsample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9)) + { + ret = GLEW_SGIX_subsample; + continue; + } +#endif +#ifdef GL_SGIX_tag_sample_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"tag_sample_buffer", 17)) + { + ret = GLEW_SGIX_tag_sample_buffer; + continue; + } +#endif +#ifdef GL_SGIX_texture_add_env + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_add_env", 15)) + { + ret = GLEW_SGIX_texture_add_env; + continue; + } +#endif +#ifdef GL_SGIX_texture_coordinate_clamp + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_coordinate_clamp", 24)) + { + ret = GLEW_SGIX_texture_coordinate_clamp; + continue; + } +#endif +#ifdef GL_SGIX_texture_lod_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16)) + { + ret = GLEW_SGIX_texture_lod_bias; + continue; + } +#endif +#ifdef GL_SGIX_texture_mipmap_anisotropic + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mipmap_anisotropic", 26)) + { + ret = GLEW_SGIX_texture_mipmap_anisotropic; + continue; + } +#endif +#ifdef GL_SGIX_texture_multi_buffer + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multi_buffer", 20)) + { + ret = GLEW_SGIX_texture_multi_buffer; + continue; + } +#endif +#ifdef GL_SGIX_texture_phase + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_phase", 13)) + { + ret = GLEW_SGIX_texture_phase; + continue; + } +#endif +#ifdef GL_SGIX_texture_range + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13)) + { + ret = GLEW_SGIX_texture_range; + continue; + } +#endif +#ifdef GL_SGIX_texture_scale_bias + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scale_bias", 18)) + { + ret = GLEW_SGIX_texture_scale_bias; + continue; + } +#endif +#ifdef GL_SGIX_texture_supersample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_supersample", 19)) + { + ret = GLEW_SGIX_texture_supersample; + continue; + } +#endif +#ifdef GL_SGIX_vector_ops + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vector_ops", 10)) + { + ret = GLEW_SGIX_vector_ops; + continue; + } +#endif +#ifdef GL_SGIX_vertex_array_object + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19)) + { + ret = GLEW_SGIX_vertex_array_object; + continue; + } +#endif +#ifdef GL_SGIX_vertex_preclip + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip", 14)) + { + ret = GLEW_SGIX_vertex_preclip; + continue; + } +#endif +#ifdef GL_SGIX_vertex_preclip_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip_hint", 19)) + { + ret = GLEW_SGIX_vertex_preclip_hint; + continue; + } +#endif +#ifdef GL_SGIX_ycrcb + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb", 5)) + { + ret = GLEW_SGIX_ycrcb; + continue; + } +#endif +#ifdef GL_SGIX_ycrcb_subsample + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb_subsample", 15)) + { + ret = GLEW_SGIX_ycrcb_subsample; + continue; + } +#endif +#ifdef GL_SGIX_ycrcba + if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcba", 6)) + { + ret = GLEW_SGIX_ycrcba; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4)) + { +#ifdef GL_SGI_color_matrix + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix", 12)) + { + ret = GLEW_SGI_color_matrix; + continue; + } +#endif +#ifdef GL_SGI_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table", 11)) + { + ret = GLEW_SGI_color_table; + continue; + } +#endif +#ifdef GL_SGI_complex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"complex", 7)) + { + ret = GLEW_SGI_complex; + continue; + } +#endif +#ifdef GL_SGI_complex_type + if (_glewStrSame3(&pos, &len, (const GLubyte*)"complex_type", 12)) + { + ret = GLEW_SGI_complex_type; + continue; + } +#endif +#ifdef GL_SGI_fft + if (_glewStrSame3(&pos, &len, (const GLubyte*)"fft", 3)) + { + ret = GLEW_SGI_fft; + continue; + } +#endif +#ifdef GL_SGI_texture_color_table + if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_color_table", 19)) + { + ret = GLEW_SGI_texture_color_table; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUNX_", 5)) + { +#ifdef GL_SUNX_constant_data + if (_glewStrSame3(&pos, &len, (const GLubyte*)"constant_data", 13)) + { + ret = GLEW_SUNX_constant_data; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4)) + { +#ifdef GL_SUN_convolution_border_modes + if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24)) + { + ret = GLEW_SUN_convolution_border_modes; + continue; + } +#endif +#ifdef GL_SUN_global_alpha + if (_glewStrSame3(&pos, &len, (const GLubyte*)"global_alpha", 12)) + { + ret = GLEW_SUN_global_alpha; + continue; + } +#endif +#ifdef GL_SUN_mesh_array + if (_glewStrSame3(&pos, &len, (const GLubyte*)"mesh_array", 10)) + { + ret = GLEW_SUN_mesh_array; + continue; + } +#endif +#ifdef GL_SUN_read_video_pixels + if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_video_pixels", 17)) + { + ret = GLEW_SUN_read_video_pixels; + continue; + } +#endif +#ifdef GL_SUN_slice_accum + if (_glewStrSame3(&pos, &len, (const GLubyte*)"slice_accum", 11)) + { + ret = GLEW_SUN_slice_accum; + continue; + } +#endif +#ifdef GL_SUN_triangle_list + if (_glewStrSame3(&pos, &len, (const GLubyte*)"triangle_list", 13)) + { + ret = GLEW_SUN_triangle_list; + continue; + } +#endif +#ifdef GL_SUN_vertex + if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex", 6)) + { + ret = GLEW_SUN_vertex; + continue; + } +#endif + } + if (_glewStrSame2(&pos, &len, (const GLubyte*)"WIN_", 4)) + { +#ifdef GL_WIN_phong_shading + if (_glewStrSame3(&pos, &len, (const GLubyte*)"phong_shading", 13)) + { + ret = GLEW_WIN_phong_shading; + continue; + } +#endif +#ifdef GL_WIN_scene_markerXXX + if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_markerXXX", 15)) + { + ret = GLEW_WIN_scene_markerXXX; + continue; + } +#endif +#ifdef GL_WIN_specular_fog + if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_fog", 12)) + { + ret = GLEW_WIN_specular_fog; + continue; + } +#endif +#ifdef GL_WIN_swap_hint + if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_hint", 9)) + { + ret = GLEW_WIN_swap_hint; + continue; + } +#endif + } + } + ret = (len == 0); + } + return ret; +} From 04c15c82c9593633410de0fdd63dbd3e1139da70 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Jul 2020 21:22:47 -0700 Subject: [PATCH 226/848] Kernel: Add a bit more thread info on crash. --- Core/HLE/sceKernelThread.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index d892b2c1eb..427d537edf 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1183,7 +1183,8 @@ void __KernelThreadingShutdown() { } std::string __KernelThreadingSummary() { - return StringFromFormat("Cur thread: %s", __GetCurrentThread()->GetName()); + PSPThread *t = __GetCurrentThread(); + return StringFromFormat("Cur thread: %s (attr %08x)", t ? t->GetName() : "(null)", t ? t->nt.attr : 0); } const char *__KernelGetThreadName(SceUID threadID) From b071db9ec260b38c0c03f9f3345cf8cc4cd2d407 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Jul 2020 21:27:24 -0700 Subject: [PATCH 227/848] Core: Reset exception info on resume/reset. If you restart the game, it shouldn't still have this (will only show if you enter debugging, but still.) --- Core/Core.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/Core.cpp b/Core/Core.cpp index cf851e807e..e0434bb721 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -94,6 +94,7 @@ void Core_ListenStopRequest(CoreStopRequestFunc func) { } void Core_Stop() { + g_exceptionInfo.type = ExceptionType::NONE; Core_UpdateState(CORE_POWERDOWN); for (auto func : stopFuncs) { func(); @@ -264,6 +265,7 @@ void Core_UpdateSingleStep() { } void Core_SingleStep() { + g_exceptionInfo.type = ExceptionType::NONE; currentMIPS->SingleStep(); if (coreState == CORE_STEPPING) steppingCounter++; @@ -361,6 +363,8 @@ void Core_EnableStepping(bool step) { steppingCounter++; } else { host->SetDebugMode(false); + // Clear the exception if we resume. + g_exceptionInfo.type = ExceptionType::NONE; coreState = CORE_RUNNING; coreStatePending = false; m_StepCond.notify_all(); From 940066db68ffa10d143b37c6bfacaecf1eb34cf5 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Jul 2020 21:59:08 -0700 Subject: [PATCH 228/848] Core: Track exception on bad jumps. --- Core/Core.cpp | 26 ++++++++++++++++++++++++++ Core/Core.h | 9 +++++++++ Core/HLE/sceKernelThread.cpp | 34 ++++++++++++++++++++++++++++++++++ Core/MIPS/MIPSInt.cpp | 3 +++ Core/MIPS/MIPSTables.cpp | 3 ++- UI/EmuScreen.cpp | 9 +++++++++ 6 files changed, 83 insertions(+), 1 deletion(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index e0434bb721..ecc3d08259 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -404,6 +404,15 @@ const char *MemoryExceptionTypeAsString(MemoryExceptionType type) { } } +const char *ExecExceptionTypeAsString(ExecExceptionType type) { + switch (type) { + case ExecExceptionType::JUMP: return "CPU Jump"; + case ExecExceptionType::THREAD: return "Thread switch"; + default: + return "N/A"; + } +} + void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { const char *desc = MemoryExceptionTypeAsString(type); // In jit, we only flush PC when bIgnoreBadMemAccess is off. @@ -426,6 +435,23 @@ void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { } } +void Core_ExecException(u32 address, u32 pc, ExecExceptionType type) { + const char *desc = ExecExceptionTypeAsString(type); + WARN_LOG(MEMMAP, "%s: Invalid destination %08x PC %08x LR %08x", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); + + if (!g_Config.bIgnoreBadMemAccess) { + ExceptionInfo &e = g_exceptionInfo; + e = {}; + e.type = ExceptionType::BAD_EXEC_ADDR; + e.info = ""; + e.exec_type = type; + e.address = address; + e.pc = pc; + Core_EnableStepping(true); + host->SetDebugMode(true); + } +} + void Core_Break() { ERROR_LOG(CPU, "BREAK!"); diff --git a/Core/Core.h b/Core/Core.h index ef428595bd..6cb8004cf4 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -85,8 +85,13 @@ enum class MemoryExceptionType { READ_BLOCK, WRITE_BLOCK, }; +enum class ExecExceptionType { + JUMP, + THREAD, +}; void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type); +void Core_ExecException(u32 address, u32 pc, ExecExceptionType type); void Core_Break(); enum class ExceptionType { @@ -104,9 +109,13 @@ struct ExceptionInfo { MemoryExceptionType memory_type; uint32_t pc; uint32_t address; + + // Reuses pc and address from memory type, where address is the failed destination. + ExecExceptionType exec_type; }; const ExceptionInfo &Core_GetExceptionInfo(); const char *ExceptionTypeAsString(ExceptionType type); const char *MemoryExceptionTypeAsString(MemoryExceptionType type); +const char *ExecExceptionTypeAsString(ExecExceptionType type); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 427d537edf..2b4e998ba6 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -31,6 +31,7 @@ #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSDebugInterface.h" +#include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/MIPS/JitCommon/JitCommon.h" @@ -1142,6 +1143,10 @@ bool __KernelSwitchToThread(SceUID threadID, const char *reason) if (current && current->isRunning()) __KernelChangeReadyState(current, currentThread, true); + if (!Memory::IsValidAddress(t->context.pc)) { + Core_ExecException(t->context.pc, currentMIPS->pc, ExecExceptionType::THREAD); + } + __KernelSwitchContext(t, reason); return true; } @@ -1463,6 +1468,12 @@ void __KernelLoadContext(PSPThreadContext *ctx, bool vfpuEnabled) { memcpy(currentMIPS->vfpuCtrl, ctx->vfpuCtrl, sizeof(ctx->vfpuCtrl)); } +#ifdef _DEBUG + if (!Memory::IsValidAddress(ctx->pc)) { + Core_ExecException(ctx->pc, currentMIPS->pc, ExecExceptionType::THREAD); + } +#endif + memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other)); if (MIPSComp::jit) { // When thread switching, we must update the rounding mode if cached in the jit. @@ -1912,6 +1923,10 @@ SceUID __KernelSetupRootThread(SceUID moduleID, int args, const char *argp, int strcpy(thread->nt.name, "root"); + if (!Memory::IsValidAddress(thread->context.pc)) { + Core_ExecException(thread->context.pc, currentMIPS->pc, ExecExceptionType::THREAD); + } + __KernelLoadContext(&thread->context, (attr & PSP_THREAD_ATTR_VFPU) != 0); currentMIPS->r[MIPS_REG_A0] = args; currentMIPS->r[MIPS_REG_SP] -= (args + 0xf) & ~0xf; @@ -2041,6 +2056,9 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo // Smaller is better for priority. Only switch if the new thread is better. if (cur && cur->nt.currentPriority > startThread->nt.currentPriority) { + if (!Memory::IsValidAddress(startThread->context.pc)) { + Core_ExecException(startThread->context.pc, currentMIPS->pc, ExecExceptionType::THREAD); + } __KernelChangeReadyState(cur, currentThread, true); hleReSchedule("thread started"); } @@ -2903,6 +2921,10 @@ u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter) Memory::Write_U32(currentMIPS->r[MIPS_REG_SP], thread->currentStack.end - 8); Memory::Write_U32(currentMIPS->pc, thread->currentStack.end - 12); + if (!Memory::IsValidAddress(entryAddr)) { + Core_ExecException(entryAddr, currentMIPS->pc, ExecExceptionType::THREAD); + } + currentMIPS->pc = entryAddr; currentMIPS->r[MIPS_REG_A0] = entryParameter; currentMIPS->r[MIPS_REG_RA] = extendReturnHackAddr; @@ -2935,6 +2957,10 @@ void __KernelReturnFromExtendStack() return; } + if (!Memory::IsValidAddress(restorePC)) { + Core_ExecException(restorePC, currentMIPS->pc, ExecExceptionType::THREAD); + } + DEBUG_LOG(SCEKERNEL, "__KernelReturnFromExtendStack()"); currentMIPS->r[MIPS_REG_RA] = restoreRA; currentMIPS->r[MIPS_REG_SP] = restoreSP; @@ -3215,6 +3241,10 @@ bool __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter) call->savedId = cur->currentMipscallId; call->reschedAfter = reschedAfter; + if (!Memory::IsValidAddress(call->entryPoint)) { + Core_ExecException(call->entryPoint, currentMIPS->pc, ExecExceptionType::THREAD); + } + // Set up the new state currentMIPS->pc = call->entryPoint; currentMIPS->r[MIPS_REG_RA] = __KernelCallbackReturnAddress(); @@ -3264,6 +3294,10 @@ void __KernelReturnFromMipsCall() currentMIPS->r[MIPS_REG_RA] = Memory::Read_U32(sp + MIPS_REG_RA * 4); sp += 32 * 4; + if (!Memory::IsValidAddress(call->savedPc)) { + Core_ExecException(call->savedPc, currentMIPS->pc, ExecExceptionType::THREAD); + } + currentMIPS->pc = call->savedPc; // This is how we set the return value. currentMIPS->r[MIPS_REG_V0] = call->savedV0; diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index b8d99c078d..d562f97cde 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -54,6 +54,9 @@ static inline void DelayBranchTo(u32 where) { + if (!Memory::IsValidAddress(where)) { + Core_ExecException(where, PC, ExecExceptionType::JUMP); + } PC += 4; mipsr4k.nextPC = where; mipsr4k.inDelaySlot = true; diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 69e5d28afa..49f5b752b4 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -1019,13 +1019,14 @@ int MIPSInterpret_RunUntil(u64 globalTicks) if (curMips->inDelaySlot) { + curMips->downcount -= 1; // The reason we have to check this is the delay slot hack in Int_Syscall. if (wasInDelaySlot) { curMips->pc = curMips->nextPC; curMips->inDelaySlot = false; + continue; } - curMips->downcount -= 1; goto again; } } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 28c2159670..a17d0e4e65 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1305,6 +1305,15 @@ PC: %08x)", info.pc); draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); y += 120; + } else if (info.type == ExceptionType::BAD_EXEC_ADDR) { + snprintf(statbuf, sizeof(statbuf), R"( +Destination: %s to %08x +PC: %08x)", + ExecExceptionTypeAsString(info.exec_type), + info.address, + info.pc); + draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + y += 120; } std::string kernelState = __KernelStateSummary(); From d2ef6c561cc6137a03c9661d07389a58221cf281 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Jul 2020 22:03:16 -0700 Subject: [PATCH 229/848] UI: Allow non-ascii on crash dump screen. It's not really dynamic so there's no reason to flag it. That said, the draw buffer's text drawing doesn't support this flag anyway. --- UI/EmuScreen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index a17d0e4e65..80170e844b 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1293,7 +1293,7 @@ PPSSPP build: %s (%s) draw2d->SetFontScale(.7f, .7f); int x = 20; int y = 50; - draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); y += 100; if (info.type == ExceptionType::MEMORY) { @@ -1303,7 +1303,7 @@ PC: %08x)", MemoryExceptionTypeAsString(info.memory_type), info.address, info.pc); - draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); y += 120; } else if (info.type == ExceptionType::BAD_EXEC_ADDR) { snprintf(statbuf, sizeof(statbuf), R"( @@ -1312,13 +1312,13 @@ PC: %08x)", ExecExceptionTypeAsString(info.exec_type), info.address, info.pc); - draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); y += 120; } std::string kernelState = __KernelStateSummary(); - draw2d->DrawTextShadow(ubuntu24, kernelState.c_str(), x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + draw2d->DrawTextShadow(ubuntu24, kernelState.c_str(), x, y, 0xFFFFFFFF); } static void DrawAudioDebugStats(DrawBuffer *draw2d, const Bounds &bounds) { From 3c34c7c456816ab9e22fe953b8fa2457bfe904f6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Jul 2020 22:17:36 -0700 Subject: [PATCH 230/848] irjit: Add jump crash checks. Doesn't seem to have any significant impact on performance. --- Core/MIPS/IR/IRCompBranch.cpp | 3 +-- Core/MIPS/IR/IRJit.cpp | 4 ++++ Core/MIPS/MIPSInt.cpp | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/MIPS/IR/IRCompBranch.cpp b/Core/MIPS/IR/IRCompBranch.cpp index 20d352b5c1..76b89fd669 100644 --- a/Core/MIPS/IR/IRCompBranch.cpp +++ b/Core/MIPS/IR/IRCompBranch.cpp @@ -300,9 +300,8 @@ void IRFrontend::Comp_Jump(MIPSOpcode op) { js.cancel = true; else ERROR_LOG_REPORT(JIT, "Jump to invalid address: %08x", targetAddr); - js.compiling = false; // TODO: Mark this block dirty or something? May be indication it will be changed by imports. - return; + // Continue so the block gets completed and crashes properly. } switch (op >> 26) { diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index ec9a2fdabb..4922fc13f2 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -224,6 +224,10 @@ void IRJit::RunLoopUntil(u64 globalticks) { u32 data = inst & 0xFFFFFF; IRBlock *block = blocks_.GetBlock(data); mips_->pc = IRInterpret(mips_, block->GetInstructions(), block->GetNumInstructions()); + if (!Memory::IsValidAddress(mips_->pc)) { + Core_ExecException(mips_->pc, mips_->pc, ExecExceptionType::JUMP); + break; + } } else { // RestoreRoundingMode(true); Compile(mips_->pc); diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index d562f97cde..8d015de485 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -55,6 +55,7 @@ static inline void DelayBranchTo(u32 where) { if (!Memory::IsValidAddress(where)) { + // TODO: What about misaligned? Core_ExecException(where, PC, ExecExceptionType::JUMP); } PC += 4; From b3bf61dde1f7c7299db252d6afb6471ba7e9d962 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Jul 2020 22:31:39 -0700 Subject: [PATCH 231/848] x86jit: Trigger exec exceptions. A common case might be, you're hacking something in the game and you broke the stack, so you `jr ra` into outer space. --- Core/MIPS/x86/CompBranch.cpp | 13 ++++++++++++- Core/MIPS/x86/Jit.cpp | 17 ++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index 7d3a52091a..c18d9ae5d5 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -20,8 +20,9 @@ #include "profiler/profiler.h" -#include "Core/Reporting.h" #include "Core/Config.h" +#include "Core/Core.h" +#include "Core/Reporting.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" #include "Core/Host.h" @@ -591,6 +592,10 @@ void Jit::Comp_VBranch(MIPSOpcode op) } } +static void HitInvalidJump(uint32_t dest) { + Core_ExecException(dest, currentMIPS->pc - 8, ExecExceptionType::JUMP); +} + void Jit::Comp_Jump(MIPSOpcode op) { CONDITIONAL_LOG; if (js.inDelaySlot) { @@ -608,6 +613,12 @@ void Jit::Comp_Jump(MIPSOpcode op) { js.compiling = false; } // TODO: Mark this block dirty or something? May be indication it will be changed by imports. + + CompileDelaySlot(DELAYSLOT_NICE); + FlushAll(); + MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC() + 8)); + ABI_CallFunctionC((const void *)&HitInvalidJump, targetAddr); + WriteSyscallExit(); return; } diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index a9b24fa8a2..4629d57f3d 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -705,6 +705,11 @@ void Jit::WriteExit(u32 destination, int exit_num) { } } +static void HitInvalidJumpReg(uint32_t source) { + Core_ExecException(currentMIPS->pc, source, ExecExceptionType::JUMP); + currentMIPS->pc = source + 8; +} + void Jit::WriteExitDestInReg(X64Reg reg) { // If we need to verify coreState and rewind, we may not jump yet. if (js.afterOp & (JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE)) { @@ -741,15 +746,13 @@ void Jit::WriteExitDestInReg(X64Reg reg) { SetJumpTarget(tooLow); SetJumpTarget(tooHigh); - ABI_CallFunctionA((const void *)&Memory::GetPointer, R(reg)); + ABI_CallFunctionA((const void *)&Memory::IsValidAddress, R(reg)); // If we're ignoring, coreState didn't trip - so trip it now. - if (g_Config.bIgnoreBadMemAccess) { - CMP(32, R(EAX), Imm32(0)); - FixupBranch skip = J_CC(CC_NE); - ABI_CallFunctionA((const void *)&Core_UpdateState, Imm32(CORE_RUNTIME_ERROR)); - SetJumpTarget(skip); - } + CMP(32, R(EAX), Imm32(0)); + FixupBranch skip = J_CC(CC_NE); + ABI_CallFunctionC((const void *)&HitInvalidJumpReg, GetCompilerPC()); + SetJumpTarget(skip); SUB(32, MIPSSTATE_VAR(downcount), Imm8(0)); JMP(dispatcherCheckCoreState, true); From ae224b38933682f1a9628ab5150ddd43c00123af Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Jul 2020 22:53:42 -0700 Subject: [PATCH 232/848] jit: Add some basic checks in armjit/arm64jit. Just the simple (and unlikely) case so far... --- Core/MIPS/ARM/ArmCompBranch.cpp | 14 +++++++++++++- Core/MIPS/ARM/ArmJit.cpp | 2 ++ Core/MIPS/ARM64/Arm64CompBranch.cpp | 14 +++++++++++++- Core/MIPS/ARM64/Arm64Jit.cpp | 2 ++ Core/MIPS/x86/CompBranch.cpp | 2 +- Core/MIPS/x86/Jit.cpp | 9 ++++++++- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index af18735e82..2a0a67d90d 100644 --- a/Core/MIPS/ARM/ArmCompBranch.cpp +++ b/Core/MIPS/ARM/ArmCompBranch.cpp @@ -20,8 +20,9 @@ #include "profiler/profiler.h" -#include "Core/Reporting.h" #include "Core/Config.h" +#include "Core/Core.h" +#include "Core/Reporting.h" #include "Core/MemMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" @@ -446,6 +447,10 @@ void ArmJit::Comp_VBranch(MIPSOpcode op) } } +static void HitInvalidJump(uint32_t dest) { + Core_ExecException(dest, currentMIPS->pc - 8, ExecExceptionType::JUMP); +} + void ArmJit::Comp_Jump(MIPSOpcode op) { if (js.inDelaySlot) { ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); @@ -462,6 +467,13 @@ void ArmJit::Comp_Jump(MIPSOpcode op) { js.compiling = false; } // TODO: Mark this block dirty or something? May be indication it will be changed by imports. + CompileDelaySlot(DELAYSLOT_NICE); + FlushAll(); + gpr.SetRegImm(SCRATCHREG1, GetCompilerPC() + 8); + MovToPC(SCRATCHREG1); + MOVI2R(R0, targetAddr); + QuickCallFunction(SCRATCHREG2, &HitInvalidJump); + WriteSyscallExit(); return; } diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index f20e5e2600..5cf32aa86d 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -703,6 +703,7 @@ void ArmJit::UpdateRoundingMode(u32 fcr31) { // I don't think this gives us that much benefit. void ArmJit::WriteExit(u32 destination, int exit_num) { + // TODO: Check destination is valid and trigger exception. WriteDownCount(); //If nobody has taken care of this yet (this can be removed when all branches are done) JitBlock *b = js.curBlock; @@ -723,6 +724,7 @@ void ArmJit::WriteExit(u32 destination, int exit_num) void ArmJit::WriteExitDestInR(ARMReg Reg) { + // TODO: If not fast memory, check for invalid address in reg and trigger exception. MovToPC(Reg); WriteDownCount(); // TODO: shouldn't need an indirect branch here... diff --git a/Core/MIPS/ARM64/Arm64CompBranch.cpp b/Core/MIPS/ARM64/Arm64CompBranch.cpp index f203229674..cdb984608e 100644 --- a/Core/MIPS/ARM64/Arm64CompBranch.cpp +++ b/Core/MIPS/ARM64/Arm64CompBranch.cpp @@ -20,8 +20,9 @@ #include "profiler/profiler.h" -#include "Core/Reporting.h" #include "Core/Config.h" +#include "Core/Core.h" +#include "Core/Reporting.h" #include "Core/MemMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" @@ -461,6 +462,10 @@ void Arm64Jit::Comp_VBranch(MIPSOpcode op) } } +static void HitInvalidJump(uint32_t dest) { + Core_ExecException(dest, currentMIPS->pc - 8, ExecExceptionType::JUMP); +} + void Arm64Jit::Comp_Jump(MIPSOpcode op) { if (js.inDelaySlot) { ERROR_LOG_REPORT(JIT, "Branch in Jump delay slot at %08x in block starting at %08x", GetCompilerPC(), js.blockStart); @@ -477,6 +482,13 @@ void Arm64Jit::Comp_Jump(MIPSOpcode op) { js.compiling = false; } // TODO: Mark this block dirty or something? May be indication it will be changed by imports. + CompileDelaySlot(DELAYSLOT_NICE); + FlushAll(); + gpr.SetRegImm(SCRATCH1, GetCompilerPC() + 8); + MovToPC(SCRATCH1); + MOVI2R(W0, targetAddr); + QuickCallFunction(SCRATCH1, (const void *)&HitInvalidJump); + WriteSyscallExit(); return; } diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index 330c6b4761..3c39b7bf5a 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -677,6 +677,7 @@ void Arm64Jit::UpdateRoundingMode(u32 fcr31) { // though, as we need to have the SUBS flag set in the end. So with block linking in the mix, // I don't think this gives us that much benefit. void Arm64Jit::WriteExit(u32 destination, int exit_num) { + // TODO: Check destination is valid and trigger exception. WriteDownCount(); //If nobody has taken care of this yet (this can be removed when all branches are done) JitBlock *b = js.curBlock; @@ -696,6 +697,7 @@ void Arm64Jit::WriteExit(u32 destination, int exit_num) { } void Arm64Jit::WriteExitDestInR(ARM64Reg Reg) { + // TODO: If not fast memory, check for invalid address in reg and trigger exception. MovToPC(Reg); WriteDownCount(); // TODO: shouldn't need an indirect branch here... diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index c18d9ae5d5..a0c30a3582 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -617,7 +617,7 @@ void Jit::Comp_Jump(MIPSOpcode op) { CompileDelaySlot(DELAYSLOT_NICE); FlushAll(); MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC() + 8)); - ABI_CallFunctionC((const void *)&HitInvalidJump, targetAddr); + ABI_CallFunctionC(&HitInvalidJump, targetAddr); WriteSyscallExit(); return; } diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 4629d57f3d..2716f7233a 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -656,11 +656,18 @@ void Jit::Comp_Generic(MIPSOpcode op) { } } +static void HitInvalidBranch(uint32_t dest) { + Core_ExecException(dest, currentMIPS->pc, ExecExceptionType::JUMP); +} + void Jit::WriteExit(u32 destination, int exit_num) { _dbg_assert_msg_(JIT, exit_num < MAX_JIT_BLOCK_EXITS, "Expected a valid exit_num"); if (!Memory::IsValidAddress(destination)) { ERROR_LOG_REPORT(JIT, "Trying to write block exit to illegal destination %08x: pc = %08x", destination, currentMIPS->pc); + MOV(32, MIPSSTATE_VAR(pc), Imm32(GetCompilerPC())); + ABI_CallFunctionC(&HitInvalidBranch, destination); + js.afterOp |= JitState::AFTER_CORE_STATE; } // If we need to verify coreState and rewind, we may not jump yet. if (js.afterOp & (JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE)) { @@ -751,7 +758,7 @@ void Jit::WriteExitDestInReg(X64Reg reg) { // If we're ignoring, coreState didn't trip - so trip it now. CMP(32, R(EAX), Imm32(0)); FixupBranch skip = J_CC(CC_NE); - ABI_CallFunctionC((const void *)&HitInvalidJumpReg, GetCompilerPC()); + ABI_CallFunctionC(&HitInvalidJumpReg, GetCompilerPC()); SetJumpTarget(skip); SUB(32, MIPSSTATE_VAR(downcount), Imm8(0)); From fc00b1b9720eda7a8aecc199c4ce2eaee43b2583 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 13 Jul 2020 01:50:39 -0700 Subject: [PATCH 233/848] Kernel: Check thread switch PC in release. Hopefully won't be noticeable, it's not that hot and very cheap. --- Core/HLE/sceKernelThread.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 2b4e998ba6..26da3ba146 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1468,11 +1468,9 @@ void __KernelLoadContext(PSPThreadContext *ctx, bool vfpuEnabled) { memcpy(currentMIPS->vfpuCtrl, ctx->vfpuCtrl, sizeof(ctx->vfpuCtrl)); } -#ifdef _DEBUG if (!Memory::IsValidAddress(ctx->pc)) { Core_ExecException(ctx->pc, currentMIPS->pc, ExecExceptionType::THREAD); } -#endif memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other)); if (MIPSComp::jit) { From dbbcaa9eca16920508cdf87380f12626a6244996 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 16 May 2020 16:56:31 -0700 Subject: [PATCH 234/848] GLES: Invalidate framebuffers bound DONT_CARE. Let's try to invalidate when it's possible. We move the invalidate to the end of the render when detected. --- ext/native/thin3d/GLQueueRunner.cpp | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index cb5d63d847..682212be0e 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -609,6 +609,44 @@ void GLQueueRunner::RunSteps(const std::vector &steps, bool skipGLCal } } + auto ignoresContents = [](GLRRenderPassAction act) { + return act == GLRRenderPassAction::CLEAR || act == GLRRenderPassAction::DONT_CARE; + }; + int invalidateAllMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; + + for (int j = 0; j < (int)steps.size() - 1; ++j) { + GLRStep &primaryStep = *steps[j]; + if (primaryStep.stepType == GLRStepType::RENDER) { + const GLRFramebuffer *fb = primaryStep.render.framebuffer; + + // Let's see if we can invalidate it... + int invalidateMask = 0; + for (int i = j + 1; i < (int)steps.size(); ++i) { + const GLRStep &secondaryStep = *steps[i]; + if (secondaryStep.stepType == GLRStepType::RENDER && secondaryStep.render.framebuffer == fb) { + if (ignoresContents(secondaryStep.render.color)) + invalidateMask |= GL_COLOR_BUFFER_BIT; + if (ignoresContents(secondaryStep.render.depth)) + invalidateMask |= GL_DEPTH_BUFFER_BIT; + if (ignoresContents(secondaryStep.render.stencil)) + invalidateMask |= GL_STENCIL_BUFFER_BIT; + + if (invalidateMask == invalidateAllMask) + break; + } else if (secondaryStep.dependencies.contains(fb)) { + // Can't do it, this step may depend on fb's data. + break; + } + } + + if (invalidateMask) { + GLRRenderData data{ GLRRenderCommand::INVALIDATE }; + data.clear.clearMask = invalidateMask; + primaryStep.commands.push_back(data); + } + } + } + CHECK_GL_ERROR_IF_DEBUG(); size_t renderCount = 0; for (size_t i = 0; i < steps.size(); i++) { From dc6e7a79385aa9267f1482f52598ede921eb2ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 28 Jun 2020 09:52:53 +0200 Subject: [PATCH 235/848] Move the Vulkan swapchain out-of-date checking to the vkQueuePresentKHR call. --- ext/native/thin3d/VulkanRenderManager.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 573f0ce6c5..9a3a9e5e43 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -1031,14 +1031,11 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) { 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"); - outOfDateFrames_++; } else if (res == VK_ERROR_OUT_OF_DATE_KHR) { WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - not presenting"); frameData.skipSwap = true; - outOfDateFrames_++; } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res)); - outOfDateFrames_ = 0; } VkCommandBufferBeginInfo begin{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; @@ -1141,13 +1138,22 @@ void VulkanRenderManager::EndSubmitFrame(int frame) { present.waitSemaphoreCount = 1; VkResult res = vkQueuePresentKHR(vulkan_->GetGraphicsQueue(), &present); - // TODO: Deal with VK_SUBOPTIMAL_KHR ? - if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR) { - // ignore, it'll be fine. this happens sometimes during resizes, and we do make sure to recreate the swap chain. + // TODO: Deal with VK_SUBOPTIMAL_KHR here too? + if (res == VK_ERROR_OUT_OF_DATE_KHR) { + // We clearly didn't get this in vkAcquireNextImageKHR because of the skipSwap check above. + // Do the increment. + outOfDateFrames_++; + } else if (res == VK_SUBOPTIMAL_KHR) { + outOfDateFrames_++; + } else if (res != VK_SUCCESS) { + _assert_msg_(G3D, false, "vkQueuePresentKHR failed! result=%s", VulkanResultToString(res)); } else { - _assert_msg_(G3D, res == VK_SUCCESS, "vkQueuePresentKHR failed! result=%s", VulkanResultToString(res)); + // Success + outOfDateFrames_ = 0; } } else { + // We only get here if vkAcquireNextImage returned VK_ERROR_OUT_OF_DATE. + outOfDateFrames_++; frameData.skipSwap = false; } } From e8370b94c0458f7116ebf789490e63701f6b0eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 28 Jun 2020 20:06:44 +0200 Subject: [PATCH 236/848] Remove irrelevant comment --- ext/native/thin3d/VulkanRenderManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 9a3a9e5e43..d8d50bae3a 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -1138,7 +1138,6 @@ void VulkanRenderManager::EndSubmitFrame(int frame) { present.waitSemaphoreCount = 1; VkResult res = vkQueuePresentKHR(vulkan_->GetGraphicsQueue(), &present); - // TODO: Deal with VK_SUBOPTIMAL_KHR here too? if (res == VK_ERROR_OUT_OF_DATE_KHR) { // We clearly didn't get this in vkAcquireNextImageKHR because of the skipSwap check above. // Do the increment. From 20d85e57c92afdff2fd4de0ae68e287591277940 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 13 Jul 2020 19:13:18 +0200 Subject: [PATCH 237/848] (Libretro) Add optimal input read codepath - bitmasks --- libretro/libretro.cpp | 35 +- libretro/libretro.h | 880 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 797 insertions(+), 118 deletions(-) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index b188283a2f..621444d653 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -42,6 +42,8 @@ #define SAMPLERATE 44100 +static bool libretro_supports_bitmasks = false; + namespace Libretro { LibretroGraphicsContext *ctx; retro_environment_t environ_cb; @@ -306,7 +308,8 @@ void retro_set_audio_sample(retro_audio_sample_t cb) { (void)cb; } void retro_set_input_poll(retro_input_poll_t cb) { input_poll_cb = cb; } void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; } -void retro_init(void) { +void retro_init(void) +{ #if 0 g_Config.Load(""); #endif @@ -338,6 +341,9 @@ void retro_init(void) { logman->SetAllLogLevels(LogTypes::LINFO); #endif } + + if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL)) + libretro_supports_bitmasks = true; } void retro_deinit(void) { @@ -348,6 +354,8 @@ void retro_deinit(void) { delete host; host = nullptr; + + libretro_supports_bitmasks = false; } void retro_set_controller_port_device(unsigned port, unsigned device) { @@ -636,10 +644,29 @@ static void retro_input(void) { input_poll_cb(); - for (int i = 0; i < sizeof(map) / sizeof(*map); i++) { - if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, map[i].retro)) { + unsigned i; + int16_t ret = 0; + if (libretro_supports_bitmasks) + { + ret = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK); + } + else + { + for (i = RETRO_DEVICE_ID_JOYPAD_B; i <= RETRO_DEVICE_ID_JOYPAD_R; i++) + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, i)) + ret |= (1 << i); + } + + for (i = 0; i < sizeof(map) / sizeof(*map); i++) + { + bool pressed = ret & (1 << map[i].retro); + + if (pressed) + { __CtrlButtonDown(map[i].sceCtrl); - } else { + } + else + { __CtrlButtonUp(map[i].sceCtrl); } } diff --git a/libretro/libretro.h b/libretro/libretro.h index bfe832c202..1ae508fc93 100644 --- a/libretro/libretro.h +++ b/libretro/libretro.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2017 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro.h). @@ -128,7 +128,8 @@ extern "C" { /* LIGHTGUN device is similar to Guncon-2 for PlayStation 2. * It reports X/Y coordinates in screen space (similar to the pointer) - * in the range [-0x8000, 0x7fff] in both axes, with zero being center. + * in the range [-0x8000, 0x7fff] in both axes, with zero being center and + * -0x8000 being out of bounds. * As well as reporting on/off screen state. It features a trigger, * start/select buttons, auxiliary action buttons and a * directional pad. A forced off-screen shot can be requested for @@ -139,7 +140,8 @@ extern "C" { /* The ANALOG device is an extension to JOYPAD (RetroPad). * Similar to DualShock2 it adds two analog sticks and all buttons can * be analog. This is treated as a separate device type as it returns - * axis values in the full analog range of [-0x8000, 0x7fff]. + * axis values in the full analog range of [-0x7fff, 0x7fff], + * although some devices may return -0x8000. * Positive X axis is right. Positive Y axis is down. * Buttons are returned in the range [0, 0x7fff]. * Only use ANALOG type when polling for analog values. @@ -200,6 +202,8 @@ extern "C" { #define RETRO_DEVICE_ID_JOYPAD_L3 14 #define RETRO_DEVICE_ID_JOYPAD_R3 15 +#define RETRO_DEVICE_ID_JOYPAD_MASK 256 + /* Index / Id values for ANALOG device. */ #define RETRO_DEVICE_INDEX_ANALOG_LEFT 0 #define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1 @@ -246,6 +250,7 @@ extern "C" { #define RETRO_DEVICE_ID_POINTER_X 0 #define RETRO_DEVICE_ID_POINTER_Y 1 #define RETRO_DEVICE_ID_POINTER_PRESSED 2 +#define RETRO_DEVICE_ID_POINTER_COUNT 3 /* Returned from retro_get_region(). */ #define RETRO_REGION_NTSC 0 @@ -271,6 +276,12 @@ enum retro_language RETRO_LANGUAGE_POLISH = 14, RETRO_LANGUAGE_VIETNAMESE = 15, RETRO_LANGUAGE_ARABIC = 16, + RETRO_LANGUAGE_GREEK = 17, + RETRO_LANGUAGE_TURKISH = 18, + RETRO_LANGUAGE_SLOVAK = 19, + RETRO_LANGUAGE_PERSIAN = 20, + RETRO_LANGUAGE_HEBREW = 21, + RETRO_LANGUAGE_ASTURIAN = 22, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ @@ -450,6 +461,7 @@ enum retro_key RETROK_POWER = 320, RETROK_EURO = 321, RETROK_UNDO = 322, + RETROK_OEM_102 = 323, RETROK_LAST, @@ -481,11 +493,13 @@ enum retro_mod /* Environment commands. */ #define RETRO_ENVIRONMENT_SET_ROTATION 1 /* const unsigned * -- * Sets screen rotation of graphics. - * Is only implemented if rotation can be accelerated by hardware. * Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, * 270 degrees counter-clockwise respectively. */ #define RETRO_ENVIRONMENT_GET_OVERSCAN 2 /* bool * -- + * NOTE: As of 2019 this callback is considered deprecated in favor of + * using core options to manage overscan in a more nuanced, core-specific way. + * * Boolean value whether or not the implementation should use overscan, * or crop away overscan. */ @@ -599,8 +613,11 @@ enum retro_mod * GET_VARIABLE. * This allows the frontend to present these variables to * a user dynamically. - * This should be called as early as possible (ideally in - * retro_set_environment). + * This should be called the first time as early as + * possible (ideally in retro_set_environment). + * Afterward it may be called again for the core to communicate + * updated options to the frontend, but the number of core + * options must not change from the number in the initial call. * * 'data' points to an array of retro_variable structs * terminated by a { NULL, NULL } element. @@ -654,6 +671,15 @@ enum retro_mod /* Environment 20 was an obsolete version of SET_AUDIO_CALLBACK. * It was not used by any known core at the time, * and was removed from the API. */ +#define RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK 21 + /* const struct retro_frame_time_callback * -- + * Lets the core know how much time has passed since last + * invocation of retro_run(). + * The frontend can tamper with the timing to fake fast-forward, + * slow-motion, frame stepping, etc. + * In this case the delta time will use the reference value + * in frame_time_callback.. + */ #define RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK 22 /* const struct retro_audio_callback * -- * Sets an interface which is used to notify a libretro core about audio @@ -680,15 +706,6 @@ enum retro_mod * A libretro core using SET_AUDIO_CALLBACK should also make use of * SET_FRAME_TIME_CALLBACK. */ -#define RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK 21 - /* const struct retro_frame_time_callback * -- - * Lets the core know how much time has passed since last - * invocation of retro_run(). - * The frontend can tamper with the timing to fake fast-forward, - * slow-motion, frame stepping, etc. - * In this case the delta time will use the reference value - * in frame_time_callback.. - */ #define RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE 23 /* struct retro_rumble_interface * -- * Gets an interface which is used by a libretro core to set @@ -775,17 +792,18 @@ enum retro_mod */ #define RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY 31 /* const char ** -- - * Returns the "save" directory of the frontend. - * This directory can be used to store SRAM, memory cards, - * high scores, etc, if the libretro core + * Returns the "save" directory of the frontend, unless there is no + * save directory available. The save directory should be used to + * store SRAM, memory cards, high scores, etc, if the libretro core * cannot use the regular memory interface (retro_get_memory_data()). * - * NOTE: libretro cores used to check GET_SYSTEM_DIRECTORY for - * similar things before. - * They should still check GET_SYSTEM_DIRECTORY if they want to - * be backwards compatible. - * The path here can be NULL. It should only be non-NULL if the - * frontend user has set a specific save path. + * If the frontend cannot designate a save directory, it will return + * NULL to indicate that the core should attempt to operate without a + * save directory set. + * + * NOTE: early libretro cores used the system directory for save + * files. Cores that need to be backwards-compatible can still check + * GET_SYSTEM_DIRECTORY. */ #define RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO 32 /* const struct retro_system_av_info * -- @@ -853,26 +871,39 @@ enum retro_mod #define RETRO_ENVIRONMENT_SET_CONTROLLER_INFO 35 /* const struct retro_controller_info * -- * This environment call lets a libretro core tell the frontend - * which controller types are recognized in calls to + * which controller subclasses are recognized in calls to * retro_set_controller_port_device(). * - * Some emulators such as Super Nintendo - * support multiple lightgun types which must be specifically - * selected from. - * It is therefore sometimes necessary for a frontend to be able - * to tell the core about a special kind of input device which is - * not covered by the libretro input API. + * Some emulators such as Super Nintendo support multiple lightgun + * types which must be specifically selected from. It is therefore + * sometimes necessary for a frontend to be able to tell the core + * about a special kind of input device which is not specifcally + * provided by the Libretro API. * - * In order for a frontend to understand the workings of an input device, - * it must be a specialized type - * of the generic device types already defined in the libretro API. + * In order for a frontend to understand the workings of those devices, + * they must be defined as a specialized subclass of the generic device + * types already defined in the libretro API. * - * Which devices are supported can vary per input port. * The core must pass an array of const struct retro_controller_info which - * is terminated with a blanked out struct. Each element of the struct - * corresponds to an ascending port index to - * retro_set_controller_port_device(). - * Even if special device types are set in the libretro core, + * is terminated with a blanked out struct. Each element of the + * retro_controller_info struct corresponds to the ascending port index + * that is passed to retro_set_controller_port_device() when that function + * is called to indicate to the core that the frontend has changed the + * active device subclass. SEE ALSO: retro_set_controller_port_device() + * + * The ascending input port indexes provided by the core in the struct + * are generally presented by frontends as ascending User # or Player #, + * such as Player 1, Player 2, Player 3, etc. Which device subclasses are + * supported can vary per input port. + * + * The first inner element of each entry in the retro_controller_info array + * is a retro_controller_description struct that specifies the names and + * codes of all device subclasses that are available for the corresponding + * User or Player, beginning with the generic Libretro device that the + * subclasses are derived from. The second inner element of each entry is the + * total number of subclasses that are listed in the retro_controller_description. + * + * NOTE: Even if special device types are set in the libretro core, * libretro should only poll input based on the base input device types. */ #define RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL) @@ -951,7 +982,37 @@ enum retro_mod * A frontend must make sure that the pointer obtained from this function is * writeable (and readable). */ - +#define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* const struct retro_hw_render_interface ** -- + * Returns an API specific rendering interface for accessing API specific data. + * Not all HW rendering APIs support or need this. + * The contents of the returned pointer is specific to the rendering API + * being used. See the various headers like libretro_vulkan.h, etc. + * + * GET_HW_RENDER_INTERFACE cannot be called before context_reset has been called. + * Similarly, after context_destroyed callback returns, + * the contents of the HW_RENDER_INTERFACE are invalidated. + */ +#define RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS (42 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* const bool * -- + * If true, the libretro implementation supports achievements + * either via memory descriptors set with RETRO_ENVIRONMENT_SET_MEMORY_MAPS + * or via retro_get_memory_data/retro_get_memory_size. + * + * This must be called before the first call to retro_run. + */ +#define RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE (43 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* const struct retro_hw_render_context_negotiation_interface * -- + * Sets an interface which lets the libretro core negotiate with frontend how a context is created. + * The semantics of this interface depends on which API is used in SET_HW_RENDER earlier. + * This interface will be used when the frontend is trying to create a HW rendering context, + * so it will be used after SET_HW_RENDER, but before the context_reset callback. + */ +#define RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS 44 + /* uint64_t * -- + * Sets quirk flags associated with serialization. The frontend will zero any flags it doesn't + * recognize or support. Should be set in either retro_init or retro_load_game, but not both. + */ #define RETRO_ENVIRONMENT_SET_HW_SHARED_CONTEXT (44 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* N/A (null) * -- * The frontend will try to use a 'shared' hardware context (mostly applicable @@ -963,19 +1024,307 @@ enum retro_mod * This will do nothing on its own until SET_HW_RENDER env callbacks are * being used. */ - #define RETRO_ENVIRONMENT_GET_VFS_INTERFACE (45 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* struct retro_vfs_interface_info * -- * Gets access to the VFS interface. * VFS presence needs to be queried prior to load_game or any * get_system/save/other_directory being called to let front end know * core supports VFS before it starts handing out paths. - * It is recomended to do so in retro_set_environment */ + * It is recomended to do so in retro_set_environment + */ +#define RETRO_ENVIRONMENT_GET_LED_INTERFACE (46 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* struct retro_led_interface * -- + * Gets an interface which is used by a libretro core to set + * state of LEDs. + */ +#define RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE (47 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* int * -- + * Tells the core if the frontend wants audio or video. + * If disabled, the frontend will discard the audio or video, + * so the core may decide to skip generating a frame or generating audio. + * This is mainly used for increasing performance. + * Bit 0 (value 1): Enable Video + * Bit 1 (value 2): Enable Audio + * Bit 2 (value 4): Use Fast Savestates. + * Bit 3 (value 8): Hard Disable Audio + * Other bits are reserved for future use and will default to zero. + * If video is disabled: + * * The frontend wants the core to not generate any video, + * including presenting frames via hardware acceleration. + * * The frontend's video frame callback will do nothing. + * * After running the frame, the video output of the next frame should be + * no different than if video was enabled, and saving and loading state + * should have no issues. + * If audio is disabled: + * * The frontend wants the core to not generate any audio. + * * The frontend's audio callbacks will do nothing. + * * After running the frame, the audio output of the next frame should be + * no different than if audio was enabled, and saving and loading state + * should have no issues. + * Fast Savestates: + * * Guaranteed to be created by the same binary that will load them. + * * Will not be written to or read from the disk. + * * Suggest that the core assumes loading state will succeed. + * * Suggest that the core updates its memory buffers in-place if possible. + * * Suggest that the core skips clearing memory. + * * Suggest that the core skips resetting the system. + * * Suggest that the core may skip validation steps. + * Hard Disable Audio: + * * Used for a secondary core when running ahead. + * * Indicates that the frontend will never need audio from the core. + * * Suggests that the core may stop synthesizing audio, but this should not + * compromise emulation accuracy. + * * Audio output for the next frame does not matter, and the frontend will + * never need an accurate audio state in the future. + * * State will never be saved when using Hard Disable Audio. + */ +#define RETRO_ENVIRONMENT_GET_MIDI_INTERFACE (48 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* struct retro_midi_interface ** -- + * Returns a MIDI interface that can be used for raw data I/O. + */ + +#define RETRO_ENVIRONMENT_GET_FASTFORWARDING (49 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* bool * -- + * Boolean value that indicates whether or not the frontend is in + * fastforwarding mode. + */ + +#define RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE (50 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* float * -- + * Float value that lets us know what target refresh rate + * is curently in use by the frontend. + * + * The core can use the returned value to set an ideal + * refresh rate/framerate. + */ + +#define RETRO_ENVIRONMENT_GET_INPUT_BITMASKS (51 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* bool * -- + * Boolean value that indicates whether or not the frontend supports + * input bitmasks being returned by retro_input_state_t. The advantage + * of this is that retro_input_state_t has to be only called once to + * grab all button states instead of multiple times. + * + * If it returns true, you can pass RETRO_DEVICE_ID_JOYPAD_MASK as 'id' + * to retro_input_state_t (make sure 'device' is set to RETRO_DEVICE_JOYPAD). + * It will return a bitmask of all the digital buttons. + */ + +#define RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION 52 + /* unsigned * -- + * Unsigned value is the API version number of the core options + * interface supported by the frontend. If callback return false, + * API version is assumed to be 0. + * + * In legacy code, core options are set by passing an array of + * retro_variable structs to RETRO_ENVIRONMENT_SET_VARIABLES. + * This may be still be done regardless of the core options + * interface version. + * + * If version is >= 1 however, core options may instead be set by + * passing an array of retro_core_option_definition structs to + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS, or a 2D array of + * retro_core_option_definition structs to RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL. + * This allows the core to additionally set option sublabel information + * and/or provide localisation support. + */ + +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS 53 + /* const struct retro_core_option_definition ** -- + * Allows an implementation to signal the environment + * which variables it might want to check for later using + * GET_VARIABLE. + * This allows the frontend to present these variables to + * a user dynamically. + * This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION + * returns an API version of >= 1. + * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. + * This should be called the first time as early as + * possible (ideally in retro_set_environment). + * Afterwards it may be called again for the core to communicate + * updated options to the frontend, but the number of core + * options must not change from the number in the initial call. + * + * 'data' points to an array of retro_core_option_definition structs + * terminated by a { NULL, NULL, NULL, {{0}}, NULL } element. + * retro_core_option_definition::key should be namespaced to not collide + * with other implementations' keys. e.g. A core called + * 'foo' should use keys named as 'foo_option'. + * retro_core_option_definition::desc should contain a human readable + * description of the key. + * retro_core_option_definition::info should contain any additional human + * readable information text that a typical user may need to + * understand the functionality of the option. + * retro_core_option_definition::values is an array of retro_core_option_value + * structs terminated by a { NULL, NULL } element. + * > retro_core_option_definition::values[index].value is an expected option + * value. + * > retro_core_option_definition::values[index].label is a human readable + * label used when displaying the value on screen. If NULL, + * the value itself is used. + * retro_core_option_definition::default_value is the default core option + * setting. It must match one of the expected option values in the + * retro_core_option_definition::values array. If it does not, or the + * default value is NULL, the first entry in the + * retro_core_option_definition::values array is treated as the default. + * + * The number of possible options should be very limited, + * and must be less than RETRO_NUM_CORE_OPTION_VALUES_MAX. + * i.e. it should be feasible to cycle through options + * without a keyboard. + * + * Example entry: + * { + * "foo_option", + * "Speed hack coprocessor X", + * "Provides increased performance at the expense of reduced accuracy", + * { + * { "false", NULL }, + * { "true", NULL }, + * { "unstable", "Turbo (Unstable)" }, + * { NULL, NULL }, + * }, + * "false" + * } + * + * Only strings are operated on. The possible values will + * generally be displayed and stored as-is by the frontend. + */ + +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL 54 + /* const struct retro_core_options_intl * -- + * Allows an implementation to signal the environment + * which variables it might want to check for later using + * GET_VARIABLE. + * This allows the frontend to present these variables to + * a user dynamically. + * This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION + * returns an API version of >= 1. + * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. + * This should be called the first time as early as + * possible (ideally in retro_set_environment). + * Afterwards it may be called again for the core to communicate + * updated options to the frontend, but the number of core + * options must not change from the number in the initial call. + * + * This is fundamentally the same as RETRO_ENVIRONMENT_SET_CORE_OPTIONS, + * with the addition of localisation support. The description of the + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS callback should be consulted + * for further details. + * + * 'data' points to a retro_core_options_intl struct. + * + * retro_core_options_intl::us is a pointer to an array of + * retro_core_option_definition structs defining the US English + * core options implementation. It must point to a valid array. + * + * retro_core_options_intl::local is a pointer to an array of + * retro_core_option_definition structs defining core options for + * the current frontend language. It may be NULL (in which case + * retro_core_options_intl::us is used by the frontend). Any items + * missing from this array will be read from retro_core_options_intl::us + * instead. + * + * NOTE: Default core option values are always taken from the + * retro_core_options_intl::us array. Any default values in + * retro_core_options_intl::local array will be ignored. + */ + +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY 55 + /* struct retro_core_option_display * -- + * + * Allows an implementation to signal the environment to show + * or hide a variable when displaying core options. This is + * considered a *suggestion*. The frontend is free to ignore + * this callback, and its implementation not considered mandatory. + * + * 'data' points to a retro_core_option_display struct + * + * retro_core_option_display::key is a variable identifier + * which has already been set by SET_VARIABLES/SET_CORE_OPTIONS. + * + * retro_core_option_display::visible is a boolean, specifying + * whether variable should be displayed + * + * Note that all core option variables will be set visible by + * default when calling SET_VARIABLES/SET_CORE_OPTIONS. + */ + +#define RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER 56 + /* unsigned * -- + * + * Allows an implementation to ask frontend preferred hardware + * context to use. Core should use this information to deal + * with what specific context to request with SET_HW_RENDER. + * + * 'data' points to an unsigned variable + */ + +#define RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION 57 + /* unsigned * -- + * Unsigned value is the API version number of the disk control + * interface supported by the frontend. If callback return false, + * API version is assumed to be 0. + * + * In legacy code, the disk control interface is defined by passing + * a struct of type retro_disk_control_callback to + * RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE. + * This may be still be done regardless of the disk control + * interface version. + * + * If version is >= 1 however, the disk control interface may + * instead be defined by passing a struct of type + * retro_disk_control_ext_callback to + * RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE. + * This allows the core to provide additional information about + * disk images to the frontend and/or enables extra + * disk control functionality by the frontend. + */ + +#define RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE 58 + /* const struct retro_disk_control_ext_callback * -- + * Sets an interface which frontend can use to eject and insert + * disk images, and also obtain information about individual + * disk image files registered by the core. + * This is used for games which consist of multiple images and + * must be manually swapped out by the user (e.g. PSX, floppy disk + * based systems). + */ + +#define RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION 59 + /* unsigned * -- + * Unsigned value is the API version number of the message + * interface supported by the frontend. If callback returns + * false, API version is assumed to be 0. + * + * In legacy code, messages may be displayed in an + * implementation-specific manner by passing a struct + * of type retro_message to RETRO_ENVIRONMENT_SET_MESSAGE. + * This may be still be done regardless of the message + * interface version. + * + * If version is >= 1 however, messages may instead be + * displayed by passing a struct of type retro_message_ext + * to RETRO_ENVIRONMENT_SET_MESSAGE_EXT. This allows the + * core to specify message logging level, priority and + * destination (OSD, logging interface or both). + */ + +#define RETRO_ENVIRONMENT_SET_MESSAGE_EXT 60 + /* const struct retro_message_ext * -- + * Sets a message to be displayed in an implementation-specific + * manner for a certain amount of 'frames'. Additionally allows + * the core to specify message logging level, priority and + * destination (OSD, logging interface or both). + * Should not be used for trivial messages, which should simply be + * logged via RETRO_ENVIRONMENT_GET_LOG_INTERFACE (or as a + * fallback, stderr). + */ /* VFS functionality */ /* File paths: - * File paths passed as parameters when using this api shall be well formed unix-style, + * File paths passed as parameters when using this API shall be well formed UNIX-style, * using "/" (unquoted forward slash) as directory separator regardless of the platform's native separator. * Paths shall also include at least one forward slash ("game.bin" is an invalid path, use "./game.bin" instead). * Other than the directory separator, cores shall not make assumptions about path format: @@ -993,6 +1342,10 @@ enum retro_mod * Introduced in VFS API v1 */ struct retro_vfs_file_handle; +/* Opaque directory handle + * Introduced in VFS API v3 */ +struct retro_vfs_dir_handle; + /* File open flags * Introduced in VFS API v1 */ #define RETRO_VFS_FILE_ACCESS_READ (1 << 0) /* Read only mode */ @@ -1012,6 +1365,12 @@ struct retro_vfs_file_handle; #define RETRO_VFS_SEEK_POSITION_CURRENT 1 #define RETRO_VFS_SEEK_POSITION_END 2 +/* stat() result flags + * Introduced in VFS API v3 */ +#define RETRO_VFS_STAT_IS_VALID (1 << 0) +#define RETRO_VFS_STAT_IS_DIRECTORY (1 << 1) +#define RETRO_VFS_STAT_IS_CHARACTER_SPECIAL (1 << 2) + /* Get path from opaque handle. Returns the exact same path passed to file_open when getting the handle * Introduced in VFS API v1 */ typedef const char *(RETRO_CALLCONV *retro_vfs_get_path_t)(struct retro_vfs_file_handle *stream); @@ -1021,7 +1380,7 @@ typedef const char *(RETRO_CALLCONV *retro_vfs_get_path_t)(struct retro_vfs_file * Introduced in VFS API v1 */ typedef struct retro_vfs_file_handle *(RETRO_CALLCONV *retro_vfs_open_t)(const char *path, unsigned mode, unsigned hints); -/* Close the file and release its resources. Must be called if open_file returns non-NULL. Returns 0 on succes, -1 on failure. +/* Close the file and release its resources. Must be called if open_file returns non-NULL. Returns 0 on success, -1 on failure. * Whether the call succeeds ot not, the handle passed as parameter becomes invalid and should no longer be used. * Introduced in VFS API v1 */ typedef int (RETRO_CALLCONV *retro_vfs_close_t)(struct retro_vfs_file_handle *stream); @@ -1030,7 +1389,11 @@ typedef int (RETRO_CALLCONV *retro_vfs_close_t)(struct retro_vfs_file_handle *st * Introduced in VFS API v1 */ typedef int64_t (RETRO_CALLCONV *retro_vfs_size_t)(struct retro_vfs_file_handle *stream); -/* Get the current read / write position for the file. Returns - 1 for error. +/* Truncate file to specified size. Returns 0 on success or -1 on error + * Introduced in VFS API v2 */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_truncate_t)(struct retro_vfs_file_handle *stream, int64_t length); + +/* Get the current read / write position for the file. Returns -1 for error. * Introduced in VFS API v1 */ typedef int64_t (RETRO_CALLCONV *retro_vfs_tell_t)(struct retro_vfs_file_handle *stream); @@ -1058,8 +1421,42 @@ typedef int (RETRO_CALLCONV *retro_vfs_remove_t)(const char *path); * Introduced in VFS API v1 */ typedef int (RETRO_CALLCONV *retro_vfs_rename_t)(const char *old_path, const char *new_path); +/* Stat the specified file. Retruns a bitmask of RETRO_VFS_STAT_* flags, none are set if path was not valid. + * Additionally stores file size in given variable, unless NULL is given. + * Introduced in VFS API v3 */ +typedef int (RETRO_CALLCONV *retro_vfs_stat_t)(const char *path, int32_t *size); + +/* Create the specified directory. Returns 0 on success, -1 on unknown failure, -2 if already exists. + * Introduced in VFS API v3 */ +typedef int (RETRO_CALLCONV *retro_vfs_mkdir_t)(const char *dir); + +/* Open the specified directory for listing. Returns the opaque dir handle, or NULL for error. + * Support for the include_hidden argument may vary depending on the platform. + * Introduced in VFS API v3 */ +typedef struct retro_vfs_dir_handle *(RETRO_CALLCONV *retro_vfs_opendir_t)(const char *dir, bool include_hidden); + +/* Read the directory entry at the current position, and move the read pointer to the next position. + * Returns true on success, false if already on the last entry. + * Introduced in VFS API v3 */ +typedef bool (RETRO_CALLCONV *retro_vfs_readdir_t)(struct retro_vfs_dir_handle *dirstream); + +/* Get the name of the last entry read. Returns a string on success, or NULL for error. + * The returned string pointer is valid until the next call to readdir or closedir. + * Introduced in VFS API v3 */ +typedef const char *(RETRO_CALLCONV *retro_vfs_dirent_get_name_t)(struct retro_vfs_dir_handle *dirstream); + +/* Check if the last entry read was a directory. Returns true if it was, false otherwise (or on error). + * Introduced in VFS API v3 */ +typedef bool (RETRO_CALLCONV *retro_vfs_dirent_is_dir_t)(struct retro_vfs_dir_handle *dirstream); + +/* Close the directory and release its resources. Must be called if opendir returns non-NULL. Returns 0 on success, -1 on failure. + * Whether the call succeeds ot not, the handle passed as parameter becomes invalid and should no longer be used. + * Introduced in VFS API v3 */ +typedef int (RETRO_CALLCONV *retro_vfs_closedir_t)(struct retro_vfs_dir_handle *dirstream); + struct retro_vfs_interface { + /* VFS API v1 */ retro_vfs_get_path_t get_path; retro_vfs_open_t open; retro_vfs_close_t close; @@ -1071,6 +1468,16 @@ struct retro_vfs_interface retro_vfs_flush_t flush; retro_vfs_remove_t remove; retro_vfs_rename_t rename; + /* VFS API v2 */ + retro_vfs_truncate_t truncate; + /* VFS API v3 */ + retro_vfs_stat_t stat; + retro_vfs_mkdir_t mkdir; + retro_vfs_opendir_t opendir; + retro_vfs_readdir_t readdir; + retro_vfs_dirent_get_name_t dirent_get_name; + retro_vfs_dirent_is_dir_t dirent_is_dir; + retro_vfs_closedir_t closedir; }; struct retro_vfs_interface_info @@ -1093,6 +1500,7 @@ enum retro_hw_render_interface_type RETRO_HW_RENDER_INTERFACE_D3D10 = 2, RETRO_HW_RENDER_INTERFACE_D3D11 = 3, RETRO_HW_RENDER_INTERFACE_D3D12 = 4, + RETRO_HW_RENDER_INTERFACE_GSKIT_PS2 = 5, RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX }; @@ -1104,49 +1512,41 @@ struct retro_hw_render_interface unsigned interface_version; }; - -#define RETRO_ENVIRONMENT_GET_LED_INTERFACE (46 | RETRO_ENVIRONMENT_EXPERIMENTAL) - /* struct retro_led_interface * -- - * Gets an interface which is used by a libretro core to set - * state of LEDs. - */ - typedef void (RETRO_CALLCONV *retro_set_led_state_t)(int led, int state); struct retro_led_interface { retro_set_led_state_t set_led_state; }; -#define RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE (47 | RETRO_ENVIRONMENT_EXPERIMENTAL) - /* int * -- - * Queries the frontend if audio and video are enabled or not. - * If not enabled, the frontend will discard the audio or video, - * so the core may decide to skip producing audio or video. - * Bit 0 (value 1) is set if Video is enabled, - * Bit 1 (value 2) is set if Audio is enabled. - * Other bits are reserved for future use. - */ +/* Retrieves the current state of the MIDI input. + * Returns true if it's enabled, false otherwise. */ +typedef bool (RETRO_CALLCONV *retro_midi_input_enabled_t)(void); -#define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL) - /* const struct retro_hw_render_interface ** -- - * Returns an API specific rendering interface for accessing API specific data. - * Not all HW rendering APIs support or need this. - * The contents of the returned pointer is specific to the rendering API - * being used. See the various headers like libretro_vulkan.h, etc. - * - * GET_HW_RENDER_INTERFACE cannot be called before context_reset has been called. - * Similarly, after context_destroyed callback returns, - * the contents of the HW_RENDER_INTERFACE are invalidated. - */ +/* Retrieves the current state of the MIDI output. + * Returns true if it's enabled, false otherwise */ +typedef bool (RETRO_CALLCONV *retro_midi_output_enabled_t)(void); -#define RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS (42 | RETRO_ENVIRONMENT_EXPERIMENTAL) - /* const bool * -- - * If true, the libretro implementation supports achievements - * either via memory descriptors set with RETRO_ENVIRONMENT_SET_MEMORY_MAPS - * or via retro_get_memory_data/retro_get_memory_size. - * - * This must be called before the first call to retro_run. - */ +/* Reads next byte from the input stream. + * Returns true if byte is read, false otherwise. */ +typedef bool (RETRO_CALLCONV *retro_midi_read_t)(uint8_t *byte); + +/* Writes byte to the output stream. + * 'delta_time' is in microseconds and represent time elapsed since previous write. + * Returns true if byte is written, false otherwise. */ +typedef bool (RETRO_CALLCONV *retro_midi_write_t)(uint8_t byte, uint32_t delta_time); + +/* Flushes previously written data. + * Returns true if successful, false otherwise. */ +typedef bool (RETRO_CALLCONV *retro_midi_flush_t)(void); + +struct retro_midi_interface +{ + retro_midi_input_enabled_t input_enabled; + retro_midi_output_enabled_t output_enabled; + retro_midi_read_t read; + retro_midi_write_t write; + retro_midi_flush_t flush; +}; enum retro_hw_render_context_negotiation_interface_type { @@ -1161,13 +1561,6 @@ struct retro_hw_render_context_negotiation_interface enum retro_hw_render_context_negotiation_interface_type interface_type; unsigned interface_version; }; -#define RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE (43 | RETRO_ENVIRONMENT_EXPERIMENTAL) - /* const struct retro_hw_render_context_negotiation_interface * -- - * Sets an interface which lets the libretro core negotiate with frontend how a context is created. - * The semantics of this interface depends on which API is used in SET_HW_RENDER earlier. - * This interface will be used when the frontend is trying to create a HW rendering context, - * so it will be used after SET_HW_RENDER, but before the context_reset callback. - */ /* Serialized state is incomplete in some way. Set if serialization is * usable in typical end-user cases but should not be relied upon to @@ -1193,20 +1586,17 @@ struct retro_hw_render_context_negotiation_interface * dependence */ #define RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT (1 << 6) -#define RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS 44 - /* uint64_t * -- - * Sets quirk flags associated with serialization. The frontend will zero any flags it doesn't - * recognize or support. Should be set in either retro_init or retro_load_game, but not both. - */ - -#define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ -#define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ -#define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */ -#define RETRO_MEMDESC_ALIGN_4 (2 << 16) -#define RETRO_MEMDESC_ALIGN_8 (3 << 16) -#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */ -#define RETRO_MEMDESC_MINSIZE_4 (2 << 24) -#define RETRO_MEMDESC_MINSIZE_8 (3 << 24) +#define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ +#define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ +#define RETRO_MEMDESC_SYSTEM_RAM (1 << 2) /* The memory area is system RAM. This is main RAM of the gaming system. */ +#define RETRO_MEMDESC_SAVE_RAM (1 << 3) /* The memory area is save RAM. This RAM is usually found on a game cartridge, backed up by a battery. */ +#define RETRO_MEMDESC_VIDEO_RAM (1 << 4) /* The memory area is video RAM (VRAM) */ +#define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */ +#define RETRO_MEMDESC_ALIGN_4 (2 << 16) +#define RETRO_MEMDESC_ALIGN_8 (3 << 16) +#define RETRO_MEMDESC_MINSIZE_2 (1 << 24) /* All memory in this region is accessed at least 2 bytes at the time. */ +#define RETRO_MEMDESC_MINSIZE_4 (2 << 24) +#define RETRO_MEMDESC_MINSIZE_8 (3 << 24) struct retro_memory_descriptor { uint64_t flags; @@ -1607,6 +1997,10 @@ enum retro_sensor_action { RETRO_SENSOR_ACCELEROMETER_ENABLE = 0, RETRO_SENSOR_ACCELEROMETER_DISABLE, + RETRO_SENSOR_GYROSCOPE_ENABLE, + RETRO_SENSOR_GYROSCOPE_DISABLE, + RETRO_SENSOR_ILLUMINANCE_ENABLE, + RETRO_SENSOR_ILLUMINANCE_DISABLE, RETRO_SENSOR_DUMMY = INT_MAX }; @@ -1615,6 +2009,10 @@ enum retro_sensor_action #define RETRO_SENSOR_ACCELEROMETER_X 0 #define RETRO_SENSOR_ACCELEROMETER_Y 1 #define RETRO_SENSOR_ACCELEROMETER_Z 2 +#define RETRO_SENSOR_GYROSCOPE_X 3 +#define RETRO_SENSOR_GYROSCOPE_Y 4 +#define RETRO_SENSOR_GYROSCOPE_Z 5 +#define RETRO_SENSOR_ILLUMINANCE 6 typedef bool (RETRO_CALLCONV *retro_set_sensor_state_t)(unsigned port, enum retro_sensor_action action, unsigned rate); @@ -1972,7 +2370,8 @@ struct retro_keyboard_callback retro_keyboard_event_t callback; }; -/* Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE. +/* Callbacks for RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE & + * RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE. * Should be set for implementations which can swap out multiple disk * images in runtime. * @@ -2030,6 +2429,53 @@ typedef bool (RETRO_CALLCONV *retro_replace_image_index_t)(unsigned index, * with replace_image_index. */ typedef bool (RETRO_CALLCONV *retro_add_image_index_t)(void); +/* Sets initial image to insert in drive when calling + * core_load_game(). + * Since we cannot pass the initial index when loading + * content (this would require a major API change), this + * is set by the frontend *before* calling the core's + * retro_load_game()/retro_load_game_special() implementation. + * A core should therefore cache the index/path values and handle + * them inside retro_load_game()/retro_load_game_special(). + * - If 'index' is invalid (index >= get_num_images()), the + * core should ignore the set value and instead use 0 + * - 'path' is used purely for error checking - i.e. when + * content is loaded, the core should verify that the + * disk specified by 'index' has the specified file path. + * This is to guard against auto selecting the wrong image + * if (for example) the user should modify an existing M3U + * playlist. We have to let the core handle this because + * set_initial_image() must be called before loading content, + * i.e. the frontend cannot access image paths in advance + * and thus cannot perform the error check itself. + * If set path and content path do not match, the core should + * ignore the set 'index' value and instead use 0 + * Returns 'false' if index or 'path' are invalid, or core + * does not support this functionality + */ +typedef bool (RETRO_CALLCONV *retro_set_initial_image_t)(unsigned index, const char *path); + +/* Fetches the path of the specified disk image file. + * Returns 'false' if index is invalid (index >= get_num_images()) + * or path is otherwise unavailable. + */ +typedef bool (RETRO_CALLCONV *retro_get_image_path_t)(unsigned index, char *path, size_t len); + +/* Fetches a core-provided 'label' for the specified disk + * image file. In the simplest case this may be a file name + * (without extension), but for cores with more complex + * content requirements information may be provided to + * facilitate user disk swapping - for example, a core + * running floppy-disk-based content may uniquely label + * save disks, data disks, level disks, etc. with names + * corresponding to in-game disk change prompts (so the + * frontend can provide better user guidance than a 'dumb' + * disk index value). + * Returns 'false' if index is invalid (index >= get_num_images()) + * or label is otherwise unavailable. + */ +typedef bool (RETRO_CALLCONV *retro_get_image_label_t)(unsigned index, char *label, size_t len); + struct retro_disk_control_callback { retro_set_eject_state_t set_eject_state; @@ -2043,6 +2489,27 @@ struct retro_disk_control_callback retro_add_image_index_t add_image_index; }; +struct retro_disk_control_ext_callback +{ + retro_set_eject_state_t set_eject_state; + retro_get_eject_state_t get_eject_state; + + retro_get_image_index_t get_image_index; + retro_set_image_index_t set_image_index; + retro_get_num_images_t get_num_images; + + retro_replace_image_index_t replace_image_index; + retro_add_image_index_t add_image_index; + + /* NOTE: Frontend will only attempt to record/restore + * last used disk index if both set_initial_image() + * and get_image_path() are implemented */ + retro_set_initial_image_t set_initial_image; /* Optional - may be NULL */ + + retro_get_image_path_t get_image_path; /* Optional - may be NULL */ + retro_get_image_label_t get_image_label; /* Optional - may be NULL */ +}; + enum retro_pixel_format { /* 0RGB1555, native endian. @@ -2073,6 +2540,104 @@ struct retro_message unsigned frames; /* Duration in frames of message. */ }; +enum retro_message_target +{ + RETRO_MESSAGE_TARGET_ALL = 0, + RETRO_MESSAGE_TARGET_OSD, + RETRO_MESSAGE_TARGET_LOG +}; + +enum retro_message_type +{ + RETRO_MESSAGE_TYPE_NOTIFICATION = 0, + RETRO_MESSAGE_TYPE_NOTIFICATION_ALT, + RETRO_MESSAGE_TYPE_STATUS, + RETRO_MESSAGE_TYPE_PROGRESS +}; + +struct retro_message_ext +{ + /* Message string to be displayed/logged */ + const char *msg; + /* Duration (in ms) of message when targeting the OSD */ + unsigned duration; + /* Message priority when targeting the OSD + * > When multiple concurrent messages are sent to + * the frontend and the frontend does not have the + * capacity to display them all, messages with the + * *highest* priority value should be shown + * > There is no upper limit to a message priority + * value (within the bounds of the unsigned data type) + * > In the reference frontend (RetroArch), the same + * priority values are used for frontend-generated + * notifications, which are typically assigned values + * between 0 and 3 depending upon importance */ + unsigned priority; + /* Message logging level (info, warn, error, etc.) */ + enum retro_log_level level; + /* Message destination: OSD, logging interface or both */ + enum retro_message_target target; + /* Message 'type' when targeting the OSD + * > RETRO_MESSAGE_TYPE_NOTIFICATION: Specifies that a + * message should be handled in identical fashion to + * a standard frontend-generated notification + * > RETRO_MESSAGE_TYPE_NOTIFICATION_ALT: Specifies that + * message is a notification that requires user attention + * or action, but that it should be displayed in a manner + * that differs from standard frontend-generated notifications. + * This would typically correspond to messages that should be + * displayed immediately (independently from any internal + * frontend message queue), and/or which should be visually + * distinguishable from frontend-generated notifications. + * For example, a core may wish to inform the user of + * information related to a disk-change event. It is + * expected that the frontend itself may provide a + * notification in this case; if the core sends a + * message of type RETRO_MESSAGE_TYPE_NOTIFICATION, an + * uncomfortable 'double-notification' may occur. A message + * of RETRO_MESSAGE_TYPE_NOTIFICATION_ALT should therefore + * be presented such that visual conflict with regular + * notifications does not occur + * > RETRO_MESSAGE_TYPE_STATUS: Indicates that message + * is not a standard notification. This typically + * corresponds to 'status' indicators, such as a core's + * internal FPS, which are intended to be displayed + * either permanently while a core is running, or in + * a manner that does not suggest user attention or action + * is required. 'Status' type messages should therefore be + * displayed in a different on-screen location and in a manner + * easily distinguishable from both standard frontend-generated + * notifications and messages of type RETRO_MESSAGE_TYPE_NOTIFICATION_ALT + * > RETRO_MESSAGE_TYPE_PROGRESS: Indicates that message reports + * the progress of an internal core task. For example, in cases + * where a core itself handles the loading of content from a file, + * this may correspond to the percentage of the file that has been + * read. Alternatively, an audio/video playback core may use a + * message of type RETRO_MESSAGE_TYPE_PROGRESS to display the current + * playback position as a percentage of the runtime. 'Progress' type + * messages should therefore be displayed as a literal progress bar, + * where: + * - 'retro_message_ext.msg' is the progress bar title/label + * - 'retro_message_ext.progress' determines the length of + * the progress bar + * NOTE: Message type is a *hint*, and may be ignored + * by the frontend. If a frontend lacks support for + * displaying messages via alternate means than standard + * frontend-generated notifications, it will treat *all* + * messages as having the type RETRO_MESSAGE_TYPE_NOTIFICATION */ + enum retro_message_type type; + /* Task progress when targeting the OSD and message is + * of type RETRO_MESSAGE_TYPE_PROGRESS + * > -1: Unmetered/indeterminate + * > 0-100: Current progress percentage + * NOTE: Since message type is a hint, a frontend may ignore + * progress values. Where relevant, a core should therefore + * include progress percentage within the message string, + * such that the message intent remains clear when displayed + * as a standard frontend-generated notification */ + int8_t progress; +}; + /* Describes how the libretro implementation maps a libretro input bind * to its internal input system through a human readable string. * This string can be used to better let a user configure input. */ @@ -2106,17 +2671,26 @@ struct retro_system_info * Typically used for a GUI to filter * out extensions. */ - /* If true, retro_load_game() is guaranteed to provide a valid pathname - * in retro_game_info::path. - * ::data and ::size are both invalid. + /* Libretro cores that need to have direct access to their content + * files, including cores which use the path of the content files to + * determine the paths of other files, should set need_fullpath to true. * - * If false, ::data and ::size are guaranteed to be valid, but ::path - * might not be valid. + * Cores should strive for setting need_fullpath to false, + * as it allows the frontend to perform patching, etc. * - * This is typically set to true for libretro implementations that must - * load from file. - * Implementations should strive for setting this to false, as it allows - * the frontend to perform patching, etc. */ + * If need_fullpath is true and retro_load_game() is called: + * - retro_game_info::path is guaranteed to have a valid path + * - retro_game_info::data and retro_game_info::size are invalid + * + * If need_fullpath is false and retro_load_game() is called: + * - retro_game_info::path may be NULL + * - retro_game_info::data and retro_game_info::size are guaranteed + * to be valid + * + * See also: + * - RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY + * - RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY + */ bool need_fullpath; /* If true, the frontend is not allowed to extract any archives before @@ -2167,6 +2741,76 @@ struct retro_variable const char *value; }; +struct retro_core_option_display +{ + /* Variable to configure in RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY */ + const char *key; + + /* Specifies whether variable should be displayed + * when presenting core options to the user */ + bool visible; +}; + +/* Maximum number of values permitted for a core option + * > Note: We have to set a maximum value due the limitations + * of the C language - i.e. it is not possible to create an + * array of structs each containing a variable sized array, + * so the retro_core_option_definition values array must + * have a fixed size. The size limit of 128 is a balancing + * act - it needs to be large enough to support all 'sane' + * core options, but setting it too large may impact low memory + * platforms. In practise, if a core option has more than + * 128 values then the implementation is likely flawed. + * To quote the above API reference: + * "The number of possible options should be very limited + * i.e. it should be feasible to cycle through options + * without a keyboard." + */ +#define RETRO_NUM_CORE_OPTION_VALUES_MAX 128 + +struct retro_core_option_value +{ + /* Expected option value */ + const char *value; + + /* Human-readable value label. If NULL, value itself + * will be displayed by the frontend */ + const char *label; +}; + +struct retro_core_option_definition +{ + /* Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE. */ + const char *key; + + /* Human-readable core option description (used as menu label) */ + const char *desc; + + /* Human-readable core option information (used as menu sublabel) */ + const char *info; + + /* Array of retro_core_option_value structs, terminated by NULL */ + struct retro_core_option_value values[RETRO_NUM_CORE_OPTION_VALUES_MAX]; + + /* Default core option value. Must match one of the values + * in the retro_core_option_value array, otherwise will be + * ignored */ + const char *default_value; +}; + +struct retro_core_options_intl +{ + /* Pointer to an array of retro_core_option_definition structs + * - US English implementation + * - Must point to a valid array */ + struct retro_core_option_definition *us; + + /* Pointer to an array of retro_core_option_definition structs + * - Implementation for current frontend language + * - May be NULL */ + struct retro_core_option_definition *local; +}; + struct retro_game_info { const char *path; /* Path to game, UTF-8 encoded. @@ -2301,7 +2945,13 @@ RETRO_API void retro_get_system_av_info(struct retro_system_av_info *info); * will only poll input based on that particular device type. It is only a * hint to the libretro core when a core cannot automatically detect the * appropriate input device type on its own. It is also relevant when a - * core can change its behavior depending on device type. */ + * core can change its behavior depending on device type. + * + * As part of the core's implementation of retro_set_controller_port_device, + * the core should call RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS to notify the + * frontend if the descriptions for any controls have changed as a + * result of changing the device type. + */ RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device); /* Resets the current game. */ @@ -2333,7 +2983,9 @@ RETRO_API bool retro_unserialize(const void *data, size_t size); RETRO_API void retro_cheat_reset(void); RETRO_API void retro_cheat_set(unsigned index, bool enabled, const char *code); -/* Loads a game. */ +/* Loads a game. + * Return true to indicate successful loading and false to indicate load failure. + */ RETRO_API bool retro_load_game(const struct retro_game_info *game); /* Loads a "special" kind of game. Should not be used, @@ -2343,7 +2995,7 @@ RETRO_API bool retro_load_game_special( const struct retro_game_info *info, size_t num_info ); -/* Unloads a currently loaded game. */ +/* Unloads the currently loaded game. Called before retro_deinit(void). */ RETRO_API void retro_unload_game(void); /* Gets region of game. */ From e3a807fdc1f01b3a038d0c1609333d04d5d47528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 13 Jul 2020 19:41:06 +0200 Subject: [PATCH 238/848] Disable a new compiler warning that doesn't do us much good --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee98014740..0d2b57d561 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,6 +273,7 @@ if(NOT MSVC) add_definitions(-Wno-multichar) add_definitions(-Wno-deprecated-register) add_definitions(-Wno-tautological-pointer-compare) + add_definitions(-Wformat-overflow) # Don't compile with strict aliasing, we're not 100% aliasing-safe add_compile_options(-fno-strict-aliasing) From 5a3e955a5ba2eecf4ca2b08d2532b57111716c17 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 13 Jul 2020 21:11:26 +0200 Subject: [PATCH 239/848] Change libretro.cpp to confirm to libretro code formatting conventions --- libretro/libretro.cpp | 1185 +++++++++++++++++++++-------------------- 1 file changed, 618 insertions(+), 567 deletions(-) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 621444d653..e5566a7e99 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -44,125 +43,144 @@ static bool libretro_supports_bitmasks = false; -namespace Libretro { -LibretroGraphicsContext *ctx; -retro_environment_t environ_cb; -static retro_audio_sample_batch_t audio_batch_cb; -static retro_input_poll_t input_poll_cb; -static retro_input_state_t input_state_cb; +namespace Libretro +{ + LibretroGraphicsContext *ctx; + retro_environment_t environ_cb; + static retro_audio_sample_batch_t audio_batch_cb; + static retro_input_poll_t input_poll_cb; + static retro_input_state_t input_state_cb; } // namespace Libretro using namespace Libretro; -class LibretroHost : public Host { -public: - LibretroHost() {} - bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override { return true; } - void ShutdownGraphics() override {} - void InitSound() override {} - void UpdateSound() override { - extern int hostAttemptBlockSize; - const int blockSizeMax = 512; - static int16_t audio[blockSizeMax * 2]; - assert(hostAttemptBlockSize <= blockSizeMax); +class LibretroHost : public Host +{ + public: + LibretroHost() {} + bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override { return true; } + void ShutdownGraphics() override {} + void InitSound() override {} + void UpdateSound() override + { + extern int hostAttemptBlockSize; + const int blockSizeMax = 512; + static int16_t audio[blockSizeMax * 2]; + assert(hostAttemptBlockSize <= blockSizeMax); - int samples = __AudioMix(audio, hostAttemptBlockSize, SAMPLERATE); - audio_batch_cb(audio, samples); - } - void ShutdownSound() override {} - bool IsDebuggingEnabled() override { return false; } - bool AttemptLoadSymbolMap() override { return false; } + int samples = __AudioMix(audio, hostAttemptBlockSize, SAMPLERATE); + audio_batch_cb(audio, samples); + } + void ShutdownSound() override {} + bool IsDebuggingEnabled() override { return false; } + bool AttemptLoadSymbolMap() override { return false; } }; -class PrintfLogger : public LogListener { -public: - PrintfLogger(retro_log_callback log) : log_(log.log) {} - void Log(const LogMessage &message) { - switch (message.level) { - case LogTypes::LVERBOSE: - case LogTypes::LDEBUG: - log_(RETRO_LOG_DEBUG, "[%s] %s", message.log, message.msg.c_str()); - return; +class PrintfLogger : public LogListener +{ + public: + PrintfLogger(retro_log_callback log) : log_(log.log) {} + void Log(const LogMessage &message) + { + switch (message.level) + { + case LogTypes::LVERBOSE: + case LogTypes::LDEBUG: + log_(RETRO_LOG_DEBUG, "[%s] %s", + message.log, message.msg.c_str()); + break; - case LogTypes::LERROR: - log_(RETRO_LOG_ERROR, "[%s] %s", message.log, message.msg.c_str()); - return; + case LogTypes::LERROR: + log_(RETRO_LOG_ERROR, "[%s] %s", + message.log, message.msg.c_str()); + break; + case LogTypes::LNOTICE: + case LogTypes::LWARNING: + log_(RETRO_LOG_WARN, "[%s] %s", + message.log, message.msg.c_str()); + break; + case LogTypes::LINFO: + default: + log_(RETRO_LOG_INFO, "[%s] %s", + message.log, message.msg.c_str()); + break; + } + } - case LogTypes::LNOTICE: - case LogTypes::LWARNING: - log_(RETRO_LOG_WARN, "[%s] %s", message.log, message.msg.c_str()); - return; - - case LogTypes::LINFO: - default: - log_(RETRO_LOG_INFO, "[%s] %s", message.log, message.msg.c_str()); - return; - } - } - -private: - retro_log_printf_t log_; + private: + retro_log_printf_t log_; }; static PrintfLogger *printfLogger; -template class RetroOption { -public: - RetroOption(const char *id, const char *name, std::initializer_list> list) : id_(id), name_(name), list_(list.begin(), list.end()) {} - RetroOption(const char *id, const char *name, std::initializer_list list) : id_(id), name_(name) { - for (auto option : list) - list_.push_back({ option, (T)list_.size() }); - } - RetroOption(const char *id, const char *name, T first, std::initializer_list list) : id_(id), name_(name) { - for (auto option : list) - list_.push_back({ option, first + (int)list_.size() }); - } - RetroOption(const char *id, const char *name, T first, int count, int step = 1) : id_(id), name_(name) { - for (T i = first; i < first + count; i += step) - list_.push_back({ std::to_string(i), i }); - } - RetroOption(const char *id, const char *name, bool initial) : id_(id), name_(name) { - list_.push_back({ initial ? "enabled" : "disabled", initial }); - list_.push_back({ !initial ? "enabled" : "disabled", !initial }); - } - retro_variable GetOptions() { - if (options_.empty()) { - options_ = name_; - options_.push_back(';'); - for (auto &option : list_) { - if (option.first == list_.begin()->first) - options_ += std::string(" ") + option.first; - else - options_ += std::string("|") + option.first; - } - } - return { id_, options_.c_str() }; - } - bool Update(T *dest) { - retro_variable var{ id_ }; - T val = list_.front().second; +template class RetroOption +{ + public: + RetroOption(const char *id, const char *name, std::initializer_list> list) : id_(id), name_(name), list_(list.begin(), list.end()) {} + RetroOption(const char *id, const char *name, std::initializer_list list) : id_(id), name_(name) { + for (auto option : list) + list_.push_back({ option, (T)list_.size() }); + } + RetroOption(const char *id, const char *name, T first, std::initializer_list list) : id_(id), name_(name) { + for (auto option : list) + list_.push_back({ option, first + (int)list_.size() }); + } + RetroOption(const char *id, const char *name, T first, int count, int step = 1) : id_(id), name_(name) { + for (T i = first; i < first + count; i += step) + list_.push_back({ std::to_string(i), i }); + } + RetroOption(const char *id, const char *name, bool initial) : id_(id), name_(name) { + list_.push_back({ initial ? "enabled" : "disabled", initial }); + list_.push_back({ !initial ? "enabled" : "disabled", !initial }); + } - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - for (auto option : list_) { - if (option.first == var.value) { - val = option.second; - break; - } - } - } + retro_variable GetOptions() + { + if (options_.empty()) + { + options_ = name_; + options_.push_back(';'); + for (auto &option : list_) + { + if (option.first == list_.begin()->first) + options_ += std::string(" ") + option.first; + else + options_ += std::string("|") + option.first; + } + } + return { id_, options_.c_str() }; + } - if (*dest != val) { - *dest = val; - return true; - } + bool Update(T *dest) + { + retro_variable var{ id_ }; + T val = list_.front().second; - return false; - } + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + for (auto option : list_) + { + if (option.first == var.value) + { + val = option.second; + break; + } + } + } -private: - const char *id_; - const char *name_; - std::string options_; - std::vector> list_; + if (*dest != val) + { + *dest = val; + return true; + } + + return false; + } + + private: + const char *id_; + const char *name_; + std::string options_; + std::vector> list_; }; static RetroOption ppsspp_cpu_core("ppsspp_cpu_core", "CPU Core", { { "jit", CPUCore::JIT }, { "IR jit", CPUCore::IR_JIT }, { "interpreter", CPUCore::INTERPRETER } }); @@ -188,119 +206,127 @@ static RetroOption ppsspp_unsafe_func_replacements("ppsspp_unsafe_func_rep static RetroOption ppsspp_cheats("ppsspp_cheats", "Internal Cheats Support", false); static RetroOption ppsspp_io_timing_method("ppsspp_io_timing_method", "IO Timing Method", { { "Fast", IOTimingMethods::IOTIMING_FAST }, { "Host", IOTimingMethods::IOTIMING_HOST }, { "Simulate UMD delays", IOTimingMethods::IOTIMING_REALISTIC } }); -void retro_set_environment(retro_environment_t cb) { - std::vector vars; - vars.push_back(ppsspp_cpu_core.GetOptions()); - vars.push_back(ppsspp_locked_cpu_speed.GetOptions()); - vars.push_back(ppsspp_language.GetOptions()); - vars.push_back(ppsspp_rendering_mode.GetOptions()); - vars.push_back(ppsspp_auto_frameskip.GetOptions()); - vars.push_back(ppsspp_frameskip.GetOptions()); - vars.push_back(ppsspp_frameskiptype.GetOptions()); - vars.push_back(ppsspp_internal_resolution.GetOptions()); - vars.push_back(ppsspp_button_preference.GetOptions()); - vars.push_back(ppsspp_fast_memory.GetOptions()); - vars.push_back(ppsspp_block_transfer_gpu.GetOptions()); - vars.push_back(ppsspp_texture_scaling_level.GetOptions()); - vars.push_back(ppsspp_texture_scaling_type.GetOptions()); - vars.push_back(ppsspp_texture_filtering.GetOptions()); - vars.push_back(ppsspp_texture_anisotropic_filtering.GetOptions()); - vars.push_back(ppsspp_texture_deposterize.GetOptions()); - vars.push_back(ppsspp_texture_replacement.GetOptions()); - vars.push_back(ppsspp_gpu_hardware_transform.GetOptions()); - vars.push_back(ppsspp_vertex_cache.GetOptions()); - vars.push_back(ppsspp_unsafe_func_replacements.GetOptions()); - vars.push_back(ppsspp_cheats.GetOptions()); - vars.push_back(ppsspp_io_timing_method.GetOptions()); - vars.push_back({}); +void retro_set_environment(retro_environment_t cb) +{ + std::vector vars; + vars.push_back(ppsspp_cpu_core.GetOptions()); + vars.push_back(ppsspp_locked_cpu_speed.GetOptions()); + vars.push_back(ppsspp_language.GetOptions()); + vars.push_back(ppsspp_rendering_mode.GetOptions()); + vars.push_back(ppsspp_auto_frameskip.GetOptions()); + vars.push_back(ppsspp_frameskip.GetOptions()); + vars.push_back(ppsspp_frameskiptype.GetOptions()); + vars.push_back(ppsspp_internal_resolution.GetOptions()); + vars.push_back(ppsspp_button_preference.GetOptions()); + vars.push_back(ppsspp_fast_memory.GetOptions()); + vars.push_back(ppsspp_block_transfer_gpu.GetOptions()); + vars.push_back(ppsspp_texture_scaling_level.GetOptions()); + vars.push_back(ppsspp_texture_scaling_type.GetOptions()); + vars.push_back(ppsspp_texture_filtering.GetOptions()); + vars.push_back(ppsspp_texture_anisotropic_filtering.GetOptions()); + vars.push_back(ppsspp_texture_deposterize.GetOptions()); + vars.push_back(ppsspp_texture_replacement.GetOptions()); + vars.push_back(ppsspp_gpu_hardware_transform.GetOptions()); + vars.push_back(ppsspp_vertex_cache.GetOptions()); + vars.push_back(ppsspp_unsafe_func_replacements.GetOptions()); + vars.push_back(ppsspp_cheats.GetOptions()); + vars.push_back(ppsspp_io_timing_method.GetOptions()); + vars.push_back({}); - environ_cb = cb; + environ_cb = cb; - cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars.data()); + cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars.data()); } -static int get_language_auto(void) { - retro_language val = RETRO_LANGUAGE_ENGLISH; - environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &val); +static int get_language_auto(void) +{ + retro_language val = RETRO_LANGUAGE_ENGLISH; + environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &val); - switch (val) { - default: - case RETRO_LANGUAGE_ENGLISH: - return PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; - case RETRO_LANGUAGE_JAPANESE: - return PSP_SYSTEMPARAM_LANGUAGE_JAPANESE; - case RETRO_LANGUAGE_FRENCH: - return PSP_SYSTEMPARAM_LANGUAGE_FRENCH; - case RETRO_LANGUAGE_GERMAN: - return PSP_SYSTEMPARAM_LANGUAGE_GERMAN; - case RETRO_LANGUAGE_SPANISH: - return PSP_SYSTEMPARAM_LANGUAGE_SPANISH; - case RETRO_LANGUAGE_ITALIAN: - return PSP_SYSTEMPARAM_LANGUAGE_ITALIAN; - case RETRO_LANGUAGE_PORTUGUESE_BRAZIL: - case RETRO_LANGUAGE_PORTUGUESE_PORTUGAL: - return PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE; - case RETRO_LANGUAGE_RUSSIAN: - return PSP_SYSTEMPARAM_LANGUAGE_RUSSIAN; - case RETRO_LANGUAGE_DUTCH: - return PSP_SYSTEMPARAM_LANGUAGE_DUTCH; - case RETRO_LANGUAGE_KOREAN: - return PSP_SYSTEMPARAM_LANGUAGE_KOREAN; - case RETRO_LANGUAGE_CHINESE_TRADITIONAL: - return PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL; - case RETRO_LANGUAGE_CHINESE_SIMPLIFIED: - return PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED; - } + switch (val) + { + default: + case RETRO_LANGUAGE_ENGLISH: + return PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; + case RETRO_LANGUAGE_JAPANESE: + return PSP_SYSTEMPARAM_LANGUAGE_JAPANESE; + case RETRO_LANGUAGE_FRENCH: + return PSP_SYSTEMPARAM_LANGUAGE_FRENCH; + case RETRO_LANGUAGE_GERMAN: + return PSP_SYSTEMPARAM_LANGUAGE_GERMAN; + case RETRO_LANGUAGE_SPANISH: + return PSP_SYSTEMPARAM_LANGUAGE_SPANISH; + case RETRO_LANGUAGE_ITALIAN: + return PSP_SYSTEMPARAM_LANGUAGE_ITALIAN; + case RETRO_LANGUAGE_PORTUGUESE_BRAZIL: + case RETRO_LANGUAGE_PORTUGUESE_PORTUGAL: + return PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE; + case RETRO_LANGUAGE_RUSSIAN: + return PSP_SYSTEMPARAM_LANGUAGE_RUSSIAN; + case RETRO_LANGUAGE_DUTCH: + return PSP_SYSTEMPARAM_LANGUAGE_DUTCH; + case RETRO_LANGUAGE_KOREAN: + return PSP_SYSTEMPARAM_LANGUAGE_KOREAN; + case RETRO_LANGUAGE_CHINESE_TRADITIONAL: + return PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL; + case RETRO_LANGUAGE_CHINESE_SIMPLIFIED: + return PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED; + } } -static void check_variables(CoreParameter &coreParam) { - bool updated = false; +static void check_variables(CoreParameter &coreParam) +{ + bool updated = false; - if (coreState != CORE_POWERUP && environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && !updated) - return; + if ( coreState != CORE_POWERUP + && environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) + && !updated) + return; - ppsspp_button_preference.Update(&g_Config.iButtonPreference); - ppsspp_fast_memory.Update(&g_Config.bFastMemory); - ppsspp_vertex_cache.Update(&g_Config.bVertexCache); - ppsspp_gpu_hardware_transform.Update(&g_Config.bHardwareTransform); - ppsspp_frameskip.Update(&g_Config.iFrameSkip); - ppsspp_frameskiptype.Update(&g_Config.iFrameSkipType); - ppsspp_auto_frameskip.Update(&g_Config.bAutoFrameSkip); - ppsspp_block_transfer_gpu.Update(&g_Config.bBlockTransferGPU); - ppsspp_texture_filtering.Update(&g_Config.iTexFiltering); - ppsspp_texture_anisotropic_filtering.Update(&g_Config.iAnisotropyLevel); - ppsspp_texture_deposterize.Update(&g_Config.bTexDeposterize); - ppsspp_texture_replacement.Update(&g_Config.bReplaceTextures); - ppsspp_unsafe_func_replacements.Update(&g_Config.bFuncReplacements); - ppsspp_cheats.Update(&g_Config.bEnableCheats); - ppsspp_locked_cpu_speed.Update(&g_Config.iLockedCPUSpeed); - ppsspp_rendering_mode.Update(&g_Config.iRenderingMode); - ppsspp_cpu_core.Update((CPUCore *)&g_Config.iCpuCore); - ppsspp_io_timing_method.Update((IOTimingMethods *)&g_Config.iIOTimingMethod); + ppsspp_button_preference.Update(&g_Config.iButtonPreference); + ppsspp_fast_memory.Update(&g_Config.bFastMemory); + ppsspp_vertex_cache.Update(&g_Config.bVertexCache); + ppsspp_gpu_hardware_transform.Update(&g_Config.bHardwareTransform); + ppsspp_frameskip.Update(&g_Config.iFrameSkip); + ppsspp_frameskiptype.Update(&g_Config.iFrameSkipType); + ppsspp_auto_frameskip.Update(&g_Config.bAutoFrameSkip); + ppsspp_block_transfer_gpu.Update(&g_Config.bBlockTransferGPU); + ppsspp_texture_filtering.Update(&g_Config.iTexFiltering); + ppsspp_texture_anisotropic_filtering.Update(&g_Config.iAnisotropyLevel); + ppsspp_texture_deposterize.Update(&g_Config.bTexDeposterize); + ppsspp_texture_replacement.Update(&g_Config.bReplaceTextures); + ppsspp_unsafe_func_replacements.Update(&g_Config.bFuncReplacements); + ppsspp_cheats.Update(&g_Config.bEnableCheats); + ppsspp_locked_cpu_speed.Update(&g_Config.iLockedCPUSpeed); + ppsspp_rendering_mode.Update(&g_Config.iRenderingMode); + ppsspp_cpu_core.Update((CPUCore *)&g_Config.iCpuCore); + ppsspp_io_timing_method.Update((IOTimingMethods *)&g_Config.iIOTimingMethod); - ppsspp_language.Update(&g_Config.iLanguage); - if (g_Config.iLanguage < 0) { - g_Config.iLanguage = get_language_auto(); - } + ppsspp_language.Update(&g_Config.iLanguage); + if (g_Config.iLanguage < 0) + g_Config.iLanguage = get_language_auto(); - if (!PSP_IsInited() && ppsspp_internal_resolution.Update(&g_Config.iInternalResolution)) { - coreParam.pixelWidth = coreParam.renderWidth = g_Config.iInternalResolution * 480; - coreParam.pixelHeight = coreParam.renderHeight = g_Config.iInternalResolution * 272; - if (gpu) { - retro_system_av_info av_info; - retro_get_system_av_info(&av_info); - environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &av_info); - gpu->Resized(); - } - } + if (!PSP_IsInited() && ppsspp_internal_resolution.Update(&g_Config.iInternalResolution)) + { + coreParam.pixelWidth = coreParam.renderWidth = + g_Config.iInternalResolution * 480; + coreParam.pixelHeight = coreParam.renderHeight = + g_Config.iInternalResolution * 272; - if (ppsspp_texture_scaling_type.Update(&g_Config.iTexScalingType) && gpu) { - gpu->ClearCacheNextFrame(); - } + if (gpu) + { + retro_system_av_info av_info; + retro_get_system_av_info(&av_info); + environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &av_info); + gpu->Resized(); + } + } - if (ppsspp_texture_scaling_level.Update(&g_Config.iTexScalingLevel) && gpu) { - gpu->ClearCacheNextFrame(); - } + if (ppsspp_texture_scaling_type.Update(&g_Config.iTexScalingType) && gpu) + gpu->ClearCacheNextFrame(); + + if (ppsspp_texture_scaling_level.Update(&g_Config.iTexScalingLevel) && gpu) + gpu->ClearCacheNextFrame(); } void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; } @@ -310,287 +336,301 @@ void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; } void retro_init(void) { + struct retro_log_callback log; #if 0 - g_Config.Load(""); + g_Config.Load(""); #endif - g_Config.bEnableLogging = true; - g_Config.bFrameSkipUnthrottle = false; - g_Config.bMemStickInserted = PSP_MEMORYSTICK_STATE_INSERTED; - g_Config.iGlobalVolume = VOLUME_MAX - 1; - g_Config.iAltSpeedVolume = -1; - g_Config.bEnableSound = true; - g_Config.iCwCheatRefreshRate = 60; + g_Config.bEnableLogging = true; + g_Config.bFrameSkipUnthrottle = false; + g_Config.bMemStickInserted = PSP_MEMORYSTICK_STATE_INSERTED; + g_Config.iGlobalVolume = VOLUME_MAX - 1; + g_Config.iAltSpeedVolume = -1; + g_Config.bEnableSound = true; + g_Config.iCwCheatRefreshRate = 60; - g_Config.iFirmwareVersion = PSP_DEFAULT_FIRMWARE; - g_Config.iPSPModel = PSP_MODEL_SLIM; + g_Config.iFirmwareVersion = PSP_DEFAULT_FIRMWARE; + g_Config.iPSPModel = PSP_MODEL_SLIM; - LogManager::Init(); + LogManager::Init(); - host = new LibretroHost; + host = new LibretroHost; - struct retro_log_callback log; - if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) { - printfLogger = new PrintfLogger(log); - LogManager *logman = LogManager::GetInstance(); - logman->RemoveListener(logman->GetConsoleListener()); - logman->RemoveListener(logman->GetDebuggerListener()); - logman->ChangeFileLog(nullptr); - logman->AddListener(printfLogger); + if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) + { + printfLogger = new PrintfLogger(log); + LogManager *logman = LogManager::GetInstance(); + logman->RemoveListener(logman->GetConsoleListener()); + logman->RemoveListener(logman->GetDebuggerListener()); + logman->ChangeFileLog(nullptr); + logman->AddListener(printfLogger); #if 1 - logman->SetAllLogLevels(LogTypes::LINFO); + logman->SetAllLogLevels(LogTypes::LINFO); #endif - } + } if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL)) libretro_supports_bitmasks = true; } -void retro_deinit(void) { - LogManager::Shutdown(); +void retro_deinit(void) +{ + LogManager::Shutdown(); - delete printfLogger; - printfLogger = nullptr; + delete printfLogger; + printfLogger = nullptr; - delete host; - host = nullptr; + delete host; + host = nullptr; libretro_supports_bitmasks = false; } -void retro_set_controller_port_device(unsigned port, unsigned device) { +void retro_set_controller_port_device(unsigned port, unsigned device) +{ (void)port; (void)device; } -void retro_get_system_info(struct retro_system_info *info) { - *info = {}; - info->library_name = "PPSSPP"; - info->library_version = PPSSPP_GIT_VERSION; - info->need_fullpath = true; - info->valid_extensions = "elf|iso|cso|prx|pbp"; +void retro_get_system_info(struct retro_system_info *info) +{ + *info = {}; + info->library_name = "PPSSPP"; + info->library_version = PPSSPP_GIT_VERSION; + info->need_fullpath = true; + info->valid_extensions = "elf|iso|cso|prx|pbp"; } -void retro_get_system_av_info(struct retro_system_av_info *info) { - *info = {}; - info->timing.fps = 60.0f / 1.001f; - info->timing.sample_rate = SAMPLERATE; +void retro_get_system_av_info(struct retro_system_av_info *info) +{ + *info = {}; + info->timing.fps = 60.0f / 1.001f; + info->timing.sample_rate = SAMPLERATE; - info->geometry.base_width = g_Config.iInternalResolution * 480; - info->geometry.base_height = g_Config.iInternalResolution * 272; - info->geometry.max_width = g_Config.iInternalResolution * 480; - info->geometry.max_height = g_Config.iInternalResolution * 272; - info->geometry.aspect_ratio = 16.0 / 9.0; + info->geometry.base_width = g_Config.iInternalResolution * 480; + info->geometry.base_height = g_Config.iInternalResolution * 272; + info->geometry.max_width = g_Config.iInternalResolution * 480; + info->geometry.max_height = g_Config.iInternalResolution * 272; + info->geometry.aspect_ratio = 16.0 / 9.0; } unsigned retro_api_version(void) { return RETRO_API_VERSION; } -namespace Libretro { -bool useEmuThread = false; -std::atomic emuThreadState(EmuThreadState::DISABLED); +namespace Libretro +{ + bool useEmuThread = false; + std::atomic emuThreadState(EmuThreadState::DISABLED); -static std::thread emuThread; -static void EmuFrame() { - ctx->SetRenderTarget(); - if (ctx->GetDrawContext()) { - ctx->GetDrawContext()->BeginFrame(); - } + static std::thread emuThread; + static void EmuFrame() + { + ctx->SetRenderTarget(); + if (ctx->GetDrawContext()) + ctx->GetDrawContext()->BeginFrame(); - gpu->BeginHostFrame(); + gpu->BeginHostFrame(); - coreState = CORE_RUNNING; - PSP_RunLoopUntil(UINT64_MAX); + coreState = CORE_RUNNING; + PSP_RunLoopUntil(UINT64_MAX); - gpu->EndHostFrame(); + gpu->EndHostFrame(); - if (ctx->GetDrawContext()) { - ctx->GetDrawContext()->EndFrame(); - } -} + if (ctx->GetDrawContext()) + ctx->GetDrawContext()->EndFrame(); + } -static void EmuThreadFunc() { - setCurrentThreadName("Emu"); + static void EmuThreadFunc() + { + setCurrentThreadName("Emu"); - while (true) { - switch ((EmuThreadState)emuThreadState) { - case EmuThreadState::START_REQUESTED: - emuThreadState = EmuThreadState::RUNNING; - /* fallthrough */ - case EmuThreadState::RUNNING: - EmuFrame(); - break; - case EmuThreadState::PAUSE_REQUESTED: - emuThreadState = EmuThreadState::PAUSED; - /* fallthrough */ - case EmuThreadState::PAUSED: - sleep_ms(1); - break; - default: - case EmuThreadState::QUIT_REQUESTED: - emuThreadState = EmuThreadState::STOPPED; - ctx->StopThread(); - return; - } - } -} + for (;;) + { + switch ((EmuThreadState)emuThreadState) + { + case EmuThreadState::START_REQUESTED: + emuThreadState = EmuThreadState::RUNNING; + /* fallthrough */ + case EmuThreadState::RUNNING: + EmuFrame(); + break; + case EmuThreadState::PAUSE_REQUESTED: + emuThreadState = EmuThreadState::PAUSED; + /* fallthrough */ + case EmuThreadState::PAUSED: + sleep_ms(1); + break; + default: + case EmuThreadState::QUIT_REQUESTED: + emuThreadState = EmuThreadState::STOPPED; + ctx->StopThread(); + return; + } + } + } -void EmuThreadStart() { - bool wasPaused = emuThreadState == EmuThreadState::PAUSED; - emuThreadState = EmuThreadState::START_REQUESTED; + void EmuThreadStart() + { + bool wasPaused = emuThreadState == EmuThreadState::PAUSED; + emuThreadState = EmuThreadState::START_REQUESTED; - if (!wasPaused) { - ctx->ThreadStart(); - emuThread = std::thread(&EmuThreadFunc); - } -} + if (!wasPaused) + { + ctx->ThreadStart(); + emuThread = std::thread(&EmuThreadFunc); + } + } -void EmuThreadStop() { - if (emuThreadState != EmuThreadState::RUNNING) { - return; - } + void EmuThreadStop() + { + if (emuThreadState != EmuThreadState::RUNNING) + return; - emuThreadState = EmuThreadState::QUIT_REQUESTED; + emuThreadState = EmuThreadState::QUIT_REQUESTED; - while (ctx->ThreadFrame()) { - // Need to keep eating frames to allow the EmuThread to exit correctly. - continue; - } + // Need to keep eating frames to allow the EmuThread to exit correctly. + while (ctx->ThreadFrame()) + continue; - emuThread.join(); - emuThread = std::thread(); - ctx->ThreadEnd(); -} + emuThread.join(); + emuThread = std::thread(); + ctx->ThreadEnd(); + } -void EmuThreadPause() { - if (emuThreadState != EmuThreadState::RUNNING) { - return; - } + void EmuThreadPause() + { + if (emuThreadState != EmuThreadState::RUNNING) + return; - emuThreadState = EmuThreadState::PAUSE_REQUESTED; + emuThreadState = EmuThreadState::PAUSE_REQUESTED; - ctx->ThreadFrame(); // Eat 1 frame + ctx->ThreadFrame(); // Eat 1 frame - while (emuThreadState != EmuThreadState::PAUSED) { - sleep_ms(1); - } -} + while (emuThreadState != EmuThreadState::PAUSED) + sleep_ms(1); + } } // namespace Libretro -bool retro_load_game(const struct retro_game_info *game) { - struct retro_input_descriptor desc[] = { - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, - { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, - { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, - { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, - { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, - { 0 }, - }; - environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); +bool retro_load_game(const struct retro_game_info *game) +{ + static std::string retro_base_dir; + static std::string retro_save_dir; + std::string error_string; + enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888; + const char *nickname = NULL; + const char *dir_ptr = NULL; + struct retro_input_descriptor desc[] = { + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 0 }, + }; - enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888; - if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) { - ERROR_LOG(SYSTEM, "XRGB8888 is not supported.\n"); - return false; - } + environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); - const char *nickname = NULL; - if (environ_cb(RETRO_ENVIRONMENT_GET_USERNAME, &nickname) && nickname) { - g_Config.sNickName = std::string(nickname); - } + if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) + { + ERROR_LOG(SYSTEM, "XRGB8888 is not supported.\n"); + return false; + } - const char *dir_ptr = NULL; - static std::string retro_base_dir; - static std::string retro_save_dir; + if (environ_cb(RETRO_ENVIRONMENT_GET_USERNAME, &nickname) && nickname) + g_Config.sNickName = std::string(nickname); - if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir_ptr) && dir_ptr) { - retro_base_dir = dir_ptr; - // Make sure that we don't have any lingering slashes, etc, as they break Windows. - size_t last = retro_base_dir.find_last_not_of(DIR_SEP_CHRS); - if (last != std::string::npos) - last++; - retro_base_dir = retro_base_dir.substr(0, last) + DIR_SEP; - } + if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir_ptr) + && dir_ptr) + { + size_t last; + retro_base_dir = dir_ptr; + // Make sure that we don't have any lingering slashes, etc, as they break Windows. + last = retro_base_dir.find_last_not_of(DIR_SEP_CHRS); + if (last != std::string::npos) + last++; - if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir_ptr) && dir_ptr) { - retro_save_dir = dir_ptr; - // Make sure that we don't have any lingering slashes, etc, as they break Windows. - size_t last = retro_save_dir.find_last_not_of(DIR_SEP_CHRS); - if (last != std::string::npos) - last++; + retro_base_dir = retro_base_dir.substr(0, last) + DIR_SEP; + } - retro_save_dir = retro_save_dir.substr(0, last) + DIR_SEP; - } + if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir_ptr) + && dir_ptr) + { + retro_save_dir = dir_ptr; + // Make sure that we don't have any lingering slashes, etc, as they break Windows. + size_t last = retro_save_dir.find_last_not_of(DIR_SEP_CHRS); + if (last != std::string::npos) + last++; - if (retro_base_dir.empty()) { - retro_base_dir = File::GetDir(game->path); - } + retro_save_dir = retro_save_dir.substr(0, last) + DIR_SEP; + } - retro_base_dir += "PPSSPP" DIR_SEP; + if (retro_base_dir.empty()) + retro_base_dir = File::GetDir(game->path); - if (retro_save_dir.empty()) { - retro_save_dir = File::GetDir(game->path); - } + retro_base_dir += "PPSSPP" DIR_SEP; - g_Config.currentDirectory = retro_base_dir; - g_Config.externalDirectory = retro_base_dir; - g_Config.memStickDirectory = retro_save_dir; - g_Config.flash0Directory = retro_base_dir + "flash0" DIR_SEP; - g_Config.internalDataDirectory = retro_base_dir; + if (retro_save_dir.empty()) + retro_save_dir = File::GetDir(game->path); - VFSRegister("", new DirectoryAssetReader(retro_base_dir.c_str())); + g_Config.currentDirectory = retro_base_dir; + g_Config.externalDirectory = retro_base_dir; + g_Config.memStickDirectory = retro_save_dir; + g_Config.flash0Directory = retro_base_dir + "flash0" DIR_SEP; + g_Config.internalDataDirectory = retro_base_dir; - coreState = CORE_POWERUP; - ctx = LibretroGraphicsContext::CreateGraphicsContext(); - INFO_LOG(SYSTEM, "Using %s backend", ctx->Ident()); + VFSRegister("", new DirectoryAssetReader(retro_base_dir.c_str())); - Core_SetGraphicsContext(ctx); - SetGPUBackend((GPUBackend)g_Config.iGPUBackend); + coreState = CORE_POWERUP; + ctx = LibretroGraphicsContext::CreateGraphicsContext(); + INFO_LOG(SYSTEM, "Using %s backend", ctx->Ident()); - useEmuThread = ctx->GetGPUCore() == GPUCORE_GLES; + Core_SetGraphicsContext(ctx); + SetGPUBackend((GPUBackend)g_Config.iGPUBackend); - CoreParameter coreParam = {}; - coreParam.enableSound = true; - coreParam.fileToStart = std::string(game->path); - coreParam.mountIso = ""; - coreParam.startBreak = false; - coreParam.printfEmuLog = true; - coreParam.headLess = true; - coreParam.unthrottle = true; - coreParam.graphicsContext = ctx; - coreParam.gpuCore = ctx->GetGPUCore(); - coreParam.cpuCore = CPUCore::JIT; - check_variables(coreParam); + useEmuThread = ctx->GetGPUCore() == GPUCORE_GLES; + + CoreParameter coreParam = {}; + coreParam.enableSound = true; + coreParam.fileToStart = std::string(game->path); + coreParam.mountIso = ""; + coreParam.startBreak = false; + coreParam.printfEmuLog = true; + coreParam.headLess = true; + coreParam.unthrottle = true; + coreParam.graphicsContext = ctx; + coreParam.gpuCore = ctx->GetGPUCore(); + coreParam.cpuCore = CPUCore::JIT; + check_variables(coreParam); #if 0 - g_Config.bVertexDecoderJit = (coreParam.cpuCore == CPU_JIT) ? true : false; + g_Config.bVertexDecoderJit = (coreParam.cpuCore == CPU_JIT) ? true : false; #endif - std::string error_string; - if (!PSP_InitStart(coreParam, &error_string)) { - ERROR_LOG(BOOT, "%s", error_string.c_str()); - return false; - } + if (!PSP_InitStart(coreParam, &error_string)) + { + ERROR_LOG(BOOT, "%s", error_string.c_str()); + return false; + } - return true; + return true; } -void retro_unload_game(void) { - if (Libretro::useEmuThread) { +void retro_unload_game(void) +{ + if (Libretro::useEmuThread) Libretro::EmuThreadStop(); - } PSP_Shutdown(); VFSShutdown(); @@ -600,56 +640,58 @@ void retro_unload_game(void) { PSP_CoreParameter().graphicsContext = nullptr; } -void retro_reset(void) { - std::string error_string; +void retro_reset(void) +{ + std::string error_string; - PSP_Shutdown(); + PSP_Shutdown(); #if 0 - coreState = CORE_POWERUP; - if (!PSP_InitStart(PSP_CoreParameter(), &error_string)) - { - ERROR_LOG(BOOT, "%s", error_string.c_str()); - environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, nullptr); - } + coreState = CORE_POWERUP; + if (!PSP_InitStart(PSP_CoreParameter(), &error_string)) + { + ERROR_LOG(BOOT, "%s", error_string.c_str()); + environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, nullptr); + } #else - if (!PSP_Init(PSP_CoreParameter(), &error_string)) { - ERROR_LOG(BOOT, "%s", error_string.c_str()); - environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, nullptr); - } + if (!PSP_Init(PSP_CoreParameter(), &error_string)) + { + ERROR_LOG(BOOT, "%s", error_string.c_str()); + environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, nullptr); + } #endif } -static void retro_input(void) { - // clang-format off - static struct - { - u32 retro; - u32 sceCtrl; - } map[] = { - { RETRO_DEVICE_ID_JOYPAD_UP, CTRL_UP }, - { RETRO_DEVICE_ID_JOYPAD_DOWN, CTRL_DOWN }, - { RETRO_DEVICE_ID_JOYPAD_LEFT, CTRL_LEFT }, - { RETRO_DEVICE_ID_JOYPAD_RIGHT, CTRL_RIGHT }, - { RETRO_DEVICE_ID_JOYPAD_X, CTRL_TRIANGLE }, - { RETRO_DEVICE_ID_JOYPAD_A, CTRL_CIRCLE }, - { RETRO_DEVICE_ID_JOYPAD_B, CTRL_CROSS }, - { RETRO_DEVICE_ID_JOYPAD_Y, CTRL_SQUARE }, - { RETRO_DEVICE_ID_JOYPAD_L, CTRL_LTRIGGER }, - { RETRO_DEVICE_ID_JOYPAD_R, CTRL_RTRIGGER }, - { RETRO_DEVICE_ID_JOYPAD_START, CTRL_START }, - { RETRO_DEVICE_ID_JOYPAD_SELECT, CTRL_SELECT }, - }; - // clang-format on - - input_poll_cb(); - +static void retro_input(void) +{ unsigned i; int16_t ret = 0; - if (libretro_supports_bitmasks) + // clang-format off + static struct { - ret = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK); - } + u32 retro; + u32 sceCtrl; + } map[] = { + { RETRO_DEVICE_ID_JOYPAD_UP, CTRL_UP }, + { RETRO_DEVICE_ID_JOYPAD_DOWN, CTRL_DOWN }, + { RETRO_DEVICE_ID_JOYPAD_LEFT, CTRL_LEFT }, + { RETRO_DEVICE_ID_JOYPAD_RIGHT, CTRL_RIGHT }, + { RETRO_DEVICE_ID_JOYPAD_X, CTRL_TRIANGLE }, + { RETRO_DEVICE_ID_JOYPAD_A, CTRL_CIRCLE }, + { RETRO_DEVICE_ID_JOYPAD_B, CTRL_CROSS }, + { RETRO_DEVICE_ID_JOYPAD_Y, CTRL_SQUARE }, + { RETRO_DEVICE_ID_JOYPAD_L, CTRL_LTRIGGER }, + { RETRO_DEVICE_ID_JOYPAD_R, CTRL_RTRIGGER }, + { RETRO_DEVICE_ID_JOYPAD_START, CTRL_START }, + { RETRO_DEVICE_ID_JOYPAD_SELECT, CTRL_SELECT }, + }; + // clang-format on + + input_poll_cb(); + + if (libretro_supports_bitmasks) + ret = input_state_cb(0, RETRO_DEVICE_JOYPAD, + 0, RETRO_DEVICE_ID_JOYPAD_MASK); else { for (i = RETRO_DEVICE_ID_JOYPAD_B; i <= RETRO_DEVICE_ID_JOYPAD_R; i++) @@ -657,170 +699,181 @@ static void retro_input(void) { ret |= (1 << i); } - for (i = 0; i < sizeof(map) / sizeof(*map); i++) + for (i = 0; i < sizeof(map) / sizeof(*map); i++) { bool pressed = ret & (1 << map[i].retro); - if (pressed) + if (pressed) { - __CtrlButtonDown(map[i].sceCtrl); - } + __CtrlButtonDown(map[i].sceCtrl); + } else { - __CtrlButtonUp(map[i].sceCtrl); - } - } + __CtrlButtonUp(map[i].sceCtrl); + } + } - __CtrlSetAnalogX(input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 32768.0f, CTRL_STICK_LEFT); - __CtrlSetAnalogY(input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / -32768.0f, CTRL_STICK_LEFT); - __CtrlSetAnalogX(input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 32768.0f, CTRL_STICK_RIGHT); - __CtrlSetAnalogY(input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / -32768.0f, CTRL_STICK_RIGHT); + __CtrlSetAnalogX(input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 32768.0f, CTRL_STICK_LEFT); + __CtrlSetAnalogY(input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / -32768.0f, CTRL_STICK_LEFT); + __CtrlSetAnalogX(input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 32768.0f, CTRL_STICK_RIGHT); + __CtrlSetAnalogY(input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / -32768.0f, CTRL_STICK_RIGHT); } -void retro_run(void) { - if (PSP_IsIniting()) { - std::string error_string; +void retro_run(void) +{ + if (PSP_IsIniting()) + { + std::string error_string; #if 0 - if (!PSP_InitUpdate(&error_string)) - { - graphics_context->SwapBuffers(); - return; - } + if (!PSP_InitUpdate(&error_string)) + { + graphics_context->SwapBuffers(); + return; + } #else - while (!PSP_InitUpdate(&error_string)) { - sleep_ms(4); - } + while (!PSP_InitUpdate(&error_string)) + sleep_ms(4); #endif - if (!PSP_IsInited()) { - ERROR_LOG(BOOT, "%s", error_string.c_str()); - environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, nullptr); - return; - } - } + if (!PSP_IsInited()) + { + ERROR_LOG(BOOT, "%s", error_string.c_str()); + environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, nullptr); + return; + } + } - check_variables(PSP_CoreParameter()); + check_variables(PSP_CoreParameter()); - retro_input(); + retro_input(); - if (useEmuThread) { - if(emuThreadState == EmuThreadState::PAUSED || emuThreadState == EmuThreadState::PAUSE_REQUESTED) { - ctx->SwapBuffers(); - return; - } + if (useEmuThread) + { + if( emuThreadState == EmuThreadState::PAUSED || + emuThreadState == EmuThreadState::PAUSE_REQUESTED) + { + ctx->SwapBuffers(); + return; + } - if (emuThreadState != EmuThreadState::RUNNING) { - EmuThreadStart(); - } + if (emuThreadState != EmuThreadState::RUNNING) + EmuThreadStart(); - if (!ctx->ThreadFrame()) { - return; - } - } else { - EmuFrame(); - } + if (!ctx->ThreadFrame()) + return; + } + else + EmuFrame(); - ctx->SwapBuffers(); + ctx->SwapBuffers(); } unsigned retro_get_region(void) { return RETRO_REGION_NTSC; } -bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num) { - (void)type; - (void)info; - (void)num; - return false; -} +bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num) { return false; } -namespace SaveState { -struct SaveStart { - void DoState(PointerWrap &p); -}; +namespace SaveState +{ + struct SaveStart + { + void DoState(PointerWrap &p); + }; } // namespace SaveState -size_t retro_serialize_size(void) { - // TODO: Libretro API extension to use the savestate queue - if (useEmuThread) { - EmuThreadPause(); - } +size_t retro_serialize_size(void) +{ + SaveState::SaveStart state; + // TODO: Libretro API extension to use the savestate queue + if (useEmuThread) + EmuThreadPause(); - SaveState::SaveStart state; - return (CChunkFileReader::MeasurePtr(state) + 0x800000) & ~0x7FFFFF; // We don't unpause intentionally + return (CChunkFileReader::MeasurePtr(state) + 0x800000) + & ~0x7FFFFF; // We don't unpause intentionally } -bool retro_serialize(void *data, size_t size) { - // TODO: Libretro API extension to use the savestate queue - if (useEmuThread) { - EmuThreadPause(); // Does nothing if already paused - } +bool retro_serialize(void *data, size_t size) +{ + bool retVal; + SaveState::SaveStart state; + // TODO: Libretro API extension to use the savestate queue + if (useEmuThread) + EmuThreadPause(); // Does nothing if already paused - SaveState::SaveStart state; - assert(CChunkFileReader::MeasurePtr(state) <= size); - bool retVal = CChunkFileReader::SavePtr((u8 *)data, state) == CChunkFileReader::ERROR_NONE; + assert(CChunkFileReader::MeasurePtr(state) <= size); + retVal = CChunkFileReader::SavePtr((u8 *)data, state) + == CChunkFileReader::ERROR_NONE; - if (useEmuThread) { - EmuThreadStart(); - sleep_ms(4); - } + if (useEmuThread) + { + EmuThreadStart(); + sleep_ms(4); + } - return retVal; + return retVal; } -bool retro_unserialize(const void *data, size_t size) { - // TODO: Libretro API extension to use the savestate queue - if (useEmuThread) { - EmuThreadPause(); // Does nothing if already paused - } +bool retro_unserialize(const void *data, size_t size) +{ + bool retVal; + SaveState::SaveStart state; + // TODO: Libretro API extension to use the savestate queue + if (useEmuThread) + EmuThreadPause(); // Does nothing if already paused - SaveState::SaveStart state; - bool retVal = CChunkFileReader::LoadPtr((u8 *)data, state) == CChunkFileReader::ERROR_NONE; + retVal = CChunkFileReader::LoadPtr((u8 *)data, state) + == CChunkFileReader::ERROR_NONE; - if (useEmuThread) { - EmuThreadStart(); - sleep_ms(4); - } + if (useEmuThread) + { + EmuThreadStart(); + sleep_ms(4); + } - return retVal; + return retVal; } -void *retro_get_memory_data(unsigned id) { - if ( id == RETRO_MEMORY_SYSTEM_RAM ) { - return Memory::GetPointerUnchecked(PSP_GetKernelMemoryBase()) ; - } - return NULL; +void *retro_get_memory_data(unsigned id) +{ + if ( id == RETRO_MEMORY_SYSTEM_RAM ) + return Memory::GetPointerUnchecked(PSP_GetKernelMemoryBase()) ; + return NULL; } -size_t retro_get_memory_size(unsigned id) { - if ( id == RETRO_MEMORY_SYSTEM_RAM ) { +size_t retro_get_memory_size(unsigned id) +{ + if ( id == RETRO_MEMORY_SYSTEM_RAM ) return Memory::g_MemorySize ; - } return 0; } void retro_cheat_reset(void) {} -void retro_cheat_set(unsigned index, bool enabled, const char *code) { - (void)index; - (void)enabled; - (void)code; +void retro_cheat_set(unsigned index, bool enabled, const char *code) { } + +int System_GetPropertyInt(SystemProperty prop) +{ + switch (prop) + { + case SYSPROP_AUDIO_SAMPLE_RATE: + return SAMPLERATE; + default: + break; + } + + return -1; } -int System_GetPropertyInt(SystemProperty prop) { - switch (prop) { - case SYSPROP_AUDIO_SAMPLE_RATE: - return SAMPLERATE; - default: - return -1; - } -} +float System_GetPropertyFloat(SystemProperty prop) +{ + switch (prop) + { + case SYSPROP_DISPLAY_REFRESH_RATE: + return 60.f; + default: + break; + } -float System_GetPropertyFloat(SystemProperty prop) { - switch (prop) { - case SYSPROP_DISPLAY_REFRESH_RATE: - return 60.f; - default: - return -1; - } + return -1; } std::string System_GetProperty(SystemProperty prop) { return ""; } @@ -832,7 +885,5 @@ void NativeResized() {} #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) std::vector __cameraGetDeviceList() { return std::vector(); } -void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function cb) { - cb(false, ""); -} +void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function cb) { cb(false, ""); } #endif From b8ad9c4d38d34c6f6ad7eb5f7bb8d504eab683d8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 13 Jul 2020 21:12:41 +0200 Subject: [PATCH 240/848] (Libretro) Add MSVC 2019 target --- libretro/Makefile | 107 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/libretro/Makefile b/libretro/Makefile index 28d145afed..daeafa35dd 100644 --- a/libretro/Makefile +++ b/libretro/Makefile @@ -376,6 +376,113 @@ else ifneq (,$(findstring windows_msvc2017,$(platform))) GL_LIB := opengl32.lib LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib d3d9.lib d3dx9.lib +# Windows MSVC 2019 all architectures +else ifneq (,$(findstring windows_msvc2019,$(platform))) + + PlatformSuffix = $(subst windows_msvc2019_,,$(platform)) + ifneq (,$(findstring desktop,$(PlatformSuffix))) + WinPartition = desktop + MSVC2019CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_UNICODE -DUNICODE -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 + LDFLAGS += -MANIFEST -NXCOMPAT -DYNAMICBASE -DEBUG -OPT:REF -INCREMENTAL:NO -SUBSYSTEM:WINDOWS -MANIFESTUAC:"level='asInvoker' uiAccess='false'" -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 + LIBS += kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib + else ifneq (,$(findstring uwp,$(PlatformSuffix))) + WinPartition = uwp + MSVC2019CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_APP -DWINDLL -D_UNICODE -DUNICODE -DWRL_NO_DEFAULT_LIB + LDFLAGS += -APPCONTAINER -NXCOMPAT -DYNAMICBASE -MANIFEST:NO -OPT:REF -SUBSYSTEM:CONSOLE -MANIFESTUAC:NO -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 -DEBUG:FULL -WINMD:NO + LIBS += WindowsApp.lib + endif + + CFLAGS += $(MSVC2019CompileFlags) -nologo + CXXFLAGS += $(MSVC2019CompileFlags) -nologo -EHsc + + TargetArchMoniker = $(subst $(WinPartition)_,,$(PlatformSuffix)) + + CC = cl.exe + CXX = cl.exe + + SPACE := + SPACE := $(SPACE) $(SPACE) + BACKSLASH := + BACKSLASH := \$(BACKSLASH) + filter_out1 = $(filter-out $(firstword $1),$1) + filter_out2 = $(call filter_out1,$(call filter_out1,$1)) + + reg_query = $(call filter_out2,$(subst $2,,$(shell reg query "$2" -v "$1" 2>nul))) + fix_path = $(subst $(SPACE),\ ,$(subst \,/,$1)) + + b1 := ( + b2 := ) + ProgramFiles86w := $(ProgramFiles$(b1)x86$(b2)) + ProgramFiles86 := $(shell cygpath "$(ProgramFiles86w)") + + WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0) + WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0) + WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0) + WindowsSdkDir ?= $(call reg_query,InstallationFolder,HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0) + WindowsSdkDir := $(WindowsSdkDir) + + WindowsSDKVersion ?= $(firstword $(foreach folder,$(subst $(subst \,/,$(WindowsSdkDir)Include/),,$(wildcard $(call fix_path,$(WindowsSdkDir)Include\*))),$(if $(wildcard $(call fix_path,$(WindowsSdkDir)Include/$(folder)/um/Windows.h)),$(folder),)))$(BACKSLASH) + WindowsSDKVersion := $(WindowsSDKVersion) + + VsInstallBuildTools = $(ProgramFiles86)/Microsoft Visual Studio/2019/BuildTools + VsInstallEnterprise = $(ProgramFiles86)/Microsoft Visual Studio/2019/Enterprise + VsInstallProfessional = $(ProgramFiles86)/Microsoft Visual Studio/2019/Professional + VsInstallCommunity = $(ProgramFiles86)/Microsoft Visual Studio/2019/Community + + VsInstallRoot ?= $(shell if [ -d "$(VsInstallBuildTools)" ]; then echo "$(VsInstallBuildTools)"; fi) + ifeq ($(VsInstallRoot), ) + VsInstallRoot = $(shell if [ -d "$(VsInstallEnterprise)" ]; then echo "$(VsInstallEnterprise)"; fi) + endif + ifeq ($(VsInstallRoot), ) + VsInstallRoot = $(shell if [ -d "$(VsInstallProfessional)" ]; then echo "$(VsInstallProfessional)"; fi) + endif + ifeq ($(VsInstallRoot), ) + VsInstallRoot = $(shell if [ -d "$(VsInstallCommunity)" ]; then echo "$(VsInstallCommunity)"; fi) + endif + VsInstallRoot := $(VsInstallRoot) + + VcCompilerToolsVer := $(shell cat "$(VsInstallRoot)/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt" | grep -o '[0-9\.]*') + VcCompilerToolsDir := $(VsInstallRoot)/VC/Tools/MSVC/$(VcCompilerToolsVer) + VcCompilerLibDir := $(VcCompilerToolsDir)/lib/$(TargetArchMoniker) + + WindowsSDKSharedIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\shared") + WindowsSDKUCRTIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\ucrt") + WindowsSDKUMIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\$(WindowsSDKVersion)\um") + WindowsSDKUCRTLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\$(WindowsSDKVersion)\ucrt\$(TargetArchMoniker)") + WindowsSDKUMLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\$(WindowsSDKVersion)\um\$(TargetArchMoniker)") + + LIB := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerLibDir)") + INCLUDE := $(shell IFS=$$'\n'; cygpath -w "$(VcCompilerToolsDir)/include") + + # For some reason the HostX86 compiler doesn't like compiling for x64 + # ("no such file" opening a shared library), and vice-versa. + # Work around it for now by using the strictly x86 compiler for x86, and x64 for x64. + # NOTE: What about ARM? + ifneq (,$(findstring x64,$(TargetArchMoniker))) + override TARGET_ARCH = x86_64 + VCCompilerToolsBinDir := $(VcCompilerToolsDir)/bin/HostX64/$(TargetArchMoniker) + LIB := $(LIB);$(CORE_DIR)/dx9sdk/Lib/x64 + else + override TARGET_ARCH = x86 + VCCompilerToolsBinDir := $(VcCompilerToolsDir)/bin/HostX86/$(TargetArchMoniker) + LIB := $(LIB);$(CORE_DIR)/dx9sdk/Lib/x86 + endif + + PATH := $(shell IFS=$$'\n'; cygpath "$(VCCompilerToolsBinDir)"):$(PATH) + PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VsInstallRoot)/Common7/IDE") + + export INCLUDE := $(INCLUDE);$(WindowsSDKSharedIncludeDir);$(WindowsSDKUCRTIncludeDir);$(WindowsSDKUMIncludeDir) + export LIB := $(LIB);$(WindowsSDKUCRTLibDir);$(WindowsSDKUMLibDir);$(FFMPEGDIR)/Windows/$(TARGET_ARCH)/lib + TARGET := $(TARGET_NAME)_libretro.dll + PSS_STYLE :=2 + LDFLAGS += -DLL + PLATFORM_EXT := win32 + FFMPEGINCFLAGS += -I$(FFMPEGDIR)/Windows/$(TARGET_ARCH)/include + FFMPEGLIBDIR := $(FFMPEGDIR)/Windows/$(TARGET_ARCH)/lib + FFMPEGLDFLAGS += -LIBPATH:$(FFMPEGLIBDIR) + GL_LIB := opengl32.lib + LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib d3d9.lib d3dx9.lib + # Windows else ifneq (,$(findstring win,$(platform))) TARGET := $(TARGET_NAME)_libretro.dll From 53b2ab191bb62fe2e5c25ff28070c06095799e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 13 Jul 2020 23:31:51 +0200 Subject: [PATCH 241/848] Revert "Disable a new compiler warning that doesn't do us much good" This reverts commit e3a807fdc1f01b3a038d0c1609333d04d5d47528. --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d2b57d561..ee98014740 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,7 +273,6 @@ if(NOT MSVC) add_definitions(-Wno-multichar) add_definitions(-Wno-deprecated-register) add_definitions(-Wno-tautological-pointer-compare) - add_definitions(-Wformat-overflow) # Don't compile with strict aliasing, we're not 100% aliasing-safe add_compile_options(-fno-strict-aliasing) From 131a1eedfb33f51a65409f214e76c454a3edd2cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 13 Jul 2020 23:11:52 +0200 Subject: [PATCH 242/848] Vulkan: Make sure textures/samplers are unbound at the end of PresentationCommon::CopyToOutput. Validation caught an issue where old stuff lingered in sampler 1 and texture 1. Bug probably introduced in #12921, but could also be others. --- GPU/Common/PresentationCommon.cpp | 1 + ext/native/thin3d/thin3d.h | 4 ++-- ext/native/thin3d/thin3d_d3d11.cpp | 6 ++++++ ext/native/thin3d/thin3d_d3d9.cpp | 6 ++++++ ext/native/thin3d/thin3d_gl.cpp | 9 +++++++++ ext/native/thin3d/thin3d_vulkan.cpp | 24 ++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index f0bda76a8b..09bf2c2009 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -748,6 +748,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u DoRelease(srcFramebuffer_); DoRelease(srcTexture_); + // Unbinds all textures and samplers too, needed since sometimes a MakePixelTexture is deleted etc. draw_->BindPipeline(nullptr); } diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 4e61672b7f..f78dbf8f87 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -643,7 +643,7 @@ public: BindTextures(stage, 1, textures); } // from sampler 0 and upwards - // Call this with 0 to signal that you have been drawing on your own, and need the state reset on the next pipeline bind. + // Call this with nullptr to signal that you're done with the stuff you've bound, like textures and samplers and stuff. virtual void BindPipeline(Pipeline *pipeline) = 0; virtual void Draw(int vertexCount, int offset) = 0; @@ -652,7 +652,7 @@ public: // Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here. virtual void BeginFrame() {} - virtual void EndFrame() {} + virtual void EndFrame() = 0; virtual void WipeQueue() {} // This should be avoided as much as possible, in favor of clearing when binding a render target, which is native diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 96b9e1ad63..8c53ffc7d8 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -100,6 +100,8 @@ public: stencilRefDirty_ = true; } + void EndFrame() override; + void Draw(int vertexCount, int offset) override; void DrawIndexed(int vertexCount, int offset) override; void DrawUP(const void *vdata, int vertexCount) override; @@ -363,6 +365,10 @@ void D3D11DrawContext::HandleEvent(Event ev, int width, int height, void *param1 } } +void D3D11DrawContext::EndFrame() { + curPipeline_ = nullptr; +} + void D3D11DrawContext::SetViewports(int count, Viewport *viewports) { D3D11_VIEWPORT vp[4]; for (int i = 0; i < count; i++) { diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index d8556210ea..0b6740963f 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -559,6 +559,8 @@ public: curPipeline_ = (D3D9Pipeline *)pipeline; } + void EndFrame() override; + void UpdateDynamicUniformBuffer(const void *ub, size_t size) override; // Raster state @@ -802,6 +804,10 @@ void D3D9Context::BindTextures(int start, int count, Texture **textures) { } } +void D3D9Context::EndFrame() { + curPipeline_ = nullptr; +} + static void SemanticToD3D9UsageAndIndex(int semantic, BYTE *usage, BYTE *index) { *index = 0; switch (semantic) { diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index b168cb02a5..bc2eece379 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -618,6 +618,15 @@ void OpenGLContext::EndFrame() { FrameData &frameData = frameData_[renderManager_.GetCurFrame()]; renderManager_.EndPushBuffer(frameData.push); // upload the data! renderManager_.Finish(); + + // Unbind stuff. + for (auto &texture : boundTextures_) { + texture = nullptr; + } + for (auto &sampler : boundSamplers_) { + sampler = nullptr; + } + curPipeline_ = nullptr; } InputLayout *OpenGLContext::CreateInputLayout(const InputLayoutDesc &desc) { diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 7bab539197..7e161fe515 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -406,8 +406,13 @@ public: void BindSamplerStates(int start, int count, SamplerState **state) override; void BindTextures(int start, int count, Texture **textures) override; + void BindPipeline(Pipeline *pipeline) override { curPipeline_ = (VKPipeline *)pipeline; + + if (!pipeline) { + UnbindBoundState(); + } } // TODO: Make VKBuffers proper buffers, and do a proper binding model. This is just silly. @@ -494,6 +499,8 @@ public: } private: + void UnbindBoundState(); + VulkanTexture *GetNullTexture(); VulkanContext *vulkan_ = nullptr; @@ -913,6 +920,23 @@ void VKContext::EndFrame() { renderManager_.Finish(); push_ = nullptr; + + // Unbind stuff, to avoid accidentally relying on it across frames (and provide some protection against forgotten unbinds of deleted things). + UnbindBoundState(); +} + +void VKContext::UnbindBoundState() { + curPipeline_ = nullptr; + + for (auto &view : boundImageView_) { + view = nullptr; + } + for (auto &sampler : boundSamplers_) { + sampler = nullptr; + } + for (auto &texture : boundTextures_) { + texture = nullptr; + } } void VKContext::WipeQueue() { From 9ebb402e4fa9900a9b94ed64814c4386e50c0437 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 13 Jul 2020 18:19:36 -0700 Subject: [PATCH 243/848] Vulkan: Buildfix. --- ext/native/thin3d/thin3d_vulkan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 7e161fe515..04bf3bb021 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -929,7 +929,7 @@ void VKContext::UnbindBoundState() { curPipeline_ = nullptr; for (auto &view : boundImageView_) { - view = nullptr; + view = VK_NULL_HANDLE; } for (auto &sampler : boundSamplers_) { sampler = nullptr; From 143ba22097dab9f0789657f153a1465f75cc2f79 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 21:21:16 -0700 Subject: [PATCH 244/848] PPGe: Handle text shadows more consistently. Don't really want them wrapping differently or etc. Let's handle centrally so we can make them consistent and better. --- Core/Dialog/PSPDialog.cpp | 24 +++++--- Core/Dialog/PSPDialog.h | 2 + Core/Dialog/PSPMsgDialog.cpp | 19 ++----- Core/Dialog/PSPNetconfDialog.cpp | 16 ++++-- Core/Dialog/PSPOskDialog.cpp | 78 +++++++++++++++----------- Core/Dialog/PSPSaveDialog.cpp | 48 ++++++++-------- Core/Util/PPGeDraw.cpp | 96 +++++++++++++++++++++----------- Core/Util/PPGeDraw.h | 16 ++++-- 8 files changed, 179 insertions(+), 120 deletions(-) diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp index 8bc866c731..f77682848c 100644 --- a/Core/Dialog/PSPDialog.cpp +++ b/Core/Dialog/PSPDialog.cpp @@ -198,6 +198,16 @@ bool PSPDialog::IsButtonHeld(int checkButton, int &framesHeld, int framesHeldThr return false; } +PPGeStyle PSPDialog::FadedStyle(PPGeAlign align, float scale) { + PPGeStyle textStyle; + textStyle.align = align; + textStyle.scale = scale; + textStyle.color = CalcFadedColor(textStyle.color); + textStyle.hasShadow = true; + textStyle.shadowColor = CalcFadedColor(textStyle.shadowColor); + return textStyle; +} + void PSPDialog::DisplayButtons(int flags, const char *caption) { bool useCaption = false; @@ -207,6 +217,8 @@ void PSPDialog::DisplayButtons(int flags, const char *caption) truncate_cpy(safeCaption, caption); } + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_LEFT, FONT_SCALE); + auto di = GetI18NCategory("Dialog"); float x1 = 183.5f, x2 = 261.5f; if (GetCommonParam()->buttonSwap == 1) { @@ -215,16 +227,12 @@ void PSPDialog::DisplayButtons(int flags, const char *caption) } if (flags & DS_BUTTON_OK) { const char *text = useCaption ? safeCaption : di->T("Enter"); - PPGeDrawImage(okButtonImg, x2, 258, 11.5f, 11.5f, 0, CalcFadedColor(0x80000000)); - PPGeDrawImage(okButtonImg, x2, 256, 11.5f, 11.5f, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(text, x2 + 15.5f, 254, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(text, x2 + 14.5f, 252, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(okButtonImg, x2, 256, 11.5f, 11.5f, textStyle); + PPGeDrawText(text, x2 + 14.5f, 252, textStyle); } if (flags & DS_BUTTON_CANCEL) { const char *text = useCaption ? safeCaption : di->T("Back"); - PPGeDrawText(text, x1 + 15.5f, 254, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(text, x1 + 14.5f, 252, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawImage(cancelButtonImg, x1, 258, 11.5f, 11.5f, 0, CalcFadedColor(0x80000000)); - PPGeDrawImage(cancelButtonImg, x1, 256, 11.5f, 11.5f, 0, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(cancelButtonImg, x1, 256, 11.5f, 11.5f, textStyle); + PPGeDrawText(text, x1 + 14.5f, 252, textStyle); } } diff --git a/Core/Dialog/PSPDialog.h b/Core/Dialog/PSPDialog.h index 4de49d27f0..8d88c5c1a7 100644 --- a/Core/Dialog/PSPDialog.h +++ b/Core/Dialog/PSPDialog.h @@ -22,6 +22,7 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" #include "Common/Swap.h" +#include "Core/Util/PPGeDraw.h" class PointerWrap; @@ -83,6 +84,7 @@ public: void StartDraw(); void EndDraw(); protected: + PPGeStyle FadedStyle(PPGeAlign align, float scale); void UpdateButtons(); bool IsButtonPressed(int checkButton); bool IsButtonHeld(int checkButton, int &framesHeld, int framesHeldThreshold = 30, int framesHeldRepeatRate = 10); diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index 22960aa7a1..b40fc05857 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -153,23 +153,20 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) float h2 = h / 2.0f; ey = y + h2 + 20.0f; + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE); + if (hasYesNo) { auto di = GetI18NCategory("Dialog"); const char *choiceText; - u32 yesColor, noColor; float x, w; if (yesnoChoice == 1) { choiceText = di->T("Yes"); x = 204.0f; - yesColor = 0xFFFFFFFF; - noColor = 0xFFFFFFFF; } else { choiceText = di->T("No"); x = 273.0f; - yesColor = 0xFFFFFFFF; - noColor = 0xFFFFFFFF; } PPGeMeasureText(&w, &h, choiceText, FONT_SCALE); w = 15.0f; @@ -178,10 +175,8 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) h2 += h + 5.0f; y = 135.0f - h; PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x6DCFCFCF)); - PPGeDrawText(di->T("Yes"), 204.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("Yes"), 203.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(yesColor)); - PPGeDrawText(di->T("No"), 273.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("No"), 272.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(noColor)); + PPGeDrawText(di->T("Yes"), 203.0f, y2 - 1.0f, textStyle); + PPGeDrawText(di->T("No"), 272.0f, y2 - 1.0f, textStyle); if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) { yesnoChoice = 1; } @@ -201,13 +196,11 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) h2 += h + 5.0f; y = 135.0f - h; PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x6DCFCFCF)); - PPGeDrawText(di->T("OK"), 240.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("OK"), 239.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("OK"), 239.0f, y2 - 1.0f, textStyle); ey = y2 + 25.0f; } - PPGeDrawTextWrapped(text.c_str(), 241.0f, y+2, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, 0, textStyle); sy = 125.0f - h2; PPGeDrawRect(40.0f, sy, 440.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawRect(40.0f, ey, 440.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 37332f926b..998f5745cf 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -65,10 +65,13 @@ void PSPNetconfDialog::DrawBanner() { PPGeDrawRect(0, 0, 480, 23, CalcFadedColor(0x65636358)); + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f); + textStyle.hasShadow = false; + // TODO: Draw a hexagon icon - PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, textStyle.color); auto di = GetI18NCategory("Dialog"); - PPGeDrawText(di->T("Network Connection"), 30, 11, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("Network Connection"), 30, 11, textStyle); } int PSPNetconfDialog::Update(int animSpeed) { @@ -83,14 +86,17 @@ int PSPNetconfDialog::Update(int animSpeed) { const ImageID confirmBtnImage = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? ImageID("I_CROSS") : ImageID("I_CIRCLE"); const int confirmBtn = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? CTRL_CROSS : CTRL_CIRCLE; + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, 0.5f); + PPGeStyle buttonStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f); + if (request.netAction == NETCONF_CONNECT_APNET || request.netAction == NETCONF_STATUS_APNET || request.netAction == NETCONF_CONNECT_APNET_LAST) { UpdateFade(animSpeed); StartDraw(); DrawBanner(); PPGeDrawRect(0, 0, 480, 272, CalcFadedColor(0x63636363)); - PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawImage(confirmBtnImage, 195, 250, 20, 20, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("OK"), 225, 252, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, 0, textStyle); + PPGeDrawImage(confirmBtnImage, 195, 250, 20, 20, buttonStyle); + PPGeDrawText(di->T("OK"), 225, 252, buttonStyle); if (IsButtonPressed(confirmBtn)) { StartFade(false); diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index dbe5ae697b..f60f41ce5e 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -766,7 +766,18 @@ void PSPOskDialog::RenderKeyboard() float previewLeftSide = (480.0f - (12.0f * drawLimit)) / 2.0f; float title = (480.0f - (0.5f * drawLimit)) / 2.0f; - PPGeDrawText(oskDesc.c_str(), title , 20, PPGeAlign::BOX_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeStyle descStyle = FadedStyle(PPGeAlign::BOX_CENTER, 0.5f); + descStyle.hasShadow = false; + PPGeDrawText(oskDesc.c_str(), title, 20, descStyle); + + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.5f); + textStyle.hasShadow = false; + + PPGeStyle keyStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.6f); + keyStyle.hasShadow = false; + PPGeStyle selectedKeyStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.6f); + selectedKeyStyle.color = CalcFadedColor(0xFF3060FF); + selectedKeyStyle.hasShadow = false; std::u16string result; @@ -776,12 +787,11 @@ void PSPOskDialog::RenderKeyboard() drawIndex = result.size() == limit + 1 ? drawIndex - 1 : drawIndex; // When the length reached limit, the last character don't fade in and out. for (u32 i = 0; i < drawLimit; ++i, ++drawIndex) { - u32 color = CalcFadedColor(0xFFFFFFFF); if (drawIndex + 1 < result.size()) { temp[0] = result[drawIndex]; ConvertUCS2ToUTF8(buffer, temp); - PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); + PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, textStyle); } else { @@ -794,25 +804,25 @@ void PSPOskDialog::RenderKeyboard() float animStep = (float)(__DisplayGetNumVblanks() % 40) / 20.0f; // Fade in and out the next character so they know it's not part of the string yet. u32 alpha = (0.5f - (cosf(animStep * M_PI) / 2.0f)) * 128 + 127; - color = CalcFadedColor((alpha << 24) | 0xFFFFFF); + PPGeStyle animStyle = textStyle; + animStyle.color = CalcFadedColor((alpha << 24) | 0x00FFFFFF); ConvertUCS2ToUTF8(buffer, temp); - PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); + PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, animStyle); // Also draw the underline for the same reason. - color = CalcFadedColor(0xFFFFFFFF); - PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); + PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, textStyle); } else { ConvertUCS2ToUTF8(buffer, temp); - PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); + PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, textStyle); } } else { - PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color); + PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, textStyle); } } } @@ -821,17 +831,16 @@ void PSPOskDialog::RenderKeyboard() { for (int col = 0; col < numKeyCols[currentKeyboard]; ++col) { - u32 color = CalcFadedColor(0xFFFFFFFF); - if (selectedRow == row && col == selectedCol) - color = CalcFadedColor(0xFF3060FF); - temp[0] = oskKeys[currentKeyboard][row][col]; ConvertUCS2ToUTF8(buffer, temp); - PPGeDrawText(buffer.c_str(), keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), PPGeAlign::BOX_HCENTER, 0.6f, color); - if (selectedRow == row && col == selectedCol) - PPGeDrawText("_", keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), PPGeAlign::BOX_HCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); + if (selectedRow == row && col == selectedCol) { + PPGeDrawText(buffer.c_str(), keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), selectedKeyStyle); + PPGeDrawText("_", keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), keyStyle); + } else { + PPGeDrawText(buffer.c_str(), keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), keyStyle); + } } } } @@ -944,22 +953,27 @@ int PSPOskDialog::Update(int animSpeed) { auto di = GetI18NCategory("Dialog"); - PPGeDrawImage(ImageID("I_SQUARE"), 365, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("Space"), 390, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeStyle actionStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f); + actionStyle.hasShadow = false; + PPGeStyle guideStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.6f); + guideStyle.hasShadow = false; + + PPGeDrawImage(ImageID("I_SQUARE"), 365, 222, 16, 16, guideStyle); + PPGeDrawText(di->T("Space"), 390, 222, actionStyle); if (g_Config.iButtonPreference != PSP_SYSTEMPARAM_BUTTON_CIRCLE) { - PPGeDrawImage(ImageID("I_CROSS"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawImage(ImageID("I_CIRCLE"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(ImageID("I_CROSS"), 45, 222, 16, 16, guideStyle); + PPGeDrawImage(ImageID("I_CIRCLE"), 45, 247, 16, 16, guideStyle); } else { - PPGeDrawImage(ImageID("I_CIRCLE"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawImage(ImageID("I_CROSS"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(ImageID("I_CIRCLE"), 45, 222, 16, 16, guideStyle); + PPGeDrawImage(ImageID("I_CROSS"), 45, 247, 16, 16, guideStyle); } - PPGeDrawText(di->T("Select"), 75, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("Delete"), 75, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(di->T("Select"), 75, 222, actionStyle); + PPGeDrawText(di->T("Delete"), 75, 247, actionStyle); - PPGeDrawText("Start", 135, 220, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("Finish"), 185, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("Start", 135, 220, guideStyle); + PPGeDrawText(di->T("Finish"), 185, 222, actionStyle); auto lookupLangName = [&](int direction) { // First, find the valid one... @@ -983,20 +997,20 @@ int PSPOskDialog::Update(int animSpeed) { }; if (OskKeyboardNames[currentKeyboardLanguage] != "ko_KR" && IsKeyboardShiftValid(oskParams->fields[0].inputtype, currentKeyboardLanguage, currentKeyboard)) { - PPGeDrawText("Select", 135, 245, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(di->T("Shift"), 185, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("Select", 135, 245, guideStyle); + PPGeDrawText(di->T("Shift"), 185, 247, actionStyle); } const char *prevLang = lookupLangName(-1); if (prevLang) { - PPGeDrawText("L", 235, 220, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(prevLang, 255, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("L", 235, 220, guideStyle); + PPGeDrawText(prevLang, 255, 222, actionStyle); } const char *nextLang = lookupLangName(1); if (nextLang) { - PPGeDrawText("R", 235, 245, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(nextLang, 255, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText("R", 235, 245, guideStyle); + PPGeDrawText(nextLang, 255, 247, actionStyle); } if (IsButtonPressed(CTRL_UP) || IsButtonHeld(CTRL_UP, upBtnFramesHeld, framesHeldThreshold, framesHeldRepeatRate)) { diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index c78c6055bf..c2d3b0a8f7 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -282,6 +282,10 @@ void PSPSaveDialog::DisplayBanner(int which) { auto di = GetI18NCategory("Dialog"); PPGeDrawRect(0, 0, 480, 23, CalcFadedColor(0x65636358)); + + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f); + textStyle.hasShadow = false; + const char *title; switch (which) { @@ -299,8 +303,8 @@ void PSPSaveDialog::DisplayBanner(int which) break; } // TODO: Draw a hexagon icon - PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(title, 30, 11, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, textStyle.color); + PPGeDrawText(title, 30, 11, textStyle); } void PSPSaveDialog::DisplaySaveList(bool canMove) { @@ -395,7 +399,8 @@ void PSPSaveDialog::DisplaySaveDataInfo1() std::lock_guard guard(paramLock); if (param.GetFileInfo(currentSelectedSave).size == 0) { auto di = GetI18NCategory("Dialog"); - PPGeDrawText(di->T("NEW DATA"), 180, 136, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f); + PPGeDrawText(di->T("NEW DATA"), 180, 136, textStyle); } else { char title[512]; char time[512]; @@ -452,14 +457,15 @@ void PSPSaveDialog::DisplaySaveDataInfo1() std::string saveTitleTxt = saveTitle; std::string saveDetailTxt = saveDetail; - PPGeDrawText(titleTxt.c_str(), 181, 138, PPGeAlign::BOX_BOTTOM, 0.6f, CalcFadedColor(0x80000000)); - PPGeDrawText(titleTxt.c_str(), 180, 136, PPGeAlign::BOX_BOTTOM, 0.6f, CalcFadedColor(0xFFC0C0C0)); - PPGeDrawText(timeTxt.c_str(), 181, 139, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000)); - PPGeDrawText(timeTxt.c_str(), 180, 137, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(saveTitleTxt.c_str(), 176, 162, PPGeAlign::BOX_LEFT, 0.55f, CalcFadedColor(0x80000000)); - PPGeDrawText(saveTitleTxt.c_str(), 175, 159, PPGeAlign::BOX_LEFT, 0.55f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawTextWrapped(saveDetailTxt.c_str(), 176, 183, 480 - 175, 250 - 183, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000)); - PPGeDrawTextWrapped(saveDetailTxt.c_str(), 175, 181, 480 - 175, 250 - 181, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeStyle titleStyle = FadedStyle(PPGeAlign::BOX_BOTTOM, 0.6f); + PPGeStyle saveTitleStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.55f); + titleStyle.color = CalcFadedColor(0xFFC0C0C0); + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f); + + PPGeDrawText(titleTxt.c_str(), 180, 136, titleStyle); + PPGeDrawText(timeTxt.c_str(), 180, 137, textStyle); + PPGeDrawText(saveTitleTxt.c_str(), 175, 159, saveTitleStyle); + PPGeDrawTextWrapped(saveDetailTxt.c_str(), 175, 181, 480 - 175, 250 - 181, textStyle); } } @@ -525,13 +531,15 @@ void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) { snprintf(date, 256, "%d/%02d/%02d", year, month, day); } + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f); std::string saveinfoTxt = StringFromFormat("%.128s\n%s %s\n%lld KB", save_title, date, hour_time, sizeK); - PPGeDrawText(saveinfoTxt.c_str(), 9, 202, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000)); - PPGeDrawText(saveinfoTxt.c_str(), 8, 200, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(saveinfoTxt.c_str(), 8, 200, textStyle); } void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo) { + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE); + const float WRAP_WIDTH = 254.0f; float y = 136.0f, h; PPGeMeasureText(nullptr, &h, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH); @@ -540,19 +548,14 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo) { auto di = GetI18NCategory("Dialog"); const char *choiceText; - u32 yesColor, noColor; float x, w; if (yesnoChoice == 1) { choiceText = di->T("Yes"); x = 302.0f; - yesColor = 0xFFFFFFFF; - noColor = 0xFFFFFFFF; } else { choiceText = di->T("No"); x = 366.0f; - yesColor = 0xFFFFFFFF; - noColor = 0xFFFFFFFF; } PPGeMeasureText(&w, &h, choiceText, FONT_SCALE); w = w / 2.0f + 5.5f; @@ -561,10 +564,8 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo) h2 += h + 4.0f; y = 132.0f - h; PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x40C0C0C0)); - PPGeDrawText(di->T("Yes"), 303.0f, y2+2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("Yes"), 302.0f, y2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(yesColor)); - PPGeDrawText(di->T("No"), 367.0f, y2+2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawText(di->T("No"), 366.0f, y2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(noColor)); + PPGeDrawText(di->T("Yes"), 302.0f, y2, textStyle); + PPGeDrawText(di->T("No"), 366.0f, y2, textStyle); if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) { yesnoChoice = 1; } @@ -572,8 +573,7 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo) yesnoChoice = 0; } } - PPGeDrawTextWrapped(text.c_str(), 335.0f, y+2, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000)); - PPGeDrawTextWrapped(text.c_str(), 334.0f, y, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawTextWrapped(text.c_str(), 334.0f, y, WRAP_WIDTH, 0, textStyle); float sy = 122.0f - h2, ey = 150.0f + h2; PPGeDrawRect(202.0f, sy, 466.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawRect(202.0f, ey, 466.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 3e4efc8afb..688d11cb42 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -789,14 +789,14 @@ int GetPow2(int x) { return ret; } -static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, float scale, float maxWidth, bool wrap) { +static PPGeTextDrawerImage PPGeGetTextImage(const char *text, const PPGeStyle &style, float maxWidth, bool wrap) { int tdalign = 0; tdalign |= FLAG_ELLIPSIZE_TEXT; if (wrap) { tdalign |= FLAG_WRAP_TEXT; } - PPGeTextDrawerCacheKey key{ text, tdalign, maxWidth / scale }; + PPGeTextDrawerCacheKey key{ text, tdalign, maxWidth / style.scale }; PPGeTextDrawerImage im{}; auto cacheItem = textDrawerImages.find(key); @@ -805,7 +805,7 @@ static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, f cacheItem->second.entry.lastUsedFrame = gpuStats.numFlips; } else { std::vector bitmapData; - textDrawer->SetFontScale(scale, scale); + textDrawer->SetFontScale(style.scale, style.scale); Bounds b(0, 0, maxWidth, 272.0f); std::string cleaned = ReplaceAll(text, "\r", ""); textDrawer->DrawStringBitmapRect(bitmapData, im.entry, Draw::DataFormat::R8_UNORM, cleaned.c_str(), b, tdalign); @@ -842,7 +842,7 @@ static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, f return im; } -static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, PPGeAlign align, float scale, u32 color) { +static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, const PPGeStyle &style) { if (!im.ptr) { return; } @@ -855,41 +855,50 @@ static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, PPGeAlig WriteCmd(GE_CMD_TEXSIZE0, wp2 | (hp2 << 8)); WriteCmd(GE_CMD_TEXFLUSH, 0); - float w = im.entry.width * scale; - float h = im.entry.height * scale; + float w = im.entry.width * style.scale; + float h = im.entry.height * style.scale; - if (align & PPGeAlign::BOX_HCENTER) + if (style.align & PPGeAlign::BOX_HCENTER) x -= w / 2.0f; - else if (align & PPGeAlign::BOX_RIGHT) + else if (style.align & PPGeAlign::BOX_RIGHT) x -= w; - if (align & PPGeAlign::BOX_VCENTER) + if (style.align & PPGeAlign::BOX_VCENTER) y -= h / 2.0f; - else if (align & PPGeAlign::BOX_BOTTOM) + else if (style.align & PPGeAlign::BOX_BOTTOM) y -= h; BeginVertexData(); float u1 = (float)im.entry.width / (1 << wp2); float v1 = (float)im.entry.height / (1 << hp2); - Vertex(x, y, 0, 0, 1 << wp2, 1 << hp2, color); - Vertex(x + w, y + h, u1, v1, 1 << wp2, 1 << hp2, color); + if (style.hasShadow) { + Vertex(x + 1, y + 2, 0, 0, 1 << wp2, 1 << hp2, style.shadowColor); + Vertex(x + 1 + w, y + 2 + h, u1, v1, 1 << wp2, 1 << hp2, style.shadowColor); + } + Vertex(x, y, 0, 0, 1 << wp2, 1 << hp2, style.color); + Vertex(x + w, y + h, u1, v1, 1 << wp2, 1 << hp2, style.color); EndVertexDataAndDraw(GE_PRIM_RECTANGLES); PPGeSetDefaultTexture(); } -void PPGeDrawText(const char *text, float x, float y, PPGeAlign align, float scale, u32 color) { +void PPGeDrawText(const char *text, float x, float y, const PPGeStyle &style) { if (!text || !strlen(text)) { return; } if (HasTextDrawer()) { - PPGeTextDrawerImage im = PPGeGetTextImage(text, align, scale, 480.0f - x, false); - PPGeDrawTextImage(im, x, y, align, scale, color); + PPGeTextDrawerImage im = PPGeGetTextImage(text, style, 480.0f - x, false); + PPGeDrawTextImage(im, x, y, style); return; } - PPGePrepareText(text, x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS); - PPGeDrawCurrentText(color); + if (style.hasShadow) { + PPGePrepareText(text, x + 1, y + 2, style.align, style.scale, style.scale, PPGE_LINE_USE_ELLIPSIS); + PPGeDrawCurrentText(style.shadowColor); + } + + PPGePrepareText(text, x, y, style.align, style.scale, style.scale, PPGE_LINE_USE_ELLIPSIS); + PPGeDrawCurrentText(style.color); } static std::string StripTrailingWhite(const std::string &s) { @@ -915,7 +924,7 @@ static std::string CropLinesToCount(const std::string &s, int numLines) { return s.substr(0, len); } -void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, PPGeAlign align, float scale, u32 color) { +void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, const PPGeStyle &style) { std::string s = text; if (wrapHeight != 0.0f) { s = StripTrailingWhite(s); @@ -928,8 +937,11 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl float actualWidth, actualHeight; Bounds b(0, 0, wrapWidth <= 0 ? 480.0f - x : wrapWidth, wrapHeight); int tdalign = 0; - textDrawer->SetFontScale(scale, scale); + textDrawer->SetFontScale(style.scale, style.scale); textDrawer->MeasureStringRect(s.c_str(), s.size(), b, &actualWidth, &actualHeight, tdalign | FLAG_WRAP_TEXT); + + // Check if we need to scale the text down to fit better. + PPGeStyle adjustedStyle = style; if (wrapHeight != 0.0f && actualHeight > wrapHeight) { // Cheap way to get the line height. float oneLine, twoLines; @@ -945,16 +957,20 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl s = StripTrailingWhite(CropLinesToCount(s, (int)maxLines)) + "\n..."; } - scale *= wrapHeight / actualHeight; + adjustedStyle.scale *= wrapHeight / actualHeight; } - PPGeTextDrawerImage im = PPGeGetTextImage(s.c_str(), align, scale, wrapWidth <= 0 ? 480.0f - x : wrapWidth, true); - PPGeDrawTextImage(im, x, y, align, scale, color); + PPGeTextDrawerImage im = PPGeGetTextImage(s.c_str(), adjustedStyle, wrapWidth <= 0 ? 480.0f - x : wrapWidth, true); + PPGeDrawTextImage(im, x, y, adjustedStyle); return; } - PPGePrepareText(s.c_str(), x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); + int sx = style.hasShadow ? 1 : 0; + int sy = style.hasShadow ? 2 : 0; + PPGePrepareText(s.c_str(), x + sx, y + sy, style.align, style.scale, style.scale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); + float scale = style.scale; + float lineHeightScale = style.scale; float actualHeight = char_lines_metrics.lineHeight * char_lines_metrics.numLines; if (wrapHeight != 0.0f && actualHeight > wrapHeight) { if (actualHeight > wrapHeight * maxScaleDown) { @@ -967,11 +983,17 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl // Measure the text again after scaling down. PPGeResetCurrentText(); - float reduced = scale * wrapHeight / actualHeight; + float reduced = style.scale * wrapHeight / actualHeight; // Try to keep the font as large as possible, so reduce the line height some. - PPGePrepareText(s.c_str(), x, y, align, reduced * 1.15, reduced, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); + scale = reduced * 1.15f; + lineHeightScale = reduced; + PPGePrepareText(s.c_str(), x + sx, y + sy, style.align, scale, lineHeightScale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); } - PPGeDrawCurrentText(color); + if (style.hasShadow) { + PPGeDrawCurrentText(style.shadowColor); + PPGePrepareText(s.c_str(), x, y, style.align, scale, lineHeightScale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); + } + PPGeDrawCurrentText(style.color); } // Draws a "4-patch" for button-like things that can be resized @@ -1031,8 +1053,7 @@ void PPGeDrawRect(float x1, float y1, float x2, float y2, u32 color) { } // Just blits an image to the screen, multiplied with the color. -void PPGeDrawImage(ImageID atlasImage, float x, float y, int align, u32 color) -{ +void PPGeDrawImage(ImageID atlasImage, float x, float y, const PPGeStyle &style) { if (!dlPtr) return; @@ -1043,13 +1064,16 @@ void PPGeDrawImage(ImageID atlasImage, float x, float y, int align, u32 color) float w = img->w; float h = img->h; BeginVertexData(); - Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, color); - Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, color); + if (style.hasShadow) { + Vertex(x + 1, y + 2, img->u1, img->v1, atlasWidth, atlasHeight, style.shadowColor); + Vertex(x + 1 + w, y + 2 + h, img->u2, img->v2, atlasWidth, atlasHeight, style.shadowColor); + } + Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, style.color); + Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, style.color); EndVertexDataAndDraw(GE_PRIM_RECTANGLES); } -void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, int align, u32 color) -{ +void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, const PPGeStyle &style) { if (!dlPtr) return; @@ -1058,8 +1082,12 @@ void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, int a return; } BeginVertexData(); - Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, color); - Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, color); + if (style.hasShadow) { + Vertex(x + 1, y + 2, img->u1, img->v1, atlasWidth, atlasHeight, style.shadowColor); + Vertex(x + 1 + w, y + 2 + h, img->u2, img->v2, atlasWidth, atlasHeight, style.shadowColor); + } + Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, style.color); + Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, style.color); EndVertexDataAndDraw(GE_PRIM_RECTANGLES); } diff --git a/Core/Util/PPGeDraw.h b/Core/Util/PPGeDraw.h index 38eddea82c..b309a29a38 100644 --- a/Core/Util/PPGeDraw.h +++ b/Core/Util/PPGeDraw.h @@ -69,20 +69,28 @@ enum { PPGE_LINE_WRAP_CHAR = 4, }; +struct PPGeStyle { + PPGeAlign align = PPGeAlign::BOX_LEFT; + float scale = 1.0f; + uint32_t color = 0xFFFFFFFF; + bool hasShadow = false; + uint32_t shadowColor = 0x80000000; +}; + // Get the metrics of the bounding box of the text without changing the buffer or state. void PPGeMeasureText(float *w, float *h, const char *text, float scale, int WrapType = PPGE_LINE_NONE, int wrapWidth = 0); // Draws some text using the one font we have. // Clears the text buffer when done. -void PPGeDrawText(const char *text, float x, float y, PPGeAlign align, float scale = 1.0f, u32 color = 0xFFFFFFFF); -void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, PPGeAlign align, float scale = 1.0f, u32 color = 0xFFFFFFFF); +void PPGeDrawText(const char *text, float x, float y, const PPGeStyle &style); +void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, const PPGeStyle &style); // Draws a "4-patch" for button-like things that can be resized. void PPGeDraw4Patch(ImageID atlasImage, float x, float y, float w, float h, u32 color = 0xFFFFFFFF); // Just blits an image to the screen, multiplied with the color. -void PPGeDrawImage(ImageID atlasImage, float x, float y, int align, u32 color = 0xFFFFFFFF); -void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, int align, u32 color = 0xFFFFFFFF); +void PPGeDrawImage(ImageID atlasImage, float x, float y, const PPGeStyle &style); +void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, const PPGeStyle &style); void PPGeDrawImage(float x, float y, float w, float h, float u1, float v1, float u2, float v2, int tw, int th, u32 color); void PPGeNotifyFrame(); From 3586128d8d532e6bec39fde1a54457e9ff926980 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 21:42:30 -0700 Subject: [PATCH 245/848] PPGe: Draw nicer drop shadows. Only when we have a text drawer for text, because it really adds up. --- Core/Util/PPGeDraw.cpp | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 688d11cb42..ce03f15e8f 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -17,6 +17,7 @@ #include +#include "base/colorutil.h" #include "base/stringutil.h" #include "file/vfs.h" #include "gfx/texture_atlas.h" @@ -140,6 +141,7 @@ void PPGeSetTexture(u32 dataAddr, int width, int height); static void WriteCmd(u8 cmd, u32 data) { Memory::Write_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr); dlWritePtr += 4; + assert(dlWritePtr <= dlPtr + dlSize); } static void WriteCmdAddrWithBase(u8 cmd, u32 addr) { @@ -178,6 +180,7 @@ static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color Memory::WriteStruct(dataWritePtr, &vtx); dataWritePtr += sizeof(vtx); } + assert(dataWritePtr <= dataPtr + dataSize); vertexCount++; } @@ -871,8 +874,15 @@ static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, const PP float u1 = (float)im.entry.width / (1 << wp2); float v1 = (float)im.entry.height / (1 << hp2); if (style.hasShadow) { - Vertex(x + 1, y + 2, 0, 0, 1 << wp2, 1 << hp2, style.shadowColor); - Vertex(x + 1 + w, y + 2 + h, u1, v1, 1 << wp2, 1 << hp2, style.shadowColor); + // Draw more shadows for a blurrier shadow. + for (float dy = 0.0f; dy <= 2.0f; dy += 1.0f) { + for (float dx = 0.0f; dx <= 1.0f; dx += 0.5f) { + if (dx == 0.0f && dy == 0.0f) + continue; + Vertex(x + dx, y + dy, 0, 0, 1 << wp2, 1 << hp2, alphaMul(style.shadowColor, 0.35f)); + Vertex(x + dx + w, y + dy + h, u1, v1, 1 << wp2, 1 << hp2, alphaMul(style.shadowColor, 0.35f)); + } + } } Vertex(x, y, 0, 0, 1 << wp2, 1 << hp2, style.color); Vertex(x + w, y + h, u1, v1, 1 << wp2, 1 << hp2, style.color); @@ -893,6 +903,7 @@ void PPGeDrawText(const char *text, float x, float y, const PPGeStyle &style) { } if (style.hasShadow) { + // This doesn't have the nicer shadow because it's so many verts. PPGePrepareText(text, x + 1, y + 2, style.align, style.scale, style.scale, PPGE_LINE_USE_ELLIPSIS); PPGeDrawCurrentText(style.shadowColor); } @@ -990,6 +1001,7 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl PPGePrepareText(s.c_str(), x + sx, y + sy, style.align, scale, lineHeightScale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); } if (style.hasShadow) { + // This doesn't have the nicer shadow because it's so many verts. PPGeDrawCurrentText(style.shadowColor); PPGePrepareText(s.c_str(), x, y, style.align, scale, lineHeightScale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth); } @@ -1065,8 +1077,14 @@ void PPGeDrawImage(ImageID atlasImage, float x, float y, const PPGeStyle &style) float h = img->h; BeginVertexData(); if (style.hasShadow) { - Vertex(x + 1, y + 2, img->u1, img->v1, atlasWidth, atlasHeight, style.shadowColor); - Vertex(x + 1 + w, y + 2 + h, img->u2, img->v2, atlasWidth, atlasHeight, style.shadowColor); + for (float dy = 0.0f; dy <= 2.0f; dy += 1.0f) { + for (float dx = 0.0f; dx <= 1.0f; dx += 0.5f) { + if (dx == 0.0f && dy == 0.0f) + continue; + Vertex(x + dx, y + dy, img->u1, img->v1, atlasWidth, atlasHeight, alphaMul(style.shadowColor, 0.35f)); + Vertex(x + dx + w, y + dy + h, img->u2, img->v2, atlasWidth, atlasHeight, alphaMul(style.shadowColor, 0.35f)); + } + } } Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, style.color); Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, style.color); @@ -1083,8 +1101,14 @@ void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, const } BeginVertexData(); if (style.hasShadow) { - Vertex(x + 1, y + 2, img->u1, img->v1, atlasWidth, atlasHeight, style.shadowColor); - Vertex(x + 1 + w, y + 2 + h, img->u2, img->v2, atlasWidth, atlasHeight, style.shadowColor); + for (float dy = 0.0f; dy <= 2.0f; dy += 1.0f) { + for (float dx = 0.0f; dx <= 1.0f; dx += 0.5f) { + if (dx == 0.0f && dy == 0.0f) + continue; + Vertex(x + dx, y + dy, img->u1, img->v1, atlasWidth, atlasHeight, alphaMul(style.shadowColor, 0.35f)); + Vertex(x + dx + w, y + dy + h, img->u2, img->v2, atlasWidth, atlasHeight, alphaMul(style.shadowColor, 0.35f)); + } + } } Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, style.color); Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, style.color); From b181a93e5ea36bdf08921890c0a1daec3579ebf7 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 22:38:02 -0700 Subject: [PATCH 246/848] MsgDialog: Add scrollbar when message is long. Some games hard wrap their messages, and PSP firmware also showed a scrollbar. Let's do the same. One intentional difference: trying to ensure we always show part of a hidden line to make it clear to the user that there's more text. --- Core/Dialog/PSPMsgDialog.cpp | 122 +++++++++++++++++++++++------------ Core/Dialog/PSPMsgDialog.h | 3 + Core/Util/PPGeDraw.cpp | 14 +++- Core/Util/PPGeDraw.h | 4 ++ 4 files changed, 98 insertions(+), 45 deletions(-) diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index b40fc05857..1f0dabe46d 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "Core/Dialog/PSPMsgDialog.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" @@ -66,6 +67,9 @@ int PSPMsgDialog::Init(unsigned int paramAddr) { } flag = 0; + scrollPos_ = 0.0f; + framesUpHeld_ = 0; + framesDownHeld_ = 0; // Check request invalidity if(messageDialog.type == 0 && !(messageDialog.errorNum & 0x80000000)) @@ -141,67 +145,92 @@ int PSPMsgDialog::Init(unsigned int paramAddr) { return 0; } -void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) -{ +void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) { + auto di = GetI18NCategory("Dialog"); + float WRAP_WIDTH = 300.0f; if (UTF8StringNonASCIICount(text.c_str()) > 3) WRAP_WIDTH = 372.0f; - float y = 140.0f; - float h, sy, ey; - PPGeMeasureText(nullptr, &h, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH); - float h2 = h / 2.0f; - ey = y + h2 + 20.0f; + float totalHeight = 0.0f; + PPGeMeasureText(nullptr, &totalHeight, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH); + // The PSP normally only shows about 8 lines at a time. + // For improved UX, we intentionally show part of the next line. + float visibleHeight = std::min(totalHeight, 175.0f); + float h2 = visibleHeight / 2.0f; + + float centerY = 135.0f; + float sy = centerY - h2 - 15.0f; + float ey = centerY + h2 + 20.0f; + float buttonY = centerY + h2 + 5.0f; PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE); + PPGeStyle messageStyle = FadedStyle(PPGeAlign::BOX_HCENTER, FONT_SCALE); - if (hasYesNo) - { - auto di = GetI18NCategory("Dialog"); - const char *choiceText; - float x, w; + auto drawSelectionBoxAndAdjust = [&](float x) { + // Box has a fixed size. + float w = 15.0f; + float h = 8.0f; + PPGeDrawRect(x - w, buttonY - h, x + w, buttonY + h, CalcFadedColor(0x6DCFCFCF)); + + centerY -= h + 5.0f; + sy -= h + 5.0f; + ey = buttonY + h * 2.0f + 5.0f; + }; + + if (hasYesNo) { if (yesnoChoice == 1) { - choiceText = di->T("Yes"); - x = 204.0f; + drawSelectionBoxAndAdjust(204.0f); + } else { + drawSelectionBoxAndAdjust(273.0f); } - else { - choiceText = di->T("No"); - x = 273.0f; - } - PPGeMeasureText(&w, &h, choiceText, FONT_SCALE); - w = 15.0f; - h = 8.0f; - float y2 = y + h2 + 8.0f; - h2 += h + 5.0f; - y = 135.0f - h; - PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x6DCFCFCF)); - PPGeDrawText(di->T("Yes"), 203.0f, y2 - 1.0f, textStyle); - PPGeDrawText(di->T("No"), 272.0f, y2 - 1.0f, textStyle); + + PPGeDrawText(di->T("Yes"), 203.0f, buttonY - 1.0f, textStyle); + PPGeDrawText(di->T("No"), 272.0f, buttonY - 1.0f, textStyle); if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) { yesnoChoice = 1; - } - else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) { + } else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) { yesnoChoice = 0; } - ey = y2 + 25.0f; + buttonY += 8.0f + 5.0f; } if (hasOK) { - auto di = GetI18NCategory("Dialog"); - float x, w; - x = 240.0f; - w = 15.0f; - h = 8.0f; - float y2 = y + h2 + 8.0f; - h2 += h + 5.0f; - y = 135.0f - h; - PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x6DCFCFCF)); - PPGeDrawText(di->T("OK"), 239.0f, y2 - 1.0f, textStyle); - ey = y2 + 25.0f; + drawSelectionBoxAndAdjust(240.0f); + + PPGeDrawText(di->T("OK"), 239.0f, buttonY - 1.0f, textStyle); + buttonY += 8.0f + 5.0f; + } + + PPGeScissor(0, (int)(centerY - h2 - 2), 480, (int)(centerY + h2 + 2)); + PPGeDrawTextWrapped(text.c_str(), 240.0f, centerY - h2 - scrollPos_, WRAP_WIDTH, 0, messageStyle); + PPGeScissorReset(); + + // Do we need a scrollbar? + if (visibleHeight < totalHeight) { + float scrollSpeed = 5.0f; + float scrollMax = totalHeight - visibleHeight; + + float bobHeight = (visibleHeight / totalHeight) * visibleHeight; + float bobOffset = (scrollPos_ / scrollMax) * (visibleHeight - bobHeight); + float bobY1 = centerY - h2 + bobOffset; + PPGeDrawRect(435.0f, bobY1, 440.0f, bobY1 + bobHeight, CalcFadedColor(0xFFCCCCCC)); + + auto buttonDown = [this](int btn, int &held) { + if (IsButtonPressed(btn)) { + held = 0; + return true; + } + return IsButtonHeld(btn, held, 1, 1); + }; + if (buttonDown(CTRL_DOWN, framesDownHeld_) && scrollPos_ < scrollMax) { + scrollPos_ = std::min(scrollMax, scrollPos_ + scrollSpeed); + } + if (buttonDown(CTRL_UP, framesUpHeld_) && scrollPos_ > 0.0f) { + scrollPos_ = std::max(0.0f, scrollPos_ - scrollSpeed); + } } - PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, 0, textStyle); - sy = 125.0f - h2; PPGeDrawRect(40.0f, sy, 440.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawRect(40.0f, ey, 440.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); } @@ -314,6 +343,13 @@ void PSPMsgDialog::DoState(PointerWrap &p) p.Do(messageDialogAddr); p.DoArray(msgText, sizeof(msgText)); p.Do(yesnoChoice); + + // We don't save state this, you'll just have to scroll down again. + if (p.mode == p.MODE_READ) { + scrollPos_ = 0.0f; + framesUpHeld_ = 0; + framesDownHeld_ = 0; + } } pspUtilityDialogCommon *PSPMsgDialog::GetCommonParam() diff --git a/Core/Dialog/PSPMsgDialog.h b/Core/Dialog/PSPMsgDialog.h index 864420f0f0..64309f4659 100644 --- a/Core/Dialog/PSPMsgDialog.h +++ b/Core/Dialog/PSPMsgDialog.h @@ -98,5 +98,8 @@ private : char msgText[512]; int yesnoChoice; + float scrollPos_ = 0.0f; + int framesUpHeld_ = 0; + int framesDownHeld_ = 0; }; diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index ce03f15e8f..964dd45f0b 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -387,8 +387,7 @@ void PPGeBegin() PPGeSetDefaultTexture(); - WriteCmd(GE_CMD_SCISSOR1, (0 << 10) | 0); - WriteCmd(GE_CMD_SCISSOR2, (271 << 10) | 479); + PPGeScissor(0, 0, 480, 272); WriteCmd(GE_CMD_MINZ, 0); WriteCmd(GE_CMD_MAXZ, 0xFFFF); @@ -420,6 +419,17 @@ void PPGeEnd() } } +void PPGeScissor(int x1, int y1, int x2, int y2) { + assert(x1 >= 0 && x1 <= 480 && x2 >= 0 && x2 <= 480); + assert(y1 >= 0 && y1 <= 272 && y2 >= 0 && y2 <= 272); + WriteCmd(GE_CMD_SCISSOR1, (y1 << 10) | x1); + WriteCmd(GE_CMD_SCISSOR2, ((y2 - 1) << 10) | (x2 - 1)); +} + +void PPGeScissorReset() { + PPGeScissor(0, 0, 480, 272); +} + static const AtlasChar *PPGeGetChar(const AtlasFont &atlasfont, unsigned int cval) { const AtlasChar *c = atlasfont.getChar(cval); diff --git a/Core/Util/PPGeDraw.h b/Core/Util/PPGeDraw.h index b309a29a38..c9b625f40f 100644 --- a/Core/Util/PPGeDraw.h +++ b/Core/Util/PPGeDraw.h @@ -93,6 +93,10 @@ void PPGeDrawImage(ImageID atlasImage, float x, float y, const PPGeStyle &style) void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, const PPGeStyle &style); void PPGeDrawImage(float x, float y, float w, float h, float u1, float v1, float u2, float v2, int tw, int th, u32 color); +// Note: x2/y2 are exclusive. +void PPGeScissor(int x1, int y1, int x2, int y2); +void PPGeScissorReset(); + void PPGeNotifyFrame(); class PPGeImage { From 3daf536e3c0db460a9b427cdd30c70878aa0b536 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 22:52:08 -0700 Subject: [PATCH 247/848] MsgDialog: Allow text to be wider. Our font is a bit different, let's add a bit more as long as the spacing looks okay. Reduce scale if there's a lot of non-ASCII, since the PSP's font seemed to use smaller glyphs than ours for those chars. --- Core/Dialog/PSPMsgDialog.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index 1f0dabe46d..d90354f70f 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -148,9 +148,17 @@ int PSPMsgDialog::Init(unsigned int paramAddr) { void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) { auto di = GetI18NCategory("Dialog"); - float WRAP_WIDTH = 300.0f; - if (UTF8StringNonASCIICount(text.c_str()) > 3) - WRAP_WIDTH = 372.0f; + PPGeStyle buttonStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE); + PPGeStyle messageStyle = FadedStyle(PPGeAlign::BOX_HCENTER, FONT_SCALE); + + // Without the scrollbar, we have 390 total pixels. + float WRAP_WIDTH = 340.0f; + if (UTF8StringNonASCIICount(text.c_str()) >= text.size() / 4) { + WRAP_WIDTH = 376.0f; + if (text.size() > 12) { + messageStyle.scale = 0.6f; + } + } float totalHeight = 0.0f; PPGeMeasureText(nullptr, &totalHeight, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH); @@ -164,9 +172,6 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) { float ey = centerY + h2 + 20.0f; float buttonY = centerY + h2 + 5.0f; - PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE); - PPGeStyle messageStyle = FadedStyle(PPGeAlign::BOX_HCENTER, FONT_SCALE); - auto drawSelectionBoxAndAdjust = [&](float x) { // Box has a fixed size. float w = 15.0f; @@ -185,8 +190,8 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) { drawSelectionBoxAndAdjust(273.0f); } - PPGeDrawText(di->T("Yes"), 203.0f, buttonY - 1.0f, textStyle); - PPGeDrawText(di->T("No"), 272.0f, buttonY - 1.0f, textStyle); + PPGeDrawText(di->T("Yes"), 203.0f, buttonY - 1.0f, buttonStyle); + PPGeDrawText(di->T("No"), 272.0f, buttonY - 1.0f, buttonStyle); if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) { yesnoChoice = 1; } else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) { @@ -198,7 +203,7 @@ void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) { if (hasOK) { drawSelectionBoxAndAdjust(240.0f); - PPGeDrawText(di->T("OK"), 239.0f, buttonY - 1.0f, textStyle); + PPGeDrawText(di->T("OK"), 239.0f, buttonY - 1.0f, buttonStyle); buttonY += 8.0f + 5.0f; } From f16a6b8abdcb9055f81a96f74df4fc809ca2f355 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 23:11:03 -0700 Subject: [PATCH 248/848] MsgDialog: Show better error messages. I think the PSP really did just show error codes, but that's not a reason to keep that confusion going. For common save errors, let's show the messages. Some games, for example, simply show the no data found error when you play for the first time and trigger anything to check for data. --- Core/Dialog/PSPMsgDialog.cpp | 37 +++++++++++++++++++++++++++++++++++- Core/Dialog/PSPMsgDialog.h | 3 ++- Core/Dialog/SavedataParam.h | 1 + 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index d90354f70f..7ddd1f8a73 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -17,6 +17,7 @@ #include #include "Core/Dialog/PSPMsgDialog.h" +#include "Core/Dialog/PSPSaveDialog.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" #include "Core/MemMapHelpers.h" @@ -133,7 +134,7 @@ int PSPMsgDialog::Init(unsigned int paramAddr) { } if (flag & DS_ERRORMSG) { - snprintf(msgText, 512, "Error code: %08x", messageDialog.errorNum); + FormatErrorCode(messageDialog.errorNum); } else { truncate_cpy(msgText, messageDialog.string); } @@ -145,6 +146,40 @@ int PSPMsgDialog::Init(unsigned int paramAddr) { return 0; } + +void PSPMsgDialog::FormatErrorCode(uint32_t code) { + auto di = GetI18NCategory("Dialog"); + + switch (code) { + case SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN: + snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataDataBroken", "Save data was corrupt."), code); + break; + + case SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_MS: + case SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK: + case SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_MS: + case SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_MS: + case SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_MS: + snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataNoMS", "Memory stick not inserted."), code); + break; + + case SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA: + case SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA: + case SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA: + case SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA: + snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataNoData", "Warning: no save data was found."), code); + break; + + case SCE_UTILITY_SAVEDATA_ERROR_RW_MEMSTICK_FULL: + case SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE: + snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataMSFull", "Memory stick full. Check your storage space."), code); + break; + + default: + snprintf(msgText, 512, "%s %08x", di->T("MsgErrorCode", "Error code:"), code); + } +} + void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) { auto di = GetI18NCategory("Dialog"); diff --git a/Core/Dialog/PSPMsgDialog.h b/Core/Dialog/PSPMsgDialog.h index 64309f4659..78490393f8 100644 --- a/Core/Dialog/PSPMsgDialog.h +++ b/Core/Dialog/PSPMsgDialog.h @@ -74,7 +74,8 @@ protected: return false; } -private : +private: + void FormatErrorCode(uint32_t code); void DisplayMessage(std::string text, bool hasYesNo = false, bool hasOK = false); enum Flags diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h index e509463712..857c69779b 100644 --- a/Core/Dialog/SavedataParam.h +++ b/Core/Dialog/SavedataParam.h @@ -17,6 +17,7 @@ #pragma once +#include #include "Common/CommonTypes.h" #include "Core/MemMap.h" #include "Core/HLE/sceRtc.h" From dd909d36cccbb9f2e84d42b71c8c494355e1555c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 23 May 2020 23:27:20 -0700 Subject: [PATCH 249/848] Osk: Draw shadows on all the letters. --- Core/Dialog/PSPOskDialog.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index f60f41ce5e..3041cae300 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -767,17 +767,13 @@ void PSPOskDialog::RenderKeyboard() float title = (480.0f - (0.5f * drawLimit)) / 2.0f; PPGeStyle descStyle = FadedStyle(PPGeAlign::BOX_CENTER, 0.5f); - descStyle.hasShadow = false; PPGeDrawText(oskDesc.c_str(), title, 20, descStyle); PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.5f); - textStyle.hasShadow = false; PPGeStyle keyStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.6f); - keyStyle.hasShadow = false; PPGeStyle selectedKeyStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.6f); selectedKeyStyle.color = CalcFadedColor(0xFF3060FF); - selectedKeyStyle.hasShadow = false; std::u16string result; @@ -954,9 +950,7 @@ int PSPOskDialog::Update(int animSpeed) { auto di = GetI18NCategory("Dialog"); PPGeStyle actionStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f); - actionStyle.hasShadow = false; PPGeStyle guideStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.6f); - guideStyle.hasShadow = false; PPGeDrawImage(ImageID("I_SQUARE"), 365, 222, 16, 16, guideStyle); PPGeDrawText(di->T("Space"), 390, 222, actionStyle); From e66f034fb3595cedfa5fcf3427e9cbc4132fd675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 13 Jul 2020 23:31:14 +0200 Subject: [PATCH 250/848] Readback: Downgrade from vkWaitDeviceIdle to vkWaitQueueIdle. Probably effectively pretty much the same. --- ext/native/thin3d/VulkanRenderManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index d8d50bae3a..c790b6eb57 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -1188,8 +1188,8 @@ void VulkanRenderManager::EndSyncFrame(int frame) { Submit(frame, false); // This is brutal! Should probably wait for a fence instead, not that it'll matter much since we'll - // still stall everything. - vkDeviceWaitIdle(vulkan_->GetDevice()); + // still stall everything on our queue. + vkQueueWaitIdle(vulkan_->GetGraphicsQueue()); // At this point we can resume filling the command buffers for the current frame since // we know the device is idle - and thus all previously enqueued command buffers have been processed. From b5e7220ed1070936a515ecccd8cd6537a773ef17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 13 Jul 2020 23:59:09 +0200 Subject: [PATCH 251/848] Switch to a fence instead for readbacks. Some sources suggest this is better than idling a queue or device. Like https://stackoverflow.com/questions/39537176/in-what-situations-is-vkfence-better-than-vkqueuewaitidle-for-vkqueuesubmit . Additionally, this is easier to refactor and loosen up if we can in the future. --- ext/native/thin3d/VulkanRenderManager.cpp | 32 ++++++++++++++++------- ext/native/thin3d/VulkanRenderManager.h | 3 +++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index c790b6eb57..8d8659be34 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -133,7 +133,12 @@ VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan cmd_alloc.commandPool = frameData_[i].cmdPoolMain; res = vkAllocateCommandBuffers(vulkan_->GetDevice(), &cmd_alloc, &frameData_[i].mainCmd); assert(res == VK_SUCCESS); - frameData_[i].fence = vulkan_->CreateFence(true); // So it can be instantly waited on + + // Creating the frame fence with true so they can be instantly waited on the first frame + frameData_[i].fence = vulkan_->CreateFence(true); + + // This fence one is used for synchronizing readbacks. Does not need preinitialization. + frameData_[i].readbackFence = vulkan_->CreateFence(false); VkQueryPoolCreateInfo query_ci{ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO }; query_ci.queryCount = MAX_TIMESTAMP_QUERIES; @@ -307,6 +312,7 @@ VulkanRenderManager::~VulkanRenderManager() { vkDestroyCommandPool(device, frameData_[i].cmdPoolInit, nullptr); vkDestroyCommandPool(device, frameData_[i].cmdPoolMain, nullptr); vkDestroyFence(device, frameData_[i].fence, nullptr); + vkDestroyFence(device, frameData_[i].readbackFence, nullptr); vkDestroyQueryPool(device, frameData_[i].profile.queryPool, nullptr); } queueRunner_.DestroyDeviceObjects(); @@ -380,6 +386,8 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) { vkWaitForFences(device, 1, &frameData.fence, true, UINT64_MAX); vkResetFences(device, 1, &frameData.fence); + frameData.readbackFenceUsed = false; + uint64_t queryResults[MAX_TIMESTAMP_QUERIES]; if (frameData.profilingEnabled_) { @@ -1050,10 +1058,10 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) { } } -void VulkanRenderManager::Submit(int frame, bool triggerFence) { +void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) { FrameData &frameData = frameData_[frame]; if (frameData.hasInitCommands) { - if (frameData.profilingEnabled_ && triggerFence) { + if (frameData.profilingEnabled_ && triggerFrameFence) { // Pre-allocated query ID 1. vkCmdWriteTimestamp(frameData.initCmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frameData.profile.queryPool, 1); } @@ -1091,18 +1099,18 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; VkPipelineStageFlags waitStage[1]{ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; - if (triggerFence && !frameData.skipSwap) { + if (triggerFrameFence && !frameData.skipSwap) { submit_info.waitSemaphoreCount = 1; submit_info.pWaitSemaphores = &acquireSemaphore_; submit_info.pWaitDstStageMask = waitStage; } submit_info.commandBufferCount = (uint32_t)numCmdBufs; submit_info.pCommandBuffers = cmdBufs; - if (triggerFence && !frameData.skipSwap) { + if (triggerFrameFence && !frameData.skipSwap) { submit_info.signalSemaphoreCount = 1; submit_info.pSignalSemaphores = &renderingCompleteSemaphore_; } - res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFence ? frameData.fence : VK_NULL_HANDLE); + res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFrameFence ? frameData.fence : frameData.readbackFence); if (res == VK_ERROR_DEVICE_LOST) { #ifdef _WIN32 _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to Direct3D11"); @@ -1114,7 +1122,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { } // When !triggerFence, we notify after syncing with Vulkan. - if (useThread_ && triggerFence) { + if (useThread_ && triggerFrameFence) { VLOG("PULL: Frame %d.readyForFence = true", frame); std::unique_lock lock(frameData.push_mutex); frameData.readyForFence = true; @@ -1185,11 +1193,15 @@ void VulkanRenderManager::Run(int frame) { void VulkanRenderManager::EndSyncFrame(int frame) { FrameData &frameData = frameData_[frame]; + + frameData.readbackFenceUsed = true; + + // The submit will trigger the readbackFence. Submit(frame, false); - // This is brutal! Should probably wait for a fence instead, not that it'll matter much since we'll - // still stall everything on our queue. - vkQueueWaitIdle(vulkan_->GetGraphicsQueue()); + // Hard stall of the GPU, not ideal, but necessary so the CPU has the contents of the readback. + vkWaitForFences(vulkan_->GetDevice(), 1, &frameData.readbackFence, true, UINT64_MAX); + vkResetFences(vulkan_->GetDevice(), 1, &frameData.readbackFence); // At this point we can resume filling the command buffers for the current frame since // we know the device is idle - and thus all previously enqueued command buffers have been processed. diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index baf2990ab4..a47419bbf6 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -321,6 +321,9 @@ private: VKRRunType type = VKRRunType::END; VkFence fence; + VkFence readbackFence; // Strictly speaking we might only need one of these. + bool readbackFenceUsed = false; + // These are on different threads so need separate pools. VkCommandPool cmdPoolInit; VkCommandPool cmdPoolMain; From 1fce6de8b182ba0418acb4ab24e3b7eba2b63850 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 11 Feb 2019 11:11:56 +0100 Subject: [PATCH 252/848] Simple exception handler so we can ignore accesses that happen within the PSP memory space. --- CMakeLists.txt | 2 + Common/Common.vcxproj | 5 +- Common/Common.vcxproj.filters | 5 +- Common/ExceptionHandlerSetup.cpp | 316 ++++++++++++++++++++++++ Common/ExceptionHandlerSetup.h | 17 ++ Common/MachineContext.h | 243 ++++++++++++++++++ Core/MemMap.cpp | 31 +++ Core/MemMap.h | 4 + Core/System.cpp | 6 +- UWP/CommonUWP/CommonUWP.vcxproj | 2 + UWP/CommonUWP/CommonUWP.vcxproj.filters | 2 + android/jni/Android.mk | 1 + libretro/Makefile.common | 1 + 13 files changed, 632 insertions(+), 3 deletions(-) create mode 100644 Common/ExceptionHandlerSetup.cpp create mode 100644 Common/ExceptionHandlerSetup.h create mode 100644 Common/MachineContext.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ee98014740..9146253dc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -428,6 +428,8 @@ add_library(Common STATIC Common/Crypto/sha1.h Common/Crypto/sha256.cpp Common/Crypto/sha256.h + Common/ExceptionHandlerSetup.cpp + Common/ExceptionHandlerSetup.h Common/FileUtil.cpp Common/FileUtil.h Common/KeyMap.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 80278606df..6486c530e7 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -368,6 +368,7 @@ + @@ -397,6 +398,7 @@ + @@ -449,6 +451,7 @@ + true @@ -521,4 +524,4 @@ - \ No newline at end of file + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index ebe7f50688..c49d67d6af 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -74,6 +74,8 @@ Vulkan + + @@ -137,6 +139,7 @@ Vulkan + @@ -152,4 +155,4 @@ {c14d66ef-5f7c-4565-975a-72774e7ccfb9} - \ No newline at end of file + diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp new file mode 100644 index 0000000000..098b603209 --- /dev/null +++ b/Common/ExceptionHandlerSetup.cpp @@ -0,0 +1,316 @@ +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "Common/ExceptionHandlerSetup.h" + +#include +#include +#include +#include + +#include "Common/CommonFuncs.h" +#include "Common/CommonTypes.h" +#include "Common/MsgHandler.h" +#include "Common/Log.h" + +#if defined(PPSSPP_ARCH_X86) || defined(PPSSPP_ARCH_AMD64) +#include "Common/MachineContext.h" +#endif + +#ifdef __FreeBSD__ +#include +#endif +#ifndef _WIN32 +#include // Needed for _POSIX_VERSION +#endif + +static BadAccessHandler g_badAccessHandler; + +#ifdef _WIN32 + +static PVOID g_vectoredExceptionHandle; + +static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) { + switch (pPtrs->ExceptionRecord->ExceptionCode) { + case EXCEPTION_ACCESS_VIOLATION: + { + int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0]; + if (accessType == 8) { // Rule out DEP + return (DWORD)EXCEPTION_CONTINUE_SEARCH; + } + + // virtual address of the inaccessible data + uintptr_t badAddress = (uintptr_t)pPtrs->ExceptionRecord->ExceptionInformation[1]; + CONTEXT* ctx = pPtrs->ContextRecord; + + if (g_badAccessHandler(badAddress, ctx)) { + return (DWORD)EXCEPTION_CONTINUE_EXECUTION; + } else { + // Let's not prevent debugging. + return (DWORD)EXCEPTION_CONTINUE_SEARCH; + } + } + + case EXCEPTION_STACK_OVERFLOW: + // Dolphin has some handling of this for the RET optimization emulation. + return EXCEPTION_CONTINUE_SEARCH; + + case EXCEPTION_ILLEGAL_INSTRUCTION: + // No SSE support? Or simply bad codegen? + return EXCEPTION_CONTINUE_SEARCH; + + case EXCEPTION_PRIV_INSTRUCTION: + // okay, dynarec codegen is obviously broken. + return EXCEPTION_CONTINUE_SEARCH; + + case EXCEPTION_IN_PAGE_ERROR: + // okay, something went seriously wrong, out of memory? + return EXCEPTION_CONTINUE_SEARCH; + + case EXCEPTION_BREAKPOINT: + // might want to do something fun with this one day? + return EXCEPTION_CONTINUE_SEARCH; + + default: + return EXCEPTION_CONTINUE_SEARCH; + } +} + +void InstallExceptionHandler(BadAccessHandler badAccessHandler) { + // Make sure this is only called once per process execution + // Instead, could make a Uninstall function, but whatever.. + if (g_badAccessHandler) { + return; + } + + g_badAccessHandler = badAccessHandler; + g_vectoredExceptionHandle = AddVectoredExceptionHandler(TRUE, Handler); +} + +void UninstallExceptionHandler() { + RemoveVectoredExceptionHandler(g_vectoredExceptionHandle); +} + +#elif defined(__APPLE__) && !defined(USE_SIGACTION_ON_APPLE) + +static void CheckKR(const char* name, kern_return_t kr) { + if (kr) { + PanicAlert("%s failed: kr=%x", name, kr); + } +} + +static void ExceptionThread(mach_port_t port) { + Common::SetCurrentThreadName("Mach exception thread"); +#pragma pack(4) + struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[x86_THREAD_STATE64_COUNT]; + mach_msg_trailer_t trailer; + } msg_in; + + struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[x86_THREAD_STATE64_COUNT]; + } msg_out; +#pragma pack() + memset(&msg_in, 0xee, sizeof(msg_in)); + memset(&msg_out, 0xee, sizeof(msg_out)); + mach_msg_header_t* send_msg = nullptr; + mach_msg_size_t send_size = 0; + mach_msg_option_t option = MACH_RCV_MSG; + while (true) { + // If this isn't the first run, send the reply message. Then, receive + // a message: either a mach_exception_raise_state RPC due to + // thread_set_exception_ports, or MACH_NOTIFY_NO_SENDERS due to + // mach_port_request_notification. + CheckKR("mach_msg_overwrite", + mach_msg_overwrite(send_msg, option, send_size, sizeof(msg_in), port, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, &msg_in.Head, 0)); + + if (msg_in.Head.msgh_id == MACH_NOTIFY_NO_SENDERS) { + // the other thread exited + mach_port_destroy(mach_task_self(), port); + return; + } + + if (msg_in.Head.msgh_id != 2406) { + PanicAlert("unknown message received"); + return; + } + + if (msg_in.flavor != x86_THREAD_STATE64) { + PanicAlert("unknown flavor %d (expected %d)", msg_in.flavor, x86_THREAD_STATE64); + return; + } + + x86_thread_state64_t* state = (x86_thread_state64_t*)msg_in.old_state; + + bool ok = g_badAccessHandler((uintptr_t)msg_in.code[1], state); + + // Set up the reply. + msg_out.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(msg_in.Head.msgh_bits), 0); + msg_out.Head.msgh_remote_port = msg_in.Head.msgh_remote_port; + msg_out.Head.msgh_local_port = MACH_PORT_NULL; + msg_out.Head.msgh_id = msg_in.Head.msgh_id + 100; + msg_out.NDR = msg_in.NDR; + if (ok) { + msg_out.RetCode = KERN_SUCCESS; + msg_out.flavor = x86_THREAD_STATE64; + msg_out.new_stateCnt = x86_THREAD_STATE64_COUNT; + memcpy(msg_out.new_state, msg_in.old_state, x86_THREAD_STATE64_COUNT * sizeof(natural_t)); + } else { + // Pass the exception to the next handler (debugger or crash). + msg_out.RetCode = KERN_FAILURE; + msg_out.flavor = 0; + msg_out.new_stateCnt = 0; + } + msg_out.Head.msgh_size = + offsetof(__typeof__(msg_out), new_state) + msg_out.new_stateCnt * sizeof(natural_t); + + send_msg = &msg_out.Head; + send_size = msg_out.Head.msgh_size; + option |= MACH_SEND_MSG; + } +} + +void InstallExceptionHandler(BadAccessHandler badAccessHandler) { + g_badAccessHandler = badAccessHandler; + mach_port_t port; + CheckKR("mach_port_allocate", + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)); + std::thread exc_thread(ExceptionThread, port); + exc_thread.detach(); + // Obtain a send right for thread_set_exception_ports to copy... + CheckKR("mach_port_insert_right", + mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND)); + // Mach tries the following exception ports in order: thread, task, host. + // Debuggers set the task port, so we grab the thread port. + CheckKR("thread_set_exception_ports", + thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, port, + EXCEPTION_STATE | MACH_EXCEPTION_CODES, x86_THREAD_STATE64)); + // ...and get rid of our copy so that MACH_NOTIFY_NO_SENDERS works. + CheckKR("mach_port_mod_refs", + mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, -1)); + mach_port_t previous; + CheckKR("mach_port_request_notification", + mach_port_request_notification(mach_task_self(), port, MACH_NOTIFY_NO_SENDERS, 0, port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous)); +} + +void UninstallExceptionHandler() { +} + +#elif defined(_POSIX_VERSION) && !defined(_M_GENERIC) + +static struct sigaction old_sa_segv; +static struct sigaction old_sa_bus; + +static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context) { + if (sig != SIGSEGV && sig != SIGBUS) { + // We are not interested in other signals - handle it as usual. + return; + } + ucontext_t* context = (ucontext_t*)raw_context; + int sicode = info->si_code; + if (sicode != SEGV_MAPERR && sicode != SEGV_ACCERR) { + // Huh? Return. + return; + } + uintptr_t bad_address = (uintptr_t)info->si_addr; + + // Get all the information we can out of the context. +#ifdef __OpenBSD__ + ucontext_t* ctx = context; +#else + mcontext_t* ctx = &context->uc_mcontext; +#endif + // assume it's not a write + if (!g_badAccessHandler(bad_address, +#ifdef __APPLE__ + *ctx +#else + ctx +#endif + )) { + // retry and crash + // According to the sigaction man page, if sa_flags "SA_SIGINFO" is set to the sigaction + // function pointer, otherwise sa_handler contains one of: + // SIG_DEF: The 'default' action is performed + // SIG_IGN: The signal is ignored + // Any other value is a function pointer to a signal handler + + struct sigaction* old_sa; + if (sig == SIGSEGV) { + old_sa = &old_sa_segv; + } else { + old_sa = &old_sa_bus; + } + + if (old_sa->sa_flags & SA_SIGINFO) { + old_sa->sa_sigaction(sig, info, raw_context); + return; + } + if (old_sa->sa_handler == SIG_DFL) { + signal(sig, SIG_DFL); + return; + } + if (old_sa->sa_handler == SIG_IGN) { + // Ignore signal + return; + } + old_sa->sa_handler(sig); + } +} + +void InstallExceptionHandler(BadAccessHandler badAccessHandler) { + g_badAccessHandler = badAccessHandler; + + stack_t signal_stack; +#ifdef __FreeBSD__ + signal_stack.ss_sp = (char*)malloc(SIGSTKSZ); +#else + signal_stack.ss_sp = malloc(SIGSTKSZ); +#endif + signal_stack.ss_size = SIGSTKSZ; + signal_stack.ss_flags = 0; + if (sigaltstack(&signal_stack, nullptr)) + PanicAlert("sigaltstack failed"); + struct sigaction sa; + sa.sa_handler = nullptr; + sa.sa_sigaction = &sigsegv_handler; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, &old_sa_segv); +#ifdef __APPLE__ + sigaction(SIGBUS, &sa, &old_sa_bus); +#endif +} + +void UninstallExceptionHandler() { + stack_t signal_stack, old_stack; + signal_stack.ss_flags = SS_DISABLE; + if (!sigaltstack(&signal_stack, &old_stack) && !(old_stack.ss_flags & SS_DISABLE)) { + free(old_stack.ss_sp); + } + sigaction(SIGSEGV, &old_sa_segv, nullptr); +#ifdef __APPLE__ + sigaction(SIGBUS, &old_sa_bus, nullptr); +#endif +} +#else // _M_GENERIC or unsupported platform + +void InstallExceptionHandler(BadAccessHandler badAccessHandler) { } +void UninstallExceptionHandler() { } + +#endif diff --git a/Common/ExceptionHandlerSetup.h b/Common/ExceptionHandlerSetup.h new file mode 100644 index 0000000000..8f88176e0e --- /dev/null +++ b/Common/ExceptionHandlerSetup.h @@ -0,0 +1,17 @@ +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +// On Windows, context is a CONTEXT object. +// On Apple, context is a x86_thread_state64_t. +// On Unix/Linux, context is a mcontext_t. +// On OpenBSD, context is a ucontext_t. +// Ugh, might need to abstract this better. +typedef bool (*BadAccessHandler)(uintptr_t address, void *context); + +void InstallExceptionHandler(BadAccessHandler accessHandler); +void UninstallExceptionHandler(); diff --git a/Common/MachineContext.h b/Common/MachineContext.h new file mode 100644 index 0000000000..643fac4858 --- /dev/null +++ b/Common/MachineContext.h @@ -0,0 +1,243 @@ +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "ppsspp_config.h" + +#if PPSSPP_PLATFORM(WINDOWS) +#include +typedef CONTEXT SContext; +#if PPSSPP_ARCH_AMD64 +#define CTX_RAX Rax +#define CTX_RBX Rbx +#define CTX_RCX Rcx +#define CTX_RDX Rdx +#define CTX_RDI Rdi +#define CTX_RSI Rsi +#define CTX_RBP Rbp +#define CTX_RSP Rsp +#define CTX_R8 R8 +#define CTX_R9 R9 +#define CTX_R10 R10 +#define CTX_R11 R11 +#define CTX_R12 R12 +#define CTX_R13 R13 +#define CTX_R14 R14 +#define CTX_R15 R15 +#define CTX_RIP Rip +#else +#define CTX_RAX Eax +#define CTX_RBX Ebx +#define CTX_RCX Ecx +#define CTX_RDX Edx +#define CTX_RDI Edi +#define CTX_RSI Esi +#define CTX_RBP Ebp +#define CTX_RSP Esp +#define CTX_RIP Eip + +#endif +#elif defined(__APPLE__) && !defined(USE_SIGACTION_ON_APPLE) +// for modules: +#define _XOPEN_SOURCE +#include + +#include +#include +#if _M_X86_64 +typedef x86_thread_state64_t SContext; +#define CTX_RAX __rax +#define CTX_RBX __rbx +#define CTX_RCX __rcx +#define CTX_RDX __rdx +#define CTX_RDI __rdi +#define CTX_RSI __rsi +#define CTX_RBP __rbp +#define CTX_RSP __rsp +#define CTX_R8 __r8 +#define CTX_R9 __r9 +#define CTX_R10 __r10 +#define CTX_R11 __r11 +#define CTX_R12 __r12 +#define CTX_R13 __r13 +#define CTX_R14 __r14 +#define CTX_R15 __r15 +#define CTX_RIP __rip +#else +#error No context definition for architecture +#endif +#elif defined(__APPLE__) +#include +typedef _STRUCT_MCONTEXT64 SContext; +#define CTX_RAX __ss.__rax +#define CTX_RBX __ss.__rbx +#define CTX_RCX __ss.__rcx +#define CTX_RDX __ss.__rdx +#define CTX_RDI __ss.__rdi +#define CTX_RSI __ss.__rsi +#define CTX_RBP __ss.__rbp +#define CTX_RSP __ss.__rsp +#define CTX_R8 __ss.__r8 +#define CTX_R9 __ss.__r9 +#define CTX_R10 __ss.__r10 +#define CTX_R11 __ss.__r11 +#define CTX_R12 __ss.__r12 +#define CTX_R13 __ss.__r13 +#define CTX_R14 __ss.__r14 +#define CTX_R15 __ss.__r15 +#define CTX_RIP __ss.__rip +#elif defined(__linux__) +#include + +#include +typedef mcontext_t SContext; + +#if _M_X86_64 +#define CTX_RAX gregs[REG_RAX] +#define CTX_RBX gregs[REG_RBX] +#define CTX_RCX gregs[REG_RCX] +#define CTX_RDX gregs[REG_RDX] +#define CTX_RDI gregs[REG_RDI] +#define CTX_RSI gregs[REG_RSI] +#define CTX_RBP gregs[REG_RBP] +#define CTX_RSP gregs[REG_RSP] +#define CTX_R8 gregs[REG_R8] +#define CTX_R9 gregs[REG_R9] +#define CTX_R10 gregs[REG_R10] +#define CTX_R11 gregs[REG_R11] +#define CTX_R12 gregs[REG_R12] +#define CTX_R13 gregs[REG_R13] +#define CTX_R14 gregs[REG_R14] +#define CTX_R15 gregs[REG_R15] +#define CTX_RIP gregs[REG_RIP] +#elif _M_ARM_64 +#define CTX_REG(x) regs[x] +#define CTX_SP sp +#define CTX_PC pc +#else +#error No context definition for architecture +#endif +#elif defined(__OpenBSD__) +#include +typedef ucontext_t SContext; +#if _M_X86_64 +#define CTX_RAX sc_rax +#define CTX_RBX sc_rbx +#define CTX_RCX sc_rcx +#define CTX_RDX sc_rdx +#define CTX_RDI sc_rdi +#define CTX_RSI sc_rsi +#define CTX_RBP sc_rbp +#define CTX_RSP sc_rsp +#define CTX_R8 sc_r8 +#define CTX_R9 sc_r9 +#define CTX_R10 sc_r10 +#define CTX_R11 sc_r11 +#define CTX_R12 sc_r12 +#define CTX_R13 sc_r13 +#define CTX_R14 sc_r14 +#define CTX_R15 sc_r15 +#define CTX_RIP sc_rip +#else +#error No context definition for architecture +#endif +#elif defined(__NetBSD__) +#include +typedef mcontext_t SContext; +#if _M_X86_64 +#define CTX_RAX __gregs[_REG_RAX] +#define CTX_RBX __gregs[_REG_RBX] +#define CTX_RCX __gregs[_REG_RCX] +#define CTX_RDX __gregs[_REG_RDX] +#define CTX_RDI __gregs[_REG_RDI] +#define CTX_RSI __gregs[_REG_RSI] +#define CTX_RBP __gregs[_REG_RBP] +#define CTX_RSP __gregs[_REG_RSP] +#define CTX_R8 __gregs[_REG_R8] +#define CTX_R9 __gregs[_REG_R9] +#define CTX_R10 __gregs[_REG_R10] +#define CTX_R11 __gregs[_REG_R11] +#define CTX_R12 __gregs[_REG_R12] +#define CTX_R13 __gregs[_REG_R13] +#define CTX_R14 __gregs[_REG_R14] +#define CTX_R15 __gregs[_REG_R15] +#define CTX_RIP __gregs[_REG_RIP] +#else +#error No context definition for architecture +#endif +#elif defined(__FreeBSD__) +#include +typedef mcontext_t SContext; +#if _M_X86_64 +#define CTX_RAX mc_rax +#define CTX_RBX mc_rbx +#define CTX_RCX mc_rcx +#define CTX_RDX mc_rdx +#define CTX_RDI mc_rdi +#define CTX_RSI mc_rsi +#define CTX_RBP mc_rbp +#define CTX_RSP mc_rsp +#define CTX_R8 mc_r8 +#define CTX_R9 mc_r9 +#define CTX_R10 mc_r10 +#define CTX_R11 mc_r11 +#define CTX_R12 mc_r12 +#define CTX_R13 mc_r13 +#define CTX_R14 mc_r14 +#define CTX_R15 mc_r15 +#define CTX_RIP mc_rip +#else +#error No context definition for architecture +#endif +#elif defined(__HAIKU__) +#include +typedef mcontext_t SContext; +#if _M_X86_64 +#define CTX_RAX rax +#define CTX_RBX rbx +#define CTX_RCX rcx +#define CTX_RDX rdx +#define CTX_RDI rdi +#define CTX_RSI rsi +#define CTX_RBP rbp +#define CTX_RSP rsp +#define CTX_R8 r8 +#define CTX_R9 r9 +#define CTX_R10 r10 +#define CTX_R11 r11 +#define CTX_R12 r12 +#define CTX_R13 r13 +#define CTX_R14 r14 +#define CTX_R15 r15 +#define CTX_RIP rip +#else +#error No context definition for machine +#endif +#else +#error No context definition for OS +#endif + +#if defined(PPSSPP_ARCH_AMD64) || defined(PPSSPP_ARCH_X86) +#include +#define CTX_PC CTX_RIP +static inline u64* ContextRN(SContext* ctx, int n) +{ +#if PPSSPP_ARCH_32BIT + static const u8 offsets[] = { + offsetof(SContext, CTX_RAX), offsetof(SContext, CTX_RCX), offsetof(SContext, CTX_RDX), + offsetof(SContext, CTX_RBX), offsetof(SContext, CTX_RSP), offsetof(SContext, CTX_RBP), + offsetof(SContext, CTX_RSI), offsetof(SContext, CTX_RDI)}; +#else + static const u8 offsets[] = { + offsetof(SContext, CTX_RAX), offsetof(SContext, CTX_RCX), offsetof(SContext, CTX_RDX), + offsetof(SContext, CTX_RBX), offsetof(SContext, CTX_RSP), offsetof(SContext, CTX_RBP), + offsetof(SContext, CTX_RSI), offsetof(SContext, CTX_RDI), offsetof(SContext, CTX_R8), + offsetof(SContext, CTX_R9), offsetof(SContext, CTX_R10), offsetof(SContext, CTX_R11), + offsetof(SContext, CTX_R12), offsetof(SContext, CTX_R13), offsetof(SContext, CTX_R14), + offsetof(SContext, CTX_R15)}; +#endif + return (u64*)((char*)ctx + offsets[n]); +} +#endif diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 9c7a2cce19..93d2029da2 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -28,6 +28,7 @@ #include "Common/MemoryUtil.h" #include "Common/MemArena.h" #include "Common/ChunkFile.h" +#include "Common/MachineContext.h" #include "Core/MemMap.h" #include "Core/HDRemaster.h" @@ -457,4 +458,34 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength) { CBreakPoints::ExecMemCheck(_Address, true, _iLength, currentMIPS->pc); } +bool HandleFault(uintptr_t hostAddress, void *ctx) { + SContext *context = (SContext *)ctx; + const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); + + // TODO: Check that codePtr is within the current JIT space. + // bool inJitSpace = MIPSComp::jit->IsInSpace(codePtr); + // if (!inJitSpace) return false; + + // TODO: Disassemble at codePtr to figure out if it's a read or a write. + + uintptr_t baseAddress = (uintptr_t)base; + +#ifdef MASKED_PSP_MEMORY + const uintptr_t addressSpaceSize = 0x100000000ULL; +#else + const uintptr_t addressSpaceSize = 0x40000000ULL; +#endif + + // Check whether hostAddress is within the PSP memory space, which (likely) means it was a game that did the bad access. + if (hostAddress >= baseAddress && hostAddress <= baseAddress + addressSpaceSize) { + uint32_t guestAddress = hostAddress - baseAddress; + // Maybe we should also somehow check whether the JIT is on the stack. + ERROR_LOG(SYSTEM, "Bad memory access detected and ignored: %08x (%p)", guestAddress, hostAddress); + return true; + } + + // A regular crash of some sort. Pass it on. + return false; +} + } // namespace diff --git a/Core/MemMap.h b/Core/MemMap.h index 4f598961f3..a7849a6fb7 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -147,6 +147,10 @@ Opcode Read_Opcode_JIT(const u32 _Address); // used by JIT. Reads in the "Locked cache" mode void Write_Opcode_JIT(const u32 _Address, const Opcode& _Value); +// Called by exception handlers. We simply filter out accesses to PSP RAM and otherwise +// just leave it as-is. +bool HandleFault(uintptr_t hostAddress, void *context); + // Should be used by analyzers, disassemblers etc. Does resolve replacements. Opcode Read_Instruction(const u32 _Address, bool resolveReplacements = false); Opcode ReadUnchecked_Instruction(const u32 _Address, bool resolveReplacements = false); diff --git a/Core/System.cpp b/Core/System.cpp index c8a8b4c769..c679bb60b9 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -62,6 +62,7 @@ #include "Core/ELF/ParamSFO.h" #include "Core/SaveState.h" #include "Common/LogManager.h" +#include "Common/ExceptionHandlerSetup.h" #include "Core/HLE/sceAudiocodec.h" #include "GPU/GPUState.h" @@ -266,10 +267,11 @@ void CPU_Init() { return; } - if (coreParameter.updateRecent) { g_Config.AddRecent(filename); } + + InstallExceptionHandler(&Memory::HandleFault); } PSP_LoadingLock::PSP_LoadingLock() { @@ -281,6 +283,8 @@ PSP_LoadingLock::~PSP_LoadingLock() { } void CPU_Shutdown() { + UninstallExceptionHandler(); + // Since we load on a background thread, wait for startup to complete. PSP_LoadingLock lock; PSPLoaders_Shutdown(); diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index a5fe599d10..88559e8c82 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -398,6 +398,7 @@ + @@ -435,6 +436,7 @@ + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 566049b279..100c103e66 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -16,6 +16,7 @@ + @@ -65,6 +66,7 @@ + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 5bdf22bd18..0adfb91db9 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -205,6 +205,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Crypto/sha256.cpp \ $(SRC)/Common/ChunkFile.cpp \ $(SRC)/Common/ColorConv.cpp \ + $(SRC)/Common/ExceptionHandlerSetup.cpp \ $(SRC)/Common/KeyMap.cpp \ $(SRC)/Common/LogManager.cpp \ $(SRC)/Common/MemArenaAndroid.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index ab7d30ebdf..ed78f44cc4 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -143,6 +143,7 @@ SOURCES_CXX += \ SOURCES_CXX += \ $(COMMONDIR)/ChunkFile.cpp \ $(COMMONDIR)/ConsoleListener.cpp \ + $(COMMONDIR)/ExceptionHandlerSetup.cpp \ $(COMMONDIR)/FileUtil.cpp \ $(COMMONDIR)/KeyMap.cpp \ $(COMMONDIR)/LogManager.cpp \ From aa802ecc0f2697f10562be5187ae9169c13ae818 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 12 Feb 2019 10:08:11 +0100 Subject: [PATCH 253/848] Skip bad reads/writes by the guest executable. --- Common/ExceptionHandlerSetup.cpp | 1 + Common/x64Analyzer.cpp | 11 ++++- Common/x64Analyzer.h | 2 +- Core/MemMap.cpp | 69 ++++++++++++++++++++++---------- 4 files changed, 59 insertions(+), 24 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 098b603209..f538efb5a1 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -90,6 +90,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { void UninstallExceptionHandler() { RemoveVectoredExceptionHandler(g_vectoredExceptionHandle); + g_badAccessHandler = nullptr; } #elif defined(__APPLE__) && !defined(USE_SIGACTION_ON_APPLE) diff --git a/Common/x64Analyzer.cpp b/Common/x64Analyzer.cpp index 1940416d6a..42095b03c9 100644 --- a/Common/x64Analyzer.cpp +++ b/Common/x64Analyzer.cpp @@ -17,8 +17,10 @@ #include "x64Analyzer.h" -bool DisassembleMov(const unsigned char *codePtr, InstructionInfo &info, int accessType) +bool DisassembleMov(const unsigned char *codePtr, InstructionInfo &info) { + int accessType = 0; + unsigned const char *startCodePtr = codePtr; u8 rex = 0; u8 codeByte = 0; @@ -80,6 +82,12 @@ bool DisassembleMov(const unsigned char *codePtr, InstructionInfo &info, int acc modRMbyte = *codePtr++; hasModRM = true; } + + // TODO: Add more cases. + if ((codeByte & 0xF0) == 0x80) + accessType = 1; + if ((codeByte & 0xF0) == 0xC0) + accessType = 1; } else { @@ -135,7 +143,6 @@ bool DisassembleMov(const unsigned char *codePtr, InstructionInfo &info, int acc else info.displacement = *((s32 *)codePtr); codePtr += displacementSize; - if (accessType == 1) { diff --git a/Common/x64Analyzer.h b/Common/x64Analyzer.h index ad2fed886d..d448d4c60f 100644 --- a/Common/x64Analyzer.h +++ b/Common/x64Analyzer.h @@ -60,4 +60,4 @@ enum AccessType { OP_ACCESS_WRITE = 1 }; -bool DisassembleMov(const unsigned char *codePtr, InstructionInfo &info, int accessType); +bool DisassembleMov(const unsigned char *codePtr, InstructionInfo &info); diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 93d2029da2..af47ce6668 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -29,6 +29,7 @@ #include "Common/MemArena.h" #include "Common/ChunkFile.h" #include "Common/MachineContext.h" +#include "Common/x64Analyzer.h" #include "Core/MemMap.h" #include "Core/HDRemaster.h" @@ -463,29 +464,55 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); // TODO: Check that codePtr is within the current JIT space. - // bool inJitSpace = MIPSComp::jit->IsInSpace(codePtr); - // if (!inJitSpace) return false; - - // TODO: Disassemble at codePtr to figure out if it's a read or a write. - - uintptr_t baseAddress = (uintptr_t)base; - -#ifdef MASKED_PSP_MEMORY - const uintptr_t addressSpaceSize = 0x100000000ULL; -#else - const uintptr_t addressSpaceSize = 0x40000000ULL; -#endif - - // Check whether hostAddress is within the PSP memory space, which (likely) means it was a game that did the bad access. - if (hostAddress >= baseAddress && hostAddress <= baseAddress + addressSpaceSize) { - uint32_t guestAddress = hostAddress - baseAddress; - // Maybe we should also somehow check whether the JIT is on the stack. - ERROR_LOG(SYSTEM, "Bad memory access detected and ignored: %08x (%p)", guestAddress, hostAddress); - return true; + bool inJitSpace = true; // MIPSComp::jit->IsInSpace(codePtr); + if (!inJitSpace) { + // This is a crash in non-jitted code. Not something we want to handle here, ignore. + return false; } - // A regular crash of some sort. Pass it on. - return false; + uintptr_t baseAddress = (uintptr_t)base; +#ifdef MASKED_PSP_MEMORY + const uintptr_t addressSpaceSize = 0x40000000ULL; +#else + const uintptr_t addressSpaceSize = 0x100000000ULL; +#endif + + // Check whether hostAddress is within the PSP memory space, which (likely) means it was a guest executable that did the bad access. + if (hostAddress < baseAddress || hostAddress >= baseAddress + addressSpaceSize) { + // Host address outside - this was a different kind of crash. + return false; + } + + // OK, a guest executable did a bad access. Take care of it. + + uint32_t guestAddress = hostAddress - baseAddress; + ERROR_LOG(SYSTEM, "Bad memory access detected and ignored: %08x (%p)", guestAddress, hostAddress); + // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC + +#if defined(PPSSPP_ARCH_AMD64) || defined(PPSSPP_ARCH_X86) + + InstructionInfo info; + DisassembleMov(codePtr, info); + + if (g_Config.bIgnoreBadMemAccess) { + if (!info.isMemoryWrite) { + // Must have been a read. Fill the register with 0. + // TODO + } + // Move on to the next instruction. + context->CTX_PC += info.instructionSize; + } else { + // Jump to a crash handler. + // TODO + context->CTX_PC += info.instructionSize; + } + +#else + // ARM, ARM64 : All instructions are always 4 bytes in size. As an initial implementation, + // let's just skip the offending instruction. + context->CTX_PC += 4; +#endif + return true; } } // namespace From c988d42b046c55d875d56bca122bdd8f380d2398 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 12 Feb 2019 10:58:20 +0100 Subject: [PATCH 254/848] ARM/ARM64 instruction analysis, hook up to handler --- Common/CodeBlock.h | 2 +- Common/ExceptionHandlerSetup.cpp | 22 +++++++++-- Common/x64Analyzer.cpp | 2 +- Common/x64Analyzer.h | 4 +- Core/MIPS/ARM/ArmAsm.cpp | 7 ++++ Core/MIPS/ARM/ArmJit.h | 4 ++ Core/MIPS/ARM64/Arm64Asm.cpp | 7 ++++ Core/MIPS/ARM64/Arm64Jit.h | 4 ++ Core/MIPS/IR/IRJit.h | 5 +++ Core/MIPS/JitCommon/JitCommon.h | 2 + Core/MIPS/x86/Asm.cpp | 10 +++++ Core/MIPS/x86/Jit.cpp | 2 + Core/MIPS/x86/Jit.h | 4 ++ Core/MemMap.cpp | 63 +++++++++++++++++++++++++------- Core/Util/DisArm64.cpp | 35 ++++++++++++++++++ Core/Util/DisArm64.h | 21 +++++++++++ ext/disarm.cpp | 29 +++------------ ext/disarm.h | 30 +++++++++++---- 18 files changed, 202 insertions(+), 51 deletions(-) diff --git a/Common/CodeBlock.h b/Common/CodeBlock.h index f60c4b9305..777fb164a4 100644 --- a/Common/CodeBlock.h +++ b/Common/CodeBlock.h @@ -19,7 +19,7 @@ public: CodeBlockCommon() {} virtual ~CodeBlockCommon() {} - bool IsInSpace(const u8 *ptr) { + bool IsInSpace(const u8 *ptr) const { return (ptr >= region) && (ptr < (region + region_size)); } diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index f538efb5a1..d9c3d5c4ad 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "Common/ExceptionHandlerSetup.h" - #include #include #include @@ -84,6 +83,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { return; } + INFO_LOG(SYSTEM, "Installing exception handler"); g_badAccessHandler = badAccessHandler; g_vectoredExceptionHandle = AddVectoredExceptionHandler(TRUE, Handler); } @@ -91,6 +91,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { void UninstallExceptionHandler() { RemoveVectoredExceptionHandler(g_vectoredExceptionHandle); g_badAccessHandler = nullptr; + INFO_LOG(SYSTEM, "Removed exception handler"); } #elif defined(__APPLE__) && !defined(USE_SIGACTION_ON_APPLE) @@ -186,7 +187,14 @@ static void ExceptionThread(mach_port_t port) { } void InstallExceptionHandler(BadAccessHandler badAccessHandler) { - g_badAccessHandler = badAccessHandler; + if (!g_badAccessHandler) { + g_badAccessHandler = badAccessHandler; + } else { + // The rest of the setup we don't need to do again. + g_badAccessHandler = badAccessHandler; + return; + } + INFO_LOG(SYSTEM, "Installing exception handler"); mach_port_t port; CheckKR("mach_port_allocate", mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port)); @@ -275,6 +283,10 @@ static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context) { } void InstallExceptionHandler(BadAccessHandler badAccessHandler) { + if (g_badAccessHandler) { + return; + } + NOTICE_LOG(SYSTEM, "Installed exception handler"); g_badAccessHandler = badAccessHandler; stack_t signal_stack; @@ -308,10 +320,14 @@ void UninstallExceptionHandler() { #ifdef __APPLE__ sigaction(SIGBUS, &old_sa_bus, nullptr); #endif + NOTICE_LOG(SYSTEM, "Uninstalled exception handler"); + g_badAccessHandler = nullptr; } #else // _M_GENERIC or unsupported platform -void InstallExceptionHandler(BadAccessHandler badAccessHandler) { } +void InstallExceptionHandler(BadAccessHandler badAccessHandler) { + ERROR_LOG(SYSTEM, "Exception handler not implemented on this platform, can't install"); +} void UninstallExceptionHandler() { } #endif diff --git a/Common/x64Analyzer.cpp b/Common/x64Analyzer.cpp index 42095b03c9..0d04346c04 100644 --- a/Common/x64Analyzer.cpp +++ b/Common/x64Analyzer.cpp @@ -17,7 +17,7 @@ #include "x64Analyzer.h" -bool DisassembleMov(const unsigned char *codePtr, InstructionInfo &info) +bool X86AnalyzeMOV(const unsigned char *codePtr, LSInstructionInfo &info) { int accessType = 0; diff --git a/Common/x64Analyzer.h b/Common/x64Analyzer.h index d448d4c60f..8ba78005e5 100644 --- a/Common/x64Analyzer.h +++ b/Common/x64Analyzer.h @@ -19,7 +19,7 @@ #include "Common.h" -struct InstructionInfo +struct LSInstructionInfo { int operandSize; //8, 16, 32, 64 int instructionSize; @@ -60,4 +60,4 @@ enum AccessType { OP_ACCESS_WRITE = 1 }; -bool DisassembleMov(const unsigned char *codePtr, InstructionInfo &info); +bool X86AnalyzeMOV(const unsigned char *codePtr, LSInstructionInfo &info); diff --git a/Core/MIPS/ARM/ArmAsm.cpp b/Core/MIPS/ARM/ArmAsm.cpp index 3a5bcba1a5..fa5a10195d 100644 --- a/Core/MIPS/ARM/ArmAsm.cpp +++ b/Core/MIPS/ARM/ArmAsm.cpp @@ -237,6 +237,7 @@ void ArmJit::GenerateFixedCode() { CMP(R0, 0); B_CC(CC_EQ, outerLoop); + const uint8_t *quitLoop = GetCodePtr(); SetJumpTarget(badCoreState); SaveDowncount(); @@ -251,6 +252,12 @@ void ArmJit::GenerateFixedCode() { POP(9, R4, R5, R6, R7, R8, R9, R10, R11, R_PC); // Returns + crashHandler = GetCodePtr(); + MOVP2R(R0, &coreState); + MOVI2R(R1, CORE_ERROR); + STR(R1, R0, 0); + B(quitLoop); + // Uncomment if you want to see the output... if (disasm) { INFO_LOG(JIT, "THE DISASM ========================"); diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 80a3bc6ae9..50322a65bc 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -51,6 +51,8 @@ public: void Compile(u32 em_address) override; // Compiles a block at current MIPS PC + const u8 *GetCrashHandler() const override { return crashHandler; } + bool CodeInRange(const u8 *ptr) const override { return IsInSpace(ptr); } bool DescribeCodePtr(const u8 *ptr, std::string &name) override; MIPSOpcode GetOriginalOp(MIPSOpcode op) override; @@ -313,6 +315,8 @@ public: const u8 *restoreRoundingMode; const u8 *applyRoundingMode; + + const u8 *crashHandler; }; } // namespace MIPSComp diff --git a/Core/MIPS/ARM64/Arm64Asm.cpp b/Core/MIPS/ARM64/Arm64Asm.cpp index 755e35f57c..a884f6ac4e 100644 --- a/Core/MIPS/ARM64/Arm64Asm.cpp +++ b/Core/MIPS/ARM64/Arm64Asm.cpp @@ -277,6 +277,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { CMP(SCRATCH1, 0); B(CC_EQ, outerLoop); + const uint8_t *quitLoop = GetCodePtr(); SetJumpTarget(badCoreState); SaveStaticRegisters(); @@ -286,6 +287,12 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { RET(); + crashHandler = GetCodePtr(); + MOVP2R(SCRATCH1_64, &coreState); + MOVI2R(SCRATCH2, CORE_ERROR); + STR(INDEX_UNSIGNED, SCRATCH2, SCRATCH1_64, 0); + B(quitLoop); + // Generate some integer conversion funcs. // MIPS order! static const RoundingMode roundModes[8] = { ROUND_N, ROUND_Z, ROUND_P, ROUND_M, ROUND_N, ROUND_Z, ROUND_P, ROUND_M }; diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index 6ad5921d53..17734ade59 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -52,6 +52,8 @@ public: void Compile(u32 em_address) override; // Compiles a block at current MIPS PC const u8 *DoJit(u32 em_address, JitBlock *b); + const u8 *GetCrashHandler() const override { return crashHandler; } + bool CodeInRange(const u8 *ptr) const override { return IsInSpace(ptr); } bool DescribeCodePtr(const u8 *ptr, std::string &name) override; MIPSOpcode GetOriginalOp(MIPSOpcode op) override; @@ -281,6 +283,8 @@ public: const u8 *applyRoundingMode; const u8 *updateRoundingMode; + const u8 *crashHandler; + int jitStartOffset; // Indexed by FPCR FZ:RN bits for convenience. Uses SCRATCH2. diff --git a/Core/MIPS/IR/IRJit.h b/Core/MIPS/IR/IRJit.h index d378dcfc87..9beabe585a 100644 --- a/Core/MIPS/IR/IRJit.h +++ b/Core/MIPS/IR/IRJit.h @@ -160,7 +160,12 @@ public: void InvalidateCacheAt(u32 em_address, int length = 4) override; void UpdateFCR31() override; + bool CodeInRange(const u8 *ptr) const override { + return false; + } + const u8 *GetDispatcher() const override { return nullptr; } + const u8 *GetCrashHandler() const override { return nullptr; } void LinkBlock(u8 *exitPoint, const u8 *checkedEntry) override; void UnlinkBlock(u8 *checkedEntry, u32 originalAddress) override; diff --git a/Core/MIPS/JitCommon/JitCommon.h b/Core/MIPS/JitCommon/JitCommon.h index bf3023e21d..08063f866e 100644 --- a/Core/MIPS/JitCommon/JitCommon.h +++ b/Core/MIPS/JitCommon/JitCommon.h @@ -121,8 +121,10 @@ namespace MIPSComp { public: virtual ~JitInterface() {} + virtual bool CodeInRange(const u8 *ptr) const = 0; virtual bool DescribeCodePtr(const u8 *ptr, std::string &name) = 0; virtual const u8 *GetDispatcher() const = 0; + virtual const u8 *GetCrashHandler() const = 0; virtual JitBlockCache *GetBlockCache() = 0; virtual JitBlockCacheDebugInterface *GetBlockCacheDebugInterface() = 0; virtual void InvalidateCacheAt(u32 em_address, int length = 4) = 0; diff --git a/Core/MIPS/x86/Asm.cpp b/Core/MIPS/x86/Asm.cpp index fd1815132d..d927ba8c6d 100644 --- a/Core/MIPS/x86/Asm.cpp +++ b/Core/MIPS/x86/Asm.cpp @@ -206,11 +206,21 @@ void Jit::GenerateFixedCode(JitOptions &jo) { } J_CC(CC_Z, outerLoop, true); + const uint8_t *quitLoop = GetCodePtr(); SetJumpTarget(badCoreState); RestoreRoundingMode(true); ABI_PopAllCalleeSavedRegsAndAdjustStack(); RET(); + crashHandler = GetCodePtr(); + if (RipAccessible((const void *)&coreState)) { + MOV(32, M(&coreState), Imm32(CORE_RUNTIME_ERROR)); + } else { + MOV(PTRBITS, R(RAX), ImmPtr((const void *)&coreState)); + MOV(32, MatR(RAX), Imm32(CORE_RUNTIME_ERROR)); + } + JMP(quitLoop, true); + // Let's spare the pre-generated code from unprotect-reprotect. endOfPregeneratedCode = AlignCodePage(); EndWrite(); diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 2716f7233a..0dbdf34d7b 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -442,6 +442,8 @@ bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name) { name = "enterDispatcher"; else if (ptr == restoreRoundingMode) name = "restoreRoundingMode"; + else if (ptr == crashHandler) + name = "crashHandler"; else { u32 jitAddr = blocks.GetAddressFromBlockPtr(ptr); diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 0eefe89c40..b065d90522 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -63,6 +63,8 @@ public: void Compile(u32 em_address) override; // Compiles a block at current MIPS PC const u8 *DoJit(u32 em_address, JitBlock *b); + const u8 *GetCrashHandler() const override { return crashHandler; } + bool CodeInRange(const u8 *ptr) const override { return IsInSpace(ptr); } bool DescribeCodePtr(const u8 *ptr, std::string &name) override; void Comp_RunBlock(MIPSOpcode op) override; @@ -325,6 +327,8 @@ private: const u8 *endOfPregeneratedCode; + const u8 *crashHandler; + friend class JitSafeMem; friend class JitSafeMemFuncs; }; diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index af47ce6668..78abbaeacb 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -28,8 +28,20 @@ #include "Common/MemoryUtil.h" #include "Common/MemArena.h" #include "Common/ChunkFile.h" + + +#if defined(PPSSPP_ARCH_AMD64) || defined(PPSSPP_ARCH_X86) #include "Common/MachineContext.h" #include "Common/x64Analyzer.h" +#elif defined(PPSSPP_ARCH_ARM64) +#include "Core/Util/DisArm64.h" +typedef sigcontext SContext; +#define CTX_PC pc +#elif defined(PPSSPP_ARCH_ARM) +#include "ext/disarm.h" +typedef sigcontext SContext; +#define CTX_PC arm_pc +#endif #include "Core/MemMap.h" #include "Core/HDRemaster.h" @@ -43,6 +55,8 @@ #include "Core/ConfigValues.h" #include "Core/HLE/ReplaceTables.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" +#include "Core/MIPS/JitCommon/JitCommon.h" +#include "UI/OnScreenDisplay.h" namespace Memory { @@ -87,6 +101,8 @@ u32 g_PSPModel; std::recursive_mutex g_shutdownLock; +static int64_t g_numReportedBadAccesses = 0; + // We don't declare the IO region in here since its handled by other means. static MemoryView views[] = { @@ -292,6 +308,8 @@ void Init() { INFO_LOG(MEMMAP, "Memory system initialized. Base at %p (RAM at @ %p, uncached @ %p)", base, m_pPhysicalRAM, m_pUncachedRAM); + + g_numReportedBadAccesses = 0; } void Reinit() { @@ -464,7 +482,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); // TODO: Check that codePtr is within the current JIT space. - bool inJitSpace = true; // MIPSComp::jit->IsInSpace(codePtr); + bool inJitSpace = MIPSComp::jit->CodeInRange(codePtr); if (!inJitSpace) { // This is a crash in non-jitted code. Not something we want to handle here, ignore. return false; @@ -486,32 +504,49 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { // OK, a guest executable did a bad access. Take care of it. uint32_t guestAddress = hostAddress - baseAddress; - ERROR_LOG(SYSTEM, "Bad memory access detected and ignored: %08x (%p)", guestAddress, hostAddress); - // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC + + // TODO: Share the struct between the various analyzers, that will allow us to share most of + // the implementations here. #if defined(PPSSPP_ARCH_AMD64) || defined(PPSSPP_ARCH_X86) + // X86, X86-64. Variable instruction size so need to analyze the mov instruction in detail. - InstructionInfo info; - DisassembleMov(codePtr, info); + // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC + LSInstructionInfo info; + X86AnalyzeMOV(codePtr, info); +#elif defined(PPSSPP_ARCH_ARM64) + uint32_t word; + memcpy(&word, codePtr, 4); + // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC + Arm64LSInstructionInfo info; + Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info); +#elif defined(PPSSPP_ARCH_ARM) + uint32_t word; + memcpy(&word, codePtr, 4); + // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC + ArmLSInstructionInfo info; + ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info); +#endif if (g_Config.bIgnoreBadMemAccess) { if (!info.isMemoryWrite) { - // Must have been a read. Fill the register with 0. + // It was a read. Fill the destination register with 0. // TODO } // Move on to the next instruction. context->CTX_PC += info.instructionSize; + // Fall through to logging. } else { - // Jump to a crash handler. - // TODO - context->CTX_PC += info.instructionSize; + // Jump to a crash handler that will exit the game. + context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler(); + ERROR_LOG(SYSTEM, "Bad memory access detected! %08x (%p) Stopping emulation.", guestAddress, (void *)hostAddress); + return true; } -#else - // ARM, ARM64 : All instructions are always 4 bytes in size. As an initial implementation, - // let's just skip the offending instruction. - context->CTX_PC += 4; -#endif + g_numReportedBadAccesses++; + if (g_numReportedBadAccesses < 100) { + ERROR_LOG(SYSTEM, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress); + } return true; } diff --git a/Core/Util/DisArm64.cpp b/Core/Util/DisArm64.cpp index fd17c54412..c891b5eb05 100644 --- a/Core/Util/DisArm64.cpp +++ b/Core/Util/DisArm64.cpp @@ -265,6 +265,41 @@ static void BranchExceptionAndSystem(uint32_t w, uint64_t addr, Instruction *ins } } +void Arm64AnalyzeLoadStore(uint64_t addr, uint32_t w, Arm64LSInstructionInfo *info) { + *info = {}; + info->instructionSize = 4; + int id = (w >> 25) & 0xF; + switch (id) { + case 4: case 6: case 0xC: case 0xE: + info->isLoadOrStore = true; + break; + default: + ERROR_LOG(CPU, "Tried to disassemble %08x at %p as a load/store instruction", w, (void *)addr); + return; // not the expected instruction + } + + info->size = w >> 30; + info->Rt = (w & 0x1F); + info->Rn = ((w >> 5) & 0x1F); + info->Rm = ((w >> 16) & 0x1F); + int opc = (w >> 22) & 0x3; + if (opc == 0 || opc == 2) { + info->isMemoryWrite = true; + } + + if (((w >> 27) & 7) == 7) { + int V = (w >> 26) & 1; + if (V == 0) { + info->isIntegerLoadStore = true; + } else { + info->isFPLoadStore = true; + } + } else { + info->isPairLoadStore = true; + // TODO + } +} + static void LoadStore(uint32_t w, uint64_t addr, Instruction *instr) { int size = w >> 30; int imm9 = SignExtend9((w >> 12) & 0x1FF); diff --git a/Core/Util/DisArm64.h b/Core/Util/DisArm64.h index fc55c6c34b..73b22db4bd 100644 --- a/Core/Util/DisArm64.h +++ b/Core/Util/DisArm64.h @@ -24,3 +24,24 @@ typedef bool (*SymbolCallback)(char *buffer, int bufsize, uint8_t *address); void Arm64Dis(uint64_t addr, uint32_t w, char *output, int bufsize, bool includeWord, SymbolCallback symbolCallback = nullptr); +// Information about a load/store instruction. +struct Arm64LSInstructionInfo { + int instructionSize; + + bool isLoadOrStore; + + bool isIntegerLoadStore; + bool isFPLoadStore; + bool isPairLoadStore; + + int size; // 0 = 8-bit, 1 = 16-bit, 2 = 32-bit, 3 = 64-bit + bool isMemoryWrite; + + int Rt; + int Rn; + int Rm; + + // TODO: more. +}; + +void Arm64AnalyzeLoadStore(uint64_t addr, uint32_t op, Arm64LSInstructionInfo *info); diff --git a/ext/disarm.cpp b/ext/disarm.cpp index 90c89c16b5..c3d0662f3f 100644 --- a/ext/disarm.cpp +++ b/ext/disarm.cpp @@ -72,6 +72,7 @@ #include "base/basictypes.h" #include "Common/ArmEmitter.h" +#include "ext/disarm.h" static const char *CCFlagsStr[] = { "EQ", // Equal @@ -759,30 +760,12 @@ static bool DisasmNeon(uint32_t op, char *text) { return false; } +void ArmAnalyzeLoadStore(uint32_t addr, uint32_t op, ArmLSInstructionInfo *info) { + *info = {}; + info->instructionSize = 4; - - - - - - - - - - - - - - - - - - - - - - - + // TODO +} typedef unsigned int word; diff --git a/ext/disarm.h b/ext/disarm.h index 9bae68f215..138f3e3e69 100644 --- a/ext/disarm.h +++ b/ext/disarm.h @@ -17,18 +17,34 @@ #pragma once +#include -// This stuff only disassembles very old ARM but should be sufficient -// for the basics except for MOVW/MOVT. - - +// This stuff used to only disassemble very old ARM but has now +// been extended to support most (but not all) modern instructions, including NEON. // Disarm itself has the license you can see in the cpp file. // I'm not entirely sure it's 100% gpl compatible but it's nearly // public domain so meh. -// The only changes I've done is C++ compat and replaced the main -// program with this function. - const char *ArmRegName(int r); void ArmDis(unsigned int addr, unsigned int w, char *output, int bufsize, bool includeWord); + +// Information about a load/store instruction. +struct ArmLSInstructionInfo { + int instructionSize; + + bool isIntegerLoadStore; + bool isFPLoadStore; + bool isMultiLoadStore; + + int size; // 0 = 8-bit, 1 = 16-bit, 2 = 32-bit, 3 = 64-bit + bool isMemoryWrite; + + int Rt; + int Rn; + int Rm; + + // TODO: more. +}; + +void ArmAnalyzeLoadStore(uint32_t addr, uint32_t op, ArmLSInstructionInfo *info); From cbc90955ba3d27d53e63fead0d9d1cd53b1085f9 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 12 Feb 2019 13:29:37 +0100 Subject: [PATCH 255/848] Draw a minimal crash dump on the emu screen after a crash (if bIgnoreBadMemAccess is false). Add setting for ignore bad memory accesses --- UI/EmuScreen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 80170e844b..ea0dc9ea11 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1539,8 +1539,10 @@ bool EmuScreen::hasVisibleUI() { return true; // Exception information. - if (coreState == CORE_RUNTIME_ERROR || coreState == CORE_STEPPING) + if (coreState == CORE_RUNTIME_ERROR || coreState == CORE_STEPPING) { return true; + } + return false; } From c3016fe6a506ef1a8fff8f6e01f32b37ec999241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Feb 2019 18:00:57 +0100 Subject: [PATCH 256/848] Mac/Linux buildfixes --- Common/ExceptionHandlerSetup.cpp | 4 +++- Common/MachineContext.h | 12 ++++++------ Core/MemMap.h | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index d9c3d5c4ad..62dd26d984 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -7,11 +7,13 @@ #include #include #include +#include #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" #include "Common/MsgHandler.h" #include "Common/Log.h" +#include "ext/native/thread/threadutil.h" #if defined(PPSSPP_ARCH_X86) || defined(PPSSPP_ARCH_AMD64) #include "Common/MachineContext.h" @@ -103,7 +105,7 @@ static void CheckKR(const char* name, kern_return_t kr) { } static void ExceptionThread(mach_port_t port) { - Common::SetCurrentThreadName("Mach exception thread"); + setCurrentThreadName("Mach exception thread"); #pragma pack(4) struct { mach_msg_header_t Head; diff --git a/Common/MachineContext.h b/Common/MachineContext.h index 643fac4858..9ce074ba41 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -46,7 +46,7 @@ typedef CONTEXT SContext; #include #include -#if _M_X86_64 +#if PPSSPP_ARCH_AMD64 typedef x86_thread_state64_t SContext; #define CTX_RAX __rax #define CTX_RBX __rbx @@ -94,7 +94,7 @@ typedef _STRUCT_MCONTEXT64 SContext; #include typedef mcontext_t SContext; -#if _M_X86_64 +#if PPSSPP_ARCH_AMD64 #define CTX_RAX gregs[REG_RAX] #define CTX_RBX gregs[REG_RBX] #define CTX_RCX gregs[REG_RCX] @@ -122,7 +122,7 @@ typedef mcontext_t SContext; #elif defined(__OpenBSD__) #include typedef ucontext_t SContext; -#if _M_X86_64 +#if PPSSPP_ARCH_AMD64 #define CTX_RAX sc_rax #define CTX_RBX sc_rbx #define CTX_RCX sc_rcx @@ -146,7 +146,7 @@ typedef ucontext_t SContext; #elif defined(__NetBSD__) #include typedef mcontext_t SContext; -#if _M_X86_64 +#if PPSSPP_ARCH_AMD64 #define CTX_RAX __gregs[_REG_RAX] #define CTX_RBX __gregs[_REG_RBX] #define CTX_RCX __gregs[_REG_RCX] @@ -170,7 +170,7 @@ typedef mcontext_t SContext; #elif defined(__FreeBSD__) #include typedef mcontext_t SContext; -#if _M_X86_64 +#if PPSSPP_ARCH_AMD64 #define CTX_RAX mc_rax #define CTX_RBX mc_rbx #define CTX_RCX mc_rcx @@ -194,7 +194,7 @@ typedef mcontext_t SContext; #elif defined(__HAIKU__) #include typedef mcontext_t SContext; -#if _M_X86_64 +#if PPSSPP_ARCH_AMD64 #define CTX_RAX rax #define CTX_RBX rbx #define CTX_RCX rcx diff --git a/Core/MemMap.h b/Core/MemMap.h index a7849a6fb7..dcbbad5441 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -20,6 +20,7 @@ #include "ppsspp_config.h" #include +#include #ifndef offsetof #include #endif From 96a40bb36d32dbcd8fc684afc9f697be065340f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 17 Feb 2019 17:28:36 +0000 Subject: [PATCH 257/848] Exceptions: A bit more consistency in callback registeration. --- Common/ExceptionHandlerSetup.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 62dd26d984..64dc68286a 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +// The corresponding file is called MemTools in the Dolphin project. + #include "Common/ExceptionHandlerSetup.h" #include #include @@ -82,6 +84,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { // Make sure this is only called once per process execution // Instead, could make a Uninstall function, but whatever.. if (g_badAccessHandler) { + g_badAccessHandler = badAccessHandler; return; } @@ -189,13 +192,13 @@ static void ExceptionThread(mach_port_t port) { } void InstallExceptionHandler(BadAccessHandler badAccessHandler) { - if (!g_badAccessHandler) { - g_badAccessHandler = badAccessHandler; - } else { + if (g_badAccessHandler) { // The rest of the setup we don't need to do again. g_badAccessHandler = badAccessHandler; return; } + g_badAccessHandler = badAccessHandler; + INFO_LOG(SYSTEM, "Installing exception handler"); mach_port_t port; CheckKR("mach_port_allocate", @@ -286,6 +289,7 @@ static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context) { void InstallExceptionHandler(BadAccessHandler badAccessHandler) { if (g_badAccessHandler) { + g_badAccessHandler = badAccessHandler; return; } NOTICE_LOG(SYSTEM, "Installed exception handler"); From 236cb5722486c55977f0fbfb277aac0960117bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 17 Feb 2019 17:46:42 +0000 Subject: [PATCH 258/848] More info on crash screen --- UI/EmuScreen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index ea0dc9ea11..b624dd6186 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1271,7 +1271,8 @@ static void DrawCrashDump(DrawBuffer *draw2d) { FontID ubuntu24("UBUNTU24"); char statbuf[4096]; char versionString[256]; - sprintf(versionString, "%s", PPSSPP_GIT_VERSION); + snprintf(versionString, sizeof(versionString), "%s", PPSSPP_GIT_VERSION); + // TODO: Draw a lot more information. Full register set, and so on. #ifdef _DEBUG From fdcf4f06f20457a31ebaa90344df9d09d85fcf0f Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 18 Feb 2019 14:02:39 +0100 Subject: [PATCH 259/848] Add x64Analyzer to Android.mk. Some minor cleanup --- CMakeLists.txt | 3 --- Common/ExceptionHandlerSetup.cpp | 9 +++++--- Common/MachineContext.h | 38 +++++++++++++++++++------------- Core/MIPS/MIPS.h | 6 +++-- Core/MemMap.cpp | 12 +++++----- android/jni/Android.mk | 2 ++ 6 files changed, 41 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9146253dc4..9d866fe92c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -340,9 +340,6 @@ macro(setup_target_project TargetName ProjectDir) endforeach() endmacro() -# Commented-out files are files that don't compile -# and were disabled in the original MSVC project anyway - set(CommonX86 Common/ABI.cpp Common/ABI.h diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 64dc68286a..c5725c581c 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -4,6 +4,8 @@ // The corresponding file is called MemTools in the Dolphin project. +#include "ppsspp_config.h" + #include "Common/ExceptionHandlerSetup.h" #include #include @@ -17,7 +19,7 @@ #include "Common/Log.h" #include "ext/native/thread/threadutil.h" -#if defined(PPSSPP_ARCH_X86) || defined(PPSSPP_ARCH_AMD64) +#if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) #include "Common/MachineContext.h" #endif @@ -225,7 +227,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { void UninstallExceptionHandler() { } -#elif defined(_POSIX_VERSION) && !defined(_M_GENERIC) +#elif defined(_POSIX_VERSION) static struct sigaction old_sa_segv; static struct sigaction old_sa_bus; @@ -329,7 +331,8 @@ void UninstallExceptionHandler() { NOTICE_LOG(SYSTEM, "Uninstalled exception handler"); g_badAccessHandler = nullptr; } -#else // _M_GENERIC or unsupported platform + +#else // Unsupported platform. Could also #error void InstallExceptionHandler(BadAccessHandler badAccessHandler) { ERROR_LOG(SYSTEM, "Exception handler not implemented on this platform, can't install"); diff --git a/Common/MachineContext.h b/Common/MachineContext.h index 9ce074ba41..c39df38abd 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -9,7 +9,7 @@ #if PPSSPP_PLATFORM(WINDOWS) #include typedef CONTEXT SContext; -#if PPSSPP_ARCH_AMD64 +#if PPSSPP_ARCH(AMD64) #define CTX_RAX Rax #define CTX_RBX Rbx #define CTX_RCX Rcx @@ -46,7 +46,7 @@ typedef CONTEXT SContext; #include #include -#if PPSSPP_ARCH_AMD64 +#if PPSSPP_ARCH(AMD64) typedef x86_thread_state64_t SContext; #define CTX_RAX __rax #define CTX_RBX __rbx @@ -94,7 +94,7 @@ typedef _STRUCT_MCONTEXT64 SContext; #include typedef mcontext_t SContext; -#if PPSSPP_ARCH_AMD64 +#if PPSSPP_ARCH(AMD64) #define CTX_RAX gregs[REG_RAX] #define CTX_RBX gregs[REG_RBX] #define CTX_RCX gregs[REG_RCX] @@ -122,7 +122,7 @@ typedef mcontext_t SContext; #elif defined(__OpenBSD__) #include typedef ucontext_t SContext; -#if PPSSPP_ARCH_AMD64 +#if PPSSPP_ARCH(AMD64) #define CTX_RAX sc_rax #define CTX_RBX sc_rbx #define CTX_RCX sc_rcx @@ -146,7 +146,7 @@ typedef ucontext_t SContext; #elif defined(__NetBSD__) #include typedef mcontext_t SContext; -#if PPSSPP_ARCH_AMD64 +#if PPSSPP_ARCH(AMD64) #define CTX_RAX __gregs[_REG_RAX] #define CTX_RBX __gregs[_REG_RBX] #define CTX_RCX __gregs[_REG_RCX] @@ -170,7 +170,7 @@ typedef mcontext_t SContext; #elif defined(__FreeBSD__) #include typedef mcontext_t SContext; -#if PPSSPP_ARCH_AMD64 +#if PPSSPP_ARCH(AMD64) #define CTX_RAX mc_rax #define CTX_RBX mc_rbx #define CTX_RCX mc_rcx @@ -194,7 +194,7 @@ typedef mcontext_t SContext; #elif defined(__HAIKU__) #include typedef mcontext_t SContext; -#if PPSSPP_ARCH_AMD64 +#if PPSSPP_ARCH(AMD64) #define CTX_RAX rax #define CTX_RBX rbx #define CTX_RCX rcx @@ -219,17 +219,12 @@ typedef mcontext_t SContext; #error No context definition for OS #endif -#if defined(PPSSPP_ARCH_AMD64) || defined(PPSSPP_ARCH_X86) +#if PPSSPP_ARCH(AMD64) + #include #define CTX_PC CTX_RIP static inline u64* ContextRN(SContext* ctx, int n) { -#if PPSSPP_ARCH_32BIT - static const u8 offsets[] = { - offsetof(SContext, CTX_RAX), offsetof(SContext, CTX_RCX), offsetof(SContext, CTX_RDX), - offsetof(SContext, CTX_RBX), offsetof(SContext, CTX_RSP), offsetof(SContext, CTX_RBP), - offsetof(SContext, CTX_RSI), offsetof(SContext, CTX_RDI)}; -#else static const u8 offsets[] = { offsetof(SContext, CTX_RAX), offsetof(SContext, CTX_RCX), offsetof(SContext, CTX_RDX), offsetof(SContext, CTX_RBX), offsetof(SContext, CTX_RSP), offsetof(SContext, CTX_RBP), @@ -237,7 +232,20 @@ static inline u64* ContextRN(SContext* ctx, int n) offsetof(SContext, CTX_R9), offsetof(SContext, CTX_R10), offsetof(SContext, CTX_R11), offsetof(SContext, CTX_R12), offsetof(SContext, CTX_R13), offsetof(SContext, CTX_R14), offsetof(SContext, CTX_R15)}; -#endif return (u64*)((char*)ctx + offsets[n]); } + +#elif PPSSPP_ARCH(X86) + +#include +#define CTX_PC CTX_RIP + +static inline u32* ContextRN(SContext* ctx, int n) +{ + static const u8 offsets[] = { + offsetof(SContext, CTX_RAX), offsetof(SContext, CTX_RCX), offsetof(SContext, CTX_RDX), + offsetof(SContext, CTX_RBX), offsetof(SContext, CTX_RSP), offsetof(SContext, CTX_RBP), + offsetof(SContext, CTX_RSI), offsetof(SContext, CTX_RDI)}; + return (u32*)((char*)ctx + offsets[n]); +} #endif diff --git a/Core/MIPS/MIPS.h b/Core/MIPS/MIPS.h index 7d2c40e879..bcc9910358 100644 --- a/Core/MIPS/MIPS.h +++ b/Core/MIPS/MIPS.h @@ -17,6 +17,8 @@ #pragma once +#include "ppsspp_config.h" + #include #include "util/random/rng.h" @@ -148,7 +150,7 @@ extern u8 fromvoffset[128]; enum class CPUCore; -#if defined(PPSSPP_ARCH_X86) || defined(PPSSPP_ARCH_AMD64) +#if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) // Note that CTXREG is offset to point at the first floating point register, intentionally. This is so that a byte offset // can reach both GPR and FPR regs. @@ -246,7 +248,7 @@ public: static const u32 FCR0_VALUE = 0x00003351; -#if defined(PPSSPP_ARCH_X86) || defined(PPSSPP_ARCH_AMD64) +#if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) // FPU TEMP0, etc. are swapped in here if necessary (e.g. on x86.) float tempValues[NUM_X86_FPU_TEMPS]; #endif diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 78abbaeacb..dc92f93121 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -30,14 +30,14 @@ #include "Common/ChunkFile.h" -#if defined(PPSSPP_ARCH_AMD64) || defined(PPSSPP_ARCH_X86) +#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) #include "Common/MachineContext.h" #include "Common/x64Analyzer.h" -#elif defined(PPSSPP_ARCH_ARM64) +#elif PPSSPP_ARCH(ARM64) #include "Core/Util/DisArm64.h" typedef sigcontext SContext; #define CTX_PC pc -#elif defined(PPSSPP_ARCH_ARM) +#elif PPSSPP_ARCH(ARM) #include "ext/disarm.h" typedef sigcontext SContext; #define CTX_PC arm_pc @@ -508,19 +508,19 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { // TODO: Share the struct between the various analyzers, that will allow us to share most of // the implementations here. -#if defined(PPSSPP_ARCH_AMD64) || defined(PPSSPP_ARCH_X86) +#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) // X86, X86-64. Variable instruction size so need to analyze the mov instruction in detail. // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC LSInstructionInfo info; X86AnalyzeMOV(codePtr, info); -#elif defined(PPSSPP_ARCH_ARM64) +#elif PPSSPP_ARCH(ARM64) uint32_t word; memcpy(&word, codePtr, 4); // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC Arm64LSInstructionInfo info; Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info); -#elif defined(PPSSPP_ARCH_ARM) +#elif PPSSPP_ARCH(ARM) uint32_t word; memcpy(&word, codePtr, 4); // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 0adfb91db9..44ab4a7332 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -15,6 +15,7 @@ ifeq ($(TARGET_ARCH_ABI),x86) ARCH_FILES := \ $(SRC)/Common/ABI.cpp \ $(SRC)/Common/x64Emitter.cpp \ + $(SRC)/Common/x64Analyzer.cpp \ $(SRC)/Common/CPUDetect.cpp \ $(SRC)/Common/Thunk.cpp \ $(SRC)/Core/MIPS/x86/CompALU.cpp \ @@ -36,6 +37,7 @@ ifeq ($(TARGET_ARCH_ABI),x86_64) ARCH_FILES := \ $(SRC)/Common/ABI.cpp \ $(SRC)/Common/x64Emitter.cpp \ + $(SRC)/Common/x64Analyzer.cpp \ $(SRC)/Common/CPUDetect.cpp \ $(SRC)/Common/Thunk.cpp \ $(SRC)/Core/MIPS/x86/CompALU.cpp \ From ac456c2231f4fe3f4e2a020da2cb95010177e96f Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 18 Feb 2019 14:50:57 +0100 Subject: [PATCH 260/848] MachineContext, Linux/Android: Try to support android-x86 (32-bit) --- Common/MachineContext.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Common/MachineContext.h b/Common/MachineContext.h index c39df38abd..34e5a280a0 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -112,10 +112,16 @@ typedef mcontext_t SContext; #define CTX_R14 gregs[REG_R14] #define CTX_R15 gregs[REG_R15] #define CTX_RIP gregs[REG_RIP] -#elif _M_ARM_64 -#define CTX_REG(x) regs[x] -#define CTX_SP sp -#define CTX_PC pc +#elif PPSSPP_ARCH(X86) +#define CTX_RAX gregs[REG_EAX] +#define CTX_RBX gregs[REG_EBX] +#define CTX_RCX gregs[REG_ECX] +#define CTX_RDX gregs[REG_EDX] +#define CTX_RDI gregs[REG_EDI] +#define CTX_RSI gregs[REG_ESI] +#define CTX_RBP gregs[REG_EBP] +#define CTX_RSP gregs[REG_ESP] +#define CTX_RIP gregs[REG_EIP] #else #error No context definition for architecture #endif From 15c7358e8017981db4098887b7d2583a08ea7b77 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 18 Feb 2019 15:00:31 +0100 Subject: [PATCH 261/848] Try USE_SIGACTION_ON_APPLE on IOS. --- Common/ExceptionHandlerSetup.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index c5725c581c..37913774af 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -23,6 +23,10 @@ #include "Common/MachineContext.h" #endif +#if PPSSPP_PLATFORM(IOS) +#define USE_SIGACTION_ON_APPLE +#endif + #ifdef __FreeBSD__ #include #endif From 430c3ee6a384749d9fcc5c759cc46920cd3d6955 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 18 Feb 2019 15:09:58 +0100 Subject: [PATCH 262/848] HandleFault: Add missing nullcheck --- Core/MemMap.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index dc92f93121..684d162b5e 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -482,7 +482,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); // TODO: Check that codePtr is within the current JIT space. - bool inJitSpace = MIPSComp::jit->CodeInRange(codePtr); + bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr); if (!inJitSpace) { // This is a crash in non-jitted code. Not something we want to handle here, ignore. return false; @@ -533,19 +533,16 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { // It was a read. Fill the destination register with 0. // TODO } - // Move on to the next instruction. + // Move on to the next instruction. Note that handling bad accesses like this is pretty slow. context->CTX_PC += info.instructionSize; - // Fall through to logging. + g_numReportedBadAccesses++; + if (g_numReportedBadAccesses < 100) { + ERROR_LOG(MEMMAP, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress); + } } else { - // Jump to a crash handler that will exit the game. + // Redirect execution to a crash handler that will exit the game. context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler(); - ERROR_LOG(SYSTEM, "Bad memory access detected! %08x (%p) Stopping emulation.", guestAddress, (void *)hostAddress); - return true; - } - - g_numReportedBadAccesses++; - if (g_numReportedBadAccesses < 100) { - ERROR_LOG(SYSTEM, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress); + ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation.", guestAddress, (void *)hostAddress); } return true; } From 465367bf1b3116c55bd15d5c44d1398d7acf4429 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 18 Feb 2019 16:04:38 +0100 Subject: [PATCH 263/848] iOS buildfix attempt --- Core/MemMap.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 684d162b5e..fa1e3d96b5 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -29,6 +29,12 @@ #include "Common/MemArena.h" #include "Common/ChunkFile.h" +#ifdef __FreeBSD__ +#include +#endif +#ifndef _WIN32 +#include // Needed for _POSIX_VERSION +#endif #if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) #include "Common/MachineContext.h" From a56f39171346708cc5dbbc72a93c8c24ba7d5180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jul 2020 11:40:58 +0200 Subject: [PATCH 264/848] Make fastmem memory exceptions report the exceptions to Core correctly. --- Common/ExceptionHandlerSetup.cpp | 4 ++-- Core/Core.h | 1 + Core/MemMap.cpp | 22 ++++++++++++++++++---- UI/EmuScreen.cpp | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 37913774af..7c8d64b1eb 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -40,7 +40,7 @@ static BadAccessHandler g_badAccessHandler; static PVOID g_vectoredExceptionHandle; -static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) { +static LONG NTAPI GlobalExceptionHandler(PEXCEPTION_POINTERS pPtrs) { switch (pPtrs->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: { @@ -96,7 +96,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { INFO_LOG(SYSTEM, "Installing exception handler"); g_badAccessHandler = badAccessHandler; - g_vectoredExceptionHandle = AddVectoredExceptionHandler(TRUE, Handler); + g_vectoredExceptionHandle = AddVectoredExceptionHandler(TRUE, GlobalExceptionHandler); } void UninstallExceptionHandler() { diff --git a/Core/Core.h b/Core/Core.h index 6cb8004cf4..e7bdb5a462 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -80,6 +80,7 @@ void Core_SetPowerSaving(bool mode); bool Core_GetPowerSaving(); enum class MemoryExceptionType { + NONE, READ_WORD, WRITE_WORD, READ_BLOCK, diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index fa1e3d96b5..9e8968fd8c 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -513,28 +513,38 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { // TODO: Share the struct between the various analyzers, that will allow us to share most of // the implementations here. + bool success = false; + + MemoryExceptionType type = MemoryExceptionType::NONE; #if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) // X86, X86-64. Variable instruction size so need to analyze the mov instruction in detail. // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC LSInstructionInfo info; - X86AnalyzeMOV(codePtr, info); + success = X86AnalyzeMOV(codePtr, info); #elif PPSSPP_ARCH(ARM64) uint32_t word; memcpy(&word, codePtr, 4); // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC Arm64LSInstructionInfo info; - Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info); + success = Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info); #elif PPSSPP_ARCH(ARM) uint32_t word; memcpy(&word, codePtr, 4); // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC ArmLSInstructionInfo info; - ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info); + success = ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info); #endif + if (success) { + if (info.isMemoryWrite) { + type = MemoryExceptionType::WRITE_WORD; + } else { + type = MemoryExceptionType::READ_WORD; + } + } - if (g_Config.bIgnoreBadMemAccess) { + if (success && g_Config.bIgnoreBadMemAccess) { if (!info.isMemoryWrite) { // It was a read. Fill the destination register with 0. // TODO @@ -546,6 +556,10 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { ERROR_LOG(MEMMAP, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress); } } else { + // Either bIgnoreBadMemAccess is off, or we failed recovery analysis. + uint32_t approximatePC = currentMIPS->pc; + Core_MemoryException(guestAddress, currentMIPS->pc, type); + // Redirect execution to a crash handler that will exit the game. context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler(); ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation.", guestAddress, (void *)hostAddress); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index b624dd6186..7992aeab31 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1158,7 +1158,7 @@ void EmuScreen::update() { PSP_CoreParameter().pixelHeight = pixel_yres * bounds.h / dp_yres; #endif - if (!invalid_) { + if (!invalid_ && coreState != CORE_RUNTIME_ERROR) { UpdateUIState(UISTATE_INGAME); } From 6f97c3d4228a34f6c4dad0c0b724d38c758c0282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 13 Jul 2020 09:17:42 +0200 Subject: [PATCH 265/848] Various platform buildfixes --- Common/ExceptionHandlerSetup.cpp | 3 ++- Core/Core.cpp | 1 + Core/Core.h | 1 + Core/CoreTiming.cpp | 5 +++++ Core/MIPS/ARM/ArmAsm.cpp | 2 +- Core/MIPS/ARM64/Arm64Asm.cpp | 2 +- Core/MemMap.cpp | 2 ++ Core/Util/DisArm64.cpp | 7 +++---- Core/Util/DisArm64.h | 6 ++---- ext/disarm.cpp | 4 +++- ext/disarm.h | 2 +- 11 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 7c8d64b1eb..6cdbefede4 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -36,7 +36,8 @@ static BadAccessHandler g_badAccessHandler; -#ifdef _WIN32 +// We cannot handle exceptions in UWP builds. Bleh. +#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP) static PVOID g_vectoredExceptionHandle; diff --git a/Core/Core.cpp b/Core/Core.cpp index ecc3d08259..dfb28a6fc8 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -395,6 +395,7 @@ const char *ExceptionTypeAsString(ExceptionType type) { const char *MemoryExceptionTypeAsString(MemoryExceptionType type) { switch (type) { + case MemoryExceptionType::UNKNOWN: return "Unknown"; case MemoryExceptionType::READ_WORD: return "Read Word"; case MemoryExceptionType::WRITE_WORD: return "Write Word"; case MemoryExceptionType::READ_BLOCK: return "Read Block"; diff --git a/Core/Core.h b/Core/Core.h index e7bdb5a462..314a2823a1 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -81,6 +81,7 @@ bool Core_GetPowerSaving(); enum class MemoryExceptionType { NONE, + UNKNOWN, READ_WORD, WRITE_WORD, READ_BLOCK, diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 2f0016d511..251a2c0f9e 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -97,6 +97,11 @@ void FireMhzChange() { } void SetClockFrequencyHz(int cpuHz) { + if (cpuHz <= 0) { + // Paranoid check, protecting against division by zero and similar nonsense. + return; + } + // When the mhz changes, we keep track of what "time" it was before hand. // This way, time always moves forward, even if mhz is changed. lastGlobalTimeUs = GetGlobalTimeUs(); diff --git a/Core/MIPS/ARM/ArmAsm.cpp b/Core/MIPS/ARM/ArmAsm.cpp index fa5a10195d..44176dc293 100644 --- a/Core/MIPS/ARM/ArmAsm.cpp +++ b/Core/MIPS/ARM/ArmAsm.cpp @@ -254,7 +254,7 @@ void ArmJit::GenerateFixedCode() { crashHandler = GetCodePtr(); MOVP2R(R0, &coreState); - MOVI2R(R1, CORE_ERROR); + MOVI2R(R1, CORE_RUNTIME_ERROR); STR(R1, R0, 0); B(quitLoop); diff --git a/Core/MIPS/ARM64/Arm64Asm.cpp b/Core/MIPS/ARM64/Arm64Asm.cpp index a884f6ac4e..81f67fa3a3 100644 --- a/Core/MIPS/ARM64/Arm64Asm.cpp +++ b/Core/MIPS/ARM64/Arm64Asm.cpp @@ -289,7 +289,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { crashHandler = GetCodePtr(); MOVP2R(SCRATCH1_64, &coreState); - MOVI2R(SCRATCH2, CORE_ERROR); + MOVI2R(SCRATCH2, CORE_RUNTIME_ERROR); STR(INDEX_UNSIGNED, SCRATCH2, SCRATCH1_64, 0); B(quitLoop); diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 9e8968fd8c..34d2b5f76d 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -542,6 +542,8 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { } else { type = MemoryExceptionType::READ_WORD; } + } else { + type = MemoryExceptionType::UNKNOWN; } if (success && g_Config.bIgnoreBadMemAccess) { diff --git a/Core/Util/DisArm64.cpp b/Core/Util/DisArm64.cpp index c891b5eb05..e6c983be55 100644 --- a/Core/Util/DisArm64.cpp +++ b/Core/Util/DisArm64.cpp @@ -265,17 +265,15 @@ static void BranchExceptionAndSystem(uint32_t w, uint64_t addr, Instruction *ins } } -void Arm64AnalyzeLoadStore(uint64_t addr, uint32_t w, Arm64LSInstructionInfo *info) { +bool Arm64AnalyzeLoadStore(uint64_t addr, uint32_t w, Arm64LSInstructionInfo *info) { *info = {}; info->instructionSize = 4; int id = (w >> 25) & 0xF; switch (id) { case 4: case 6: case 0xC: case 0xE: - info->isLoadOrStore = true; break; default: - ERROR_LOG(CPU, "Tried to disassemble %08x at %p as a load/store instruction", w, (void *)addr); - return; // not the expected instruction + return false; // not the expected instruction } info->size = w >> 30; @@ -298,6 +296,7 @@ void Arm64AnalyzeLoadStore(uint64_t addr, uint32_t w, Arm64LSInstructionInfo *in info->isPairLoadStore = true; // TODO } + return true; } static void LoadStore(uint32_t w, uint64_t addr, Instruction *instr) { diff --git a/Core/Util/DisArm64.h b/Core/Util/DisArm64.h index 73b22db4bd..ced77f2cc2 100644 --- a/Core/Util/DisArm64.h +++ b/Core/Util/DisArm64.h @@ -18,7 +18,7 @@ // Basic ARM64 disassembler. // No promises of accuracy, mostly just made to debug JIT code. -#include +#include typedef bool (*SymbolCallback)(char *buffer, int bufsize, uint8_t *address); @@ -28,8 +28,6 @@ void Arm64Dis(uint64_t addr, uint32_t w, char *output, int bufsize, bool include struct Arm64LSInstructionInfo { int instructionSize; - bool isLoadOrStore; - bool isIntegerLoadStore; bool isFPLoadStore; bool isPairLoadStore; @@ -44,4 +42,4 @@ struct Arm64LSInstructionInfo { // TODO: more. }; -void Arm64AnalyzeLoadStore(uint64_t addr, uint32_t op, Arm64LSInstructionInfo *info); +bool Arm64AnalyzeLoadStore(uint64_t addr, uint32_t op, Arm64LSInstructionInfo *info); diff --git a/ext/disarm.cpp b/ext/disarm.cpp index c3d0662f3f..ece10410f4 100644 --- a/ext/disarm.cpp +++ b/ext/disarm.cpp @@ -760,11 +760,13 @@ static bool DisasmNeon(uint32_t op, char *text) { return false; } -void ArmAnalyzeLoadStore(uint32_t addr, uint32_t op, ArmLSInstructionInfo *info) { +bool ArmAnalyzeLoadStore(uint32_t addr, uint32_t op, ArmLSInstructionInfo *info) { *info = {}; info->instructionSize = 4; // TODO + + return false; } diff --git a/ext/disarm.h b/ext/disarm.h index 138f3e3e69..901e74cd4f 100644 --- a/ext/disarm.h +++ b/ext/disarm.h @@ -47,4 +47,4 @@ struct ArmLSInstructionInfo { // TODO: more. }; -void ArmAnalyzeLoadStore(uint32_t addr, uint32_t op, ArmLSInstructionInfo *info); +bool ArmAnalyzeLoadStore(uint32_t addr, uint32_t op, ArmLSInstructionInfo *info); From f6cc45a96a9caa3e23498e37386d2bf16caf9789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 14 Jul 2020 09:31:58 +0200 Subject: [PATCH 266/848] Another iOS buildfix attempt --- Core/MemMap.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 34d2b5f76d..c935d6b99b 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -43,7 +43,7 @@ #include "Core/Util/DisArm64.h" typedef sigcontext SContext; #define CTX_PC pc -#elif PPSSPP_ARCH(ARM) +#elif PPSSPP_ARCH(ARM) && !PPSSPP_PLATFORM(IOS) #include "ext/disarm.h" typedef sigcontext SContext; #define CTX_PC arm_pc @@ -245,16 +245,22 @@ bool MemoryMap_Setup(u32 flags) { #if !PPSSPP_PLATFORM(ANDROID) if (g_arena.NeedsProbing()) { int base_attempts = 0; -#if defined(_WIN32) && PPSSPP_ARCH(32BIT) +#if PPSSPP_PLATFORM(WINDOWS) && PPSSPP_ARCH(32BIT) // Try a whole range of possible bases. Return once we got a valid one. uintptr_t max_base_addr = 0x7FFF0000 - 0x10000000; uintptr_t min_base_addr = 0x01000000; uintptr_t stride = 0x400000; -#else +#elif PPSSPP_ARCH(ARM64) && PPSSPP_PLATFORM(IOS) // iOS uintptr_t max_base_addr = 0x1FFFF0000ULL - 0x80000000ULL; uintptr_t min_base_addr = 0x100000000ULL; uintptr_t stride = 0x800000; +#else + uintptr_t max_base_addr = 0; + uintptr_t min_base_addr = 0; + uintptr_t stride = 0; + ERROR_LOG(MEMMAP, "MemoryMap_Setup: Hit a wrong path, should not be needed on this platform."); + return false; #endif for (uintptr_t base_addr = min_base_addr; base_addr < max_base_addr; base_addr += stride) { base_attempts++; From 893aa29191fe3aeef808102f1827552ba2c2ccf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 14 Jul 2020 10:34:40 +0200 Subject: [PATCH 267/848] Yet another iOS buildfix attempt --- Core/MemMap.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index c935d6b99b..b20a39d783 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -489,6 +489,10 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength) { CBreakPoints::ExecMemCheck(_Address, true, _iLength, currentMIPS->pc); } +// We do not support crash catching on UWP and iOS. +// On iOS, the sigcontext struct seems to be missing?? +#if !PPSSPP_PLATFORM(IOS) && !PPSSPP_PLATFORM(UWP) + bool HandleFault(uintptr_t hostAddress, void *ctx) { SContext *context = (SContext *)ctx; const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); @@ -575,4 +579,13 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { return true; } +#else + +bool HandleFault(uintptr_t hostAddress, void *ctx) { + ERROR_LOG(MEMMAP, "Exception handling not supported"); + return false; +} + +#endif + } // namespace From f62df94ab2ad86550276a21c91043de1559b926e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 14 Jul 2020 11:39:18 +0200 Subject: [PATCH 268/848] There's no sigcontext on 64-bit iOS either, apparently. --- Core/MemMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index b20a39d783..4c36b7c608 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -39,7 +39,7 @@ #if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) #include "Common/MachineContext.h" #include "Common/x64Analyzer.h" -#elif PPSSPP_ARCH(ARM64) +#elif PPSSPP_ARCH(ARM64) && !PPSSPP_PLATFORM(IOS) #include "Core/Util/DisArm64.h" typedef sigcontext SContext; #define CTX_PC pc From 056999a691289f23be02e4e9f12c818396ecc5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 14 Jul 2020 12:06:31 +0200 Subject: [PATCH 269/848] Refactor MachineContext.h to reduce ifdefs elsewhere. Also fixes Windows on ARM64 (at least the build). --- Common/ExceptionHandlerSetup.cpp | 21 ++--- Common/MachineContext.h | 156 ++++++++++++++++++++++++------- Core/MemMap.cpp | 16 +--- 3 files changed, 133 insertions(+), 60 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 6cdbefede4..e8ca92b0a9 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -19,23 +19,16 @@ #include "Common/Log.h" #include "ext/native/thread/threadutil.h" -#if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) #include "Common/MachineContext.h" -#endif -#if PPSSPP_PLATFORM(IOS) -#define USE_SIGACTION_ON_APPLE -#endif - -#ifdef __FreeBSD__ -#include -#endif #ifndef _WIN32 #include // Needed for _POSIX_VERSION #endif static BadAccessHandler g_badAccessHandler; +#ifdef MACHINE_CONTEXT_SUPPORTED + // We cannot handle exceptions in UWP builds. Bleh. #if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP) @@ -106,7 +99,7 @@ void UninstallExceptionHandler() { INFO_LOG(SYSTEM, "Removed exception handler"); } -#elif defined(__APPLE__) && !defined(USE_SIGACTION_ON_APPLE) +#elif defined(__APPLE__) static void CheckKR(const char* name, kern_return_t kr) { if (kr) { @@ -339,9 +332,15 @@ void UninstallExceptionHandler() { #else // Unsupported platform. Could also #error +#error Shouldn't get here + +#endif + +#else // !MACHINE_CONTEXT_SUPPORTED + void InstallExceptionHandler(BadAccessHandler badAccessHandler) { ERROR_LOG(SYSTEM, "Exception handler not implemented on this platform, can't install"); } void UninstallExceptionHandler() { } -#endif +#endif // MACHINE_CONTEXT_SUPPORTED diff --git a/Common/MachineContext.h b/Common/MachineContext.h index 34e5a280a0..5fca7a3204 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -2,14 +2,22 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +// Note: If MACHINE_CONTEXT_SUPPORTED is not set after including this, +// there is no access to the context from exception handlers (and possibly no exception handling support). + #pragma once #include "ppsspp_config.h" -#if PPSSPP_PLATFORM(WINDOWS) +#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP) + #include typedef CONTEXT SContext; + #if PPSSPP_ARCH(AMD64) + +#define MACHINE_CONTEXT_SUPPORTED + #define CTX_RAX Rax #define CTX_RBX Rbx #define CTX_RCX Rcx @@ -27,7 +35,11 @@ typedef CONTEXT SContext; #define CTX_R14 R14 #define CTX_R15 R15 #define CTX_RIP Rip -#else + +#elif PPSSPP_ARCH(X86) + +#define MACHINE_CONTEXT_SUPPORTED + #define CTX_RAX Eax #define CTX_RBX Ebx #define CTX_RCX Ecx @@ -38,15 +50,27 @@ typedef CONTEXT SContext; #define CTX_RSP Esp #define CTX_RIP Eip +#elif PPSSPP_ARCH(ARM64) + +#define CTX_REG(x) X[x] +#define CTX_SP Sp +#define CTX_PC Pc + #endif -#elif defined(__APPLE__) && !defined(USE_SIGACTION_ON_APPLE) + +#elif PPSSPP_PLATFORM(MACOS) + // for modules: #define _XOPEN_SOURCE #include #include #include + #if PPSSPP_ARCH(AMD64) + +#define MACHINE_CONTEXT_SUPPORTED + typedef x86_thread_state64_t SContext; #define CTX_RAX __rax #define CTX_RBX __rbx @@ -65,36 +89,24 @@ typedef x86_thread_state64_t SContext; #define CTX_R14 __r14 #define CTX_R15 __r15 #define CTX_RIP __rip + #else -#error No context definition for architecture + +// No context definition for architecture + #endif -#elif defined(__APPLE__) -#include -typedef _STRUCT_MCONTEXT64 SContext; -#define CTX_RAX __ss.__rax -#define CTX_RBX __ss.__rbx -#define CTX_RCX __ss.__rcx -#define CTX_RDX __ss.__rdx -#define CTX_RDI __ss.__rdi -#define CTX_RSI __ss.__rsi -#define CTX_RBP __ss.__rbp -#define CTX_RSP __ss.__rsp -#define CTX_R8 __ss.__r8 -#define CTX_R9 __ss.__r9 -#define CTX_R10 __ss.__r10 -#define CTX_R11 __ss.__r11 -#define CTX_R12 __ss.__r12 -#define CTX_R13 __ss.__r13 -#define CTX_R14 __ss.__r14 -#define CTX_R15 __ss.__r15 -#define CTX_RIP __ss.__rip + #elif defined(__linux__) + #include +#if PPSSPP_ARCH(AMD64) + #include typedef mcontext_t SContext; -#if PPSSPP_ARCH(AMD64) +#define MACHINE_CONTEXT_SUPPORTED + #define CTX_RAX gregs[REG_RAX] #define CTX_RBX gregs[REG_RBX] #define CTX_RCX gregs[REG_RCX] @@ -112,7 +124,14 @@ typedef mcontext_t SContext; #define CTX_R14 gregs[REG_R14] #define CTX_R15 gregs[REG_R15] #define CTX_RIP gregs[REG_RIP] + #elif PPSSPP_ARCH(X86) + +#include +typedef mcontext_t SContext; + +#define MACHINE_CONTEXT_SUPPORTED + #define CTX_RAX gregs[REG_EAX] #define CTX_RBX gregs[REG_EBX] #define CTX_RCX gregs[REG_ECX] @@ -122,13 +141,40 @@ typedef mcontext_t SContext; #define CTX_RBP gregs[REG_EBP] #define CTX_RSP gregs[REG_ESP] #define CTX_RIP gregs[REG_EIP] + +#elif PPSSPP_ARCH(ARM64) + +#define MACHINE_CONTEXT_SUPPORTED + +typedef sigcontext SContext; + +#define CTX_REG(x) regs[x] +#define CTX_SP sp +#define CTX_PC pc + +#elif PPSSPP_ARCH(ARM) + +#define MACHINE_CONTEXT_SUPPORTED + +typedef sigcontext SContext; +#define CTX_PC arm_pc +#define CTX_REG(x) regs[x] + #else -#error No context definition for architecture + +// No context definition for architecture + #endif + #elif defined(__OpenBSD__) + +#if PPSSPP_ARCH(AMD64) + #include typedef ucontext_t SContext; -#if PPSSPP_ARCH(AMD64) + +#define MACHINE_CONTEXT_SUPPORTED + #define CTX_RAX sc_rax #define CTX_RBX sc_rbx #define CTX_RCX sc_rcx @@ -146,13 +192,22 @@ typedef ucontext_t SContext; #define CTX_R14 sc_r14 #define CTX_R15 sc_r15 #define CTX_RIP sc_rip + #else -#error No context definition for architecture + +// No context definition for architecture + #endif + #elif defined(__NetBSD__) + +#if PPSSPP_ARCH(AMD64) + #include typedef mcontext_t SContext; -#if PPSSPP_ARCH(AMD64) + +#define MACHINE_CONTEXT_SUPPORTED + #define CTX_RAX __gregs[_REG_RAX] #define CTX_RBX __gregs[_REG_RBX] #define CTX_RCX __gregs[_REG_RCX] @@ -170,13 +225,22 @@ typedef mcontext_t SContext; #define CTX_R14 __gregs[_REG_R14] #define CTX_R15 __gregs[_REG_R15] #define CTX_RIP __gregs[_REG_RIP] + #else -#error No context definition for architecture + +// No context definition for architecture + #endif + #elif defined(__FreeBSD__) + +#if PPSSPP_ARCH(AMD64) + #include typedef mcontext_t SContext; -#if PPSSPP_ARCH(AMD64) + +#define MACHINE_CONTEXT_SUPPORTED + #define CTX_RAX mc_rax #define CTX_RBX mc_rbx #define CTX_RCX mc_rcx @@ -194,13 +258,22 @@ typedef mcontext_t SContext; #define CTX_R14 mc_r14 #define CTX_R15 mc_r15 #define CTX_RIP mc_rip + #else -#error No context definition for architecture + +// No context definition for architecture + #endif + #elif defined(__HAIKU__) + +#if PPSSPP_ARCH(AMD64) + #include typedef mcontext_t SContext; -#if PPSSPP_ARCH(AMD64) + +#define MACHINE_CONTEXT_SUPPORTED + #define CTX_RAX rax #define CTX_RBX rbx #define CTX_RCX rcx @@ -218,13 +291,21 @@ typedef mcontext_t SContext; #define CTX_R14 r14 #define CTX_R15 r15 #define CTX_RIP rip + #else -#error No context definition for machine + +// No context definition for machine + #endif + #else -#error No context definition for OS + +// No context definition for OS + #endif +#ifdef MACHINE_CONTEXT_SUPPORTED + #if PPSSPP_ARCH(AMD64) #include @@ -254,4 +335,7 @@ static inline u32* ContextRN(SContext* ctx, int n) offsetof(SContext, CTX_RSI), offsetof(SContext, CTX_RDI)}; return (u32*)((char*)ctx + offsets[n]); } -#endif + +#endif // arch + +#endif // MACHINE_CONTEXT_SUPPORTED diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 4c36b7c608..5eefe1c941 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -29,24 +29,14 @@ #include "Common/MemArena.h" #include "Common/ChunkFile.h" -#ifdef __FreeBSD__ -#include -#endif -#ifndef _WIN32 -#include // Needed for _POSIX_VERSION -#endif +#include "Common/MachineContext.h" #if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) -#include "Common/MachineContext.h" #include "Common/x64Analyzer.h" -#elif PPSSPP_ARCH(ARM64) && !PPSSPP_PLATFORM(IOS) +#elif PPSSPP_ARCH(ARM64) #include "Core/Util/DisArm64.h" -typedef sigcontext SContext; -#define CTX_PC pc -#elif PPSSPP_ARCH(ARM) && !PPSSPP_PLATFORM(IOS) +#elif PPSSPP_ARCH(ARM) #include "ext/disarm.h" -typedef sigcontext SContext; -#define CTX_PC arm_pc #endif #include "Core/MemMap.h" From 82bc6f6cc5a1dd8ebfe150409b17cc9956e9dc51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 14 Jul 2020 13:47:07 +0200 Subject: [PATCH 270/848] Windows ARM fix, cleanup --- Common/MachineContext.h | 6 ++++++ GPU/Common/ShaderTranslation.cpp | 5 +++++ UI/UI.vcxproj | 10 +++++----- Windows/PPSSPP.vcxproj | 5 +---- ext/native/native.vcxproj | 1 - headless/Headless.vcxproj | 4 ---- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Common/MachineContext.h b/Common/MachineContext.h index 5fca7a3204..f6aa42d7ea 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -56,6 +56,12 @@ typedef CONTEXT SContext; #define CTX_SP Sp #define CTX_PC Pc +#elif PPSSPP_ARCH(ARM) + +//#define CTX_REG(x) R##x +#define CTX_SP Sp +#define CTX_PC Pc + #endif #elif PPSSPP_PLATFORM(MACOS) diff --git a/GPU/Common/ShaderTranslation.cpp b/GPU/Common/ShaderTranslation.cpp index 2361ba9e11..3693e2393d 100644 --- a/GPU/Common/ShaderTranslation.cpp +++ b/GPU/Common/ShaderTranslation.cpp @@ -29,6 +29,11 @@ #undef realloc #endif +// Weird issue +#if PPSSPP_PLATFORM(WINDOWS) && PPSSPP_ARCH(ARM) +#undef free +#endif + #include "base/logging.h" #include "base/basictypes.h" #include "base/stringutil.h" diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index 2ea403dff0..132b9b9640 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -248,7 +248,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_64=1;WIN32;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext true false false @@ -269,7 +269,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_32=1;WIN32;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext true false false @@ -346,7 +346,7 @@ true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_64=1;WIN32;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext false true false @@ -373,7 +373,7 @@ true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_32=1;WIN32;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext false true false @@ -394,4 +394,4 @@ - + \ No newline at end of file diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index aed4bc4e16..ed8abc3a30 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -119,7 +119,6 @@ Application Unicode $(DefaultPlatformToolset) - Spectre true @@ -349,7 +348,6 @@ stdafx.h MultiThreadedDebug false - NotSet Precise true false @@ -513,7 +511,6 @@ Sync MultiThreaded false - NotSet Precise Use Level3 @@ -1720,4 +1717,4 @@ - + \ No newline at end of file diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 919ce1166b..d13049e3e9 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -310,7 +310,6 @@ true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); - NotSet Precise true false diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 13618da2af..8702c8a511 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -243,7 +243,6 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native - NotSet Precise false true @@ -273,7 +272,6 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native - NotSet Precise false true @@ -381,7 +379,6 @@ USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native false - NotSet Precise Speed false @@ -416,7 +413,6 @@ USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native false - NotSet Precise Speed false From d4e1f87487c5931bb74f7e7a2dc3a7d65f8f50a1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 14 Jul 2020 14:09:50 +0200 Subject: [PATCH 271/848] (Libretro) Buildfix - add missing file x64Analyzer.cpp --- libretro/Makefile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index ed78f44cc4..0ac5b33297 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -569,6 +569,7 @@ endif endif SOURCES_CXX += $(GPUDIR)/Software/SamplerX86.cpp SOURCES_CXX += $(COMMONDIR)/x64Emitter.cpp \ + $(COMMONDIR)/x64Analyzer.cpp \ $(COMMONDIR)/ABI.cpp \ $(COMMONDIR)/Thunk.cpp \ $(COMMONDIR)/CPUDetect.cpp \ From cb1e0438f9f170f7c8c9f434b8128922705cf08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 14 Jul 2020 14:39:19 +0200 Subject: [PATCH 272/848] Fix --- Common/MachineContext.h | 2 +- Core/MemMap.cpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Common/MachineContext.h b/Common/MachineContext.h index f6aa42d7ea..fdd84f26d1 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -64,7 +64,7 @@ typedef CONTEXT SContext; #endif -#elif PPSSPP_PLATFORM(MACOS) +#elif PPSSPP_PLATFORM(MAC) // for modules: #define _XOPEN_SOURCE diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 5eefe1c941..730613d5e9 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -479,9 +479,7 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength) { CBreakPoints::ExecMemCheck(_Address, true, _iLength, currentMIPS->pc); } -// We do not support crash catching on UWP and iOS. -// On iOS, the sigcontext struct seems to be missing?? -#if !PPSSPP_PLATFORM(IOS) && !PPSSPP_PLATFORM(UWP) +#ifdef MACHINE_CONTEXT_SUPPORTED bool HandleFault(uintptr_t hostAddress, void *ctx) { SContext *context = (SContext *)ctx; From 3e817eae4f1aaa4371e7379bfda3bafb83f5ba54 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 14 Jul 2020 07:27:12 -0700 Subject: [PATCH 273/848] Travis: Don't update python3. We already have python3, so no need to update, hopefully. --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a9a454f062..fccd90b7bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,6 @@ addons: update: true packages: - ccache - - python - sdl2 cache: From 500107a540e59bf17c705c49213a01c170870c3b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 14 Jul 2020 18:59:23 -0700 Subject: [PATCH 274/848] Savedata: Correct AM/PM and time/date settings. The defaults and exposed system param values were out of sync. --- Core/Config.cpp | 4 +- Core/Dialog/PSPSaveDialog.cpp | 150 +++++++++++++--------------------- Core/HLE/sceUtility.cpp | 5 +- UI/GameSettingsScreen.cpp | 6 +- 4 files changed, 67 insertions(+), 98 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 9ff2635200..1ef4dc5ba2 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -973,8 +973,8 @@ static ConfigSetting systemParamSettings[] = { ConfigSetting("MacAddress", &g_Config.sMACAddress, "", true, true), ConfigSetting("PortOffset", &g_Config.iPortOffset, 0, true, true), ReportedConfigSetting("Language", &g_Config.iLanguage, &DefaultSystemParamLanguage, true, true), - ConfigSetting("TimeFormat", &g_Config.iTimeFormat, PSP_SYSTEMPARAM_TIME_FORMAT_24HR, true, true), - ConfigSetting("DateFormat", &g_Config.iDateFormat, PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD, true, true), + ConfigSetting("ParamTimeFormat", &g_Config.iTimeFormat, PSP_SYSTEMPARAM_TIME_FORMAT_24HR, true, true), + ConfigSetting("ParamDateFormat", &g_Config.iDateFormat, PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD, true, true), ConfigSetting("TimeZone", &g_Config.iTimeZone, 0, true, true), ConfigSetting("DayLightSavings", &g_Config.bDayLightSavings, (bool) PSP_SYSTEMPARAM_DAYLIGHTSAVINGS_STD, true, true), ReportedConfigSetting("ButtonPreference", &g_Config.iButtonPreference, PSP_SYSTEMPARAM_BUTTON_CROSS, true, true), diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index c78c6055bf..6481b34cae 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -29,6 +29,7 @@ #include "Core/FileSystems/MetaFileSystem.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" +#include "Core/HLE/sceUtility.h" #include "Core/MemMapHelpers.h" #include "Core/Config.h" #include "Core/Reporting.h" @@ -390,67 +391,66 @@ void PSPSaveDialog::DisplaySaveIcon(bool checkExists) PPGeSetDefaultTexture(); } -void PSPSaveDialog::DisplaySaveDataInfo1() -{ +static void FormatSaveHourMin(char *hour_time, size_t sz, const tm &t) { + const char *am_pm = "AM"; + int hour = t.tm_hour; + switch (g_Config.iTimeFormat) { + case 1: + if (hour == 12) { + am_pm = "PM"; + } else if (hour > 12) { + am_pm = "PM"; + hour -= 12; + } else if (hour == 0) { + hour = 12; + } + snprintf(hour_time, sz, "%02d:%02d %s", hour, t.tm_min, am_pm); + break; + case 0: + default: + snprintf(hour_time, sz, "%02d:%02d", hour, t.tm_min); + break; + } +} + +static void FormatSaveDate(char *date, size_t sz, const tm &t) { + int year = t.tm_year + 1900; + int month = t.tm_mon + 1; + switch (g_Config.iDateFormat) { + case 1: + snprintf(date, sz, "%02d/%02d/%04d", month, t.tm_mday, year); + break; + case 2: + snprintf(date, sz, "%02d/%02d/%04d", t.tm_mday, month, year); + break; + case 0: + default: + snprintf(date, sz, "%04d/%02d/%02d", year, month, t.tm_mday); + break; + } +} + +void PSPSaveDialog::DisplaySaveDataInfo1() { std::lock_guard guard(paramLock); - if (param.GetFileInfo(currentSelectedSave).size == 0) { + const SaveFileInfo &saveInfo = param.GetFileInfo(currentSelectedSave); + + if (saveInfo.size == 0) { auto di = GetI18NCategory("Dialog"); PPGeDrawText(di->T("NEW DATA"), 180, 136, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF)); } else { - char title[512]; - char time[512]; - char saveTitle[1024]; - char saveDetail[1024]; - - char am_pm[] = "AM"; 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) { - case 1: - if (hour > 12) { - strcpy(am_pm, "PM"); - hour -= 12; - } - snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm); - break; - case 2: - snprintf(hour_time, sizeof(hour_time), "%02d:%02d", hour, min); - break; - default: - if (hour > 12) { - strcpy(am_pm, "PM"); - hour -= 12; - } - snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm); - } + FormatSaveHourMin(hour_time, sizeof(hour_time), saveInfo.modif_time); - snprintf(title, sizeof(title), "%s", param.GetFileInfo(currentSelectedSave).title); - int day = param.GetFileInfo(currentSelectedSave).modif_time.tm_mday; - int month = param.GetFileInfo(currentSelectedSave).modif_time.tm_mon + 1; - int year = param.GetFileInfo(currentSelectedSave).modif_time.tm_year + 1900; - s64 sizeK = param.GetFileInfo(currentSelectedSave).size / 1024; - switch (g_Config.iDateFormat) { - case 1: - snprintf(time, sizeof(time), "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK); - break; - case 2: - snprintf(time, sizeof(time), "%02d/%02d/%d %s %lld KB", month, day, year, hour_time, sizeK); - break; - case 3: - snprintf(time, sizeof(time), "%02d/%02d/%d %s %lld KB", day, month, year, hour_time, sizeK); - break; - default: - snprintf(time, sizeof(time), "%d/%02d/%02d %s %lld KB", year, month, day, hour_time, sizeK); - } - snprintf(saveTitle, sizeof(saveTitle), "%s", param.GetFileInfo(currentSelectedSave).saveTitle); - snprintf(saveDetail, sizeof(saveDetail), "%s", param.GetFileInfo(currentSelectedSave).saveDetail); + char date_year[32]; + FormatSaveDate(date_year, sizeof(date_year), saveInfo.modif_time); + + s64 sizeK = saveInfo.size / 1024; PPGeDrawRect(180, 136, 480, 137, CalcFadedColor(0xFFFFFFFF)); - std::string titleTxt = title; - std::string timeTxt = time; - std::string saveTitleTxt = saveTitle; - std::string saveDetailTxt = saveDetail; + std::string titleTxt = saveInfo.title; + std::string timeTxt = StringFromFormat("%s %s %lld KB", date_year, hour_time, sizeK); + std::string saveTitleTxt = saveInfo.saveTitle; + std::string saveDetailTxt = saveInfo.saveDetail; PPGeDrawText(titleTxt.c_str(), 181, 138, PPGeAlign::BOX_BOTTOM, 0.6f, CalcFadedColor(0x80000000)); PPGeDrawText(titleTxt.c_str(), 180, 136, PPGeAlign::BOX_BOTTOM, 0.6f, CalcFadedColor(0xFFC0C0C0)); @@ -483,49 +483,15 @@ void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) { data_size = param.GetFileInfo(currentSelectedSave).size; } - char date[256]; - char am_pm[] = "AM"; char hour_time[32]; - int hour = modif_time.tm_hour; - int min = modif_time.tm_min; - switch (g_Config.iTimeFormat) { - case 1: - if (hour > 12) { - strcpy(am_pm, "PM"); - hour -= 12; - } - snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm); - break; - case 2: - snprintf(hour_time, sizeof(hour_time), "%02d:%02d", hour, min); - break; - default: - if (hour > 12) { - strcpy(am_pm, "PM"); - hour -= 12; - } - snprintf(hour_time, sizeof(hour_time), "%02d:%02d %s", hour, min, am_pm); - } + FormatSaveHourMin(hour_time, sizeof(hour_time), modif_time); + + char date_year[32]; + FormatSaveDate(date_year, sizeof(date_year), modif_time); - int day = modif_time.tm_mday; - int month = modif_time.tm_mon + 1; - int year = modif_time.tm_year + 1900; s64 sizeK = data_size / 1024; - switch (g_Config.iDateFormat) { - case 1: - snprintf(date, 256, "%d/%02d/%02d", year, month, day); - break; - case 2: - snprintf(date, 256, "%02d/%02d/%d", month, day, year); - break; - case 3: - snprintf(date, 256, "%02d/%02d/%d", day, month, year); - break; - default: - snprintf(date, 256, "%d/%02d/%02d", year, month, day); - } - std::string saveinfoTxt = StringFromFormat("%.128s\n%s %s\n%lld KB", save_title, date, hour_time, sizeK); + std::string saveinfoTxt = StringFromFormat("%.128s\n%s %s\n%lld KB", save_title, date_year, hour_time, sizeK); PPGeDrawText(saveinfoTxt.c_str(), 9, 202, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000)); PPGeDrawText(saveinfoTxt.c_str(), 8, 200, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); } diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 42ba77e2f6..4838013dc4 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -722,7 +722,10 @@ static u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) param = g_Config.iDateFormat; break; case PSP_SYSTEMPARAM_ID_INT_TIME_FORMAT: - param = g_Config.iTimeFormat?PSP_SYSTEMPARAM_TIME_FORMAT_12HR:PSP_SYSTEMPARAM_TIME_FORMAT_24HR; + if (g_Config.iTimeFormat == PSP_SYSTEMPARAM_TIME_FORMAT_12HR) + param = PSP_SYSTEMPARAM_TIME_FORMAT_12HR; + else + param = PSP_SYSTEMPARAM_TIME_FORMAT_24HR; break; case PSP_SYSTEMPARAM_ID_INT_TIMEZONE: param = g_Config.iTimeZone; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 1099158a9c..6c95bf7e91 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -918,9 +918,9 @@ void GameSettingsScreen::CreateViews() { #endif systemSettings->Add(new CheckBox(&g_Config.bDayLightSavings, sy->T("Day Light Saving"))); static const char *dateFormat[] = { "YYYYMMDD", "MMDDYYYY", "DDMMYYYY"}; - systemSettings->Add(new PopupMultiChoice(&g_Config.iDateFormat, sy->T("Date Format"), dateFormat, 1, 3, sy->GetName(), screenManager())); - static const char *timeFormat[] = { "12HR", "24HR"}; - systemSettings->Add(new PopupMultiChoice(&g_Config.iTimeFormat, sy->T("Time Format"), timeFormat, 1, 2, sy->GetName(), screenManager())); + systemSettings->Add(new PopupMultiChoice(&g_Config.iDateFormat, sy->T("Date Format"), dateFormat, 0, 3, sy->GetName(), screenManager())); + static const char *timeFormat[] = { "24HR", "12HR" }; + systemSettings->Add(new PopupMultiChoice(&g_Config.iTimeFormat, sy->T("Time Format"), timeFormat, 0, 2, sy->GetName(), screenManager())); static const char *buttonPref[] = { "Use O to confirm", "Use X to confirm" }; systemSettings->Add(new PopupMultiChoice(&g_Config.iButtonPreference, sy->T("Confirmation Button"), buttonPref, 0, 2, sy->GetName(), screenManager())); } From 8f37dbe3e43ce534a0655f216b2ea0a7a2680c73 Mon Sep 17 00:00:00 2001 From: iota97 Date: Wed, 15 Jul 2020 10:21:15 +0200 Subject: [PATCH 275/848] Update README following unknows markup way --- README.md | 361 +++++++++++++++++++++++++++++++++++-------------- history.md | 140 +++++++++++++------ link_readme.py | 36 ++++- 3 files changed, 394 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index c8bfcac53f..2222637105 100644 --- a/README.md +++ b/README.md @@ -27,55 +27,55 @@ For game compatibility, see [community compatibility feedback](https://report.pp What's new in 1.10.3 -------------------- -* Fix for control layout editor ([#13125](https://github.com/hrydgard/ppsspp/issues/13125)) +* Fix for control layout editor ([#13125][]) What's new in 1.10.2 -------------------- -* More crashfixes ([#13094](https://github.com/hrydgard/ppsspp/issues/13094), [#13093](https://github.com/hrydgard/ppsspp/issues/13093)) -* Improve download performance and cancel behavior ([#13095](https://github.com/hrydgard/ppsspp/issues/13095)) -* Restore the removed I/O on Thread option ([#13096](https://github.com/hrydgard/ppsspp/issues/13096)) +* More crashfixes ([#13094][], [#13093][]) +* Improve download performance and cancel behavior ([#13095][]) +* Restore the removed I/O on Thread option ([#13096][]) What's new in 1.10.1 -------------------- -* Fixes for common crashes ([#13077](https://github.com/hrydgard/ppsspp/issues/13077), [#13076](https://github.com/hrydgard/ppsspp/issues/13076), see [#13057](https://github.com/hrydgard/ppsspp/issues/13057)) -* Fix for offset rendering in D3D9 ([#13071](https://github.com/hrydgard/ppsspp/issues/13071)) +* Fixes for common crashes ([#13077][], [#13076][], see [#13057][]) +* Fix for offset rendering in D3D9 ([#13071][]) What's new in 1.10.0 -------------------- -* Graphics and compatibility fixes ([#12800](https://github.com/hrydgard/ppsspp/issues/12800), [#12670](https://github.com/hrydgard/ppsspp/issues/12670), [#12635](https://github.com/hrydgard/ppsspp/issues/12635), [#12857](https://github.com/hrydgard/ppsspp/issues/12857), [#12941](https://github.com/hrydgard/ppsspp/issues/12941), [#11898](https://github.com/hrydgard/ppsspp/issues/11898), [#12695](https://github.com/hrydgard/ppsspp/issues/12695), more) -* Assorted minor performance improvements, game load speedup ([#12462](https://github.com/hrydgard/ppsspp/issues/12462), [#12652](https://github.com/hrydgard/ppsspp/issues/12652)) -* Screen inset (notch) support on Android ([#12779](https://github.com/hrydgard/ppsspp/issues/12779)) -* Analog stick support for menu navigation ([#12685](https://github.com/hrydgard/ppsspp/issues/12685)) -* Fixed audio glitches in SDL builds ([#12916](https://github.com/hrydgard/ppsspp/issues/12916), [#12920](https://github.com/hrydgard/ppsspp/issues/12920)) -* Support more languages in in-game dialogs ([#12702](https://github.com/hrydgard/ppsspp/issues/12702)). Croatian language added to PPSSPP. -* Simple multiplayer chat ([#12667](https://github.com/hrydgard/ppsspp/issues/12667)) -* More advanced postprocessing (multipass, parameters) ([#12905](https://github.com/hrydgard/ppsspp/issues/12905), [#12901](https://github.com/hrydgard/ppsspp/issues/12901)) -* Add PPSSPP-specific CWCheat ([#12816](https://github.com/hrydgard/ppsspp/issues/12816), [#12912](https://github.com/hrydgard/ppsspp/issues/12912)) -* Reintroduce Cardboard VR, allow more resolutions ([#12449](https://github.com/hrydgard/ppsspp/issues/12449), [#8714](https://github.com/hrydgard/ppsspp/issues/8714)) -* Fix some crashes ([#12908](https://github.com/hrydgard/ppsspp/issues/12908), [#12876](https://github.com/hrydgard/ppsspp/issues/12876)) -* Ghost in the Shell graphics fixed (JIT inaccuracy with inf*0) ([#12519](https://github.com/hrydgard/ppsspp/issues/12519)) -* Mac build now supports Vulkan on top of MoltenVK ([#12583](https://github.com/hrydgard/ppsspp/issues/12583)) -* Raspberry Pi 4 EGL crash fixed ([#12474](https://github.com/hrydgard/ppsspp/issues/12474)) -* VSync now supported on all backends, frame duplication option added for 30 Hz games ([#12659](https://github.com/hrydgard/ppsspp/issues/12659), [#12602](https://github.com/hrydgard/ppsspp/issues/12602)) -* Camera supported on Windows, Linux and Mac (still no microphone though) ([#12572](https://github.com/hrydgard/ppsspp/issues/12572), [#12580](https://github.com/hrydgard/ppsspp/issues/12580), [#12607](https://github.com/hrydgard/ppsspp/issues/12607)) -* Darkstalkers fixed and working through software rendering. SW rendering fixed on GLES 2.0 ([#12443](https://github.com/hrydgard/ppsspp/issues/12443), [#12898](https://github.com/hrydgard/ppsspp/issues/12898)) -* Hot Shots Golf slowdown and flicker on Vulkan fixed ([#12873](https://github.com/hrydgard/ppsspp/issues/12873), [#12746](https://github.com/hrydgard/ppsspp/issues/12746)) -* Pangya Golf crashes and hangs fixed ([#12718](https://github.com/hrydgard/ppsspp/issues/12718)) -* Allow rebinding of right touch screen analog ([#12486](https://github.com/hrydgard/ppsspp/issues/12486)) -* Add option to prevent mipmaps from being dumped ([#12818](https://github.com/hrydgard/ppsspp/issues/12818)) -* Tilt control now have a base radius to help with deadzone ([#12756](https://github.com/hrydgard/ppsspp/issues/12756)) -* Mappable auto rotating analog stick to pass some game checks ([#12749](https://github.com/hrydgard/ppsspp/issues/12749)) -* Touch control position can now be snapped to a grid ([#12517](https://github.com/hrydgard/ppsspp/issues/12517)) -* HiDPI retina display support ([#12552](https://github.com/hrydgard/ppsspp/issues/12552)) -* Rapid-fire on touch control ([#12601](https://github.com/hrydgard/ppsspp/issues/12601)) -* Toggle mute button ([#12643](https://github.com/hrydgard/ppsspp/issues/12643)) -* Add option to resize game icons and more ([#12646](https://github.com/hrydgard/ppsspp/issues/12646), [#12637](https://github.com/hrydgard/ppsspp/issues/12637)) -* Frames in-flight now configurable to reduce input lag at the cost of speed ([#12660](https://github.com/hrydgard/ppsspp/issues/12660)) -* Add toggle mode to combo button ([#12623](https://github.com/hrydgard/ppsspp/issues/12623)) -* SDL mouse support, Qt menu upgrades ([#12612](https://github.com/hrydgard/ppsspp/issues/12612), [#12817](https://github.com/hrydgard/ppsspp/issues/12817)) -* Real support for chinese patched version of Hatsune Miku Project Diva Extend ([#13007](https://github.com/hrydgard/ppsspp/issues/13007)) -* Some minor kernel module support ([#13028](https://github.com/hrydgard/ppsspp/issues/13028), [#12225](https://github.com/hrydgard/ppsspp/issues/12225), [#13026](https://github.com/hrydgard/ppsspp/issues/13026), [#13004](https://github.com/hrydgard/ppsspp/issues/13004), [#13038](https://github.com/hrydgard/ppsspp/issues/13038), [#13023](https://github.com/hrydgard/ppsspp/issues/13023)) -* Fixed fullscreen toggling with Vulkan in SDL builds ([#11974](https://github.com/hrydgard/ppsspp/issues/11974)) +* Graphics and compatibility fixes ([#12800][], [#12670][], [#12635][], [#12857][], [#12941][], [#11898][], [#12695][], more) +* Assorted minor performance improvements, game load speedup ([#12462][], [#12652][]) +* Screen inset (notch) support on Android ([#12779][]) +* Analog stick support for menu navigation ([#12685][]) +* Fixed audio glitches in SDL builds ([#12916][], [#12920][]) +* Support more languages in in-game dialogs ([#12702][]). Croatian language added to PPSSPP. +* Simple multiplayer chat ([#12667][]) +* More advanced postprocessing (multipass, parameters) ([#12905][], [#12901][]) +* Add PPSSPP-specific CWCheat ([#12816][], [#12912][]) +* Reintroduce Cardboard VR, allow more resolutions ([#12449][], [#8714][]) +* Fix some crashes ([#12908][], [#12876][]) +* Ghost in the Shell graphics fixed (JIT inaccuracy with inf*0) ([#12519][]) +* Mac build now supports Vulkan on top of MoltenVK ([#12583][]) +* Raspberry Pi 4 EGL crash fixed ([#12474][]) +* VSync now supported on all backends, frame duplication option added for 30 Hz games ([#12659][], [#12602][]) +* Camera supported on Windows, Linux and Mac (still no microphone though) ([#12572][], [#12580][], [#12607][]) +* Darkstalkers fixed and working through software rendering. SW rendering fixed on GLES 2.0 ([#12443][], [#12898][]) +* Hot Shots Golf slowdown and flicker on Vulkan fixed ([#12873][], [#12746][]) +* Pangya Golf crashes and hangs fixed ([#12718][]) +* Allow rebinding of right touch screen analog ([#12486][]) +* Add option to prevent mipmaps from being dumped ([#12818][]) +* Tilt control now have a base radius to help with deadzone ([#12756][]) +* Mappable auto rotating analog stick to pass some game checks ([#12749][]) +* Touch control position can now be snapped to a grid ([#12517][]) +* HiDPI retina display support ([#12552][]) +* Rapid-fire on touch control ([#12601][]) +* Toggle mute button ([#12643][]) +* Add option to resize game icons and more ([#12646][], [#12637][]) +* Frames in-flight now configurable to reduce input lag at the cost of speed ([#12660][]) +* Add toggle mode to combo button ([#12623][]) +* SDL mouse support, Qt menu upgrades ([#12612][], [#12817][]) +* Real support for chinese patched version of Hatsune Miku Project Diva Extend ([#13007][]) +* Some minor kernel module support ([#13028][], [#12225][], [#13026][], [#13004][], [#13038][], [#13023][]) +* Fixed fullscreen toggling with Vulkan in SDL builds ([#11974][]) What's new in 1.9.0/1.9.3 ------------------------- @@ -84,62 +84,62 @@ What's new in 1.9.0/1.9.3 What's new in 1.9.0/1.9.2 ------------------------- -* Flicker fixed in God of War that appeared with newer drivers for Mali GPUs ([#12224](https://github.com/hrydgard/ppsspp/issues/12224)) -* Improve performance of God of War on Vulkan ([#12242](https://github.com/hrydgard/ppsspp/issues/12242)), implement built-in GPU profiler ([#12262](https://github.com/hrydgard/ppsspp/issues/12262), [#12266](https://github.com/hrydgard/ppsspp/issues/12266)) -* Vertex range culling fixed on ARM Mali ([#12227](https://github.com/hrydgard/ppsspp/issues/12227)) -* Started to improve VFPU precision, resulting so far in a fix for the long standing Tekken 6 leg shaking problem ([#12217](https://github.com/hrydgard/ppsspp/issues/12217)) -* Fixed a VFPU precision snafu on ARM64, fixing disappearing officers in Warriors Orochi ([#11299](https://github.com/hrydgard/ppsspp/issues/11299)) and some problems in Tomb Raider ([#11179](https://github.com/hrydgard/ppsspp/issues/11179)). +* Flicker fixed in God of War that appeared with newer drivers for Mali GPUs ([#12224][]) +* Improve performance of God of War on Vulkan ([#12242][]), implement built-in GPU profiler ([#12262][], [#12266][]) +* Vertex range culling fixed on ARM Mali ([#12227][]) +* Started to improve VFPU precision, resulting so far in a fix for the long standing Tekken 6 leg shaking problem ([#12217][]) +* Fixed a VFPU precision snafu on ARM64, fixing disappearing officers in Warriors Orochi ([#11299][]) and some problems in Tomb Raider ([#11179][]). * Vulkan is the default again on Android versions newer than Pie * Fix various homebrew store issues -* GPU pause signal handling fixed, fixing some hangs in Bleach and Armored Core games ([#12160](https://github.com/hrydgard/ppsspp/issues/12160)) -* Audio sample rate conversion handling fixes ([#12147](https://github.com/hrydgard/ppsspp/issues/12147)) -* Some Vulkan optimizations (pre-rotation ([#12216](https://github.com/hrydgard/ppsspp/issues/12216)), perf fix in Metal Gear Acid, etc) -* Multiple fixes for the UWP build ([#12036](https://github.com/hrydgard/ppsspp/issues/12036), others) -* MP3 playback fixes ([#12005](https://github.com/hrydgard/ppsspp/issues/12005)) -* Audio in Motorstorm: Arctic Edge fixed by returning errors correctly ([#12121](https://github.com/hrydgard/ppsspp/issues/12121)) -* Audio glitches in Final Fantasy Tactics fixed ([#9956](https://github.com/hrydgard/ppsspp/issues/9956)) -* Camera display in Invizimals fixed ([#12278](https://github.com/hrydgard/ppsspp/issues/12278), [#8521](https://github.com/hrydgard/ppsspp/issues/8521)) -* Added hotkeys for texture dump and replace ([#11938](https://github.com/hrydgard/ppsspp/issues/11938)) -* Added Visual Studio 2019 support. Windows XP is no longer supported ([#11995](https://github.com/hrydgard/ppsspp/issues/11995), others) -* Fixes for video capture ([#12069](https://github.com/hrydgard/ppsspp/issues/12069)) -* Added a separate sound volume for alternative speed ([#12124](https://github.com/hrydgard/ppsspp/issues/12124)) -* Improved mouse control (Windows only) ([#12173](https://github.com/hrydgard/ppsspp/issues/12173), [#12176](https://github.com/hrydgard/ppsspp/issues/12176)) -* Support for installing texture packs and ISOs from zips ([#12175](https://github.com/hrydgard/ppsspp/issues/12175)) -* Right analog support for touch controls (only used by patched games and some HD remasters) ([#12182](https://github.com/hrydgard/ppsspp/issues/12182)) -* Android: Fix OpenSL initialization, possibly helps audio crackle a little. ([#12333](https://github.com/hrydgard/ppsspp/issues/12333)). +* GPU pause signal handling fixed, fixing some hangs in Bleach and Armored Core games ([#12160][]) +* Audio sample rate conversion handling fixes ([#12147][]) +* Some Vulkan optimizations (pre-rotation ([#12216][]), perf fix in Metal Gear Acid, etc) +* Multiple fixes for the UWP build ([#12036][], others) +* MP3 playback fixes ([#12005][]) +* Audio in Motorstorm: Arctic Edge fixed by returning errors correctly ([#12121][]) +* Audio glitches in Final Fantasy Tactics fixed ([#9956][]) +* Camera display in Invizimals fixed ([#12278][], [#8521][]) +* Added hotkeys for texture dump and replace ([#11938][]) +* Added Visual Studio 2019 support. Windows XP is no longer supported ([#11995][], others) +* Fixes for video capture ([#12069][]) +* Added a separate sound volume for alternative speed ([#12124][]) +* Improved mouse control (Windows only) ([#12173][], [#12176][]) +* Support for installing texture packs and ISOs from zips ([#12175][]) +* Right analog support for touch controls (only used by patched games and some HD remasters) ([#12182][]) +* Android: Fix OpenSL initialization, possibly helps audio crackle a little. ([#12333][]). * Fix graphics on Amazon Fire TV Stick 4K -* Fixed strange vehicle behavior in MGS:PW (somehow) ([#12342](https://github.com/hrydgard/ppsspp/issues/12342)) +* Fixed strange vehicle behavior in MGS:PW (somehow) ([#12342][]) What's new in 1.8.0 ------------------- -* Avoid crash when starting PPSSPP due to bad AMD Vulkan drivers ([#11802](https://github.com/hrydgard/ppsspp/issues/11802)) -* PowerVR Vulkan display corruption fixed ([#11744](https://github.com/hrydgard/ppsspp/issues/11744), [#11747](https://github.com/hrydgard/ppsspp/issues/11747)) -* Naruto Shippuden 3 hang fixed ([#11780](https://github.com/hrydgard/ppsspp/issues/11780)) -* Fixes to various lighting bugs ([#11567](https://github.com/hrydgard/ppsspp/issues/11567), [#11574](https://github.com/hrydgard/ppsspp/issues/11574), [#11577](https://github.com/hrydgard/ppsspp/issues/11577)) -* Fix control issue in Sonic Rivals and Rock Band ([#11878](https://github.com/hrydgard/ppsspp/issues/11878), [#11798](https://github.com/hrydgard/ppsspp/issues/11798), [#11879](https://github.com/hrydgard/ppsspp/issues/11879)) -* Significant performance improvement in Earth Defense Force 2 ([#11172](https://github.com/hrydgard/ppsspp/issues/11172)) -* Fix "real clock sync" setting (helps with latency for music games - [#11813](https://github.com/hrydgard/ppsspp/issues/11813)) -* More speed in FF4 effects and other generated curves ([#11425](https://github.com/hrydgard/ppsspp/issues/11425)) -* Support for resizing Vulkan on Linux ([#11451](https://github.com/hrydgard/ppsspp/issues/11451)) -* Improved support for GLES on Linux/IoT ([#11507](https://github.com/hrydgard/ppsspp/issues/11507), [#11537](https://github.com/hrydgard/ppsspp/issues/11537), [#11541](https://github.com/hrydgard/ppsspp/issues/11541), [#11632](https://github.com/hrydgard/ppsspp/issues/11632), [#11746](https://github.com/hrydgard/ppsspp/issues/11746), [#11806](https://github.com/hrydgard/ppsspp/issues/11806), [#11845](https://github.com/hrydgard/ppsspp/issues/11845)) -* Percentage based frameskipping ([#11523](https://github.com/hrydgard/ppsspp/issues/11523)) -* DXT accuracy improved, fixing thick white line in Gran Turismo sky ([#11530](https://github.com/hrydgard/ppsspp/issues/11530)) -* Fix Motorstorm freeze on non-Windows ([#11618](https://github.com/hrydgard/ppsspp/issues/11618)) -* Faster block transfer in some games like Digimon Adventures ([#11531](https://github.com/hrydgard/ppsspp/issues/11531), [#11553](https://github.com/hrydgard/ppsspp/issues/11553), [#11776](https://github.com/hrydgard/ppsspp/issues/11776)) -* Blending optimizations and improvements ([#11543](https://github.com/hrydgard/ppsspp/issues/11543), [#11620](https://github.com/hrydgard/ppsspp/issues/11620)) -* Improve D3D11 rendering issues ([#11584](https://github.com/hrydgard/ppsspp/issues/11584)) -* Change default graphics backend to D3D11 or OpenGL ([#11621](https://github.com/hrydgard/ppsspp/issues/11621), [#11658](https://github.com/hrydgard/ppsspp/issues/11658)) -* Remove some outdated settings ([#11665](https://github.com/hrydgard/ppsspp/issues/11665), [#11666](https://github.com/hrydgard/ppsspp/issues/11666), [#11667](https://github.com/hrydgard/ppsspp/issues/11667)) -* Fix remote disc streaming with ipv6 ([#11689](https://github.com/hrydgard/ppsspp/issues/11689), [#11700](https://github.com/hrydgard/ppsspp/issues/11700)) -* Vulkan: Workarounds for some driver bugs for 5xx series Qualcomm GPUs ([#11691](https://github.com/hrydgard/ppsspp/issues/11691), [#11694](https://github.com/hrydgard/ppsspp/issues/11694)) -* Fix some Qt port issues with recent performance improvements ([#11720](https://github.com/hrydgard/ppsspp/issues/11720), [#11807](https://github.com/hrydgard/ppsspp/issues/11807), [#11808](https://github.com/hrydgard/ppsspp/issues/11808)) -* UWP Xbox One: fix X/Back button confusion ([#11740](https://github.com/hrydgard/ppsspp/issues/11740)) -* Fix Formula 1 2006 timing issue ([#11767](https://github.com/hrydgard/ppsspp/issues/11767)) -* Fixes and workarounds for some vertex range culling bugs that broke a few games ([#11785](https://github.com/hrydgard/ppsspp/issues/11785), [#11859](https://github.com/hrydgard/ppsspp/issues/11859)), and disable it on older GPUs ([#11712](https://github.com/hrydgard/ppsspp/issues/11712), [#11773](https://github.com/hrydgard/ppsspp/issues/11773), [#11787](https://github.com/hrydgard/ppsspp/issues/11787)) -* Android: Allow putting PSP storage on custom paths like SD cards ([#11812](https://github.com/hrydgard/ppsspp/issues/11812)) -* Corrected vocp instruction, fixing models in Artdink games ([#11822](https://github.com/hrydgard/ppsspp/issues/11822), [#11835](https://github.com/hrydgard/ppsspp/issues/11835)) -* Bundle SDL in binary for macOS builds ([#11831](https://github.com/hrydgard/ppsspp/issues/11831)) -* Prevent keeping games open on Windows ([#11842](https://github.com/hrydgard/ppsspp/issues/11842)) +* 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][]) +* 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][]) +* 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 ------------------- @@ -154,20 +154,20 @@ What's new in 1.7.2 What's new in 1.7.1 ------------------- * Minor crashfixes, lang updates -* Save bug fixed ([#11508](https://github.com/hrydgard/ppsspp/issues/11508)) +* Save bug fixed ([#11508][]) What's new in 1.7.0 ------------------- -* Fix for insta-crash on Galaxy Note 9, some Xiaomi devices, and the new nVidia Shield ([#11441](https://github.com/hrydgard/ppsspp/issues/11441)) -* Vertex range culling on most platforms, fixes DTM: Race Driver and similar ([#11393](https://github.com/hrydgard/ppsspp/issues/11393)) -* Major speed boost in some Gundam and Earth Defense Force games ([#10973](https://github.com/hrydgard/ppsspp/issues/10973)) -* Fix for issues with post processing shaders in GL 3+ ([#11182](https://github.com/hrydgard/ppsspp/issues/11182)) -* Fixes to sound output switching on Windows (WASAPI) ([#11438](https://github.com/hrydgard/ppsspp/issues/11438)) -* Detects DirectInput devices when running ([#11461](https://github.com/hrydgard/ppsspp/issues/11461)) -* Simple Discord integration ([#11307](https://github.com/hrydgard/ppsspp/issues/11307)) -* New debugging APIs ([#10909](https://github.com/hrydgard/ppsspp/issues/10909)) -* Task switching made a lot more robust (fixes GPD XD problems) ([#11447](https://github.com/hrydgard/ppsspp/issues/11447)) -* Texture decoding optimizations ([#11350](https://github.com/hrydgard/ppsspp/issues/11350)) +* Fix for insta-crash on Galaxy Note 9, some Xiaomi devices, and the new nVidia Shield ([#11441][]) +* Vertex range culling on most platforms, fixes DTM: Race Driver and similar ([#11393][]) +* Major speed boost in some Gundam and Earth Defense Force games ([#10973][]) +* Fix for issues with post processing shaders in GL 3+ ([#11182][]) +* Fixes to sound output switching on Windows (WASAPI) ([#11438][]) +* Detects DirectInput devices when running ([#11461][]) +* Simple Discord integration ([#11307][]) +* New debugging APIs ([#10909][]) +* Task switching made a lot more robust (fixes GPD XD problems) ([#11447][]) +* Texture decoding optimizations ([#11350][]) * Tons and tons of miscellaneous bugfixes and compatibility fixes Looking for [older news](history.md)? @@ -182,3 +182,162 @@ Credit goes to: - [coldbird's code](https://code.google.com/archive/p/aemu/) - Kyhel +[#13125]: https://github.com/hrydgard/ppsspp/issues/13125 "Refactor and fix touch control layout screen for notch" +[#13094]: https://github.com/hrydgard/ppsspp/issues/13094 "Camera initialization crash fix" +[#13093]: https://github.com/hrydgard/ppsspp/issues/13093 "Add a try/catch to Android camera device listing." +[#13095]: https://github.com/hrydgard/ppsspp/issues/13095 "http: Check cancel flag more often" +[#13096]: https://github.com/hrydgard/ppsspp/issues/13096 "Revert \"Remove the I/O on Thread option - treat it as always on.\"" +[#13077]: https://github.com/hrydgard/ppsspp/issues/13077 "SaveState: Make sure to default init net data" +[#13076]: https://github.com/hrydgard/ppsspp/issues/13076 "Add some excessive null checks to GameScreen::render()" +[#13057]: https://github.com/hrydgard/ppsspp/issues/13057 "The 1.10 Android mystery crash thread!" +[#13071]: https://github.com/hrydgard/ppsspp/issues/13071 "D3D9: Fix a sign mistake generating the projection matrix." +[#12800]: https://github.com/hrydgard/ppsspp/issues/12800 "x86jit: Force INF * 0 to +NAN" +[#12670]: https://github.com/hrydgard/ppsspp/issues/12670 "Attempts to replace 0 frame width with valid frame width.(sceMpegAvcCsc)" +[#12635]: https://github.com/hrydgard/ppsspp/issues/12635 "Kernel: Delay better in sceKernelReferThreadStatus" +[#12857]: https://github.com/hrydgard/ppsspp/issues/12857 "Mumbo Jumbo games freeze on loading screen since v1.6" +[#12941]: https://github.com/hrydgard/ppsspp/issues/12941 "Vulkan: Deal with the reformat clear better" +[#11898]: https://github.com/hrydgard/ppsspp/issues/11898 "Strike Witches - Hakugin no Tsubasa missing intro video" +[#12695]: https://github.com/hrydgard/ppsspp/issues/12695 "New heuristic for getting rid of unnecessary \"antialias-lines\"." +[#12462]: https://github.com/hrydgard/ppsspp/issues/12462 "Vulkan: Enable renderpass merging for all games" +[#12652]: https://github.com/hrydgard/ppsspp/issues/12652 "ScanForFunctions: Speed up game loading" +[#12779]: https://github.com/hrydgard/ppsspp/issues/12779 "Support drawing around notches on Android displays. Fixes #12261" +[#12685]: https://github.com/hrydgard/ppsspp/issues/12685 "UI: Simple joystick navigation. Fixes #10996." +[#12916]: https://github.com/hrydgard/ppsspp/issues/12916 "More audio buffering fixes (primarily affects SDL)" +[#12920]: https://github.com/hrydgard/ppsspp/issues/12920 "Remove the Audio Resampling setting (now always on)." +[#12702]: https://github.com/hrydgard/ppsspp/issues/12702 "PPGe: Use TextDrawer for save UI if available" +[#12667]: https://github.com/hrydgard/ppsspp/issues/12667 "Chat feature based on Adenovan's Rechat branch" +[#12905]: https://github.com/hrydgard/ppsspp/issues/12905 "Allow chained post-processing shaders" +[#12901]: https://github.com/hrydgard/ppsspp/issues/12901 "Post shader setting uniform" +[#12816]: https://github.com/hrydgard/ppsspp/issues/12816 "Implement Xinput vibration CWCheat (PPSSPP specific 0xA code type)" +[#12912]: https://github.com/hrydgard/ppsspp/issues/12912 "Add CWCHEAT for postprocessing" +[#12449]: https://github.com/hrydgard/ppsspp/issues/12449 "Reintroduce Cardboard VR" +[#8714]: https://github.com/hrydgard/ppsspp/issues/8714 "Allow > 5x PSP resolution for devices like iPad Pro 12.9" +[#12908]: https://github.com/hrydgard/ppsspp/issues/12908 "Fix \"Improved compatibility of sceGeListEnQueue: verify that stackDepth < 256\"" +[#12876]: https://github.com/hrydgard/ppsspp/issues/12876 "Windows: Add safety checks to WASAPI code" +[#12519]: https://github.com/hrydgard/ppsspp/issues/12519 "Ghost In The Shell - Stand Alone Complex (ULUS10020) - Black Textures and missing screens." +[#12583]: https://github.com/hrydgard/ppsspp/issues/12583 "macOS: Initial support for vulkan on macOS ( MoltenVK )" +[#12474]: https://github.com/hrydgard/ppsspp/issues/12474 "Egl bug on rpi4 with master mesa?" +[#12659]: https://github.com/hrydgard/ppsspp/issues/12659 "Support vsync in all hardware backends, support runtime update" +[#12602]: https://github.com/hrydgard/ppsspp/issues/12602 "Add option to improve frame pacing through duplicate frames if below 60hz." +[#12572]: https://github.com/hrydgard/ppsspp/issues/12572 "Add camera support for windows." +[#12580]: https://github.com/hrydgard/ppsspp/issues/12580 "Add camera support for linux (V4L2)" +[#12607]: https://github.com/hrydgard/ppsspp/issues/12607 "QT API for camera (Linux/macOS)" +[#12443]: https://github.com/hrydgard/ppsspp/issues/12443 "Darkstalkers Chronicle: Add specializations and speedhacks to get it kinda playable" +[#12898]: https://github.com/hrydgard/ppsspp/issues/12898 "[Android] [Mali GPU] [OpenGL] Lastest build blackscreen on buffered rendering mode" +[#12873]: https://github.com/hrydgard/ppsspp/issues/12873 "Vulkan: Framebuffer manager: Use an allocator for \"MakePixelTexture\" images." +[#12746]: https://github.com/hrydgard/ppsspp/issues/12746 "GPU: Assume a scissor of 481x273 is a mistake" +[#12718]: https://github.com/hrydgard/ppsspp/issues/12718 "Vpl: Correct allocation order when splitting block" +[#12486]: https://github.com/hrydgard/ppsspp/issues/12486 "Rebindable touch right analog" +[#12818]: https://github.com/hrydgard/ppsspp/issues/12818 "Add option to prevent Mipmaps from being dumped" +[#12756]: https://github.com/hrydgard/ppsspp/issues/12756 "Skip deadzone option on tilt" +[#12749]: https://github.com/hrydgard/ppsspp/issues/12749 "Auto rotating analog" +[#12517]: https://github.com/hrydgard/ppsspp/issues/12517 "Touch control grid snap" +[#12552]: https://github.com/hrydgard/ppsspp/issues/12552 "Qt/macOS: enable HiDPI ( retina display ) support" +[#12601]: https://github.com/hrydgard/ppsspp/issues/12601 "Add rapid fire to touch control" +[#12643]: https://github.com/hrydgard/ppsspp/issues/12643 "Toggle mute button" +[#12646]: https://github.com/hrydgard/ppsspp/issues/12646 "Resizable game icons" +[#12637]: https://github.com/hrydgard/ppsspp/issues/12637 "Region flag and game ID on game selection screen" +[#12660]: https://github.com/hrydgard/ppsspp/issues/12660 "GPU: Add setting to control inflight frame usage" +[#12623]: https://github.com/hrydgard/ppsspp/issues/12623 "Add toggle flag to combo button" +[#12612]: https://github.com/hrydgard/ppsspp/issues/12612 "SDL analog mouse input" +[#12817]: https://github.com/hrydgard/ppsspp/issues/12817 "Unification of the menu of Linux and Windows versions" +[#13007]: https://github.com/hrydgard/ppsspp/issues/13007 "Real support \"Hatsune Miku Project Diva Extend\" chinese patched version" +[#13028]: https://github.com/hrydgard/ppsspp/issues/13028 "Real support Code Geass: Lost Colors chinese patched version" +[#12225]: https://github.com/hrydgard/ppsspp/issues/12225 "Rebased: Wrap some SysMemForKernel's nids, fixing #7960" +[#13026]: https://github.com/hrydgard/ppsspp/issues/13026 "Add some ThreadManForKernel nids" +[#13004]: https://github.com/hrydgard/ppsspp/issues/13004 "Warp some ThreadManForKernel and sceKernelExitVSHKernel" +[#13038]: https://github.com/hrydgard/ppsspp/issues/13038 "Add sysclib_strncmp,sysclib_memmove" +[#13023]: https://github.com/hrydgard/ppsspp/issues/13023 "Add sysclib_strstr" +[#11974]: https://github.com/hrydgard/ppsspp/issues/11974 "[Linux] [Vulkan] Toggle fullscreen doesn't update display properly" +[#12224]: https://github.com/hrydgard/ppsspp/issues/12224 "Vulkan: Add missing barrier between multiple passes to the same target." +[#12242]: https://github.com/hrydgard/ppsspp/issues/12242 "Vulkan: Automatically merge render passes to the same target when possible" +[#12262]: https://github.com/hrydgard/ppsspp/issues/12262 "Vulkan: Implement basic integrated GPU profiling." +[#12266]: https://github.com/hrydgard/ppsspp/issues/12266 "Vulkan: Further improvements to GPU profiling" +[#12227]: https://github.com/hrydgard/ppsspp/issues/12227 "Vulkan/GL: Set all four coordinates to NaN instead of just W." +[#12217]: https://github.com/hrydgard/ppsspp/issues/12217 "Merge vfpu-dot changes and add compat flag for Tekken" +[#11299]: https://github.com/hrydgard/ppsspp/issues/11299 "Warrior Orochi Enemy Missing" +[#11179]: https://github.com/hrydgard/ppsspp/issues/11179 "Tomb Raider Anniversary jump to horizontal bar issue" +[#12160]: https://github.com/hrydgard/ppsspp/issues/12160 "GPU: Forget pause signal on new list" +[#12147]: https://github.com/hrydgard/ppsspp/issues/12147 "Handle audio SRC mixing more correctly" +[#12216]: https://github.com/hrydgard/ppsspp/issues/12216 "Cant get Invizimals to work on PPSSPP (Video source not rendered)" +[#12036]: https://github.com/hrydgard/ppsspp/issues/12036 "Several UWP fixes" +[#12005]: https://github.com/hrydgard/ppsspp/issues/12005 "Correct mp3 looping, frame num, and sum decoded" +[#12121]: https://github.com/hrydgard/ppsspp/issues/12121 "Return errors on Audio2 release when channel busy" +[#9956]: https://github.com/hrydgard/ppsspp/issues/9956 "Audio crackle/distortion in Final Fantasy Tactics" +[#12278]: https://github.com/hrydgard/ppsspp/issues/12278 "UsbCam/jpeg: Cleanups, notify framebuffer manager" +[#8521]: https://github.com/hrydgard/ppsspp/issues/8521 "PSP Camera Support (Android)" +[#11938]: https://github.com/hrydgard/ppsspp/issues/11938 "Add texture dump/replace hotkeys." +[#11995]: https://github.com/hrydgard/ppsspp/issues/11995 "Fix VS2019 builds and remove _xp dependency" +[#12069]: https://github.com/hrydgard/ppsspp/issues/12069 "Fix avi dump feature" +[#12124]: https://github.com/hrydgard/ppsspp/issues/12124 "Audio: Add volume for alternate speed" +[#12173]: https://github.com/hrydgard/ppsspp/issues/12173 "Ignore mapped mouse input for UI" +[#12176]: https://github.com/hrydgard/ppsspp/issues/12176 "Mouse improvements" +[#12175]: https://github.com/hrydgard/ppsspp/issues/12175 "UI: Allow installing texture packs from zips" +[#12182]: https://github.com/hrydgard/ppsspp/issues/12182 "Add right analog for touch controls." +[#12333]: https://github.com/hrydgard/ppsspp/issues/12333 "Android OpenSL initial queue fix" +[#12342]: https://github.com/hrydgard/ppsspp/issues/12342 "Serious MGS Peace Walker bug fixed post-1.8.0" +[#11802]: https://github.com/hrydgard/ppsspp/issues/11802 "Windows: Detect Vulkan in separate process" +[#11744]: https://github.com/hrydgard/ppsspp/issues/11744 "VulkanDeviceAlloc: Memorytype per slab" +[#11747]: https://github.com/hrydgard/ppsspp/issues/11747 "Vk validation fixes, plus PowerVR swapchain hack" +[#11780]: https://github.com/hrydgard/ppsspp/issues/11780 "Naruto Shippuden Ultimate Ninja 3: Probably a better fix for the video hang issue." +[#11567]: https://github.com/hrydgard/ppsspp/issues/11567 "Correct shade mapping when light pos is all zeros" +[#11574]: https://github.com/hrydgard/ppsspp/issues/11574 "Correct various light param issues based on tests" +[#11577]: https://github.com/hrydgard/ppsspp/issues/11577 "Correct provoking vertex for lighting when flat shading" +[#11878]: https://github.com/hrydgard/ppsspp/issues/11878 "Sonic Rivals controls semi-broken" +[#11798]: https://github.com/hrydgard/ppsspp/issues/11798 "User report: Long notes in Rock Band Unplugged are not registered correctly" +[#11879]: https://github.com/hrydgard/ppsspp/issues/11879 "Fix apparent bug in #11094, fixes #11878 and likely #11798" +[#11172]: https://github.com/hrydgard/ppsspp/issues/11172 "handle cullface, help to #10597" +[#11813]: https://github.com/hrydgard/ppsspp/issues/11813 "Core: Fix lag sync on game start / after pause" +[#11425]: https://github.com/hrydgard/ppsspp/issues/11425 "[Refactoring] Improve spline/bezier." +[#11451]: https://github.com/hrydgard/ppsspp/issues/11451 "SDL/Vulkan window resize improvements" +[#11507]: https://github.com/hrydgard/ppsspp/issues/11507 "Improve support of Qt + USING_GLES2" +[#11537]: https://github.com/hrydgard/ppsspp/issues/11537 "CMake: Allow disabling Wayland support with USE_WAYLAND_WSI" +[#11541]: https://github.com/hrydgard/ppsspp/issues/11541 "CMake: Fix linking X11 when using EGL and not fbdev" +[#11632]: https://github.com/hrydgard/ppsspp/issues/11632 "SDL: Allow toggling fullscreen for GLES2 on desktops." +[#11746]: https://github.com/hrydgard/ppsspp/issues/11746 "CMakeLists: fix EGL detection for ARM devices" +[#11806]: https://github.com/hrydgard/ppsspp/issues/11806 "SDL: Force fullscreen desktop for USING_FBDEV" +[#11845]: https://github.com/hrydgard/ppsspp/issues/11845 "EGL: Avoid HDR mode. Uses unknownbrackets' changes from #11839." +[#11523]: https://github.com/hrydgard/ppsspp/issues/11523 "Add frameskip setting" +[#11530]: https://github.com/hrydgard/ppsspp/issues/11530 "Make DXT alpha and color calculation more accurate" +[#11618]: https://github.com/hrydgard/ppsspp/issues/11618 "Io: Ensure sign extension for error codes" +[#11531]: https://github.com/hrydgard/ppsspp/issues/11531 "WIP: Virtual readbacks" +[#11553]: https://github.com/hrydgard/ppsspp/issues/11553 "Remove constraint that virtual framebuffers have to represent VRAM." +[#11776]: https://github.com/hrydgard/ppsspp/issues/11776 "Only gate really expensive block transfers behind the setting." +[#11543]: https://github.com/hrydgard/ppsspp/issues/11543 "GPU: Dirty frag shader on depth write" +[#11620]: https://github.com/hrydgard/ppsspp/issues/11620 "Optimize out some stencil emulation, try to avoid depth write" +[#11584]: https://github.com/hrydgard/ppsspp/issues/11584 "D3D11: Allow shader blend to self" +[#11621]: https://github.com/hrydgard/ppsspp/issues/11621 "Vulkan: Avoid using Vulkan" +[#11658]: https://github.com/hrydgard/ppsspp/issues/11658 "Windows: Hide Vulkan/D3D11 if not available" +[#11665]: https://github.com/hrydgard/ppsspp/issues/11665 "Remove the \"Disable stencil test\" hack setting" +[#11666]: https://github.com/hrydgard/ppsspp/issues/11666 "Remove \"Timer Hack\" setting." +[#11667]: https://github.com/hrydgard/ppsspp/issues/11667 "Remove outdated TrueColor setting." +[#11689]: https://github.com/hrydgard/ppsspp/issues/11689 "Correct remote disc streaming with ipv6" +[#11700]: https://github.com/hrydgard/ppsspp/issues/11700 "http: Report errors reading discs" +[#11691]: https://github.com/hrydgard/ppsspp/issues/11691 "WIP: Vulkan/adreno: Apply workaround for Harvest Moon issue #10421" +[#11694]: https://github.com/hrydgard/ppsspp/issues/11694 "Vulkan: Limit stencil workaround to Adreno 5xx" +[#11720]: https://github.com/hrydgard/ppsspp/issues/11720 "Try to support Qt keyboard input directly. Fixes #11653" +[#11807]: https://github.com/hrydgard/ppsspp/issues/11807 "Qt: Re-enable Load button to browse for file" +[#11808]: https://github.com/hrydgard/ppsspp/issues/11808 "Qt: Correct text bind on first draw of string" +[#11740]: https://github.com/hrydgard/ppsspp/issues/11740 "Fix for weird Xbox B button behavior, see #10948." +[#11767]: https://github.com/hrydgard/ppsspp/issues/11767 "Compat: Force realistic UMD timing for F1 2006." +[#11785]: https://github.com/hrydgard/ppsspp/issues/11785 "GPU: Correct depth clamp range in range cull" +[#11859]: https://github.com/hrydgard/ppsspp/issues/11859 "GPU: Handle cull range properly drawing at offset" +[#11712]: https://github.com/hrydgard/ppsspp/issues/11712 "GLES: Detect Vivante GPU, disable vertex range culling" +[#11773]: https://github.com/hrydgard/ppsspp/issues/11773 "D3D9: Disable range culling on really old NVIDIA cards" +[#11787]: https://github.com/hrydgard/ppsspp/issues/11787 "GLES: Disable range culling on VideoCore/Vivante" +[#11812]: https://github.com/hrydgard/ppsspp/issues/11812 "Android: Allow using a custom Memory Stick storage path" +[#11822]: https://github.com/hrydgard/ppsspp/issues/11822 "interp: Correct vocp prefix handling" +[#11835]: https://github.com/hrydgard/ppsspp/issues/11835 "Correct vocp / vsocp prefix handling" +[#11831]: https://github.com/hrydgard/ppsspp/issues/11831 "Bundle libSDL inside app on macOS, fixes #11830" +[#11842]: https://github.com/hrydgard/ppsspp/issues/11842 "Win32 handle leak fix" +[#11508]: https://github.com/hrydgard/ppsspp/issues/11508 "Savedata: Write only one secure entry" +[#11441]: https://github.com/hrydgard/ppsspp/issues/11441 "Vulkan: Apply Themaister's patch, removing illegal pre-transitions of swapchain images. Fixes #11417 (crash on Note 9)" +[#11393]: https://github.com/hrydgard/ppsspp/issues/11393 "Implement vertex range culling" +[#10973]: https://github.com/hrydgard/ppsspp/issues/10973 "handle cull mode" +[#11182]: https://github.com/hrydgard/ppsspp/issues/11182 "GLES: Use accurate GLSL ver in postshader convert" +[#11438]: https://github.com/hrydgard/ppsspp/issues/11438 "Allow WASAPI device switching" +[#11461]: https://github.com/hrydgard/ppsspp/issues/11461 "Windows: Detect DirectInput devices after launch" +[#11307]: https://github.com/hrydgard/ppsspp/issues/11307 "Enable Discord integration for Mac and Linux." +[#10909]: https://github.com/hrydgard/ppsspp/issues/10909 "WebSocket based debugger interface" +[#11447]: https://github.com/hrydgard/ppsspp/issues/11447 "Avoid calling any GL calls during shutdown on Android. Should help #11063" +[#11350]: https://github.com/hrydgard/ppsspp/issues/11350 "TexCache: Optimize DXT3/DXT5 decode to single pass" diff --git a/history.md b/history.md index 33e74ce4c2..c6f48dca3f 100644 --- a/history.md +++ b/history.md @@ -14,16 +14,16 @@ What's new in 1.6.1, 1.6.2 What's new in 1.6.0 ------------------- * OpenGL backend now properly multithreaded, giving a good speed boost. -* Various Vulkan performance improvements (like [#10911](https://github.com/hrydgard/ppsspp/issues/10911)) and memory allocation fixes. -* GPU command interpreter performance improvements ([#10658](https://github.com/hrydgard/ppsspp/issues/10658)) -* Various fixes for app switching and widgets ([#10855](https://github.com/hrydgard/ppsspp/issues/10855)) on Android +* Various Vulkan performance improvements (like [#10911][]) and memory allocation fixes. +* GPU command interpreter performance improvements ([#10658][]) +* Various fixes for app switching and widgets ([#10855][]) on Android * Bugfixes and some performance improvements in the ARM64 JIT compiler and IR interpreter * Shader cache enabled for Vulkan -* Multiple iOS fixes, including JIT ([#10465](https://github.com/hrydgard/ppsspp/issues/10465)) and file browser ([#10921](https://github.com/hrydgard/ppsspp/issues/10921)). -* Improved compatibility on Mac ([#10113](https://github.com/hrydgard/ppsspp/issues/10113)) +* Multiple iOS fixes, including JIT ([#10465][]) and file browser ([#10921][]). +* Improved compatibility on Mac ([#10113][]) * Texture replacement ID bugfix (note: some textures from 1.5.4 may become incompatible) -* Adhoc multiplayer fixes ([#8975](https://github.com/hrydgard/ppsspp/issues/8975)) -* Vulkan support on Linux/SDL ([#10413](https://github.com/hrydgard/ppsspp/issues/10413)) +* Adhoc multiplayer fixes ([#8975][]) +* Vulkan support on Linux/SDL ([#10413][]) * Retroarch support What's new in 1.5.4 @@ -32,18 +32,18 @@ What's new in 1.5.4 What's new in 1.5.0 ------------------- -* Full Vulkan support, also for Android now. Very fast on supported devices. ([#10033](https://github.com/hrydgard/ppsspp/issues/10033), [#10049](https://github.com/hrydgard/ppsspp/issues/10049)) -* Smarter graphics state management, reduced CPU consumption on all backends ([#9899](https://github.com/hrydgard/ppsspp/issues/9899)) +* Full Vulkan support, also for Android now. Very fast on supported devices. ([#10033][], [#10049][]) +* Smarter graphics state management, reduced CPU consumption on all backends ([#9899][]) * Android: Support for Arabic and other scripts we couldn't support before -* Fix Android widgets, screen scaling ([#10145](https://github.com/hrydgard/ppsspp/issues/10145)) +* Fix Android widgets, screen scaling ([#10145][]) * Fixes to video dumping * Geometry problems fixed in Medal of Honor -* Implement immediate draws, fixing Thrillville ([#7459](https://github.com/hrydgard/ppsspp/issues/7459)) +* Implement immediate draws, fixing Thrillville ([#7459][]) * Software rendering improvements, speed and accuracy * Hardware tesselation of PSP Beziers and Splines (used by a few games) * Partial sceUsbGps and sceUsbCam support (Android) -* Android "Sustained performance mode" to avoid thermal throttling ([#9901](https://github.com/hrydgard/ppsspp/issues/9901)) -* Linux controller mapping fixes ([#9997](https://github.com/hrydgard/ppsspp/issues/9997)) +* Android "Sustained performance mode" to avoid thermal throttling ([#9901][]) +* Linux controller mapping fixes ([#9997][]) * Assorted bugfixes and compatibility improvements What's new in 1.4.2 @@ -55,15 +55,15 @@ What's new in 1.4.2 What's new in 1.4.1 ------------------- -* Fixes for some common hangs and crashes ([#9698](https://github.com/hrydgard/ppsspp/issues/9698), ...) -* Vertex decoder optimizations ([#9674](https://github.com/hrydgard/ppsspp/issues/9674)) -* Corrections to mipmap bias and selection function ([#9633](https://github.com/hrydgard/ppsspp/issues/9633)) -* Major improvements and fixes to software renderer, including mipmap support ([#9635](https://github.com/hrydgard/ppsspp/issues/9635), ...) +* Fixes for some common hangs and crashes ([#9698][], ...) +* Vertex decoder optimizations ([#9674][]) +* Corrections to mipmap bias and selection function ([#9633][]) +* Major improvements and fixes to software renderer, including mipmap support ([#9635][], ...) * UI background image support * Basic mouse input support on Windows -* Windows desktop touch fixes ([#9560](https://github.com/hrydgard/ppsspp/issues/9560)) +* Windows desktop touch fixes ([#9560][]) * D3D11 "depal" color fixes, fixing Sonic Rivals -* Fix crash in framebuffer blits affecting Persona 3 ([#9566](https://github.com/hrydgard/ppsspp/issues/9566)) +* Fix crash in framebuffer blits affecting Persona 3 ([#9566][]) What's new in 1.4-2 ------------------- @@ -72,12 +72,12 @@ What's new in 1.4-2 What's new in 1.4 ----------------- * Support D3D11 (performs better than OpenGL or D3D9 on most hardware) -* Audio quality improvement (linear interpolation) ([#8950](https://github.com/hrydgard/ppsspp/issues/8950)) +* Audio quality improvement (linear interpolation) ([#8950][]) * Hardware spline/bezier tesselation in OpenGL, D3D11 and Vulkan (...) * Post-processing shaders in D3D11 -* Prescale UV setting removed, now the default (improves perf) ([#9176](https://github.com/hrydgard/ppsspp/issues/9176)) +* Prescale UV setting removed, now the default (improves perf) ([#9176][]) * High DPI display fixes -* Various fixes for UMD switching for multi-UMD games ([#9245](https://github.com/hrydgard/ppsspp/issues/9245), [#9256](https://github.com/hrydgard/ppsspp/issues/9256)) +* Various fixes for UMD switching for multi-UMD games ([#9245][], [#9256][]) * New audio setting to improve compatibility with Bluetooth headsets * Various desktop gamepad compatibility fixes * Workaround for mipmap issue, fixing fonts in Tactics Ogre Japanese @@ -87,25 +87,25 @@ Support for Symbian, Maemo and Blackberry has been removed. What's new in 1.3.0 ------------------- -* Fix JIT problems on Galaxy S7 and iOS 9+ devices. ([#8965](https://github.com/hrydgard/ppsspp/issues/8965), [#8937](https://github.com/hrydgard/ppsspp/issues/8937)) -* Fix Android TV support and use latest FFmpeg. ([#8651](https://github.com/hrydgard/ppsspp/issues/8651), [#8870](https://github.com/hrydgard/ppsspp/issues/8870)) -* Texture replacement support - for custom textures and upscaling. ([#8715](https://github.com/hrydgard/ppsspp/issues/8715), [#8821](https://github.com/hrydgard/ppsspp/issues/8821)) -* Initial game recording / TAS features. ([#8939](https://github.com/hrydgard/ppsspp/issues/8939), [#8945](https://github.com/hrydgard/ppsspp/issues/8945)) -* Correctly map memory on Raspberry Pi 3, much better performance. ([#8801](https://github.com/hrydgard/ppsspp/issues/8801)) +* Fix JIT problems on Galaxy S7 and iOS 9+ devices. ([#8965][], [#8937][]) +* Fix Android TV support and use latest FFmpeg. ([#8651][], [#8870][]) +* Texture replacement support - for custom textures and upscaling. ([#8715][], [#8821][]) +* Initial game recording / TAS features. ([#8939][], [#8945][]) +* Correctly map memory on Raspberry Pi 3, much better performance. ([#8801][]) * Workaround rendering issues on Tegra K1/X1. (8294a54) -* Disc streaming to play quickly from tablet/phone on wifi. ([#8845](https://github.com/hrydgard/ppsspp/issues/8845)) -* Initial Vulkan support - not full featured yet. ([#8601](https://github.com/hrydgard/ppsspp/issues/8601), etc.) -* Experimental new CPU backend and CPU fixes. ([#8725](https://github.com/hrydgard/ppsspp/issues/8725)) -* Allow insert/eject of memstick - required by some games. ([#8889](https://github.com/hrydgard/ppsspp/issues/8889)) -* Better support for ps3 controller mapping. ([#8949](https://github.com/hrydgard/ppsspp/issues/8949)) -* Better UI handling for settings with long names in some languages. ([#8900](https://github.com/hrydgard/ppsspp/issues/8900), [#8898](https://github.com/hrydgard/ppsspp/issues/8898)) -* Screenshots in compatibility reporting, better website. ([#8812](https://github.com/hrydgard/ppsspp/issues/8812)) -* Fix type D cheat codes, allow for homebrew. ([#8818](https://github.com/hrydgard/ppsspp/issues/8818)) -* Graphic glitch fixes in several games. ([#8686](https://github.com/hrydgard/ppsspp/issues/8686), [#8757](https://github.com/hrydgard/ppsspp/issues/8757), [#8804](https://github.com/hrydgard/ppsspp/issues/8804)) -* Fix video playback glitches in several games. ([#8793](https://github.com/hrydgard/ppsspp/issues/8793), [#8803](https://github.com/hrydgard/ppsspp/issues/8803), [#8867](https://github.com/hrydgard/ppsspp/issues/8867), [#8914](https://github.com/hrydgard/ppsspp/issues/8914)) -* Various performance and compatibility improvements. ([#8868](https://github.com/hrydgard/ppsspp/issues/8868), [#8884](https://github.com/hrydgard/ppsspp/issues/8884), [#8932](https://github.com/hrydgard/ppsspp/issues/8932), [#8934](https://github.com/hrydgard/ppsspp/issues/8934), [#8813](https://github.com/hrydgard/ppsspp/issues/8813), [#8701](https://github.com/hrydgard/ppsspp/issues/8701), [#8960](https://github.com/hrydgard/ppsspp/issues/8960)) -* Various debugger and GE debugger improvements. ([#8882](https://github.com/hrydgard/ppsspp/issues/8882), [#8762](https://github.com/hrydgard/ppsspp/issues/8762)) -* Fix some problems when switching away from and back to the app ([#8968](https://github.com/hrydgard/ppsspp/issues/8968)) +* Disc streaming to play quickly from tablet/phone on wifi. ([#8845][]) +* Initial Vulkan support - not full featured yet. ([#8601][], etc.) +* Experimental new CPU backend and CPU fixes. ([#8725][]) +* Allow insert/eject of memstick - required by some games. ([#8889][]) +* Better support for ps3 controller mapping. ([#8949][]) +* Better UI handling for settings with long names in some languages. ([#8900][], [#8898][]) +* Screenshots in compatibility reporting, better website. ([#8812][]) +* Fix type D cheat codes, allow for homebrew. ([#8818][]) +* Graphic glitch fixes in several games. ([#8686][], [#8757][], [#8804][]) +* Fix video playback glitches in several games. ([#8793][], [#8803][], [#8867][], [#8914][]) +* Various performance and compatibility improvements. ([#8868][], [#8884][], [#8932][], [#8934][], [#8813][], [#8701][], [#8960][]) +* Various debugger and GE debugger improvements. ([#8882][], [#8762][]) +* Fix some problems when switching away from and back to the app ([#8968][]) What's new in 1.2.2 ------------------- @@ -320,3 +320,63 @@ go to see there http://forums.ppsspp.org/showthread.php?tid=3595&pid=59241#pid59 * Got it tested windows <-> mac osx <-> psp, it works * Monster Hunter 3rd HD works too, as well as God Eater Burst. +[#10911]: https://github.com/hrydgard/ppsspp/issues/10911 "Vulkan: Depalettize in shaders" +[#10658]: https://github.com/hrydgard/ppsspp/issues/10658 "Execute_Prim: Add a smaller \"inner interpreter\" to speed long up sequences of PRIM commands" +[#10855]: https://github.com/hrydgard/ppsspp/issues/10855 "PPSSPP 1.5.4 on Android. Shortcuts do not work the first time." +[#10465]: https://github.com/hrydgard/ppsspp/issues/10465 "Allow arm64 jit when memory base is not nicely aligned" +[#10921]: https://github.com/hrydgard/ppsspp/issues/10921 "Add support for File app (file browser) on iOS 11" +[#10113]: https://github.com/hrydgard/ppsspp/issues/10113 "Request a core profile in OpenGL (after 1.5.0)" +[#8975]: https://github.com/hrydgard/ppsspp/issues/8975 "Ad hoc: Band-aid fix for clear peer list. Should fix #7331" +[#10413]: https://github.com/hrydgard/ppsspp/issues/10413 "SDL/X11 Vulkan init" +[#10033]: https://github.com/hrydgard/ppsspp/issues/10033 "VulkanRenderManager - big refactoring of the Vulkan code" +[#10049]: https://github.com/hrydgard/ppsspp/issues/10049 "Vulkan threading tweaks and minor" +[#9899]: https://github.com/hrydgard/ppsspp/issues/9899 "Vulkan state optimizations" +[#10145]: https://github.com/hrydgard/ppsspp/issues/10145 "Android: When creating shortcuts, put the file path in data, not in extras." +[#7459]: https://github.com/hrydgard/ppsspp/issues/7459 "Thrillville Off The Rails Graphics' issues" +[#9901]: https://github.com/hrydgard/ppsspp/issues/9901 "Initial work on supporting sustained perf mode" +[#9997]: https://github.com/hrydgard/ppsspp/issues/9997 "Create default mapping for unknown control pads in SDL's controller database" +[#9698]: https://github.com/hrydgard/ppsspp/issues/9698 "General crash and hang fixes" +[#9674]: https://github.com/hrydgard/ppsspp/issues/9674 "Implement a few x86 vertexjit optimizations" +[#9633]: https://github.com/hrydgard/ppsspp/issues/9633 "Improve support for mipmaps and related headless fixes" +[#9635]: https://github.com/hrydgard/ppsspp/issues/9635 "SoftGPU: Rasterize triangles in chunks of 4 pixels" +[#9560]: https://github.com/hrydgard/ppsspp/issues/9560 "Allow using any touchId to scroll. Should help #9554." +[#9566]: https://github.com/hrydgard/ppsspp/issues/9566 "Fix out-of-bounds framebuffer blit on color bind" +[#8950]: https://github.com/hrydgard/ppsspp/issues/8950 "SasAudio: Implement linear interpolation" +[#9176]: https://github.com/hrydgard/ppsspp/issues/9176 "Always prescale uv (\"texcoord speedhack\")" +[#9245]: https://github.com/hrydgard/ppsspp/issues/9245 "Fix \"Akaya Akashiya Ayakashi\" umd switch" +[#9256]: https://github.com/hrydgard/ppsspp/issues/9256 "Fix Dies irae Amantes amentes umd switch" +[#8965]: https://github.com/hrydgard/ppsspp/issues/8965 "Port over the Exynos cacheline size fix from Dolphin." +[#8937]: https://github.com/hrydgard/ppsspp/issues/8937 "Implement W^X-compatible JIT. Hopefully makes JIT work on iOS again" +[#8651]: https://github.com/hrydgard/ppsspp/issues/8651 "Switch Android build to using clang (needs buildbot update)" +[#8870]: https://github.com/hrydgard/ppsspp/issues/8870 "Update to target Android SDK platform 24 (N)" +[#8715]: https://github.com/hrydgard/ppsspp/issues/8715 "Initial texture replacement support" +[#8821]: https://github.com/hrydgard/ppsspp/issues/8821 "Add basic TextureReplacement UI options." +[#8939]: https://github.com/hrydgard/ppsspp/issues/8939 "Add Frame Advance" +[#8945]: https://github.com/hrydgard/ppsspp/issues/8945 "Add Display Recording and Audio Dumping to Desktop" +[#8801]: https://github.com/hrydgard/ppsspp/issues/8801 "Improve performance on Raspberry Pi (and maybe other Linux)" +[#8845]: https://github.com/hrydgard/ppsspp/issues/8845 "Add UI for wifi remote disc streaming" +[#8601]: https://github.com/hrydgard/ppsspp/issues/8601 "Vulkan rendering backend. Early Work-In-Progress" +[#8725]: https://github.com/hrydgard/ppsspp/issues/8725 "IR Interpreter" +[#8889]: https://github.com/hrydgard/ppsspp/issues/8889 "Initial support for memstick insert/remove" +[#8949]: https://github.com/hrydgard/ppsspp/issues/8949 "Adds --PS3 comand line option for PS3 controller support on SDL." +[#8900]: https://github.com/hrydgard/ppsspp/issues/8900 "Wrap text in many places where it makes sense" +[#8898]: https://github.com/hrydgard/ppsspp/issues/8898 "UI: Scale option text down when there's no space" +[#8812]: https://github.com/hrydgard/ppsspp/issues/8812 "Include screenshots in compatibility reports" +[#8818]: https://github.com/hrydgard/ppsspp/issues/8818 "CWC improvements/fixes" +[#8686]: https://github.com/hrydgard/ppsspp/issues/8686 "Interpolate bezier patch colors/UVs using bernstein" +[#8757]: https://github.com/hrydgard/ppsspp/issues/8757 "Save FBOs on decimate when a safe size is known" +[#8804]: https://github.com/hrydgard/ppsspp/issues/8804 "Download single-use renders right away" +[#8793]: https://github.com/hrydgard/ppsspp/issues/8793 "Correct some scePsmf info retrieval funcs and error handling" +[#8803]: https://github.com/hrydgard/ppsspp/issues/8803 "Reject invalid MPEG puts for certain lib versions" +[#8867]: https://github.com/hrydgard/ppsspp/issues/8867 "Improve mpeg parsing / corruption issues" +[#8914]: https://github.com/hrydgard/ppsspp/issues/8914 "Psmf: Ignore stream size with old PsmfPlayer libs" +[#8868]: https://github.com/hrydgard/ppsspp/issues/8868 "Return error when trying to close files with pending operations" +[#8884]: https://github.com/hrydgard/ppsspp/issues/8884 "Better support zh_gb.pgf" +[#8932]: https://github.com/hrydgard/ppsspp/issues/8932 "Font: Draw nothing for chars before first glyph" +[#8934]: https://github.com/hrydgard/ppsspp/issues/8934 "Io: Do not delay on file seek" +[#8813]: https://github.com/hrydgard/ppsspp/issues/8813 "Enable extra ram for The Elder Scrolls Travels Oblivion USA Beta and Melodie alpha" +[#8701]: https://github.com/hrydgard/ppsspp/issues/8701 "Correct dependency handling when loading modules" +[#8960]: https://github.com/hrydgard/ppsspp/issues/8960 "Fix scePowerSetClockFrequency timing" +[#8882]: https://github.com/hrydgard/ppsspp/issues/8882 "Add custom log expressions to the debugger" +[#8762]: https://github.com/hrydgard/ppsspp/issues/8762 "Add more GE debugger features" +[#8968]: https://github.com/hrydgard/ppsspp/issues/8968 "Android: Add both a lost and restore phase" diff --git a/link_readme.py b/link_readme.py index c2e8a998f6..a0df5b9883 100755 --- a/link_readme.py +++ b/link_readme.py @@ -1,10 +1,42 @@ -#!/bin/python +#!/usr/bin/env python import re +import time +import urllib.request +from urllib.error import HTTPError +import time +from lxml.html import parse + +footer = "" +def replace_foo(match): + first_char = match.group(1) + id = match.group(2) + replace = first_char + "[#"+id+"][]" + + url = "https://github.com/hrydgard/ppsspp/issues/"+id + title = None + while title is None: + try: + page = urllib.request.urlopen(url) + p = parse(page) + title = p.find(".//title").text.split('by')[0].split('·')[0].strip() + title = re.sub(r"\"", r'\\"', title) + except HTTPError: + print("Something went wrong, retrying in 10 sec...") + time.sleep(10) + pass + + global footer + addition = "[#"+id+"]: https://github.com/hrydgard/ppsspp/issues/"+id+" \""+title+"\"" + print("Done: " + addition) + footer += addition+"\n" + return replace + f = open("README.md", "r+") cont = f.read() -updated = re.sub(r"([^[])#(\d+)", r"\1[#\2](https://github.com/hrydgard/ppsspp/issues/\2)", cont) +updated = re.sub(r"([^[])#(\d+)", replace_foo, cont) f.seek(0) f.write(updated) +f.write(footer) f.truncate() f.close() From 626d173d1037eec477a3d655f4832c749de7a270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 15 Jul 2020 12:10:33 +0200 Subject: [PATCH 276/848] Split the fault handling from MemMap.cpp to MemFault.cpp. --- CMakeLists.txt | 2 + Common/MachineContext.h | 18 ++-- Core/Core.vcxproj | 5 +- Core/Core.vcxproj.filters | 8 +- Core/MemFault.cpp | 143 ++++++++++++++++++++++++++++ Core/MemFault.h | 13 +++ Core/MemMap.cpp | 114 +--------------------- Core/MemMap.h | 4 - Core/System.cpp | 2 +- UI/DevScreens.h | 1 + UI/EmuScreen.cpp | 4 +- UWP/CoreUWP/CoreUWP.vcxproj | 4 +- UWP/CoreUWP/CoreUWP.vcxproj.filters | 2 + android/jni/Android.mk | 1 + libretro/Makefile.common | 1 + 15 files changed, 191 insertions(+), 131 deletions(-) create mode 100644 Core/MemFault.cpp create mode 100644 Core/MemFault.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d866fe92c..28d99b3fb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1740,6 +1740,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/MIPS/MIPSVFPUUtils.h Core/MIPS/MIPSAsm.cpp Core/MIPS/MIPSAsm.h + Core/MemFault.cpp + Core/MemFault.h Core/MemMap.cpp Core/MemMap.h Core/MemMapFunctions.cpp diff --git a/Common/MachineContext.h b/Common/MachineContext.h index fdd84f26d1..e2cf802888 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -314,32 +314,30 @@ typedef mcontext_t SContext; #if PPSSPP_ARCH(AMD64) -#include +#include #define CTX_PC CTX_RIP -static inline u64* ContextRN(SContext* ctx, int n) -{ - static const u8 offsets[] = { +static inline uint64_t *ContextRN(SContext* ctx, int n) { + static const uint8_t offsets[] = { offsetof(SContext, CTX_RAX), offsetof(SContext, CTX_RCX), offsetof(SContext, CTX_RDX), offsetof(SContext, CTX_RBX), offsetof(SContext, CTX_RSP), offsetof(SContext, CTX_RBP), offsetof(SContext, CTX_RSI), offsetof(SContext, CTX_RDI), offsetof(SContext, CTX_R8), offsetof(SContext, CTX_R9), offsetof(SContext, CTX_R10), offsetof(SContext, CTX_R11), offsetof(SContext, CTX_R12), offsetof(SContext, CTX_R13), offsetof(SContext, CTX_R14), offsetof(SContext, CTX_R15)}; - return (u64*)((char*)ctx + offsets[n]); + return (uint64_t *)((char *)ctx + offsets[n]); } #elif PPSSPP_ARCH(X86) -#include +#include #define CTX_PC CTX_RIP -static inline u32* ContextRN(SContext* ctx, int n) -{ - static const u8 offsets[] = { +static inline uint32_t *ContextRN(SContext* ctx, int n) { + static const uint8_t offsets[] = { offsetof(SContext, CTX_RAX), offsetof(SContext, CTX_RCX), offsetof(SContext, CTX_RDX), offsetof(SContext, CTX_RBX), offsetof(SContext, CTX_RSP), offsetof(SContext, CTX_RBP), offsetof(SContext, CTX_RSI), offsetof(SContext, CTX_RDI)}; - return (u32*)((char*)ctx + offsets[n]); + return (uint32_t *)((char*)ctx + offsets[n]); } #endif // arch diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 4498efe743..6679ddbf34 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -129,8 +129,7 @@ - + @@ -389,6 +388,7 @@ + @@ -918,6 +918,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index c95b6aa41f..5cfb4de0f5 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -743,6 +743,9 @@ HLE\Kernel + + Core + @@ -1379,10 +1382,13 @@ HLE\Kernel + + Core + - + \ No newline at end of file diff --git a/Core/MemFault.cpp b/Core/MemFault.cpp new file mode 100644 index 0000000000..3e15ecdbb7 --- /dev/null +++ b/Core/MemFault.cpp @@ -0,0 +1,143 @@ +// Copyright (C) 2020 PPSSPP Project + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "ppsspp_config.h" + +#include "Common/MachineContext.h" + +#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) +#include "Common/x64Analyzer.h" +#elif PPSSPP_ARCH(ARM64) +#include "Core/Util/DisArm64.h" +#elif PPSSPP_ARCH(ARM) +#include "ext/disarm.h" +#endif + +#include "Core/Core.h" +#include "Core/MemFault.h" +#include "Core/MemMap.h" +#include "Core/MIPS/JitCommon/JitCommon.h" + +namespace Memory { + +static int64_t g_numReportedBadAccesses = 0; + +void MemFault_Init() { + g_numReportedBadAccesses = 0; +} + +#ifdef MACHINE_CONTEXT_SUPPORTED + +bool HandleFault(uintptr_t hostAddress, void *ctx) { + SContext *context = (SContext *)ctx; + const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); + + // TODO: Check that codePtr is within the current JIT space. + bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr); + if (!inJitSpace) { + // This is a crash in non-jitted code. Not something we want to handle here, ignore. + return false; + } + + uintptr_t baseAddress = (uintptr_t)base; +#ifdef MASKED_PSP_MEMORY + const uintptr_t addressSpaceSize = 0x40000000ULL; +#else + const uintptr_t addressSpaceSize = 0x100000000ULL; +#endif + + // Check whether hostAddress is within the PSP memory space, which (likely) means it was a guest executable that did the bad access. + if (hostAddress < baseAddress || hostAddress >= baseAddress + addressSpaceSize) { + // Host address outside - this was a different kind of crash. + return false; + } + + // OK, a guest executable did a bad access. Take care of it. + + uint32_t guestAddress = hostAddress - baseAddress; + + // TODO: Share the struct between the various analyzers, that will allow us to share most of + // the implementations here. + bool success = false; + + MemoryExceptionType type = MemoryExceptionType::NONE; + + std::string disassembly; + +#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) + // X86, X86-64. Variable instruction size so need to analyze the mov instruction in detail. + + // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC + LSInstructionInfo info; + success = X86AnalyzeMOV(codePtr, info); + +#elif PPSSPP_ARCH(ARM64) + uint32_t word; + memcpy(&word, codePtr, 4); + // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC + Arm64LSInstructionInfo info; + success = Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info); +#elif PPSSPP_ARCH(ARM) + uint32_t word; + memcpy(&word, codePtr, 4); + // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC + ArmLSInstructionInfo info; + success = ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info); +#endif + if (success) { + if (info.isMemoryWrite) { + type = MemoryExceptionType::WRITE_WORD; + } else { + type = MemoryExceptionType::READ_WORD; + } + } else { + type = MemoryExceptionType::UNKNOWN; + } + + if (success && g_Config.bIgnoreBadMemAccess) { + if (!info.isMemoryWrite) { + // It was a read. Fill the destination register with 0. + // TODO + } + // Move on to the next instruction. Note that handling bad accesses like this is pretty slow. + context->CTX_PC += info.instructionSize; + g_numReportedBadAccesses++; + if (g_numReportedBadAccesses < 100) { + ERROR_LOG(MEMMAP, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress); + } + } else { + // Either bIgnoreBadMemAccess is off, or we failed recovery analysis. + uint32_t approximatePC = currentMIPS->pc; + Core_MemoryException(guestAddress, currentMIPS->pc, type); + + // Redirect execution to a crash handler that will exit the game. + context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler(); + ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation.", guestAddress, (void *)hostAddress); + } + return true; +} + +#else + +bool HandleFault(uintptr_t hostAddress, void *ctx) { + ERROR_LOG(MEMMAP, "Exception handling not supported"); + return false; +} + +#endif + +} // namespace Memory diff --git a/Core/MemFault.h b/Core/MemFault.h new file mode 100644 index 0000000000..40472a50da --- /dev/null +++ b/Core/MemFault.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace Memory { + +void MemFault_Init(); + +// Called by exception handlers. We simply filter out accesses to PSP RAM and otherwise +// just leave it as-is. +bool HandleFault(uintptr_t hostAddress, void *context); + +} diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 730613d5e9..b2fa2d0cd7 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -29,17 +29,8 @@ #include "Common/MemArena.h" #include "Common/ChunkFile.h" -#include "Common/MachineContext.h" - -#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) -#include "Common/x64Analyzer.h" -#elif PPSSPP_ARCH(ARM64) -#include "Core/Util/DisArm64.h" -#elif PPSSPP_ARCH(ARM) -#include "ext/disarm.h" -#endif - #include "Core/MemMap.h" +#include "Core/MemFault.h" #include "Core/HDRemaster.h" #include "Core/MIPS/MIPS.h" #include "Core/HLE/HLE.h" @@ -57,7 +48,7 @@ namespace Memory { // The base pointer to the auto-mirrored arena. -u8* base = NULL; +u8* base = nullptr; // The MemArena class MemArena g_arena; @@ -97,8 +88,6 @@ u32 g_PSPModel; std::recursive_mutex g_shutdownLock; -static int64_t g_numReportedBadAccesses = 0; - // We don't declare the IO region in here since its handled by other means. static MemoryView views[] = { @@ -311,7 +300,7 @@ void Init() { INFO_LOG(MEMMAP, "Memory system initialized. Base at %p (RAM at @ %p, uncached @ %p)", base, m_pPhysicalRAM, m_pUncachedRAM); - g_numReportedBadAccesses = 0; + MemFault_Init(); } void Reinit() { @@ -479,101 +468,4 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength) { CBreakPoints::ExecMemCheck(_Address, true, _iLength, currentMIPS->pc); } -#ifdef MACHINE_CONTEXT_SUPPORTED - -bool HandleFault(uintptr_t hostAddress, void *ctx) { - SContext *context = (SContext *)ctx; - const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); - - // TODO: Check that codePtr is within the current JIT space. - bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr); - if (!inJitSpace) { - // This is a crash in non-jitted code. Not something we want to handle here, ignore. - return false; - } - - uintptr_t baseAddress = (uintptr_t)base; -#ifdef MASKED_PSP_MEMORY - const uintptr_t addressSpaceSize = 0x40000000ULL; -#else - const uintptr_t addressSpaceSize = 0x100000000ULL; -#endif - - // Check whether hostAddress is within the PSP memory space, which (likely) means it was a guest executable that did the bad access. - if (hostAddress < baseAddress || hostAddress >= baseAddress + addressSpaceSize) { - // Host address outside - this was a different kind of crash. - return false; - } - - // OK, a guest executable did a bad access. Take care of it. - - uint32_t guestAddress = hostAddress - baseAddress; - - // TODO: Share the struct between the various analyzers, that will allow us to share most of - // the implementations here. - bool success = false; - - MemoryExceptionType type = MemoryExceptionType::NONE; - -#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) - // X86, X86-64. Variable instruction size so need to analyze the mov instruction in detail. - - // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC - LSInstructionInfo info; - success = X86AnalyzeMOV(codePtr, info); -#elif PPSSPP_ARCH(ARM64) - uint32_t word; - memcpy(&word, codePtr, 4); - // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC - Arm64LSInstructionInfo info; - success = Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info); -#elif PPSSPP_ARCH(ARM) - uint32_t word; - memcpy(&word, codePtr, 4); - // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC - ArmLSInstructionInfo info; - success = ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info); -#endif - if (success) { - if (info.isMemoryWrite) { - type = MemoryExceptionType::WRITE_WORD; - } else { - type = MemoryExceptionType::READ_WORD; - } - } else { - type = MemoryExceptionType::UNKNOWN; - } - - if (success && g_Config.bIgnoreBadMemAccess) { - if (!info.isMemoryWrite) { - // It was a read. Fill the destination register with 0. - // TODO - } - // Move on to the next instruction. Note that handling bad accesses like this is pretty slow. - context->CTX_PC += info.instructionSize; - g_numReportedBadAccesses++; - if (g_numReportedBadAccesses < 100) { - ERROR_LOG(MEMMAP, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress); - } - } else { - // Either bIgnoreBadMemAccess is off, or we failed recovery analysis. - uint32_t approximatePC = currentMIPS->pc; - Core_MemoryException(guestAddress, currentMIPS->pc, type); - - // Redirect execution to a crash handler that will exit the game. - context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler(); - ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation.", guestAddress, (void *)hostAddress); - } - return true; -} - -#else - -bool HandleFault(uintptr_t hostAddress, void *ctx) { - ERROR_LOG(MEMMAP, "Exception handling not supported"); - return false; -} - -#endif - } // namespace diff --git a/Core/MemMap.h b/Core/MemMap.h index dcbbad5441..515d866f6f 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -148,10 +148,6 @@ Opcode Read_Opcode_JIT(const u32 _Address); // used by JIT. Reads in the "Locked cache" mode void Write_Opcode_JIT(const u32 _Address, const Opcode& _Value); -// Called by exception handlers. We simply filter out accesses to PSP RAM and otherwise -// just leave it as-is. -bool HandleFault(uintptr_t hostAddress, void *context); - // Should be used by analyzers, disassemblers etc. Does resolve replacements. Opcode Read_Instruction(const u32 _Address, bool resolveReplacements = false); Opcode ReadUnchecked_Instruction(const u32 _Address, bool resolveReplacements = false); diff --git a/Core/System.cpp b/Core/System.cpp index c679bb60b9..1f738882c7 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -39,7 +39,7 @@ #include "util/text/utf8.h" #include "Common/GraphicsContext.h" -#include "Core/MemMap.h" +#include "Core/MemFault.h" #include "Core/HDRemaster.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSAnalyst.h" diff --git a/UI/DevScreens.h b/UI/DevScreens.h index 8b98b022c6..7b71ad6f13 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -182,3 +182,4 @@ private: }; void DrawProfile(UIContext &ui); +const char *GetCompilerABI(); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 7992aeab31..873908586a 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1283,12 +1283,14 @@ static void DrawCrashDump(DrawBuffer *draw2d) { snprintf(statbuf, sizeof(statbuf), R"(%s Game ID (Title): %s (%s) PPSSPP build: %s (%s) +ABI: %s )", ExceptionTypeAsString(info.type), g_paramSFO.GetDiscID().c_str(), g_paramSFO.GetValueString("TITLE").c_str(), versionString, - build + build, + GetCompilerABI() ); draw2d->SetFontScale(.7f, .7f); diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 75b8b2c4c5..900df8f61a 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -519,6 +519,7 @@ + @@ -730,6 +731,7 @@ + @@ -947,4 +949,4 @@ - \ No newline at end of file + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 7afcc97e71..8055a958ff 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -82,6 +82,7 @@ + @@ -719,6 +720,7 @@ + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 44ab4a7332..5a08665464 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -300,6 +300,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/FileLoaders/LocalFileLoader.cpp \ $(SRC)/Core/FileLoaders/RamCachingFileLoader.cpp \ $(SRC)/Core/FileLoaders/RetryingFileLoader.cpp \ + $(SRC)/Core/MemFault.cpp \ $(SRC)/Core/MemMap.cpp \ $(SRC)/Core/MemMapFunctions.cpp \ $(SRC)/Core/Reporting.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 0ac5b33297..3b12a0ba07 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -472,6 +472,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/MIPS/MIPSIntVFPU.cpp \ $(COREDIR)/MIPS/MIPSTables.cpp \ $(COREDIR)/MIPS/MIPSVFPUUtils.cpp \ + $(COREDIR)/MemFault.cpp \ $(COREDIR)/MemMap.cpp \ $(COREDIR)/MemMapFunctions.cpp \ $(COREDIR)/PSPLoaders.cpp \ From 8c38d7305e6ef2ae72df8baa94a5b09836a39fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 15 Jul 2020 12:38:05 +0200 Subject: [PATCH 277/848] Crash: Show disassembly of the instruction causing the crash, and the symbol name. --- Core/Core.cpp | 22 ++++++++++++++++++++++ Core/Core.h | 6 ++++++ Core/MemFault.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++----- UI/EmuScreen.cpp | 8 +++++--- 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index dfb28a6fc8..01b2970cda 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -436,6 +436,28 @@ void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { } } +void Core_MemoryExceptionInfo(u32 address, u32 pc, MemoryExceptionType type, std::string additionalInfo) { + const char *desc = MemoryExceptionTypeAsString(type); + // In jit, we only flush PC when bIgnoreBadMemAccess is off. + if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { + WARN_LOG(MEMMAP, "%s: Invalid address %08x. %s", desc, address, additionalInfo.c_str()); + } else { + WARN_LOG(MEMMAP, "%s: Invalid address %08x PC %08x LR %08x %s", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA], additionalInfo.c_str()); + } + + if (!g_Config.bIgnoreBadMemAccess) { + ExceptionInfo &e = g_exceptionInfo; + e = {}; + e.type = ExceptionType::MEMORY; + e.info = additionalInfo; + e.memory_type = type; + e.address = address; + e.pc = pc; + Core_EnableStepping(true); + host->SetDebugMode(true); + } +} + void Core_ExecException(u32 address, u32 pc, ExecExceptionType type) { const char *desc = ExecExceptionTypeAsString(type); WARN_LOG(MEMMAP, "%s: Invalid destination %08x PC %08x LR %08x", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); diff --git a/Core/Core.h b/Core/Core.h index 314a2823a1..21facdb735 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -17,6 +17,8 @@ #pragma once +#include + #include "Core/System.h" #include "Core/CoreParameter.h" @@ -92,7 +94,11 @@ enum class ExecExceptionType { THREAD, }; +// Separate one for without info, to avoid having to allocate a string void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type); + +void Core_MemoryExceptionInfo(u32 address, u32 pc, MemoryExceptionType type, std::string additionalInfo); + void Core_ExecException(u32 address, u32 pc, ExecExceptionType type); void Core_Break(); diff --git a/Core/MemFault.cpp b/Core/MemFault.cpp index 3e15ecdbb7..104be4af59 100644 --- a/Core/MemFault.cpp +++ b/Core/MemFault.cpp @@ -21,6 +21,7 @@ #if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) #include "Common/x64Analyzer.h" + #elif PPSSPP_ARCH(ARM64) #include "Core/Util/DisArm64.h" #elif PPSSPP_ARCH(ARM) @@ -42,6 +43,29 @@ void MemFault_Init() { #ifdef MACHINE_CONTEXT_SUPPORTED +static bool DisassembleNativeAt(const uint8_t *codePtr, int instructionSize, std::string *dest) { +#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) + auto lines = DisassembleX86(codePtr, instructionSize); + if (!lines.empty()) { + *dest = lines[0]; + return true; + } +#elif PPSSPP_ARCH(ARM64) + auto lines = DisassembleArm64(codePtr, instructionSize); + if (!lines.empty()) { + *dest = lines[0]; + return true; + } +#elif PPSSPP_ARCH(ARM) + auto lines = DisassembleArm2(codePtr, instructionSize); + if (!lines.empty()) { + *dest = lines[0]; + return true; + } +#endif + return false; +} + bool HandleFault(uintptr_t hostAddress, void *ctx) { SContext *context = (SContext *)ctx; const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); @@ -76,15 +100,23 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { MemoryExceptionType type = MemoryExceptionType::NONE; - std::string disassembly; + std::string infoString = ""; + if (MIPSComp::jit) { + std::string desc; + if (MIPSComp::jit->DescribeCodePtr(codePtr, desc)) { + infoString += desc + "\n"; + } + } + + int instructionSize = 4; #if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) // X86, X86-64. Variable instruction size so need to analyze the mov instruction in detail. // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC LSInstructionInfo info; success = X86AnalyzeMOV(codePtr, info); - + instructionSize = info.instructionSize; #elif PPSSPP_ARCH(ARM64) uint32_t word; memcpy(&word, codePtr, 4); @@ -98,6 +130,12 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { ArmLSInstructionInfo info; success = ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info); #endif + + std::string disassembly; + if (DisassembleNativeAt(codePtr, instructionSize, &disassembly)) { + infoString += disassembly + "\n"; + } + if (success) { if (info.isMemoryWrite) { type = MemoryExceptionType::WRITE_WORD; @@ -122,11 +160,11 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { } else { // Either bIgnoreBadMemAccess is off, or we failed recovery analysis. uint32_t approximatePC = currentMIPS->pc; - Core_MemoryException(guestAddress, currentMIPS->pc, type); + Core_MemoryExceptionInfo(guestAddress, approximatePC, type, infoString); - // Redirect execution to a crash handler that will exit the game. + // Redirect execution to a crash handler that will exit the game immediately. context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler(); - ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation.", guestAddress, (void *)hostAddress); + ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation. Info:\n%s", guestAddress, (void *)hostAddress, infoString.c_str()); } return true; } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 873908586a..5c34224cc0 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1302,12 +1302,14 @@ ABI: %s if (info.type == ExceptionType::MEMORY) { snprintf(statbuf, sizeof(statbuf), R"( Access: %s at %08x -PC: %08x)", +PC: %08x +%s)", MemoryExceptionTypeAsString(info.memory_type), info.address, - info.pc); + info.pc, + info.info.c_str()); draw2d->DrawTextShadow(ubuntu24, statbuf, x, y, 0xFFFFFFFF); - y += 120; + y += 180; } else if (info.type == ExceptionType::BAD_EXEC_ADDR) { snprintf(statbuf, sizeof(statbuf), R"( Destination: %s to %08x From f5fd27c3b60140a2313a74dc0c0e18a4fdfbe40a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 15 Jul 2020 13:53:20 +0200 Subject: [PATCH 278/848] Buildfix. Checking _POSIX_VERSION is not recommended anyway. --- Common/ExceptionHandlerSetup.cpp | 10 +--------- Common/MachineContext.h | 2 ++ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index e8ca92b0a9..0f541333a7 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -21,10 +21,6 @@ #include "Common/MachineContext.h" -#ifndef _WIN32 -#include // Needed for _POSIX_VERSION -#endif - static BadAccessHandler g_badAccessHandler; #ifdef MACHINE_CONTEXT_SUPPORTED @@ -225,7 +221,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { void UninstallExceptionHandler() { } -#elif defined(_POSIX_VERSION) +#else static struct sigaction old_sa_segv; static struct sigaction old_sa_bus; @@ -330,10 +326,6 @@ void UninstallExceptionHandler() { g_badAccessHandler = nullptr; } -#else // Unsupported platform. Could also #error - -#error Shouldn't get here - #endif #else // !MACHINE_CONTEXT_SUPPORTED diff --git a/Common/MachineContext.h b/Common/MachineContext.h index e2cf802888..dabc854003 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -315,6 +315,7 @@ typedef mcontext_t SContext; #if PPSSPP_ARCH(AMD64) #include +#include #define CTX_PC CTX_RIP static inline uint64_t *ContextRN(SContext* ctx, int n) { static const uint8_t offsets[] = { @@ -330,6 +331,7 @@ static inline uint64_t *ContextRN(SContext* ctx, int n) { #elif PPSSPP_ARCH(X86) #include +#include #define CTX_PC CTX_RIP static inline uint32_t *ContextRN(SContext* ctx, int n) { From 697c3b8b36e4c21cb2d9e39da327ba6b3f033f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 18 Jul 2020 20:35:39 +0200 Subject: [PATCH 279/848] Cleanup log output on swapchain/surface recreation. --- Common/Vulkan/VulkanContext.cpp | 91 +++++++++++++++++----------- Common/Vulkan/VulkanContext.h | 9 +-- SDL/SDLMain.cpp | 4 +- SDL/SDLVulkanGraphicsContext.cpp | 25 +++++--- UI/GameSettingsScreen.cpp | 3 +- Windows/GPU/WindowsVulkanContext.cpp | 8 +-- android/jni/AndroidVulkanContext.cpp | 11 ++-- 7 files changed, 91 insertions(+), 60 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 31cb1573d3..9a36f3eaea 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -318,26 +318,18 @@ bool VulkanContext::MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirem return false; } -bool VulkanContext::InitObjects() { - if (!InitQueue()) { - return false; +void VulkanContext::DestroySwapchain() { + if (swapchain_ != VK_NULL_HANDLE) { + vkDestroySwapchainKHR(device_, swapchain_, nullptr); + swapchain_ = VK_NULL_HANDLE; } - - if (!InitSwapchain()) { - // Destroy queue? - return false; - } - return true; } -void VulkanContext::DestroyObjects() { - ILOG("VulkanContext::DestroyObjects (including swapchain)"); - if (swapchain_ != VK_NULL_HANDLE) - vkDestroySwapchainKHR(device_, swapchain_, nullptr); - swapchain_ = VK_NULL_HANDLE; - - vkDestroySurfaceKHR(instance_, surface_, nullptr); - surface_ = VK_NULL_HANDLE; +void VulkanContext::DestroySurface() { + if (surface_ != VK_NULL_HANDLE) { + vkDestroySurfaceKHR(instance_, surface_, nullptr); + surface_ = VK_NULL_HANDLE; + } } VkResult VulkanContext::GetInstanceLayerExtensionList(const char *layerName, std::vector &extensions) { @@ -716,7 +708,10 @@ VkResult VulkanContext::ReinitSurface() { surface_ = VK_NULL_HANDLE; } - ILOG("Creating Vulkan surface for window"); + ILOG("Creating Vulkan surface for window (%p %p)", winsysData1_, winsysData2_); + + VkResult retval = VK_SUCCESS; + switch (winsys_) { #ifdef _WIN32 case WINDOWSYSTEM_WIN32: @@ -725,7 +720,8 @@ VkResult VulkanContext::ReinitSurface() { win32.flags = 0; win32.hwnd = (HWND)winsysData2_; win32.hinstance = (HINSTANCE)winsysData1_; - return vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_); + retval = vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_); + break; } #endif #if defined(__ANDROID__) @@ -735,7 +731,8 @@ VkResult VulkanContext::ReinitSurface() { VkAndroidSurfaceCreateInfoKHR android{ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR }; android.flags = 0; android.window = wnd; - return vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_); + retval = vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_); + break; } #endif #if defined(VK_USE_PLATFORM_METAL_EXT) @@ -745,7 +742,8 @@ VkResult VulkanContext::ReinitSurface() { metal.flags = 0; metal.pLayer = winsysData1_; metal.pNext = winsysData2_; - return vkCreateMetalSurfaceEXT(instance_, &metal, nullptr, &surface_); + retval = vkCreateMetalSurfaceEXT(instance_, &metal, nullptr, &surface_); + break; } #endif #if defined(VK_USE_PLATFORM_XLIB_KHR) @@ -755,7 +753,8 @@ VkResult VulkanContext::ReinitSurface() { xlib.flags = 0; xlib.dpy = (Display *)winsysData1_; xlib.window = (Window)winsysData2_; - return vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_); + retval = vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_); + break; } #endif #if defined(VK_USE_PLATFORM_XCB_KHR) @@ -765,7 +764,8 @@ VkResult VulkanContext::ReinitSurface() { xcb.flags = 0; xcb.connection = (Connection *)winsysData1_; xcb.window = (Window)(uintptr_t)winsysData2_; - return vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_); + retval = vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_); + break; } #endif #if defined(VK_USE_PLATFORM_WAYLAND_KHR) @@ -775,7 +775,8 @@ VkResult VulkanContext::ReinitSurface() { wayland.flags = 0; wayland.display = (wl_display *)winsysData1_; wayland.surface = (wl_surface *)winsysData2_; - return vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_); + retval = vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_); + break; } #endif @@ -783,9 +784,19 @@ VkResult VulkanContext::ReinitSurface() { _assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented"); return VK_ERROR_INITIALIZATION_FAILED; } + + if (retval != VK_SUCCESS) { + return retval; + } + + if (!ChooseQueue()) { + return VK_ERROR_INITIALIZATION_FAILED; + } + + return VK_SUCCESS; } -bool VulkanContext::InitQueue() { +bool VulkanContext::ChooseQueue() { // Iterate over each queue to learn whether it supports presenting: VkBool32 *supportsPresent = new VkBool32[queue_count]; for (uint32_t i = 0; i < queue_count; i++) { @@ -869,7 +880,6 @@ bool VulkanContext::InitQueue() { } vkGetDeviceQueue(device_, graphics_queue_family_index_, 0, &gfx_queue_); - ILOG("gfx_queue_: %p", gfx_queue_); return true; } @@ -906,21 +916,27 @@ bool VulkanContext::InitSwapchain() { res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[physical_device_], surface_, &presentModeCount, presentModes); assert(res == VK_SUCCESS); - ILOG("surfCapabilities_.currentExtent: %dx%d", surfCapabilities_.currentExtent.width, surfCapabilities_.currentExtent.height); - ILOG("surfCapabilities_.minImageExtent: %dx%d", surfCapabilities_.minImageExtent.width, surfCapabilities_.minImageExtent.height); - ILOG("surfCapabilities_.maxImageExtent: %dx%d", surfCapabilities_.maxImageExtent.width, surfCapabilities_.maxImageExtent.height); swapChainExtent_.width = clamp(surfCapabilities_.currentExtent.width, surfCapabilities_.minImageExtent.width, surfCapabilities_.maxImageExtent.width); swapChainExtent_.height = clamp(surfCapabilities_.currentExtent.height, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.height); - ILOG("swapChainExtent: %dx%d", swapChainExtent_.width, swapChainExtent_.height); + ILOG("surfCapabilities_.current: %dx%d min: %dx%d max: %dx%d computed: %dx%d", + surfCapabilities_.currentExtent.width, surfCapabilities_.currentExtent.height, + surfCapabilities_.minImageExtent.width, surfCapabilities_.minImageExtent.height, + surfCapabilities_.maxImageExtent.width, surfCapabilities_.maxImageExtent.height, + swapChainExtent_.width, swapChainExtent_.height); // TODO: Find a better way to specify the prioritized present mode while being able // to fall back in a sensible way. VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR; + std::string modes = ""; for (size_t i = 0; i < presentModeCount; i++) { - ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i])); + modes += PresentModeString(presentModes[i]); + if (i != presentModeCount - 1) { + modes += ", "; + } } + ILOG("Supported present modes: %s", modes.c_str()); for (size_t i = 0; i < presentModeCount; i++) { bool match = false; match = match || ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR); @@ -940,13 +956,11 @@ bool VulkanContext::InitSwapchain() { // HACK swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; #endif - ILOG("Chosen present mode: %d (%s)", swapchainPresentMode, PresentModeString(swapchainPresentMode)); delete[] presentModes; // Determine the number of VkImage's to use in the swap chain (we desire to // own only 1 image at a time, besides the images being displayed and // queued for display): uint32_t desiredNumberOfSwapChainImages = surfCapabilities_.minImageCount + 1; - ILOG("numSwapChainImages: %d", desiredNumberOfSwapChainImages); if ((surfCapabilities_.maxImageCount > 0) && (desiredNumberOfSwapChainImages > surfCapabilities_.maxImageCount)) { @@ -954,14 +968,16 @@ bool VulkanContext::InitSwapchain() { desiredNumberOfSwapChainImages = surfCapabilities_.maxImageCount; } + ILOG("Chosen present mode: %d (%s). numSwapChainImages: %d/%d", + swapchainPresentMode, PresentModeString(swapchainPresentMode), + desiredNumberOfSwapChainImages, surfCapabilities_.maxImageCount); + // We mostly follow the practices from // https://arm-software.github.io/vulkan_best_practice_for_mobile_developers/samples/surface_rotation/surface_rotation_tutorial.html // VkSurfaceTransformFlagBitsKHR preTransform; std::string supportedTransforms = surface_transforms_to_string(surfCapabilities_.supportedTransforms); std::string currentTransform = surface_transforms_to_string(surfCapabilities_.currentTransform); - ILOG("Supported transforms: %s", supportedTransforms.c_str()); - ILOG("Current transform: %s", currentTransform.c_str()); g_display_rotation = DisplayRotation::ROTATE_0; g_display_rot_matrix.setIdentity(); bool swapChainExtentSwap = false; @@ -993,8 +1009,10 @@ bool VulkanContext::InitSwapchain() { // Let the OS rotate the image (potentially slow on many Android devices) preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; } + std::string preTransformStr = surface_transforms_to_string(preTransform); - ILOG("Chosen pretransform transform: %s", preTransformStr.c_str()); + + ILOG("Transform supported: %s current: %s chosen: %s", supportedTransforms.c_str(), currentTransform.c_str(), preTransformStr.c_str()); if (physicalDeviceProperties_[physical_device_].properties.vendorID == VULKAN_VENDOR_IMGTEC) { ILOG("Applying PowerVR hack (rounding off the width!)"); @@ -1017,6 +1035,7 @@ bool VulkanContext::InitSwapchain() { swap_chain_info.oldSwapchain = VK_NULL_HANDLE; swap_chain_info.clipped = true; swap_chain_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + // Don't ask for TRANSFER_DST for the swapchain image, we don't use that. // if (surfCapabilities_.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) // swap_chain_info.imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 3a8e519381..db61f2e5b1 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -147,12 +147,11 @@ public: VkResult InitSurface(WindowSystem winsys, void *data1, void *data2); VkResult ReinitSurface(); - bool InitQueue(); - bool InitObjects(); bool InitSwapchain(); - // Also destroys the surface. - void DestroyObjects(); + void DestroySwapchain(); + void DestroySurface(); + void DestroyDevice(); void PerformPendingDeletes(); @@ -273,6 +272,8 @@ public: void GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation); private: + bool ChooseQueue(); + VkResult InitDebugUtilsCallback(); // A layer can expose extensions, keep track of those extensions here. diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index a5928d45ba..ece0b81c96 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -114,11 +114,11 @@ static void InitSDLAudioDevice(const std::string &name = "") { } } if (audioDev <= 0) { - ILOG("SDL: Trying a different device"); + ILOG("SDL: Trying a different audio device"); audioDev = SDL_OpenAudioDevice(nullptr, 0, &fmt, &g_retFmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); } if (audioDev <= 0) { - ELOG("Failed to open audio: %s", SDL_GetError()); + ELOG("Failed to open audio device: %s", SDL_GetError()); } else { if (g_retFmt.samples != fmt.samples) // Notify, but still use it ELOG("Output audio samples: %d (requested: %d)", g_retFmt.samples, fmt.samples); diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 45898f3826..26a311394f 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -20,6 +20,15 @@ static const bool g_Validate = true; static const bool g_Validate = false; #endif +static uint32_t FlagsFromConfig() { + uint32_t flags = 0; + flags = g_Config.bVSync ? VULKAN_FLAG_PRESENT_FIFO : VULKAN_FLAG_PRESENT_MAILBOX; + if (g_Validate) { + flags |= VULKAN_FLAG_VALIDATE; + } + return flags; +} + bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) { window = SDL_CreateWindow("Initializing Vulkan...", x, y, pixel_xres, pixel_yres, mode); if (!window) { @@ -41,10 +50,7 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, } vulkan_ = new VulkanContext(); - int vulkanFlags = VULKAN_FLAG_PRESENT_MAILBOX; - if (g_Validate) { - vulkanFlags |= VULKAN_FLAG_VALIDATE; - } + int vulkanFlags = FlagsFromConfig(); VulkanContext::CreateInfo info{}; info.app_name = "PPSSPP"; @@ -102,7 +108,7 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, break; } - if (!vulkan_->InitObjects()) { + if (!vulkan_->InitSwapchain()) { *error_message = vulkan_->InitError(); Shutdown(); return false; @@ -126,7 +132,8 @@ void SDLVulkanGraphicsContext::Shutdown() { delete draw_; draw_ = nullptr; vulkan_->WaitUntilQueueIdle(); - vulkan_->DestroyObjects(); + vulkan_->DestroySwapchain(); + vulkan_->DestroySurface(); vulkan_->DestroyDevice(); vulkan_->DestroyInstance(); delete vulkan_; @@ -136,9 +143,11 @@ void SDLVulkanGraphicsContext::Shutdown() { void SDLVulkanGraphicsContext::Resize() { draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - vulkan_->DestroyObjects(); + vulkan_->DestroySwapchain(); + vulkan_->DestroySurface(); + vulkan_->UpdateFlags(FlagsFromConfig()); vulkan_->ReinitSurface(); - vulkan_->InitObjects(); + vulkan_->InitSwapchain(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); } diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 6c95bf7e91..1b353d8797 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -350,13 +350,14 @@ void GameSettingsScreen::CreateViews() { } #endif -#ifdef _WIN32 +#if !PPSSPP_PLATFORM(ANDROID) CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync"))); vSync->OnClick.Add([=](EventParams &e) { NativeResized(); return UI::EVENT_CONTINUE; }); #endif + CheckBox *frameDuplication = graphicsSettings->Add(new CheckBox(&g_Config.bRenderDuplicateFrames, gr->T("Render duplicate frames to 60hz"))); frameDuplication->SetEnabledFunc([] { return g_Config.iRenderingMode != FB_NON_BUFFERED_MODE || (g_Config.bSoftwareRendering && g_Config.iFrameSkip != 0); diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 8f7249dbc5..33281640d4 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -173,12 +173,10 @@ void WindowsVulkanContext::Shutdown() { void WindowsVulkanContext::Resize() { draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - g_Vulkan->DestroyObjects(); - + g_Vulkan->DestroySwapchain(); g_Vulkan->UpdateFlags(FlagsFromConfig()); - g_Vulkan->ReinitSurface(); - - g_Vulkan->InitObjects(); + g_Vulkan_->ReinitSurface(); + g_Vulkan_->InitSwapchain(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); } diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 39fe573057..c5c2f0a02a 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -116,7 +116,8 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB ILOG("AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed"); if (!success) { - g_Vulkan->DestroyObjects(); + g_Vulkan->DestroySwapchain(); + g_Vulkan->DestroySurface(); g_Vulkan->DestroyDevice(); g_Vulkan->DestroyInstance(); } @@ -130,7 +131,8 @@ void AndroidVulkanContext::ShutdownFromRenderThread() { draw_ = nullptr; g_Vulkan->WaitUntilQueueIdle(); g_Vulkan->PerformPendingDeletes(); - g_Vulkan->DestroyObjects(); // Also destroys the surface, a bit asymmetric + g_Vulkan->DestroySwapchain(); + g_Vulkan->DestroySurface(); ILOG("Done with ShutdownFromRenderThread"); } @@ -150,11 +152,12 @@ void AndroidVulkanContext::Resize() { ILOG("AndroidVulkanContext::Resize begin (oldsize: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - g_Vulkan->DestroyObjects(); + g_Vulkan->DestroySwapchain(); + g_Vulkan->DestroySurface(); g_Vulkan->UpdateFlags(FlagsFromConfig()); g_Vulkan->ReinitSurface(); - g_Vulkan->InitObjects(); + g_Vulkan->InitSwapchain(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); ILOG("AndroidVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); } From 49d9caeb0d6b9928c4f1d8b9ae2635e169d25b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 18 Jul 2020 20:37:55 +0200 Subject: [PATCH 280/848] SDL: Avoid destroying the surface on resize. --- Common/Vulkan/VulkanContext.cpp | 7 +++++++ SDL/SDLVulkanGraphicsContext.cpp | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 9a36f3eaea..e4aa024173 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -1083,6 +1083,13 @@ void VulkanContext::PerformPendingDeletes() { } void VulkanContext::DestroyDevice() { + if (swapchain_) { + ELOG("DestroyDevice: Swapchain should have been destroyed."); + } + if (surface_) { + ELOG("DestroyDevice: Surface should have been destroyed."); + } + ILOG("VulkanContext::DestroyDevice (performing deletes)"); PerformPendingDeletes(); diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 26a311394f..06f253c6d5 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -144,9 +144,7 @@ void SDLVulkanGraphicsContext::Shutdown() { void SDLVulkanGraphicsContext::Resize() { draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); vulkan_->DestroySwapchain(); - vulkan_->DestroySurface(); vulkan_->UpdateFlags(FlagsFromConfig()); - vulkan_->ReinitSurface(); vulkan_->InitSwapchain(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); } From e48cb916dd19c16bfde397d77052e0c14bcb98f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 18 Jul 2020 20:43:47 +0200 Subject: [PATCH 281/848] Buildfix --- Windows/GPU/WindowsVulkanContext.cpp | 4 ++-- android/jni/AndroidVulkanContext.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 33281640d4..16376b1f30 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -175,8 +175,8 @@ void WindowsVulkanContext::Resize() { draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); g_Vulkan->DestroySwapchain(); g_Vulkan->UpdateFlags(FlagsFromConfig()); - g_Vulkan_->ReinitSurface(); - g_Vulkan_->InitSwapchain(); + g_Vulkan->ReinitSurface(); + g_Vulkan->InitSwapchain(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); } diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index c5c2f0a02a..0f4c5ff69d 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -156,6 +156,7 @@ void AndroidVulkanContext::Resize() { g_Vulkan->DestroySurface(); g_Vulkan->UpdateFlags(FlagsFromConfig()); + g_Vulkan->ReinitSurface(); g_Vulkan->InitSwapchain(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); From 1897eed9b442c7b0c61de49fb442e478abe3c5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 18 Jul 2020 21:42:13 +0200 Subject: [PATCH 282/848] More buildfixes --- Core/HLE/sceDisplay.cpp | 8 +++++++- Windows/GPU/WindowsVulkanContext.cpp | 6 ++++-- android/jni/AndroidVulkanContext.cpp | 2 +- libretro/LibretroVulkanContext.cpp | 5 +++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 362ad09ce1..176cfdd5f8 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -758,8 +758,14 @@ void __DisplayFlip(int cyclesLate) { bool duplicateFrames = g_Config.bRenderDuplicateFrames && g_Config.iFrameSkip == 0; + bool unthrottleNeedsSkip = g_Config.bFrameSkipUnthrottle; + if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) { + // Vulkan doesn't support the interval setting, so we force frameskip. + unthrottleNeedsSkip = true; + } + // postEffectRequiresFlip is not compatible with frameskip unthrottling, see #12325. - if (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && !(g_Config.bFrameSkipUnthrottle && !FrameTimingThrottled())) { + if (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && !(unthrottleNeedsSkip && !FrameTimingThrottled())) { if (shaderInfo) { postEffectRequiresFlip = (shaderInfo->requires60fps || duplicateFrames); } else { diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 16376b1f30..c597a9fba5 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -129,7 +129,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m } g_Vulkan->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd); - if (!g_Vulkan->InitObjects()) { + if (!g_Vulkan->InitSwapchain()) { *error_message = g_Vulkan->InitError(); Shutdown(); return false; @@ -160,7 +160,8 @@ void WindowsVulkanContext::Shutdown() { draw_ = nullptr; g_Vulkan->WaitUntilQueueIdle(); - g_Vulkan->DestroyObjects(); + g_Vulkan->DestroySwapchain(); + g_Vulkan->DestroySurface(); g_Vulkan->DestroyDevice(); g_Vulkan->DestroyInstance(); @@ -174,6 +175,7 @@ void WindowsVulkanContext::Shutdown() { void WindowsVulkanContext::Resize() { draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); g_Vulkan->DestroySwapchain(); + g_Vulkan->DestroySurface(); g_Vulkan->UpdateFlags(FlagsFromConfig()); g_Vulkan->ReinitSurface(); g_Vulkan->InitSwapchain(); diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 0f4c5ff69d..3363bfeac6 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -100,7 +100,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB } bool success = true; - if (g_Vulkan->InitObjects()) { + if (g_Vulkan->InitSwapchain()) { draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, g_Config.bGfxDebugSplitSubmit); SetGPUBackend(GPUBackend::VULKAN); success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler. diff --git a/libretro/LibretroVulkanContext.cpp b/libretro/LibretroVulkanContext.cpp index ed5615b500..906d8550cd 100644 --- a/libretro/LibretroVulkanContext.cpp +++ b/libretro/LibretroVulkanContext.cpp @@ -69,7 +69,7 @@ static bool create_device(retro_vulkan_context *context, VkInstance instance, Vk vk->InitSurface(WINDOWSYSTEM_WAYLAND, nullptr, nullptr); #endif - if (!vk->InitQueue()) { + if (!vk->InitSwapchain()) { return false; } @@ -116,7 +116,8 @@ void LibretroVulkanContext::Shutdown() { vk->WaitUntilQueueIdle(); - vk->DestroyObjects(); + vk->DestroySwapchain(); + vk->DestroySurface(); vk->DestroyDevice(); vk->DestroyInstance(); delete vk; From 05ba88d20c6f94180570ea3fec94fcdd8fb979f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 18 Jul 2020 21:43:27 +0200 Subject: [PATCH 283/848] Windows/Vulkan: Don't destroy the surface during resize, no need. --- Windows/GPU/WindowsVulkanContext.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index c597a9fba5..929f8b51f9 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -175,9 +175,7 @@ void WindowsVulkanContext::Shutdown() { void WindowsVulkanContext::Resize() { draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); g_Vulkan->DestroySwapchain(); - g_Vulkan->DestroySurface(); g_Vulkan->UpdateFlags(FlagsFromConfig()); - g_Vulkan->ReinitSurface(); g_Vulkan->InitSwapchain(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); } From 21f99259f3b234e8a38a6c22d46f25dd53fb6256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 18 Jul 2020 22:50:26 +0200 Subject: [PATCH 284/848] Eliminate an unnecessary global g_Vulkan. --- Windows/GPU/WindowsVulkanContext.cpp | 72 ++++++++++++++-------------- Windows/GPU/WindowsVulkanContext.h | 2 + 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 929f8b51f9..909881b3d8 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -69,8 +69,6 @@ static const bool g_validate_ = true; static const bool g_validate_ = false; #endif -static VulkanContext *g_Vulkan; - static uint32_t FlagsFromConfig() { uint32_t flags = 0; flags = g_Config.bVSync ? VULKAN_FLAG_PRESENT_FIFO : VULKAN_FLAG_PRESENT_MAILBOX; @@ -83,7 +81,7 @@ static uint32_t FlagsFromConfig() { bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_message) { *error_message = "N/A"; - if (g_Vulkan) { + if (vulkan_) { *error_message = "Already initialized"; return false; } @@ -101,47 +99,47 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m return false; } - g_Vulkan = new VulkanContext(); + vulkan_ = new VulkanContext(); VulkanContext::CreateInfo info{}; info.app_name = "PPSSPP"; info.app_ver = gitVer.ToInteger(); info.flags = FlagsFromConfig(); - if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) { - *error_message = g_Vulkan->InitError(); - delete g_Vulkan; - g_Vulkan = nullptr; + if (VK_SUCCESS != vulkan_->CreateInstance(info)) { + *error_message = vulkan_->InitError(); + delete vulkan_; + vulkan_ = nullptr; return false; } - int deviceNum = g_Vulkan->GetPhysicalDeviceByName(g_Config.sVulkanDevice); + int deviceNum = vulkan_->GetPhysicalDeviceByName(g_Config.sVulkanDevice); if (deviceNum < 0) { - deviceNum = g_Vulkan->GetBestPhysicalDevice(); + deviceNum = vulkan_->GetBestPhysicalDevice(); if (!g_Config.sVulkanDevice.empty()) - g_Config.sVulkanDevice = g_Vulkan->GetPhysicalDeviceProperties(deviceNum).properties.deviceName; + g_Config.sVulkanDevice = vulkan_->GetPhysicalDeviceProperties(deviceNum).properties.deviceName; } - g_Vulkan->ChooseDevice(deviceNum); - if (g_Vulkan->CreateDevice() != VK_SUCCESS) { - *error_message = g_Vulkan->InitError(); - delete g_Vulkan; - g_Vulkan = nullptr; + vulkan_->ChooseDevice(deviceNum); + if (vulkan_->CreateDevice() != VK_SUCCESS) { + *error_message = vulkan_->InitError(); + delete vulkan_; + vulkan_ = nullptr; return false; } - g_Vulkan->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd); - if (!g_Vulkan->InitSwapchain()) { - *error_message = g_Vulkan->InitError(); + vulkan_->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd); + if (!vulkan_->InitSwapchain()) { + *error_message = vulkan_->InitError(); Shutdown(); return false; } bool splitSubmit = g_Config.bGfxDebugSplitSubmit; - draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, splitSubmit); - SetGPUBackend(GPUBackend::VULKAN, g_Vulkan->GetPhysicalDeviceProperties(deviceNum).properties.deviceName); + draw_ = Draw::T3DCreateVulkanContext(vulkan_, splitSubmit); + SetGPUBackend(GPUBackend::VULKAN, vulkan_->GetPhysicalDeviceProperties(deviceNum).properties.deviceName); bool success = draw_->CreatePresets(); _assert_msg_(G3D, success, "Failed to compile preset shaders"); - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); renderManager_ = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); renderManager_->SetInflightFrames(g_Config.iInflightFrames); @@ -154,39 +152,39 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m void WindowsVulkanContext::Shutdown() { if (draw_) - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); delete draw_; draw_ = nullptr; - g_Vulkan->WaitUntilQueueIdle(); - g_Vulkan->DestroySwapchain(); - g_Vulkan->DestroySurface(); - g_Vulkan->DestroyDevice(); - g_Vulkan->DestroyInstance(); + vulkan_->WaitUntilQueueIdle(); + vulkan_->DestroySwapchain(); + vulkan_->DestroySurface(); + vulkan_->DestroyDevice(); + vulkan_->DestroyInstance(); - delete g_Vulkan; - g_Vulkan = nullptr; + delete vulkan_; + vulkan_ = nullptr; renderManager_ = nullptr; finalize_glslang(); } void WindowsVulkanContext::Resize() { - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - g_Vulkan->DestroySwapchain(); - g_Vulkan->UpdateFlags(FlagsFromConfig()); - g_Vulkan->InitSwapchain(); - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); + vulkan_->DestroySwapchain(); + vulkan_->UpdateFlags(FlagsFromConfig()); + vulkan_->InitSwapchain(); + draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); } void WindowsVulkanContext::Poll() { // Check for existing swapchain to avoid issues during shutdown. - if (g_Vulkan->GetSwapchain() && renderManager_->NeedsSwapchainRecreate()) { + if (vulkan_->GetSwapchain() && renderManager_->NeedsSwapchainRecreate()) { Resize(); } } void *WindowsVulkanContext::GetAPIContext() { - return g_Vulkan; + return vulkan_; } diff --git a/Windows/GPU/WindowsVulkanContext.h b/Windows/GPU/WindowsVulkanContext.h index a006c52ed1..46abc4e841 100644 --- a/Windows/GPU/WindowsVulkanContext.h +++ b/Windows/GPU/WindowsVulkanContext.h @@ -21,6 +21,7 @@ #include "Windows/GPU/WindowsGraphicsContext.h" #include "thin3d/thin3d.h" +class VulkanContext; class VulkanRenderManager; class WindowsVulkanContext : public WindowsGraphicsContext { @@ -38,6 +39,7 @@ public: Draw::DrawContext *GetDrawContext() override { return draw_; } private: Draw::DrawContext *draw_; + VulkanContext *vulkan_ = nullptr; VulkanRenderManager *renderManager_ = nullptr; }; From cd6f16189efd9e72bb98cef6096fdb9ee0eb2e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Jul 2020 11:10:31 +0200 Subject: [PATCH 285/848] Update lang submodule --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index 942934a3d5..1c64b8fbd3 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 942934a3d55f600622fb3f3ad60ecc1f3da23b6b +Subproject commit 1c64b8fbd3cb6bd87935eb53f302f7de6f86e209 From f5afb2dbbd123c135b1537a053852e590ecd6be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 27 Jun 2020 09:41:48 +0200 Subject: [PATCH 286/848] Improve some logging, and print the line number from PanicAlerts. --- Common/MsgHandler.cpp | 12 ++++++------ Common/MsgHandler.h | 8 ++++---- ext/native/thin3d/VulkanRenderManager.cpp | 14 +++----------- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/Common/MsgHandler.cpp b/Common/MsgHandler.cpp index b53d79d41a..f2ec4dcadd 100644 --- a/Common/MsgHandler.cpp +++ b/Common/MsgHandler.cpp @@ -24,9 +24,9 @@ #include "base/logging.h" #include "util/text/utf8.h" -bool MsgHandler(const char *caption, const char *text, bool yes_no, int Style); +bool MsgHandler(const char *caption, const char *text, const char *file, int line, bool yes_no, int Style); -bool MsgAlert(bool yes_no, int Style, const char* format, ...) { +bool MsgAlert(bool yes_no, int Style, const char *file, int line, const char* format, ...) { // Read message and write it to the log char buffer[2048]; static const char *captions[] = { @@ -42,10 +42,10 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...) { CharArrayFromFormatV(buffer, sizeof(buffer)-1, format, args); va_end(args); // Normal logging (will also log to Android log) - ERROR_LOG(SYSTEM, "%s: %s", caption, buffer); + ERROR_LOG(SYSTEM, "(%s:%d) %s: %s", file, line, caption, buffer); // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored if (Style == QUESTION || Style == CRITICAL) - return MsgHandler(caption, buffer, yes_no, Style); + return MsgHandler(caption, buffer, file, line, yes_no, Style); return true; } @@ -54,7 +54,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...) { #endif // Default non library dependent panic alert -bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style) { +bool MsgHandler(const char* caption, const char* text, const char *file, int line, bool yes_no, int Style) { #if defined(USING_WIN_UI) int msgBoxStyle = MB_ICONINFORMATION; if (Style == QUESTION) msgBoxStyle = MB_ICONQUESTION; @@ -69,7 +69,7 @@ bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style) { return false; #else // Will use android-log if available, printf if not. - ELOG("%s", text); + ELOG("(%s:%d) %s", file, line, text); return false; #endif } diff --git a/Common/MsgHandler.h b/Common/MsgHandler.h index ee28d8ea33..4f453172c9 100644 --- a/Common/MsgHandler.h +++ b/Common/MsgHandler.h @@ -25,13 +25,13 @@ enum MSG_TYPE { CRITICAL }; -bool MsgAlert(bool yes_no, int Style, const char* format, ...) +bool MsgAlert(bool yes_no, int Style, const char *file, int line, const char* format, ...) #ifdef __GNUC__ - __attribute__((format(printf, 3, 4))) + __attribute__((format(printf, 5, 6))) #endif ; -#define PanicAlert(...) MsgAlert(false, WARNING, __VA_ARGS__) +#define PanicAlert(...) MsgAlert(false, WARNING, __FILE__, __LINE__, __VA_ARGS__) // Used only for asserts. -#define PanicYesNo(...) MsgAlert(true, CRITICAL, __VA_ARGS__) +#define PanicYesNo(...) MsgAlert(true, CRITICAL, __FILE__, __LINE__, __VA_ARGS__) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 8d8659be34..8278e1ca99 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -1040,7 +1040,7 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) { // 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"); + WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - processing the frame, but not presenting"); frameData.skipSwap = true; } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res)); @@ -1084,11 +1084,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) { submit_info.pCommandBuffers = cmdBufs; res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, VK_NULL_HANDLE); if (res == VK_ERROR_DEVICE_LOST) { -#ifdef _WIN32 - _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to Direct3D11"); -#else - _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to OpenGL"); -#endif + _assert_msg_(G3D, false, "Lost the Vulkan device in split submit! If this happens again, switch Graphics Backend away from Vulkan"); } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res)); } @@ -1112,11 +1108,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) { } res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFrameFence ? frameData.fence : frameData.readbackFence); if (res == VK_ERROR_DEVICE_LOST) { -#ifdef _WIN32 - _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to Direct3D11"); -#else - _assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to OpenGL"); -#endif + _assert_msg_(G3D, false, "Lost the Vulkan device in vkQueueSubmit! If this happens again, switch Graphics Backend away from Vulkan"); } else { _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%s", (int)splitSubmit_, VulkanResultToString(res)); } From 6560192d8ef1d89a7646a4cf8e13038ec179dd50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Jul 2020 11:03:46 +0200 Subject: [PATCH 287/848] Support full VSync control in SDL OpenGL. (Not yet Qt). Forgot about iOS SDL headless buildfix Additional iOS buildfix --- Common/GraphicsContext.h | 10 ---------- Core/Config.cpp | 2 +- GPU/GPUCommon.cpp | 2 +- GPU/GPUCommon.h | 2 -- Qt/QtMain.h | 7 ++++++- SDL/SDLGLGraphicsContext.cpp | 9 +++++++++ SDL/SDLGLGraphicsContext.h | 7 ++++++- UI/GameSettingsScreen.cpp | 4 ++-- ext/native/thin3d/thin3d_gl.cpp | 2 -- headless/SDLHeadlessHost.cpp | 9 +++++++-- ios/ViewController.mm | 9 ++++++++- 11 files changed, 40 insertions(+), 23 deletions(-) diff --git a/Common/GraphicsContext.h b/Common/GraphicsContext.h index d17d77d726..bf4f493871 100644 --- a/Common/GraphicsContext.h +++ b/Common/GraphicsContext.h @@ -40,13 +40,3 @@ public: virtual Draw::DrawContext *GetDrawContext() = 0; }; - -class DummyGraphicsContext : public GraphicsContext { -public: - void Shutdown() override {} - void SwapInterval(int interval) override {} - void SwapBuffers() override {} - void Resize() override {} - - Draw::DrawContext *GetDrawContext() override { return nullptr; } -}; diff --git a/Core/Config.cpp b/Core/Config.cpp index 1ef4dc5ba2..84e8bcf01e 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -530,7 +530,7 @@ static int DefaultInternalResolution() { } static bool DefaultFrameskipUnthrottle() { -#if !PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(UWP) +#if PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS) return true; #else return false; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 0a09725677..9c7baedf54 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -467,7 +467,7 @@ void GPUCommon::Reinitialize() { } void GPUCommon::UpdateVsyncInterval(bool force) { -#ifdef _WIN32 +#if !(PPSSPP_PLATFORM(ANDROID) || USING_QT_UI || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS)) int desiredVSyncInterval = g_Config.bVSync ? 1 : 0; if (PSP_CoreParameter().unthrottle) { desiredVSyncInterval = 0; diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 27deb1b77b..2dd4d7da1b 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -364,9 +364,7 @@ private: double timeSteppingStarted_; double timeSpentStepping_; -#ifdef _WIN32 int lastVsync_ = -1; -#endif }; struct CommonCommandTableEntry { diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 93bf5ccb75..ebb2c03cea 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -56,6 +56,8 @@ public: renderManager_->SetInflightFrames(g_Config.iInflightFrames); bool success = draw_->CreatePresets(); _assert_msg_(G3D, success, "Failed to compile preset shaders"); + + // TODO: Need to figure out how to implement SetSwapInterval for Qt. } ~QtGLGraphicsContext() { @@ -65,7 +67,10 @@ public: } void Shutdown() override {} - void SwapInterval(int interval) override {} + void SwapInterval(int interval) override { + // See TODO in constructor. + // renderManager_->SwapInterval(interval); + } void SwapBuffers() override {} void Resize() override {} diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index 7f1a58c66a..772f5c764f 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -423,10 +423,19 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: SDL_GL_SwapWindow(window_); #endif }); + + renderManager_->SetSwapIntervalFunction([&](int interval) { + ILOG("SDL SwapInterval: %d", interval); + SDL_GL_SetSwapInterval(interval); + }); window_ = window; return 0; } +void SDLGLGraphicsContext::SwapInterval(int interval) { + renderManager_->SwapInterval(interval); +} + void SDLGLGraphicsContext::Shutdown() { } diff --git a/SDL/SDLGLGraphicsContext.h b/SDL/SDLGLGraphicsContext.h index 666aa72774..88c9d8202d 100644 --- a/SDL/SDLGLGraphicsContext.h +++ b/SDL/SDLGLGraphicsContext.h @@ -5,7 +5,7 @@ #include "gfx/gl_common.h" #include "Common/GraphicsContext.h" -class SDLGLGraphicsContext : public DummyGraphicsContext { +class SDLGLGraphicsContext : public GraphicsContext { public: SDLGLGraphicsContext() { } @@ -20,6 +20,11 @@ public: // Do nothing, the render thread takes care of this. } + // Gets forwarded to the render thread. + void SwapInterval(int interval) override; + + void Resize() override {} + Draw::DrawContext *GetDrawContext() override { return draw_; } diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 1b353d8797..44d6f52151 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -338,7 +338,7 @@ void GameSettingsScreen::CreateViews() { return !g_Config.bSoftwareRendering && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; }); -#ifdef __ANDROID__ +#if PPSSPP_PLATFORM(ANDROID) if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) != DEVICE_TYPE_TV) { static const char *deviceResolutions[] = { "Native device resolution", "Auto (same as Rendering)", "1x PSP", "2x PSP", "3x PSP", "4x PSP", "5x PSP" }; int max_res_temp = std::max(System_GetPropertyInt(SYSPROP_DISPLAY_XRES), System_GetPropertyInt(SYSPROP_DISPLAY_YRES)) / 480 + 2; @@ -350,7 +350,7 @@ void GameSettingsScreen::CreateViews() { } #endif -#if !PPSSPP_PLATFORM(ANDROID) +#if !(PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(IOS) CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync"))); vSync->OnClick.Add([=](EventParams &e) { NativeResized(); diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index bc2eece379..e25535816f 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -297,7 +297,6 @@ public: OpenGLPipeline(GLRenderManager *render) : render_(render) { } ~OpenGLPipeline() { - DLOG("OpenGLPipeline released"); for (auto &iter : shaders) { iter->Release(); } @@ -979,7 +978,6 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { pipeline->dynamicUniforms = *desc.uniformDesc; pipeline->dynamicUniformLocs_.resize(desc.uniformDesc->uniforms.size()); } - ILOG("Linking shaders."); if (pipeline->LinkShaders()) { // Build the rest of the virtual pipeline object. pipeline->prim = primToGL[(int)desc.prim]; diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index d0e5757fff..b45b50724d 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -53,7 +53,7 @@ SDL_Window *CreateHiddenWindow() { return SDL_CreateWindow("PPSSPPHeadless", 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, flags); } -class GLDummyGraphicsContext : public DummyGraphicsContext { +class GLDummyGraphicsContext : public GraphicsContext { public: GLDummyGraphicsContext() { } @@ -92,6 +92,11 @@ public: renderManager_->StopThread(); } + void Shutdown() override {} + void Resize() override {} + void SwapInterval(int interval) override {} + void SwapBuffers() override {} + private: Draw::DrawContext *draw_; GLRenderManager *renderManager_ = nullptr; @@ -124,7 +129,7 @@ bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) { glContext_ = SDL_GL_CreateContext(screen_); // Ensure that the swap interval is set after context creation (needed for kmsdrm) - SDL_GL_SetSwapInterval(1); + SDL_GL_SetSwapInterval(0); #ifndef USING_GLES2 // Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc. diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 73fd05c7fd..d36ae51b07 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -38,7 +38,7 @@ #define IS_IPAD() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) #define IS_IPHONE() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) -class IOSGraphicsContext : public DummyGraphicsContext { +class IOSGraphicsContext : public GraphicsContext { public: IOSGraphicsContext() { CheckGLExtensions(); @@ -55,6 +55,12 @@ public: Draw::DrawContext *GetDrawContext() override { return draw_; } + + void SwapInterval(int interval) override {} + void SwapBuffers() override {} + void Resize() override {} + void Shutdown() override {} + void ThreadStart() override { renderManager_->ThreadStart(draw_); } @@ -71,6 +77,7 @@ public: renderManager_->WaitUntilQueueIdle(); renderManager_->StopThread(); } + private: Draw::DrawContext *draw_; GLRenderManager *renderManager_; From 4ef63843d2fb865d683e7c958805d6337d1aa0f5 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 May 2020 14:57:18 -0700 Subject: [PATCH 288/848] Display: Allow unthrottle to skip only flipping. Before, it either flipped continuously, or forced frameskip on. This makes it so you can still draw frames, but skip actual flips. This is useful when games draw things only in a single frame and reuse later. It's also useful when measuring speed improvements if you already get 100% speed on a device. --- Core/Config.cpp | 30 ++++++++++++++++++++++++++---- Core/Config.h | 2 +- Core/ConfigValues.h | 6 ++++++ Core/HLE/sceDisplay.cpp | 19 ++++++++++++++++--- headless/Headless.cpp | 2 +- libretro/libretro.cpp | 2 +- 6 files changed, 51 insertions(+), 10 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 84e8bcf01e..94a52cf781 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -529,11 +529,11 @@ static int DefaultInternalResolution() { #endif } -static bool DefaultFrameskipUnthrottle() { +static int DefaultUnthrottleMode() { #if PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS) - return true; + return (int)UnthrottleMode::SKIP_DRAW; #else - return false; + return (int)UnthrottleMode::CONTINUOUS; #endif } @@ -705,6 +705,28 @@ struct ConfigTranslator { typedef ConfigTranslator GPUBackendTranslator; +static int UnthrottleModeFromString(const std::string &s) { + if (!strcasecmp(s.c_str(), "CONTINUOUS")) + return (int)UnthrottleMode::CONTINUOUS; + if (!strcasecmp(s.c_str(), "SKIP_DRAW")) + return (int)UnthrottleMode::SKIP_DRAW; + if (!strcasecmp(s.c_str(), "SKIP_FLIP")) + return (int)UnthrottleMode::SKIP_FLIP; + return DefaultUnthrottleMode(); +} + +std::string UnthrottleModeToString(int v) { + switch (UnthrottleMode(v)) { + case UnthrottleMode::CONTINUOUS: + return "CONTINUOUS"; + case UnthrottleMode::SKIP_DRAW: + return "SKIP_DRAW"; + case UnthrottleMode::SKIP_FLIP: + return "SKIP_FLIP"; + } + return "CONTINUOUS"; +} + static ConfigSetting graphicsSettings[] = { ConfigSetting("EnableCardboardVR", &g_Config.bEnableCardboardVR, false, true, true), ConfigSetting("CardboardScreenSize", &g_Config.iCardboardScreenSize, 50, true, true), @@ -734,7 +756,7 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("AutoFrameSkip", &g_Config.bAutoFrameSkip, false, true, true), ConfigSetting("FrameRate", &g_Config.iFpsLimit1, 0, true, true), ConfigSetting("FrameRate2", &g_Config.iFpsLimit2, -1, true, true), - ConfigSetting("FrameSkipUnthrottle", &g_Config.bFrameSkipUnthrottle, &DefaultFrameskipUnthrottle, true, false), + ConfigSetting("UnthrottleMode", &g_Config.iUnthrottleMode, &DefaultUnthrottleMode, &UnthrottleModeToString, &UnthrottleModeFromString, true, true), #if defined(USING_WIN_UI) ConfigSetting("RestartRequired", &g_Config.bRestartRequired, false, false), #endif diff --git a/Core/Config.h b/Core/Config.h index 1843823047..d858b85804 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -161,8 +161,8 @@ public: bool bVSync; int iFrameSkip; int iFrameSkipType; + int iUnthrottleMode; // See UnthrottleMode in ConfigValues.h. bool bAutoFrameSkip; - bool bFrameSkipUnthrottle; bool bEnableCardboardVR; // Cardboard Master Switch int iCardboardScreenSize; // Screen Size (in %) diff --git a/Core/ConfigValues.h b/Core/ConfigValues.h index 89c8598112..8936f63809 100644 --- a/Core/ConfigValues.h +++ b/Core/ConfigValues.h @@ -110,3 +110,9 @@ enum class AutoLoadSaveState { OLDEST = 1, NEWEST = 2, }; + +enum class UnthrottleMode { + CONTINUOUS = 0, + SKIP_DRAW = 1, + SKIP_FLIP = 2, +}; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 176cfdd5f8..12c069ab0e 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -561,7 +561,7 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { // we have nothing to do here. bool doFrameSkip = g_Config.iFrameSkip != 0; - bool unthrottleNeedsSkip = g_Config.bFrameSkipUnthrottle; + bool unthrottleNeedsSkip = g_Config.iUnthrottleMode == (int)UnthrottleMode::SKIP_DRAW; if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) { // Vulkan doesn't support the interval setting, so we force frameskip. unthrottleNeedsSkip = true; @@ -758,7 +758,7 @@ void __DisplayFlip(int cyclesLate) { bool duplicateFrames = g_Config.bRenderDuplicateFrames && g_Config.iFrameSkip == 0; - bool unthrottleNeedsSkip = g_Config.bFrameSkipUnthrottle; + bool unthrottleNeedsSkip = g_Config.iUnthrottleMode != (int)UnthrottleMode::CONTINUOUS; if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) { // Vulkan doesn't support the interval setting, so we force frameskip. unthrottleNeedsSkip = true; @@ -794,11 +794,24 @@ void __DisplayFlip(int cyclesLate) { hasNotifiedSlow = true; } + bool forceNoFlip = false; + // Alternative to frameskip unthrottle, where we draw everything. + // Useful if skipping a frame breaks graphics or for checking drawing speed. + if (g_Config.iUnthrottleMode == (int)UnthrottleMode::SKIP_FLIP && !FrameTimingThrottled()) { + static double lastFlip = 0; + double now = time_now_d(); + if ((now - lastFlip) < 1.0f / System_GetPropertyFloat(SYSPROP_DISPLAY_REFRESH_RATE)) { + forceNoFlip = true; + } else { + lastFlip = now; + } + } + // Setting CORE_NEXTFRAME causes a swap. const bool fbReallyDirty = gpu->FramebufferReallyDirty(); if (fbReallyDirty || noRecentFlip || postEffectRequiresFlip) { // Check first though, might've just quit / been paused. - if (Core_NextFrame()) { + if (!forceNoFlip && Core_NextFrame()) { gpu->CopyDisplayToOutput(fbReallyDirty); if (fbReallyDirty) { actualFlips++; diff --git a/headless/Headless.cpp b/headless/Headless.cpp index ef43d5ba85..8246a7df43 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -382,7 +382,7 @@ int main(int argc, const char* argv[]) g_Config.iButtonPreference = PSP_SYSTEMPARAM_BUTTON_CROSS; g_Config.iLockParentalLevel = 9; g_Config.iInternalResolution = 1; - g_Config.bFrameSkipUnthrottle = false; + g_Config.iUnthrottleMode = (int)UnthrottleMode::CONTINUOUS; g_Config.bEnableLogging = fullLog; g_Config.iNumWorkerThreads = 1; g_Config.bSoftwareSkinning = true; diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index e5566a7e99..4e2a6bf07d 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -342,7 +342,7 @@ void retro_init(void) #endif g_Config.bEnableLogging = true; - g_Config.bFrameSkipUnthrottle = false; + g_Config.iUnthrottleMode = (int)UnthrottleMode::CONTINUOUS; g_Config.bMemStickInserted = PSP_MEMORYSTICK_STATE_INSERTED; g_Config.iGlobalVolume = VOLUME_MAX - 1; g_Config.iAltSpeedVolume = -1; From 033c764378a8aeac8614f3e9027e260848b53059 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 16 Jul 2020 19:44:34 -0700 Subject: [PATCH 289/848] EditorConfig: Separate indent style for libretro. Three spaces is weird, but better to be consistent and have the config specify what's being used. --- .editorconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.editorconfig b/.editorconfig index c379dffa45..965fbcf1ee 100644 --- a/.editorconfig +++ b/.editorconfig @@ -28,3 +28,7 @@ charset = utf-8-bom [Windows/{aboutbox.rc,version.rc}] charset = utf-16le + +[libretro/**.{cpp,h}] +indent_style = space +indent_size = 3 From dae9df38295f6034b416a0b62d74c6c414e67b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Jul 2020 17:22:33 +0200 Subject: [PATCH 290/848] Fix a bug in crashhandler where we could end up disassembling far too much. --- Common/x64Analyzer.cpp | 8 ++++++-- Common/x64Analyzer.h | 1 + Core/MIPS/JitCommon/JitCommon.cpp | 7 ++++++- Core/MemFault.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Common/x64Analyzer.cpp b/Common/x64Analyzer.cpp index 0d04346c04..1a9d236db6 100644 --- a/Common/x64Analyzer.cpp +++ b/Common/x64Analyzer.cpp @@ -15,7 +15,8 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "x64Analyzer.h" +#include "Common/Log.h" +#include "Common/x64Analyzer.h" bool X86AnalyzeMOV(const unsigned char *codePtr, LSInstructionInfo &info) { @@ -183,8 +184,11 @@ bool X86AnalyzeMOV(const unsigned char *codePtr, LSInstructionInfo &info) case MOVE_REG_TO_MEM: //move reg to memory break; + case MOVE_MEM_TO_REG: + break; + default: - PanicAlert("Unhandled disasm case in write handler!\n\nPlease implement or avoid."); + ERROR_LOG(CPU, "Unhandled disasm case in write handler!\n\nPlease implement or avoid."); return false; } } diff --git a/Common/x64Analyzer.h b/Common/x64Analyzer.h index 8ba78005e5..f9a35e785c 100644 --- a/Common/x64Analyzer.h +++ b/Common/x64Analyzer.h @@ -53,6 +53,7 @@ enum { MOVE_8BIT = 0xC6, //move 8-bit immediate MOVE_16_32BIT = 0xC7, //move 16 or 32-bit immediate MOVE_REG_TO_MEM = 0x89, //move reg to memory + MOVE_MEM_TO_REG = 0x8B, //move memory to reg }; enum AccessType { diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index baf26f6bcc..697733ec1d 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -246,7 +246,12 @@ std::vector DisassembleX86(const u8 *data, int size) { int int3_count = 0; while (ud_disassemble(&ud_obj) != 0) { - std::string str = ud_insn_asm(&ud_obj); + const char *buf = ud_insn_asm(&ud_obj); + if (!buf) { + lines.push_back("[bad]"); + continue; + } + std::string str = buf; if (str == "int3") { int3_count++; } else { diff --git a/Core/MemFault.cpp b/Core/MemFault.cpp index 104be4af59..5e8748a333 100644 --- a/Core/MemFault.cpp +++ b/Core/MemFault.cpp @@ -114,25 +114,25 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { // X86, X86-64. Variable instruction size so need to analyze the mov instruction in detail. // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC - LSInstructionInfo info; + LSInstructionInfo info{}; success = X86AnalyzeMOV(codePtr, info); instructionSize = info.instructionSize; #elif PPSSPP_ARCH(ARM64) uint32_t word; memcpy(&word, codePtr, 4); // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC - Arm64LSInstructionInfo info; + Arm64LSInstructionInfo info{}; success = Arm64AnalyzeLoadStore((uint64_t)codePtr, word, &info); #elif PPSSPP_ARCH(ARM) uint32_t word; memcpy(&word, codePtr, 4); // To ignore the access, we need to disassemble the instruction and modify context->CTX_PC - ArmLSInstructionInfo info; + ArmLSInstructionInfo info{}; success = ArmAnalyzeLoadStore((uint32_t)codePtr, word, &info); #endif std::string disassembly; - if (DisassembleNativeAt(codePtr, instructionSize, &disassembly)) { + if (success && DisassembleNativeAt(codePtr, instructionSize, &disassembly)) { infoString += disassembly + "\n"; } From c5e0b799d9197e56f49a9531d64dd97f6d8f6261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Jul 2020 17:47:02 +0200 Subject: [PATCH 291/848] Remove category from _assert_msg_ functions. We don't filter these by category anyway. Fixes the inconsistency where we _assert_ didn't take a category but _assert_msg_ did. --- Common/Arm64Emitter.cpp | 192 +++---- Common/Arm64Emitter.h | 4 +- Common/ArmEmitter.cpp | 636 ++++++++++----------- Common/ArmEmitter.h | 44 +- Common/ChunkFile.cpp | 10 +- Common/ConsoleListener.cpp | 12 +- Common/Hashmaps.h | 18 +- Common/Log.h | 18 +- Common/MipsEmitter.cpp | 86 +-- Common/Vulkan/VulkanContext.cpp | 4 +- Common/Vulkan/VulkanImage.cpp | 6 +- Common/Vulkan/VulkanMemory.cpp | 26 +- Common/x64Emitter.cpp | 140 +++-- Common/x64Emitter.h | 2 +- Core/Config.cpp | 6 +- Core/CoreTiming.cpp | 4 +- Core/FileLoaders/DiskCachingFileLoader.cpp | 2 +- Core/FileSystems/ISOFileSystem.cpp | 4 +- Core/FileSystems/tlzrc.cpp | 4 +- Core/Font/PGF.cpp | 2 +- Core/HLE/HLE.cpp | 10 +- Core/HLE/ThreadQueueList.h | 8 +- Core/HLE/sceCtrl.cpp | 2 +- Core/HLE/sceKernel.h | 9 +- Core/HLE/sceKernelMbx.cpp | 4 +- Core/HLE/sceKernelMemory.cpp | 26 +- Core/HLE/sceKernelMutex.cpp | 6 +- Core/HLE/sceKernelThread.cpp | 16 +- Core/HLE/sceUmd.cpp | 4 +- Core/MIPS/ARM/ArmCompBranch.cpp | 14 +- Core/MIPS/ARM/ArmCompLoadStore.cpp | 4 +- Core/MIPS/ARM/ArmCompVFPU.cpp | 4 +- Core/MIPS/ARM/ArmCompVFPUNEON.cpp | 6 +- Core/MIPS/ARM/ArmRegCacheFPU.cpp | 2 +- Core/MIPS/ARM64/Arm64CompBranch.cpp | 14 +- Core/MIPS/ARM64/Arm64CompLoadStore.cpp | 4 +- Core/MIPS/ARM64/Arm64CompVFPU.cpp | 6 +- Core/MIPS/ARM64/Arm64RegCache.cpp | 2 +- Core/MIPS/ARM64/Arm64RegCacheFPU.cpp | 2 +- Core/MIPS/IR/IRCompBranch.cpp | 10 +- Core/MIPS/IR/IRJit.cpp | 2 +- Core/MIPS/MIPSInt.cpp | 42 +- Core/MIPS/MIPSIntVFPU.cpp | 44 +- Core/MIPS/MIPSTables.cpp | 2 +- Core/MIPS/MIPSVFPUUtils.cpp | 34 +- Core/MIPS/x86/Asm.cpp | 4 +- Core/MIPS/x86/CompBranch.cpp | 18 +- Core/MIPS/x86/CompFPU.cpp | 4 +- Core/MIPS/x86/CompLoadStore.cpp | 4 +- Core/MIPS/x86/CompVFPU.cpp | 6 +- Core/MIPS/x86/Jit.cpp | 4 +- Core/MIPS/x86/JitSafeMem.cpp | 6 +- Core/MIPS/x86/RegCache.cpp | 13 +- Core/MIPS/x86/RegCacheFPU.cpp | 74 +-- Core/MIPS/x86/RegCacheFPU.h | 8 +- Core/MemMap.cpp | 4 +- Core/Screenshot.cpp | 2 +- Core/TextureReplacer.cpp | 8 +- GPU/Common/DepalettizeShaderCommon.cpp | 2 +- GPU/Common/FramebufferCommon.cpp | 4 +- GPU/Common/FramebufferCommon.h | 4 +- GPU/Common/ShaderId.cpp | 2 +- GPU/Common/TextureCacheCommon.cpp | 4 +- GPU/Common/VertexDecoderArm.cpp | 18 +- GPU/Common/VertexDecoderX86.cpp | 8 +- GPU/D3D11/DrawEngineD3D11.cpp | 2 +- GPU/Debugger/Playback.cpp | 2 +- GPU/Directx9/DrawEngineDX9.cpp | 2 +- GPU/GLES/DrawEngineGLES.cpp | 4 +- GPU/GLES/FramebufferManagerGLES.cpp | 2 +- GPU/GLES/ShaderManagerGLES.cpp | 8 +- GPU/GPUCommon.cpp | 6 +- GPU/Software/Rasterizer.cpp | 6 +- GPU/Software/SamplerX86.cpp | 2 +- GPU/Software/TransformUnit.cpp | 4 +- GPU/Vulkan/DrawEngineVulkan.cpp | 18 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 4 +- GPU/Vulkan/ShaderManagerVulkan.cpp | 12 +- GPU/Vulkan/TextureCacheVulkan.cpp | 4 +- Qt/QtMain.h | 2 +- UI/NativeApp.cpp | 8 +- Windows/GEDebugger/GEDebugger.cpp | 2 +- Windows/GEDebugger/SimpleGLWindow.cpp | 2 +- Windows/GPU/D3D11Context.cpp | 2 +- Windows/GPU/WindowsGLContext.cpp | 2 +- Windows/GPU/WindowsVulkanContext.cpp | 2 +- android/jni/AndroidEGLContext.cpp | 2 +- android/jni/AndroidJavaGLContext.cpp | 2 +- android/jni/AndroidVulkanContext.cpp | 2 +- ext/native/thin3d/GLQueueRunner.cpp | 10 +- ext/native/thin3d/GLRenderManager.cpp | 14 +- ext/native/thin3d/GLRenderManager.h | 72 +-- ext/native/thin3d/VulkanQueueRunner.cpp | 22 +- ext/native/thin3d/VulkanRenderManager.cpp | 66 +-- ext/native/thin3d/VulkanRenderManager.h | 26 +- ext/native/thin3d/thin3d.cpp | 4 +- ext/native/thin3d/thin3d_gl.cpp | 6 +- ext/native/thin3d/thin3d_vulkan.cpp | 4 +- ios/ViewController.mm | 2 +- 99 files changed, 1007 insertions(+), 1015 deletions(-) diff --git a/Common/Arm64Emitter.cpp b/Common/Arm64Emitter.cpp index e3e148a60a..531c2ddb79 100644 --- a/Common/Arm64Emitter.cpp +++ b/Common/Arm64Emitter.cpp @@ -211,7 +211,7 @@ bool IsImmLogical(uint64_t value, unsigned int width, unsigned int *n, unsigned }; int multiplier_idx = CountLeadingZeros(d, kXRegSizeInBits) - 57; // Ensure that the index to the multipliers array is within bounds. - _dbg_assert_(JIT, (multiplier_idx >= 0) && + _dbg_assert_((multiplier_idx >= 0) && (static_cast(multiplier_idx) < ARRAY_SIZE(multipliers))); uint64_t multiplier = multipliers[multiplier_idx]; uint64_t candidate = (b - a) * multiplier; @@ -491,11 +491,11 @@ void ARM64XEmitter::EncodeCompareBranchInst(u32 op, ARM64Reg Rt, const void* ptr bool b64Bit = Is64Bit(Rt); s64 distance = (s64)ptr - (s64)m_code; - _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %llx", __FUNCTION__, distance); + _assert_msg_(!(distance & 0x3), "%s: distance must be a multiple of 4: %llx", __FUNCTION__, distance); distance >>= 2; - _assert_msg_(DYNA_REC, distance >= -0x40000 && distance <= 0x3FFFF, "%s: Received too large distance: %llx", __FUNCTION__, distance); + _assert_msg_(distance >= -0x40000 && distance <= 0x3FFFF, "%s: Received too large distance: %llx", __FUNCTION__, distance); Rt = DecodeReg(Rt); Write32((b64Bit << 31) | (0x34 << 24) | (op << 24) | \ @@ -507,11 +507,11 @@ void ARM64XEmitter::EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const voi bool b64Bit = Is64Bit(Rt); s64 distance = (s64)ptr - (s64)m_code; - _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %llx", __FUNCTION__, distance); + _assert_msg_(!(distance & 0x3), "%s: distance must be a multiple of 4: %llx", __FUNCTION__, distance); distance >>= 2; - _assert_msg_(DYNA_REC, distance >= -0x1FFF && distance < 0x1FFF, "%s: Received too large distance: %llx", __FUNCTION__, distance); + _assert_msg_(distance >= -0x1FFF && distance < 0x1FFF, "%s: Received too large distance: %llx", __FUNCTION__, distance); Rt = DecodeReg(Rt); Write32((b64Bit << 31) | (0x36 << 24) | (op << 24) | \ @@ -522,11 +522,11 @@ void ARM64XEmitter::EncodeUnconditionalBranchInst(u32 op, const void* ptr) { s64 distance = (s64)ptr - s64(m_code); - _assert_msg_(DYNA_REC, !(distance & 0x3), "%s: distance must be a multiple of 4: %llx", __FUNCTION__, distance); + _assert_msg_(!(distance & 0x3), "%s: distance must be a multiple of 4: %llx", __FUNCTION__, distance); distance >>= 2; - _assert_msg_(DYNA_REC, distance >= -0x2000000LL && distance <= 0x1FFFFFFLL, "%s: Received too large distance: %llx", __FUNCTION__, distance); + _assert_msg_(distance >= -0x2000000LL && distance <= 0x1FFFFFFLL, "%s: Received too large distance: %llx", __FUNCTION__, distance); Write32((op << 31) | (0x5 << 26) | (distance & 0x3FFFFFF)); } @@ -539,7 +539,7 @@ void ARM64XEmitter::EncodeUnconditionalBranchInst(u32 opc, u32 op2, u32 op3, u32 void ARM64XEmitter::EncodeExceptionInst(u32 instenc, u32 imm) { - _assert_msg_(DYNA_REC, !(imm & ~0xFFFF), "%s: Exception instruction too large immediate: %d", __FUNCTION__, imm); + _assert_msg_(!(imm & ~0xFFFF), "%s: Exception instruction too large immediate: %d", __FUNCTION__, imm); Write32((0xD4 << 24) | (ExcEnc[instenc][0] << 21) | (imm << 5) | (ExcEnc[instenc][1] << 2) | ExcEnc[instenc][2]); } @@ -575,8 +575,8 @@ void ARM64XEmitter::EncodeCondCompareImmInst(u32 op, ARM64Reg Rn, u32 imm, u32 n { bool b64Bit = Is64Bit(Rn); - _assert_msg_(DYNA_REC, !(imm & ~0x1F), "%s: too large immediate: %d", __FUNCTION__, imm) - _assert_msg_(DYNA_REC, !(nzcv & ~0xF), "%s: Flags out of range: %d", __FUNCTION__, nzcv) + _assert_msg_(!(imm & ~0x1F), "%s: too large immediate: %d", __FUNCTION__, imm) + _assert_msg_(!(nzcv & ~0xF), "%s: Flags out of range: %d", __FUNCTION__, nzcv) Rn = DecodeReg(Rn); Write32((b64Bit << 31) | (op << 30) | (1 << 29) | (0xD2 << 21) | \ @@ -587,7 +587,7 @@ void ARM64XEmitter::EncodeCondCompareRegInst(u32 op, ARM64Reg Rn, ARM64Reg Rm, u { bool b64Bit = Is64Bit(Rm); - _assert_msg_(DYNA_REC, !(nzcv & ~0xF), "%s: Flags out of range: %d", __FUNCTION__, nzcv) + _assert_msg_(!(nzcv & ~0xF), "%s: Flags out of range: %d", __FUNCTION__, nzcv) Rm = DecodeReg(Rm); Rn = DecodeReg(Rn); @@ -659,7 +659,7 @@ void ARM64XEmitter::EncodeLoadRegisterInst(u32 bitop, ARM64Reg Rt, u32 imm) bool b64Bit = Is64Bit(Rt); bool bVec = IsVector(Rt); - _assert_msg_(DYNA_REC, !(imm & 0xFFFFF), "%s: offset too large %d", __FUNCTION__, imm); + _assert_msg_(!(imm & 0xFFFFF), "%s: offset too large %d", __FUNCTION__, imm); Rt = DecodeReg(Rt); if (b64Bit && bitop != 0x2) // LDRSW(0x2) uses 64bit reg, doesn't have 64bit bit set @@ -692,7 +692,7 @@ void ARM64XEmitter::EncodeLoadStorePairedInst(u32 op, ARM64Reg Rt, ARM64Reg Rt2, else imm >>= 2; - _assert_msg_(DYNA_REC, !(imm & ~0xF), "%s: offset too large %d", __FUNCTION__, imm); + _assert_msg_(!(imm & ~0xF), "%s: offset too large %d", __FUNCTION__, imm); u32 opc = 0; if (b128Bit) @@ -715,7 +715,7 @@ void ARM64XEmitter::EncodeLoadStoreIndexedInst(u32 op, u32 op2, ARM64Reg Rt, ARM u32 offset = imm & 0x1FF; - _assert_msg_(DYNA_REC, !(imm < -256 || imm > 255), "%s: offset too large %d", __FUNCTION__, imm); + _assert_msg_(!(imm < -256 || imm > 255), "%s: offset too large %d", __FUNCTION__, imm); Rt = DecodeReg(Rt); Rn = DecodeReg(Rn); @@ -736,12 +736,12 @@ void ARM64XEmitter::EncodeLoadStoreIndexedInst(u32 op, ARM64Reg Rt, ARM64Reg Rn, shift = 1; if (shift) { - _assert_msg_(DYNA_REC, ((imm >> shift) << shift) == imm, "%s(INDEX_UNSIGNED): offset must be aligned %d", __FUNCTION__, imm); + _assert_msg_(((imm >> shift) << shift) == imm, "%s(INDEX_UNSIGNED): offset must be aligned %d", __FUNCTION__, imm); imm >>= shift; } - _assert_msg_(DYNA_REC, imm >= 0, "%s(INDEX_UNSIGNED): offset must be positive %d", __FUNCTION__, imm); - _assert_msg_(DYNA_REC, !(imm & ~0xFFF), "%s(INDEX_UNSIGNED): offset too large %d", __FUNCTION__, imm); + _assert_msg_(imm >= 0, "%s(INDEX_UNSIGNED): offset must be positive %d", __FUNCTION__, imm); + _assert_msg_(!(imm & ~0xFFF), "%s(INDEX_UNSIGNED): offset too large %d", __FUNCTION__, imm); Rt = DecodeReg(Rt); Rn = DecodeReg(Rn); @@ -752,7 +752,7 @@ void ARM64XEmitter::EncodeMOVWideInst(u32 op, ARM64Reg Rd, u32 imm, ShiftAmount { bool b64Bit = Is64Bit(Rd); - _assert_msg_(DYNA_REC, !(imm & ~0xFFFF), "%s: immediate out of range: %d", __FUNCTION__, imm); + _assert_msg_(!(imm & ~0xFFFF), "%s: immediate out of range: %d", __FUNCTION__, imm); Rd = DecodeReg(Rd); Write32((b64Bit << 31) | (op << 29) | (0x25 << 23) | (pos << 21) | (imm << 5) | Rd); @@ -782,7 +782,7 @@ void ARM64XEmitter::EncodeAddSubImmInst(u32 op, bool flags, u32 shift, u32 imm, { bool b64Bit = Is64Bit(Rd); - _assert_msg_(DYNA_REC, !(imm & ~0xFFF), "%s: immediate too large: %x", __FUNCTION__, imm); + _assert_msg_(!(imm & ~0xFFF), "%s: immediate too large: %x", __FUNCTION__, imm); Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -819,7 +819,7 @@ void ARM64XEmitter::EncodeLoadStorePair(u32 op, u32 load, IndexType type, ARM64R type_encode = 3; break; case INDEX_UNSIGNED: - _assert_msg_(DYNA_REC, false, "%s doesn't support INDEX_UNSIGNED!", __FUNCTION__); + _assert_msg_(false, "%s doesn't support INDEX_UNSIGNED!", __FUNCTION__); break; } @@ -832,7 +832,7 @@ void ARM64XEmitter::EncodeLoadStorePair(u32 op, u32 load, IndexType type, ARM64R imm >>= 2; } - _assert_msg_(JIT, imm >= -64 && imm <= 63, "%s recieved too large imm: %d", __FUNCTION__, imm); + _assert_msg_(imm >= -64 && imm <= 63, "%s recieved too large imm: %d", __FUNCTION__, imm); Rt = DecodeReg(Rt); Rt2 = DecodeReg(Rt2); @@ -851,7 +851,7 @@ void ARM64XEmitter::EncodeAddressInst(u32 op, ARM64Reg Rd, s32 imm) void ARM64XEmitter::EncodeLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm) { - _assert_msg_(DYNA_REC, !(imm < -256 || imm > 255), "%s received too large offset: %d", __FUNCTION__, imm); + _assert_msg_(!(imm < -256 || imm > 255), "%s received too large offset: %d", __FUNCTION__, imm); Rt = DecodeReg(Rt); Rn = DecodeReg(Rn); @@ -896,31 +896,31 @@ void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch) Not = true; case 0: // CBZ { - _assert_msg_(DYNA_REC, IsInRangeImm19(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); + _assert_msg_(IsInRangeImm19(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); bool b64Bit = Is64Bit(branch.reg); ARM64Reg reg = DecodeReg(branch.reg); inst = (b64Bit << 31) | (0x1A << 25) | (Not << 24) | (MaskImm19(distance) << 5) | reg; } break; case 2: // B (conditional) - _assert_msg_(DYNA_REC, IsInRangeImm19(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); + _assert_msg_(IsInRangeImm19(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); inst = (0x2A << 25) | (MaskImm19(distance) << 5) | branch.cond; break; case 4: // TBNZ Not = true; case 3: // TBZ { - _assert_msg_(DYNA_REC, IsInRangeImm14(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); + _assert_msg_(IsInRangeImm14(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); ARM64Reg reg = DecodeReg(branch.reg); inst = ((branch.bit & 0x20) << 26) | (0x1B << 25) | (Not << 24) | ((branch.bit & 0x1F) << 19) | (MaskImm14(distance) << 5) | reg; } break; case 5: // B (unconditional) - _assert_msg_(DYNA_REC, IsInRangeImm26(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); + _assert_msg_(IsInRangeImm26(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); inst = (0x5 << 26) | MaskImm26(distance); break; case 6: // BL (unconditional) - _assert_msg_(DYNA_REC, IsInRangeImm26(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); + _assert_msg_(IsInRangeImm26(distance), "%s(%d): Received too large distance: %llx", __FUNCTION__, branch.type, distance); inst = (0x25 << 26) | MaskImm26(distance); break; } @@ -1010,7 +1010,7 @@ void ARM64XEmitter::B(CCFlags cond, const void* ptr) distance >>= 2; - _assert_msg_(DYNA_REC, IsInRangeImm19(distance), "%s: Received too large distance: %p->%p %lld %llx", __FUNCTION__, m_code, ptr, distance, distance); + _assert_msg_(IsInRangeImm19(distance), "%s: Received too large distance: %p->%p %lld %llx", __FUNCTION__, m_code, ptr, distance, distance); Write32((0x54 << 24) | (MaskImm19(distance) << 5) | cond); } @@ -1119,7 +1119,7 @@ void ARM64XEmitter::_MSR(PStateField field, u8 imm) case FIELD_DAIFSet: op1 = 3; op2 = 6; break; case FIELD_DAIFClr: op1 = 3; op2 = 7; break; default: - _assert_msg_(JIT, false, "Invalid PStateField to do a imm move to"); + _assert_msg_(false, "Invalid PStateField to do a imm move to"); break; } EncodeSystemInst(0, op1, 4, imm, op2, WSP); @@ -1137,21 +1137,21 @@ static void GetSystemReg(PStateField field, int &o0, int &op1, int &CRn, int &CR o0 = 3; op1 = 3; CRn = 4; CRm = 4; op2 = 1; break; default: - _assert_msg_(JIT, false, "Invalid PStateField to do a register move from/to"); + _assert_msg_(false, "Invalid PStateField to do a register move from/to"); break; } } void ARM64XEmitter::_MSR(PStateField field, ARM64Reg Rt) { int o0 = 0, op1 = 0, CRn = 0, CRm = 0, op2 = 0; - _assert_msg_(JIT, Is64Bit(Rt), "MSR: Rt must be 64-bit"); + _assert_msg_(Is64Bit(Rt), "MSR: Rt must be 64-bit"); GetSystemReg(field, o0, op1, CRn, CRm, op2); EncodeSystemInst(o0, op1, CRn, CRm, op2, DecodeReg(Rt)); } void ARM64XEmitter::MRS(ARM64Reg Rt, PStateField field) { int o0 = 0, op1 = 0, CRn = 0, CRm = 0, op2 = 0; - _assert_msg_(JIT, Is64Bit(Rt), "MRS: Rt must be 64-bit"); + _assert_msg_(Is64Bit(Rt), "MRS: Rt must be 64-bit"); GetSystemReg(field, o0, op1, CRn, CRm, op2); EncodeSystemInst(o0 | 4, op1, CRn, CRm, op2, DecodeReg(Rt)); } @@ -1475,7 +1475,7 @@ void ARM64XEmitter::MOV(ARM64Reg Rd, ARM64Reg Rm) if (IsGPR(Rd) && IsGPR(Rm)) { ORR(Rd, Is64Bit(Rd) ? ZR : WZR, Rm, ArithOption(Rm, ST_LSL, 0)); } else { - _assert_msg_(JIT, false, "Non-GPRs not supported in MOV"); + _assert_msg_(false, "Non-GPRs not supported in MOV"); } } @@ -1587,14 +1587,14 @@ void ARM64XEmitter::UBFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms) void ARM64XEmitter::BFI(ARM64Reg Rd, ARM64Reg Rn, u32 lsb, u32 width) { u32 size = Is64Bit(Rn) ? 64 : 32; - _assert_msg_(DYNA_REC, (lsb + width) <= size, "%s passed lsb %d and width %d which is greater than the register size!", + _assert_msg_((lsb + width) <= size, "%s passed lsb %d and width %d which is greater than the register size!", __FUNCTION__, lsb, width); EncodeBitfieldMOVInst(1, Rd, Rn, (size - lsb) % size, width - 1); } void ARM64XEmitter::UBFIZ(ARM64Reg Rd, ARM64Reg Rn, u32 lsb, u32 width) { u32 size = Is64Bit(Rn) ? 64 : 32; - _assert_msg_(DYNA_REC, (lsb + width) <= size, "%s passed lsb %d and width %d which is greater than the register size!", + _assert_msg_((lsb + width) <= size, "%s passed lsb %d and width %d which is greater than the register size!", __FUNCTION__, lsb, width); EncodeBitfieldMOVInst(2, Rd, Rn, (size - lsb) % size, width - 1); } @@ -1616,7 +1616,7 @@ void ARM64XEmitter::SXTH(ARM64Reg Rd, ARM64Reg Rn) } void ARM64XEmitter::SXTW(ARM64Reg Rd, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, Is64Bit(Rd), "%s requires 64bit register as destination", __FUNCTION__); + _assert_msg_(Is64Bit(Rd), "%s requires 64bit register as destination", __FUNCTION__); SBFM(Rd, Rn, 0, 31); } void ARM64XEmitter::UXTB(ARM64Reg Rd, ARM64Reg Rn) @@ -1912,7 +1912,7 @@ void ARM64XEmitter::LDUR(ARM64Reg Rt, ARM64Reg Rn, s32 imm) } void ARM64XEmitter::LDURSW(ARM64Reg Rt, ARM64Reg Rn, s32 imm) { - _assert_msg_(DYNA_REC, !Is64Bit(Rt), "%s must have a 64bit destination register!", __FUNCTION__); + _assert_msg_(!Is64Bit(Rt), "%s must have a 64bit destination register!", __FUNCTION__); EncodeLoadStoreUnscaled(2, 2, Rt, Rn, imm); } @@ -2067,8 +2067,8 @@ void ARM64FloatEmitter::EmitLoadStoreImmediate(u8 size, u32 opc, IndexType type, if (type == INDEX_UNSIGNED) { - _assert_msg_(DYNA_REC, !(imm & ((size - 1) >> 3)), "%s(INDEX_UNSIGNED) immediate offset must be aligned to size! (%d) (%p)", __FUNCTION__, imm, m_emit->GetCodePointer()); - _assert_msg_(DYNA_REC, imm >= 0, "%s(INDEX_UNSIGNED) immediate offset must be positive!", __FUNCTION__); + _assert_msg_(!(imm & ((size - 1) >> 3)), "%s(INDEX_UNSIGNED) immediate offset must be aligned to size! (%d) (%p)", __FUNCTION__, imm, m_emit->GetCodePointer()); + _assert_msg_(imm >= 0, "%s(INDEX_UNSIGNED) immediate offset must be positive!", __FUNCTION__); if (size == 16) imm >>= 1; else if (size == 32) @@ -2081,7 +2081,7 @@ void ARM64FloatEmitter::EmitLoadStoreImmediate(u8 size, u32 opc, IndexType type, } else { - _assert_msg_(DYNA_REC, !(imm < -256 || imm > 255), "%s immediate offset must be within range of -256 to 255!", __FUNCTION__); + _assert_msg_(!(imm < -256 || imm > 255), "%s immediate offset must be within range of -256 to 255!", __FUNCTION__); encoded_imm = (imm & 0x1FF) << 2; if (type == INDEX_POST) encoded_imm |= 1; @@ -2095,7 +2095,7 @@ void ARM64FloatEmitter::EmitLoadStoreImmediate(u8 size, u32 opc, IndexType type, void ARM64FloatEmitter::EmitScalar2Source(bool M, bool S, u32 type, u32 opcode, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - _assert_msg_(DYNA_REC, !IsQuad(Rd), "%s only supports double and single registers!", __FUNCTION__); + _assert_msg_(!IsQuad(Rd), "%s only supports double and single registers!", __FUNCTION__); Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); Rm = DecodeReg(Rm); @@ -2106,7 +2106,7 @@ void ARM64FloatEmitter::EmitScalar2Source(bool M, bool S, u32 type, u32 opcode, void ARM64FloatEmitter::EmitThreeSame(bool U, u32 size, u32 opcode, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - _assert_msg_(DYNA_REC, !IsSingle(Rd), "%s doesn't support singles!", __FUNCTION__); + _assert_msg_(!IsSingle(Rd), "%s doesn't support singles!", __FUNCTION__); bool quad = IsQuad(Rd); Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -2127,7 +2127,7 @@ void ARM64FloatEmitter::EmitCopy(bool Q, u32 op, u32 imm5, u32 imm4, ARM64Reg Rd void ARM64FloatEmitter::Emit2RegMisc(bool Q, bool U, u32 size, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, !IsSingle(Rd), "%s doesn't support singles!", __FUNCTION__); + _assert_msg_(!IsSingle(Rd), "%s doesn't support singles!", __FUNCTION__); Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -2137,7 +2137,7 @@ void ARM64FloatEmitter::Emit2RegMisc(bool Q, bool U, u32 size, u32 opcode, ARM64 void ARM64FloatEmitter::EmitLoadStoreSingleStructure(bool L, bool R, u32 opcode, bool S, u32 size, ARM64Reg Rt, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, !IsSingle(Rt), "%s doesn't support singles!", __FUNCTION__); + _assert_msg_(!IsSingle(Rt), "%s doesn't support singles!", __FUNCTION__); bool quad = IsQuad(Rt); Rt = DecodeReg(Rt); Rn = DecodeReg(Rn); @@ -2148,7 +2148,7 @@ void ARM64FloatEmitter::EmitLoadStoreSingleStructure(bool L, bool R, u32 opcode, void ARM64FloatEmitter::EmitLoadStoreSingleStructure(bool L, bool R, u32 opcode, bool S, u32 size, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm) { - _assert_msg_(DYNA_REC, !IsSingle(Rt), "%s doesn't support singles!", __FUNCTION__); + _assert_msg_(!IsSingle(Rt), "%s doesn't support singles!", __FUNCTION__); bool quad = IsQuad(Rt); Rt = DecodeReg(Rt); Rn = DecodeReg(Rn); @@ -2160,7 +2160,7 @@ void ARM64FloatEmitter::EmitLoadStoreSingleStructure(bool L, bool R, u32 opcode, void ARM64FloatEmitter::Emit1Source(bool M, bool S, u32 type, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, !IsQuad(Rd), "%s doesn't support vector!", __FUNCTION__); + _assert_msg_(!IsQuad(Rd), "%s doesn't support vector!", __FUNCTION__); Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -2170,7 +2170,7 @@ void ARM64FloatEmitter::Emit1Source(bool M, bool S, u32 type, u32 opcode, ARM64R void ARM64FloatEmitter::EmitConversion(bool sf, bool S, u32 type, u32 rmode, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, Rn <= SP, "%s only supports GPR as source!", __FUNCTION__); + _assert_msg_(Rn <= SP, "%s only supports GPR as source!", __FUNCTION__); Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -2180,7 +2180,7 @@ void ARM64FloatEmitter::EmitConversion(bool sf, bool S, u32 type, u32 rmode, u32 void ARM64FloatEmitter::EmitConvertScalarToInt(ARM64Reg Rd, ARM64Reg Rn, RoundingMode round, bool sign) { - _dbg_assert_msg_(JIT, IsScalar(Rn), "fcvts: Rn must be floating point"); + _dbg_assert_msg_(IsScalar(Rn), "fcvts: Rn must be floating point"); if (IsGPR(Rd)) { // Use the encoding that transfers the result to a GPR. bool sf = Is64Bit(Rd); @@ -2235,7 +2235,7 @@ void ARM64FloatEmitter::EmitConversion2(bool sf, bool S, bool direction, u32 typ void ARM64FloatEmitter::EmitCompare(bool M, bool S, u32 op, u32 opcode2, ARM64Reg Rn, ARM64Reg Rm) { - _assert_msg_(DYNA_REC, !IsQuad(Rn), "%s doesn't support vector!", __FUNCTION__); + _assert_msg_(!IsQuad(Rn), "%s doesn't support vector!", __FUNCTION__); bool is_double = IsDouble(Rn); Rn = DecodeReg(Rn); @@ -2247,7 +2247,7 @@ void ARM64FloatEmitter::EmitCompare(bool M, bool S, u32 op, u32 opcode2, ARM64Re void ARM64FloatEmitter::EmitCondSelect(bool M, bool S, CCFlags cond, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - _assert_msg_(DYNA_REC, !IsQuad(Rd), "%s doesn't support vector!", __FUNCTION__); + _assert_msg_(!IsQuad(Rd), "%s doesn't support vector!", __FUNCTION__); bool is_double = IsDouble(Rd); Rd = DecodeReg(Rd); @@ -2260,7 +2260,7 @@ void ARM64FloatEmitter::EmitCondSelect(bool M, bool S, CCFlags cond, ARM64Reg Rd void ARM64FloatEmitter::EmitPermute(u32 size, u32 op, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - _assert_msg_(DYNA_REC, !IsSingle(Rd), "%s doesn't support singles!", __FUNCTION__); + _assert_msg_(!IsSingle(Rd), "%s doesn't support singles!", __FUNCTION__); bool quad = IsQuad(Rd); @@ -2282,7 +2282,7 @@ void ARM64FloatEmitter::EmitPermute(u32 size, u32 op, ARM64Reg Rd, ARM64Reg Rn, void ARM64FloatEmitter::EmitScalarImm(bool M, bool S, u32 type, u32 imm5, ARM64Reg Rd, u32 imm8) { - _assert_msg_(DYNA_REC, !IsQuad(Rd), "%s doesn't support vector!", __FUNCTION__); + _assert_msg_(!IsQuad(Rd), "%s doesn't support vector!", __FUNCTION__); bool is_double = !IsSingle(Rd); @@ -2294,7 +2294,7 @@ void ARM64FloatEmitter::EmitScalarImm(bool M, bool S, u32 type, u32 imm5, ARM64R void ARM64FloatEmitter::EmitShiftImm(bool Q, bool U, u32 immh, u32 immb, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, immh, "%s bad encoding! Can't have zero immh", __FUNCTION__); + _assert_msg_(immh, "%s bad encoding! Can't have zero immh", __FUNCTION__); Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -2352,7 +2352,7 @@ void ARM64FloatEmitter::EmitLoadStoreMultipleStructurePost(u32 size, bool L, u32 void ARM64FloatEmitter::EmitScalar1Source(bool M, bool S, u32 type, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, !IsQuad(Rd), "%s doesn't support vector!", __FUNCTION__); + _assert_msg_(!IsQuad(Rd), "%s doesn't support vector!", __FUNCTION__); Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -2375,7 +2375,7 @@ void ARM64FloatEmitter::EmitVectorxElement(bool U, u32 size, bool L, u32 opcode, void ARM64FloatEmitter::EmitLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm) { - _assert_msg_(DYNA_REC, !(imm < -256 || imm > 255), "%s received too large offset: %d", __FUNCTION__, imm); + _assert_msg_(!(imm < -256 || imm > 255), "%s received too large offset: %d", __FUNCTION__, imm); Rt = DecodeReg(Rt); Rn = DecodeReg(Rn); @@ -2399,25 +2399,25 @@ void ARM64FloatEmitter::EncodeLoadStorePair(u32 size, bool load, IndexType type, type_encode = 3; break; case INDEX_UNSIGNED: - _assert_msg_(DYNA_REC, false, "%s doesn't support INDEX_UNSIGNED!", __FUNCTION__); + _assert_msg_(false, "%s doesn't support INDEX_UNSIGNED!", __FUNCTION__); break; } if (size == 128) { - _assert_msg_(DYNA_REC, !(imm & 0xF), "%s received invalid offset 0x%x!", __FUNCTION__, imm); + _assert_msg_(!(imm & 0xF), "%s received invalid offset 0x%x!", __FUNCTION__, imm); opc = 2; imm >>= 4; } else if (size == 64) { - _assert_msg_(DYNA_REC, !(imm & 0x7), "%s received invalid offset 0x%x!", __FUNCTION__, imm); + _assert_msg_(!(imm & 0x7), "%s received invalid offset 0x%x!", __FUNCTION__, imm); opc = 1; imm >>= 3; } else if (size == 32) { - _assert_msg_(DYNA_REC, !(imm & 0x3), "%s received invalid offset 0x%x!", __FUNCTION__, imm); + _assert_msg_(!(imm & 0x3), "%s received invalid offset 0x%x!", __FUNCTION__, imm); opc = 0; imm >>= 2; } @@ -2433,7 +2433,7 @@ void ARM64FloatEmitter::EncodeLoadStorePair(u32 size, bool load, IndexType type, void ARM64FloatEmitter::EncodeLoadStoreRegisterOffset(u32 size, bool load, ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm) { - _assert_msg_(DYNA_REC, Rm.GetType() == ArithOption::TYPE_EXTENDEDREG, "%s must contain an extended reg as Rm!", __FUNCTION__); + _assert_msg_(Rm.GetType() == ArithOption::TYPE_EXTENDEDREG, "%s must contain an extended reg as Rm!", __FUNCTION__); u32 encoded_size = 0; u32 encoded_op = 0; @@ -2786,7 +2786,7 @@ void ARM64FloatEmitter::ST1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn, ARM64Re // Loadstore multiple structure void ARM64FloatEmitter::LD1(u8 size, u8 count, ARM64Reg Rt, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, !(count == 0 || count > 4), "%s must have a count of 1 to 4 registers!", __FUNCTION__); + _assert_msg_(!(count == 0 || count > 4), "%s must have a count of 1 to 4 registers!", __FUNCTION__); u32 opcode = 0; if (count == 1) opcode = 7; @@ -2800,8 +2800,8 @@ void ARM64FloatEmitter::LD1(u8 size, u8 count, ARM64Reg Rt, ARM64Reg Rn) } void ARM64FloatEmitter::LD1(u8 size, u8 count, IndexType type, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm) { - _assert_msg_(DYNA_REC, !(count == 0 || count > 4), "%s must have a count of 1 to 4 registers!", __FUNCTION__); - _assert_msg_(DYNA_REC, type == INDEX_POST, "%s only supports post indexing!", __FUNCTION__); + _assert_msg_(!(count == 0 || count > 4), "%s must have a count of 1 to 4 registers!", __FUNCTION__); + _assert_msg_(type == INDEX_POST, "%s only supports post indexing!", __FUNCTION__); u32 opcode = 0; if (count == 1) @@ -2816,7 +2816,7 @@ void ARM64FloatEmitter::LD1(u8 size, u8 count, IndexType type, ARM64Reg Rt, ARM6 } void ARM64FloatEmitter::ST1(u8 size, u8 count, ARM64Reg Rt, ARM64Reg Rn) { - _assert_msg_(DYNA_REC, !(count == 0 || count > 4), "%s must have a count of 1 to 4 registers!", __FUNCTION__); + _assert_msg_(!(count == 0 || count > 4), "%s must have a count of 1 to 4 registers!", __FUNCTION__); u32 opcode = 0; if (count == 1) opcode = 7; @@ -2830,8 +2830,8 @@ void ARM64FloatEmitter::ST1(u8 size, u8 count, ARM64Reg Rt, ARM64Reg Rn) } void ARM64FloatEmitter::ST1(u8 size, u8 count, IndexType type, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm) { - _assert_msg_(DYNA_REC, !(count == 0 || count > 4), "%s must have a count of 1 to 4 registers!", __FUNCTION__); - _assert_msg_(DYNA_REC, type == INDEX_POST, "%s only supports post indexing!", __FUNCTION__); + _assert_msg_(!(count == 0 || count > 4), "%s must have a count of 1 to 4 registers!", __FUNCTION__); + _assert_msg_(type == INDEX_POST, "%s only supports post indexing!", __FUNCTION__); u32 opcode = 0; if (count == 1) @@ -2851,7 +2851,7 @@ void ARM64FloatEmitter::FMOV(ARM64Reg Rd, ARM64Reg Rn, bool top) if (IsScalar(Rd) && IsScalar(Rn)) { EmitScalar1Source(0, 0, IsDouble(Rd), 0, Rd, Rn); } else { - _assert_msg_(JIT, !IsQuad(Rd) && !IsQuad(Rn), "FMOV can't move to/from quads"); + _assert_msg_(!IsQuad(Rd) && !IsQuad(Rn), "FMOV can't move to/from quads"); int rmode = 0; int opcode = 6; int sf = 0; @@ -2862,7 +2862,7 @@ void ARM64FloatEmitter::FMOV(ARM64Reg Rd, ARM64Reg Rn, bool top) // Scalar single to GPR - defaults are correct } else { // TODO - _assert_msg_(JIT, 0, "FMOV: Unhandled case"); + _assert_msg_(false, "FMOV: Unhandled case"); } Rd = DecodeReg(Rd); Rn = DecodeReg(Rn); @@ -3234,8 +3234,8 @@ void ARM64FloatEmitter::INS(u8 size, ARM64Reg Rd, u8 index1, ARM64Reg Rn, u8 ind void ARM64FloatEmitter::UMOV(u8 size, ARM64Reg Rd, ARM64Reg Rn, u8 index) { bool b64Bit = Is64Bit(Rd); - _assert_msg_(DYNA_REC, Rd < SP, "%s destination must be a GPR!", __FUNCTION__); - _assert_msg_(DYNA_REC, !(b64Bit && size != 64), "%s must have a size of 64 when destination is 64bit!", __FUNCTION__); + _assert_msg_(Rd < SP, "%s destination must be a GPR!", __FUNCTION__); + _assert_msg_(!(b64Bit && size != 64), "%s must have a size of 64 when destination is 64bit!", __FUNCTION__); u32 imm5 = 0; if (size == 8) @@ -3264,8 +3264,8 @@ void ARM64FloatEmitter::UMOV(u8 size, ARM64Reg Rd, ARM64Reg Rn, u8 index) void ARM64FloatEmitter::SMOV(u8 size, ARM64Reg Rd, ARM64Reg Rn, u8 index) { bool b64Bit = Is64Bit(Rd); - _assert_msg_(DYNA_REC, Rd < SP, "%s destination must be a GPR!", __FUNCTION__); - _assert_msg_(DYNA_REC, size != 64, "%s doesn't support 64bit destination. Use UMOV!", __FUNCTION__); + _assert_msg_(Rd < SP, "%s destination must be a GPR!", __FUNCTION__); + _assert_msg_(size != 64, "%s doesn't support 64bit destination. Use UMOV!", __FUNCTION__); u32 imm5 = 0; if (size == 8) @@ -3499,40 +3499,40 @@ static u32 EncodeImmShiftRight(u8 src_size, u32 shift) { void ARM64FloatEmitter::SSHLL(u8 src_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift, bool upper) { - _assert_msg_(DYNA_REC, shift < src_size, "%s shift amount must less than the element size!", __FUNCTION__); + _assert_msg_(shift < src_size, "%s shift amount must less than the element size!", __FUNCTION__); u32 imm = EncodeImmShiftLeft(src_size, shift); EmitShiftImm(upper, 0, imm >> 3, imm & 7, 0x14, Rd, Rn); } void ARM64FloatEmitter::USHLL(u8 src_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift, bool upper) { - _assert_msg_(DYNA_REC, shift < src_size, "%s shift amount must less than the element size!", __FUNCTION__); + _assert_msg_(shift < src_size, "%s shift amount must less than the element size!", __FUNCTION__); u32 imm = EncodeImmShiftLeft(src_size, shift); EmitShiftImm(upper, 1, imm >> 3, imm & 7, 0x14, Rd, Rn); } void ARM64FloatEmitter::SHRN(u8 dest_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift, bool upper) { - _assert_msg_(DYNA_REC, shift > 0, "%s shift amount must be greater than zero!", __FUNCTION__); - _assert_msg_(DYNA_REC, shift <= dest_size, "%s shift amount must less than or equal to the element size!", __FUNCTION__); + _assert_msg_(shift > 0, "%s shift amount must be greater than zero!", __FUNCTION__); + _assert_msg_(shift <= dest_size, "%s shift amount must less than or equal to the element size!", __FUNCTION__); u32 imm = EncodeImmShiftRight(dest_size, shift); EmitShiftImm(upper, 0, imm >> 3, imm & 7, 0x10, Rd, Rn); } void ARM64FloatEmitter::SHL(u8 dest_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift) { - _assert_msg_(DYNA_REC, shift < dest_size, "%s shift amount must less than the element size!", __FUNCTION__); + _assert_msg_(shift < dest_size, "%s shift amount must less than the element size!", __FUNCTION__); u32 imm = EncodeImmShiftLeft(dest_size, shift); EmitShiftImm(IsQuad(Rd), false, imm >> 3, imm & 7, 0xA, Rd, Rn); } void ARM64FloatEmitter::USHR(u8 dest_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift) { - _assert_msg_(DYNA_REC, shift < dest_size, "%s shift amount must less than the element size!", __FUNCTION__); + _assert_msg_(shift < dest_size, "%s shift amount must less than the element size!", __FUNCTION__); u32 imm = EncodeImmShiftRight(dest_size, shift); EmitShiftImm(IsQuad(Rd), true, imm >> 3, imm & 7, 0x0, Rd, Rn); } void ARM64FloatEmitter::SSHR(u8 dest_size, ARM64Reg Rd, ARM64Reg Rn, u32 shift) { - _assert_msg_(DYNA_REC, shift < dest_size, "%s shift amount must less than the element size!", __FUNCTION__); + _assert_msg_(shift < dest_size, "%s shift amount must less than the element size!", __FUNCTION__); u32 imm = EncodeImmShiftRight(dest_size, shift); EmitShiftImm(IsQuad(Rd), false, imm >> 3, imm & 7, 0x0, Rd, Rn); } @@ -3550,7 +3550,7 @@ void ARM64FloatEmitter::UXTL(u8 src_size, ARM64Reg Rd, ARM64Reg Rn, bool upper) // vector x indexed element void ARM64FloatEmitter::FMUL(u8 size, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u8 index) { - _assert_msg_(DYNA_REC, size == 32 || size == 64, "%s only supports 32bit or 64bit size!", __FUNCTION__); + _assert_msg_(size == 32 || size == 64, "%s only supports 32bit or 64bit size!", __FUNCTION__); bool L = false; bool H = false; @@ -3566,7 +3566,7 @@ void ARM64FloatEmitter::FMUL(u8 size, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u8 void ARM64FloatEmitter::FMLA(u8 size, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u8 index) { - _assert_msg_(DYNA_REC, size == 32 || size == 64, "%s only supports 32bit or 64bit size!", __FUNCTION__); + _assert_msg_(size == 32 || size == 64, "%s only supports 32bit or 64bit size!", __FUNCTION__); bool L = false; bool H = false; @@ -3581,7 +3581,7 @@ void ARM64FloatEmitter::FMLA(u8 size, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u8 } void ARM64FloatEmitter::ABI_PushRegisters(uint32_t registers, uint32_t fp_registers) { - _assert_msg_(DYNA_REC, (registers & 0x60000000) == 0, "ABI_PushRegisters: Do not include FP and LR, those are handled non-conditionally"); + _assert_msg_((registers & 0x60000000) == 0, "ABI_PushRegisters: Do not include FP and LR, those are handled non-conditionally"); ARM64Reg gprs[32]{}, fprs[32]{}; int num_gprs = 0, num_fprs = 0; @@ -3676,25 +3676,25 @@ void ARM64XEmitter::ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) if (!Is64Bit(Rn)) imm &= 0xFFFFFFFF; if (!TryANDI2R(Rd, Rn, imm)) { - _assert_msg_(JIT, scratch != INVALID_REG, "ANDI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); + _assert_msg_(scratch != INVALID_REG, "ANDI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); AND(Rd, Rn, scratch); } } void ARM64XEmitter::ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) { - _assert_msg_(JIT, Is64Bit(Rn) || (imm & 0xFFFFFFFF00000000UL) == 0, "ORRI2R - more bits in imm than Rn"); + _assert_msg_(Is64Bit(Rn) || (imm & 0xFFFFFFFF00000000UL) == 0, "ORRI2R - more bits in imm than Rn"); if (!TryORRI2R(Rd, Rn, imm)) { - _assert_msg_(JIT, scratch != INVALID_REG, "ORRI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); + _assert_msg_(scratch != INVALID_REG, "ORRI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); ORR(Rd, Rn, scratch); } } void ARM64XEmitter::EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) { - _assert_msg_(JIT, Is64Bit(Rn) || (imm & 0xFFFFFFFF00000000UL) == 0, "EORI2R - more bits in imm than Rn"); + _assert_msg_(Is64Bit(Rn) || (imm & 0xFFFFFFFF00000000UL) == 0, "EORI2R - more bits in imm than Rn"); if (!TryEORI2R(Rd, Rn, imm)) { - _assert_msg_(JIT, scratch != INVALID_REG, "EORI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); + _assert_msg_(scratch != INVALID_REG, "EORI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); EOR(Rd, Rn, scratch); } @@ -3709,7 +3709,7 @@ void ARM64XEmitter::ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) } else if (imm == 0) { ANDS(Rd, Rn, Is64Bit(Rn) ? ZR : WZR); } else { - _assert_msg_(JIT, scratch != INVALID_REG, "ANDSI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); + _assert_msg_(scratch != INVALID_REG, "ANDSI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); ANDS(Rd, Rn, scratch); } @@ -3717,7 +3717,7 @@ void ARM64XEmitter::ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) void ARM64XEmitter::ADDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) { if (!TryADDI2R(Rd, Rn, imm)) { - _assert_msg_(JIT, scratch != INVALID_REG, "ADDI2R - failed to construct arithmetic immediate value from %08x, need scratch", (u32)imm); + _assert_msg_(scratch != INVALID_REG, "ADDI2R - failed to construct arithmetic immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); ADD(Rd, Rn, scratch); } @@ -3725,7 +3725,7 @@ void ARM64XEmitter::ADDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) void ARM64XEmitter::SUBI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) { if (!TrySUBI2R(Rd, Rn, imm)) { - _assert_msg_(JIT, scratch != INVALID_REG, "SUBI2R - failed to construct arithmetic immediate value from %08x, need scratch", (u32)imm); + _assert_msg_(scratch != INVALID_REG, "SUBI2R - failed to construct arithmetic immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); SUB(Rd, Rn, scratch); } @@ -3733,7 +3733,7 @@ void ARM64XEmitter::SUBI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) void ARM64XEmitter::CMPI2R(ARM64Reg Rn, u64 imm, ARM64Reg scratch) { if (!TryCMPI2R(Rn, imm)) { - _assert_msg_(JIT, scratch != INVALID_REG, "CMPI2R - failed to construct arithmetic immediate value from %08x, need scratch", (u32)imm); + _assert_msg_(scratch != INVALID_REG, "CMPI2R - failed to construct arithmetic immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); CMP(Rn, scratch); } @@ -3807,7 +3807,7 @@ bool ARM64XEmitter::TryANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm) { } } bool ARM64XEmitter::TryORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm) { - _assert_msg_(JIT, Is64Bit(Rn) || (imm & 0xFFFFFFFF00000000UL) == 0, "TryORRI2R - more bits in imm than Rn"); + _assert_msg_(Is64Bit(Rn) || (imm & 0xFFFFFFFF00000000UL) == 0, "TryORRI2R - more bits in imm than Rn"); u32 n, imm_r, imm_s; if (IsImmLogical(imm, Is64Bit(Rn) ? 64 : 32, &n, &imm_s, &imm_r)) { ORR(Rd, Rn, imm_r, imm_s, n != 0); @@ -3822,7 +3822,7 @@ bool ARM64XEmitter::TryORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm) { } } bool ARM64XEmitter::TryEORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm) { - _assert_msg_(JIT, Is64Bit(Rn) || (imm & 0xFFFFFFFF00000000UL) == 0, "TryEORI2R - more bits in imm than Rn"); + _assert_msg_(Is64Bit(Rn) || (imm & 0xFFFFFFFF00000000UL) == 0, "TryEORI2R - more bits in imm than Rn"); u32 n, imm_r, imm_s; if (IsImmLogical(imm, Is64Bit(Rn) ? 64 : 32, &n, &imm_s, &imm_r)) { EOR(Rd, Rn, imm_r, imm_s, n != 0); @@ -3872,7 +3872,7 @@ bool FPImm8FromFloat(float value, uint8_t *immOut) { } void ARM64FloatEmitter::MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch, bool negate) { - _assert_msg_(JIT, !IsDouble(Rd), "MOVI2F does not yet support double precision"); + _assert_msg_(!IsDouble(Rd), "MOVI2F does not yet support double precision"); uint8_t imm8; if (value == 0.0) { if (std::signbit(value)) { @@ -3891,7 +3891,7 @@ void ARM64FloatEmitter::MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch, bool FNEG(Rd, Rd); } } else { - _assert_msg_(JIT, scratch != INVALID_REG, "Failed to find a way to generate FP immediate %f without scratch", value); + _assert_msg_(scratch != INVALID_REG, "Failed to find a way to generate FP immediate %f without scratch", value); u32 ival; if (negate) { value = -value; @@ -3923,7 +3923,7 @@ void ARM64XEmitter::SUBSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) if (IsImmArithmetic(imm, &val, &shift)) { SUBS(Rd, Rn, val, shift); } else { - _assert_msg_(JIT, scratch != INVALID_REG, "SUBSI2R - failed to construct immediate value from %08x, need scratch", (u32)imm); + _assert_msg_(scratch != INVALID_REG, "SUBSI2R - failed to construct immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); SUBS(Rd, Rn, scratch); } diff --git a/Common/Arm64Emitter.h b/Common/Arm64Emitter.h index eb0fe1f1e5..3e5dd0050b 100644 --- a/Common/Arm64Emitter.h +++ b/Common/Arm64Emitter.h @@ -329,7 +329,7 @@ public: (m_shift << 10); break; default: - _dbg_assert_msg_(DYNA_REC, false, "Invalid type in GetData"); + _dbg_assert_msg_(false, "Invalid type in GetData"); break; } return 0; @@ -697,7 +697,7 @@ public: void MOVI2R(ARM64Reg Rd, u64 imm, bool optimize = true); template void MOVP2R(ARM64Reg Rd, P *ptr) { - _assert_msg_(JIT, Is64Bit(Rd), "Can't store pointers in 32-bit registers"); + _assert_msg_(Is64Bit(Rd), "Can't store pointers in 32-bit registers"); MOVI2R(Rd, (uintptr_t)ptr); } diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index dcaab522c5..596fff7aae 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -95,7 +95,7 @@ bool TryMakeOperand2_AllowNegation(s32 imm, Operand2 &op2, bool *negated) Operand2 AssumeMakeOperand2(u32 imm) { Operand2 op2; bool result = TryMakeOperand2(imm, op2); - _dbg_assert_msg_(JIT, result, "Could not make assumed Operand2."); + _dbg_assert_msg_(result, "Could not make assumed Operand2."); if (!result) { // Make double sure that we get it logged. ERROR_LOG(JIT, "Could not make assumed Operand2."); @@ -705,7 +705,7 @@ FixupBranch ARMXEmitter::B_CC(CCFlags Cond) void ARMXEmitter::B_CC(CCFlags Cond, const void *fnptr) { ptrdiff_t distance = (intptr_t)fnptr - ((intptr_t)(code) + 8); - _assert_msg_(JIT, distance > -0x2000000 && distance < 0x2000000, + _assert_msg_(distance > -0x2000000 && distance < 0x2000000, "B_CC out of range (%p calls %p)", code, fnptr); Write32((Cond << 28) | 0x0A000000 | ((distance >> 2) & 0x00FFFFFF)); @@ -723,7 +723,7 @@ FixupBranch ARMXEmitter::BL_CC(CCFlags Cond) void ARMXEmitter::SetJumpTarget(FixupBranch const &branch) { ptrdiff_t distance = ((intptr_t)(code) - 8) - (intptr_t)branch.ptr; - _assert_msg_(JIT, distance > -0x2000000 && distance < 0x2000000, + _assert_msg_(distance > -0x2000000 && distance < 0x2000000, "SetJumpTarget out of range (%p calls %p)", code, branch.ptr); u32 instr = (u32)(branch.condition | ((distance >> 2) & 0x00FFFFFF)); instr |= branch.type == 0 ? /* B */ 0x0A000000 : /* BL */ 0x0B000000; @@ -732,7 +732,7 @@ void ARMXEmitter::SetJumpTarget(FixupBranch const &branch) void ARMXEmitter::B(const void *fnptr) { ptrdiff_t distance = (intptr_t)fnptr - (intptr_t(code) + 8); - _assert_msg_(JIT, distance > -0x2000000 && distance < 0x2000000, + _assert_msg_(distance > -0x2000000 && distance < 0x2000000, "B out of range (%p calls %p)", code, fnptr); Write32(condition | 0x0A000000 | ((distance >> 2) & 0x00FFFFFF)); @@ -754,7 +754,7 @@ bool ARMXEmitter::BLInRange(const void *fnptr) const { void ARMXEmitter::BL(const void *fnptr) { ptrdiff_t distance = (intptr_t)fnptr - (intptr_t(code) + 8); - _assert_msg_(JIT, distance > -0x2000000 && distance < 0x2000000, + _assert_msg_(distance > -0x2000000 && distance < 0x2000000, "BL out of range (%p calls %p)", code, fnptr); Write32(condition | 0x0B000000 | ((distance >> 2) & 0x00FFFFFF)); } @@ -894,7 +894,7 @@ void ARMXEmitter::WriteInstruction (u32 Op, ARMReg Rd, ARMReg Rn, Operand2 Rm, b } } if (op == -1) - _assert_msg_(JIT, false, "%s not yet support %d", InstNames[Op], Rm.GetType()); + _assert_msg_(false, "%s not yet support %d", InstNames[Op], Rm.GetType()); Write32(condition | (op << 21) | (SetFlags ? (1 << 20) : 0) | Rn << 16 | Rd << 12 | Data); } @@ -921,21 +921,21 @@ void ARMXEmitter::LSLS(ARMReg dest, ARMReg src, Operand2 op2) { WriteShiftedData void ARMXEmitter::LSL (ARMReg dest, ARMReg src, ARMReg op2) { WriteShiftedDataOp(1, false, dest, src, op2);} void ARMXEmitter::LSLS(ARMReg dest, ARMReg src, ARMReg op2) { WriteShiftedDataOp(1, true, dest, src, op2);} void ARMXEmitter::LSR (ARMReg dest, ARMReg src, Operand2 op2) { - _assert_msg_(JIT, op2.GetType() != TYPE_IMM || op2.Imm5() != 0, "LSR must have a non-zero shift (use LSL.)"); + _assert_msg_(op2.GetType() != TYPE_IMM || op2.Imm5() != 0, "LSR must have a non-zero shift (use LSL.)"); WriteShiftedDataOp(2, false, dest, src, op2); } void ARMXEmitter::LSRS(ARMReg dest, ARMReg src, Operand2 op2) { - _assert_msg_(JIT, op2.GetType() != TYPE_IMM || op2.Imm5() != 0, "LSRS must have a non-zero shift (use LSLS.)"); + _assert_msg_(op2.GetType() != TYPE_IMM || op2.Imm5() != 0, "LSRS must have a non-zero shift (use LSLS.)"); WriteShiftedDataOp(2, true, dest, src, op2); } void ARMXEmitter::LSR (ARMReg dest, ARMReg src, ARMReg op2) { WriteShiftedDataOp(3, false, dest, src, op2);} void ARMXEmitter::LSRS(ARMReg dest, ARMReg src, ARMReg op2) { WriteShiftedDataOp(3, true, dest, src, op2);} void ARMXEmitter::ASR (ARMReg dest, ARMReg src, Operand2 op2) { - _assert_msg_(JIT, op2.GetType() != TYPE_IMM || op2.Imm5() != 0, "ASR must have a non-zero shift (use LSL.)"); + _assert_msg_(op2.GetType() != TYPE_IMM || op2.Imm5() != 0, "ASR must have a non-zero shift (use LSL.)"); WriteShiftedDataOp(4, false, dest, src, op2); } void ARMXEmitter::ASRS(ARMReg dest, ARMReg src, Operand2 op2) { - _assert_msg_(JIT, op2.GetType() != TYPE_IMM || op2.Imm5() != 0, "ASRS must have a non-zero shift (use LSLS.)"); + _assert_msg_(op2.GetType() != TYPE_IMM || op2.Imm5() != 0, "ASRS must have a non-zero shift (use LSLS.)"); WriteShiftedDataOp(4, true, dest, src, op2); } void ARMXEmitter::ASR (ARMReg dest, ARMReg src, ARMReg op2) { WriteShiftedDataOp(5, false, dest, src, op2);} @@ -990,7 +990,7 @@ void ARMXEmitter::CLZ(ARMReg rd, ARMReg rm) } void ARMXEmitter::PLD(ARMReg rn, int offset, bool forWrite) { - _dbg_assert_msg_(JIT, offset < 0x3ff && offset > -0x3ff, "PLD: Max 12 bits of offset allowed"); + _dbg_assert_msg_(offset < 0x3ff && offset > -0x3ff, "PLD: Max 12 bits of offset allowed"); bool U = offset >= 0; if (offset < 0) offset = -offset; @@ -1060,7 +1060,7 @@ void ARMXEmitter::LDREX(ARMReg dest, ARMReg base) } void ARMXEmitter::STREX(ARMReg result, ARMReg base, ARMReg op) { - _assert_msg_(JIT, (result != base && result != op), "STREX dest can't be other two registers"); + _assert_msg_((result != base && result != op), "STREX dest can't be other two registers"); Write32(condition | (24 << 20) | (base << 16) | (result << 12) | (0xF9 << 4) | op); } void ARMXEmitter::DMB () @@ -1113,7 +1113,7 @@ void ARMXEmitter::WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 Rm, bool R bool SignedLoad = false; if (op == -1) - _assert_msg_(JIT, false, "%s does not support %d", LoadStoreNames[Op], Rm.GetType()); + _assert_msg_(false, "%s does not support %d", LoadStoreNames[Op], Rm.GetType()); switch (Op) { @@ -1205,7 +1205,7 @@ void ARMXEmitter::WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegLi } void ARMXEmitter::WriteVRegStoreOp(u32 op, ARMReg Rn, bool Double, bool WriteBack, ARMReg Vd, u8 numregs) { - _dbg_assert_msg_(JIT, !WriteBack || Rn != R_PC, "VLDM/VSTM cannot use WriteBack with PC (PC is deprecated anyway.)"); + _dbg_assert_msg_(!WriteBack || Rn != R_PC, "VLDM/VSTM cannot use WriteBack with PC (PC is deprecated anyway.)"); Write32(condition | (op << 20) | (WriteBack << 21) | (Rn << 16) | EncodeVd(Vd) | ((0xA | (int)Double) << 8) | (numregs << (int)Double)); } void ARMXEmitter::STMFD(ARMReg dest, bool WriteBack, const int Regnum, ...) @@ -1259,8 +1259,8 @@ void ARMXEmitter::LDMBitmask(ARMReg dest, bool Add, bool Before, bool WriteBack, // NEON Specific void ARMXEmitter::VABD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _assert_msg_(JIT, Vd >= D0, "Pass invalid register to VABD(float)"); - _assert_msg_(JIT, cpu_info.bNEON, "Can't use VABD(float) when CPU doesn't support it"); + _assert_msg_(Vd >= D0, "Pass invalid register to VABD(float)"); + _assert_msg_(cpu_info.bNEON, "Can't use VABD(float) when CPU doesn't support it"); bool register_quad = Vd >= Q0; // Gets encoded as a double register @@ -1274,8 +1274,8 @@ void ARMXEmitter::VABD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VADD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _assert_msg_(JIT, Vd >= D0, "Pass invalid register to VADD(integer)"); - _assert_msg_(JIT, cpu_info.bNEON, "Can't use VADD(integer) when CPU doesn't support it"); + _assert_msg_(Vd >= D0, "Pass invalid register to VADD(integer)"); + _assert_msg_(cpu_info.bNEON, "Can't use VADD(integer) when CPU doesn't support it"); bool register_quad = Vd >= Q0; @@ -1291,8 +1291,8 @@ void ARMXEmitter::VADD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _assert_msg_(JIT, Vd >= Q0, "Pass invalid register to VSUB(integer)"); - _assert_msg_(JIT, cpu_info.bNEON, "Can't use VSUB(integer) when CPU doesn't support it"); + _assert_msg_(Vd >= Q0, "Pass invalid register to VSUB(integer)"); + _assert_msg_(cpu_info.bNEON, "Can't use VSUB(integer) when CPU doesn't support it"); // Gets encoded as a double register Vd = SubBase(Vd); @@ -1399,7 +1399,7 @@ u32 encodedSize(u32 value) else if (value & I_64) return 3; else - _dbg_assert_msg_(JIT, false, "Passed invalid size to integer NEON instruction"); + _dbg_assert_msg_(false, "Passed invalid size to integer NEON instruction"); return 0; } @@ -1444,7 +1444,7 @@ void ARMXEmitter::WriteVFPDataOp(u32 Op, ARMReg Vd, ARMReg Vn, ARMReg Vm) VFPEnc enc = VFPOps[Op][quad_reg]; if (enc.opc1 == -1 && enc.opc2 == -1) - _assert_msg_(JIT, false, "%s does not support %s", VFPOpNames[Op], quad_reg ? "NEON" : "VFP"); + _assert_msg_(false, "%s does not support %s", VFPOpNames[Op], quad_reg ? "NEON" : "VFP"); u32 VdEnc = EncodeVd(Vd); u32 VnEnc = EncodeVn(Vn); u32 VmEnc = EncodeVm(Vm); @@ -1481,25 +1481,25 @@ void ARMXEmitter::VSTMIA(ARMReg ptr, bool WriteBack, ARMReg firstvreg, int numvr void ARMXEmitter::VLDMDB(ARMReg ptr, bool WriteBack, ARMReg firstvreg, int numvregs) { - _dbg_assert_msg_(JIT, WriteBack, "Writeback is required for VLDMDB"); + _dbg_assert_msg_(WriteBack, "Writeback is required for VLDMDB"); WriteVRegStoreOp(0x80 | 0x040 | 0x10 | 1, ptr, firstvreg >= D0, WriteBack, firstvreg, numvregs); } void ARMXEmitter::VSTMDB(ARMReg ptr, bool WriteBack, ARMReg firstvreg, int numvregs) { - _dbg_assert_msg_(JIT, WriteBack, "Writeback is required for VSTMDB"); + _dbg_assert_msg_(WriteBack, "Writeback is required for VSTMDB"); WriteVRegStoreOp(0x80 | 0x040 | 0x10, ptr, firstvreg >= D0, WriteBack, firstvreg, numvregs); } void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset) { - _assert_msg_(JIT, Dest >= S0 && Dest <= D31, "Passed Invalid dest register to VLDR"); - _assert_msg_(JIT, Base <= R15, "Passed invalid Base register to VLDR"); + _assert_msg_(Dest >= S0 && Dest <= D31, "Passed Invalid dest register to VLDR"); + _assert_msg_(Base <= R15, "Passed invalid Base register to VLDR"); bool Add = offset >= 0 ? true : false; u32 imm = abs(offset); - _assert_msg_(JIT, (imm & 0xC03) == 0, "VLDR: Offset needs to be word aligned and small enough"); + _assert_msg_((imm & 0xC03) == 0, "VLDR: Offset needs to be word aligned and small enough"); if (imm & 0xC03) ERROR_LOG(JIT, "VLDR: Bad offset %08x", imm); @@ -1521,13 +1521,13 @@ void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset) } void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, s16 offset) { - _assert_msg_(JIT, Src >= S0 && Src <= D31, "Passed invalid src register to VSTR"); - _assert_msg_(JIT, Base <= R15, "Passed invalid base register to VSTR"); + _assert_msg_(Src >= S0 && Src <= D31, "Passed invalid src register to VSTR"); + _assert_msg_(Base <= R15, "Passed invalid base register to VSTR"); bool Add = offset >= 0 ? true : false; u32 imm = abs(offset); - _assert_msg_(JIT, (imm & 0xC03) == 0, "VSTR: Offset needs to be word aligned and small enough"); + _assert_msg_((imm & 0xC03) == 0, "VSTR: Offset needs to be word aligned and small enough"); if (imm & 0xC03) ERROR_LOG(JIT, "VSTR: Bad offset %08x", imm); @@ -1560,15 +1560,15 @@ void ARMXEmitter::VMSR(ARMReg Rt) { void ARMXEmitter::VMOV(ARMReg Dest, Operand2 op2) { - _assert_msg_(JIT, cpu_info.bVFPv3, "VMOV #imm requires VFPv3"); + _assert_msg_(cpu_info.bVFPv3, "VMOV #imm requires VFPv3"); int sz = Dest >= D0 ? (1 << 8) : 0; Write32(condition | (0xEB << 20) | EncodeVd(Dest) | (5 << 9) | sz | op2.Imm8VFP()); } void ARMXEmitter::VMOV_neon(u32 Size, ARMReg Vd, u32 imm) { - _assert_msg_(JIT, cpu_info.bNEON, "VMOV_neon #imm requires NEON"); - _assert_msg_(JIT, Vd >= D0, "VMOV_neon #imm must target a double or quad"); + _assert_msg_(cpu_info.bNEON, "VMOV_neon #imm requires NEON"); + _assert_msg_(Vd >= D0, "VMOV_neon #imm must target a double or quad"); bool register_quad = Vd >= Q0; int cmode = 0; @@ -1642,7 +1642,7 @@ void ARMXEmitter::VMOV_neon(u32 Size, ARMReg Vd, u32 imm) cmode = 7 << 1; op2 = IMM(imm8 | (imm8 << 4)); } else { - _assert_msg_(JIT, false, "VMOV_neon #imm invalid constant value"); + _assert_msg_(false, "VMOV_neon #imm invalid constant value"); } } @@ -1652,7 +1652,7 @@ void ARMXEmitter::VMOV_neon(u32 Size, ARMReg Vd, u32 imm) void ARMXEmitter::VMOV_neon(u32 Size, ARMReg Vd, ARMReg Rt, int lane) { - _assert_msg_(JIT, cpu_info.bNEON, "VMOV_neon requires NEON"); + _assert_msg_(cpu_info.bNEON, "VMOV_neon requires NEON"); int opc1 = 0; int opc2 = 0; @@ -1666,7 +1666,7 @@ void ARMXEmitter::VMOV_neon(u32 Size, ARMReg Vd, ARMReg Rt, int lane) opc1 = lane & 1; break; default: - _assert_msg_(JIT, false, "VMOV_neon unsupported size"); + _assert_msg_(false, "VMOV_neon unsupported size"); } if (Vd < S0 && Rt >= D0 && Rt < Q0) @@ -1675,7 +1675,7 @@ void ARMXEmitter::VMOV_neon(u32 Size, ARMReg Vd, ARMReg Rt, int lane) ARMReg Src = Rt; ARMReg Dest = Vd; - _dbg_assert_msg_(JIT, (Size & (I_UNSIGNED | I_SIGNED | F_32)) != 0, "Must specify I_SIGNED or I_UNSIGNED in VMOV, unless F_32"); + _dbg_assert_msg_((Size & (I_UNSIGNED | I_SIGNED | F_32)) != 0, "Must specify I_SIGNED or I_UNSIGNED in VMOV, unless F_32"); int U = (Size & I_UNSIGNED) ? (1 << 23) : 0; Write32(condition | (0xE1 << 20) | U | (opc1 << 21) | EncodeVn(Src) | (Dest << 12) | (0xB << 8) | (opc2 << 5) | (1 << 4)); @@ -1687,12 +1687,12 @@ void ARMXEmitter::VMOV_neon(u32 Size, ARMReg Vd, ARMReg Rt, int lane) Write32(condition | (0xE0 << 20) | (opc1 << 21) | EncodeVn(Dest) | (Src << 12) | (0xB << 8) | (opc2 << 5) | (1 << 4)); } else - _assert_msg_(JIT, false, "VMOV_neon unsupported arguments (Dx -> Rx or Rx -> Dx)"); + _assert_msg_(false, "VMOV_neon unsupported arguments (Dx -> Rx or Rx -> Dx)"); } void ARMXEmitter::VMOV(ARMReg Vd, ARMReg Rt, ARMReg Rt2) { - _assert_msg_(JIT, cpu_info.bVFP | cpu_info.bNEON, "VMOV_neon requires VFP or NEON"); + _assert_msg_(cpu_info.bVFP | cpu_info.bNEON, "VMOV_neon requires VFP or NEON"); if (Vd < S0 && Rt < S0 && Rt2 >= D0) { @@ -1710,13 +1710,13 @@ void ARMXEmitter::VMOV(ARMReg Vd, ARMReg Rt, ARMReg Rt2) Write32(condition | (0xC4 << 20) | (Src2 << 16) | (Src1 << 12) | (0xB << 8) | EncodeVm(Dest) | (1 << 4)); } else - _assert_msg_(JIT, false, "VMOV_neon requires either Dm, Rt, Rt2 or Rt, Rt2, Dm."); + _assert_msg_(false, "VMOV_neon requires either Dm, Rt, Rt2 or Rt, Rt2, Dm."); } void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src, bool high) { - _assert_msg_(JIT, Src < S0, "This VMOV doesn't support SRC other than ARM Reg"); - _assert_msg_(JIT, Dest >= D0, "This VMOV doesn't support DEST other than VFP"); + _assert_msg_(Src < S0, "This VMOV doesn't support SRC other than ARM Reg"); + _assert_msg_(Dest >= D0, "This VMOV doesn't support DEST other than VFP"); Dest = SubBase(Dest); @@ -1744,7 +1744,7 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src) else { // Move 64bit from Arm reg - _assert_msg_(JIT, false, "This VMOV doesn't support moving 64bit ARM to NEON"); + _assert_msg_(false, "This VMOV doesn't support moving 64bit ARM to NEON"); return; } } @@ -1764,14 +1764,14 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src) else { // Move 64bit To Arm reg - _assert_msg_(JIT, false, "This VMOV doesn't support moving 64bit ARM From NEON"); + _assert_msg_(false, "This VMOV doesn't support moving 64bit ARM From NEON"); return; } } else { // Move Arm reg to Arm reg - _assert_msg_(JIT, false, "VMOV doesn't support moving ARM registers"); + _assert_msg_(false, "VMOV doesn't support moving ARM registers"); } } // Moving NEON registers @@ -1780,7 +1780,7 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src) bool Single = DestSize == 1; bool Quad = DestSize == 4; - _assert_msg_(JIT, SrcSize == DestSize, "VMOV doesn't support moving different register sizes"); + _assert_msg_(SrcSize == DestSize, "VMOV doesn't support moving different register sizes"); if (SrcSize != DestSize) { ELOG("SrcSize: %i (%s) DestDize: %i (%s)", SrcSize, ARMRegAsString(Src), DestSize, ARMRegAsString(Dest)); } @@ -1798,7 +1798,7 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src) // Double and quad if (Quad) { - _assert_msg_(JIT, cpu_info.bNEON, "Trying to use quad registers when you don't support ASIMD."); + _assert_msg_(cpu_info.bNEON, "Trying to use quad registers when you don't support ASIMD."); // Gets encoded as a Double register Write32((0xF2 << 24) | ((Dest & 0x10) << 18) | (2 << 20) | ((Src & 0xF) << 16) \ | ((Dest & 0xF) << 12) | (1 << 8) | ((Src & 0x10) << 3) | (1 << 6) \ @@ -1859,9 +1859,9 @@ void ARMXEmitter::VCVT(ARMReg Dest, ARMReg Source, int flags) void ARMXEmitter::VABA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | EncodeVn(Vn) \ @@ -1870,11 +1870,11 @@ void ARMXEmitter::VABA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VABAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vn >= D0 && Vn < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vn >= D0 && Vn < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (1 << 23) | EncodeVn(Vn) \ | (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x50 << 4) | EncodeVm(Vm)); @@ -1882,8 +1882,8 @@ void ARMXEmitter::VABAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VABD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; if (Size & F_32) @@ -1895,11 +1895,11 @@ void ARMXEmitter::VABD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VABDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vn >= D0 && Vn < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vn >= D0 && Vn < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (1 << 23) | EncodeVn(Vn) \ | (encodedSize(Size) << 20) | EncodeVd(Vd) | (0x70 << 4) | EncodeVm(Vm)); @@ -1907,8 +1907,8 @@ void ARMXEmitter::VABDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VABS(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (0xB1 << 16) | (encodedSize(Size) << 18) | EncodeVd(Vd) \ @@ -1918,8 +1918,8 @@ void ARMXEmitter::VABS(u32 Size, ARMReg Vd, ARMReg Vm) void ARMXEmitter::VACGE(ARMReg Vd, ARMReg Vn, ARMReg Vm) { // Only Float - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | EncodeVn(Vn) | EncodeVd(Vd) \ @@ -1929,8 +1929,8 @@ void ARMXEmitter::VACGE(ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VACGT(ARMReg Vd, ARMReg Vn, ARMReg Vm) { // Only Float - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (1 << 21) | EncodeVn(Vn) | EncodeVd(Vd) \ @@ -1949,8 +1949,8 @@ void ARMXEmitter::VACLT(ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -1963,11 +1963,11 @@ void ARMXEmitter::VADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vn >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vn >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) \ | EncodeVd(Vd) | (0x80 << 4) | EncodeVm(Vm)); @@ -1975,84 +1975,84 @@ void ARMXEmitter::VADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VADDL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vn >= D0 && Vn < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vn >= D0 && Vn < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) \ | EncodeVd(Vd) | EncodeVm(Vm)); } void ARMXEmitter::VADDW(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vn >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vn >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) \ | EncodeVd(Vd) | (1 << 8) | EncodeVm(Vm)); } void ARMXEmitter::VAND(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Vd == Vn && Vn == Vm), "All operands the same for %s is a nop", __FUNCTION__); - // _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Vd == Vn && Vn == Vm), "All operands the same for %s is a nop", __FUNCTION__); + // _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF2 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm)); } void ARMXEmitter::VBIC(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - // _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + // _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF2 << 24) | (1 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm)); } void ARMXEmitter::VEOR(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s: %i", __FUNCTION__, Vd); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s: %i", __FUNCTION__, Vd); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm)); } void ARMXEmitter::VBIF(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - // _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + // _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (3 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm)); } void ARMXEmitter::VBIT(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - // _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + // _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (2 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm)); } void ARMXEmitter::VBSL(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - // _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + // _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (1 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x11 << 4) | (register_quad << 6) | EncodeVm(Vm)); } void ARMXEmitter::VCEQ(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; if (Size & F_32) @@ -2064,8 +2064,8 @@ void ARMXEmitter::VCEQ(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VCEQ(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2074,8 +2074,8 @@ void ARMXEmitter::VCEQ(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VCGE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; if (Size & F_32) @@ -2086,8 +2086,8 @@ void ARMXEmitter::VCGE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VCGE(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (0xB << 20) | (encodedSize(Size) << 18) | (1 << 16) \ @@ -2095,8 +2095,8 @@ void ARMXEmitter::VCGE(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VCGT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; if (Size & F_32) @@ -2107,8 +2107,8 @@ void ARMXEmitter::VCGT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VCGT(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \ @@ -2120,8 +2120,8 @@ void ARMXEmitter::VCLE(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VCLE(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \ @@ -2129,9 +2129,9 @@ void ARMXEmitter::VCLE(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VCLS(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \ @@ -2143,8 +2143,8 @@ void ARMXEmitter::VCLT(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VCLT(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) | (1 << 16) \ @@ -2152,8 +2152,8 @@ void ARMXEmitter::VCLT(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VCLZ(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \ @@ -2161,9 +2161,9 @@ void ARMXEmitter::VCLZ(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VCNT(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, Size & I_8, "Can only use I_8 with %s", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Size & I_8, "Can only use I_8 with %s", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF3 << 24) | (0xD << 20) | (encodedSize(Size) << 18) \ @@ -2171,9 +2171,9 @@ void ARMXEmitter::VCNT(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VDUP(u32 Size, ARMReg Vd, ARMReg Vm, u8 index) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; u32 imm4 = 0; @@ -2188,9 +2188,9 @@ void ARMXEmitter::VDUP(u32 Size, ARMReg Vd, ARMReg Vm, u8 index) } void ARMXEmitter::VDUP(u32 Size, ARMReg Vd, ARMReg Rt) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Rt < S0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Rt < S0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Vd = SubBase(Vd); @@ -2207,8 +2207,8 @@ void ARMXEmitter::VDUP(u32 Size, ARMReg Vd, ARMReg Rt) } void ARMXEmitter::VEXT(ARMReg Vd, ARMReg Vn, ARMReg Vm, u8 index) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF2 << 24) | (0xB << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (index & 0xF) \ @@ -2216,29 +2216,29 @@ void ARMXEmitter::VEXT(ARMReg Vd, ARMReg Vn, ARMReg Vm, u8 index) } void ARMXEmitter::VFMA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Size == F_32, "Passed invalid size to FP-only NEON instruction"); - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bVFPv4, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Size == F_32, "Passed invalid size to FP-only NEON instruction"); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bVFPv4, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF2 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0xC1 << 4) | (register_quad << 6) | EncodeVm(Vm)); } void ARMXEmitter::VFMS(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Size == F_32, "Passed invalid size to FP-only NEON instruction"); - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bVFPv4, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Size == F_32, "Passed invalid size to FP-only NEON instruction"); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bVFPv4, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Write32((0xF2 << 24) | (1 << 21) | EncodeVn(Vn) | EncodeVd(Vd) | (0xC1 << 4) | (register_quad << 6) | EncodeVm(Vm)); } void ARMXEmitter::VHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2247,9 +2247,9 @@ void ARMXEmitter::VHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VHSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2258,8 +2258,8 @@ void ARMXEmitter::VHSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2271,8 +2271,8 @@ void ARMXEmitter::VMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2284,8 +2284,8 @@ void ARMXEmitter::VMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VMLA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2296,8 +2296,8 @@ void ARMXEmitter::VMLA(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VMLS(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2308,30 +2308,30 @@ void ARMXEmitter::VMLS(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VMLAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vn >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vn >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) \ | EncodeVn(Vn) | EncodeVd(Vd) | (0x80 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VMLSL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vn >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float.", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vn >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= D0 && Vm < Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float.", __FUNCTION__); Write32((0xF2 << 24) | ((Size & I_UNSIGNED ? 1 : 0) << 24) | (encodedSize(Size) << 20) \ | EncodeVn(Vn) | EncodeVd(Vd) | (0xA0 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VMUL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2343,17 +2343,17 @@ void ARMXEmitter::VMUL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VMULL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0xC0 << 4) | ((Size & I_POLYNOMIAL) ? 1 << 9 : 0) | EncodeVm(Vm)); } void ARMXEmitter::VMLA_scalar(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2361,15 +2361,15 @@ void ARMXEmitter::VMLA_scalar(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) if (Size & F_32) Write32((0xF2 << 24) | (register_quad << 24) | (1 << 23) | (2 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x14 << 4) | EncodeVm(Vm)); else - _dbg_assert_msg_(JIT, false, "VMLA_scalar only supports float atm"); + _dbg_assert_msg_(false, "VMLA_scalar only supports float atm"); //else // Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x90 << 4) | (1 << 6) | EncodeVm(Vm)); // Unsigned support missing } void ARMXEmitter::VMUL_scalar(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2378,7 +2378,7 @@ void ARMXEmitter::VMUL_scalar(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) if (Size & F_32) // Q flag Write32((0xF2 << 24) | (register_quad << 24) | (1 << 23) | (2 << 20) | EncodeVn(Vn) | EncodeVd(Vd) | (0x94 << 4) | VmEnc); else - _dbg_assert_msg_(JIT, false, "VMUL_scalar only supports float atm"); + _dbg_assert_msg_(false, "VMUL_scalar only supports float atm"); // Write32((0xF2 << 24) | ((Size & I_POLYNOMIAL) ? (1 << 24) : 0) | (1 << 23) | (encodedSize(Size) << 20) | // EncodeVn(Vn) | EncodeVd(Vd) | (0x84 << 4) | (register_quad << 6) | EncodeVm(Vm)); @@ -2387,8 +2387,8 @@ void ARMXEmitter::VMUL_scalar(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) void ARMXEmitter::VMVN(ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2398,8 +2398,8 @@ void ARMXEmitter::VMVN(ARMReg Vd, ARMReg Vm) void ARMXEmitter::VNEG(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2408,8 +2408,8 @@ void ARMXEmitter::VNEG(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VORN(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2417,9 +2417,9 @@ void ARMXEmitter::VORN(ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VORR(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Vd == Vn && Vn == Vm), "All operands the same for %s is a nop", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Vd == Vn && Vn == Vm), "All operands the same for %s is a nop", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2427,9 +2427,9 @@ void ARMXEmitter::VORR(ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VPADAL(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2438,8 +2438,8 @@ void ARMXEmitter::VPADAL(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VPADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); if (Size & F_32) Write32((0xF3 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0xD0 << 4) | EncodeVm(Vm)); @@ -2449,9 +2449,9 @@ void ARMXEmitter::VPADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VPADDL(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2460,8 +2460,8 @@ void ARMXEmitter::VPADDL(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VPMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); if (Size & F_32) Write32((0xF3 << 24) | EncodeVn(Vn) | EncodeVd(Vd) | (0xF0 << 4) | EncodeVm(Vm)); @@ -2471,8 +2471,8 @@ void ARMXEmitter::VPMAX(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VPMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); if (Size & F_32) Write32((0xF3 << 24) | (1 << 21) | EncodeVn(Vn) | EncodeVd(Vd) | (0xF0 << 4) | EncodeVm(Vm)); @@ -2482,9 +2482,9 @@ void ARMXEmitter::VPMIN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VQABS(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2493,9 +2493,9 @@ void ARMXEmitter::VQABS(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VQADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2504,45 +2504,45 @@ void ARMXEmitter::VQADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VQDMLAL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0x90 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VQDMLSL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0xB0 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VQDMULH(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); Write32((0xF2 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0xB0 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VQDMULL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); Write32((0xF2 << 24) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0xD0 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VQNEG(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2551,18 +2551,18 @@ void ARMXEmitter::VQNEG(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VQRDMULH(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); Write32((0xF3 << 24) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0xB0 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VQRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2571,9 +2571,9 @@ void ARMXEmitter::VQRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VQSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2582,9 +2582,9 @@ void ARMXEmitter::VQSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VQSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2593,17 +2593,17 @@ void ARMXEmitter::VQSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VRADDHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); Write32((0xF3 << 24) | (1 << 23) | ((encodedSize(Size) - 1) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0x40 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VRECPE(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2612,8 +2612,8 @@ void ARMXEmitter::VRECPE(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VRECPS(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2621,9 +2621,9 @@ void ARMXEmitter::VRECPS(ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VRHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2632,9 +2632,9 @@ void ARMXEmitter::VRHADD(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2643,8 +2643,8 @@ void ARMXEmitter::VRSHL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VRSQRTE(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; Vd = SubBase(Vd); @@ -2656,8 +2656,8 @@ void ARMXEmitter::VRSQRTE(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VRSQRTS(ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2666,18 +2666,18 @@ void ARMXEmitter::VRSQRTS(ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VRSUBHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); Write32((0xF3 << 24) | (1 << 23) | ((encodedSize(Size) - 1) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0x60 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VSHL(u32 Size, ARMReg Vd, ARMReg Vm, ARMReg Vn) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2694,7 +2694,7 @@ static int EncodeSizeShift(u32 Size, int amount, bool inverse, bool halve) { case I_64: sz = 64; break; } if (inverse && halve) { - _dbg_assert_msg_(JIT, amount <= sz / 2, "Amount %d too large for narrowing shift (max %d)", amount, sz/2); + _dbg_assert_msg_(amount <= sz / 2, "Amount %d too large for narrowing shift (max %d)", amount, sz/2); return (sz / 2) + (sz / 2) - amount; } else if (inverse) { return sz + (sz - amount); @@ -2704,9 +2704,9 @@ static int EncodeSizeShift(u32 Size, int amount, bool inverse, bool halve) { } void ARMXEmitter::EncodeShiftByImm(u32 Size, ARMReg Vd, ARMReg Vm, int shiftAmount, u8 opcode, bool register_quad, bool inverse, bool halve) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, !(Size & F_32), "%s doesn't support float", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(!(Size & F_32), "%s doesn't support float", __FUNCTION__); int imm7 = EncodeSizeShift(Size, shiftAmount, inverse, halve); int L = (imm7 >> 6) & 1; int U = (Size & I_UNSIGNED) ? 1 : 0; @@ -2727,7 +2727,7 @@ void ARMXEmitter::VSHLL(u32 Size, ARMReg Vd, ARMReg Vm, int shiftAmount) { case I_16: sz = 1; break; case I_32: sz = 2; break; case I_64: - _dbg_assert_msg_(JIT, false, "Cannot VSHLL 64-bit elements"); + _dbg_assert_msg_(false, "Cannot VSHLL 64-bit elements"); } int imm6 = 0x32 | (sz << 2); u32 value = (0xF3 << 24) | (1 << 23) | (imm6 << 16) | EncodeVd(Vd) | (0x3 << 8) | EncodeVm(Vm); @@ -2748,8 +2748,8 @@ void ARMXEmitter::VSHRN(u32 Size, ARMReg Vd, ARMReg Vm, int shiftAmount) { void ARMXEmitter::VSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2762,32 +2762,32 @@ void ARMXEmitter::VSUB(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VSUBHN(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); Write32((0xF2 << 24) | (1 << 23) | ((encodedSize(Size) - 1) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0x60 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VSUBL(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0x20 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VSUBW(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); Write32((0xF2 << 24) | (Size & I_UNSIGNED ? 1 << 24 : 0) | (1 << 23) | (encodedSize(Size) << 20) | EncodeVn(Vn) | EncodeVd(Vd) | \ (0x30 << 4) | EncodeVm(Vm)); } void ARMXEmitter::VSWP(ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2796,8 +2796,8 @@ void ARMXEmitter::VSWP(ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VTRN(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2806,8 +2806,8 @@ void ARMXEmitter::VTRN(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VTST(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2816,8 +2816,8 @@ void ARMXEmitter::VTST(u32 Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) } void ARMXEmitter::VUZP(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2826,8 +2826,8 @@ void ARMXEmitter::VUZP(u32 Size, ARMReg Vd, ARMReg Vm) } void ARMXEmitter::VZIP(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= D0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); bool register_quad = Vd >= Q0; @@ -2837,10 +2837,10 @@ void ARMXEmitter::VZIP(u32 Size, ARMReg Vd, ARMReg Vm) void ARMXEmitter::VMOVL(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vm >= D0 && Vm <= D31, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, (Size & (I_UNSIGNED | I_SIGNED)) != 0, "Must specify I_SIGNED or I_UNSIGNED in VMOVL"); + _dbg_assert_msg_(Vd >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vm >= D0 && Vm <= D31, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_((Size & (I_UNSIGNED | I_SIGNED)) != 0, "Must specify I_SIGNED or I_UNSIGNED in VMOVL"); bool unsign = (Size & I_UNSIGNED) != 0; int imm3 = 0; @@ -2854,10 +2854,10 @@ void ARMXEmitter::VMOVL(u32 Size, ARMReg Vd, ARMReg Vm) void ARMXEmitter::VMOVN(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vm >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vd >= D0 && Vd <= D31, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, (Size & I_8) == 0, "%s cannot narrow from I_8", __FUNCTION__); + _dbg_assert_msg_(Vm >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0 && Vd <= D31, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_((Size & I_8) == 0, "%s cannot narrow from I_8", __FUNCTION__); // For consistency with assembler syntax and VMOVL - encode one size down. int halfSize = encodedSize(Size) - 1; @@ -2867,11 +2867,11 @@ void ARMXEmitter::VMOVN(u32 Size, ARMReg Vd, ARMReg Vm) void ARMXEmitter::VQMOVN(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vm >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vd >= D0 && Vd <= D31, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, (Size & (I_UNSIGNED | I_SIGNED)) != 0, "Must specify I_SIGNED or I_UNSIGNED in %s NEON", __FUNCTION__); - _dbg_assert_msg_(JIT, (Size & I_8) == 0, "%s cannot narrow from I_8", __FUNCTION__); + _dbg_assert_msg_(Vm >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0 && Vd <= D31, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_((Size & (I_UNSIGNED | I_SIGNED)) != 0, "Must specify I_SIGNED or I_UNSIGNED in %s NEON", __FUNCTION__); + _dbg_assert_msg_((Size & I_8) == 0, "%s cannot narrow from I_8", __FUNCTION__); int halfSize = encodedSize(Size) - 1; int op = (1 << 7) | (Size & I_UNSIGNED ? 1 << 6 : 0); @@ -2881,10 +2881,10 @@ void ARMXEmitter::VQMOVN(u32 Size, ARMReg Vd, ARMReg Vm) void ARMXEmitter::VQMOVUN(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, Vm >= Q0, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, Vd >= D0 && Vd <= D31, "Pass invalid register to %s", __FUNCTION__); - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); - _dbg_assert_msg_(JIT, (Size & I_8) == 0, "%s cannot narrow from I_8", __FUNCTION__); + _dbg_assert_msg_(Vm >= Q0, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(Vd >= D0 && Vd <= D31, "Pass invalid register to %s", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_((Size & I_8) == 0, "%s cannot narrow from I_8", __FUNCTION__); int halfSize = encodedSize(Size) - 1; int op = (1 << 6); @@ -2894,7 +2894,7 @@ void ARMXEmitter::VQMOVUN(u32 Size, ARMReg Vd, ARMReg Vm) void ARMXEmitter::VCVT(u32 Size, ARMReg Vd, ARMReg Vm) { - _dbg_assert_msg_(JIT, (Size & (I_UNSIGNED | I_SIGNED)) != 0, "Must specify I_SIGNED or I_UNSIGNED in VCVT NEON"); + _dbg_assert_msg_((Size & (I_UNSIGNED | I_SIGNED)) != 0, "Must specify I_SIGNED or I_UNSIGNED in VCVT NEON"); bool register_quad = Vd >= Q0; bool toInteger = (Size & I_32) != 0; @@ -2907,18 +2907,18 @@ void ARMXEmitter::VCVT(u32 Size, ARMReg Vd, ARMReg Vm) static int RegCountToType(int nRegs, NEONAlignment align) { switch (nRegs) { case 1: - _dbg_assert_msg_(JIT, !((int)align & 1), "align & 1 must be == 0"); + _dbg_assert_msg_(!((int)align & 1), "align & 1 must be == 0"); return 7; case 2: - _dbg_assert_msg_(JIT, !((int)align == 3), "align must be != 3"); + _dbg_assert_msg_(!((int)align == 3), "align must be != 3"); return 10; case 3: - _dbg_assert_msg_(JIT, !((int)align & 1), "align & 1 must be == 0"); + _dbg_assert_msg_(!((int)align & 1), "align & 1 must be == 0"); return 6; case 4: return 2; default: - _dbg_assert_msg_(JIT, false, "Invalid number of registers passed to vector load/store"); + _dbg_assert_msg_(false, "Invalid number of registers passed to vector load/store"); return 0; } } @@ -2935,12 +2935,12 @@ void ARMXEmitter::WriteVLDST1(bool load, u32 Size, ARMReg Vd, ARMReg Rn, int reg } void ARMXEmitter::VLD1(u32 Size, ARMReg Vd, ARMReg Rn, int regCount, NEONAlignment align, ARMReg Rm) { - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); WriteVLDST1(true, Size, Vd, Rn, regCount, align, Rm); } void ARMXEmitter::VST1(u32 Size, ARMReg Vd, ARMReg Rn, int regCount, NEONAlignment align, ARMReg Rm) { - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); WriteVLDST1(false, Size, Vd, Rn, regCount, align, Rm); } @@ -2970,12 +2970,12 @@ void ARMXEmitter::WriteVLDST1_lane(bool load, u32 Size, ARMReg Vd, ARMReg Rn, in } void ARMXEmitter::VLD1_lane(u32 Size, ARMReg Vd, ARMReg Rn, int lane, bool aligned, ARMReg Rm) { - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); WriteVLDST1_lane(true, Size, Vd, Rn, lane, aligned, Rm); } void ARMXEmitter::VST1_lane(u32 Size, ARMReg Vd, ARMReg Rn, int lane, bool aligned, ARMReg Rm) { - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); WriteVLDST1_lane(false, Size, Vd, Rn, lane, aligned, Rm); } @@ -3012,7 +3012,7 @@ void ARMXEmitter::WriteVimm(ARMReg Vd, int cmode, u8 imm, int op) { } void ARMXEmitter::VMOV_imm(u32 Size, ARMReg Vd, VIMMMode type, int imm) { - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); // Only let through the modes that apply. switch (type) { case VIMM___x___x: @@ -3045,11 +3045,11 @@ void ARMXEmitter::VMOV_imm(u32 Size, ARMReg Vd, VIMMMode type, int imm) { return; error: - _dbg_assert_msg_(JIT, false, "Bad Size or type specified in %s: Size %i Type %i", __FUNCTION__, (int)Size, type); + _dbg_assert_msg_(false, "Bad Size or type specified in %s: Size %i Type %i", __FUNCTION__, (int)Size, type); } void ARMXEmitter::VMOV_immf(ARMReg Vd, float value) { // This only works with a select few values. I've hardcoded 1.0f. - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); u8 bits = 0; if (value == 0.0f) { @@ -3065,13 +3065,13 @@ void ARMXEmitter::VMOV_immf(ARMReg Vd, float value) { // This only works with a } else if (value == -1.0f) { bits = 0xF0; } else { - _dbg_assert_msg_(JIT, false, "%s: Invalid floating point immediate", __FUNCTION__); + _dbg_assert_msg_(false, "%s: Invalid floating point immediate", __FUNCTION__); } WriteVimm(Vd, VIMMf000f000, bits, 0); } void ARMXEmitter::VORR_imm(u32 Size, ARMReg Vd, VIMMMode type, int imm) { - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); // Only let through the modes that apply. switch (type) { case VIMM___x___x: @@ -3093,11 +3093,11 @@ void ARMXEmitter::VORR_imm(u32 Size, ARMReg Vd, VIMMMode type, int imm) { } return; error: - _dbg_assert_msg_(JIT, false, "Bad Size or type specified in VORR_imm"); + _dbg_assert_msg_(false, "Bad Size or type specified in VORR_imm"); } void ARMXEmitter::VBIC_imm(u32 Size, ARMReg Vd, VIMMMode type, int imm) { - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); // Only let through the modes that apply. switch (type) { case VIMM___x___x: @@ -3119,12 +3119,12 @@ void ARMXEmitter::VBIC_imm(u32 Size, ARMReg Vd, VIMMMode type, int imm) { } return; error: - _dbg_assert_msg_(JIT, false, "Bad Size or type specified in VBIC_imm"); + _dbg_assert_msg_(false, "Bad Size or type specified in VBIC_imm"); } void ARMXEmitter::VMVN_imm(u32 Size, ARMReg Vd, VIMMMode type, int imm) { - _dbg_assert_msg_(JIT, cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); + _dbg_assert_msg_(cpu_info.bNEON, "Can't use %s when CPU doesn't support it", __FUNCTION__); // Only let through the modes that apply. switch (type) { case VIMM___x___x: @@ -3146,7 +3146,7 @@ void ARMXEmitter::VMVN_imm(u32 Size, ARMReg Vd, VIMMMode type, int imm) { } return; error: - _dbg_assert_msg_(JIT, false, "Bad Size or type specified in VMVN_imm"); + _dbg_assert_msg_(false, "Bad Size or type specified in VMVN_imm"); } @@ -3180,9 +3180,9 @@ void ARMXEmitter::VREV16(u32 Size, ARMReg Vd, ARMReg Vm) // Dest is a Q register, Src is a D register. void ARMXEmitter::VCVTF32F16(ARMReg Dest, ARMReg Src) { - _assert_msg_(JIT, cpu_info.bVFPv4, "Can't use half-float conversions when you don't support VFPv4"); + _assert_msg_(cpu_info.bVFPv4, "Can't use half-float conversions when you don't support VFPv4"); if (Dest < Q0 || Dest > Q15 || Src < D0 || Src > D15) { - _assert_msg_(JIT, cpu_info.bNEON, "Bad inputs to VCVTF32F16"); + _assert_msg_(cpu_info.bNEON, "Bad inputs to VCVTF32F16"); // Invalid! } @@ -3196,9 +3196,9 @@ void ARMXEmitter::VCVTF32F16(ARMReg Dest, ARMReg Src) { // UNTESTED // Dest is a D register, Src is a Q register. void ARMXEmitter::VCVTF16F32(ARMReg Dest, ARMReg Src) { - _assert_msg_(JIT, cpu_info.bVFPv4, "Can't use half-float conversions when you don't support VFPv4"); + _assert_msg_(cpu_info.bVFPv4, "Can't use half-float conversions when you don't support VFPv4"); if (Dest < D0 || Dest > D15 || Src < Q0 || Src > Q15) { - _assert_msg_(JIT, cpu_info.bNEON, "Bad inputs to VCVTF32F16"); + _assert_msg_(cpu_info.bNEON, "Bad inputs to VCVTF32F16"); // Invalid! } Dest = SubBase(Dest); diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index b8116129ec..19dab7c135 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -145,7 +145,7 @@ public: Operand2(ARMReg base, ShiftType type, ARMReg shift) // RSR { Type = TYPE_RSR; - _assert_msg_(JIT, type != ST_RRX, "Invalid Operand2: RRX does not take a register shift amount"); + _assert_msg_(type != ST_RRX, "Invalid Operand2: RRX does not take a register shift amount"); IndexOrShift = shift; Shift = type; Value = base; @@ -157,29 +157,29 @@ public: switch (type) { case ST_LSL: - _assert_msg_(JIT, shift < 32, "Invalid Operand2: LSL %u", shift); + _assert_msg_(shift < 32, "Invalid Operand2: LSL %u", shift); break; case ST_LSR: - _assert_msg_(JIT, shift <= 32, "Invalid Operand2: LSR %u", shift); + _assert_msg_(shift <= 32, "Invalid Operand2: LSR %u", shift); if (!shift) type = ST_LSL; if (shift == 32) shift = 0; break; case ST_ASR: - _assert_msg_(JIT, shift < 32, "Invalid Operand2: ASR %u", shift); + _assert_msg_(shift < 32, "Invalid Operand2: ASR %u", shift); if (!shift) type = ST_LSL; if (shift == 32) shift = 0; break; case ST_ROR: - _assert_msg_(JIT, shift < 32, "Invalid Operand2: ROR %u", shift); + _assert_msg_(shift < 32, "Invalid Operand2: ROR %u", shift); if (!shift) type = ST_LSL; break; case ST_RRX: - _assert_msg_(JIT, shift == 0, "Invalid Operand2: RRX does not take an immediate shift amount"); + _assert_msg_(shift == 0, "Invalid Operand2: RRX does not take an immediate shift amount"); type = ST_ROR; break; } @@ -201,45 +201,45 @@ public: case TYPE_RSR: return RSR(); default: - _assert_msg_(JIT, false, "GetData with Invalid Type"); + _assert_msg_(false, "GetData with Invalid Type"); return 0; } } u32 IMMSR() // IMM shifted register { - _assert_msg_(JIT, Type == TYPE_IMMSREG, "IMMSR must be imm shifted register"); + _assert_msg_(Type == TYPE_IMMSREG, "IMMSR must be imm shifted register"); return ((IndexOrShift & 0x1f) << 7 | (Shift << 5) | Value); } u32 RSR() // Register shifted register { - _assert_msg_(JIT, Type == TYPE_RSR, "RSR must be RSR Of Course"); + _assert_msg_(Type == TYPE_RSR, "RSR must be RSR Of Course"); return (IndexOrShift << 8) | (Shift << 5) | 0x10 | Value; } u32 Rm() const { - _assert_msg_(JIT, Type == TYPE_REG, "Rm must be with Reg"); + _assert_msg_(Type == TYPE_REG, "Rm must be with Reg"); return Value; } u32 Imm5() const { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm5 not IMM value"); + _assert_msg_((Type == TYPE_IMM), "Imm5 not IMM value"); return ((Value & 0x0000001F) << 7); } u32 Imm8() const { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm8Rot not IMM value"); + _assert_msg_((Type == TYPE_IMM), "Imm8Rot not IMM value"); return Value & 0xFF; } u32 Imm8Rot() const // IMM8 with Rotation { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm8Rot not IMM value"); - _assert_msg_(JIT, (Rotation & 0xE1) != 0, "Invalid Operand2: immediate rotation %u", Rotation); + _assert_msg_((Type == TYPE_IMM), "Imm8Rot not IMM value"); + _assert_msg_((Rotation & 0xE1) != 0, "Invalid Operand2: immediate rotation %u", Rotation); return (1 << 25) | (Rotation << 7) | (Value & 0x000000FF); } u32 Imm12() const { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm12 not IMM"); + _assert_msg_((Type == TYPE_IMM), "Imm12 not IMM"); return (Value & 0x00000FFF); } @@ -250,12 +250,12 @@ public: // expand a 8bit IMM to a 32bit value and gives you some rotation as // well. // Each rotation rotates to the right by 2 bits - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm12Mod not IMM"); + _assert_msg_((Type == TYPE_IMM), "Imm12Mod not IMM"); return ((Rotation & 0xF) << 8) | (Value & 0xFF); } u32 Imm16() const { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm16 not IMM"); + _assert_msg_((Type == TYPE_IMM), "Imm16 not IMM"); return ( (Value & 0xF000) << 4) | (Value & 0x0FFF); } u32 Imm16Low() const @@ -264,23 +264,23 @@ public: } u32 Imm16High() const // Returns high 16bits { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm16 not IMM"); + _assert_msg_((Type == TYPE_IMM), "Imm16 not IMM"); return ( ((Value >> 16) & 0xF000) << 4) | ((Value >> 16) & 0x0FFF); } u32 Imm24() const { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm16 not IMM"); + _assert_msg_((Type == TYPE_IMM), "Imm16 not IMM"); return (Value & 0x0FFFFFFF); } // NEON and ASIMD specific u32 Imm8ASIMD() const { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm8ASIMD not IMM"); + _assert_msg_((Type == TYPE_IMM), "Imm8ASIMD not IMM"); return ((Value & 0x80) << 17) | ((Value & 0x70) << 12) | (Value & 0xF); } u32 Imm8VFP() const { - _assert_msg_(JIT, (Type == TYPE_IMM), "Imm8VFP not IMM"); + _assert_msg_((Type == TYPE_IMM), "Imm8VFP not IMM"); return ((Value & 0xF0) << 12) | (Value & 0xF); } }; @@ -733,7 +733,7 @@ public: } void VMOV_neon(u32 Size, ARMReg Vd, u32 imm); void VMOV_neon(u32 Size, ARMReg Vd, float imm) { - _dbg_assert_msg_(JIT, Size == F_32, "Expecting F_32 immediate for VMOV_neon float arg."); + _dbg_assert_msg_(Size == F_32, "Expecting F_32 immediate for VMOV_neon float arg."); union { float f; u32 u; diff --git a/Common/ChunkFile.cpp b/Common/ChunkFile.cpp index 8334e9b5a7..760dbc1855 100644 --- a/Common/ChunkFile.cpp +++ b/Common/ChunkFile.cpp @@ -69,7 +69,7 @@ bool PointerWrap::ExpectVoid(void *data, int size) { case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything case MODE_VERIFY: for (int i = 0; i < size; i++) - _dbg_assert_msg_(COMMON, ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); + _dbg_assert_msg_(((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); break; default: break; // throw an error? } @@ -84,7 +84,7 @@ void PointerWrap::DoVoid(void *data, int size) { case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything case MODE_VERIFY: for (int i = 0; i < size; i++) - _dbg_assert_msg_(COMMON, ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); + _dbg_assert_msg_(((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); break; default: break; // throw an error? } @@ -99,7 +99,7 @@ void PointerWrap::Do(std::string &x) { case MODE_READ: x = (char*)*ptr; break; case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_MEASURE: break; - case MODE_VERIFY: _dbg_assert_msg_(COMMON, !strcmp(x.c_str(), (char*)*ptr), "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (char*)*ptr, ptr); break; + case MODE_VERIFY: _dbg_assert_msg_(!strcmp(x.c_str(), (char*)*ptr), "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (char*)*ptr, ptr); break; } (*ptr) += stringLen; } @@ -112,7 +112,7 @@ void PointerWrap::Do(std::wstring &x) { case MODE_READ: x = (wchar_t*)*ptr; break; case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_MEASURE: break; - case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; + case MODE_VERIFY: _dbg_assert_msg_(x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; } (*ptr) += stringLen; } @@ -125,7 +125,7 @@ void PointerWrap::Do(std::u16string &x) { case MODE_READ: x = (char16_t*)*ptr; break; case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; case MODE_MEASURE: break; - case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (char16_t*)*ptr, "Savestate verification failure: (at %p).\n", x.c_str()); break; + case MODE_VERIFY: _dbg_assert_msg_(x == (char16_t*)*ptr, "Savestate verification failure: (at %p).\n", x.c_str()); break; } (*ptr) += stringLen; } diff --git a/Common/ConsoleListener.cpp b/Common/ConsoleListener.cpp index 18472eaa07..39b1073ad3 100644 --- a/Common/ConsoleListener.cpp +++ b/Common/ConsoleListener.cpp @@ -232,7 +232,7 @@ bool ConsoleListener::IsOpen() */ void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst) { - _dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console."); + _dbg_assert_msg_(IsOpen(), "Don't call this before opening the console."); #if defined(USING_WIN_UI) BOOL SB, SW; if (BufferFirst) @@ -257,7 +257,7 @@ void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int S } void ConsoleListener::LetterSpace(int Width, int Height) { - _dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console."); + _dbg_assert_msg_(IsOpen(), "Don't call this before opening the console."); #if defined(USING_WIN_UI) // Get console info CONSOLE_SCREEN_BUFFER_INFO ConInfo; @@ -392,7 +392,7 @@ void ConsoleListener::SendToThread(LogTypes::LOG_LEVELS Level, const char *Text) // Not ANSI, since the console doesn't support it, but ANSI-like. snprintf(ColorAttr, 16, "\033%d", Level); // For now, rather than properly support it. - _dbg_assert_msg_(COMMON, strlen(ColorAttr) == 2, "Console logging doesn't support > 9 levels."); + _dbg_assert_msg_(strlen(ColorAttr) == 2, "Console logging doesn't support > 9 levels."); ColorLen = (int)strlen(ColorAttr); } @@ -455,7 +455,7 @@ void ConsoleListener::SendToThread(LogTypes::LOG_LEVELS Level, const char *Text) void ConsoleListener::WriteToConsole(LogTypes::LOG_LEVELS Level, const char *Text, size_t Len) { - _dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console."); + _dbg_assert_msg_(IsOpen(), "Don't call this before opening the console."); /* const int MAX_BYTES = 1024*10; @@ -510,7 +510,7 @@ void ConsoleListener::WriteToConsole(LogTypes::LOG_LEVELS Level, const char *Tex void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize) { - _dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console."); + _dbg_assert_msg_(IsOpen(), "Don't call this before opening the console."); #if defined(USING_WIN_UI) // Check size if (Width < 8 || Height < 12) return; @@ -632,7 +632,7 @@ void ConsoleListener::Log(const LogMessage &msg) { // Clear console screen void ConsoleListener::ClearScreen(bool Cursor) { - _dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console."); + _dbg_assert_msg_(IsOpen(), "Don't call this before opening the console."); #if defined(USING_WIN_UI) COORD coordScreen = { 0, 0 }; DWORD cCharsWritten; diff --git a/Common/Hashmaps.h b/Common/Hashmaps.h index e5e36be02e..04d88067bd 100644 --- a/Common/Hashmaps.h +++ b/Common/Hashmaps.h @@ -53,7 +53,7 @@ public: return NullValue; p = (p + 1) & mask; // If the state is REMOVED, we just keep on walking. if (p == pos) { - _assert_msg_(SYSTEM, false, "DenseHashMap: Hit full on Get()"); + _assert_msg_(false, "DenseHashMap: Hit full on Get()"); } } return NullValue; @@ -72,7 +72,7 @@ public: if (state[p] == BucketState::TAKEN) { if (KeyEquals(key, map[p].key)) { // Bad! We already got this one. Let's avoid this case. - _assert_msg_(SYSTEM, false, "DenseHashMap: Duplicate key inserted"); + _assert_msg_(false, "DenseHashMap: Duplicate key inserted"); return false; } // continue looking.... @@ -83,7 +83,7 @@ public: p = (p + 1) & mask; if (p == pos) { // FULL! Error. Should not happen thanks to Grow(). - _assert_msg_(SYSTEM, false, "DenseHashMap: Hit full on Insert()"); + _assert_msg_(false, "DenseHashMap: Hit full on Insert()"); } } if (state[p] == BucketState::REMOVED) { @@ -111,7 +111,7 @@ public: p = (p + 1) & mask; if (p == pos) { // FULL! Error. Should not happen. - _assert_msg_(SYSTEM, false, "DenseHashMap: Hit full on Remove()"); + _assert_msg_(false, "DenseHashMap: Hit full on Remove()"); } } return false; @@ -168,7 +168,7 @@ private: Insert(old[i].key, old[i].value); } } - _assert_msg_(SYSTEM, oldCount == count_, "DenseHashMap: count should not change in Grow()"); + _assert_msg_(oldCount == count_, "DenseHashMap: count should not change in Grow()"); } struct Pair { Key key; @@ -204,7 +204,7 @@ public: return NullValue; p = (p + 1) & mask; // If the state is REMOVED, we just keep on walking. if (p == pos) { - _assert_msg_(SYSTEM, false, "PrehashMap: Hit full on Get()"); + _assert_msg_(false, "PrehashMap: Hit full on Get()"); } } return NullValue; @@ -230,7 +230,7 @@ public: p = (p + 1) & mask; if (p == pos) { // FULL! Error. Should not happen thanks to Grow(). - _assert_msg_(SYSTEM, false, "PrehashMap: Hit full on Insert()"); + _assert_msg_(false, "PrehashMap: Hit full on Insert()"); } } if (state[p] == BucketState::REMOVED) { @@ -257,7 +257,7 @@ public: } p = (p + 1) & mask; if (p == pos) { - _assert_msg_(SYSTEM, false, "PrehashMap: Hit full on Remove()"); + _assert_msg_(false, "PrehashMap: Hit full on Remove()"); } } return false; @@ -317,7 +317,7 @@ private: } } INFO_LOG(G3D, "Grew hashmap capacity from %d to %d", oldCapacity, capacity_); - _assert_msg_(SYSTEM, oldCount == count_, "PrehashMap: count should not change in Grow()"); + _assert_msg_(oldCount == count_, "PrehashMap: count should not change in Grow()"); } struct Pair { uint32_t hash; diff --git a/Common/Log.h b/Common/Log.h index c53da51cb2..418ec15c61 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -120,30 +120,30 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * #endif #if MAX_LOGLEVEL >= DEBUG_LEVEL -#define _dbg_assert_(_t_, _a_) \ +#define _dbg_assert_(_a_) \ if (!(_a_)) {\ printf(#_a_ "\n\nError...\n\n Line: %d\n File: %s\n\n", \ __LINE__, __FILE__); \ - ERROR_LOG(_t_, #_a_ "\n\nError...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \ + ERROR_LOG(SYSTEM, #_a_ "\n\nError...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \ __LINE__, __FILE__); \ if (!PanicYesNo("*** Assertion ***\n")) { Crash(); } \ } #if defined(__ANDROID__) -#define _dbg_assert_msg_(_t_, _a_, ...)\ +#define _dbg_assert_msg_(_a_, ...)\ if (!(_a_)) {\ printf(__VA_ARGS__); \ - ERROR_LOG(_t_, __VA_ARGS__); \ + ERROR_LOG(SYSTEM, __VA_ARGS__); \ if (!PanicYesNo(__VA_ARGS__)) AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ } #else // !defined(__ANDROID__) -#define _dbg_assert_msg_(_t_, _a_, ...)\ +#define _dbg_assert_msg_(_a_, ...)\ if (!(_a_)) {\ printf(__VA_ARGS__); \ - ERROR_LOG(_t_, __VA_ARGS__); \ + ERROR_LOG(SYSTEM, __VA_ARGS__); \ if (!PanicYesNo(__VA_ARGS__)) { Crash();} \ } @@ -167,7 +167,7 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "Assertion failed!"); \ } -#define _assert_msg_(_t_, _a_, ...) \ +#define _assert_msg_(_a_, ...) \ if (!(_a_) && !PanicYesNo(__VA_ARGS__)) { \ AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ } @@ -181,9 +181,9 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * if (!PanicYesNo("*** Assertion ***\n")) { Crash(); } \ } -#define _assert_msg_(_t_, _a_, ...) \ +#define _assert_msg_(_a_, ...) \ if (!(_a_) && !PanicYesNo(__VA_ARGS__)) { \ - Crash(); \ + Crash(); \ } #endif // __ANDROID__ diff --git a/Common/MipsEmitter.cpp b/Common/MipsEmitter.cpp index bd26315ba0..bd4e878959 100644 --- a/Common/MipsEmitter.cpp +++ b/Common/MipsEmitter.cpp @@ -76,7 +76,7 @@ void MIPSEmitter::FlushIcacheSection(u8 *start, u8 *end) { void MIPSEmitter::BREAK(u32 code) { // 000000 iiiiiiiiiiiiiiiiiiii 001101 - _dbg_assert_msg_(JIT, code <= 0xfffff, "Bad emitter arguments"); + _dbg_assert_msg_(code <= 0xfffff, "Bad emitter arguments"); Write32Fields(26, 0x00, 6, code & 0xfffff, 0, 0x0d); } @@ -106,21 +106,21 @@ void MIPSEmitter::JAL(const void *func, std::function delaySlot) { void MIPSEmitter::JR(MIPSReg rs, std::function delaySlot) { // 000000 sssss xxxxxxxxxx hint- 001000 (hint must be 0.) - _dbg_assert_msg_(JIT, rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 0, 0x08); ApplyDelaySlot(delaySlot); } void MIPSEmitter::JALR(MIPSReg rd, MIPSReg rs, std::function delaySlot) { // 000000 sssss xxxxx ddddd hint- 001001 (hint must be 0.) - _dbg_assert_msg_(JIT, rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 11, rd, 0, 0x09); ApplyDelaySlot(delaySlot); } FixupBranch MIPSEmitter::BLTZ(MIPSReg rs, std::function delaySlot) { // 000001 sssss xxxxx iiiiiiiiiiiiiii (fix up) - _dbg_assert_msg_(JIT, rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE, "Bad emitter arguments"); FixupBranch b = MakeFixupBranch(BRANCH_16); Write32Fields(26, 0x01, 21, rs); ApplyDelaySlot(delaySlot); @@ -133,7 +133,7 @@ void MIPSEmitter::BLTZ(MIPSReg rs, const void *func, std::function dela FixupBranch MIPSEmitter::BEQ(MIPSReg rs, MIPSReg rt, std::function delaySlot) { // 000100 sssss ttttt iiiiiiiiiiiiiii (fix up) - _dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); FixupBranch b = MakeFixupBranch(BRANCH_16); Write32Fields(26, 0x04, 21, rs, 16, rt); ApplyDelaySlot(delaySlot); @@ -146,7 +146,7 @@ void MIPSEmitter::BEQ(MIPSReg rs, MIPSReg rt, const void *func, std::function delaySlot) { // 000101 sssss ttttt iiiiiiiiiiiiiii (fix up) - _dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); FixupBranch b = MakeFixupBranch(BRANCH_16); Write32Fields(26, 0x05, 21, rs, 16, rt); ApplyDelaySlot(delaySlot); @@ -159,7 +159,7 @@ void MIPSEmitter::BNE(MIPSReg rs, MIPSReg rt, const void *func, std::function delaySlot) { // 000110 sssss xxxxx iiiiiiiiiiiiiii (fix up) - _dbg_assert_msg_(JIT, rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE, "Bad emitter arguments"); FixupBranch b = MakeFixupBranch(BRANCH_16); Write32Fields(26, 0x06, 21, rs); ApplyDelaySlot(delaySlot); @@ -172,7 +172,7 @@ void MIPSEmitter::BLEZ(MIPSReg rs, const void *func, std::function dela FixupBranch MIPSEmitter::BGTZ(MIPSReg rs, std::function delaySlot) { // 000111 sssss xxxxx iiiiiiiiiiiiiii (fix up) - _dbg_assert_msg_(JIT, rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE, "Bad emitter arguments"); FixupBranch b = MakeFixupBranch(BRANCH_16); Write32Fields(26, 0x07, 21, rs); ApplyDelaySlot(delaySlot); @@ -200,16 +200,16 @@ void MIPSEmitter::SetJumpTarget(const FixupBranch &branch, const void *dst) { const intptr_t dstp = (intptr_t)dst; u32 *fixup = (u32 *)branch.ptr; - _dbg_assert_msg_(JIT, (dstp & 3) == 0, "Destination should be aligned"); + _dbg_assert_msg_((dstp & 3) == 0, "Destination should be aligned"); if (branch.type == BRANCH_16) { // The distance is encoded as words from the delay slot. ptrdiff_t distance = (dstp - srcp - 4) >> 2; - _dbg_assert_msg_(JIT, BInRange(branch.ptr, dst), "Destination is too far away (%p -> %p)", branch.ptr, dst); + _dbg_assert_msg_(BInRange(branch.ptr, dst), "Destination is too far away (%p -> %p)", branch.ptr, dst); *fixup = (*fixup & 0xffff0000) | (distance & 0x0000ffff); } else { // Absolute, easy. - _dbg_assert_msg_(JIT, JInRange(branch.ptr, dst), "Destination is too far away (%p -> %p)", branch.ptr, dst); + _dbg_assert_msg_(JInRange(branch.ptr, dst), "Destination is too far away (%p -> %p)", branch.ptr, dst); *fixup = (*fixup & 0xfc000000) | ((dstp >> 2) & 0x03ffffff); } } @@ -240,7 +240,7 @@ void MIPSEmitter::ApplyDelaySlot(std::function delaySlot) { } void MIPSEmitter::QuickCallFunction(MIPSReg scratchreg, const void *func) { - _dbg_assert_msg_(JIT, scratchreg < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(scratchreg < F_BASE, "Bad emitter arguments"); if (JInRange(func)) { JAL(func); } else { @@ -259,176 +259,176 @@ FixupBranch MIPSEmitter::MakeFixupBranch(FixupBranchType type) { void MIPSEmitter::LB(MIPSReg value, MIPSReg base, s16 offset) { // 100000 sssss ttttt iiiiiiiiiiiiiiii - rs = base, rt = value - _dbg_assert_msg_(JIT, value < F_BASE && base < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(value < F_BASE && base < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x20, 21, base, 16, value, 0, (u16)offset); } void MIPSEmitter::LH(MIPSReg value, MIPSReg base, s16 offset) { // 100001 sssss ttttt iiiiiiiiiiiiiiii - rs = base, rt = value - _dbg_assert_msg_(JIT, value < F_BASE && base < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(value < F_BASE && base < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x21, 21, base, 16, value, 0, (u16)offset); } void MIPSEmitter::LW(MIPSReg value, MIPSReg base, s16 offset) { // 100011 sssss ttttt iiiiiiiiiiiiiiii - rs = base, rt = value - _dbg_assert_msg_(JIT, value < F_BASE && base < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(value < F_BASE && base < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x23, 21, base, 16, value, 0, (u16)offset); } void MIPSEmitter::SB(MIPSReg value, MIPSReg base, s16 offset) { // 101000 sssss ttttt iiiiiiiiiiiiiiii - rs = base, rt = value - _dbg_assert_msg_(JIT, value < F_BASE && base < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(value < F_BASE && base < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x28, 21, base, 16, value, 0, (u16)offset); } void MIPSEmitter::SH(MIPSReg value, MIPSReg base, s16 offset) { // 101001 sssss ttttt iiiiiiiiiiiiiiii - rs = base, rt = value - _dbg_assert_msg_(JIT, value < F_BASE && base < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(value < F_BASE && base < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x29, 21, base, 16, value, 0, (u16)offset); } void MIPSEmitter::SW(MIPSReg value, MIPSReg base, s16 offset) { // 101011 sssss ttttt iiiiiiiiiiiiiiii - rs = base, rt = value - _dbg_assert_msg_(JIT, value < F_BASE && base < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(value < F_BASE && base < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x2b, 21, base, 16, value, 0, (u16)offset); } void MIPSEmitter::SLL(MIPSReg rd, MIPSReg rt, u8 sa) { // 000000 xxxxx ttttt ddddd aaaaa 000000 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && sa <= 0x1f, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && sa <= 0x1f, "Bad emitter arguments"); Write32Fields(26, 0x00, 16, rt, 11, rd, 6, sa & 0x1f, 0, 0x00); } void MIPSEmitter::SRL(MIPSReg rd, MIPSReg rt, u8 sa) { // 000000 xxxxx ttttt ddddd aaaaa 000010 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && sa <= 0x1f, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && sa <= 0x1f, "Bad emitter arguments"); Write32Fields(26, 0x00, 16, rt, 11, rd, 6, sa & 0x1f, 0, 0x02); } void MIPSEmitter::SRA(MIPSReg rd, MIPSReg rt, u8 sa) { // 000000 xxxxx ttttt ddddd aaaaa 000011 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && sa <= 0x1f, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && sa <= 0x1f, "Bad emitter arguments"); Write32Fields(26, 0x00, 16, rt, 11, rd, 6, sa & 0x1f, 0, 0x03); } void MIPSEmitter::SLLV(MIPSReg rd, MIPSReg rt, MIPSReg rs) { // 000000 sssss ttttt ddddd xxxxx 000100 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x04); } void MIPSEmitter::SRLV(MIPSReg rd, MIPSReg rt, MIPSReg rs) { // 000000 sssss ttttt ddddd xxxxx 000110 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x06); } void MIPSEmitter::SRAV(MIPSReg rd, MIPSReg rt, MIPSReg rs) { // 000000 sssss ttttt ddddd xxxxx 000111 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x07); } void MIPSEmitter::SLT(MIPSReg rd, MIPSReg rs, MIPSReg rt) { // 000000 sssss ttttt ddddd xxxxx 101010 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x2a); } void MIPSEmitter::SLTU(MIPSReg rd, MIPSReg rs, MIPSReg rt) { // 000000 sssss ttttt ddddd xxxxx 101011 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x2b); } void MIPSEmitter::SLTI(MIPSReg rt, MIPSReg rs, s16 imm) { // 001010 sssss ttttt iiiiiiiiiiiiiiii - _dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x0a, 21, rs, 16, rt, 0, (u16)imm); } void MIPSEmitter::SLTIU(MIPSReg rt, MIPSReg rs, s16 imm) { // 001011 sssss ttttt iiiiiiiiiiiiiiii - _dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x0b, 21, rs, 16, rt, 0, (u16)imm); } void MIPSEmitter::ADDU(MIPSReg rd, MIPSReg rs, MIPSReg rt) { // 000000 sssss ttttt ddddd 00000100001 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x21); } void MIPSEmitter::SUBU(MIPSReg rd, MIPSReg rs, MIPSReg rt) { // 000000 sssss ttttt ddddd 00000100011 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x23); } void MIPSEmitter::ADDIU(MIPSReg rt, MIPSReg rs, s16 imm) { // 001001 sssss ttttt iiiiiiiiiiiiiiii - _dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x09, 21, rs, 16, rt, 0, (u16)imm); } void MIPSEmitter::AND(MIPSReg rd, MIPSReg rs, MIPSReg rt) { // 000000 sssss ttttt ddddd 00000100100 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x24); } void MIPSEmitter::OR(MIPSReg rd, MIPSReg rs, MIPSReg rt) { // 000000 sssss ttttt ddddd 00000100101 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x25); } void MIPSEmitter::XOR(MIPSReg rd, MIPSReg rs, MIPSReg rt) { // 000000 sssss ttttt ddddd 00000100110 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && rs < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x00, 21, rs, 16, rt, 11, rd, 0, 0x26); } void MIPSEmitter::ANDI(MIPSReg rt, MIPSReg rs, s16 imm) { // 001100 sssss ttttt iiiiiiiiiiiiiiii - _dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x0c, 21, rs, 16, rt, 0, (u16)imm); } void MIPSEmitter::ORI(MIPSReg rt, MIPSReg rs, s16 imm) { // 001101 sssss ttttt iiiiiiiiiiiiiiii - _dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x0d, 21, rs, 16, rt, 0, (u16)imm); } void MIPSEmitter::XORI(MIPSReg rt, MIPSReg rs, s16 imm) { // 001110 sssss ttttt iiiiiiiiiiiiiiii - _dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rs < F_BASE && rt < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x0e, 21, rs, 16, rt, 0, (u16)imm); } void MIPSEmitter::LUI(MIPSReg rt, s16 imm) { // 001111 00000 ttttt iiiiiiiiiiiiiiii - _dbg_assert_msg_(JIT, rt < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(rt < F_BASE, "Bad emitter arguments"); Write32Fields(26, 0x0f, 16, rt, 0, (u16)imm); } void MIPSEmitter::INS(MIPSReg rt, MIPSReg rs, s8 pos, s8 size) { // 011111 sssss ttttt xxxxx yyyyy 000100 - _dbg_assert_msg_(JIT, rt < F_BASE && rs < F_BASE && pos <= 0x1f && (size+pos+1) <= 0x1f, "Bad emitter arguments"); + _dbg_assert_msg_(rt < F_BASE && rs < F_BASE && pos <= 0x1f && (size+pos+1) <= 0x1f, "Bad emitter arguments"); Write32Fields(26, 0x1f, 21, rt, 16, rs, 11, (size+pos+1) & 0x1f, 6, pos & 0x1f, 0, 0x04); } void MIPSEmitter::EXT(MIPSReg rt, MIPSReg rs, s8 pos, s8 size) { // 111111 sssss ttttt xxxxx yyyyy 000000 - _dbg_assert_msg_(JIT, rt < F_BASE && rs < F_BASE && pos <= 0x1f && size >= 1, "Bad emitter arguments"); + _dbg_assert_msg_(rt < F_BASE && rs < F_BASE && pos <= 0x1f && size >= 1, "Bad emitter arguments"); Write32Fields(26, 0x3f, 21, rt, 16, rs, 11, (size-1) & 0x1f, 6, pos & 0x1f, 0, 0x00); } void MIPSEmitter::DSLL(MIPSReg rd, MIPSReg rt, u8 sa) { // 000000 xxxxx ttttt ddddd aaaaa 111000 DSLL // 000000 xxxxx ttttt ddddd aaaaa 111100 DSLL32 - _dbg_assert_msg_(JIT, rd < F_BASE && rt < F_BASE && sa <= 0x3f, "Bad emitter arguments"); + _dbg_assert_msg_(rd < F_BASE && rt < F_BASE && sa <= 0x3f, "Bad emitter arguments"); // TODO: Assert MIPS64. if (sa >= 32) { Write32Fields(26, 0x00, 16, rt, 11, rd, 6, (sa - 32) & 0x1f, 0, 0x3c); @@ -438,7 +438,7 @@ void MIPSEmitter::DSLL(MIPSReg rd, MIPSReg rt, u8 sa) { } void MIPSEmitter::MOVI2R(MIPSReg reg, u64 imm) { - _dbg_assert_msg_(JIT, reg < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(reg < F_BASE, "Bad emitter arguments"); // TODO: Assert MIPS64. // Probably better to use a literal pool and load. @@ -451,7 +451,7 @@ void MIPSEmitter::MOVI2R(MIPSReg reg, u64 imm) { } void MIPSEmitter::MOVI2R(MIPSReg reg, u32 imm) { - _dbg_assert_msg_(JIT, reg < F_BASE, "Bad emitter arguments"); + _dbg_assert_msg_(reg < F_BASE, "Bad emitter arguments"); if ((imm & 0xffff0000) != 0) { #if 0 diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index e4aa024173..abf4072a23 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -781,7 +781,7 @@ VkResult VulkanContext::ReinitSurface() { #endif default: - _assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented"); + _assert_msg_(false, "Vulkan support for chosen window system not implemented"); return VK_ERROR_INITIALIZATION_FAILED; } @@ -843,7 +843,7 @@ bool VulkanContext::ChooseQueue() { // Get the list of VkFormats that are supported: uint32_t formatCount = 0; VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, nullptr); - _assert_msg_(G3D, res == VK_SUCCESS, "Failed to get formats for device %d: %d", physical_device_, (int)res); + _assert_msg_(res == VK_SUCCESS, "Failed to get formats for device %d: %d", physical_device_, (int)res); if (res != VK_SUCCESS) { return false; } diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 614cd0e3fb..d6f3f53877 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -101,7 +101,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem_); if (res != VK_SUCCESS) { ELOG("vkAllocateMemory failed: %s", VulkanResultToString(res)); - _assert_msg_(G3D, res != VK_ERROR_TOO_MANY_OBJECTS, "Too many Vulkan memory objects!"); + _assert_msg_(res != VK_ERROR_TOO_MANY_OBJECTS, "Too many Vulkan memory objects!"); _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; } @@ -178,8 +178,8 @@ void VulkanTexture::UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mi } void VulkanTexture::GenerateMip(VkCommandBuffer cmd, int mip) { - _assert_msg_(G3D, mip != 0, "Cannot generate the first level"); - _assert_msg_(G3D, mip < numMips_, "Cannot generate mipmaps past the maximum created (%d vs %d)", mip, numMips_); + _assert_msg_(mip != 0, "Cannot generate the first level"); + _assert_msg_(mip < numMips_, "Cannot generate mipmaps past the maximum created (%d vs %d)", mip, numMips_); VkImageBlit blit{}; blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; blit.srcSubresource.layerCount = 1; diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 3673d3ea6f..0974bb8000 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -47,7 +47,7 @@ bool VulkanPushBuffer::AddBuffer() { VkResult res = vkCreateBuffer(device, &b, nullptr, &info.buffer); if (VK_SUCCESS != res) { - _assert_msg_(G3D, false, "vkCreateBuffer failed! result=%d", (int)res); + _assert_msg_(false, "vkCreateBuffer failed! result=%d", (int)res); return false; } @@ -62,7 +62,7 @@ bool VulkanPushBuffer::AddBuffer() { 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); + _assert_msg_(false, "vkAllocateMemory failed! size=%d result=%d", (int)reqs.size, (int)res); vkDestroyBuffer(device, info.buffer, nullptr); return false; } @@ -136,14 +136,14 @@ size_t VulkanPushBuffer::GetTotalSize() const { } void VulkanPushBuffer::Map() { - _dbg_assert_(G3D, !writePtr_); + _dbg_assert_(!writePtr_); VkResult res = vkMapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_)); - _dbg_assert_(G3D, writePtr_); + _dbg_assert_(writePtr_); assert(VK_SUCCESS == res); } void VulkanPushBuffer::Unmap() { - _dbg_assert_(G3D, writePtr_ != 0); + _dbg_assert_(writePtr_ != 0); if ((memoryPropertyMask_ & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) { VkMappedMemoryRange range{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; @@ -177,7 +177,7 @@ void VulkanDeviceAllocator::Destroy() { if (slabUsage == 1) { ERROR_LOG(G3D, "VulkanDeviceAllocator detected memory leak of size %d", (int)pair.second); } else { - _dbg_assert_msg_(G3D, slabUsage == 2, "Destroy: slabUsage has unexpected value %d", slabUsage); + _dbg_assert_msg_(slabUsage == 2, "Destroy: slabUsage has unexpected value %d", slabUsage); } } @@ -314,13 +314,13 @@ void VulkanDeviceAllocator::DoTouch(VkDeviceMemory deviceMemory, size_t offset) } } - _assert_msg_(G3D, found, "Failed to find allocation to touch - use after free?"); + _assert_msg_(found, "Failed to find allocation to touch - use after free?"); } void VulkanDeviceAllocator::Free(VkDeviceMemory deviceMemory, size_t offset) { assert(!destroyed_); - _assert_msg_(G3D, !slabs_.empty(), "No slabs - can't be anything to free! double-freed?"); + _assert_msg_(!slabs_.empty(), "No slabs - can't be anything to free! double-freed?"); // First, let's validate. This will allow stack traces to tell us when frees are bad. size_t start = offset >> SLAB_GRAIN_SHIFT; @@ -331,9 +331,9 @@ void VulkanDeviceAllocator::Free(VkDeviceMemory deviceMemory, size_t offset) { } auto it = slab.allocSizes.find(start); - _assert_msg_(G3D, it != slab.allocSizes.end(), "Double free?"); + _assert_msg_(it != slab.allocSizes.end(), "Double free?"); // This means a double free, while queued to actually free. - _assert_msg_(G3D, slab.usage[start] == 1, "Double free when queued to free!"); + _assert_msg_(slab.usage[start] == 1, "Double free when queued to free!"); // Mark it as "free in progress". slab.usage[start] = 2; @@ -342,7 +342,7 @@ void VulkanDeviceAllocator::Free(VkDeviceMemory deviceMemory, size_t offset) { } // Wrong deviceMemory even? Maybe it was already decimated, but that means a double-free. - _assert_msg_(G3D, found, "Failed to find allocation to free! Double-freed?"); + _assert_msg_(found, "Failed to find allocation to free! Double-freed?"); // Okay, now enqueue. It's valid. FreeInfo *info = new FreeInfo(this, deviceMemory, offset); @@ -383,7 +383,7 @@ void VulkanDeviceAllocator::ExecuteFree(FreeInfo *userdata) { } } else { // Ack, a double free? - _assert_msg_(G3D, false, "Double free? Block missing at offset %d", (int)userdata->offset); + _assert_msg_(false, "Double free? Block missing at offset %d", (int)userdata->offset); } auto itTag = slab.tags.find(start); if (itTag != slab.tags.end()) { @@ -394,7 +394,7 @@ void VulkanDeviceAllocator::ExecuteFree(FreeInfo *userdata) { } // Wrong deviceMemory even? Maybe it was already decimated, but that means a double-free. - _assert_msg_(G3D, found, "ExecuteFree: Block not found (offset %d)", (int)offset); + _assert_msg_(found, "ExecuteFree: Block not found (offset %d)", (int)offset); delete userdata; } diff --git a/Common/x64Emitter.cpp b/Common/x64Emitter.cpp index df14332f13..1639b4a1c8 100644 --- a/Common/x64Emitter.cpp +++ b/Common/x64Emitter.cpp @@ -25,9 +25,6 @@ #define PRIx64 "llx" -// Minimize the diff against Dolphin -#define DYNA_REC JIT - namespace Gen { @@ -148,7 +145,7 @@ const u8 *XEmitter::AlignCodePage() // causing a subtle JIT bug. void XEmitter::CheckFlags() { - _assert_msg_(DYNA_REC, !flags_locked, "Attempt to modify flags while flags locked!"); + _assert_msg_(!flags_locked, "Attempt to modify flags while flags locked!"); } void XEmitter::WriteModRM(int mod, int reg, int rm) @@ -182,16 +179,16 @@ void OpArg::WriteRex(XEmitter *emit, int opBits, int bits, int customOp) const { emit->Write8(op); // Check the operation doesn't access AH, BH, CH, or DH. - _dbg_assert_(DYNA_REC, (offsetOrBaseReg & 0x100) == 0); - _dbg_assert_(DYNA_REC, (customOp & 0x100) == 0); + _dbg_assert_((offsetOrBaseReg & 0x100) == 0); + _dbg_assert_((customOp & 0x100) == 0); } #else - _dbg_assert_(DYNA_REC, opBits != 64); - _dbg_assert_(DYNA_REC, (customOp & 8) == 0 || customOp == -1); - _dbg_assert_(DYNA_REC, (indexReg & 8) == 0); - _dbg_assert_(DYNA_REC, (offsetOrBaseReg & 8) == 0); - _dbg_assert_(DYNA_REC, opBits != 8 || (customOp & 0x10c) != 4 || customOp == -1); - _dbg_assert_(DYNA_REC, scale == SCALE_ATREG || bits != 8 || (offsetOrBaseReg & 0x10c) != 4); + _dbg_assert_(opBits != 64); + _dbg_assert_((customOp & 8) == 0 || customOp == -1); + _dbg_assert_((indexReg & 8) == 0); + _dbg_assert_((offsetOrBaseReg & 8) == 0); + _dbg_assert_(opBits != 8 || (customOp & 0x10c) != 4 || customOp == -1); + _dbg_assert_(scale == SCALE_ATREG || bits != 8 || (offsetOrBaseReg & 0x10c) != 4); #endif } @@ -239,7 +236,7 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg, #ifdef _M_X64 u64 ripAddr = (u64)emit->GetCodePointer() + 4 + extraBytes; s64 distance = (s64)offset - (s64)ripAddr; - _assert_msg_(DYNA_REC, + _assert_msg_( (distance < 0x80000000LL && distance >= -0x80000000LL) || !warn_64bit_offset, @@ -344,7 +341,7 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg, case SCALE_NOBASE_4: ss = 2; break; case SCALE_NOBASE_8: ss = 3; break; case SCALE_ATREG: ss = 0; break; - default: _assert_msg_(DYNA_REC, 0, "Invalid scale for SIB byte"); ss = 0; break; + default: _assert_msg_(false, "Invalid scale for SIB byte"); ss = 0; break; } emit->Write8((u8)((ss << 6) | ((ireg&7)<<3) | (_offsetOrBaseReg&7))); } @@ -380,7 +377,7 @@ void XEmitter::JMP(const u8 *addr, bool force5Bytes) if (!force5Bytes) { s64 distance = (s64)(fn - ((u64)code + 2)); - _assert_msg_(DYNA_REC, distance >= -0x80 && distance < 0x80, + _assert_msg_(distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true"); //8 bits will do Write8(0xEB); @@ -390,8 +387,7 @@ void XEmitter::JMP(const u8 *addr, bool force5Bytes) { s64 distance = (s64)(fn - ((u64)code + 5)); - _assert_msg_(DYNA_REC, - distance >= -0x80000000LL && distance < 0x80000000LL, + _assert_msg_(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); Write8(0xE9); Write32((u32)(s32)distance); @@ -401,7 +397,7 @@ void XEmitter::JMP(const u8 *addr, bool force5Bytes) void XEmitter::JMPptr(const OpArg &arg2) { OpArg arg = arg2; - if (arg.IsImm()) _assert_msg_(DYNA_REC, 0, "JMPptr - Imm argument"); + if (arg.IsImm()) _assert_msg_(false, "JMPptr - Imm argument"); arg.operandReg = 4; arg.WriteRex(this, 0, 0); Write8(0xFF); @@ -418,7 +414,7 @@ void XEmitter::JMPself() void XEmitter::CALLptr(OpArg arg) { - if (arg.IsImm()) _assert_msg_(DYNA_REC, 0, "CALLptr - Imm argument"); + if (arg.IsImm()) _assert_msg_(false, "CALLptr - Imm argument"); arg.operandReg = 2; arg.WriteRex(this, 0, 0); Write8(0xFF); @@ -428,8 +424,7 @@ void XEmitter::CALLptr(OpArg arg) void XEmitter::CALL(const void *fnptr) { u64 distance = u64(fnptr) - (u64(code) + 5); - _assert_msg_(DYNA_REC, - distance < 0x0000000080000000ULL || + _assert_msg_(distance < 0x0000000080000000ULL || distance >= 0xFFFFFFFF80000000ULL, "CALL out of range (%p calls %p)", code, fnptr); Write8(0xE8); @@ -482,8 +477,7 @@ void XEmitter::J_CC(CCFlags conditionCode, const u8* addr, bool force5bytes) if (distance < -0x80 || distance >= 0x80 || force5bytes) { distance = (s64)(fn - ((u64)code + 6)); - _assert_msg_(DYNA_REC, - distance >= -0x80000000LL && distance < 0x80000000LL, + _assert_msg_(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); Write8(0x0F); Write8(0x80 + conditionCode); @@ -501,13 +495,13 @@ void XEmitter::SetJumpTarget(const FixupBranch &branch) if (branch.type == 0) { s64 distance = (s64)(code - branch.ptr); - _assert_msg_(DYNA_REC, distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true"); + _assert_msg_(distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true"); branch.ptr[-1] = (u8)(s8)distance; } else if (branch.type == 1) { s64 distance = (s64)(code - branch.ptr); - _assert_msg_(DYNA_REC, distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); + _assert_msg_(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); ((s32*)branch.ptr)[-1] = (s32)distance; } } @@ -518,7 +512,7 @@ void XEmitter::SetJumpTarget(const FixupBranch &branch) /* void XEmitter::INC(int bits, OpArg arg) { - if (arg.IsImm()) _assert_msg_(DYNA_REC, 0, "INC - Imm argument"); + if (arg.IsImm()) _assert_msg_(false, "INC - Imm argument"); arg.operandReg = 0; if (bits == 16) {Write8(0x66);} arg.WriteRex(this, bits, bits); @@ -527,7 +521,7 @@ void XEmitter::INC(int bits, OpArg arg) } void XEmitter::DEC(int bits, OpArg arg) { - if (arg.IsImm()) _assert_msg_(DYNA_REC, 0, "DEC - Imm argument"); + if (arg.IsImm()) _assert_msg_(false, "DEC - Imm argument"); arg.operandReg = 1; if (bits == 16) {Write8(0x66);} arg.WriteRex(this, bits, bits); @@ -545,7 +539,7 @@ void XEmitter::RET_FAST() {Write8(0xF3); Write8(0xC3);} //two-byte return (rep // The first sign of decadence: optimized NOPs. void XEmitter::NOP(size_t size) { - _dbg_assert_(DYNA_REC, (int)size > 0); + _dbg_assert_((int)size > 0); while (true) { switch (size) @@ -689,7 +683,7 @@ void XEmitter::PUSH(int bits, const OpArg ®) Write32((u32)reg.offset); break; default: - _assert_msg_(DYNA_REC, 0, "PUSH - Bad imm bits"); + _assert_msg_(false, "PUSH - Bad imm bits"); break; } } @@ -708,7 +702,7 @@ void XEmitter::POP(int /*bits*/, const OpArg ®) if (reg.IsSimpleReg()) POP(reg.GetSimpleReg()); else - _assert_msg_(DYNA_REC, 0, "POP - Unsupported encoding"); + _assert_msg_(false, "POP - Unsupported encoding"); } void XEmitter::BSWAP(int bits, X64Reg reg) @@ -727,7 +721,7 @@ void XEmitter::BSWAP(int bits, X64Reg reg) } else { - _assert_msg_(DYNA_REC, 0, "BSWAP - Wrong number of bits"); + _assert_msg_(false, "BSWAP - Wrong number of bits"); } } @@ -741,7 +735,7 @@ void XEmitter::UD2() void XEmitter::PREFETCH(PrefetchLevel level, OpArg arg) { - _assert_msg_(DYNA_REC, !arg.IsImm(), "PREFETCH - Imm argument"); + _assert_msg_(!arg.IsImm(), "PREFETCH - Imm argument"); arg.operandReg = (u8)level; arg.WriteRex(this, 0, 0); Write8(0x0F); @@ -751,7 +745,7 @@ void XEmitter::PREFETCH(PrefetchLevel level, OpArg arg) void XEmitter::SETcc(CCFlags flag, OpArg dest) { - _assert_msg_(DYNA_REC, !dest.IsImm(), "SETcc - Imm argument"); + _assert_msg_(!dest.IsImm(), "SETcc - Imm argument"); dest.operandReg = 0; dest.WriteRex(this, 0, 8); Write8(0x0F); @@ -761,8 +755,8 @@ void XEmitter::SETcc(CCFlags flag, OpArg dest) void XEmitter::CMOVcc(int bits, X64Reg dest, OpArg src, CCFlags flag) { - _assert_msg_(DYNA_REC, !src.IsImm(), "CMOVcc - Imm argument"); - _assert_msg_(DYNA_REC, bits != 8, "CMOVcc - 8 bits unsupported"); + _assert_msg_(!src.IsImm(), "CMOVcc - Imm argument"); + _assert_msg_(bits != 8, "CMOVcc - 8 bits unsupported"); if (bits == 16) Write8(0x66); src.operandReg = dest; @@ -774,7 +768,7 @@ void XEmitter::CMOVcc(int bits, X64Reg dest, OpArg src, CCFlags flag) void XEmitter::WriteMulDivType(int bits, OpArg src, int ext) { - _assert_msg_(DYNA_REC, !src.IsImm(), "WriteMulDivType - Imm argument"); + _assert_msg_(!src.IsImm(), "WriteMulDivType - Imm argument"); CheckFlags(); src.operandReg = ext; if (bits == 16) @@ -800,7 +794,7 @@ void XEmitter::NOT(int bits, OpArg src) {WriteMulDivType(bits, src, 2);} void XEmitter::WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2, bool rep) { - _assert_msg_(DYNA_REC, !src.IsImm(), "WriteBitSearchType - Imm argument"); + _assert_msg_(!src.IsImm(), "WriteBitSearchType - Imm argument"); CheckFlags(); src.operandReg = (u8)dest; if (bits == 16) @@ -816,7 +810,7 @@ void XEmitter::WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2, bo void XEmitter::MOVNTI(int bits, OpArg dest, X64Reg src) { if (bits <= 16) - _assert_msg_(DYNA_REC, 0, "MOVNTI - bits<=16"); + _assert_msg_(false, "MOVNTI - bits<=16"); WriteBitSearchType(bits, src, dest, 0xC3); } @@ -840,7 +834,7 @@ void XEmitter::LZCNT(int bits, X64Reg dest, OpArg src) void XEmitter::MOVSX(int dbits, int sbits, X64Reg dest, OpArg src) { - _assert_msg_(DYNA_REC, !src.IsImm(), "MOVSX - Imm argument"); + _assert_msg_(!src.IsImm(), "MOVSX - Imm argument"); if (dbits == sbits) { MOV(dbits, R(dest), src); @@ -873,7 +867,7 @@ void XEmitter::MOVSX(int dbits, int sbits, X64Reg dest, OpArg src) void XEmitter::MOVZX(int dbits, int sbits, X64Reg dest, OpArg src) { - _assert_msg_(DYNA_REC, !src.IsImm(), "MOVZX - Imm argument"); + _assert_msg_(!src.IsImm(), "MOVZX - Imm argument"); if (dbits == sbits) { MOV(dbits, R(dest), src); @@ -900,14 +894,14 @@ void XEmitter::MOVZX(int dbits, int sbits, X64Reg dest, OpArg src) } else { - _assert_msg_(DYNA_REC, 0, "MOVZX - Invalid size"); + _assert_msg_(false, "MOVZX - Invalid size"); } src.WriteRest(this); } void XEmitter::MOVBE(int bits, const OpArg& dest, const OpArg& src) { - _assert_msg_(DYNA_REC, cpu_info.bMOVBE, "Generating MOVBE on a system that does not support it."); + _assert_msg_(cpu_info.bMOVBE, "Generating MOVBE on a system that does not support it."); if (bits == 8) { MOV(bits, dest, src); @@ -919,28 +913,28 @@ void XEmitter::MOVBE(int bits, const OpArg& dest, const OpArg& src) if (dest.IsSimpleReg()) { - _assert_msg_(DYNA_REC, !src.IsSimpleReg() && !src.IsImm(), "MOVBE: Loading from !mem"); + _assert_msg_(!src.IsSimpleReg() && !src.IsImm(), "MOVBE: Loading from !mem"); src.WriteRex(this, bits, bits, dest.GetSimpleReg()); Write8(0x0F); Write8(0x38); Write8(0xF0); src.WriteRest(this, 0, dest.GetSimpleReg()); } else if (src.IsSimpleReg()) { - _assert_msg_(DYNA_REC, !dest.IsSimpleReg() && !dest.IsImm(), "MOVBE: Storing to !mem"); + _assert_msg_(!dest.IsSimpleReg() && !dest.IsImm(), "MOVBE: Storing to !mem"); dest.WriteRex(this, bits, bits, src.GetSimpleReg()); Write8(0x0F); Write8(0x38); Write8(0xF1); dest.WriteRest(this, 0, src.GetSimpleReg()); } else { - _assert_msg_(DYNA_REC, 0, "MOVBE: Not loading or storing to mem"); + _assert_msg_(false, "MOVBE: Not loading or storing to mem"); } } void XEmitter::LEA(int bits, X64Reg dest, OpArg src) { - _assert_msg_(DYNA_REC, !src.IsImm(), "LEA - Imm argument"); + _assert_msg_(!src.IsImm(), "LEA - Imm argument"); src.operandReg = (u8)dest; if (bits == 16) Write8(0x66); //TODO: performance warning @@ -956,11 +950,11 @@ void XEmitter::WriteShift(int bits, OpArg dest, OpArg &shift, int ext) bool writeImm = false; if (dest.IsImm()) { - _assert_msg_(DYNA_REC, 0, "WriteShift - can't shift imms"); + _assert_msg_(false, "WriteShift - can't shift imms"); } if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8)) { - _assert_msg_(DYNA_REC, 0, "WriteShift - illegal argument"); + _assert_msg_(false, "WriteShift - illegal argument"); } dest.operandReg = ext; if (bits == 16) @@ -1005,11 +999,11 @@ void XEmitter::WriteBitTest(int bits, OpArg &dest, OpArg &index, int ext) CheckFlags(); if (dest.IsImm()) { - _assert_msg_(DYNA_REC, 0, "WriteBitTest - can't test imms"); + _assert_msg_(false, "WriteBitTest - can't test imms"); } if ((index.IsImm() && index.GetImmBits() != 8)) { - _assert_msg_(DYNA_REC, 0, "WriteBitTest - illegal argument"); + _assert_msg_(false, "WriteBitTest - illegal argument"); } if (bits == 16) Write8(0x66); @@ -1040,15 +1034,15 @@ void XEmitter::SHRD(int bits, OpArg dest, OpArg src, OpArg shift) CheckFlags(); if (dest.IsImm()) { - _assert_msg_(DYNA_REC, 0, "SHRD - can't use imms as destination"); + _assert_msg_(false, "SHRD - can't use imms as destination"); } if (!src.IsSimpleReg()) { - _assert_msg_(DYNA_REC, 0, "SHRD - must use simple register as source"); + _assert_msg_(false, "SHRD - must use simple register as source"); } if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8)) { - _assert_msg_(DYNA_REC, 0, "SHRD - illegal shift"); + _assert_msg_(false, "SHRD - illegal shift"); } if (bits == 16) Write8(0x66); @@ -1072,15 +1066,15 @@ void XEmitter::SHLD(int bits, OpArg dest, OpArg src, OpArg shift) CheckFlags(); if (dest.IsImm()) { - _assert_msg_(DYNA_REC, 0, "SHLD - can't use imms as destination"); + _assert_msg_(false, "SHLD - can't use imms as destination"); } if (!src.IsSimpleReg()) { - _assert_msg_(DYNA_REC, 0, "SHLD - must use simple register as source"); + _assert_msg_(false, "SHLD - must use simple register as source"); } if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8)) { - _assert_msg_(DYNA_REC, 0, "SHLD - illegal shift"); + _assert_msg_(false, "SHLD - illegal shift"); } if (bits == 16) Write8(0x66); @@ -1116,7 +1110,7 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &o X64Reg _operandReg; if (IsImm()) { - _assert_msg_(DYNA_REC, 0, "WriteNormalOp - Imm argument, wrong order"); + _assert_msg_(false, "WriteNormalOp - Imm argument, wrong order"); } if (bits == 16) @@ -1130,7 +1124,7 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &o if (!toRM) { - _assert_msg_(DYNA_REC, 0, "WriteNormalOp - Writing to Imm (!toRM)"); + _assert_msg_(false, "WriteNormalOp - Writing to Imm (!toRM)"); } if (operand.scale == SCALE_IMM8 && bits == 8) @@ -1206,7 +1200,7 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &o { if (scale) { - _assert_msg_(DYNA_REC, 0, "WriteNormalOp - MOV with 64-bit imm requres register destination"); + _assert_msg_(false, "WriteNormalOp - MOV with 64-bit imm requres register destination"); } // mov reg64, imm64 else if (op == nrmMOV) @@ -1215,11 +1209,11 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &o emit->Write64((u64)operand.offset); return; } - _assert_msg_(DYNA_REC, 0, "WriteNormalOp - Only MOV can take 64-bit imm"); + _assert_msg_(false, "WriteNormalOp - Only MOV can take 64-bit imm"); } else { - _assert_msg_(DYNA_REC, 0, "WriteNormalOp - Unhandled case"); + _assert_msg_(false, "WriteNormalOp - Unhandled case"); } _operandReg = (X64Reg)normalops[op].ext; //pass extension in REG of ModRM } @@ -1253,7 +1247,7 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &o emit->Write32((u32)operand.offset); break; default: - _assert_msg_(DYNA_REC, 0, "WriteNormalOp - Unhandled case"); + _assert_msg_(false, "WriteNormalOp - Unhandled case"); } } @@ -1262,7 +1256,7 @@ void XEmitter::WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg if (a1.IsImm()) { //Booh! Can't write to an imm - _assert_msg_(DYNA_REC, 0, "WriteNormalOp - a1 cannot be imm"); + _assert_msg_(false, "WriteNormalOp - a1 cannot be imm"); return; } if (a2.IsImm()) @@ -1277,7 +1271,7 @@ void XEmitter::WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg } else { - _assert_msg_(DYNA_REC, a2.IsSimpleReg() || a2.IsImm(), "WriteNormalOp - a1 and a2 cannot both be memory"); + _assert_msg_(a2.IsSimpleReg() || a2.IsImm(), "WriteNormalOp - a1 and a2 cannot both be memory"); a1.WriteNormalOp(emit, true, op, a2, bits); } } @@ -1293,7 +1287,7 @@ void XEmitter::XOR (int bits, const OpArg &a1, const OpArg &a2) {CheckFlags(); W void XEmitter::MOV (int bits, const OpArg &a1, const OpArg &a2) { if (a1.IsSimpleReg() && a2.IsSimpleReg() && a1.GetSimpleReg() == a2.GetSimpleReg()) - ERROR_LOG(DYNA_REC, "Redundant MOV @ %p - bug in JIT?", code); + ERROR_LOG(JIT, "Redundant MOV @ %p - bug in JIT?", code); WriteNormalOp(this, bits, nrmMOV, a1, a2); } void XEmitter::TEST(int bits, const OpArg &a1, const OpArg &a2) {CheckFlags(); WriteNormalOp(this, bits, nrmTEST, a1, a2);} @@ -1305,19 +1299,19 @@ void XEmitter::IMUL(int bits, X64Reg regOp, OpArg a1, OpArg a2) CheckFlags(); if (bits == 8) { - _assert_msg_(DYNA_REC, 0, "IMUL - illegal bit size!"); + _assert_msg_(false, "IMUL - illegal bit size!"); return; } if (a1.IsImm()) { - _assert_msg_(DYNA_REC, 0, "IMUL - second arg cannot be imm!"); + _assert_msg_(false, "IMUL - second arg cannot be imm!"); return; } if (!a2.IsImm()) { - _assert_msg_(DYNA_REC, 0, "IMUL - third arg must be imm!"); + _assert_msg_(false, "IMUL - third arg must be imm!"); return; } @@ -1348,7 +1342,7 @@ void XEmitter::IMUL(int bits, X64Reg regOp, OpArg a1, OpArg a2) } else { - _assert_msg_(DYNA_REC, 0, "IMUL - unhandled case!"); + _assert_msg_(false, "IMUL - unhandled case!"); } } } @@ -1358,7 +1352,7 @@ void XEmitter::IMUL(int bits, X64Reg regOp, OpArg a) CheckFlags(); if (bits == 8) { - _assert_msg_(DYNA_REC, 0, "IMUL - illegal bit size!"); + _assert_msg_(false, "IMUL - illegal bit size!"); return; } @@ -1508,7 +1502,7 @@ void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src) void XEmitter::WriteMXCSR(OpArg arg, int ext) { if (arg.IsImm() || arg.IsSimpleReg()) - _assert_msg_(DYNA_REC, 0, "MXCSR - invalid operand"); + _assert_msg_(false, "MXCSR - invalid operand"); arg.operandReg = ext; arg.WriteRex(this, 0, 0); @@ -1968,13 +1962,13 @@ void XEmitter::FWAIT() void XEmitter::WriteFloatLoadStore(int bits, FloatOp op, FloatOp op_80b, OpArg arg) { int mf = 0; - _assert_msg_(DYNA_REC, !(bits == 80 && op_80b == floatINVALID), "WriteFloatLoadStore: 80 bits not supported for this instruction"); + _assert_msg_(!(bits == 80 && op_80b == floatINVALID), "WriteFloatLoadStore: 80 bits not supported for this instruction"); switch (bits) { case 32: mf = 0; break; case 64: mf = 4; break; case 80: mf = 2; break; - default: _assert_msg_(DYNA_REC, 0, "WriteFloatLoadStore: invalid bits (should be 32/64/80)"); + default: _assert_msg_(false, "WriteFloatLoadStore: invalid bits (should be 32/64/80)"); } Write8(0xd9 | mf); // x87 instructions use the reg field of the ModR/M byte as opcode: diff --git a/Common/x64Emitter.h b/Common/x64Emitter.h index 30309f71ba..a89cd11afb 100644 --- a/Common/x64Emitter.h +++ b/Common/x64Emitter.h @@ -292,7 +292,7 @@ template<> inline u32 PtrOffsetTpl<8>(const void *ptr, const void* base) { if (distance >= 0x80000000LL || distance < -0x80000000LL) { - _assert_msg_(DYNA_REC, 0, "pointer offset out of range"); + _assert_msg_(false, "pointer offset out of range"); return 0; } diff --git a/Core/Config.cpp b/Core/Config.cpp index 94a52cf781..892482ca42 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -249,7 +249,7 @@ struct ConfigSetting { } return true; default: - _dbg_assert_msg_(LOADER, false, "Unexpected ini setting type"); + _dbg_assert_msg_(false, "Unexpected ini setting type"); return false; } } @@ -282,7 +282,7 @@ struct ConfigSetting { } return; default: - _dbg_assert_msg_(LOADER, false, "Unexpected ini setting type"); + _dbg_assert_msg_(false, "Unexpected ini setting type"); return; } } @@ -306,7 +306,7 @@ struct ConfigSetting { // Doesn't report. return; default: - _dbg_assert_msg_(LOADER, false, "Unexpected ini setting type"); + _dbg_assert_msg_(false, "Unexpected ini setting type"); return; } } diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 251a2c0f9e..686ade0e71 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -183,7 +183,7 @@ void AntiCrashCallback(u64 userdata, int cyclesLate) void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callback) { - _assert_msg_(CORETIMING, event_type >= 0, "Invalid event type %d", event_type) + _assert_msg_(event_type >= 0, "Invalid event type %d", event_type) if (event_type >= (int) event_types.size()) event_types.resize(event_type + 1, EventType(AntiCrashCallback, "INVALID EVENT")); @@ -572,7 +572,7 @@ void ForceCheck() slicelength = -1; #ifdef _DEBUG - _dbg_assert_msg_(CPU, cyclesExecuted >= 0, "Shouldn't have a negative cyclesExecuted"); + _dbg_assert_msg_( cyclesExecuted >= 0, "Shouldn't have a negative cyclesExecuted"); #endif } diff --git a/Core/FileLoaders/DiskCachingFileLoader.cpp b/Core/FileLoaders/DiskCachingFileLoader.cpp index 62f733dc89..4b8888c802 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.cpp +++ b/Core/FileLoaders/DiskCachingFileLoader.cpp @@ -398,7 +398,7 @@ u32 DiskCachingFileLoaderCache::AllocateBlock(u32 indexPos) { } } - _dbg_assert_msg_(LOADER, false, "Not enough free blocks"); + _dbg_assert_msg_(false, "Not enough free blocks"); return INVALID_BLOCK; } diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 3f481a2f9b..b0461ba014 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -535,7 +535,9 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) { u32 secNum = (u32)(positionOnIso / 2048); u8 theSector[2048]; - _dbg_assert_msg_(FILESYS, (middleSize & 2047) == 0, "Remaining size should be aligned"); + if ((middleSize & 2047) != 0) { + ERROR_LOG(FILESYS, "Remaining size should be aligned"); + } const u8 *const start = pointer; if (firstBlockSize > 0) { diff --git a/Core/FileSystems/tlzrc.cpp b/Core/FileSystems/tlzrc.cpp index 851e1c12e6..5692d52d92 100644 --- a/Core/FileSystems/tlzrc.cpp +++ b/Core/FileSystems/tlzrc.cpp @@ -63,7 +63,7 @@ typedef struct{ static u8 rc_getbyte(LZRC_DECODE *rc) { if(rc->in_ptr == rc->in_len){ - _dbg_assert_msg_(LOADER, false, "LZRC: End of input!"); + _dbg_assert_msg_(false, "LZRC: End of input!"); } return rc->input[rc->in_ptr++]; @@ -72,7 +72,7 @@ static u8 rc_getbyte(LZRC_DECODE *rc) static void rc_putbyte(LZRC_DECODE *rc, u8 byte) { if(rc->out_ptr == rc->out_len){ - _dbg_assert_msg_(LOADER, false, "LZRC: Output overflow!"); + _dbg_assert_msg_(false, "LZRC: Output overflow!"); } rc->output[rc->out_ptr++] = byte; diff --git a/Core/Font/PGF.cpp b/Core/Font/PGF.cpp index 9113498425..2383736a94 100644 --- a/Core/Font/PGF.cpp +++ b/Core/Font/PGF.cpp @@ -37,7 +37,7 @@ static bool isJPCSPFont(const char *fontName) { // Gets a number of bits from an offset. static int getBits(int numBits, const u8 *buf, size_t pos) { - _dbg_assert_msg_(SCEFONT, numBits <= 32, "Unable to return more than 32 bits, %d requested", numBits); + _dbg_assert_msg_(numBits <= 32, "Unable to return more than 32 bits, %d requested", numBits); const size_t wordpos = pos >> 5; const u32 *wordbuf = (const u32 *)buf; diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index d1dadad229..cde8b2cf37 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -215,7 +215,7 @@ const HLEFunction *GetFunc(const char *moduleName, u32 nib) const char *GetFuncName(const char *moduleName, u32 nib) { - _dbg_assert_msg_(HLE, moduleName != NULL, "Invalid module name."); + _dbg_assert_msg_(moduleName != nullptr, "Invalid module name."); const HLEFunction *func = GetFunc(moduleName,nib); if (func) @@ -314,7 +314,7 @@ void hleCheckCurrentCallbacks() void hleReSchedule(const char *reason) { #ifdef _DEBUG - _dbg_assert_msg_(HLE, reason != nullptr && strlen(reason) < 256, "hleReSchedule: Invalid or too long reason."); + _dbg_assert_msg_(reason != nullptr && strlen(reason) < 256, "hleReSchedule: Invalid or too long reason."); #endif hleAfterSyscall |= HLE_AFTER_RESCHED; @@ -820,7 +820,7 @@ size_t hleFormatLogArgs(char *message, size_t sz, const char *argmask) { // TODO: Double? Does it ever happen? default: - _dbg_assert_msg_(HLE, false, "Invalid argmask character: %c", argmask[i]); + _dbg_assert_msg_(false, "Invalid argmask character: %c", argmask[i]); APPEND_FMT(" -- invalid arg format: %c -- %08x", argmask[i], regval); break; } @@ -844,7 +844,7 @@ void hleDoLogInternal(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u64 res, const char *funcName = "?"; u32 funcFlags = 0; if (latestSyscall) { - _dbg_assert_(HLE, latestSyscall->argmask != nullptr); + _dbg_assert_(latestSyscall->argmask != nullptr); hleFormatLogArgs(formatted_args, sizeof(formatted_args), latestSyscall->argmask); // This acts as an override (for error returns which are usually hex.) @@ -866,7 +866,7 @@ void hleDoLogInternal(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u64 res, // TODO: For now, floats are just shown as bits. fmt = "%s%08x=%s(%s)%s"; } else { - _dbg_assert_msg_(HLE, false, "Invalid return format: %c", retmask); + _dbg_assert_msg_(false, "Invalid return format: %c", retmask); fmt = "%s%08llx=%s(%s)%s"; } diff --git a/Core/HLE/ThreadQueueList.h b/Core/HLE/ThreadQueueList.h index 9111fff41d..dbb46d1818 100644 --- a/Core/HLE/ThreadQueueList.h +++ b/Core/HLE/ThreadQueueList.h @@ -82,7 +82,7 @@ struct ThreadQueueList { cur = cur->next; } - _dbg_assert_msg_(SCEKERNEL, false, "ThreadQueueList should not be empty."); + _dbg_assert_msg_(false, "ThreadQueueList should not be empty."); return 0; } @@ -127,7 +127,7 @@ struct ThreadQueueList { inline void remove(u32 priority, const SceUID threadID) { Queue *cur = &queues[priority]; - _dbg_assert_msg_(SCEKERNEL, cur->next != nullptr, "ThreadQueueList::Queue should already be linked up."); + _dbg_assert_msg_(cur->next != nullptr, "ThreadQueueList::Queue should already be linked up."); for (int i = cur->first; i < cur->end; ++i) { if (cur->data[i] == threadID) { @@ -148,7 +148,7 @@ struct ThreadQueueList { inline void rotate(u32 priority) { Queue *cur = &queues[priority]; - _dbg_assert_msg_(SCEKERNEL, cur->next != nullptr, "ThreadQueueList::Queue should already be linked up."); + _dbg_assert_msg_(cur->next != nullptr, "ThreadQueueList::Queue should already be linked up."); if (cur->size() > 1) { // Grab the front and push it on the end. @@ -222,7 +222,7 @@ private: // Initialize a priority level and link to other queues. void link(u32 priority, int size) { - _dbg_assert_msg_(SCEKERNEL, queues[priority].data == nullptr, "ThreadQueueList::Queue should only be initialized once."); + _dbg_assert_msg_(queues[priority].data == nullptr, "ThreadQueueList::Queue should only be initialized once."); // Make sure we stay a multiple of INITIAL_CAPACITY. if (size <= INITIAL_CAPACITY) diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index 17ab7084cd..8bad0e193a 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -306,7 +306,7 @@ static void __CtrlVblank() static void __CtrlTimerUpdate(u64 userdata, int cyclesLate) { // This only runs in timer mode (ctrlCycle > 0.) - _dbg_assert_msg_(SCECTRL, ctrlCycle > 0, "Ctrl: sampling cycle should be > 0"); + _dbg_assert_msg_(ctrlCycle > 0, "Ctrl: sampling cycle should be > 0"); CoreTiming::ScheduleEvent(usToCycles(ctrlCycle) - cyclesLate, ctrlTimer, 0); diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 692d23ec89..78c7b746bf 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -418,13 +418,12 @@ public: virtual int GetIDType() const = 0; virtual void GetQuickInfo(char *ptr, int size); - // Implement this in all subclasses: + // Implement the following in all subclasses: // static u32 GetMissingErrorCode() // static int GetStaticIDType() - virtual void DoState(PointerWrap &p) - { - _dbg_assert_msg_(SCEKERNEL, false, "Unable to save state: bad kernel object."); + virtual void DoState(PointerWrap &p) { + _dbg_assert_msg_(false, "Unable to save state: bad kernel object."); } }; @@ -482,7 +481,7 @@ public: template T *GetFast(SceUID handle) { const SceUID realHandle = handle - handleOffset; - _dbg_assert_(SCEKERNEL, realHandle >= 0 && realHandle < maxCount && occupied[realHandle]); + _dbg_assert_(realHandle >= 0 && realHandle < maxCount && occupied[realHandle]); return static_cast(pool[realHandle]); } diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index 4f9b497c02..0eb6bc89b3 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -273,7 +273,7 @@ static void __KernelWaitMbx(Mbx *m, u32 timeoutPtr) static std::vector::iterator __KernelMbxFindPriority(std::vector &waiting) { - _dbg_assert_msg_(SCEKERNEL, !waiting.empty(), "__KernelMutexFindPriority: Trying to find best of no threads."); + _dbg_assert_msg_(!waiting.empty(), "__KernelMutexFindPriority: Trying to find best of no threads."); std::vector::iterator iter, end, best = waiting.end(); u32 best_prio = 0xFFFFFFFF; @@ -287,7 +287,7 @@ static std::vector::iterator __KernelMbxFindPriority(std::vect } } - _dbg_assert_msg_(SCEKERNEL, best != waiting.end(), "__KernelMutexFindPriority: Returning invalid best thread."); + _dbg_assert_msg_(best != waiting.end(), "__KernelMutexFindPriority: Returning invalid best thread."); return best; } diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 41ccd6d82a..7d2e7e4241 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -302,11 +302,11 @@ struct SceKernelVplHeader { inline void Validate() { auto lastBlock = LastBlock(); - _dbg_assert_msg_(SCEKERNEL, nextFreeBlock_->next.ptr != SentinelPtr(), "Next free block should not be allocated."); - _dbg_assert_msg_(SCEKERNEL, nextFreeBlock_->next.ptr != sentinel_, "Next free block should not point to sentinel."); - _dbg_assert_msg_(SCEKERNEL, lastBlock->sizeInBlocks == 0, "Last block should have size of 0."); - _dbg_assert_msg_(SCEKERNEL, lastBlock->next.ptr != SentinelPtr(), "Last block should not be allocated."); - _dbg_assert_msg_(SCEKERNEL, lastBlock->next.ptr != sentinel_, "Last block should not point to sentinel."); + _dbg_assert_msg_(nextFreeBlock_->next.ptr != SentinelPtr(), "Next free block should not be allocated."); + _dbg_assert_msg_(nextFreeBlock_->next.ptr != sentinel_, "Next free block should not point to sentinel."); + _dbg_assert_msg_(lastBlock->sizeInBlocks == 0, "Last block should have size of 0."); + _dbg_assert_msg_(lastBlock->next.ptr != SentinelPtr(), "Last block should not be allocated."); + _dbg_assert_msg_(lastBlock->next.ptr != sentinel_, "Last block should not point to sentinel."); auto b = PSPPointer::Create(FirstBlockPtr()); bool sawFirstFree = false; @@ -314,22 +314,22 @@ struct SceKernelVplHeader { bool isFree = b->next.ptr != SentinelPtr(); if (isFree) { if (!sawFirstFree) { - _dbg_assert_msg_(SCEKERNEL, lastBlock->next.ptr == b.ptr, "Last block should point to first free block."); + _dbg_assert_msg_(lastBlock->next.ptr == b.ptr, "Last block should point to first free block."); sawFirstFree = true; } - _dbg_assert_msg_(SCEKERNEL, b->next.ptr != SentinelPtr(), "Free blocks should only point to other free blocks."); - _dbg_assert_msg_(SCEKERNEL, b->next.ptr > b.ptr, "Free blocks should be in order."); - _dbg_assert_msg_(SCEKERNEL, b + b->sizeInBlocks < b->next || b->next.ptr == lastBlock.ptr, "Two free blocks should not be next to each other."); + _dbg_assert_msg_(b->next.ptr != SentinelPtr(), "Free blocks should only point to other free blocks."); + _dbg_assert_msg_(b->next.ptr > b.ptr, "Free blocks should be in order."); + _dbg_assert_msg_(b + b->sizeInBlocks < b->next || b->next.ptr == lastBlock.ptr, "Two free blocks should not be next to each other."); } else { - _dbg_assert_msg_(SCEKERNEL, b->next.ptr == SentinelPtr(), "Allocated blocks should point to the sentinel."); + _dbg_assert_msg_(b->next.ptr == SentinelPtr(), "Allocated blocks should point to the sentinel."); } - _dbg_assert_msg_(SCEKERNEL, b->sizeInBlocks != 0, "Only the last block should have a size of 0."); + _dbg_assert_msg_(b->sizeInBlocks != 0, "Only the last block should have a size of 0."); b += b->sizeInBlocks; } if (!sawFirstFree) { - _dbg_assert_msg_(SCEKERNEL, lastBlock->next.ptr == lastBlock.ptr, "Last block should point to itself when full."); + _dbg_assert_msg_(lastBlock->next.ptr == lastBlock.ptr, "Last block should point to itself when full."); } - _dbg_assert_msg_(SCEKERNEL, b.ptr == lastBlock.ptr, "Blocks should not extend outside vpl."); + _dbg_assert_msg_(b.ptr == lastBlock.ptr, "Blocks should not extend outside vpl."); } void ListBlocks() { diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index 38b4583c9b..7418a68f05 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -206,7 +206,7 @@ static void __KernelMutexAcquireLock(PSPMutex *mutex, int count, SceUID thread) #if defined(_DEBUG) auto locked = mutexHeldLocks.equal_range(thread); for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) - _dbg_assert_msg_(SCEKERNEL, (*iter).second != mutex->GetUID(), "Thread %d / mutex %d wasn't removed from mutexHeldLocks properly.", thread, mutex->GetUID()); + _dbg_assert_msg_((*iter).second != mutex->GetUID(), "Thread %d / mutex %d wasn't removed from mutexHeldLocks properly.", thread, mutex->GetUID()); #endif mutexHeldLocks.insert(std::make_pair(thread, mutex->GetUID())); @@ -238,7 +238,7 @@ static void __KernelMutexEraseLock(PSPMutex *mutex) { static std::vector::iterator __KernelMutexFindPriority(std::vector &waiting) { - _dbg_assert_msg_(SCEKERNEL, !waiting.empty(), "__KernelMutexFindPriority: Trying to find best of no threads."); + _dbg_assert_msg_(!waiting.empty(), "__KernelMutexFindPriority: Trying to find best of no threads."); std::vector::iterator iter, end, best = waiting.end(); u32 best_prio = 0xFFFFFFFF; @@ -252,7 +252,7 @@ static std::vector::iterator __KernelMutexFindPriority(std::vector= 0x200, "thread stack should be 256 bytes or larger"); + _assert_msg_(stackSize >= 0x200, "thread stack should be 256 bytes or larger"); FreeStack(); @@ -1046,7 +1046,7 @@ static void __KernelFireThreadEnd(SceUID threadID) // TODO: Use __KernelChangeThreadState instead? It has other affects... static void __KernelChangeReadyState(PSPThread *thread, SceUID threadID, bool ready) { // Passing the id as a parameter is just an optimization, if it's wrong it will cause havoc. - _dbg_assert_msg_(SCEKERNEL, thread->GetUID() == threadID, "Incorrect threadID"); + _dbg_assert_msg_(thread->GetUID() == threadID, "Incorrect threadID"); int prio = thread->nt.currentPriority; if (thread->isReady()) @@ -1422,7 +1422,7 @@ u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 i break; default: - _dbg_assert_msg_(SCEKERNEL, false, "Unexpected type %d", type); + _dbg_assert_msg_(false, "Unexpected type %d", type); } for (size_t i = 0; i < threadqueue.size(); i++) { @@ -2132,7 +2132,7 @@ void __KernelReturnFromThread() int exitStatus = currentMIPS->r[MIPS_REG_V0]; PSPThread *thread = __GetCurrentThread(); - _dbg_assert_msg_(SCEKERNEL, thread != NULL, "Returned from a NULL thread."); + _dbg_assert_msg_(thread != NULL, "Returned from a NULL thread."); DEBUG_LOG(SCEKERNEL, "__KernelReturnFromThread: %d", exitStatus); __KernelStopThread(currentThread, exitStatus, "thread returned"); @@ -2147,7 +2147,7 @@ void __KernelReturnFromThread() void sceKernelExitThread(int exitStatus) { PSPThread *thread = __GetCurrentThread(); - _dbg_assert_msg_(SCEKERNEL, thread != NULL, "Exited from a NULL thread."); + _dbg_assert_msg_(thread != NULL, "Exited from a NULL thread."); INFO_LOG(SCEKERNEL, "sceKernelExitThread(%d)", exitStatus); __KernelStopThread(currentThread, exitStatus, "thread exited"); @@ -2162,7 +2162,7 @@ void sceKernelExitThread(int exitStatus) { void _sceKernelExitThread(int exitStatus) { PSPThread *thread = __GetCurrentThread(); - _dbg_assert_msg_(SCEKERNEL, thread != NULL, "_Exited from a NULL thread."); + _dbg_assert_msg_(thread != NULL, "_Exited from a NULL thread."); ERROR_LOG_REPORT(SCEKERNEL, "_sceKernelExitThread(%d): should not be called directly", exitStatus); __KernelStopThread(currentThread, exitStatus, "thread _exited"); @@ -3133,7 +3133,7 @@ void __KernelCallAddress(PSPThread *thread, u32 entryPoint, PSPAction *afterActi WARN_LOG_REPORT(SCEKERNEL, "Running mipscall on dormant thread"); } - _dbg_assert_msg_(SCEKERNEL, numargs <= 6, "MipsCalls can only take 6 args."); + _dbg_assert_msg_(numargs <= 6, "MipsCalls can only take 6 args."); if (thread) { ActionAfterMipsCall *after = (ActionAfterMipsCall *) __KernelCreateAction(actionAfterMipsCall); @@ -3338,7 +3338,7 @@ void __KernelReturnFromMipsCall() // First arg must be current thread, passed to avoid perf cost of a lookup. bool __KernelExecutePendingMipsCalls(PSPThread *thread, bool reschedAfter) { - _dbg_assert_msg_(SCEKERNEL, thread->GetUID() == __KernelGetCurThread(), "__KernelExecutePendingMipsCalls() should be called only with the current thread."); + _dbg_assert_msg_(thread->GetUID() == __KernelGetCurThread(), "__KernelExecutePendingMipsCalls() should be called only with the current thread."); if (thread->pendingMipsCalls.empty()) { // Nothing to do diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index ab2d62a490..a93fa7f977 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -189,7 +189,7 @@ void __UmdBeginCallback(SceUID threadID, SceUID prevCallbackId) if (umdPausedWaits.find(pauseKey) != umdPausedWaits.end()) return; - _dbg_assert_msg_(SCEIO, umdStatTimeoutEvent != -1, "Must have a umd timer"); + _dbg_assert_msg_(umdStatTimeoutEvent != -1, "Must have a umd timer"); s64 cyclesLeft = CoreTiming::UnscheduleEvent(umdStatTimeoutEvent, threadID); if (cyclesLeft != 0) umdPausedWaits[pauseKey] = CoreTiming::GetTicks() + cyclesLeft; @@ -234,7 +234,7 @@ void __UmdEndCallback(SceUID threadID, SceUID prevCallbackId) __KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT); else { - _dbg_assert_msg_(SCEIO, umdStatTimeoutEvent != -1, "Must have a umd timer"); + _dbg_assert_msg_(umdStatTimeoutEvent != -1, "Must have a umd timer"); CoreTiming::ScheduleEvent(cyclesLeft, umdStatTimeoutEvent, __KernelGetCurThread()); umdWaitingThreads.push_back(threadID); diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index 2a0a67d90d..b92cca816a 100644 --- a/Core/MIPS/ARM/ArmCompBranch.cpp +++ b/Core/MIPS/ARM/ArmCompBranch.cpp @@ -86,7 +86,7 @@ void ArmJit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) { case CC_EQ: immBranchNotTaken = rsImm == rtImm; break; case CC_NEQ: immBranchNotTaken = rsImm != rtImm; break; - default: immBranchNotTaken = false; _dbg_assert_msg_(JIT, false, "Bad cc flag in BranchRSRTComp()."); + default: immBranchNotTaken = false; _dbg_assert_msg_(false, "Bad cc flag in BranchRSRTComp()."); } immBranch = true; immBranchTaken = !immBranchNotTaken; @@ -199,7 +199,7 @@ void ArmJit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool like case CC_GE: immBranchNotTaken = imm >= 0; break; case CC_LT: immBranchNotTaken = imm < 0; break; case CC_LE: immBranchNotTaken = imm <= 0; break; - default: immBranchNotTaken = false; _dbg_assert_msg_(JIT, false, "Bad cc flag in BranchRSZeroComp()."); + default: immBranchNotTaken = false; _dbg_assert_msg_(false, "Bad cc flag in BranchRSZeroComp()."); } immBranch = true; immBranchTaken = !immBranchNotTaken; @@ -298,7 +298,7 @@ void ArmJit::Comp_RelBranch(MIPSOpcode op) case 23: BranchRSZeroComp(op, CC_LE, false, true); break;//bgtzl default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } } @@ -316,7 +316,7 @@ void ArmJit::Comp_RelBranchRI(MIPSOpcode op) case 18: BranchRSZeroComp(op, CC_GE, true, true); break; //R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(addr); else SkipLikely(); break;//bltzall case 19: BranchRSZeroComp(op, CC_LT, true, true); break; //R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(addr); else SkipLikely(); break;//bgezall default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } } @@ -374,7 +374,7 @@ void ArmJit::Comp_FPUBranch(MIPSOpcode op) case 2: BranchFPFlag(op, CC_NEQ, true); break; // bc1fl case 3: BranchFPFlag(op, CC_EQ, true); break; // bc1tl default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } } @@ -511,7 +511,7 @@ void ArmJit::Comp_Jump(MIPSOpcode op) { break; default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } js.compiling = false; @@ -587,7 +587,7 @@ void ArmJit::Comp_JumpReg(MIPSOpcode op) case 9: //jalr break; default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } diff --git a/Core/MIPS/ARM/ArmCompLoadStore.cpp b/Core/MIPS/ARM/ArmCompLoadStore.cpp index 3dfcae2e61..3d49b2dc61 100644 --- a/Core/MIPS/ARM/ArmCompLoadStore.cpp +++ b/Core/MIPS/ARM/ArmCompLoadStore.cpp @@ -182,7 +182,7 @@ namespace MIPSComp // 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); + _dbg_assert_msg_(!gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr); } if (load) { @@ -339,7 +339,7 @@ namespace MIPSComp addrReg = R0; } } else { - _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address? CPU bug?"); + _dbg_assert_msg_(!gpr.IsImm(rs), "Invalid immediate address? CPU bug?"); load ? gpr.MapDirtyIn(rt, rs) : gpr.MapInIn(rt, rs); if (!g_Config.bFastMemory && rs != MIPS_REG_SP) { diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index 94cd0d811c..979baedfaa 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -543,7 +543,7 @@ namespace MIPSComp VMOV(fpr.V(dregs[3]), (vd&3)==3 ? S1 : S0); break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } @@ -1320,7 +1320,7 @@ namespace MIPSComp } } else { //ERROR - _dbg_assert_msg_(CPU,0,"mtv - invalid register"); + _dbg_assert_msg_(false,"mtv - invalid register"); } break; diff --git a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp index 43462dbf09..41961e944b 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp @@ -730,7 +730,7 @@ void ArmJit::CompNEON_Mftv(MIPSOpcode op) { } } else { //ERROR - _dbg_assert_msg_(CPU,0,"mtv - invalid register"); + _dbg_assert_msg_(false,"mtv - invalid register"); } break; @@ -808,7 +808,7 @@ void ArmJit::CompNEON_VMatrixInit(MIPSOpcode op) { // NEONTranspose4x4(cols); break; default: - _assert_msg_(JIT, 0, "Bad matrix size"); + _assert_msg_(false, "Bad matrix size"); break; } break; @@ -1159,7 +1159,7 @@ void ArmJit::CompNEON_VIdt(MIPSOpcode op) { } break; default: - _dbg_assert_msg_(CPU,0,"Bad vidt instruction"); + _dbg_assert_msg_(false,"Bad vidt instruction"); break; } diff --git a/Core/MIPS/ARM/ArmRegCacheFPU.cpp b/Core/MIPS/ARM/ArmRegCacheFPU.cpp index cac7f374b9..a1378a67b3 100644 --- a/Core/MIPS/ARM/ArmRegCacheFPU.cpp +++ b/Core/MIPS/ARM/ArmRegCacheFPU.cpp @@ -561,7 +561,7 @@ int ArmRegCacheFPU::GetTempR() { } ERROR_LOG(CPU, "Out of temp regs! Might need to DiscardR() some"); - _assert_msg_(JIT, 0, "Regcache ran out of temp regs, might need to DiscardR() some."); + _assert_msg_(false, "Regcache ran out of temp regs, might need to DiscardR() some."); return -1; } diff --git a/Core/MIPS/ARM64/Arm64CompBranch.cpp b/Core/MIPS/ARM64/Arm64CompBranch.cpp index cdb984608e..3e84996487 100644 --- a/Core/MIPS/ARM64/Arm64CompBranch.cpp +++ b/Core/MIPS/ARM64/Arm64CompBranch.cpp @@ -86,7 +86,7 @@ void Arm64Jit::BranchRSRTComp(MIPSOpcode op, CCFlags cc, bool likely) { case CC_EQ: immBranchNotTaken = rsImm == rtImm; break; case CC_NEQ: immBranchNotTaken = rsImm != rtImm; break; - default: immBranchNotTaken = false; _dbg_assert_msg_(JIT, false, "Bad cc flag in BranchRSRTComp()."); + default: immBranchNotTaken = false; _dbg_assert_msg_(false, "Bad cc flag in BranchRSRTComp()."); } immBranch = true; immBranchTaken = !immBranchNotTaken; @@ -217,7 +217,7 @@ void Arm64Jit::BranchRSZeroComp(MIPSOpcode op, CCFlags cc, bool andLink, bool li case CC_GE: immBranchNotTaken = imm >= 0; break; case CC_LT: immBranchNotTaken = imm < 0; break; case CC_LE: immBranchNotTaken = imm <= 0; break; - default: immBranchNotTaken = false; _dbg_assert_msg_(JIT, false, "Bad cc flag in BranchRSZeroComp()."); + default: immBranchNotTaken = false; _dbg_assert_msg_(false, "Bad cc flag in BranchRSZeroComp()."); } immBranch = true; immBranchTaken = !immBranchNotTaken; @@ -316,7 +316,7 @@ void Arm64Jit::Comp_RelBranch(MIPSOpcode op) case 23: BranchRSZeroComp(op, CC_LE, false, true); break;//bgtzl default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } } @@ -334,7 +334,7 @@ void Arm64Jit::Comp_RelBranchRI(MIPSOpcode op) case 18: BranchRSZeroComp(op, CC_GE, true, true); break; //R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(addr); else SkipLikely(); break;//bltzall case 19: BranchRSZeroComp(op, CC_LT, true, true); break; //R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(addr); else SkipLikely(); break;//bgezall default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } } @@ -391,7 +391,7 @@ void Arm64Jit::Comp_FPUBranch(MIPSOpcode op) { case 2: BranchFPFlag(op, CC_NEQ, true); break; // bc1fl case 3: BranchFPFlag(op, CC_EQ, true); break; // bc1tl default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( 0, "Trying to interpret instruction that can't be interpreted"); break; } } @@ -526,7 +526,7 @@ void Arm64Jit::Comp_Jump(MIPSOpcode op) { break; default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } js.compiling = false; @@ -604,7 +604,7 @@ void Arm64Jit::Comp_JumpReg(MIPSOpcode op) case 9: //jalr break; default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } diff --git a/Core/MIPS/ARM64/Arm64CompLoadStore.cpp b/Core/MIPS/ARM64/Arm64CompLoadStore.cpp index a4d647d98b..ad706c5221 100644 --- a/Core/MIPS/ARM64/Arm64CompLoadStore.cpp +++ b/Core/MIPS/ARM64/Arm64CompLoadStore.cpp @@ -180,7 +180,7 @@ namespace MIPSComp { return; } - _dbg_assert_msg_(JIT, !gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr); + _dbg_assert_msg_(!gpr.IsImm(rs), "Invalid immediate address %08x? CPU bug?", iaddr); if (load) { gpr.MapDirtyIn(rt, rs, false); } else { @@ -380,7 +380,7 @@ namespace MIPSComp { // 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); + _dbg_assert_msg_(!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. diff --git a/Core/MIPS/ARM64/Arm64CompVFPU.cpp b/Core/MIPS/ARM64/Arm64CompVFPU.cpp index 69d6a302c6..b297f139e4 100644 --- a/Core/MIPS/ARM64/Arm64CompVFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompVFPU.cpp @@ -171,7 +171,7 @@ namespace MIPSComp { } void Arm64Jit::ApplyPrefixD(const u8 *vregs, VectorSize sz) { - _assert_msg_(JIT, js.prefixDFlag & JitState::PREFIX_KNOWN, "Unexpected unknown prefix!"); + _assert_msg_(js.prefixDFlag & JitState::PREFIX_KNOWN, "Unexpected unknown prefix!"); if (!js.prefixD) return; @@ -435,7 +435,7 @@ namespace MIPSComp { fp.FMOV(fpr.V(dregs[3]), (vd & 3) == 3 ? S1 : S0); break; default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( 0, "Trying to interpret instruction that can't be interpreted"); break; } @@ -1069,7 +1069,7 @@ namespace MIPSComp { } } else { //ERROR - _dbg_assert_msg_(CPU, 0, "mtv - invalid register"); + _dbg_assert_msg_( 0, "mtv - invalid register"); } break; diff --git a/Core/MIPS/ARM64/Arm64RegCache.cpp b/Core/MIPS/ARM64/Arm64RegCache.cpp index b089efa309..a853359ae4 100644 --- a/Core/MIPS/ARM64/Arm64RegCache.cpp +++ b/Core/MIPS/ARM64/Arm64RegCache.cpp @@ -215,7 +215,7 @@ void Arm64RegCache::MapRegTo(ARM64Reg reg, MIPSGPReg mipsReg, int mapFlags) { mr[mipsReg].loc = ML_ARMREG_IMM; break; default: - _assert_msg_(JIT, mr[mipsReg].loc != ML_ARMREG_AS_PTR, "MapRegTo with a pointer?"); + _assert_msg_(mr[mipsReg].loc != ML_ARMREG_AS_PTR, "MapRegTo with a pointer?"); mr[mipsReg].loc = ML_ARMREG; break; } diff --git a/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp b/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp index ba2bb0105b..7df249eaaa 100644 --- a/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp +++ b/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp @@ -479,7 +479,7 @@ int Arm64RegCacheFPU::GetTempR() { } ERROR_LOG(CPU, "Out of temp regs! Might need to DiscardR() some"); - _assert_msg_(JIT, 0, "Regcache ran out of temp regs, might need to DiscardR() some."); + _assert_msg_(false, "Regcache ran out of temp regs, might need to DiscardR() some."); return -1; } diff --git a/Core/MIPS/IR/IRCompBranch.cpp b/Core/MIPS/IR/IRCompBranch.cpp index 76b89fd669..df23efa1e1 100644 --- a/Core/MIPS/IR/IRCompBranch.cpp +++ b/Core/MIPS/IR/IRCompBranch.cpp @@ -165,7 +165,7 @@ void IRFrontend::Comp_RelBranch(MIPSOpcode op) { case 23: BranchRSZeroComp(op, IRComparison::LessEqual, false, true); break;//bgtzl default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } } @@ -181,7 +181,7 @@ void IRFrontend::Comp_RelBranchRI(MIPSOpcode op) { case 18: BranchRSZeroComp(op, IRComparison::GreaterEqual, true, true); break; //R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(addr); else SkipLikely(); break;//bltzall case 19: BranchRSZeroComp(op, IRComparison::Less, true, true); break; //R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(addr); else SkipLikely(); break;//bgezall default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } } @@ -224,7 +224,7 @@ void IRFrontend::Comp_FPUBranch(MIPSOpcode op) { case 2: BranchFPFlag(op, IRComparison::NotEqual, true); break; // bc1fl case 3: BranchFPFlag(op, IRComparison::Equal, true); break; // bc1tl default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( 0, "Trying to interpret instruction that can't be interpreted"); break; } } @@ -315,7 +315,7 @@ void IRFrontend::Comp_Jump(MIPSOpcode op) { break; default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } @@ -379,7 +379,7 @@ void IRFrontend::Comp_JumpReg(MIPSOpcode op) { case 9: //jalr break; default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 4922fc13f2..5063911293 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -104,7 +104,7 @@ void IRJit::Compile(u32 em_address) { bool IRJit::CompileBlock(u32 em_address, std::vector &instructions, u32 &mipsBytes, bool preload) { frontend_.DoJit(em_address, instructions, mipsBytes, preload); if (instructions.empty()) { - _dbg_assert_(JIT, preload); + _dbg_assert_(preload); // We return true when preloading so it doesn't abort. return preload; } diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index 8d015de485..d43cd130d3 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -180,7 +180,7 @@ namespace MIPSInt case 23: if ((s32)R(rs) > 0) DelayBranchTo(addr); else SkipLikely(); break; //bgtzl default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } } @@ -202,7 +202,7 @@ namespace MIPSInt case 18: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(addr); else SkipLikely(); break;//bltzall case 19: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(addr); else SkipLikely(); break;//bgezall default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } } @@ -237,7 +237,7 @@ namespace MIPSInt case 2: if (!currentMIPS->fpcond) DelayBranchTo(addr); else SkipLikely(); break;//bc1fl case 3: if ( currentMIPS->fpcond) DelayBranchTo(addr); else SkipLikely(); break;//bc1tl default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } } @@ -245,7 +245,7 @@ namespace MIPSInt void Int_JumpType(MIPSOpcode op) { if (mipsr4k.inDelaySlot) - _dbg_assert_msg_(CPU,0,"Jump in delay slot :("); + _dbg_assert_msg_(false,"Jump in delay slot :("); u32 off = ((op & 0x03FFFFFF) << 2); u32 addr = (currentMIPS->pc & 0xF0000000) | off; @@ -258,7 +258,7 @@ namespace MIPSInt DelayBranchTo(addr); break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } } @@ -271,7 +271,7 @@ namespace MIPSInt if (op == 0x03e00008) return; ERROR_LOG(CPU, "Jump in delay slot :("); - _dbg_assert_msg_(CPU,0,"Jump in delay slot :("); + _dbg_assert_msg_(false,"Jump in delay slot :("); } int rs = _RS; @@ -316,7 +316,7 @@ namespace MIPSInt case 14: R(rt) = R(rs) ^ uimm; break; //xori case 15: R(rt) = uimm << 16; break; //lui default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } PC += 4; @@ -348,7 +348,7 @@ namespace MIPSInt } break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } PC += 4; @@ -386,7 +386,7 @@ namespace MIPSInt case 44: R(rd) = ((s32)R(rs) > (s32)R(rt)) ? R(rs) : R(rt); break; //max case 45: R(rd) = ((s32)R(rs) < (s32)R(rt)) ? R(rs) : R(rt); break;//min default: - _dbg_assert_msg_(CPU, 0, "Unknown MIPS instruction %08x", op.encoding); + _dbg_assert_msg_( 0, "Unknown MIPS instruction %08x", op.encoding); break; } PC += 4; @@ -457,7 +457,7 @@ namespace MIPSInt break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret Mem instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret Mem instruction that can't be interpreted"); break; } PC += 4; @@ -475,7 +475,7 @@ namespace MIPSInt case 49: FI(ft) = Memory::Read_U32(addr); break; //lwc1 case 57: Memory::Write_U32(FI(ft), addr); break; //swc1 default: - _dbg_assert_msg_(CPU,0,"Trying to interpret FPULS instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret FPULS instruction that can't be interpreted"); break; } PC += 4; @@ -528,7 +528,7 @@ namespace MIPSInt } default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } PC += 4; @@ -555,7 +555,7 @@ namespace MIPSInt R(rd) = clz32(~R(rs)); break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } PC += 4; @@ -659,7 +659,7 @@ namespace MIPSInt break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } PC += 4; @@ -714,7 +714,7 @@ namespace MIPSInt case 7: R(rd) = (u32)(((s32)R(rt)) >> (R(rs)&0x1F)); break; //srav default: wrong: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } PC += 4; @@ -757,7 +757,7 @@ namespace MIPSInt break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret ALLEGREX instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret ALLEGREX instruction that can't be interpreted"); break; } PC += 4; @@ -784,7 +784,7 @@ namespace MIPSInt R(rd) = swap32(R(rt)); break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret ALLEGREX instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret ALLEGREX instruction that can't be interpreted"); break; } PC += 4; @@ -902,7 +902,7 @@ namespace MIPSInt } break; //cvt.w.s default: - _dbg_assert_msg_(CPU,0,"Trying to interpret FPU2Op instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret FPU2Op instruction that can't be interpreted"); break; } PC += 4; @@ -956,7 +956,7 @@ namespace MIPSInt break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret FPUComp instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret FPUComp instruction that can't be interpreted"); cond = false; break; } @@ -984,7 +984,7 @@ namespace MIPSInt break; case 3: F(fd) = F(fs) / F(ft); break; // div.s default: - _dbg_assert_msg_(CPU,0,"Trying to interpret FPU3Op instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret FPU3Op instruction that can't be interpreted"); break; } PC += 4; @@ -1009,7 +1009,7 @@ namespace MIPSInt void Int_Emuhack(MIPSOpcode op) { if (((op >> 24) & 3) != EMUOP_CALL_REPLACEMENT) { - _dbg_assert_msg_(CPU,0,"Trying to interpret emuhack instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret emuhack instruction that can't be interpreted"); } // It's a replacement func! int index = op.encoding & 0xFFFFFF; diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 322d334153..bc8d698c59 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -213,7 +213,7 @@ namespace MIPSInt { if (addr & 0x3) { - _dbg_assert_msg_(CPU, 0, "Misaligned lvX.q at %08x (pc = %08x)", addr, PC); + _dbg_assert_msg_( 0, "Misaligned lvX.q at %08x (pc = %08x)", addr, PC); } float d[4]; ReadVector(d, V_Quad, vt); @@ -241,7 +241,7 @@ namespace MIPSInt case 54: //lv.q if (addr & 0xF) { - _dbg_assert_msg_(CPU, 0, "Misaligned lv.q at %08x (pc = %08x)", addr, PC); + _dbg_assert_msg_( 0, "Misaligned lv.q at %08x (pc = %08x)", addr, PC); } #ifndef COMMON_BIG_ENDIAN WriteVector((const float*)Memory::GetPointer(addr), V_Quad, vt); @@ -261,7 +261,7 @@ namespace MIPSInt { if (addr & 0x3) { - _dbg_assert_msg_(CPU, 0, "Misaligned svX.q at %08x (pc = %08x)", addr, PC); + _dbg_assert_msg_( 0, "Misaligned svX.q at %08x (pc = %08x)", addr, PC); } float d[4]; ReadVector(d, V_Quad, vt); @@ -288,7 +288,7 @@ namespace MIPSInt case 62: //sv.q if (addr & 0xF) { - _dbg_assert_msg_(CPU, 0, "Misaligned sv.q at %08x (pc = %08x)", addr, PC); + _dbg_assert_msg_( 0, "Misaligned sv.q at %08x (pc = %08x)", addr, PC); } #ifndef COMMON_BIG_ENDIAN ReadVector(reinterpret_cast(Memory::GetPointer(addr)), V_Quad, vt); @@ -304,7 +304,7 @@ namespace MIPSInt break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret VQ instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret VQ instruction that can't be interpreted"); break; } PC += 4; @@ -338,7 +338,7 @@ namespace MIPSInt case 6: m=zero; break; // vmzero case 7: m=one; break; // vmone default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); PC += 4; EatPrefixes(); return; @@ -369,7 +369,7 @@ namespace MIPSInt sprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::ONE, VFPUConst::ONE, VFPUConst::ONE, VFPUConst::ONE); break; default: - _dbg_assert_msg_(CPU, 0, "Unknown matrix init op"); + _dbg_assert_msg_( 0, "Unknown matrix init op"); break; } ApplyPrefixST(&prefixed[off * 4], VFPURewritePrefix(VFPU_CTRL_SPREFIX, sprefixRemove, sprefixAdd), V_Quad); @@ -393,7 +393,7 @@ namespace MIPSInt case 6: constant = VFPUConst::ZERO; break; //vzero case 7: constant = VFPUConst::ONE; break; //vone default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( 0, "Trying to interpret instruction that can't be interpreted"); PC += 4; EatPrefixes(); return; @@ -422,7 +422,7 @@ namespace MIPSInt } else if (type == 7) { f[0] = Float16ToFloat32((u16)uimm16); // vfim } else { - _dbg_assert_msg_(CPU, 0, "Invalid Viim opcode type %d", type); + _dbg_assert_msg_( 0, "Invalid Viim opcode type %d", type); f[0] = 0; } @@ -634,7 +634,7 @@ namespace MIPSInt case 26: { d[i] = -vfpu_sin(s[i]); } break; // vnsin case 28: d[i] = 1.0f / powf(2.0, s[i]); break; // vrexp2 default: - _dbg_assert_msg_(CPU, false, "Invalid VV2Op op type %d", optype); + _dbg_assert_msg_( false, "Invalid VV2Op op type %d", optype); break; } } @@ -993,7 +993,7 @@ namespace MIPSInt break; default: - _dbg_assert_msg_(CPU, false, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( false, "Trying to interpret instruction that can't be interpreted"); break; } @@ -1051,7 +1051,7 @@ namespace MIPSInt case V_Pair: oz = V_Single; break; case V_Single: oz = V_Single; break; default: - _dbg_assert_msg_(CPU, false, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( false, "Trying to interpret instruction that can't be interpreted"); oz = V_Single; break; } @@ -1070,13 +1070,13 @@ namespace MIPSInt case V_Pair: oz = V_Single; break; case V_Single: oz = V_Single; break; default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( 0, "Trying to interpret instruction that can't be interpreted"); oz = V_Single; break; } break; default: - _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( 0, "Trying to interpret instruction that can't be interpreted"); oz = V_Single; break; } @@ -1550,7 +1550,7 @@ namespace MIPSInt case 1: d.u[i] = currentMIPS->rng.R32(); break; // vrndi case 2: d.f[i] = 1.0f + ((float)currentMIPS->rng.R32() / 0xFFFFFFFF); break; // vrndf1 TODO: make more accurate case 3: d.f[i] = 2.0f + 2 * ((float)currentMIPS->rng.R32() / 0xFFFFFFFF); break; // vrndf2 TODO: make more accurate - default: _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + default: _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); } } // D prefix is broken and applies to the last element only (mask and sat.) @@ -1724,7 +1724,7 @@ namespace MIPSInt Memory::Write_U32(VI(vt), addr); break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } PC += 4; @@ -1746,7 +1746,7 @@ namespace MIPSInt R(rt) = currentMIPS->vfpuCtrl[imm - 128]; } else { //ERROR - maybe need to make this value too an "interlock" value? - _dbg_assert_msg_(CPU,0,"mfv - invalid register"); + _dbg_assert_msg_(false,"mfv - invalid register"); } } break; @@ -1761,12 +1761,12 @@ namespace MIPSInt } } else { //ERROR - _dbg_assert_msg_(CPU,0,"mtv - invalid register"); + _dbg_assert_msg_(false,"mtv - invalid register"); } break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } PC += 4; @@ -1853,7 +1853,7 @@ namespace MIPSInt case VC_NS: c = !(my_isnanorinf(s[i])); break; // How about t[i] ? default: - _dbg_assert_msg_(CPU,0,"Unsupported vcmp condition code %d", cond); + _dbg_assert_msg_(false,"Unsupported vcmp condition code %d", cond); PC += 4; EatPrefixes(); return; @@ -1920,7 +1920,7 @@ namespace MIPSInt } break; default: - _dbg_assert_msg_(CPU,0,"unknown min/max op %d", cond); + _dbg_assert_msg_(false,"unknown min/max op %d", cond); PC += 4; EatPrefixes(); return; @@ -2075,7 +2075,7 @@ namespace MIPSInt break; default: bad: - _dbg_assert_msg_(CPU, 0, "Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_( 0, "Trying to interpret instruction that can't be interpreted"); break; } diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 49f5b752b4..d958c4cd2a 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -948,7 +948,7 @@ void MIPSInterpret(MIPSOpcode op) { // Try to disassemble it char disasm[256]; MIPSDisAsm(op, currentMIPS->pc, disasm); - _dbg_assert_msg_(CPU, 0, "%s", disasm); + _dbg_assert_msg_( 0, "%s", disasm); currentMIPS->pc += 4; } } diff --git a/Core/MIPS/MIPSVFPUUtils.cpp b/Core/MIPS/MIPSVFPUUtils.cpp index 280dec90e4..923faf804d 100644 --- a/Core/MIPS/MIPSVFPUUtils.cpp +++ b/Core/MIPS/MIPSVFPUUtils.cpp @@ -41,7 +41,7 @@ void GetVectorRegs(u8 regs[4], VectorSize N, int vectorReg) { case V_Pair: row=(vectorReg>>5)&2; length = 2; break; case V_Triple: row=(vectorReg>>6)&1; length = 3; break; case V_Quad: row=(vectorReg>>5)&2; length = 4; break; - default: _assert_msg_(JIT, 0, "%s: Bad vector size", __FUNCTION__); + default: _assert_msg_(false, "%s: Bad vector size", __FUNCTION__); } for (int i = 0; i < length; i++) { @@ -67,7 +67,7 @@ void GetMatrixRegs(u8 regs[16], MatrixSize N, int matrixReg) { case M_2x2: row = (matrixReg >> 5) & 2; side = 2; break; case M_3x3: row = (matrixReg >> 6) & 1; side = 3; break; case M_4x4: row = (matrixReg >> 5) & 2; side = 4; break; - default: _assert_msg_(JIT, 0, "%s: Bad matrix size", __FUNCTION__); + default: _assert_msg_(false, "%s: Bad matrix size", __FUNCTION__); } for (int i = 0; i < side; i++) { @@ -112,7 +112,7 @@ int GetMatrixName(int matrix, MatrixSize msize, int column, int row, bool transp name |= (row << 5) | column; break; - default: _assert_msg_(JIT, 0, "%s: Bad matrix size", __FUNCTION__); + default: _assert_msg_(false, "%s: Bad matrix size", __FUNCTION__); } return name; @@ -161,7 +161,7 @@ void ReadVector(float *rd, VectorSize size, int reg) { case V_Pair: row=(reg>>5)&2; length = 2; break; case V_Triple: row=(reg>>6)&1; length = 3; break; case V_Quad: row=(reg>>5)&2; length = 4; break; - default: _assert_msg_(JIT, 0, "%s: Bad vector size", __FUNCTION__); + default: _assert_msg_(false, "%s: Bad vector size", __FUNCTION__); } int transpose = (reg>>5) & 1; const int mtx = (reg >> 2) & 7; @@ -194,11 +194,11 @@ void WriteVector(const float *rd, VectorSize size, int reg) { int length = 0; switch (size) { - case V_Single: _dbg_assert_(JIT, 0); return; // transpose = 0; row=(reg>>5)&3; length = 1; break; + case V_Single: _dbg_assert_(false); return; // transpose = 0; row=(reg>>5)&3; length = 1; break; case V_Pair: row=(reg>>5)&2; length = 2; break; case V_Triple: row=(reg>>6)&1; length = 3; break; case V_Quad: row=(reg>>5)&2; length = 4; break; - default: _assert_msg_(JIT, 0, "%s: Bad vector size", __FUNCTION__); + default: _assert_msg_(false, "%s: Bad vector size", __FUNCTION__); } if (currentMIPS->VfpuWriteMask() == 0) { @@ -243,7 +243,7 @@ void ReadMatrix(float *rd, MatrixSize size, int reg) { case M_2x2: row = (reg >> 5) & 2; side = 2; break; case M_3x3: row = (reg >> 6) & 1; side = 3; break; case M_4x4: row = (reg >> 5) & 2; side = 4; break; - default: _assert_msg_(JIT, 0, "%s: Bad matrix size", __FUNCTION__); + default: _assert_msg_(false, "%s: Bad matrix size", __FUNCTION__); } // The voffset ordering is now integrated in these formulas, @@ -293,7 +293,7 @@ void WriteMatrix(const float *rd, MatrixSize size, int reg) { case M_2x2: row = (reg >> 5) & 2; side = 2; break; case M_3x3: row = (reg >> 6) & 1; side = 3; break; case M_4x4: row = (reg >> 5) & 2; side = 4; break; - default: _assert_msg_(JIT, 0, "%s: Bad matrix size", __FUNCTION__); + default: _assert_msg_(false, "%s: Bad matrix size", __FUNCTION__); } if (currentMIPS->VfpuWriteMask() != 0) { @@ -374,7 +374,7 @@ VectorSize GetHalfVectorSizeSafe(VectorSize sz) { VectorSize GetHalfVectorSize(VectorSize sz) { VectorSize res = GetHalfVectorSizeSafe(sz); - _assert_msg_(JIT, res != V_Invalid, "%s: Bad vector size", __FUNCTION__); + _assert_msg_(res != V_Invalid, "%s: Bad vector size", __FUNCTION__); return res; } @@ -388,7 +388,7 @@ VectorSize GetDoubleVectorSizeSafe(VectorSize sz) { VectorSize GetDoubleVectorSize(VectorSize sz) { VectorSize res = GetDoubleVectorSizeSafe(sz); - _assert_msg_(JIT, res != V_Invalid, "%s: Bad vector size", __FUNCTION__); + _assert_msg_(res != V_Invalid, "%s: Bad vector size", __FUNCTION__); return res; } @@ -407,7 +407,7 @@ VectorSize GetVecSizeSafe(MIPSOpcode op) { VectorSize GetVecSize(MIPSOpcode op) { VectorSize res = GetVecSizeSafe(op); - _assert_msg_(JIT, res != V_Invalid, "%s: Bad vector size", __FUNCTION__); + _assert_msg_(res != V_Invalid, "%s: Bad vector size", __FUNCTION__); return res; } @@ -423,7 +423,7 @@ VectorSize GetVectorSizeSafe(MatrixSize sz) { VectorSize GetVectorSize(MatrixSize sz) { VectorSize res = GetVectorSizeSafe(sz); - _assert_msg_(JIT, res != V_Invalid, "%s: Bad vector size", __FUNCTION__); + _assert_msg_(res != V_Invalid, "%s: Bad vector size", __FUNCTION__); return res; } @@ -439,7 +439,7 @@ MatrixSize GetMatrixSizeSafe(VectorSize sz) { MatrixSize GetMatrixSize(VectorSize sz) { MatrixSize res = GetMatrixSizeSafe(sz); - _assert_msg_(JIT, res != M_Invalid, "%s: Bad vector size", __FUNCTION__); + _assert_msg_(res != M_Invalid, "%s: Bad vector size", __FUNCTION__); return res; } @@ -458,7 +458,7 @@ MatrixSize GetMtxSizeSafe(MIPSOpcode op) { MatrixSize GetMtxSize(MIPSOpcode op) { MatrixSize res = GetMtxSizeSafe(op); - _assert_msg_(JIT, res != M_Invalid, "%s: Bad matrix size", __FUNCTION__); + _assert_msg_(res != M_Invalid, "%s: Bad matrix size", __FUNCTION__); return res; } @@ -474,7 +474,7 @@ VectorSize MatrixVectorSizeSafe(MatrixSize sz) { VectorSize MatrixVectorSize(MatrixSize sz) { VectorSize res = MatrixVectorSizeSafe(sz); - _assert_msg_(JIT, res != V_Invalid, "%s: Bad matrix size", __FUNCTION__); + _assert_msg_(res != V_Invalid, "%s: Bad matrix size", __FUNCTION__); return res; } @@ -490,7 +490,7 @@ int GetMatrixSideSafe(MatrixSize sz) { int GetMatrixSide(MatrixSize sz) { int res = GetMatrixSideSafe(sz); - _assert_msg_(JIT, res != 0, "%s: Bad matrix size", __FUNCTION__); + _assert_msg_(res != 0, "%s: Bad matrix size", __FUNCTION__); return res; } @@ -776,7 +776,7 @@ float vfpu_dot(float a[4], float b[4]) { mant_sum <<= shift; max_exp -= shift; } - _dbg_assert_msg_(JIT, (mant_sum & 0x00800000) != 0, "Mantissa wrong: %08x", mant_sum); + _dbg_assert_msg_((mant_sum & 0x00800000) != 0, "Mantissa wrong: %08x", mant_sum); if (max_exp >= 255) { max_exp = 255; diff --git a/Core/MIPS/x86/Asm.cpp b/Core/MIPS/x86/Asm.cpp index d927ba8c6d..a70a414049 100644 --- a/Core/MIPS/x86/Asm.cpp +++ b/Core/MIPS/x86/Asm.cpp @@ -163,13 +163,13 @@ void Jit::GenerateFixedCode(JitOptions &jo) { #endif #ifdef _M_IX86 - _assert_msg_(CPU, Memory::base != 0, "Memory base bogus"); + _assert_msg_( Memory::base != 0, "Memory base bogus"); MOV(32, R(EAX), MDisp(EAX, (u32)Memory::base)); #elif _M_X64 MOV(32, R(EAX), MComplex(MEMBASEREG, RAX, SCALE_1, 0)); #endif MOV(32, R(EDX), R(EAX)); - _assert_msg_(JIT, MIPS_JITBLOCK_MASK == 0xFF000000, "Hardcoded assumption of emuhack mask"); + _assert_msg_(MIPS_JITBLOCK_MASK == 0xFF000000, "Hardcoded assumption of emuhack mask"); SHR(32, R(EDX), Imm8(24)); CMP(32, R(EDX), Imm8(MIPS_EMUHACK_OPCODE >> 24)); FixupBranch notfound = J_CC(CC_NE); diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index a0c30a3582..b8816d4a12 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -336,7 +336,7 @@ void Jit::BranchRSRTComp(MIPSOpcode op, Gen::CCFlags cc, bool likely) { case CC_E: immBranchNotTaken = rsImm == rtImm; break; case CC_NE: immBranchNotTaken = rsImm != rtImm; break; - default: immBranchNotTaken = false; _dbg_assert_msg_(JIT, false, "Bad cc flag in BranchRSRTComp()."); + default: immBranchNotTaken = false; _dbg_assert_msg_(false, "Bad cc flag in BranchRSRTComp()."); } immBranch = true; immBranchTaken = !immBranchNotTaken; @@ -412,7 +412,7 @@ void Jit::BranchRSZeroComp(MIPSOpcode op, Gen::CCFlags cc, bool andLink, bool li case CC_GE: immBranchNotTaken = imm >= 0; break; case CC_L: immBranchNotTaken = imm < 0; break; case CC_LE: immBranchNotTaken = imm <= 0; break; - default: immBranchNotTaken = false; _dbg_assert_msg_(JIT, false, "Bad cc flag in BranchRSZeroComp()."); + default: immBranchNotTaken = false; _dbg_assert_msg_(false, "Bad cc flag in BranchRSZeroComp()."); } immBranch = true; immBranchTaken = !immBranchNotTaken; @@ -479,7 +479,7 @@ void Jit::Comp_RelBranch(MIPSOpcode op) case 23: BranchRSZeroComp(op, CC_LE, false, true); break;//bgtzl default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } } @@ -497,7 +497,7 @@ void Jit::Comp_RelBranchRI(MIPSOpcode op) case 18: BranchRSZeroComp(op, CC_GE, true, true); break; //R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(addr); else SkipLikely(); break;//bltzall case 19: BranchRSZeroComp(op, CC_L, true, true); break; //R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(addr); else SkipLikely(); break;//bgezall default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } } @@ -536,7 +536,7 @@ void Jit::Comp_FPUBranch(MIPSOpcode op) case 2: BranchFPFlag(op, CC_NZ, true); break; //bc1fl case 3: BranchFPFlag(op, CC_Z, true); break; //bc1tl default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } } @@ -587,7 +587,7 @@ void Jit::Comp_VBranch(MIPSOpcode op) case 2: BranchVFPUFlag(op, CC_NZ, true); break; //bvfl case 3: BranchVFPUFlag(op, CC_Z, true); break; //bvtl default: - _dbg_assert_msg_(CPU,0,"Comp_VBranch: Invalid instruction"); + _dbg_assert_msg_(false,"Comp_VBranch: Invalid instruction"); break; } } @@ -665,7 +665,7 @@ void Jit::Comp_Jump(MIPSOpcode op) { break; default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } js.compiling = false; @@ -699,7 +699,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op) CompileDelaySlot(DELAYSLOT_FLUSH); // Syscalls write the exit code for us. - _dbg_assert_msg_(JIT, !js.compiling, "Expected syscall to write an exit code."); + _dbg_assert_msg_(!js.compiling, "Expected syscall to write an exit code."); return; } else if (delaySlotIsNice) @@ -753,7 +753,7 @@ void Jit::Comp_JumpReg(MIPSOpcode op) case 9: //jalr break; default: - _dbg_assert_msg_(CPU,0,"Trying to compile instruction that can't be compiled"); + _dbg_assert_msg_(false,"Trying to compile instruction that can't be compiled"); break; } diff --git a/Core/MIPS/x86/CompFPU.cpp b/Core/MIPS/x86/CompFPU.cpp index 806d631047..cb1d7be5ed 100644 --- a/Core/MIPS/x86/CompFPU.cpp +++ b/Core/MIPS/x86/CompFPU.cpp @@ -116,7 +116,7 @@ void Jit::Comp_FPU3op(MIPSOpcode op) { break; case 3: CompFPTriArith(op, &XEmitter::DIVSS, true); break; //F(fd) = F(fs) / F(ft); //div default: - _dbg_assert_msg_(CPU,0,"Trying to compile FPU3Op instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to compile FPU3Op instruction that can't be interpreted"); break; } } @@ -169,7 +169,7 @@ void Jit::Comp_FPULS(MIPSOpcode op) { break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret FPULS instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret FPULS instruction that can't be interpreted"); break; } } diff --git a/Core/MIPS/x86/CompLoadStore.cpp b/Core/MIPS/x86/CompLoadStore.cpp index 5182c7fdc2..e3d87bcf94 100644 --- a/Core/MIPS/x86/CompLoadStore.cpp +++ b/Core/MIPS/x86/CompLoadStore.cpp @@ -228,7 +228,7 @@ namespace MIPSComp { break; default: - _dbg_assert_msg_(JIT, 0, "Unsupported left/right load/store instruction."); + _dbg_assert_msg_(false, "Unsupported left/right load/store instruction."); } // Flip ECX around from 3 bytes / 24 bits. @@ -279,7 +279,7 @@ namespace MIPSComp { break; default: - _dbg_assert_msg_(JIT, 0, "Unsupported left/right load/store instruction."); + _dbg_assert_msg_(false, "Unsupported left/right load/store instruction."); } } diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index ff7bd79f2b..da083d97bb 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -602,7 +602,7 @@ void Jit::Comp_VIdt(MIPSOpcode op) { MOVSS(fpr.VX(dregs[3]), R((vd&3)==3 ? XMM1 : XMM0)); break; default: - _dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted"); + _dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted"); break; } ApplyPrefixD(dregs, sz); @@ -2478,7 +2478,7 @@ void Jit::Comp_Mftv(MIPSOpcode op) { } } else { //ERROR - maybe need to make this value too an "interlock" value? - _dbg_assert_msg_(CPU,0,"mfv - invalid register"); + _dbg_assert_msg_(false,"mfv - invalid register"); } } break; @@ -2519,7 +2519,7 @@ void Jit::Comp_Mftv(MIPSOpcode op) { } } else { //ERROR - _dbg_assert_msg_(CPU,0,"mtv - invalid register"); + _dbg_assert_msg_(false,"mtv - invalid register"); } break; diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 0dbdf34d7b..a062c6fc51 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -633,7 +633,7 @@ void Jit::Comp_ReplacementFunc(MIPSOpcode op) { void Jit::Comp_Generic(MIPSOpcode op) { FlushAll(); MIPSInterpretFunc func = MIPSGetInterpretFunc(op); - _dbg_assert_msg_(JIT, (MIPSGetInfo(op) & DELAYSLOT) == 0, "Cannot use interpreter for branch ops."); + _dbg_assert_msg_((MIPSGetInfo(op) & DELAYSLOT) == 0, "Cannot use interpreter for branch ops."); if (func) { @@ -663,7 +663,7 @@ static void HitInvalidBranch(uint32_t dest) { } void Jit::WriteExit(u32 destination, int exit_num) { - _dbg_assert_msg_(JIT, exit_num < MAX_JIT_BLOCK_EXITS, "Expected a valid exit_num"); + _dbg_assert_msg_(exit_num < MAX_JIT_BLOCK_EXITS, "Expected a valid exit_num"); if (!Memory::IsValidAddress(destination)) { ERROR_LOG_REPORT(JIT, "Trying to write block exit to illegal destination %08x: pc = %08x", destination, currentMIPS->pc); diff --git a/Core/MIPS/x86/JitSafeMem.cpp b/Core/MIPS/x86/JitSafeMem.cpp index 676f8b1ced..d35e3022ce 100644 --- a/Core/MIPS/x86/JitSafeMem.cpp +++ b/Core/MIPS/x86/JitSafeMem.cpp @@ -142,7 +142,7 @@ OpArg JitSafeMem::NextFastAddress(int suboffset) #endif } - _dbg_assert_msg_(JIT, (suboffset & alignMask_) == suboffset, "suboffset must be aligned"); + _dbg_assert_msg_((suboffset & alignMask_) == suboffset, "suboffset must be aligned"); #if PPSSPP_ARCH(32BIT) return MDisp(xaddr_, (u32) Memory::base + offset_ + suboffset); @@ -303,7 +303,7 @@ bool JitSafeMem::PrepareSlowRead(const void *safeFunc) void JitSafeMem::NextSlowRead(const void *safeFunc, int suboffset) { - _dbg_assert_msg_(JIT, !fast_, "NextSlowRead() called in fast memory mode?"); + _dbg_assert_msg_(!fast_, "NextSlowRead() called in fast memory mode?"); // For simplicity, do nothing for 0. We already read in PrepareSlowRead(). if (suboffset == 0) @@ -311,7 +311,7 @@ void JitSafeMem::NextSlowRead(const void *safeFunc, int suboffset) if (jit_->gpr.IsImm(raddr_)) { - _dbg_assert_msg_(JIT, !Memory::IsValidAddress(iaddr_ + suboffset), "NextSlowRead() for an invalid immediate address?"); + _dbg_assert_msg_(!Memory::IsValidAddress(iaddr_ + suboffset), "NextSlowRead() for an invalid immediate address?"); jit_->MOV(32, R(EAX), Imm32((iaddr_ + suboffset) & alignMask_)); } diff --git a/Core/MIPS/x86/RegCache.cpp b/Core/MIPS/x86/RegCache.cpp index 11868c0e82..43c22b100f 100644 --- a/Core/MIPS/x86/RegCache.cpp +++ b/Core/MIPS/x86/RegCache.cpp @@ -198,7 +198,7 @@ X64Reg GPRRegCache::GetFreeXReg() } //Still no dice? Die! - _assert_msg_(JIT, 0, "Regcache ran out of regs"); + _assert_msg_(false, "Regcache ran out of regs"); return (X64Reg) -1; } @@ -302,7 +302,7 @@ bool GPRRegCache::IsImm(MIPSGPReg preg) const { } u32 GPRRegCache::GetImm(MIPSGPReg preg) const { - _dbg_assert_msg_(JIT, IsImm(preg), "Reg %d must be an immediate.", preg); + _dbg_assert_msg_(IsImm(preg), "Reg %d must be an immediate.", preg); // Always 0 for ZERO. if (preg == MIPS_REG_ZERO) return 0; @@ -411,15 +411,12 @@ void GPRRegCache::StoreFromRegister(MIPSGPReg i) { void GPRRegCache::Flush() { for (int i = 0; i < NUM_X_REGS; i++) { - if (xregs[i].allocLocked) - PanicAlert("Someone forgot to unlock X64 reg %i.", i); + _assert_msg_(!xregs[i].allocLocked, "Someone forgot to unlock X64 reg %i.", i); } SetImm(MIPS_REG_ZERO, 0); for (int i = 1; i < NUM_MIPS_GPRS; i++) { const MIPSGPReg r = MIPSGPReg(i); - if (regs[i].locked) { - PanicAlert("Somebody forgot to unlock MIPS reg %i.", i); - } + _assert_msg_(!regs[i].locked, "Somebody forgot to unlock MIPS reg %i.", i); if (regs[i].away) { if (regs[i].location.IsSimpleReg()) { X64Reg xr = RX(r); @@ -429,7 +426,7 @@ void GPRRegCache::Flush() { else if (regs[i].location.IsImm()) { StoreFromRegister(r); } else { - _assert_msg_(JIT,0,"Jit64 - Flush unhandled case, reg %i PC: %08x", i, mips->pc); + _assert_msg_(false, "Jit64 - Flush unhandled case, reg %i PC: %08x", i, mips->pc); } } } diff --git a/Core/MIPS/x86/RegCacheFPU.cpp b/Core/MIPS/x86/RegCacheFPU.cpp index b4542a3f5c..74adfe7d3f 100644 --- a/Core/MIPS/x86/RegCacheFPU.cpp +++ b/Core/MIPS/x86/RegCacheFPU.cpp @@ -199,7 +199,7 @@ bool FPURegCache::IsMappedVS(const u8 *v, VectorSize vsz) { void FPURegCache::MapRegsVS(const u8 *r, VectorSize vsz, int flags) { const int n = GetNumVectorElements(vsz); - _dbg_assert_msg_(JIT, jo_->enableVFPUSIMD, "Should not map simd regs when option is off."); + _dbg_assert_msg_(jo_->enableVFPUSIMD, "Should not map simd regs when option is off."); if (!TryMapRegsVS(r, vsz, flags)) { // TODO: Could be more optimal. @@ -207,7 +207,7 @@ void FPURegCache::MapRegsVS(const u8 *r, VectorSize vsz, int flags) { StoreFromRegisterV(r[i]); } if (!TryMapRegsVS(r, vsz, flags)) { - _dbg_assert_msg_(JIT, false, "MapRegsVS() failed on second try."); + _dbg_assert_msg_(false, "MapRegsVS() failed on second try."); } } } @@ -223,8 +223,8 @@ bool FPURegCache::CanMapVS(const u8 *v, VectorSize vsz) { return true; } else if (vregs[v[0]].lane != 0) { const MIPSCachedFPReg &v0 = vregs[v[0]]; - _dbg_assert_msg_(JIT, v0.away, "Must be away when lane != 0"); - _dbg_assert_msg_(JIT, v0.location.IsSimpleReg(), "Must be is register when lane != 0"); + _dbg_assert_msg_(v0.away, "Must be away when lane != 0"); + _dbg_assert_msg_(v0.location.IsSimpleReg(), "Must be is register when lane != 0"); // Already in a different simd set. return false; @@ -245,7 +245,7 @@ bool FPURegCache::CanMapVS(const u8 *v, VectorSize vsz) { if (vregs[v[i]].locked) { return false; } - _assert_msg_(JIT, !vregs[v[i]].location.IsImm(), "Cannot handle imms in fp cache."); + _assert_msg_(!vregs[v[i]].location.IsImm(), "Cannot handle imms in fp cache."); } return true; @@ -331,7 +331,7 @@ X64Reg FPURegCache::LoadRegsVS(const u8 *v, int n) { X64Reg xrs[4] = {INVALID_REG, INVALID_REG, INVALID_REG, INVALID_REG}; bool xrsLoaded[4] = {false, false, false, false}; - _dbg_assert_msg_(JIT, n >= 2 && n <= 4, "LoadRegsVS is only implemented for simd loads."); + _dbg_assert_msg_(n >= 2 && n <= 4, "LoadRegsVS is only implemented for simd loads."); for (int i = 0; i < n; ++i) { const MIPSCachedFPReg &mr = vregs[v[i]]; @@ -345,7 +345,7 @@ X64Reg FPURegCache::LoadRegsVS(const u8 *v, int n) { ++regsLoaded; ++regsAvail; } else if (mr.lane != 0) { - _dbg_assert_msg_(JIT, false, "LoadRegsVS is not able to handle simd remapping yet, store first."); + _dbg_assert_msg_(false, "LoadRegsVS is not able to handle simd remapping yet, store first."); } } } @@ -386,8 +386,8 @@ X64Reg FPURegCache::LoadRegsVS(const u8 *v, int n) { // TODO: Not handling the case of some regs avail and some loaded right now. if (regsAvail < n && (sequential != n || regsLoaded == n || regsAvail == 0)) { regsAvail = GetFreeXRegs(xrs, 2, true); - _dbg_assert_msg_(JIT, regsAvail >= 2, "Ran out of fp regs for loading simd regs with."); - _dbg_assert_msg_(JIT, xrs[0] != xrs[1], "Regs for simd load are the same, bad things await."); + _dbg_assert_msg_(regsAvail >= 2, "Ran out of fp regs for loading simd regs with."); + _dbg_assert_msg_(xrs[0] != xrs[1], "Regs for simd load are the same, bad things await."); // We spilled, so we assume that all our regs are screwed up now anyway. for (int i = 0; i < 4; ++i) { xrsLoaded[i] = false; @@ -448,7 +448,7 @@ X64Reg FPURegCache::LoadRegsVS(const u8 *v, int n) { } res = xrs[0]; } else { - _dbg_assert_msg_(JIT, n > 2, "2 should not be possible here."); + _dbg_assert_msg_(n > 2, "2 should not be possible here."); // Available regs are less than n, and some may be loaded. // Let's grab the most optimal unloaded ones. @@ -513,8 +513,8 @@ bool FPURegCache::TryMapDirtyInVS(const u8 *vd, VectorSize vdsz, const u8 *vs, V ReleaseSpillLockV(vs, vssz); ReleaseSpillLockV(vd, vdsz); - _dbg_assert_msg_(JIT, !success || IsMappedVS(vd, vdsz), "vd should be mapped now"); - _dbg_assert_msg_(JIT, !success || IsMappedVS(vs, vssz), "vs should be mapped now"); + _dbg_assert_msg_(!success || IsMappedVS(vd, vdsz), "vd should be mapped now"); + _dbg_assert_msg_(!success || IsMappedVS(vs, vssz), "vs should be mapped now"); return success; } @@ -538,9 +538,9 @@ bool FPURegCache::TryMapDirtyInInVS(const u8 *vd, VectorSize vdsz, const u8 *vs, ReleaseSpillLockV(vs, vssz); ReleaseSpillLockV(vt, vtsz); - _dbg_assert_msg_(JIT, !success || IsMappedVS(vd, vdsz), "vd should be mapped now"); - _dbg_assert_msg_(JIT, !success || IsMappedVS(vs, vssz), "vs should be mapped now"); - _dbg_assert_msg_(JIT, !success || IsMappedVS(vt, vtsz), "vt should be mapped now"); + _dbg_assert_msg_(!success || IsMappedVS(vd, vdsz), "vd should be mapped now"); + _dbg_assert_msg_(!success || IsMappedVS(vs, vssz), "vs should be mapped now"); + _dbg_assert_msg_(!success || IsMappedVS(vt, vtsz), "vt should be mapped now"); return success; } @@ -585,7 +585,7 @@ void FPURegCache::SimpleRegV(const u8 v, int flags) { if (flags & MAP_DIRTY) { xregs[VX(v)].dirty = true; } - _assert_msg_(JIT, vr.location.IsSimpleReg(), "not loaded and not simple."); + _assert_msg_(vr.location.IsSimpleReg(), "not loaded and not simple."); } Invariant(); } @@ -603,13 +603,13 @@ void FPURegCache::ReleaseSpillLocks() { void FPURegCache::MapReg(const int i, bool doLoad, bool makeDirty) { pendingFlush = true; - _assert_msg_(JIT, !regs[i].location.IsImm(), "WTF - FPURegCache::MapReg - imm"); - _assert_msg_(JIT, i >= 0 && i < NUM_MIPS_FPRS, "WTF - FPURegCache::MapReg - invalid mips reg %d", i); + _assert_msg_(!regs[i].location.IsImm(), "WTF - FPURegCache::MapReg - imm"); + _assert_msg_(i >= 0 && i < NUM_MIPS_FPRS, "WTF - FPURegCache::MapReg - invalid mips reg %d", i); if (!regs[i].away) { // Reg is at home in the memory register file. Let's pull it out. X64Reg xr = GetFreeXReg(); - _assert_msg_(JIT, xr < NUM_X_FPREGS, "WTF - FPURegCache::MapReg - invalid reg %d", (int)xr); + _assert_msg_(xr < NUM_X_FPREGS, "WTF - FPURegCache::MapReg - invalid reg %d", (int)xr); xregs[xr].mipsReg = i; xregs[xr].dirty = makeDirty; OpArg newloc = ::Gen::R(xr); @@ -627,7 +627,7 @@ void FPURegCache::MapReg(const int i, bool doLoad, bool makeDirty) { } else { // There are no immediates in the FPR reg file, so we already had this in a register. Make dirty as necessary. xregs[RX(i)].dirty |= makeDirty; - _assert_msg_(JIT, regs[i].location.IsSimpleReg(), "not loaded and not simple."); + _assert_msg_(regs[i].location.IsSimpleReg(), "not loaded and not simple."); } Invariant(); } @@ -648,12 +648,12 @@ static int MMShuffleSwapTo0(int lane) { } void FPURegCache::StoreFromRegister(int i) { - _assert_msg_(JIT, !regs[i].location.IsImm(), "WTF - FPURegCache::StoreFromRegister - it's an imm"); - _assert_msg_(JIT, i >= 0 && i < NUM_MIPS_FPRS, "WTF - FPURegCache::StoreFromRegister - invalid mipsreg %i PC=%08x", i, js_->compilerPC); + _assert_msg_(!regs[i].location.IsImm(), "WTF - FPURegCache::StoreFromRegister - it's an imm"); + _assert_msg_(i >= 0 && i < NUM_MIPS_FPRS, "WTF - FPURegCache::StoreFromRegister - invalid mipsreg %i PC=%08x", i, js_->compilerPC); if (regs[i].away) { X64Reg xr = regs[i].location.GetSimpleReg(); - _assert_msg_(JIT, xr < NUM_X_FPREGS, "WTF - FPURegCache::StoreFromRegister - invalid reg: x %i (mr: %i). PC=%08x", (int)xr, i, js_->compilerPC); + _assert_msg_(xr < NUM_X_FPREGS, "WTF - FPURegCache::StoreFromRegister - invalid reg: x %i (mr: %i). PC=%08x", (int)xr, i, js_->compilerPC); if (regs[i].lane != 0) { const int *mri = xregs[xr].mipsRegs; int seq = 1; @@ -727,16 +727,16 @@ void FPURegCache::StoreFromRegister(int i) { xregs[xr].dirty = false; regs[i].away = false; } else { - // _assert_msg_(DYNA_REC,0,"already stored"); + // _assert_msg_(false,"already stored"); } Invariant(); } void FPURegCache::DiscardR(int i) { - _assert_msg_(JIT, !regs[i].location.IsImm(), "FPU can't handle imm yet."); + _assert_msg_(!regs[i].location.IsImm(), "FPU can't handle imm yet."); if (regs[i].away) { X64Reg xr = regs[i].location.GetSimpleReg(); - _assert_msg_(JIT, xr < NUM_X_FPREGS, "DiscardR: MipsReg had bad X64Reg"); + _assert_msg_(xr < NUM_X_FPREGS, "DiscardR: MipsReg had bad X64Reg"); // Note that we DO NOT write it back here. That's the whole point of Discard. if (regs[i].lane != 0) { // But we can't just discard all of them in SIMD, just the one lane. @@ -769,19 +769,19 @@ void FPURegCache::DiscardR(int i) { regs[i].away = false; regs[i].tempLocked = false; } else { - // _assert_msg_(DYNA_REC,0,"already stored"); + // _assert_msg_(false,"already stored"); regs[i].tempLocked = false; } Invariant(); } void FPURegCache::DiscardVS(int vreg) { - _assert_msg_(JIT, !vregs[vreg].location.IsImm(), "FPU can't handle imm yet."); + _assert_msg_(!vregs[vreg].location.IsImm(), "FPU can't handle imm yet."); if (vregs[vreg].away) { - _assert_msg_(JIT, vregs[vreg].lane != 0, "VS expects a SIMD reg."); + _assert_msg_(vregs[vreg].lane != 0, "VS expects a SIMD reg."); X64Reg xr = vregs[vreg].location.GetSimpleReg(); - _assert_msg_(JIT, xr < NUM_X_FPREGS, "DiscardR: MipsReg had bad X64Reg"); + _assert_msg_(xr < NUM_X_FPREGS, "DiscardR: MipsReg had bad X64Reg"); // Note that we DO NOT write it back here. That's the whole point of Discard. for (int i = 0; i < 4; ++i) { int mr = xregs[xr].mipsRegs[i]; @@ -813,7 +813,7 @@ int FPURegCache::GetTempR() { } } - _assert_msg_(JIT, 0, "Regcache ran out of temp regs, might need to DiscardR() some."); + _assert_msg_(false, "Regcache ran out of temp regs, might need to DiscardR() some."); return -1; } @@ -852,7 +852,7 @@ int FPURegCache::GetTempVS(u8 *v, VectorSize vsz) { } if (found != n) { - _assert_msg_(JIT, 0, "Regcache ran out of temp regs, might need to DiscardR() some."); + _assert_msg_(false, "Regcache ran out of temp regs, might need to DiscardR() some."); return -1; } @@ -879,7 +879,7 @@ void FPURegCache::Flush() { } else if (regs[i].location.IsImm()) { StoreFromRegister(i); } else { - _assert_msg_(JIT,0,"Jit64 - Flush unhandled case, reg %i PC: %08x", i, mips->pc); + _assert_msg_(false, "Jit64 - Flush unhandled case, reg %i PC: %08x", i, mips->pc); } } } @@ -909,7 +909,7 @@ OpArg FPURegCache::GetDefaultLocation(int reg) const { void FPURegCache::Invariant() const { #ifdef _DEBUG - _dbg_assert_msg_(JIT, SanityCheck() == 0, "Sanity check failed: %d", SanityCheck()); + _dbg_assert_msg_(SanityCheck() == 0, "Sanity check failed: %d", SanityCheck()); #endif } @@ -1043,7 +1043,7 @@ X64Reg FPURegCache::GetFreeXReg() { X64Reg res; int obtained = GetFreeXRegs(&res, 1); - _assert_msg_(JIT, obtained == 1, "Regcache ran out of regs"); + _assert_msg_(obtained == 1, "Regcache ran out of regs"); return res; } @@ -1052,7 +1052,7 @@ int FPURegCache::GetFreeXRegs(X64Reg *res, int n, bool spill) { int aCount; const int *aOrder = GetAllocationOrder(aCount); - _dbg_assert_msg_(JIT, n <= NUM_X_FPREGS - 2, "Cannot obtain that many regs."); + _dbg_assert_msg_(n <= NUM_X_FPREGS - 2, "Cannot obtain that many regs."); int r = 0; @@ -1072,7 +1072,7 @@ int FPURegCache::GetFreeXRegs(X64Reg *res, int n, bool spill) { for (int i = 0; i < aCount; i++) { X64Reg xr = (X64Reg)aOrder[i]; int preg = xregs[xr].mipsReg; - _assert_msg_(JIT, preg >= -1 && preg < NUM_MIPS_FPRS, "WTF - FPURegCache::GetFreeXRegs - invalid mips reg %d in xr %d", preg, (int)xr); + _assert_msg_(preg >= -1 && preg < NUM_MIPS_FPRS, "WTF - FPURegCache::GetFreeXRegs - invalid mips reg %d in xr %d", preg, (int)xr); // We're only spilling here, so don't overlap. if (preg != -1 && !regs[preg].locked) { diff --git a/Core/MIPS/x86/RegCacheFPU.h b/Core/MIPS/x86/RegCacheFPU.h index dd0916ebc9..8054321834 100644 --- a/Core/MIPS/x86/RegCacheFPU.h +++ b/Core/MIPS/x86/RegCacheFPU.h @@ -126,11 +126,11 @@ public: const Gen::OpArg &R(int freg) const {return regs[freg].location;} const Gen::OpArg &V(int vreg) const { - _dbg_assert_msg_(JIT, vregs[vreg].lane == 0, "SIMD reg %d used as V reg (use VS instead). pc=%08x", vreg, mips->pc); + _dbg_assert_msg_(vregs[vreg].lane == 0, "SIMD reg %d used as V reg (use VS instead). pc=%08x", vreg, mips->pc); return vregs[vreg].location; } const Gen::OpArg &VS(const u8 *vs) const { - _dbg_assert_msg_(JIT, vregs[vs[0]].lane != 0, "V reg %d used as VS reg (use V instead). pc=%08x", vs[0], mips->pc); + _dbg_assert_msg_(vregs[vs[0]].lane != 0, "V reg %d used as VS reg (use V instead). pc=%08x", vs[0], mips->pc); return vregs[vs[0]].location; } @@ -142,7 +142,7 @@ public: } Gen::X64Reg VX(int vreg) const { - _dbg_assert_msg_(JIT, vregs[vreg].lane == 0, "SIMD reg %d used as V reg (use VSX instead). pc=%08x", vreg, mips->pc); + _dbg_assert_msg_(vregs[vreg].lane == 0, "SIMD reg %d used as V reg (use VSX instead). pc=%08x", vreg, mips->pc); if (vregs[vreg].away && vregs[vreg].location.IsSimpleReg()) return vregs[vreg].location.GetSimpleReg(); PanicAlert("Not so simple - v%i", vreg); @@ -150,7 +150,7 @@ public: } Gen::X64Reg VSX(const u8 *vs) const { - _dbg_assert_msg_(JIT, vregs[vs[0]].lane != 0, "V reg %d used as VS reg (use VX instead). pc=%08x", vs[0], mips->pc); + _dbg_assert_msg_(vregs[vs[0]].lane != 0, "V reg %d used as VS reg (use VX instead). pc=%08x", vs[0], mips->pc); if (vregs[vs[0]].away && vregs[vs[0]].location.IsSimpleReg()) return vregs[vs[0]].location.GetSimpleReg(); PanicAlert("Not so simple - v%i", vs[0]); diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index b2fa2d0cd7..066ad85602 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -285,7 +285,7 @@ void Init() { // On some 32 bit platforms, you can only map < 32 megs at a time. // TODO: Wait, wtf? What platforms are those? This seems bad. const static int MAX_MMAP_SIZE = 31 * 1024 * 1024; - _dbg_assert_msg_(MEMMAP, g_MemorySize < MAX_MMAP_SIZE * 3, "ACK - too much memory for three mmap views."); + _dbg_assert_msg_(g_MemorySize < MAX_MMAP_SIZE * 3, "ACK - too much memory for three mmap views."); for (size_t i = 0; i < ARRAY_SIZE(views); i++) { if (views[i].flags & MV_IS_PRIMARY_RAM) views[i].size = std::min((int)g_MemorySize, MAX_MMAP_SIZE); @@ -304,7 +304,7 @@ void Init() { } void Reinit() { - _assert_msg_(SYSTEM, PSP_IsInited(), "Cannot reinit during startup/shutdown"); + _assert_msg_(PSP_IsInited(), "Cannot reinit during startup/shutdown"); Core_NotifyLifecycle(CoreLifecycle::MEMORY_REINITING); Shutdown(); Init(); diff --git a/Core/Screenshot.cpp b/Core/Screenshot.cpp index a90f3c542b..fb1ef83944 100644 --- a/Core/Screenshot.cpp +++ b/Core/Screenshot.cpp @@ -229,7 +229,7 @@ static bool ConvertPixelTo8888RGBA(GPUDebugBufferFormat fmt, u8 &r, u8 &g, u8 &b a = (src >> 8) & 0xFF; break; default: - _assert_msg_(SYSTEM, false, "Unsupported framebuffer format for screenshot: %d", fmt); + _assert_msg_(false, "Unsupported framebuffer format for screenshot: %d", fmt); return false; } diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 4b10586b07..41edb29ce0 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -222,7 +222,7 @@ void TextureReplacer::ParseHashRange(const std::string &key, const std::string & } u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, GETextureFormat fmt, u16 maxSeenV) { - _dbg_assert_msg_(G3D, enabled_, "Replacement not enabled"); + _dbg_assert_msg_(enabled_, "Replacement not enabled"); if (!LookupHashRange(addr, w, h)) { // There wasn't any hash range, let's fall back to maxSeenV logic. @@ -398,7 +398,7 @@ static bool WriteTextureToPNG(png_imagep image, const std::string &filename, int #endif void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &replacedInfo, const void *data, int pitch, int level, int w, int h) { - _assert_msg_(G3D, enabled_, "Replacement not enabled"); + _assert_msg_(enabled_, "Replacement not enabled"); if (!g_Config.bSaveNewTextures) { // Ignore. return; @@ -595,8 +595,8 @@ bool TextureReplacer::LookupHashRange(u32 addr, int &w, int &h) { } void ReplacedTexture::Load(int level, void *out, int rowPitch) { - _assert_msg_(G3D, (size_t)level < levels_.size(), "Invalid miplevel"); - _assert_msg_(G3D, out != nullptr && rowPitch > 0, "Invalid out/pitch"); + _assert_msg_((size_t)level < levels_.size(), "Invalid miplevel"); + _assert_msg_(out != nullptr && rowPitch > 0, "Invalid out/pitch"); const ReplacedTextureLevel &info = levels_[level]; diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index a5e9bc0e5e..a29f4f49e9 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -292,7 +292,7 @@ void GenerateDepalShader(char *buffer, GEBufferFormat pixelFormat, ShaderLanguag break; case HLSL_D3D11_LEVEL9: default: - _assert_msg_(G3D, false, "Depal shader language not supported: %d", (int)language); + _assert_msg_(false, "Depal shader language not supported: %d", (int)language); } } diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index a09460a46c..22fd104386 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -746,7 +746,7 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G break; case GE_FORMAT_INVALID: - _dbg_assert_msg_(G3D, false, "Invalid pixelFormat passed to DrawPixels()."); + _dbg_assert_msg_(false, "Invalid pixelFormat passed to DrawPixels()."); break; } } @@ -1441,7 +1441,7 @@ void FramebufferManagerCommon::ApplyClearToMemory(int x1, int y1, int x2, int y2 case GE_FORMAT_565: ConvertRGBA8888ToRGB565(&clear16, &clearColor, 1); break; case GE_FORMAT_5551: ConvertRGBA8888ToRGBA5551(&clear16, &clearColor, 1); break; case GE_FORMAT_4444: ConvertRGBA8888ToRGBA4444(&clear16, &clearColor, 1); break; - default: _dbg_assert_(G3D, 0); break; + default: _dbg_assert_(0); break; } clearBits = clear16 | (clear16 << 16); } diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 7f5eb26bdc..07ee628d1e 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -210,8 +210,8 @@ public: FramebufferHeuristicParams inputs; GetFramebufferHeuristicInputs(&inputs, gstate); VirtualFramebuffer *vfb = DoSetRenderFrameBuffer(inputs, skipDrawReason); - _dbg_assert_msg_(G3D, vfb, "DoSetRenderFramebuffer must return a valid framebuffer."); - _dbg_assert_msg_(G3D, currentRenderVfb_, "DoSetRenderFramebuffer must set a valid framebuffer."); + _dbg_assert_msg_(vfb, "DoSetRenderFramebuffer must return a valid framebuffer."); + _dbg_assert_msg_(currentRenderVfb_, "DoSetRenderFramebuffer must set a valid framebuffer."); return vfb; } } diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index 7d75996f3f..b33738f508 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -147,7 +147,7 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, id.SetBit(VS_BIT_FLATSHADE, doFlatShading); // These two bits cannot be combined, otherwise havoc occurs. We get reports that indicate this happened somehow... "ERROR: 0:14: 'u_proj' : undeclared identifier" - _dbg_assert_msg_(G3D, !id.Bit(VS_BIT_USE_HW_TRANSFORM) || !id.Bit(VS_BIT_IS_THROUGH), "Can't have both THROUGH and USE_HW_TRANSFORM together!"); + _dbg_assert_msg_(!id.Bit(VS_BIT_USE_HW_TRANSFORM) || !id.Bit(VS_BIT_IS_THROUGH), "Can't have both THROUGH and USE_HW_TRANSFORM together!"); *id_out = id; } diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 851be7d363..8680f33f1b 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -866,7 +866,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi } void TextureCacheCommon::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) { - _dbg_assert_msg_(G3D, framebuffer != nullptr, "Framebuffer must not be null."); + _dbg_assert_msg_(framebuffer != nullptr, "Framebuffer must not be null."); framebuffer->usageFlags |= FB_USAGE_TEXTURE; if (framebufferManager_->UseBufferedRendering()) { @@ -1181,7 +1181,7 @@ static inline void ConvertFormatToRGBA8888(GETextureFormat format, u32 *dst, con ConvertRGB565ToRGBA8888(dst, src, numPixels); break; default: - _dbg_assert_msg_(G3D, false, "Incorrect texture format."); + _dbg_assert_msg_(false, "Incorrect texture format."); break; } } diff --git a/GPU/Common/VertexDecoderArm.cpp b/GPU/Common/VertexDecoderArm.cpp index f4fde1e097..5f9dd3371a 100644 --- a/GPU/Common/VertexDecoderArm.cpp +++ b/GPU/Common/VertexDecoderArm.cpp @@ -543,7 +543,7 @@ void VertexDecoderJitCache::Jit_WeightsU16Skin() { void VertexDecoderJitCache::Jit_WeightsFloatSkin() { for (int i = 1; i < dec_->nweights; ++i) { - _dbg_assert_msg_(JIT, weightRegs[i - 1] + 1 == weightRegs[i], "VertexDecoder weightRegs must be in order."); + _dbg_assert_msg_(weightRegs[i - 1] + 1 == weightRegs[i], "VertexDecoder weightRegs must be in order."); } // Weights are always first, so we can use srcReg directly. @@ -1210,8 +1210,8 @@ void VertexDecoderJitCache::Jit_NormalFloat() { // Through expands into floats, always. Might want to look at changing this. void VertexDecoderJitCache::Jit_PosS8Through() { DEBUG_LOG_REPORT_ONCE(vertexS8Through, G3D, "Using S8 positions in throughmode"); - _dbg_assert_msg_(JIT, fpScratchReg + 1 == fpScratchReg2, "VertexDecoder fpScratchRegs must be in order."); - _dbg_assert_msg_(JIT, fpScratchReg2 + 1 == fpScratchReg3, "VertexDecoder fpScratchRegs must be in order."); + _dbg_assert_msg_(fpScratchReg + 1 == fpScratchReg2, "VertexDecoder fpScratchRegs must be in order."); + _dbg_assert_msg_(fpScratchReg2 + 1 == fpScratchReg3, "VertexDecoder fpScratchRegs must be in order."); // TODO: SIMD LDRSB(tempReg1, srcReg, dec_->posoff); @@ -1236,8 +1236,8 @@ void VertexDecoderJitCache::Jit_PosS8Through() { // Through expands into floats, always. Might want to look at changing this. void VertexDecoderJitCache::Jit_PosS16Through() { - _dbg_assert_msg_(JIT, fpScratchReg + 1 == fpScratchReg2, "VertexDecoder fpScratchRegs must be in order."); - _dbg_assert_msg_(JIT, fpScratchReg2 + 1 == fpScratchReg3, "VertexDecoder fpScratchRegs must be in order."); + _dbg_assert_msg_(fpScratchReg + 1 == fpScratchReg2, "VertexDecoder fpScratchRegs must be in order."); + _dbg_assert_msg_(fpScratchReg2 + 1 == fpScratchReg3, "VertexDecoder fpScratchRegs must be in order."); LDRSH(tempReg1, srcReg, dec_->posoff); LDRSH(tempReg2, srcReg, dec_->posoff + 2); @@ -1301,7 +1301,7 @@ void VertexDecoderJitCache::Jit_NormalS16Skin() { void VertexDecoderJitCache::Jit_NormalFloatSkin() { for (int i = 1; i < 3; ++i) { - _dbg_assert_msg_(JIT, src[i - 1] + 1 == src[i], "VertexDecoder src regs must be in order."); + _dbg_assert_msg_(src[i - 1] + 1 == src[i], "VertexDecoder src regs must be in order."); } ADD(tempReg1, srcReg, dec_->nrmoff); @@ -1325,8 +1325,8 @@ void VertexDecoderJitCache::Jit_WriteMatrixMul(int outOff, bool pos) { } VST1(F_32, accNEON, scratchReg, 2); } else { - _dbg_assert_msg_(JIT, fpScratchReg + 1 == fpScratchReg2, "VertexDecoder fpScratchRegs must be in order."); - _dbg_assert_msg_(JIT, fpScratchReg2 + 1 == fpScratchReg3, "VertexDecoder fpScratchRegs must be in order."); + _dbg_assert_msg_(fpScratchReg + 1 == fpScratchReg2, "VertexDecoder fpScratchRegs must be in order."); + _dbg_assert_msg_(fpScratchReg2 + 1 == fpScratchReg3, "VertexDecoder fpScratchRegs must be in order."); MOVP2R(tempReg1, skinMatrix); VLDMIA(tempReg1, true, fpScratchReg, 3); @@ -1364,7 +1364,7 @@ void VertexDecoderJitCache::Jit_PosS16Skin() { void VertexDecoderJitCache::Jit_PosFloatSkin() { for (int i = 1; i < 3; ++i) { - _dbg_assert_msg_(JIT, src[i - 1] + 1 == src[i], "VertexDecoder src regs must be in order."); + _dbg_assert_msg_(src[i - 1] + 1 == src[i], "VertexDecoder src regs must be in order."); } ADD(tempReg1, srcReg, dec_->posoff); diff --git a/GPU/Common/VertexDecoderX86.cpp b/GPU/Common/VertexDecoderX86.cpp index e67b50fea0..c8329ec1c4 100644 --- a/GPU/Common/VertexDecoderX86.cpp +++ b/GPU/Common/VertexDecoderX86.cpp @@ -1452,8 +1452,8 @@ void VertexDecoderJitCache::Jit_AnyS16ToFloat(int srcoff) { } void VertexDecoderJitCache::Jit_AnyU8ToFloat(int srcoff, u32 bits) { - _dbg_assert_msg_(JIT, (bits & ~(32 | 16 | 8)) == 0, "Bits must be a multiple of 8."); - _dbg_assert_msg_(JIT, bits >= 8 && bits <= 32, "Bits must be a between 8 and 32."); + _dbg_assert_msg_((bits & ~(32 | 16 | 8)) == 0, "Bits must be a multiple of 8."); + _dbg_assert_msg_(bits >= 8 && bits <= 32, "Bits must be a between 8 and 32."); if (!cpu_info.bSSE4_1) { PXOR(XMM3, R(XMM3)); @@ -1484,8 +1484,8 @@ void VertexDecoderJitCache::Jit_AnyU8ToFloat(int srcoff, u32 bits) { } void VertexDecoderJitCache::Jit_AnyU16ToFloat(int srcoff, u32 bits) { - _dbg_assert_msg_(JIT, (bits & ~(64 | 32 | 16)) == 0, "Bits must be a multiple of 16."); - _dbg_assert_msg_(JIT, bits >= 16 && bits <= 64, "Bits must be a between 16 and 64."); + _dbg_assert_msg_((bits & ~(64 | 32 | 16)) == 0, "Bits must be a multiple of 16."); + _dbg_assert_msg_(bits >= 16 && bits <= 64, "Bits must be a between 16 and 64."); if (!cpu_info.bSSE4_1) { PXOR(XMM3, R(XMM3)); diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 6db131aceb..2eb66a4472 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -437,7 +437,7 @@ void DrawEngineD3D11::DoFlush() { vai->numVerts = indexGen.PureCount(); } - _dbg_assert_msg_(G3D, gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); + _dbg_assert_msg_(gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); // TODO: Combine these two into one buffer? u32 size = dec_->GetDecVtxFmt().stride * indexGen.MaxIndex(); diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index b11e0a7dda..6a4e2c2e97 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -664,7 +664,7 @@ static void ReplayStop() { } bool RunMountedReplay(const std::string &filename) { - _assert_msg_(SYSTEM, !GPURecord::IsActivePending(), "Cannot run replay while recording."); + _assert_msg_(!GPURecord::IsActivePending(), "Cannot run replay while recording."); std::lock_guard guard(executeLock); Core_ListenStopRequest(&ReplayStop); diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index d34d75c087..521393b548 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -417,7 +417,7 @@ void DrawEngineDX9::DoFlush() { vai->numVerts = indexGen.PureCount(); } - _dbg_assert_msg_(G3D, gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); + _dbg_assert_msg_(gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); void * pVb; u32 size = dec_->GetDecVtxFmt().stride * indexGen.MaxIndex(); diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 92edeb6f08..737548acd1 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -109,7 +109,7 @@ void DrawEngineGLES::DeviceRestore(Draw::DrawContext *draw) { } void DrawEngineGLES::InitDeviceObjects() { - _assert_msg_(G3D, render_ != nullptr, "Render manager must be set"); + _assert_msg_(render_ != nullptr, "Render manager must be set"); for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { frameData_[i].pushVertex = render_->CreatePushBuffer(i, GL_ARRAY_BUFFER, 1024 * 1024); @@ -416,7 +416,7 @@ void DrawEngineGLES::DoFlush() { } if (vai->vbo == nullptr) { - _dbg_assert_msg_(G3D, gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); + _dbg_assert_msg_(gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); // We'll populate the cache this time around, use it next time. populateCache = true; diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index cd63cb8c0d..d3ae9616c7 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -312,7 +312,7 @@ void FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFra } void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { - _assert_msg_(G3D, nvfb->fbo, "Expecting a valid nvfb in UpdateDownloadTempBuffer"); + _assert_msg_(nvfb->fbo, "Expecting a valid nvfb in UpdateDownloadTempBuffer"); // Discard the previous contents of this buffer where possible. if (gl_extensions.GLES3) { diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index d13c892ac6..eb992d642a 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -736,10 +736,10 @@ LinkedShader *ShaderManagerGLES::ApplyFragmentShader(VShaderID VSID, Shader *vs, shaderSwitchDirtyUniforms_ = 0; if (ls == nullptr) { - _dbg_assert_(G3D, FSID.Bit(FS_BIT_LMODE) == VSID.Bit(VS_BIT_LMODE)); - _dbg_assert_(G3D, FSID.Bit(FS_BIT_DO_TEXTURE) == VSID.Bit(VS_BIT_DO_TEXTURE)); - _dbg_assert_(G3D, FSID.Bit(FS_BIT_ENABLE_FOG) == VSID.Bit(VS_BIT_ENABLE_FOG)); - _dbg_assert_(G3D, FSID.Bit(FS_BIT_FLATSHADE) == VSID.Bit(VS_BIT_FLATSHADE)); + _dbg_assert_(FSID.Bit(FS_BIT_LMODE) == VSID.Bit(VS_BIT_LMODE)); + _dbg_assert_(FSID.Bit(FS_BIT_DO_TEXTURE) == VSID.Bit(VS_BIT_DO_TEXTURE)); + _dbg_assert_(FSID.Bit(FS_BIT_ENABLE_FOG) == VSID.Bit(VS_BIT_ENABLE_FOG)); + _dbg_assert_(FSID.Bit(FS_BIT_FLATSHADE) == VSID.Bit(VS_BIT_FLATSHADE)); // Check if we can link these. ls = new LinkedShader(render_, VSID, vs, FSID, fs, vs->UseHWTransform()); diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 9c7baedf54..a73b09de25 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -2541,7 +2541,7 @@ std::vector GPUCommon::ActiveDisplayLists() { void GPUCommon::ResetListPC(int listID, u32 pc) { if (listID < 0 || listID >= DisplayListMaxCount) { - _dbg_assert_msg_(G3D, false, "listID out of range: %d", listID); + _dbg_assert_msg_(false, "listID out of range: %d", listID); return; } @@ -2550,7 +2550,7 @@ void GPUCommon::ResetListPC(int listID, u32 pc) { void GPUCommon::ResetListStall(int listID, u32 stall) { if (listID < 0 || listID >= DisplayListMaxCount) { - _dbg_assert_msg_(G3D, false, "listID out of range: %d", listID); + _dbg_assert_msg_(false, "listID out of range: %d", listID); return; } @@ -2559,7 +2559,7 @@ void GPUCommon::ResetListStall(int listID, u32 stall) { void GPUCommon::ResetListState(int listID, DisplayListState state) { if (listID < 0 || listID >= DisplayListMaxCount) { - _dbg_assert_msg_(G3D, false, "listID out of range: %d", listID); + _dbg_assert_msg_(false, "listID out of range: %d", listID); return; } diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 23a0437be2..f7897008f2 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -268,7 +268,7 @@ static inline u32 GetPixelColor(int x, int y) return fb.Get32(x, y, gstate.FrameBufStride()); case GE_FORMAT_INVALID: - _dbg_assert_msg_(G3D, false, "Software: invalid framebuf format."); + _dbg_assert_msg_(false, "Software: invalid framebuf format."); } return 0; } @@ -293,7 +293,7 @@ static inline void SetPixelColor(int x, int y, u32 value) break; case GE_FORMAT_INVALID: - _dbg_assert_msg_(G3D, false, "Software: invalid framebuf format."); + _dbg_assert_msg_(false, "Software: invalid framebuf format."); } } @@ -1498,7 +1498,7 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) break; case GE_FORMAT_INVALID: - _dbg_assert_msg_(G3D, false, "Software: invalid framebuf format."); + _dbg_assert_msg_(false, "Software: invalid framebuf format."); break; } diff --git a/GPU/Software/SamplerX86.cpp b/GPU/Software/SamplerX86.cpp index 5fdca729f8..2fb08e88d3 100644 --- a/GPU/Software/SamplerX86.cpp +++ b/GPU/Software/SamplerX86.cpp @@ -97,7 +97,7 @@ alignas(16) static const float by256[4] = { 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / alignas(16) static const float ones[4] = { 1.0f, 1.0f, 1.0f, 1.0f, }; LinearFunc SamplerJitCache::CompileLinear(const SamplerID &id) { - _assert_msg_(G3D, id.linear, "Linear should be set on sampler id"); + _assert_msg_(id.linear, "Linear should be set on sampler id"); BeginWrite(); // We'll first write the nearest sampler, which we will CALL. diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 0efb0903d4..a30f7f875f 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -54,7 +54,7 @@ void SoftwareDrawEngine::DispatchFlush() { } void SoftwareDrawEngine::DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) { - _assert_msg_(G3D, cullMode == gstate.getCullMode(), "Mixed cull mode not supported."); + _assert_msg_(cullMode == gstate.getCullMode(), "Mixed cull mode not supported."); transformUnit.SubmitPrimitive(verts, inds, prim, vertexCount, vertTypeID, bytesRead, this); } @@ -398,7 +398,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy break; default: - _dbg_assert_msg_(G3D, false, "Unexpected prim type: %d", prim_type); + _dbg_assert_msg_(false, "Unexpected prim type: %d", prim_type); } } break; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 704d2367dc..506716dd00 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -393,9 +393,9 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView key.base_ = base; key.light_ = light; key.bone_ = bone; - _dbg_assert_(G3D, base != VK_NULL_HANDLE); - _dbg_assert_(G3D, light != VK_NULL_HANDLE); - _dbg_assert_(G3D, bone != VK_NULL_HANDLE); + _dbg_assert_(base != VK_NULL_HANDLE); + _dbg_assert_(light != VK_NULL_HANDLE); + _dbg_assert_(bone != VK_NULL_HANDLE); FrameData &frame = frame_[vulkan_->GetCurFrame()]; // See if we already have this descriptor set cached. @@ -425,14 +425,14 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView // so let's do that. See https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkAllocateDescriptorSets.html // Fragmentation shouldn't really happen though since we wipe the pool every frame.. VkResult res = RecreateDescriptorPool(frame, frame.descPoolSize); - _assert_msg_(G3D, res == VK_SUCCESS, "Ran out of descriptor space (frag?) and failed to recreate a descriptor pool. sz=%d res=%d", (int)frame.descSets.size(), (int)res); + _assert_msg_(res == VK_SUCCESS, "Ran out of descriptor space (frag?) and failed to recreate a descriptor pool. sz=%d res=%d", (int)frame.descSets.size(), (int)res); descAlloc.descriptorPool = frame.descPool; // Need to update this pointer since we have allocated a new one. result = vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc); - _assert_msg_(G3D, result == VK_SUCCESS, "Ran out of descriptor space (frag?) and failed to allocate after recreating a descriptor pool. res=%d", (int)result); + _assert_msg_(result == VK_SUCCESS, "Ran out of descriptor space (frag?) and failed to allocate after recreating a descriptor pool. res=%d", (int)result); } // Even in release mode, this is bad. - _assert_msg_(G3D, result == VK_SUCCESS, "Ran out of descriptor space in pool. sz=%d res=%d", (int)frame.descSets.size(), (int)result); + _assert_msg_(result == VK_SUCCESS, "Ran out of descriptor space in pool. sz=%d res=%d", (int)frame.descSets.size(), (int)result); // We just don't write to the slots we don't care about, which is fine. VkWriteDescriptorSet writes[7]{}; @@ -713,7 +713,7 @@ void DrawEngineVulkan::DoFlush() { if (!vai->vb) { // Directly push to the vertex cache. DecodeVertsToPushBuffer(vertexCache_, &vai->vbOffset, &vai->vb); - _dbg_assert_msg_(G3D, gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); + _dbg_assert_msg_(gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching."); vai->numVerts = indexGen.VertexCount(); vai->prim = indexGen.Prim(); vai->maxIndex = indexGen.MaxIndex(); @@ -823,7 +823,7 @@ void DrawEngineVulkan::DoFlush() { } shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, true, useHWTessellation_); // usehwtransform - _dbg_assert_msg_(G3D, vshader->UseHWTransform(), "Bad vshader"); + _dbg_assert_msg_(vshader->UseHWTransform(), "Bad vshader"); Draw::NativeObject object = framebufferManager_->UseBufferedRendering() ? Draw::NativeObject::FRAMEBUFFER_RENDERPASS : Draw::NativeObject::BACKBUFFER_RENDERPASS; VkRenderPass renderPass = (VkRenderPass)draw_->GetNativeObject(object); @@ -946,7 +946,7 @@ void DrawEngineVulkan::DoFlush() { } if (!lastPipeline_ || gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE) || prim != lastPrim_) { shaderManager_->GetShaders(prim, lastVType_, &vshader, &fshader, false, false); // usehwtransform - _dbg_assert_msg_(G3D, !vshader->UseHWTransform(), "Bad vshader"); + _dbg_assert_msg_(!vshader->UseHWTransform(), "Bad vshader"); if (prim != lastPrim_ || gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE)) { ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey_, dynState_); } diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index d655404c5c..e8898c144b 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -307,7 +307,7 @@ static VulkanPipeline *CreateVulkanPipeline(VkDevice device, VkPipelineCache pip // 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)); + _dbg_assert_msg_(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. @@ -335,7 +335,7 @@ VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layo } VulkanPipelineKey key{}; - _assert_msg_(G3D, renderPass, "Can't create a pipeline with a null renderpass"); + _assert_msg_(renderPass, "Can't create a pipeline with a null renderpass"); key.raster = rasterKey; key.renderPass = renderPass; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index fab02bb056..6e6cff086a 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -245,16 +245,16 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader FSID = lastFSID_; } - _dbg_assert_(G3D, FSID.Bit(FS_BIT_LMODE) == VSID.Bit(VS_BIT_LMODE)); - _dbg_assert_(G3D, FSID.Bit(FS_BIT_DO_TEXTURE) == VSID.Bit(VS_BIT_DO_TEXTURE)); - _dbg_assert_(G3D, FSID.Bit(FS_BIT_ENABLE_FOG) == VSID.Bit(VS_BIT_ENABLE_FOG)); - _dbg_assert_(G3D, FSID.Bit(FS_BIT_FLATSHADE) == VSID.Bit(VS_BIT_FLATSHADE)); + _dbg_assert_(FSID.Bit(FS_BIT_LMODE) == VSID.Bit(VS_BIT_LMODE)); + _dbg_assert_(FSID.Bit(FS_BIT_DO_TEXTURE) == VSID.Bit(VS_BIT_DO_TEXTURE)); + _dbg_assert_(FSID.Bit(FS_BIT_ENABLE_FOG) == VSID.Bit(VS_BIT_ENABLE_FOG)); + _dbg_assert_(FSID.Bit(FS_BIT_FLATSHADE) == VSID.Bit(VS_BIT_FLATSHADE)); // Just update uniforms if this is the same shader as last time. if (lastVShader_ != nullptr && lastFShader_ != nullptr && VSID == lastVSID_ && FSID == lastFSID_) { *vshader = lastVShader_; *fshader = lastFShader_; - _dbg_assert_msg_(G3D, (*vshader)->UseHWTransform() == useHWTransform, "Bad vshader was cached"); + _dbg_assert_msg_((*vshader)->UseHWTransform() == useHWTransform, "Bad vshader was cached"); // Already all set, no need to look up in shader maps. return; } @@ -284,7 +284,7 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader *vshader = vs; *fshader = fs; - _dbg_assert_msg_(G3D, (*vshader)->UseHWTransform() == useHWTransform, "Bad vshader was computed"); + _dbg_assert_msg_((*vshader)->UseHWTransform() == useHWTransform, "Bad vshader was computed"); } std::vector ShaderManagerVulkan::DebugGetShaderIDs(DebugShaderType type) { diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index f729c75224..8e1adacccf 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -654,9 +654,9 @@ void TextureCacheVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext if (g_Config.bTexHardwareScaling) { uploadCS_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_COMPUTE_BIT, fullUploadShader.c_str(), &error); - _dbg_assert_msg_(G3D, uploadCS_ != VK_NULL_HANDLE, "failed to compile upload shader"); + _dbg_assert_msg_(uploadCS_ != VK_NULL_HANDLE, "failed to compile upload shader"); copyCS_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_COMPUTE_BIT, fullCopyShader.c_str(), &error); - _dbg_assert_msg_(G3D, copyCS_!= VK_NULL_HANDLE, "failed to compile copy shader"); + _dbg_assert_msg_(copyCS_!= VK_NULL_HANDLE, "failed to compile copy shader"); } computeShaderManager_.DeviceRestore(vulkan); diff --git a/Qt/QtMain.h b/Qt/QtMain.h index ebb2c03cea..19a820e7fb 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -55,7 +55,7 @@ public: renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); renderManager_->SetInflightFrames(g_Config.iInflightFrames); bool success = draw_->CreatePresets(); - _assert_msg_(G3D, success, "Failed to compile preset shaders"); + _assert_msg_(success, "Failed to compile preset shaders"); // TODO: Need to figure out how to implement SetSwapInterval for Qt. } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 4420a5a04d..bb59188e86 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -808,7 +808,7 @@ void RenderOverlays(UIContext *dc, void *userdata); bool NativeInitGraphics(GraphicsContext *graphicsContext) { ILOG("NativeInitGraphics"); - _assert_msg_(G3D, graphicsContext, "No graphics context!"); + _assert_msg_(graphicsContext, "No graphics context!"); // We set this now so any resize during init is processed later. resized = false; @@ -816,8 +816,8 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { using namespace Draw; Core_SetGraphicsContext(graphicsContext); g_draw = graphicsContext->GetDrawContext(); - _assert_msg_(G3D, g_draw, "No draw context available!"); - _assert_msg_(G3D, g_draw->GetVshaderPreset(VS_COLOR_2D) != nullptr, "Failed to compile presets"); + _assert_msg_(g_draw, "No draw context available!"); + _assert_msg_(g_draw->GetVshaderPreset(VS_COLOR_2D) != nullptr, "Failed to compile presets"); // Load the atlas. @@ -825,7 +825,7 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { if (!g_ui_atlas.IsMetadataLoaded()) { const uint8_t *atlas_data = VFSReadFile("ui_atlas.meta", &atlas_data_size); bool load_success = atlas_data != nullptr && g_ui_atlas.Load(atlas_data, atlas_data_size); - _assert_msg_(G3D, load_success, "Failed to load ui_atlas.meta"); + _assert_msg_(load_success, "Failed to load ui_atlas.meta"); delete[] atlas_data; } ui_draw2d.SetAtlas(&g_ui_atlas); diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 384849aedd..6b41ca425b 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -280,7 +280,7 @@ void CGEDebugger::DescribePrimaryPreview(const GPUgstate &state, wchar_t desc[25 return; } - _assert_msg_(G3D, primaryBuffer_ != nullptr, "Must have a valid primaryBuffer_"); + _assert_msg_(primaryBuffer_ != nullptr, "Must have a valid primaryBuffer_"); switch (PrimaryDisplayType(fbTabs->CurrentTabIndex())) { case PRIMARY_FRAMEBUF: diff --git a/Windows/GEDebugger/SimpleGLWindow.cpp b/Windows/GEDebugger/SimpleGLWindow.cpp index 07fef48e02..4586ab566b 100644 --- a/Windows/GEDebugger/SimpleGLWindow.cpp +++ b/Windows/GEDebugger/SimpleGLWindow.cpp @@ -296,7 +296,7 @@ void SimpleGLWindow::Draw(const u8 *data, int w, int h, bool flipped, Format fmt glfmt = GL_UNSIGNED_BYTE; components = GL_RED; } else { - _dbg_assert_msg_(COMMON, false, "Invalid SimpleGLWindow format."); + _dbg_assert_msg_(false, "Invalid SimpleGLWindow format."); } } diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 31b3bcb086..498467ea37 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -187,7 +187,7 @@ bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { draw_ = Draw::T3DCreateD3D11Context(device_, context_, device1_, context1_, featureLevel_, hWnd_, adapterNames); SetGPUBackend(GPUBackend::DIRECT3D11, chosenAdapterName); bool success = draw_->CreatePresets(); // If we can run D3D11, there's a compiler installed. I think. - _assert_msg_(G3D, success, "Failed to compile preset shaders"); + _assert_msg_(success, "Failed to compile preset shaders"); int width; int height; diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index 71e215c0bc..9e5e028fc2 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -409,7 +409,7 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) { renderManager_->SetInflightFrames(g_Config.iInflightFrames); SetGPUBackend(GPUBackend::OPENGL); bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these. - _assert_msg_(G3D, success, "Failed to compile preset shaders"); + _assert_msg_(success, "Failed to compile preset shaders"); renderManager_->SetSwapFunction([&]() {::SwapBuffers(hDC); }); if (wglSwapIntervalEXT) { // glew loads wglSwapIntervalEXT if available diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 909881b3d8..c74fa27024 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -138,7 +138,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m draw_ = Draw::T3DCreateVulkanContext(vulkan_, splitSubmit); SetGPUBackend(GPUBackend::VULKAN, vulkan_->GetPhysicalDeviceProperties(deviceNum).properties.deviceName); bool success = draw_->CreatePresets(); - _assert_msg_(G3D, success, "Failed to compile preset shaders"); + _assert_msg_(success, "Failed to compile preset shaders"); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); renderManager_ = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index 5e7604a0c0..de58b828c1 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -53,7 +53,7 @@ bool AndroidEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int des renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); renderManager_->SetInflightFrames(g_Config.iInflightFrames); bool success = draw_->CreatePresets(); // There will always be a GLSL compiler capable of compiling these. - _assert_msg_(G3D, success, "Failed to compile preset shaders"); + _assert_msg_(success, "Failed to compile preset shaders"); return true; } diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index b60f87cfb4..afc5de6921 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -21,7 +21,7 @@ bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); renderManager_->SetInflightFrames(g_Config.iInflightFrames); bool success = draw_->CreatePresets(); - _assert_msg_(G3D, success, "Failed to compile preset shaders"); + _assert_msg_(success, "Failed to compile preset shaders"); return success; } diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 3363bfeac6..06b09dae9b 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -104,7 +104,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, g_Config.bGfxDebugSplitSubmit); SetGPUBackend(GPUBackend::VULKAN); success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler. - _assert_msg_(G3D, success, "Failed to compile preset shaders"); + _assert_msg_(success, "Failed to compile preset shaders"); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 682212be0e..a8ae366eda 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -180,10 +180,10 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski CHECK_GL_ERROR_IF_DEBUG(); GLRProgram *program = step.create_program.program; program->program = glCreateProgram(); - _assert_msg_(G3D, step.create_program.num_shaders > 0, "Can't create a program with zero shaders"); + _assert_msg_(step.create_program.num_shaders > 0, "Can't create a program with zero shaders"); bool anyFailed = false; for (int j = 0; j < step.create_program.num_shaders; j++) { - _dbg_assert_msg_(G3D, step.create_program.shaders[j]->shader, "Can't create a program with a null shader"); + _dbg_assert_msg_(step.create_program.shaders[j]->shader, "Can't create a program with a null shader"); anyFailed = anyFailed || step.create_program.shaders[j]->failed; glAttachShader(program->program, step.create_program.shaders[j]->shader); } @@ -1310,7 +1310,7 @@ void GLQueueRunner::PerformCopy(const GLRStep &step) { break; case GL_DEPTH_BUFFER_BIT: // TODO: Support depth copies. - _assert_msg_(G3D, false, "Depth copies not yet supported - soon"); + _assert_msg_(false, "Depth copies not yet supported - soon"); target = GL_RENDERBUFFER; /* srcTex = src->depth.texture; @@ -1319,8 +1319,8 @@ void GLQueueRunner::PerformCopy(const GLRStep &step) { break; } - _dbg_assert_(G3D, srcTex); - _dbg_assert_(G3D, dstTex); + _dbg_assert_(srcTex); + _dbg_assert_(dstTex); #if defined(USING_GLES2) #ifndef IOS diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 3ceb142b69..220b54aec4 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -320,7 +320,7 @@ void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRende } void GLRenderManager::BindFramebufferAsTexture(GLRFramebuffer *fb, int binding, int aspectBit, int attachment) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BIND_FB_TEXTURE }; data.bind_fb_texture.slot = binding; data.bind_fb_texture.framebuffer = fb; @@ -675,7 +675,7 @@ void GLPushBuffer::Unmap() { void GLPushBuffer::Flush() { // Must be called from the render thread. - _dbg_assert_(G3D, OnRenderThread()); + _dbg_assert_(OnRenderThread()); buffers_[buf_].flushOffset = offset_; if (!buffers_[buf_].deviceMemory && writePtr_) { @@ -760,7 +760,7 @@ void GLPushBuffer::NextBuffer(size_t minSize) { } void GLPushBuffer::Defragment() { - _dbg_assert_msg_(G3D, !OnRenderThread(), "Defragment must not run on the render thread"); + _dbg_assert_msg_(!OnRenderThread(), "Defragment must not run on the render thread"); if (buffers_.size() <= 1) { // Let's take this chance to jetison localMemory we don't need. @@ -780,7 +780,7 @@ void GLPushBuffer::Defragment() { size_ = newSize; bool res = AddBuffer(); - _assert_msg_(G3D, res, "AddBuffer failed"); + _assert_msg_(res, "AddBuffer failed"); } size_t GLPushBuffer::GetTotalSize() const { @@ -792,7 +792,7 @@ size_t GLPushBuffer::GetTotalSize() const { } void GLPushBuffer::MapDevice(GLBufferStrategy strategy) { - _dbg_assert_msg_(G3D, OnRenderThread(), "MapDevice must run on render thread"); + _dbg_assert_msg_(OnRenderThread(), "MapDevice must run on render thread"); strategy_ = strategy; if (strategy_ == GLBufferStrategy::SUBDATA) { @@ -815,7 +815,7 @@ void GLPushBuffer::MapDevice(GLBufferStrategy strategy) { mapChanged = true; } - _dbg_assert_msg_(G3D, info.localMemory || info.deviceMemory, "Local or device memory must succeed"); + _dbg_assert_msg_(info.localMemory || info.deviceMemory, "Local or device memory must succeed"); } if (writePtr_ && mapChanged) { @@ -826,7 +826,7 @@ void GLPushBuffer::MapDevice(GLBufferStrategy strategy) { } void GLPushBuffer::UnmapDevice() { - _dbg_assert_msg_(G3D, OnRenderThread(), "UnmapDevice must run on render thread"); + _dbg_assert_msg_(OnRenderThread(), "UnmapDevice must run on render thread"); for (auto &info : buffers_) { if (info.deviceMemory) { diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 40cbcb0d27..13aa599741 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -325,7 +325,7 @@ public: } void Take(GLDeleter &other) { - _assert_msg_(G3D, IsEmpty(), "Deleter already has stuff"); + _assert_msg_(IsEmpty(), "Deleter already has stuff"); shaders = std::move(other.shaders); programs = std::move(other.programs); buffers = std::move(other.buffers); @@ -437,7 +437,7 @@ public: step.create_program.program->queries_ = queries; step.create_program.program->initialize_ = initalizers; step.create_program.support_dual_source = supportDualSource; - _assert_msg_(G3D, shaders.size() > 0, "Can't create a program with zero shaders"); + _assert_msg_(shaders.size() > 0, "Can't create a program with zero shaders"); for (size_t i = 0; i < shaders.size(); i++) { step.create_program.shaders[i] = shaders[i]; } @@ -531,8 +531,8 @@ public: // TODO: Maybe should be a render command instead of an init command? When possible it's better as // an init command, that's for sure. GLRInitStep step{ GLRInitStepType::BUFFER_SUBDATA }; - _dbg_assert_(G3D, offset >= 0); - _dbg_assert_(G3D, offset <= buffer->size_ - size); + _dbg_assert_(offset >= 0); + _dbg_assert_(offset <= buffer->size_ - size); step.buffer_subdata.buffer = buffer; step.buffer_subdata.offset = (int)offset; step.buffer_subdata.size = (int)size; @@ -556,7 +556,7 @@ public: } void TextureSubImage(GLRTexture *texture, int level, int x, int y, int width, int height, Draw::DataFormat format, uint8_t *data, GLRAllocType allocType = GLRAllocType::NEW) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData _data{ GLRRenderCommand::TEXTURE_SUBIMAGE }; _data.texture_subimage.texture = texture; _data.texture_subimage.data = data; @@ -579,18 +579,18 @@ public: } void BindTexture(int slot, GLRTexture *tex) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BINDTEXTURE }; - _dbg_assert_(G3D, slot < 16); + _dbg_assert_(slot < 16); data.texture.slot = slot; data.texture.texture = tex; curRenderStep_->commands.push_back(data); } void BindProgram(GLRProgram *program) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BINDPROGRAM }; - _dbg_assert_(G3D, program != nullptr); + _dbg_assert_(program != nullptr); data.program.program = program; curRenderStep_->commands.push_back(data); #ifdef _DEBUG @@ -599,7 +599,7 @@ public: } void BindPixelPackBuffer(GLRBuffer *buffer) { // Want to support an offset but can't in ES 2.0. We supply an offset when binding the buffers instead. - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BIND_BUFFER }; data.bind_buffer.buffer = buffer; data.bind_buffer.target = GL_PIXEL_PACK_BUFFER; @@ -607,7 +607,7 @@ public: } void BindIndexBuffer(GLRBuffer *buffer) { // Want to support an offset but can't in ES 2.0. We supply an offset when binding the buffers instead. - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BIND_BUFFER}; data.bind_buffer.buffer = buffer; data.bind_buffer.target = GL_ELEMENT_ARRAY_BUFFER; @@ -615,7 +615,7 @@ public: } void BindVertexBuffer(GLRInputLayout *inputLayout, GLRBuffer *buffer, size_t offset) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); assert(inputLayout); GLRRenderData data{ GLRRenderCommand::BIND_VERTEX_BUFFER }; data.bindVertexBuffer.inputLayout = inputLayout; @@ -625,7 +625,7 @@ public: } void SetDepth(bool enabled, bool write, GLenum func) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::DEPTH }; data.depth.enabled = enabled; data.depth.write = write; @@ -634,21 +634,21 @@ public: } void SetViewport(const GLRViewport &vp) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::VIEWPORT }; data.viewport.vp = vp; curRenderStep_->commands.push_back(data); } void SetScissor(const GLRect2D &rc) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::SCISSOR }; data.scissor.rc = rc; curRenderStep_->commands.push_back(data); } void SetUniformI(const GLint *loc, int count, const int *udata) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); #endif @@ -660,7 +660,7 @@ public: } void SetUniformI1(const GLint *loc, int udata) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); #endif @@ -672,7 +672,7 @@ public: } void SetUniformF(const GLint *loc, int count, const float *udata) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); #endif @@ -684,7 +684,7 @@ public: } void SetUniformF1(const GLint *loc, const float udata) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); #endif @@ -696,7 +696,7 @@ public: } void SetUniformF(const char *name, int count, const float *udata) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); #endif @@ -708,7 +708,7 @@ public: } void SetUniformM4x4(const GLint *loc, const float *udata) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); #endif @@ -719,7 +719,7 @@ public: } void SetUniformM4x4(const char *name, const float *udata) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG assert(curProgram_); #endif @@ -730,7 +730,7 @@ public: } void SetBlendAndMask(int colorMask, bool blendEnabled, GLenum srcColor, GLenum dstColor, GLenum srcAlpha, GLenum dstAlpha, GLenum funcColor, GLenum funcAlpha) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BLEND }; data.blend.mask = colorMask; data.blend.enabled = blendEnabled; @@ -744,7 +744,7 @@ public: } void SetNoBlendAndMask(int colorMask) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BLEND }; data.blend.mask = colorMask; data.blend.enabled = false; @@ -753,7 +753,7 @@ public: #ifndef USING_GLES2 void SetLogicOp(bool enabled, GLenum logicOp) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::LOGICOP }; data.logic.enabled = enabled; data.logic.logicOp = logicOp; @@ -762,7 +762,7 @@ public: #endif void SetStencilFunc(bool enabled, GLenum func, uint8_t refValue, uint8_t compareMask) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::STENCILFUNC }; data.stencilFunc.enabled = enabled; data.stencilFunc.func = func; @@ -772,7 +772,7 @@ public: } void SetStencilOp(uint8_t writeMask, GLenum sFail, GLenum zFail, GLenum pass) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::STENCILOP }; data.stencilOp.writeMask = writeMask; data.stencilOp.sFail = sFail; @@ -782,7 +782,7 @@ public: } void SetStencilDisabled() { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data; data.cmd = GLRRenderCommand::STENCILFUNC; data.stencilFunc.enabled = false; @@ -790,14 +790,14 @@ public: } void SetBlendFactor(const float color[4]) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BLENDCOLOR }; CopyFloat4(data.blendColor.color, color); curRenderStep_->commands.push_back(data); } void SetRaster(GLboolean cullEnable, GLenum frontFace, GLenum cullFace, GLboolean ditherEnable) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::RASTER }; data.raster.cullEnable = cullEnable; data.raster.frontFace = frontFace; @@ -808,7 +808,7 @@ public: // Modifies the current texture as per GL specs, not global state. void SetTextureSampler(int slot, GLenum wrapS, GLenum wrapT, GLenum magFilter, GLenum minFilter, float anisotropy) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::TEXTURESAMPLER }; data.textureSampler.slot = slot; data.textureSampler.wrapS = wrapS; @@ -820,7 +820,7 @@ public: } void SetTextureLod(int slot, float minLod, float maxLod, float lodBias) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::TEXTURELOD}; data.textureLod.slot = slot; data.textureLod.minLod = minLod; @@ -831,7 +831,7 @@ public: // If scissorW == 0, no scissor is applied (the whole render target is cleared). void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask, int colorMask, int scissorX, int scissorY, int scissorW, int scissorH) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); if (!clearMask) return; GLRRenderData data{ GLRRenderCommand::CLEAR }; @@ -848,14 +848,14 @@ public: } void Invalidate(int invalidateMask) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::INVALIDATE }; data.clear.clearMask = invalidateMask; curRenderStep_->commands.push_back(data); } void Draw(GLenum mode, int first, int count) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::DRAW }; data.draw.mode = mode; data.draw.first = first; @@ -866,7 +866,7 @@ public: } void DrawIndexed(GLenum mode, int count, GLenum indexType, void *indices, int instances = 1) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::DRAW_INDEXED }; data.drawIndexed.mode = mode; data.drawIndexed.count = count; diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index f078dd705a..088af77b01 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -289,7 +289,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; break; default: - _dbg_assert_msg_(G3D, false, "GetRenderPass: Unexpected color layout %d", (int)key.prevColorLayout); + _dbg_assert_msg_(false, "GetRenderPass: Unexpected color layout %d", (int)key.prevColorLayout); break; } @@ -313,7 +313,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; break; default: - _dbg_assert_msg_(G3D, false, "PerformBindRT: Unexpected depth layout %d", (int)key.prevDepthLayout); + _dbg_assert_msg_(false, "PerformBindRT: Unexpected depth layout %d", (int)key.prevDepthLayout); break; } @@ -346,7 +346,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { // Nothing to do. break; default: - _dbg_assert_msg_(G3D, false, "GetRenderPass: Unexpected final color layout %d", (int)key.finalColorLayout); + _dbg_assert_msg_(false, "GetRenderPass: Unexpected final color layout %d", (int)key.finalColorLayout); break; } @@ -976,7 +976,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; break; default: - _assert_msg_(G3D, false, "PerformRenderPass: Unexpected oldLayout: %d", (int)barrier.oldLayout); + _assert_msg_(false, "PerformRenderPass: Unexpected oldLayout: %d", (int)barrier.oldLayout); break; } barrier.newLayout = iter.targetLayout; @@ -986,7 +986,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; break; default: - _assert_msg_(G3D, false, "PerformRenderPass: Unexpected newLayout: %d", (int)barrier.newLayout); + _assert_msg_(false, "PerformRenderPass: Unexpected newLayout: %d", (int)barrier.newLayout); break; } barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -1081,8 +1081,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c const VkRect2D &rc = c.scissor.scissor; DisplayRect rotated_rc{ rc.offset.x, rc.offset.y, (int)rc.extent.width, (int)rc.extent.height }; RotateRectToDisplay(rotated_rc, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); - _dbg_assert_(G3D, rotated_rc.x >= 0); - _dbg_assert_(G3D, rotated_rc.y >= 0); + _dbg_assert_(rotated_rc.x >= 0); + _dbg_assert_(rotated_rc.y >= 0); VkRect2D finalRect = VkRect2D{ { rotated_rc.x, rotated_rc.y }, { (uint32_t)rotated_rc.w, (uint32_t)rotated_rc.h} }; vkCmdSetScissor(cmd, 0, 1, &finalRect); } @@ -1185,7 +1185,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step int w; int h; if (step.render.framebuffer) { - _dbg_assert_(G3D, step.render.finalColorLayout != VK_IMAGE_LAYOUT_UNDEFINED); + _dbg_assert_(step.render.finalColorLayout != VK_IMAGE_LAYOUT_UNDEFINED); VKRFramebuffer *fb = step.render.framebuffer; framebuf = fb->framebuf; @@ -1429,7 +1429,7 @@ void VulkanQueueRunner::SetupTransitionToTransferSrc(VKRImage &img, VkImageMemor stage |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; break; default: - _dbg_assert_msg_(G3D, false, "Transition from this layout to transfer src not supported (%d)", (int)img.layout); + _dbg_assert_msg_(false, "Transition from this layout to transfer src not supported (%d)", (int)img.layout); break; } barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; @@ -1488,7 +1488,7 @@ void VulkanQueueRunner::SetupTransitionToTransferDst(VKRImage &img, VkImageMemor stage |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; break; default: - _dbg_assert_msg_(G3D, false, "Transition from this layout to transfer dst not supported (%d)", (int)img.layout); + _dbg_assert_msg_(false, "Transition from this layout to transfer dst not supported (%d)", (int)img.layout); break; } barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; @@ -1553,7 +1553,7 @@ void VulkanQueueRunner::PerformReadback(const VKRStep &step, VkCommandBuffer cmd } else if (step.readback.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { srcImage = &step.readback.src->depth; } else { - _dbg_assert_msg_(G3D, false, "No image aspect to readback?"); + _dbg_assert_msg_(false, "No image aspect to readback?"); return; } diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 8278e1ca99..b2307a5a38 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -841,7 +841,7 @@ static void CleanupRenderCommands(std::vector *cmds) { } void VulkanRenderManager::Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); if (!clearMask) return; // If this is the first drawing command or clears everything, merge it into the pass. @@ -868,18 +868,18 @@ void VulkanRenderManager::Clear(uint32_t clearColor, float clearZ, int clearSten } void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, int aspectMask, const char *tag) { - _dbg_assert_msg_(G3D, srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); - _dbg_assert_msg_(G3D, srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); - _dbg_assert_msg_(G3D, srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); - _dbg_assert_msg_(G3D, srcRect.offset.y + srcRect.extent.height <= (uint32_t)src->height, "srcrect offset y (%d) + extent (%d) > height (%d)", srcRect.offset.y, srcRect.extent.height, (uint32_t)src->height); + _dbg_assert_msg_(srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); + _dbg_assert_msg_(srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); + _dbg_assert_msg_(srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); + _dbg_assert_msg_(srcRect.offset.y + srcRect.extent.height <= (uint32_t)src->height, "srcrect offset y (%d) + extent (%d) > height (%d)", srcRect.offset.y, srcRect.extent.height, (uint32_t)src->height); - _dbg_assert_msg_(G3D, srcRect.extent.width > 0, "copy srcwidth == 0"); - _dbg_assert_msg_(G3D, srcRect.extent.height > 0, "copy srcheight == 0"); + _dbg_assert_msg_(srcRect.extent.width > 0, "copy srcwidth == 0"); + _dbg_assert_msg_(srcRect.extent.height > 0, "copy srcheight == 0"); - _dbg_assert_msg_(G3D, dstPos.x >= 0, "dstPos offset x (%d) < 0", dstPos.x); - _dbg_assert_msg_(G3D, dstPos.y >= 0, "dstPos offset y (%d) < 0", dstPos.y); - _dbg_assert_msg_(G3D, dstPos.x + srcRect.extent.width <= (uint32_t)dst->width, "dstPos + extent x > width"); - _dbg_assert_msg_(G3D, dstPos.y + srcRect.extent.height <= (uint32_t)dst->height, "dstPos + extent y > height"); + _dbg_assert_msg_(dstPos.x >= 0, "dstPos offset x (%d) < 0", dstPos.x); + _dbg_assert_msg_(dstPos.y >= 0, "dstPos offset y (%d) < 0", dstPos.y); + _dbg_assert_msg_(dstPos.x + srcRect.extent.width <= (uint32_t)dst->width, "dstPos + extent x > width"); + _dbg_assert_msg_(dstPos.y + srcRect.extent.height <= (uint32_t)dst->height, "dstPos + extent y > height"); for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { @@ -918,21 +918,21 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, } void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter, const char *tag) { - _dbg_assert_msg_(G3D, srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); - _dbg_assert_msg_(G3D, srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); - _dbg_assert_msg_(G3D, srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); - _dbg_assert_msg_(G3D, srcRect.offset.y + srcRect.extent.height <= (uint32_t)src->height, "srcrect offset y (%d) + extent (%d) > height (%d)", srcRect.offset.y, srcRect.extent.height, (uint32_t)src->height); + _dbg_assert_msg_(srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); + _dbg_assert_msg_(srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); + _dbg_assert_msg_(srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); + _dbg_assert_msg_(srcRect.offset.y + srcRect.extent.height <= (uint32_t)src->height, "srcrect offset y (%d) + extent (%d) > height (%d)", srcRect.offset.y, srcRect.extent.height, (uint32_t)src->height); - _dbg_assert_msg_(G3D, srcRect.extent.width > 0, "blit srcwidth == 0"); - _dbg_assert_msg_(G3D, srcRect.extent.height > 0, "blit srcheight == 0"); + _dbg_assert_msg_(srcRect.extent.width > 0, "blit srcwidth == 0"); + _dbg_assert_msg_(srcRect.extent.height > 0, "blit srcheight == 0"); - _dbg_assert_msg_(G3D, dstRect.offset.x >= 0, "dstrect offset x < 0"); - _dbg_assert_msg_(G3D, dstRect.offset.y >= 0, "dstrect offset y < 0"); - _dbg_assert_msg_(G3D, dstRect.offset.x + dstRect.extent.width <= (uint32_t)dst->width, "dstrect offset x + extent > width"); - _dbg_assert_msg_(G3D, dstRect.offset.y + dstRect.extent.height <= (uint32_t)dst->height, "dstrect offset y + extent > height"); + _dbg_assert_msg_(dstRect.offset.x >= 0, "dstrect offset x < 0"); + _dbg_assert_msg_(dstRect.offset.y >= 0, "dstrect offset y < 0"); + _dbg_assert_msg_(dstRect.offset.x + dstRect.extent.width <= (uint32_t)dst->width, "dstrect offset x + extent > width"); + _dbg_assert_msg_(dstRect.offset.y + dstRect.extent.height <= (uint32_t)dst->height, "dstrect offset y + extent > height"); - _dbg_assert_msg_(G3D, dstRect.extent.width > 0, "blit dstwidth == 0"); - _dbg_assert_msg_(G3D, dstRect.extent.height > 0, "blit dstheight == 0"); + _dbg_assert_msg_(dstRect.extent.width > 0, "blit dstwidth == 0"); + _dbg_assert_msg_(dstRect.extent.height > 0, "blit dstheight == 0"); for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { @@ -961,7 +961,7 @@ void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, } VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, int aspectBit, int attachment) { - _dbg_assert_(G3D, curRenderStep_ != nullptr); + _dbg_assert_(curRenderStep_ != nullptr); // Mark the dependency, check for required transitions, and return the image. for (int i = (int)steps_.size() - 1; i >= 0; i--) { @@ -1043,14 +1043,14 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) { WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - processing the frame, but not presenting"); frameData.skipSwap = true; } else { - _assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res)); + _assert_msg_(res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res)); } VkCommandBufferBeginInfo begin{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; res = vkBeginCommandBuffer(frameData.mainCmd, &begin); - _assert_msg_(G3D, res == VK_SUCCESS, "vkBeginCommandBuffer failed! result=%s", VulkanResultToString(res)); + _assert_msg_(res == VK_SUCCESS, "vkBeginCommandBuffer failed! result=%s", VulkanResultToString(res)); queueRunner_.SetBackbuffer(framebuffers_[frameData.curSwapchainImage], swapchainImages_[frameData.curSwapchainImage].image); @@ -1066,11 +1066,11 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) { vkCmdWriteTimestamp(frameData.initCmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frameData.profile.queryPool, 1); } VkResult res = vkEndCommandBuffer(frameData.initCmd); - _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%s", VulkanResultToString(res)); + _assert_msg_(res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%s", VulkanResultToString(res)); } VkResult res = vkEndCommandBuffer(frameData.mainCmd); - _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%s", VulkanResultToString(res)); + _assert_msg_(res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%s", VulkanResultToString(res)); VkCommandBuffer cmdBufs[2]; int numCmdBufs = 0; @@ -1084,9 +1084,9 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) { submit_info.pCommandBuffers = cmdBufs; res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, VK_NULL_HANDLE); if (res == VK_ERROR_DEVICE_LOST) { - _assert_msg_(G3D, false, "Lost the Vulkan device in split submit! If this happens again, switch Graphics Backend away from Vulkan"); + _assert_msg_(false, "Lost the Vulkan device in split submit! If this happens again, switch Graphics Backend away from Vulkan"); } else { - _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res)); + _assert_msg_(res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res)); } numCmdBufs = 0; } @@ -1108,9 +1108,9 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) { } res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFrameFence ? frameData.fence : frameData.readbackFence); if (res == VK_ERROR_DEVICE_LOST) { - _assert_msg_(G3D, false, "Lost the Vulkan device in vkQueueSubmit! If this happens again, switch Graphics Backend away from Vulkan"); + _assert_msg_(false, "Lost the Vulkan device in vkQueueSubmit! If this happens again, switch Graphics Backend away from Vulkan"); } else { - _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%s", (int)splitSubmit_, VulkanResultToString(res)); + _assert_msg_(res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%s", (int)splitSubmit_, VulkanResultToString(res)); } // When !triggerFence, we notify after syncing with Vulkan. @@ -1145,7 +1145,7 @@ void VulkanRenderManager::EndSubmitFrame(int frame) { } else if (res == VK_SUBOPTIMAL_KHR) { outOfDateFrames_++; } else if (res != VK_SUCCESS) { - _assert_msg_(G3D, false, "vkQueuePresentKHR failed! result=%s", VulkanResultToString(res)); + _assert_msg_(false, "vkQueuePresentKHR failed! result=%s", VulkanResultToString(res)); } else { // Success outOfDateFrames_ = 0; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index a47419bbf6..3bc5a344e7 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -133,17 +133,17 @@ public: void BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter, const char *tag); void BindPipeline(VkPipeline pipeline) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); - _dbg_assert_(G3D, pipeline != VK_NULL_HANDLE); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(pipeline != VK_NULL_HANDLE); VkRenderData data{ VKRRenderCommand::BIND_PIPELINE }; data.pipeline.pipeline = pipeline; curRenderStep_->commands.push_back(data); } void SetViewport(const VkViewport &vp) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); - _dbg_assert_(G3D, (int)vp.width >= 0); - _dbg_assert_(G3D, (int)vp.height >= 0); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_((int)vp.width >= 0); + _dbg_assert_((int)vp.height >= 0); VkRenderData data{ VKRRenderCommand::VIEWPORT }; data.viewport.vp.x = vp.x; data.viewport.vp.y = vp.y; @@ -159,9 +159,9 @@ 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); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_((int)rc.extent.width >= 0); + _dbg_assert_((int)rc.extent.height >= 0); VkRenderData data{ VKRRenderCommand::SCISSOR }; data.scissor.scissor = rc; curRenderStep_->commands.push_back(data); @@ -169,7 +169,7 @@ public: } void SetStencilParams(uint8_t writeMask, uint8_t compareMask, uint8_t refValue) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); VkRenderData data{ VKRRenderCommand::STENCIL }; data.stencil.stencilWriteMask = writeMask; data.stencil.stencilCompareMask = compareMask; @@ -178,14 +178,14 @@ public: } void SetBlendFactor(uint32_t color) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); VkRenderData data{ VKRRenderCommand::BLEND }; data.blendColor.color = color; curRenderStep_->commands.push_back(data); } void PushConstants(VkPipelineLayout pipelineLayout, VkShaderStageFlags stages, int offset, int size, void *constants) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); assert(size + offset < 40); VkRenderData data{ VKRRenderCommand::PUSH_CONSTANTS }; data.push.pipelineLayout = pipelineLayout; @@ -199,7 +199,7 @@ public: void Clear(uint32_t clearColor, float clearZ, int clearStencil, int clearMask); void Draw(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, int count, int offset = 0) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_); VkRenderData data{ VKRRenderCommand::DRAW }; data.draw.count = count; data.draw.offset = offset; @@ -216,7 +216,7 @@ public: } void DrawIndexed(VkPipelineLayout layout, VkDescriptorSet descSet, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType indexType) { - _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_); + _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_); VkRenderData data{ VKRRenderCommand::DRAW_INDEXED }; data.drawIndexed.count = count; data.drawIndexed.instances = numInstances; diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index 5ee4a9e44a..97b6fe9e0a 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -78,13 +78,13 @@ bool RefCountedObject::Release() { } } else { - _dbg_assert_msg_(G3D, false, "Refcount (%d) invalid for object %p - corrupt?", refcount_, this); + _dbg_assert_msg_(false, "Refcount (%d) invalid for object %p - corrupt?", refcount_, this); } return false; } bool RefCountedObject::ReleaseAssertLast() { - _dbg_assert_msg_(G3D, refcount_ == 1, "RefCountedObject: Expected to be the last reference, but isn't!"); + _dbg_assert_msg_(refcount_ == 1, "RefCountedObject: Expected to be the last reference, but isn't!"); if (refcount_ > 0 && refcount_ < 10000) { refcount_--; if (refcount_ == 0) { diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index e25535816f..47d54cd354 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -1107,15 +1107,15 @@ void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { } void OpenGLContext::Draw(int vertexCount, int offset) { - _dbg_assert_msg_(G3D, curVBuffers_[0], "Can't call Draw without a vertex buffer"); + _dbg_assert_msg_(curVBuffers_[0], "Can't call Draw without a vertex buffer"); ApplySamplers(); renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]); renderManager_.Draw(curPipeline_->prim, offset, vertexCount); } void OpenGLContext::DrawIndexed(int vertexCount, int offset) { - _dbg_assert_msg_(G3D, curVBuffers_[0], "Can't call DrawIndexed without a vertex buffer"); - _dbg_assert_msg_(G3D, curIBuffer_, "Can't call DrawIndexed without an index buffer"); + _dbg_assert_msg_(curVBuffers_[0], "Can't call DrawIndexed without a vertex buffer"); + _dbg_assert_msg_(curIBuffer_, "Can't call DrawIndexed without an index buffer"); ApplySamplers(); renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]); renderManager_.BindIndexBuffer(curIBuffer_->buffer_); diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 04bf3bb021..ea04100813 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1451,9 +1451,9 @@ uint32_t VKContext::GetDataFormatSupport(DataFormat fmt) const { // use this frame's init command buffer. class VKFramebuffer : public Framebuffer { public: - VKFramebuffer(VKRFramebuffer *fb) : buf_(fb) { _assert_msg_(G3D, fb, "Null fb in VKFramebuffer constructor"); } + VKFramebuffer(VKRFramebuffer *fb) : buf_(fb) { _assert_msg_(fb, "Null fb in VKFramebuffer constructor"); } ~VKFramebuffer() { - _assert_msg_(G3D, buf_, "Null buf_ in VKFramebuffer - double delete?"); + _assert_msg_(buf_, "Null buf_ in VKFramebuffer - double delete?"); buf_->vulkan_->Delete().QueueCallback([](void *fb) { VKRFramebuffer *vfb = static_cast(fb); delete vfb; diff --git a/ios/ViewController.mm b/ios/ViewController.mm index d36ae51b07..4f6f9a4db3 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -47,7 +47,7 @@ public: renderManager_->SetInflightFrames(g_Config.iInflightFrames); SetGPUBackend(GPUBackend::OPENGL); bool success = draw_->CreatePresets(); - _assert_msg_(G3D, success, "Failed to compile preset shaders"); + _assert_msg_(success, "Failed to compile preset shaders"); } ~IOSGraphicsContext() { delete draw_; From 617bbcfb87ac8256f6336c5faf4edab948808d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Jul 2020 17:52:41 +0200 Subject: [PATCH 292/848] Step 1 of removing PanicAlert --- Common/ArmEmitter.cpp | 6 ++---- Common/ChunkFile.cpp | 2 +- Common/CodeBlock.h | 7 ++----- Common/Common.h | 2 +- Common/ExceptionHandlerSetup.cpp | 20 ++++++-------------- Common/MemArenaAndroid.cpp | 5 +---- Common/MemArenaPosix.cpp | 8 ++------ Common/MemoryUtil.cpp | 3 +-- 8 files changed, 16 insertions(+), 37 deletions(-) diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index 596fff7aae..9c713c8aab 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -905,14 +905,12 @@ void ARMXEmitter::WriteSignedMultiply(u32 Op, u32 Op2, u32 Op3, ARMReg dest, ARM } void ARMXEmitter::UDIV(ARMReg dest, ARMReg dividend, ARMReg divisor) { - if (!cpu_info.bIDIVa) - PanicAlert("Trying to use integer divide on hardware that doesn't support it. Bad programmer."); + _assert_(cpu_info.bIDIVa, "Trying to use integer divide on hardware that doesn't support it. Bad programmer."); WriteSignedMultiply(3, 0xF, 0, dest, divisor, dividend); } void ARMXEmitter::SDIV(ARMReg dest, ARMReg dividend, ARMReg divisor) { - if (!cpu_info.bIDIVa) - PanicAlert("Trying to use integer divide on hardware that doesn't support it. Bad programmer."); + _assert_(cpu_info.bIDIVa, "Trying to use integer divide on hardware that doesn't support it. Bad programmer."); WriteSignedMultiply(1, 0xF, 0, dest, divisor, dividend); } diff --git a/Common/ChunkFile.cpp b/Common/ChunkFile.cpp index 760dbc1855..cbfec7ffe7 100644 --- a/Common/ChunkFile.cpp +++ b/Common/ChunkFile.cpp @@ -168,7 +168,7 @@ void PointerWrap::DoMarker(const char *prevName, u32 arbitraryNumber) { u32 cookie = arbitraryNumber; Do(cookie); if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) { - PanicAlert("Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); + _assert_msg_(false, "Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); SetError(ERROR_FAILURE); } } diff --git a/Common/CodeBlock.h b/Common/CodeBlock.h index 777fb164a4..c4023d4a8e 100644 --- a/Common/CodeBlock.h +++ b/Common/CodeBlock.h @@ -85,11 +85,8 @@ public: // If you don't specify a size and we later encounter an executable non-writable block, we're screwed. // These CANNOT be nested. We rely on the memory protection starting at READ|WRITE after start and reset. void BeginWrite(size_t sizeEstimate = 1) { -#ifdef _DEBUG - if (writeStart_) { - PanicAlert("Can't nest BeginWrite calls"); - } -#endif + _dbg_assert_msg_(!writeStart_, "Can't nest BeginWrite calls"); + // In case the last block made the current page exec/no-write, let's fix that. if (PlatformIsWXExclusive()) { writeStart_ = GetCodePtr(); diff --git a/Common/Common.h b/Common/Common.h index ec69b6022b..afd4176a10 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -64,7 +64,7 @@ #if defined(_DEBUG) #include #undef CHECK_HEAP_INTEGRITY - #define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) PanicAlert("memory corruption detected. see log.");} + #define CHECK_HEAP_INTEGRITY() {if (!_CrtCheckMemory()) _assert_msg_(false, "Memory corruption detected. See log.");} #endif #else diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 0f541333a7..9ff5255237 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -98,9 +98,7 @@ void UninstallExceptionHandler() { #elif defined(__APPLE__) static void CheckKR(const char* name, kern_return_t kr) { - if (kr) { - PanicAlert("%s failed: kr=%x", name, kr); - } + _assert_msg_(kr == 0, "%s failed: kr=%x", name, kr); } static void ExceptionThread(mach_port_t port) { @@ -147,15 +145,8 @@ static void ExceptionThread(mach_port_t port) { return; } - if (msg_in.Head.msgh_id != 2406) { - PanicAlert("unknown message received"); - return; - } - - if (msg_in.flavor != x86_THREAD_STATE64) { - PanicAlert("unknown flavor %d (expected %d)", msg_in.flavor, x86_THREAD_STATE64); - return; - } + _assert_msg_(msg_in.Head.msgh_id == 2406, "unknown message received"); + _assert_msg_(msg_in.flavor == x86_THREAD_STATE64, "unknown flavor %d (expected %d)", msg_in.flavor, x86_THREAD_STATE64); x86_thread_state64_t* state = (x86_thread_state64_t*)msg_in.old_state; @@ -299,8 +290,9 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { #endif signal_stack.ss_size = SIGSTKSZ; signal_stack.ss_flags = 0; - if (sigaltstack(&signal_stack, nullptr)) - PanicAlert("sigaltstack failed"); + if (sigaltstack(&signal_stack, nullptr)) { + _assert_msg_(false, "sigaltstack failed"); + } struct sigaction sa; sa.sa_handler = nullptr; sa.sa_sigaction = &sigsegv_handler; diff --git a/Common/MemArenaAndroid.cpp b/Common/MemArenaAndroid.cpp index a0b8614f19..67e1861e5a 100644 --- a/Common/MemArenaAndroid.cpp +++ b/Common/MemArenaAndroid.cpp @@ -156,10 +156,7 @@ u8* MemArena::Find4GBBase() { #else // Address masking is used in 32-bit mode, so we can get away with less memory. void* base = mmap(0, 0x10000000, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); - if (base == MAP_FAILED) { - PanicAlert("Failed to map 256 MB of memory space: %s", strerror(errno)); - return 0; - } + _assert_msg_(base != MAP_FAILED, "Failed to map 256 MB of memory space: %s", strerror(errno)); munmap(base, 0x10000000); return static_cast(base); #endif diff --git a/Common/MemArenaPosix.cpp b/Common/MemArenaPosix.cpp index 5ee371ed17..15647b147a 100644 --- a/Common/MemArenaPosix.cpp +++ b/Common/MemArenaPosix.cpp @@ -124,12 +124,8 @@ u8* MemArena::Find4GBBase() { } #else size_t size = 0x10000000; - void* base = mmap(0, size, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_SHARED, -1, 0); - if (base == MAP_FAILED) { - PanicAlert("Failed to map 256 MB of memory space: %s", strerror(errno)); - return 0; - } + void* base = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); + _assert_msg_(base != MAP_FAILED, "Failed to map 256 MB of memory space: %s", strerror(errno)); munmap(base, size); return static_cast(base); #endif diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index 519bfc6bd5..8e3ba5c56d 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -292,8 +292,7 @@ bool ProtectMemoryPages(const void* ptr, size_t size, uint32_t memProtFlags) { if (PlatformIsWXExclusive()) { if ((memProtFlags & (MEM_PROT_WRITE | MEM_PROT_EXEC)) == (MEM_PROT_WRITE | MEM_PROT_EXEC)) { - ERROR_LOG(MEMMAP, "Bad memory protection %d!", memProtFlags); - PanicAlert("Bad memory protect : W^X is in effect, can't both write and exec"); + _assert_msg_(false, "Bad memory protect flags %d: W^X is in effect, can't both write and exec", memProtFlags); } } // Note - VirtualProtect will affect the full pages containing the requested range. From 47a3bf1dd7b9381bba6be84a47ab77f798dc390e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Jul 2020 19:49:20 +0200 Subject: [PATCH 293/848] Step 2 of removing PanicAlert --- Common/Thunk.cpp | 4 ++-- Common/x64Emitter.cpp | 15 +++++---------- Core/MIPS/x86/RegCache.cpp | 7 +++---- Core/MIPS/x86/RegCache.h | 2 +- Core/Util/PPGeDraw.cpp | 3 +-- Core/WaveFile.cpp | 25 ++++++++----------------- Windows/GPU/D3D9Context.cpp | 2 +- 7 files changed, 21 insertions(+), 37 deletions(-) diff --git a/Common/Thunk.cpp b/Common/Thunk.cpp index fe4850b594..06e517cc6c 100644 --- a/Common/Thunk.cpp +++ b/Common/Thunk.cpp @@ -147,8 +147,8 @@ const void *ThunkManager::ProtectFunction(const void *function, int num_params) iter = thunks.find(function); if (iter != thunks.end()) return (const void *)iter->second; - if (!region) - PanicAlert("Trying to protect functions before the emu is started. Bad bad bad."); + + _assert_msg_(region != nullptr, "Can't protect functions before the emu is started."); BeginWrite(); const u8 *call_point = GetCodePtr(); diff --git a/Common/x64Emitter.cpp b/Common/x64Emitter.cpp index 1639b4a1c8..d00d07f8ac 100644 --- a/Common/x64Emitter.cpp +++ b/Common/x64Emitter.cpp @@ -1414,8 +1414,7 @@ static int GetVEXpp(u8 opPrefix) void XEmitter::WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes) { - if (!cpu_info.bAVX) - PanicAlert("Trying to use AVX on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bAVX, "Trying to use AVX on a system that doesn't support it. Bad programmer."); int mmmmm = GetVEXmmmmm(op); int pp = GetVEXpp(opPrefix); // FIXME: we currently don't support 256-bit instructions, and "size" is not the vector size here @@ -1439,16 +1438,14 @@ void XEmitter::WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg r void XEmitter::WriteBMI1Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes) { CheckFlags(); - if (!cpu_info.bBMI1) - PanicAlert("Trying to use BMI1 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bBMI1, "Trying to use BMI1 on a system that doesn't support it. Bad programmer."); WriteVEXOp(size, opPrefix, op, regOp1, regOp2, arg, extrabytes); } void XEmitter::WriteBMI2Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes) { CheckFlags(); - if (!cpu_info.bBMI2) - PanicAlert("Trying to use BMI2 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bBMI2, "Trying to use BMI2 on a system that doesn't support it. Bad programmer."); WriteVEXOp(size, opPrefix, op, regOp1, regOp2, arg, extrabytes); } @@ -1742,15 +1739,13 @@ void XEmitter::PMULUDQ(X64Reg dest, const OpArg &arg) {WriteSSEOp(0x66, 0xF4, de void XEmitter::WriteSSSE3Op(u8 opPrefix, u16 op, X64Reg regOp, OpArg arg, int extrabytes) { - if (!cpu_info.bSSSE3) - PanicAlert("Trying to use SSSE3 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bSSSE3, "Trying to use SSSE3 on a system that doesn't support it. Bad programmer."); WriteSSEOp(opPrefix, op, regOp, arg, extrabytes); } void XEmitter::WriteSSE41Op(u8 opPrefix, u16 op, X64Reg regOp, OpArg arg, int extrabytes) { - if (!cpu_info.bSSE4_1) - PanicAlert("Trying to use SSE4.1 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bSSE4_1, "Trying to use SSE4.1 on a system that doesn't support it. Bad programmer."); WriteSSEOp(opPrefix, op, regOp, arg, extrabytes); } diff --git a/Core/MIPS/x86/RegCache.cpp b/Core/MIPS/x86/RegCache.cpp index 43c22b100f..b9849b355d 100644 --- a/Core/MIPS/x86/RegCache.cpp +++ b/Core/MIPS/x86/RegCache.cpp @@ -356,8 +356,8 @@ void GPRRegCache::MapReg(MIPSGPReg i, bool doLoad, bool makeDirty) { if (!regs[i].away || (regs[i].away && regs[i].location.IsImm())) { X64Reg xr = GetFreeXReg(); - if (xregs[xr].dirty) PanicAlert("Xreg already dirty"); - if (xregs[xr].allocLocked) PanicAlert("GetFreeXReg returned locked register"); + _assert_msg_(!xregs[xr].dirty, "Xreg already dirty"); + _assert_msg_(!xregs[xr].allocLocked, "GetFreeXReg returned locked register"); xregs[xr].free = false; xregs[xr].mipsReg = i; xregs[xr].dirty = makeDirty || regs[i].location.IsImm(); @@ -371,8 +371,7 @@ void GPRRegCache::MapReg(MIPSGPReg i, bool doLoad, bool makeDirty) { } for (int j = 0; j < 32; j++) { if (i != MIPSGPReg(j) && regs[j].location.IsSimpleReg(xr)) { - ERROR_LOG(JIT, "BindToRegister: Strange condition"); - Crash(); + _assert_msg_(false, "BindToRegister: Strange condition"); } } regs[i].away = true; diff --git a/Core/MIPS/x86/RegCache.h b/Core/MIPS/x86/RegCache.h index fe7cc43a21..cdda09eb3f 100644 --- a/Core/MIPS/x86/RegCache.h +++ b/Core/MIPS/x86/RegCache.h @@ -101,7 +101,7 @@ public: { if (regs[preg].away && regs[preg].location.IsSimpleReg()) return regs[preg].location.GetSimpleReg(); - PanicAlert("Not so simple - %i", preg); + _assert_msg_(false, "Not so simple - %d", preg); return (Gen::X64Reg)-1; } Gen::OpArg GetDefaultLocation(MIPSGPReg reg) const; diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 964dd45f0b..b679581a0e 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -222,8 +222,7 @@ void __PPGeInit() { bool loadedZIM = !skipZIM && LoadZIM("ppge_atlas.zim", width, height, &flags, imageData); if (!skipZIM && !loadedZIM) { - PanicAlert("Failed to load ppge_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory."); - ERROR_LOG(SCEGE, "PPGe init failed - no atlas texture. PPGe stuff will not be drawn."); + ERROR_LOG(SCEGE, "Failed to load ppge_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory.\n\nPPGe stuff will not be drawn."); } if (loadedZIM) { diff --git a/Core/WaveFile.cpp b/Core/WaveFile.cpp index 76df969f61..f789a7807e 100644 --- a/Core/WaveFile.cpp +++ b/Core/WaveFile.cpp @@ -23,19 +23,14 @@ WaveFileWriter::~WaveFileWriter() bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRate) { // Check if the file is already open - if (file) - { - PanicAlert("The file %s was already open, the file header will not be written.", - filename.c_str()); + if (file) { + ERROR_LOG(SYSTEM, "The file %s was already open, the file header will not be written.", filename.c_str()); return false; } file.Open(filename, "wb"); - if (!file) - { - PanicAlert("The file %s could not be opened for writing. Please check if it's already opened " - "by another program.", - filename.c_str()); + if (!file) { + ERROR_LOG(SYSTEM, "The file %s could not be opened for writing. Please check if it's already opened by another program.", filename.c_str()); return false; } @@ -61,9 +56,8 @@ bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRa Write(100 * 1000 * 1000 - 32); // We are now at offset 44 - if (file.Tell() != 44) - PanicAlert("Wrong offset: %lld", (long long)file.Tell()); - + u64 offset = file.Tell(); + _assert_msg_(offset == 44, "Wrong offset: %lld", (long long)offset); return true; } @@ -91,11 +85,8 @@ void WaveFileWriter::Write4(const char* ptr) void WaveFileWriter::AddStereoSamples(const short* sample_data, u32 count) { - if (!file) - PanicAlert("WaveFileWriter - file not open."); - - if (count > BUFFER_SIZE * 2) - PanicAlert("WaveFileWriter - buffer too small (count = %u).", count); + _assert_msg_(file, "WaveFileWriter - file not open."); + _assert_msg_(count <= BUFFER_SIZE * 2, "WaveFileWriter - buffer too small (count = %u).", count); if (skip_silence) { diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index 2ea38836e0..e87ed1ea60 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -218,7 +218,7 @@ void D3D9Context::Resize() { HRESULT hr = device_->Reset(&presentParams_); if (FAILED(hr)) { // Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015. - PanicAlert("Unable to reset D3D9 device"); + _assert_msg_(false, "Unable to reset D3D9 device"); } draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr); } From 082954398732fb3c1e62143964229e1a37e8b512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Jul 2020 20:32:15 +0200 Subject: [PATCH 294/848] Third part of getting rid of PanicAlert --- Common/ArmEmitter.cpp | 4 +-- Common/MemoryUtil.cpp | 43 +++++++++++++-------------- Common/MsgHandler.h | 2 -- Common/x64Emitter.cpp | 19 +++++------- Core/CoreTiming.cpp | 18 +++++------ Core/MIPS/JitCommon/JitBlockCache.cpp | 2 +- Core/MIPS/x86/RegCache.cpp | 38 +++++++++++------------ Core/MIPS/x86/RegCacheFPU.cpp | 17 ++++------- Core/MIPS/x86/RegCacheFPU.h | 6 ++-- Core/MemMap.cpp | 9 ++++-- Core/MemMap.h | 2 +- Core/System.cpp | 15 +++++++--- ext/native/ui/ui_context.cpp | 4 +-- 13 files changed, 85 insertions(+), 94 deletions(-) diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index 9c713c8aab..d289bdfb99 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -905,12 +905,12 @@ void ARMXEmitter::WriteSignedMultiply(u32 Op, u32 Op2, u32 Op3, ARMReg dest, ARM } void ARMXEmitter::UDIV(ARMReg dest, ARMReg dividend, ARMReg divisor) { - _assert_(cpu_info.bIDIVa, "Trying to use integer divide on hardware that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bIDIVa, "Trying to use integer divide on hardware that doesn't support it."); WriteSignedMultiply(3, 0xF, 0, dest, divisor, dividend); } void ARMXEmitter::SDIV(ARMReg dest, ARMReg dividend, ARMReg divisor) { - _assert_(cpu_info.bIDIVa, "Trying to use integer divide on hardware that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bIDIVa, "Trying to use integer divide on hardware that doesn't support it."); WriteSignedMultiply(1, 0xF, 0, dest, divisor, dividend); } diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index 8e3ba5c56d..9a078ea728 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -19,12 +19,13 @@ #include "base/logging.h" -#include "Common.h" -#include "MemoryUtil.h" -#include "StringUtils.h" +#include "Common/Common.h" +#include "Common/Log.h" +#include "Common/MemoryUtil.h" +#include "Common/StringUtils.h" #ifdef _WIN32 -#include "CommonWindows.h" +#include "Common/CommonWindows.h" #else #include #include @@ -53,7 +54,7 @@ static SYSTEM_INFO sys_info; #define ppsspp_round_page(x) ((((uintptr_t)(x)) + MEM_PAGE_MASK) & ~(MEM_PAGE_MASK)) #ifdef _WIN32 -// Win32 flags are odd... +// Win32 memory protection flags are odd... static uint32_t ConvertProtFlagsWin32(uint32_t flags) { uint32_t protect = 0; switch (flags) { @@ -185,7 +186,6 @@ void *AllocateExecutableMemory(size_t size) { if (ptr == failed_result) { ptr = nullptr; ERROR_LOG(MEMMAP, "Failed to allocate executable memory (%d) errno=%d", (int)size, errno); - PanicAlert("Failed to allocate executable memory\n%s", GetLastErrorMsg()); } #if defined(_M_X64) && !defined(_WIN32) @@ -214,13 +214,15 @@ void *AllocateMemoryPages(size_t size, uint32_t memProtFlags) { #else void* ptr = VirtualAlloc(0, size, MEM_COMMIT, protect); #endif - if (!ptr) - PanicAlert("Failed to allocate raw memory"); + if (!ptr) { + ERROR_LOG(MEMMAP, "Failed to allocate raw memory pages"); + return nullptr; + } #else uint32_t protect = ConvertProtFlagsUnix(memProtFlags); void *ptr = mmap(0, size, protect, MAP_ANON | MAP_PRIVATE, -1, 0); if (ptr == MAP_FAILED) { - ERROR_LOG(MEMMAP, "Failed to allocate memory pages: errno=%d", errno); + ERROR_LOG(MEMMAP, "Failed to allocate raw memory pages: errno=%d", errno); return nullptr; } #endif @@ -232,23 +234,19 @@ void *AllocateMemoryPages(size_t size, uint32_t memProtFlags) { void *AllocateAlignedMemory(size_t size, size_t alignment) { #ifdef _WIN32 - void* ptr = _aligned_malloc(size,alignment); + void* ptr = _aligned_malloc(size,alignment); #else void* ptr = NULL; #ifdef __ANDROID__ ptr = memalign(alignment, size); #else - if (posix_memalign(&ptr, alignment, size) != 0) - ptr = NULL; + if (posix_memalign(&ptr, alignment, size) != 0) { + ptr = nullptr; + } #endif #endif - // printf("Mapped memory at %p (size %ld)\n", ptr, - // (unsigned long)size); - - if (ptr == NULL) - PanicAlert("Failed to allocate aligned memory"); - + _assert_msg_(ptr != nullptr, "Failed to allocate aligned memory"); return ptr; } @@ -258,8 +256,9 @@ void FreeMemoryPages(void *ptr, size_t size) { uintptr_t page_size = GetMemoryProtectPageSize(); size = (size + page_size - 1) & (~(page_size - 1)); #ifdef _WIN32 - if (!VirtualFree(ptr, 0, MEM_RELEASE)) - PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg()); + if (!VirtualFree(ptr, 0, MEM_RELEASE)) { + ERROR_LOG(MEMMAP, "FreeMemoryPages failed!\n%s", GetLastErrorMsg()); + } #else munmap(ptr, size); #endif @@ -303,13 +302,13 @@ bool ProtectMemoryPages(const void* ptr, size_t size, uint32_t memProtFlags) { #if PPSSPP_PLATFORM(UWP) DWORD oldValue; if (!VirtualProtectFromApp((void *)ptr, size, protect, &oldValue)) { - PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); + ERROR_LOG(MEMMAP, "WriteProtectMemory failed!\n%s", GetLastErrorMsg()); return false; } #else DWORD oldValue; if (!VirtualProtect((void *)ptr, size, protect, &oldValue)) { - PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg()); + ERROR_LOG(MEMMAP, "WriteProtectMemory failed!\n%s", GetLastErrorMsg()); return false; } #endif diff --git a/Common/MsgHandler.h b/Common/MsgHandler.h index 4f453172c9..a940366255 100644 --- a/Common/MsgHandler.h +++ b/Common/MsgHandler.h @@ -31,7 +31,5 @@ bool MsgAlert(bool yes_no, int Style, const char *file, int line, const char* fo #endif ; -#define PanicAlert(...) MsgAlert(false, WARNING, __FILE__, __LINE__, __VA_ARGS__) - // Used only for asserts. #define PanicYesNo(...) MsgAlert(true, CRITICAL, __FILE__, __LINE__, __VA_ARGS__) diff --git a/Common/x64Emitter.cpp b/Common/x64Emitter.cpp index d00d07f8ac..eac312914b 100644 --- a/Common/x64Emitter.cpp +++ b/Common/x64Emitter.cpp @@ -820,15 +820,13 @@ void XEmitter::BSR(int bits, X64Reg dest, OpArg src) {WriteBitSearchType(bits,de void XEmitter::TZCNT(int bits, X64Reg dest, OpArg src) { CheckFlags(); - if (!cpu_info.bBMI1) - PanicAlert("Trying to use BMI1 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bBMI1, "Trying to use BMI1 on a system that doesn't support it."); WriteBitSearchType(bits, dest, src, 0xBC, true); } void XEmitter::LZCNT(int bits, X64Reg dest, OpArg src) { CheckFlags(); - if (!cpu_info.bLZCNT) - PanicAlert("Trying to use LZCNT on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bLZCNT, "Trying to use LZCNT on a system that doesn't support it."); WriteBitSearchType(bits, dest, src, 0xBD, true); } @@ -1414,7 +1412,7 @@ static int GetVEXpp(u8 opPrefix) void XEmitter::WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes) { - _assert_msg_(cpu_info.bAVX, "Trying to use AVX on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bAVX, "Trying to use AVX on a system that doesn't support it."); int mmmmm = GetVEXmmmmm(op); int pp = GetVEXpp(opPrefix); // FIXME: we currently don't support 256-bit instructions, and "size" is not the vector size here @@ -1426,8 +1424,7 @@ void XEmitter::WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpA // Like the above, but more general; covers GPR-based VEX operations, like BMI1/2 void XEmitter::WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes) { - if (size != 32 && size != 64) - PanicAlert("VEX GPR instructions only support 32-bit and 64-bit modes!"); + _assert_msg_(size == 32 || size == 64, "VEX GPR instructions only support 32-bit and 64-bit modes!"); int mmmmm = GetVEXmmmmm(op); int pp = GetVEXpp(opPrefix); arg.WriteVex(this, regOp1, regOp2, 0, pp, mmmmm, size == 64); @@ -1438,14 +1435,14 @@ void XEmitter::WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg r void XEmitter::WriteBMI1Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes) { CheckFlags(); - _assert_msg_(cpu_info.bBMI1, "Trying to use BMI1 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bBMI1, "Trying to use BMI1 on a system that doesn't support it."); WriteVEXOp(size, opPrefix, op, regOp1, regOp2, arg, extrabytes); } void XEmitter::WriteBMI2Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes) { CheckFlags(); - _assert_msg_(cpu_info.bBMI2, "Trying to use BMI2 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bBMI2, "Trying to use BMI2 on a system that doesn't support it."); WriteVEXOp(size, opPrefix, op, regOp1, regOp2, arg, extrabytes); } @@ -1739,13 +1736,13 @@ void XEmitter::PMULUDQ(X64Reg dest, const OpArg &arg) {WriteSSEOp(0x66, 0xF4, de void XEmitter::WriteSSSE3Op(u8 opPrefix, u16 op, X64Reg regOp, OpArg arg, int extrabytes) { - _assert_msg_(cpu_info.bSSSE3, "Trying to use SSSE3 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bSSSE3, "Trying to use SSSE3 on a system that doesn't support it."); WriteSSEOp(opPrefix, op, regOp, arg, extrabytes); } void XEmitter::WriteSSE41Op(u8 opPrefix, u16 op, X64Reg regOp, OpArg arg, int extrabytes) { - _assert_msg_(cpu_info.bSSE4_1, "Trying to use SSE4.1 on a system that doesn't support it. Bad programmer."); + _assert_msg_(cpu_info.bSSE4_1, "Trying to use SSE4.1 on a system that doesn't support it."); WriteSSEOp(opPrefix, op, regOp, arg, extrabytes); } diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 686ade0e71..a269455161 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -192,8 +192,7 @@ void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callba void UnregisterAllEvents() { - if (first) - PanicAlert("Cannot unregister events with events pending"); + _dbg_assert_msg_(first == nullptr, "Unregistering events with events pending - this isn't good."); event_types.clear(); } @@ -647,17 +646,18 @@ void Idle(int maxIdle) currentMIPS->downcount = -1; } -std::string GetScheduledEventsSummary() -{ +std::string GetScheduledEventsSummary() { Event *ptr = first; std::string text = "Scheduled events\n"; text.reserve(1000); - while (ptr) - { + while (ptr) { unsigned int t = ptr->type; - if (t >= event_types.size()) - PanicAlert("Invalid event type"); // %i", t); - const char *name = event_types[ptr->type].name; + if (t >= event_types.size()) { + _dbg_assert_msg_(false, "Invalid event type %d", t); + ptr = ptr->next; + continue; + } + const char *name = event_types[t].name; if (!name) name = "[unknown]"; char temp[512]; diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index fa9ca1edd8..7761646993 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -420,7 +420,7 @@ void JitBlockCache::LinkBlock(int i) { if (ppp.first == ppp.second) return; for (auto iter = ppp.first; iter != ppp.second; ++iter) { - // PanicAlert("Linking block %i to block %i", iter->second, i); + // INFO_LOG(JIT, "Linking block %i to block %i", iter->second, i); LinkBlockExits(iter->second); } } diff --git a/Core/MIPS/x86/RegCache.cpp b/Core/MIPS/x86/RegCache.cpp index b9849b355d..fa8479323d 100644 --- a/Core/MIPS/x86/RegCache.cpp +++ b/Core/MIPS/x86/RegCache.cpp @@ -115,9 +115,7 @@ void GPRRegCache::Lock(MIPSGPReg p1, MIPSGPReg p2, MIPSGPReg p3, MIPSGPReg p4) { // these are x64 reg indices void GPRRegCache::LockX(int x1, int x2, int x3, int x4) { - if (xregs[x1].allocLocked) { - PanicAlert("RegCache: x %i already locked!", x1); - } + _assert_msg_(!xregs[x1].allocLocked, "RegCache: x %d already locked!", x1); xregs[x1].allocLocked = true; if (x2 != 0xFF) xregs[x2].allocLocked = true; if (x3 != 0xFF) xregs[x3].allocLocked = true; @@ -197,24 +195,23 @@ X64Reg GPRRegCache::GetFreeXReg() return bestToSpill; } - //Still no dice? Die! + // Still no dice? Give up. _assert_msg_(false, "Regcache ran out of regs"); - return (X64Reg) -1; + return (X64Reg)-1; } void GPRRegCache::FlushR(X64Reg reg) { - if (reg >= NUM_X_REGS) - PanicAlert("Flushing non existent reg"); - else if (!xregs[reg].free) + if (reg >= NUM_X_REGS) { + _assert_msg_(false, "Flushing non existent reg"); + } else if (!xregs[reg].free) { StoreFromRegister(xregs[reg].mipsReg); + } } void GPRRegCache::FlushRemap(MIPSGPReg oldreg, MIPSGPReg newreg) { OpArg oldLocation = regs[oldreg].location; - if (!oldLocation.IsSimpleReg()) { - PanicAlert("FlushRemap: Must already be in an x86 register"); - } + _assert_msg_(oldLocation.IsSimpleReg(), "FlushRemap: Must already be in an x86 register"); X64Reg xr = oldLocation.GetSimpleReg(); @@ -335,7 +332,7 @@ OpArg GPRRegCache::GetDefaultLocation(MIPSGPReg reg) const { case MIPS_REG_VFPUCC: return MIPSSTATE_VAR(vfpuCtrl[VFPU_CTRL_CC]); default: - ERROR_LOG_REPORT(JIT, "bad mips register %i", reg); + ERROR_LOG_REPORT(JIT, "Bad mips register %d", reg); return MIPSSTATE_VAR(r[0]); } } @@ -351,9 +348,9 @@ void GPRRegCache::KillImmediate(MIPSGPReg preg, bool doLoad, bool makeDirty) { } void GPRRegCache::MapReg(MIPSGPReg i, bool doLoad, bool makeDirty) { - if (!regs[i].away && regs[i].location.IsImm()) - PanicAlert("Bad immediate"); - + if (!regs[i].away && regs[i].location.IsImm()) { + _assert_msg_(false, "Bad immediate"); + } if (!regs[i].away || (regs[i].away && regs[i].location.IsImm())) { X64Reg xr = GetFreeXReg(); _assert_msg_(!xregs[xr].dirty, "Xreg already dirty"); @@ -381,9 +378,8 @@ void GPRRegCache::MapReg(MIPSGPReg i, bool doLoad, bool makeDirty) { // and immediates are taken care of above. xregs[RX(i)].dirty |= makeDirty; } - if (xregs[RX(i)].allocLocked) { - PanicAlert("Seriously WTF, this reg should have been flushed"); - } + + _assert_msg_(!xregs[RX(i)].allocLocked, "This reg should have been flushed (r%d)", i); } void GPRRegCache::StoreFromRegister(MIPSGPReg i) { @@ -410,12 +406,12 @@ void GPRRegCache::StoreFromRegister(MIPSGPReg i) { void GPRRegCache::Flush() { for (int i = 0; i < NUM_X_REGS; i++) { - _assert_msg_(!xregs[i].allocLocked, "Someone forgot to unlock X64 reg %i.", i); + _assert_msg_(!xregs[i].allocLocked, "Someone forgot to unlock X64 reg %d.", i); } SetImm(MIPS_REG_ZERO, 0); for (int i = 1; i < NUM_MIPS_GPRS; i++) { const MIPSGPReg r = MIPSGPReg(i); - _assert_msg_(!regs[i].locked, "Somebody forgot to unlock MIPS reg %i.", i); + _assert_msg_(!regs[i].locked, "Somebody forgot to unlock MIPS reg %d.", i); if (regs[i].away) { if (regs[i].location.IsSimpleReg()) { X64Reg xr = RX(r); @@ -425,7 +421,7 @@ void GPRRegCache::Flush() { else if (regs[i].location.IsImm()) { StoreFromRegister(r); } else { - _assert_msg_(false, "Jit64 - Flush unhandled case, reg %i PC: %08x", i, mips->pc); + _assert_msg_(false, "Jit64 - Flush unhandled case, reg %d PC: %08x", i, mips->pc); } } } diff --git a/Core/MIPS/x86/RegCacheFPU.cpp b/Core/MIPS/x86/RegCacheFPU.cpp index 74adfe7d3f..26e1e0dd55 100644 --- a/Core/MIPS/x86/RegCacheFPU.cpp +++ b/Core/MIPS/x86/RegCacheFPU.cpp @@ -111,15 +111,10 @@ void FPURegCache::ReduceSpillLockV(const u8 *vec, VectorSize sz) { void FPURegCache::FlushRemap(int oldreg, int newreg) { OpArg oldLocation = regs[oldreg].location; - if (!oldLocation.IsSimpleReg()) { - PanicAlert("FlushRemap: Must already be in an x86 SSE register"); - } - if (regs[oldreg].lane != 0) { - PanicAlert("FlushRemap only supports FPR registers"); - } + _assert_msg_(oldLocation.IsSimpleReg(), "FlushRemap: Must already be in an x86 SSE register"); + _assert_msg_(regs[oldreg].lane == 0, "FlushRemap only supports FPR registers"); X64Reg xr = oldLocation.GetSimpleReg(); - if (oldreg == newreg) { xregs[xr].dirty = true; return; @@ -642,7 +637,7 @@ static int MMShuffleSwapTo0(int lane) { } else if (lane == 3) { return _MM_SHUFFLE(0, 2, 1, 3); } else { - PanicAlert("MMShuffleSwapTo0: Invalid lane %d", lane); + _assert_msg_(false, "MMShuffleSwapTo0: Invalid lane %d", lane); return 0; } } @@ -868,9 +863,7 @@ void FPURegCache::Flush() { return; } for (int i = 0; i < NUM_MIPS_FPRS; i++) { - if (regs[i].locked) { - PanicAlert("Somebody forgot to unlock MIPS reg %i.", i); - } + _assert_msg_(!regs[i].locked, "Somebody forgot to unlock MIPS reg %d.", i); if (regs[i].away) { if (regs[i].location.IsSimpleReg()) { X64Reg xr = RX(i); @@ -1093,7 +1086,7 @@ int FPURegCache::GetFreeXRegs(X64Reg *res, int n, bool spill) { void FPURegCache::FlushX(X64Reg reg) { if (reg >= NUM_X_FPREGS) { - PanicAlert("Flushing non existent reg"); + _assert_msg_(false, "Flushing non existent reg"); } else if (xregs[reg].mipsReg != -1) { StoreFromRegister(xregs[reg].mipsReg); } diff --git a/Core/MIPS/x86/RegCacheFPU.h b/Core/MIPS/x86/RegCacheFPU.h index 8054321834..3cf33d53b4 100644 --- a/Core/MIPS/x86/RegCacheFPU.h +++ b/Core/MIPS/x86/RegCacheFPU.h @@ -137,7 +137,7 @@ public: Gen::X64Reg RX(int freg) const { if (regs[freg].away && regs[freg].location.IsSimpleReg()) return regs[freg].location.GetSimpleReg(); - PanicAlert("Not so simple - f%i", freg); + _assert_msg_(false, "Not so simple - f%i", freg); return (Gen::X64Reg)-1; } @@ -145,7 +145,7 @@ public: _dbg_assert_msg_(vregs[vreg].lane == 0, "SIMD reg %d used as V reg (use VSX instead). pc=%08x", vreg, mips->pc); if (vregs[vreg].away && vregs[vreg].location.IsSimpleReg()) return vregs[vreg].location.GetSimpleReg(); - PanicAlert("Not so simple - v%i", vreg); + _assert_msg_(false, "Not so simple - v%i", vreg); return (Gen::X64Reg)-1; } @@ -153,7 +153,7 @@ public: _dbg_assert_msg_(vregs[vs[0]].lane != 0, "V reg %d used as VS reg (use VX instead). pc=%08x", vs[0], mips->pc); if (vregs[vs[0]].away && vregs[vs[0]].location.IsSimpleReg()) return vregs[vs[0]].location.GetSimpleReg(); - PanicAlert("Not so simple - v%i", vs[0]); + _assert_msg_(false, "Not so simple - v%i", vs[0]); return (Gen::X64Reg)-1; } diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 066ad85602..334bb66491 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -250,7 +250,6 @@ bool MemoryMap_Setup(u32 flags) { } } ERROR_LOG(MEMMAP, "MemoryMap_Setup: Failed finding a memory base."); - PanicAlert("MemoryMap_Setup: Failed finding a memory base."); return false; } else @@ -281,7 +280,7 @@ void MemoryMap_Shutdown(u32 flags) { #endif } -void Init() { +bool Init() { // On some 32 bit platforms, you can only map < 32 megs at a time. // TODO: Wait, wtf? What platforms are those? This seems bad. const static int MAX_MMAP_SIZE = 31 * 1024 * 1024; @@ -294,13 +293,17 @@ void Init() { if (views[i].flags & MV_IS_EXTRA2_RAM) views[i].size = std::min(std::max((int)g_MemorySize - MAX_MMAP_SIZE * 2, 0), MAX_MMAP_SIZE); } + int flags = 0; - MemoryMap_Setup(flags); + if (!MemoryMap_Setup(flags)) { + return false; + } INFO_LOG(MEMMAP, "Memory system initialized. Base at %p (RAM at @ %p, uncached @ %p)", base, m_pPhysicalRAM, m_pUncachedRAM); MemFault_Init(); + return true; } void Reinit() { diff --git a/Core/MemMap.h b/Core/MemMap.h index 515d866f6f..8178a7251a 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -126,7 +126,7 @@ bool MemoryMap_Setup(u32 flags); void MemoryMap_Shutdown(u32 flags); // Init and Shutdown -void Init(); +bool Init(); void Shutdown(); void DoState(PointerWrap &p); void Clear(); diff --git a/Core/System.cpp b/Core/System.cpp index 1f738882c7..2d0ced0c6b 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -184,7 +184,7 @@ bool CPU_HasPendingAction() { void CPU_Shutdown(); -void CPU_Init() { +bool CPU_Init() { coreState = CORE_POWERUP; currentMIPS = &mipsr4k; @@ -243,7 +243,10 @@ void CPU_Init() { std::string discID = g_paramSFO.GetDiscID(); coreParameter.compat.Load(discID); - Memory::Init(); + if (!Memory::Init()) { + // We're screwed. + return false; + } mipsr4k.Reset(); host->AttemptLoadSymbolMap(); @@ -264,7 +267,7 @@ void CPU_Init() { if (!LoadFile(&loadedFile, &coreParameter.errorString)) { CPU_Shutdown(); coreParameter.fileToStart = ""; - return; + return false; } if (coreParameter.updateRecent) { @@ -272,6 +275,7 @@ void CPU_Init() { } InstallExceptionHandler(&Memory::HandleFault); + return true; } PSP_LoadingLock::PSP_LoadingLock() { @@ -361,7 +365,10 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { pspIsIniting = true; PSP_SetLoading("Loading game..."); - CPU_Init(); + if (!CPU_Init()) { + *error_string = "Failed initializing CPU/Memory"; + return false; + } // Compat flags get loaded in CPU_Init (which is a bit of a misnomer) so we check for SW renderer here. if (g_Config.bSoftwareRendering || PSP_CoreParameter().compat.flags().ForceSoftwareRenderer) { diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index 2a0d0bcce4..22cc79c24b 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -38,9 +38,7 @@ void UIContext::Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pi void UIContext::BeginFrame() { if (!uitexture_) { uitexture_ = CreateTextureFromFile(draw_, "ui_atlas.zim", ImageFileType::ZIM, false); - if (!uitexture_) { - PanicAlert("Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory."); - } + _dbg_assert_msg_(uitexture_, "Failed to load ui_atlas.zim.\n\nPlace it in the directory \"assets\" under your PPSSPP directory."); } uidrawbufferTop_->SetCurZ(0.0f); uidrawbuffer_->SetCurZ(0.0f); From dc2370ab6b123f93bd9d68ad73d9ed1dbafad1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 19 Jul 2020 21:46:46 +0200 Subject: [PATCH 295/848] Buildfix --- Common/Log.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Common/Log.h b/Common/Log.h index 418ec15c61..1b1ab1ed07 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -155,8 +155,8 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * #define _dbg_update_() ; #ifndef _dbg_assert_ -#define _dbg_assert_(_t_, _a_) {} -#define _dbg_assert_msg_(_t_, _a_, _desc_, ...) {} +#define _dbg_assert_(_a_) {} +#define _dbg_assert_msg_(_a_, _desc_, ...) {} #endif // dbg_assert #endif // MAX_LOGLEVEL DEBUG From fa59be7e5db1526d07de75f6d7c14b94e98809e6 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 8 Mar 2015 06:16:44 +0800 Subject: [PATCH 296/848] sceMpegAvcCsc: added range validity tests. http://code.google.com/p/jpcsp/source/detail?r=3715 --- Core/HLE/sceMpeg.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index dfaa2ca825..70bfb5f509 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1951,8 +1951,16 @@ static u32 sceMpegAvcCsc(u32 mpeg, u32 sourceAddr, u32 rangeAddr, int frameWidth int y = Memory::Read_U32(rangeAddr + 4); int width = Memory::Read_U32(rangeAddr + 8); int height = Memory::Read_U32(rangeAddr + 12); - int destSize = ctx->mediaengine->writeVideoImageWithRange(destAddr, frameWidth, ctx->videoPixelMode, x, y, width, height); + if (((x | y | width | height) & 0xF) != 0) { + WARN_LOG(ME, "sceMpegAvcCsc(%08x, %08x, %08x, %i, %08x) returning ERROR_MPEG_INVALID_VALUE", mpeg, sourceAddr, rangeAddr, frameWidth, destAddr); + return ERROR_MPEG_INVALID_VALUE; + } + if (x < 0 || y < 0 || width < 0 || height < 0) { + WARN_LOG(ME, "sceMpegAvcCsc(%08x, %08x, %08x, %i, %08x) returning ERROR_INVALID_VALUE", mpeg, sourceAddr, rangeAddr, frameWidth, destAddr); + return SCE_KERNEL_ERROR_INVALID_VALUE; + } + int destSize = ctx->mediaengine->writeVideoImageWithRange(destAddr, frameWidth, ctx->videoPixelMode, x, y, width, height); gpu->NotifyVideoUpload(destAddr, destSize, frameWidth, ctx->videoPixelMode); // Do not use avcDecodeDelayMs 's value From 92bbe974cdb35fe559aa248650b9add3c15fbeec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 10:01:22 +0200 Subject: [PATCH 297/848] Prevent reporting a bad memory access just because Tekken creates a mutex with a null name. --- Core/MemMap.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Core/MemMap.h b/Core/MemMap.h index 8178a7251a..40a6820698 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -258,8 +258,14 @@ bool IsRAMAddress(const u32 address); bool IsVRAMAddress(const u32 address); bool IsScratchpadAddress(const u32 address); +// Used for auto-converted char * parameters, which can sometimes legitimately be null - +// so we don't want to get caught in GetPointer's crash reporting. inline const char* GetCharPointer(const u32 address) { - return (const char *)GetPointer(address); + if (address) { + return (const char *)GetPointer(address); + } else { + return nullptr; + } } inline void MemcpyUnchecked(void *to_data, const u32 from_address, const u32 len) { From 834d08687626d09af5b387078a2411788b7fd3ab Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 10 Nov 2019 06:23:19 +0700 Subject: [PATCH 298/848] Support multiple instance of localhost Multiplayer on 1 PC --- Core/HLE/proAdhoc.cpp | 53 +++++++++- Core/HLE/proAdhoc.h | 8 +- Core/HLE/proAdhocServer.cpp | 38 +++++-- Core/HLE/sceNet.cpp | 192 +++++++++++++++++++++++++++++++++++- 4 files changed, 277 insertions(+), 14 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 17e675e175..9fe9760b77 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -21,6 +21,12 @@ // This is a direct port of Coldbird's code from http://code.google.com/p/aemu/ // All credit goes to him! +#if !defined(_WIN32) +#include +#include +#include +#endif + #include #include "util/text/parsers.h" #include "Core/Core.h" @@ -63,6 +69,10 @@ bool chatScreenVisible = false; bool updateChatScreen = false; int newChat = 0; +bool isLocalServer = false; +uint8_t PPSSPP_ID = 0; +sockaddr localIP; // This might serves the same purpose with existing "localip" above, but since this is copied from my old code so here it is (too lazy to rewrite the code) + int isLocalMAC(const SceNetEtherAddr * addr) { SceNetEtherAddr saddr; getLocalMac(&saddr); @@ -1345,7 +1355,7 @@ int getActivePeerCount(void) { int getLocalIp(sockaddr_in * SocketAddress){ #if defined(_WIN32) // Get local host name - char szHostName[128] = ""; + char szHostName[256] = ""; if(::gethostname(szHostName, sizeof(szHostName))) { // Error handling @@ -1355,11 +1365,26 @@ int getLocalIp(sockaddr_in * SocketAddress){ pHost = ::gethostbyname(szHostName); if(pHost) { memcpy(&SocketAddress->sin_addr, pHost->h_addr_list[0], pHost->h_length); + if (isLocalServer) { + SocketAddress->sin_addr = ((sockaddr_in*)&localIP)->sin_addr; + } return 0; } return -1; #else memcpy(&SocketAddress->sin_addr, &localip, sizeof(uint32_t)); + char szHostName[256] = ""; + gethostname(szHostName, sizeof(szHostName)); + struct hostent* pHost = 0; + pHost = gethostbyname(szHostName); + if (pHost) { + memcpy(&SocketAddress->sin_addr, pHost->h_addr_list[0], pHost->h_length); + if (isLocalServer) { + SocketAddress->sin_addr = ((sockaddr_in*)&localIP)->sin_addr; + } + return 0; + } + //return -1; return 0; #endif } @@ -1369,12 +1394,19 @@ uint32_t getLocalIp(int sock) { localAddr.sin_addr.s_addr = INADDR_ANY; socklen_t addrLen = sizeof(localAddr); getsockname(sock, (struct sockaddr*)&localAddr, &addrLen); + if (isLocalServer) { + localAddr.sin_addr = ((sockaddr_in*)&localIP)->sin_addr; + } return localAddr.sin_addr.s_addr; } void getLocalMac(SceNetEtherAddr * addr){ // Read MAC Address from config uint8_t mac[ETHER_ADDR_LEN] = {0}; + if (PPSSPP_ID > 1) { + memset(&mac, PPSSPP_ID, sizeof(mac)); + } + else if (!ParseMacAddress(g_Config.sMACAddress.c_str(), mac)) { ERROR_LOG(SCENET, "Error parsing mac address %s", g_Config.sMACAddress.c_str()); } @@ -1486,6 +1518,23 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ break; } } + + freeaddrinfo(resultAddr); + + // If Server is at localhost Try to Bind socket to specific adapter before connecting to prevent 2nd instance being recognized as already existing 127.0.0.1 by AdhocServer + // (may not works in WinXP/2003 for IPv4 due to "Weak End System" model) + if (((uint8_t*)&serverIp.s_addr)[0] == 0x7f) { // (serverIp.S_un.S_un_b.s_b1 == 0x7f) + int on = 1; + setsockopt(metasocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); + setsockopt(metasocket, SOL_SOCKET, SO_DONTROUTE, (const char*)&on, sizeof(on)); + + ((struct sockaddr_in*) & localIP)->sin_port = 0; + // Bind Local Address to Socket + iResult = bind(metasocket, (struct sockaddr*) & localIP, sizeof(sockaddr)); + if (iResult == SOCKET_ERROR) { + ERROR_LOG(SCENET, "Bind to alternate localhost[%s] failed(%i).", inet_ntoa(((struct sockaddr_in*) & localIP)->sin_addr), iResult); + } + } memset(¶meter, 0, sizeof(parameter)); strcpy((char *)¶meter.nickname.data, g_Config.sNickName.c_str()); @@ -1537,7 +1586,7 @@ bool resolveIP(uint32_t ip, SceNetEtherAddr * mac) { getLocalIp(&addr); uint32_t localIp = addr.sin_addr.s_addr; - if (ip == localIp){ + if (ip == localIp || ip == ((sockaddr_in*)&localIP)->sin_addr.s_addr){ getLocalMac(mac); return true; } diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 1480c03026..8440d573b5 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -36,7 +36,10 @@ class PointerWrap; // Net stuff -#if defined(_WIN32) +#ifdef _XBOX +#include +typedef int socklen_t; +#elif defined(_WIN32) #include #else #include @@ -797,6 +800,9 @@ extern SceNetAdhocPtpStat * ptp[255]; extern std::map adhocctlHandlers; extern uint16_t portOffset; +extern bool isLocalServer; +extern uint8_t PPSSPP_ID; +extern sockaddr localIP; extern uint32_t fakePoolSize; extern SceNetAdhocMatchingContext * contexts; extern int one; diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index e5e0940a71..54eeefd09f 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -498,7 +498,7 @@ void login_user_stream(int fd, uint32_t ip) if (u != NULL) { // IP Already existed uint8_t * ip4 = (uint8_t *)&u->resolver.ip; - INFO_LOG(SCENET, "AdhocServer: Already Existing IP: %u.%u.%u.%u\n", ip4[0], ip4[1], ip4[2], ip4[3]); + WARN_LOG(SCENET, "AdhocServer: Already Existing IP: %u.%u.%u.%u\n", ip4[0], ip4[1], ip4[2], ip4[3]); } // Unique IP Address @@ -567,6 +567,15 @@ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S // Valid Packet Data if(valid_product_code == 1 && memcmp(&data->mac, "\xFF\xFF\xFF\xFF\xFF\xFF", sizeof(data->mac)) != 0 && memcmp(&data->mac, "\x00\x00\x00\x00\x00\x00", sizeof(data->mac)) != 0 && data->name.data[0] != 0) { + // Check for duplicated MAC as most games identify Players by MAC + SceNetAdhocctlUserNode* u = _db_user; + while (u != NULL && !IsMatch(u->resolver.mac, data->mac)) u = u->next; + + if (u != NULL) { // MAC Already existed + uint8_t* ip4 = (uint8_t*)&u->resolver.ip; + WARN_LOG(SCENET, "AdhocServer: Already Existing MAC: %02X:%02X:%02X:%02X:%02X:%02X [%u.%u.%u.%u]\n", data->mac.data[0], data->mac.data[1], data->mac.data[2], data->mac.data[3], data->mac.data[4], data->mac.data[5], ip4[0], ip4[1], ip4[2], ip4[3]); + } + // Game Product Override game_product_override(&data->game); @@ -631,7 +640,7 @@ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; - INFO_LOG(SCENET, "AdhocServer: Invalid Login Packet Contents from %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + WARN_LOG(SCENET, "AdhocServer: Invalid Login Packet Contents from %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); } // Logout User - Out of Memory or Invalid Arguments @@ -694,7 +703,7 @@ void logout_user(SceNetAdhocctlUserNode * user) { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; - INFO_LOG(SCENET, "AdhocServer: Dropped Connection to %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + WARN_LOG(SCENET, "AdhocServer: Dropped Connection to %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); } // Free Memory @@ -907,7 +916,7 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group char safegroupstr2[9]; memset(safegroupstr2, 0, sizeof(safegroupstr2)); strncpy(safegroupstr2, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join %s group %s without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr, safegroupstr2); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join %s group %s without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr, safegroupstr2); } } @@ -922,7 +931,7 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)group->data, ADHOCCTL_GROUPNAME_LEN); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join invalid %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join invalid %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); } // Invalid State, Out of Memory or Invalid Group Name @@ -1023,7 +1032,7 @@ void disconnect_user(SceNetAdhocctlUserNode * user) char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to leave %s group without joining one first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to leave %s group without joining one first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); } // Delete User @@ -1099,7 +1108,7 @@ void send_scan_results(SceNetAdhocctlUserNode * user) char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to scan for %s groups without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to scan for %s groups without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); } // Delete User @@ -1213,7 +1222,7 @@ void spread_message(SceNetAdhocctlUserNode *user, const char *message) char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to send a text message without joining a %s group first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to send a text message without joining a %s group first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); } // Delete User @@ -1786,6 +1795,13 @@ int create_listen_socket(uint16_t port) local.sin_addr.s_addr = INADDR_ANY; local.sin_port = htons(port); + //Should only bind to specific IP for the 2nd or more instance of PPSSPP to prevent communication interference issue when sharing the same port. Doesn't work well when PPSSPP_ID reseted everytime emulation restarted. + /* + if (PPSSPP_ID > 1) { + local.sin_addr = ((sockaddr_in *)&localIP)->sin_addr; + } + */ + // Bind Local Address to Socket int bindresult = bind(fd, (struct sockaddr *)&local, sizeof(local)); @@ -1857,6 +1873,7 @@ int server_loop(int server) // Login User (Stream) if (loginresult != -1) { u32_le sip = addr.sin_addr.s_addr; + /* // Replacing 127.0.0.x with Ethernet IP will cause issue with multiple-instance of localhost (127.0.0.x) if (sip == 0x0100007f) { //127.0.0.1 should be replaced with LAN/WAN IP whenever available char str[100]; gethostname(str, 100); @@ -1865,6 +1882,7 @@ int server_loop(int server) sip = *(u32_le*)pip; WARN_LOG(SCENET, "AdhocServer: Replacing IP %s with %u.%u.%u.%u", inet_ntoa(addr.sin_addr), pip[0], pip[1], pip[2], pip[3]); } + */ login_user_stream(loginresult, sip); } } while(loginresult != -1); @@ -1925,7 +1943,7 @@ int server_loop(int server) { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; - INFO_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Waiting State from %u.%u.%u.%u", user->rx[0], ip[0], ip[1], ip[2], ip[3]); + WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Waiting State from %u.%u.%u.%u", user->rx[0], ip[0], ip[1], ip[2], ip[3]); // Logout User logout_user(user); @@ -2009,7 +2027,7 @@ int server_loop(int server) { // Notify User uint8_t * ip = (uint8_t *)&user->resolver.ip; - INFO_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Logged-In State from %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u)", user->rx[0], (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3]); + WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Logged-In State from %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u)", user->rx[0], (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3]); // Logout User logout_user(user); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 4a01534baf..ff9cca72dd 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -15,6 +15,14 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#if __linux__ || __APPLE__ +#include +#include +#include +#include +#include +#endif + #include "net/resolve.h" #include "util/text/parsers.h" @@ -49,6 +57,165 @@ static struct SceNetMallocStat netMallocStat; static std::map apctlHandlers; +#ifdef _WIN32 +static HANDLE hIDMapFile = NULL; +#elif __linux__ || __APPLE__ +static int hIDMapFile = 0; +#endif +static int32_t* pIDBuf = NULL; +#define ID_SHM_NAME "/PPSSPP_ID" + +// Get current number of instance of PPSSPP running. +static uint8_t getInstanceNumber() { +#ifdef _WIN32 +#if defined(_XBOX) + uint32_t BUF_SIZE = 0x10000; // 64k in 360; +#else + uint32_t BUF_SIZE = 4096; + SYSTEM_INFO sysInfo; + + GetSystemInfo(&sysInfo); + int gran = sysInfo.dwAllocationGranularity ? sysInfo.dwAllocationGranularity : 0x10000; + BUF_SIZE = (BUF_SIZE + gran - 1) & ~(gran - 1); +#endif + + hIDMapFile = CreateFileMapping( + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // maximum object size (high-order DWORD) + BUF_SIZE, // maximum object size (low-order DWORD) + TEXT(ID_SHM_NAME)); // name of mapping object + + DWORD lasterr = GetLastError(); + if (hIDMapFile == NULL) + { + ERROR_LOG(SCENET, "Could not create %s file mapping object (%d).", ID_SHM_NAME, lasterr); + return 1; + } + pIDBuf = (int32_t*)MapViewOfFile(hIDMapFile, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + sizeof(int32_t)); //BUF_SIZE + + if (pIDBuf == NULL) + { + ERROR_LOG(SCENET, "Could not map view of file %s (%d).", ID_SHM_NAME, GetLastError()); + //CloseHandle(hIDMapFile); + return 1; + } + + (*pIDBuf)++; + int id = *pIDBuf; + UnmapViewOfFile(pIDBuf); + //CloseHandle(hIDMapFile); //Should be called when program exits + //hIDMapFile = NULL; + + return id; +#elif __linux__ || __APPLE__ + long BUF_SIZE = 4096; + //caddr_t pIDBuf; + int status; + + // Create shared memory object + + hIDMapFile = shm_open(ID_SHM_NAME, O_CREAT | O_RDWR, 0); + BUF_SIZE = (BUF_SIZE < sysconf(_SC_PAGE_SIZE)) ? sysconf(_SC_PAGE_SIZE) : BUF_SIZE; + + if ((ftruncate(hIDMapFile, BUF_SIZE)) == -1) { // Set the size + ERROR_LOG(SCENET, "ftruncate(%s) failure.", ID_SHM_NAME); + return 1; + } + + pIDBuf = (int32_t*)mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hIDMapFile, 0); + if (pIDBuf == MAP_FAILED) { // Set the size + ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME); + pIDBuf = NULL; + return 1; + } + + int id = 1; + if (mlock(pIDBuf, BUF_SIZE) == 0) { + (*pIDBuf)++; + id = *pIDBuf; + munlock(pIDBuf, BUF_SIZE); + } + + status = munmap(pIDBuf, BUF_SIZE); // Unmap the page + //status = close(hIDMapFile); // Close file, should be called when program exits? + //status = shm_unlink(ID_SHM_NAME); // Unlink [& delete] shared-memory object, should be called when program exits + + return id; +#else + return 1; +#endif +} + +static void PPSSPPIDCleanup() { +#ifdef _WIN32 + if (hIDMapFile != NULL) { + CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted. + hIDMapFile = NULL; + } +#elif __linux__ || __APPLE__ + // TODO : This unlink should be called when program exits instead of everytime the game reset. + if (hIDMapFile != 0) { + close(hIDMapFile); + shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist. + hIDMapFile = 0; + } +#endif +} + +static int InitLocalIP() { + // find local IP + addrinfo* localAddr; + addrinfo* ptr; + char ipstr[256]; + sprintf(ipstr, "127.0.0.%u", PPSSPP_ID); + int iResult = getaddrinfo(ipstr, 0, NULL, &localAddr); + if (iResult != 0) { + ERROR_LOG(SCENET, "DNS Error (%s) result: %d\n", ipstr, iResult); + //osm.Show("DNS Error, can't resolve client bind " + ipstr, 8.0f); + ((sockaddr_in*)&localIP)->sin_family = AF_INET; + ((sockaddr_in*)&localIP)->sin_addr.s_addr = inet_addr(ipstr); //"127.0.0.1" + ((sockaddr_in*)&localIP)->sin_port = 0; + return iResult; + } + for (ptr = localAddr; ptr != NULL; ptr = ptr->ai_next) { + switch (ptr->ai_family) { + case AF_INET: + memcpy(&localIP, ptr->ai_addr, sizeof(sockaddr)); + break; + } + } + ((sockaddr_in*)&localIP)->sin_port = 0; + freeaddrinfo(localAddr); + + // Resolve server dns + addrinfo* resultAddr; + in_addr serverIp; + serverIp.s_addr = INADDR_NONE; + + iResult = getaddrinfo(g_Config.proAdhocServer.c_str(), 0, NULL, &resultAddr); + if (iResult != 0) { + ERROR_LOG(SCENET, "DNS Error (%s)\n", g_Config.proAdhocServer.c_str()); + return iResult; + } + for (ptr = resultAddr; ptr != NULL; ptr = ptr->ai_next) { + switch (ptr->ai_family) { + case AF_INET: + serverIp = ((sockaddr_in*)ptr->ai_addr)->sin_addr; + break; + } + } + freeaddrinfo(resultAddr); + isLocalServer = (((uint8_t*)&serverIp.s_addr)[0] == 0x7f); // (serverIp.S_un.S_un_b.s_b1 = 0x7f); + + return 0; +} + static void __ResetInitNetLib() { netInited = false; netApctlInited = false; @@ -59,11 +226,30 @@ static void __ResetInitNetLib() { void __NetInit() { portOffset = g_Config.iPortOffset; + //if (PPSSPP_ID == 0) // Each instance should use the same ID (and IP) once it's automatically assigned for consistency reason, But doesn't work well if PPSSPP_ID reseted everytime emulation restarted + { + PPSSPP_ID = getInstanceNumber(); // This should be called when program started instead of when the game started/reseted + } +#ifdef _WIN32 + WSADATA data; + int iResult = WSAStartup(MAKEWORD(2, 2), &data); + if (iResult != NOERROR) { + ERROR_LOG(SCENET, "WSA Failed"); + } +#endif + InitLocalIP(); + INFO_LOG(SCENET, "LocalHost IP will be %s", inet_ntoa(((sockaddr_in*)&localIP)->sin_addr)); + //net::Init(); __ResetInitNetLib(); } void __NetShutdown() { __ResetInitNetLib(); + //net::Shutdown(); +#ifdef _WIN32 + WSACleanup(); +#endif + PPSSPPIDCleanup(); //This should be called when program exited, otherwise everytime emulation restarted PPSSPP_ID will reset causing more than one instance might have the same ID and IP. } static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) { @@ -186,6 +372,10 @@ static u32 sceWlanGetEtherAddr(u32 addrAddr) { } u8 *addr = Memory::GetPointer(addrAddr); + if (PPSSPP_ID > 1) { + Memory::Memset(addrAddr, PPSSPP_ID, 6); + } + else // Read MAC Address from config if (!ParseMacAddress(g_Config.sMACAddress.c_str(), addr)) { ERROR_LOG(SCENET, "Error parsing mac address %s", g_Config.sMACAddress.c_str()); @@ -377,7 +567,7 @@ int sceNetInetPoll(void *fds, u32 nfds, int timeout) { // timeout in miliseconds DEBUG_LOG(SCENET, "UNTESTED sceNetInetPoll(%p, %d, %i) at %08x", fds, nfds, timeout, currentMIPS->pc); int retval = -1; SceNetInetPollfd *fdarray = (SceNetInetPollfd *)fds; // SceNetInetPollfd/pollfd, sceNetInetPoll() have similarity to BSD poll() but pollfd have different size on 64bit -//#ifdef _MSC_VER +//#ifdef _WIN32 //WSAPoll only available for Vista or newer, so we'll use an alternative way for XP since Windows doesn't have poll function like *NIX if (nfds > FD_SETSIZE) return -1; fd_set readfds, writefds, exceptfds; From a35acdee434d6d20266af68fe94eb3fe4c6b8f64 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 10 Nov 2019 13:42:50 +0700 Subject: [PATCH 299/848] Oops forgot to change this also for multiple-instance to work properly --- Core/HLE/sceNetAdhoc.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 6786b123dc..705e438ace 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -270,6 +270,9 @@ static int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 u sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; + if (isLocalServer) { + getLocalIp(&addr); + } //if (port < 7) addr.sin_port = htons(port + 1341); else // <= 443 addr.sin_port = htons(port + portOffset ); // This not safe in any way... @@ -1658,6 +1661,9 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; + if (isLocalServer) { + getLocalIp(&addr); + } addr.sin_port = htons(sport + portOffset); // Bound Socket to local Port @@ -2130,6 +2136,9 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; + if (isLocalServer) { + getLocalIp(&addr); + } addr.sin_port = htons(sport + portOffset); int iResult = 0; From 46ebdebe05e284b668b9d050eb70a3bee901425b Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 10 Nov 2019 13:43:17 +0700 Subject: [PATCH 300/848] Excluding Android from multiple-instance feature because i'm too lazy to learn ashmem :D --- Core/HLE/proAdhoc.cpp | 2 -- Core/HLE/sceNet.cpp | 11 ++++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 9fe9760b77..a7619de4a9 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -22,9 +22,7 @@ // All credit goes to him! #if !defined(_WIN32) -#include #include -#include #endif #include diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index ff9cca72dd..32e07afe1b 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #endif #include "net/resolve.h" @@ -113,6 +112,9 @@ static uint8_t getInstanceNumber() { //hIDMapFile = NULL; return id; +#elif __ANDROID__ + // TODO : replace shm_open & shm_unlink with ashmem or android-shmem + return 1; #elif __linux__ || __APPLE__ long BUF_SIZE = 4096; //caddr_t pIDBuf; @@ -158,6 +160,13 @@ static void PPSSPPIDCleanup() { CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted. hIDMapFile = NULL; } +#elif __ANDROID__ + if (hIDMapFile != 0) { + close(hIDMapFile); + // TODO : replace shm_unlink with ashmem or android-shmem + //shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist. + hIDMapFile = 0; + } #elif __linux__ || __APPLE__ // TODO : This unlink should be called when program exits instead of everytime the game reset. if (hIDMapFile != 0) { From 0aa899ea0bf6d3abab738de72f623312b04f3559 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 13 Nov 2019 12:28:34 +0700 Subject: [PATCH 301/848] Make PPSSPP_ID persistent every reset/changing game thus have persistent localhost IP --- Core/HLE/sceNet.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 32e07afe1b..c890e13df6 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -65,7 +65,7 @@ static int32_t* pIDBuf = NULL; #define ID_SHM_NAME "/PPSSPP_ID" // Get current number of instance of PPSSPP running. -static uint8_t getInstanceNumber() { +static uint8_t getPPSSPPInstanceNumber() { #ifdef _WIN32 #if defined(_XBOX) uint32_t BUF_SIZE = 0x10000; // 64k in 360; @@ -235,9 +235,9 @@ static void __ResetInitNetLib() { void __NetInit() { portOffset = g_Config.iPortOffset; - //if (PPSSPP_ID == 0) // Each instance should use the same ID (and IP) once it's automatically assigned for consistency reason, But doesn't work well if PPSSPP_ID reseted everytime emulation restarted + if (PPSSPP_ID == 0) // For persistent ID/IP, New instances may have a possibility to have the same ID/IP if PPSSPPIDCleanup() being called on every reset { - PPSSPP_ID = getInstanceNumber(); // This should be called when program started instead of when the game started/reseted + PPSSPP_ID = getPPSSPPInstanceNumber(); // This should be called when program started instead of when the game started/reseted } #ifdef _WIN32 WSADATA data; @@ -258,7 +258,7 @@ void __NetShutdown() { #ifdef _WIN32 WSACleanup(); #endif - PPSSPPIDCleanup(); //This should be called when program exited, otherwise everytime emulation restarted PPSSPP_ID will reset causing more than one instance might have the same ID and IP. + //PPSSPPIDCleanup(); // To make the ID/IP persistent on every reset, we should just let the OS closes all open handles instead of calling PPSSPPIDCleanup() on every reset } static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) { From 9e08f24769d66c71bb824a92380da6fb5703bcaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 09:40:56 +0200 Subject: [PATCH 302/848] Apply a few lines from "Added UPnP support", removing extra WSA calls. --- Core/HLE/sceNet.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index c890e13df6..2d41e054e0 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -239,13 +239,8 @@ void __NetInit() { { PPSSPP_ID = getPPSSPPInstanceNumber(); // This should be called when program started instead of when the game started/reseted } -#ifdef _WIN32 - WSADATA data; - int iResult = WSAStartup(MAKEWORD(2, 2), &data); - if (iResult != NOERROR) { - ERROR_LOG(SCENET, "WSA Failed"); - } -#endif + + net::Init(); InitLocalIP(); INFO_LOG(SCENET, "LocalHost IP will be %s", inet_ntoa(((sockaddr_in*)&localIP)->sin_addr)); //net::Init(); @@ -254,10 +249,8 @@ void __NetInit() { void __NetShutdown() { __ResetInitNetLib(); - //net::Shutdown(); -#ifdef _WIN32 - WSACleanup(); -#endif + + net::Shutdown(); //PPSSPPIDCleanup(); // To make the ID/IP persistent on every reset, we should just let the OS closes all open handles instead of calling PPSSPPIDCleanup() on every reset } From fa683bf902c8e4d495beb6805aca8e09e559f161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 09:51:03 +0200 Subject: [PATCH 303/848] Remove some _XBOX stuff --- Core/HLE/proAdhoc.h | 5 +---- Core/HLE/sceNet.cpp | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 8440d573b5..21470fc7a3 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -36,10 +36,7 @@ class PointerWrap; // Net stuff -#ifdef _XBOX -#include -typedef int socklen_t; -#elif defined(_WIN32) +#if defined(_WIN32) #include #else #include diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 2d41e054e0..dacb2904a8 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -65,18 +65,15 @@ static int32_t* pIDBuf = NULL; #define ID_SHM_NAME "/PPSSPP_ID" // Get current number of instance of PPSSPP running. +// Must be called only once during init. static uint8_t getPPSSPPInstanceNumber() { #ifdef _WIN32 -#if defined(_XBOX) - uint32_t BUF_SIZE = 0x10000; // 64k in 360; -#else uint32_t BUF_SIZE = 4096; SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); int gran = sysInfo.dwAllocationGranularity ? sysInfo.dwAllocationGranularity : 0x10000; BUF_SIZE = (BUF_SIZE + gran - 1) & ~(gran - 1); -#endif hIDMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file From fa0b9dc1bc0bfdb5a9e33acc2250fc8fd013f72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 11:38:39 +0200 Subject: [PATCH 304/848] Make the instance counter global and initialized at startup. Turn off config saving for secondary instances. --- CMakeLists.txt | 2 + Core/Config.cpp | 19 +++- Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 6 ++ Core/HLE/proAdhoc.cpp | 2 +- Core/HLE/proAdhoc.h | 1 - Core/HLE/sceNet.cpp | 123 +--------------------- Core/Instance.cpp | 151 ++++++++++++++++++++++++++++ Core/Instance.h | 31 ++++++ UWP/CoreUWP/CoreUWP.vcxproj | 2 + UWP/CoreUWP/CoreUWP.vcxproj.filters | 2 + Windows/WindowsHost.cpp | 14 ++- android/jni/Android.mk | 1 + libretro/Makefile.common | 1 + 14 files changed, 227 insertions(+), 130 deletions(-) create mode 100644 Core/Instance.cpp create mode 100644 Core/Instance.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 28d99b3fb8..0dc6e2114d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1449,6 +1449,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/CwCheat.h Core/HDRemaster.cpp Core/HDRemaster.h + Core/Instance.cpp + Core/Instance.h Core/ThreadEventQueue.h Core/WebServer.cpp Core/WebServer.h diff --git a/Core/Config.cpp b/Core/Config.cpp index 892482ca42..5ef4f6c26b 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -42,6 +42,7 @@ #include "Core/ConfigValues.h" #include "Core/Loaders.h" #include "Core/HLE/sceUtility.h" +#include "Core/Instance.h" #include "GPU/Common/FramebufferCommon.h" // TODO: Find a better place for this. @@ -1107,8 +1108,13 @@ static void IterateSettings(IniFile &iniFile, std::function> GetLangValuesMapping() { std::map> langValuesMapping; @@ -1290,9 +1296,18 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { jitForcedOff = true; g_Config.iCpuCore = (int)CPUCore::INTERPRETER; } + + INFO_LOG(LOADER, "Config loaded: '%s'", iniFilename_.c_str()); } void Config::Save(const char *saveReason) { + if (!IsFirstInstance()) { + // TODO: Should we allow saving config if started from a different directory? + // How do we tell? + WARN_LOG(LOADER, "Not saving config - secondary instances don't."); + return; + } + 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; diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 6679ddbf34..6ad9a0c3c0 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -388,6 +388,7 @@ + @@ -918,6 +919,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 5cfb4de0f5..b99fc00e07 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -746,6 +746,9 @@ Core + + Core + @@ -1385,6 +1388,9 @@ Core + + Core + diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a7619de4a9..7059b8eda3 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -32,6 +32,7 @@ #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelMemory.h" +#include "Core/Instance.h" #include "proAdhoc.h" #include "i18n/i18n.h" @@ -68,7 +69,6 @@ bool updateChatScreen = false; int newChat = 0; bool isLocalServer = false; -uint8_t PPSSPP_ID = 0; sockaddr localIP; // This might serves the same purpose with existing "localip" above, but since this is copied from my old code so here it is (too lazy to rewrite the code) int isLocalMAC(const SceNetEtherAddr * addr) { diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 21470fc7a3..2a7ee49132 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -798,7 +798,6 @@ extern std::map adhocctlHandlers; extern uint16_t portOffset; extern bool isLocalServer; -extern uint8_t PPSSPP_ID; extern sockaddr localIP; extern uint32_t fakePoolSize; extern SceNetAdhocMatchingContext * contexts; diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index dacb2904a8..e9996c464e 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -42,6 +42,7 @@ #include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/sceNet.h" #include "Core/Reporting.h" +#include "Core/Instance.h" static bool netInited; static bool netInetInited; @@ -56,124 +57,6 @@ static struct SceNetMallocStat netMallocStat; static std::map apctlHandlers; -#ifdef _WIN32 -static HANDLE hIDMapFile = NULL; -#elif __linux__ || __APPLE__ -static int hIDMapFile = 0; -#endif -static int32_t* pIDBuf = NULL; -#define ID_SHM_NAME "/PPSSPP_ID" - -// Get current number of instance of PPSSPP running. -// Must be called only once during init. -static uint8_t getPPSSPPInstanceNumber() { -#ifdef _WIN32 - uint32_t BUF_SIZE = 4096; - SYSTEM_INFO sysInfo; - - GetSystemInfo(&sysInfo); - int gran = sysInfo.dwAllocationGranularity ? sysInfo.dwAllocationGranularity : 0x10000; - BUF_SIZE = (BUF_SIZE + gran - 1) & ~(gran - 1); - - hIDMapFile = CreateFileMapping( - INVALID_HANDLE_VALUE, // use paging file - NULL, // default security - PAGE_READWRITE, // read/write access - 0, // maximum object size (high-order DWORD) - BUF_SIZE, // maximum object size (low-order DWORD) - TEXT(ID_SHM_NAME)); // name of mapping object - - DWORD lasterr = GetLastError(); - if (hIDMapFile == NULL) - { - ERROR_LOG(SCENET, "Could not create %s file mapping object (%d).", ID_SHM_NAME, lasterr); - return 1; - } - pIDBuf = (int32_t*)MapViewOfFile(hIDMapFile, // handle to map object - FILE_MAP_ALL_ACCESS, // read/write permission - 0, - 0, - sizeof(int32_t)); //BUF_SIZE - - if (pIDBuf == NULL) - { - ERROR_LOG(SCENET, "Could not map view of file %s (%d).", ID_SHM_NAME, GetLastError()); - //CloseHandle(hIDMapFile); - return 1; - } - - (*pIDBuf)++; - int id = *pIDBuf; - UnmapViewOfFile(pIDBuf); - //CloseHandle(hIDMapFile); //Should be called when program exits - //hIDMapFile = NULL; - - return id; -#elif __ANDROID__ - // TODO : replace shm_open & shm_unlink with ashmem or android-shmem - return 1; -#elif __linux__ || __APPLE__ - long BUF_SIZE = 4096; - //caddr_t pIDBuf; - int status; - - // Create shared memory object - - hIDMapFile = shm_open(ID_SHM_NAME, O_CREAT | O_RDWR, 0); - BUF_SIZE = (BUF_SIZE < sysconf(_SC_PAGE_SIZE)) ? sysconf(_SC_PAGE_SIZE) : BUF_SIZE; - - if ((ftruncate(hIDMapFile, BUF_SIZE)) == -1) { // Set the size - ERROR_LOG(SCENET, "ftruncate(%s) failure.", ID_SHM_NAME); - return 1; - } - - pIDBuf = (int32_t*)mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hIDMapFile, 0); - if (pIDBuf == MAP_FAILED) { // Set the size - ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME); - pIDBuf = NULL; - return 1; - } - - int id = 1; - if (mlock(pIDBuf, BUF_SIZE) == 0) { - (*pIDBuf)++; - id = *pIDBuf; - munlock(pIDBuf, BUF_SIZE); - } - - status = munmap(pIDBuf, BUF_SIZE); // Unmap the page - //status = close(hIDMapFile); // Close file, should be called when program exits? - //status = shm_unlink(ID_SHM_NAME); // Unlink [& delete] shared-memory object, should be called when program exits - - return id; -#else - return 1; -#endif -} - -static void PPSSPPIDCleanup() { -#ifdef _WIN32 - if (hIDMapFile != NULL) { - CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted. - hIDMapFile = NULL; - } -#elif __ANDROID__ - if (hIDMapFile != 0) { - close(hIDMapFile); - // TODO : replace shm_unlink with ashmem or android-shmem - //shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist. - hIDMapFile = 0; - } -#elif __linux__ || __APPLE__ - // TODO : This unlink should be called when program exits instead of everytime the game reset. - if (hIDMapFile != 0) { - close(hIDMapFile); - shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist. - hIDMapFile = 0; - } -#endif -} - static int InitLocalIP() { // find local IP addrinfo* localAddr; @@ -232,10 +115,6 @@ static void __ResetInitNetLib() { void __NetInit() { portOffset = g_Config.iPortOffset; - if (PPSSPP_ID == 0) // For persistent ID/IP, New instances may have a possibility to have the same ID/IP if PPSSPPIDCleanup() being called on every reset - { - PPSSPP_ID = getPPSSPPInstanceNumber(); // This should be called when program started instead of when the game started/reseted - } net::Init(); InitLocalIP(); diff --git a/Core/Instance.cpp b/Core/Instance.cpp new file mode 100644 index 0000000000..93d4002492 --- /dev/null +++ b/Core/Instance.cpp @@ -0,0 +1,151 @@ +// Copyright (c) 2020 PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "Instance.h" + +#if __linux__ || __APPLE__ +#include +#include +#include +#include +#endif + +#include "Common/Log.h" + +#if PPSSPP_PLATFORM(WINDOWS) + +#include "Common/CommonWindows.h" + +#endif + +#include + +uint8_t PPSSPP_ID = 0; + +#if PPSSPP_PLATFORM(WINDOWS) +static HANDLE hIDMapFile = NULL; +#else +static int hIDMapFile = 0; +#endif + +static int32_t* pIDBuf = NULL; +#define ID_SHM_NAME "/PPSSPP_ID" + +// Get current number of instance of PPSSPP running. +// Must be called only once during init. +void InitInstanceCounter() { +#if PPSSPP_PLATFORM(WINDOWS) + uint32_t BUF_SIZE = 4096; + SYSTEM_INFO sysInfo; + + GetSystemInfo(&sysInfo); + int gran = sysInfo.dwAllocationGranularity ? sysInfo.dwAllocationGranularity : 0x10000; + BUF_SIZE = (BUF_SIZE + gran - 1) & ~(gran - 1); + + hIDMapFile = CreateFileMapping( + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // maximum object size (high-order DWORD) + BUF_SIZE, // maximum object size (low-order DWORD) + TEXT(ID_SHM_NAME)); // name of mapping object + + DWORD lasterr = GetLastError(); + if (hIDMapFile == NULL) + { + ERROR_LOG(SCENET, "Could not create %s file mapping object (%d).", ID_SHM_NAME, lasterr); + PPSSPP_ID = 1; + return; + } + + pIDBuf = (int32_t*)MapViewOfFile(hIDMapFile, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + sizeof(int32_t)); //BUF_SIZE + + if (pIDBuf == NULL) { + ERROR_LOG(SCENET, "Could not map view of file %s (%d).", ID_SHM_NAME, GetLastError()); + //CloseHandle(hIDMapFile); + PPSSPP_ID = 1; + return; + } + + (*pIDBuf)++; + int id = *pIDBuf; + UnmapViewOfFile(pIDBuf); + //CloseHandle(hIDMapFile); //Should be called when program exits + //hIDMapFile = NULL; + + PPSSPP_ID = id; +#elif PPSSPP_PLATFORM(ANDROID) + // TODO : replace shm_open & shm_unlink with ashmem or android-shmem + PPSSPP_ID = 1; +#else + long BUF_SIZE = 4096; + //caddr_t pIDBuf; + int status; + + // Create shared memory object + + hIDMapFile = shm_open(ID_SHM_NAME, O_CREAT | O_RDWR, 0); + BUF_SIZE = (BUF_SIZE < sysconf(_SC_PAGE_SIZE)) ? sysconf(_SC_PAGE_SIZE) : BUF_SIZE; + + if ((ftruncate(hIDMapFile, BUF_SIZE)) == -1) { // Set the size + ERROR_LOG(SCENET, "ftruncate(%s) failure.", ID_SHM_NAME); + return 1; + } + + pIDBuf = (int32_t*)mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hIDMapFile, 0); + if (pIDBuf == MAP_FAILED) { // Set the size + ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME); + pIDBuf = NULL; + return 1; + } + + int id = 1; + if (mlock(pIDBuf, BUF_SIZE) == 0) { + (*pIDBuf)++; + id = *pIDBuf; + munlock(pIDBuf, BUF_SIZE); + } + + status = munmap(pIDBuf, BUF_SIZE); // Unmap the page + //status = close(hIDMapFile); // Close file, should be called when program exits? + //status = shm_unlink(ID_SHM_NAME); // Unlink [& delete] shared-memory object, should be called when program exits + + return id; +#endif +} + +void ShutdownInstanceCounter() { +#if PPSSPP_PLATFORM(WINDOWS) + if (hIDMapFile != NULL) { + CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted. + hIDMapFile = NULL; + } +#elif PPSSPP_PLATFORM(ANDROID) + // Do nothing +#else + // TODO : This unlink should be called when program exits instead of everytime the game reset. + if (hIDMapFile != 0) { + close(hIDMapFile); + shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist. + hIDMapFile = 0; + } +#endif +} diff --git a/Core/Instance.h b/Core/Instance.h new file mode 100644 index 0000000000..5fdfd8106c --- /dev/null +++ b/Core/Instance.h @@ -0,0 +1,31 @@ +// Copyright (c) 2020 PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "ppsspp_config.h" + +#include + +extern uint8_t PPSSPP_ID; + +void InitInstanceCounter(); +void ShutdownInstanceCounter(); + +inline bool IsFirstInstance() { + return PPSSPP_ID == 1; +} diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 900df8f61a..80830c4cc3 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -432,6 +432,7 @@ + @@ -648,6 +649,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 8055a958ff..5e9b91ec56 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -80,6 +80,7 @@ + @@ -718,6 +719,7 @@ + diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 84d09875bd..f0735eb202 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -46,6 +46,8 @@ #include "Core/CoreParameter.h" #include "Core/System.h" #include "Core/Debugger/SymbolMap.h" +#include "Core/Instance.h" + #include "Windows/EmuThread.h" #include "Windows/WindowsAudio.h" #include "Windows/WindowsHost.h" @@ -101,8 +103,9 @@ WindowsHost::WindowsHost(HINSTANCE hInstance, HWND mainWindow, HWND displayWindo void WindowsHost::SetConsolePosition() { HWND console = GetConsoleWindow(); - if (console != NULL && g_Config.iConsoleWindowX != -1 && g_Config.iConsoleWindowY != -1) + if (console != NULL && g_Config.iConsoleWindowX != -1 && g_Config.iConsoleWindowY != -1) { SetWindowPos(console, NULL, g_Config.iConsoleWindowX, g_Config.iConsoleWindowY, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + } } void WindowsHost::UpdateConsolePosition() { @@ -167,6 +170,9 @@ void WindowsHost::SetWindowTitle(const char *message) { #ifdef _DEBUG winTitle.append(L" (debug)"); #endif + if (PPSSPP_ID >= 1) { + winTitle.append(ConvertUTF8ToWString(StringFromFormat(" (instance: %d)", (int)PPSSPP_ID))); + } MainWindow::SetWindowTitle(winTitle.c_str()); PostMessage(mainWindow_, MainWindow::WM_USER_WINDOW_TITLE_CHANGED, 0, 0); @@ -280,7 +286,7 @@ static std::string SymbolMapFilename(const char *currentFilename, const char* ex return result + ".ppsspp-symbols" + ext; } else { - size_t dot = result.rfind('.'); + const size_t dot = result.rfind('.'); if (dot == result.npos) return result + ext; @@ -360,8 +366,8 @@ bool WindowsHost::CreateDesktopShortcut(std::string argumentPath, std::string ga // Sanitize the game title for banned characters. const char bannedChars[] = "<>:\"/\\|?*"; for (size_t i = 0; i < gameTitle.size(); i++) { - for (size_t c = 0; c < strlen(bannedChars); c++) { - if (gameTitle[i] == bannedChars[c]) { + for (char c : bannedChars) { + if (gameTitle[i] == c) { gameTitle[i] = '_'; break; } diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 5a08665464..7aa1cd2d4a 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -291,6 +291,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/CoreTiming.cpp \ $(SRC)/Core/CwCheat.cpp \ $(SRC)/Core/HDRemaster.cpp \ + $(SRC)/Core/Instance.cpp \ $(SRC)/Core/Host.cpp \ $(SRC)/Core/Loaders.cpp \ $(SRC)/Core/PSPLoaders.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 3b12a0ba07..b9fe4993bc 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -342,6 +342,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/CoreTiming.cpp \ $(COREDIR)/CwCheat.cpp \ $(COREDIR)/HDRemaster.cpp \ + $(COREDIR)/Instance.cpp \ $(COREDIR)/Debugger/Breakpoints.cpp \ $(COREDIR)/Debugger/SymbolMap.cpp \ $(COREDIR)/Dialog/PSPDialog.cpp \ From df6d0a8ae71d9fb1a50ed0f0f9720d0f06159447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 11:01:52 +0200 Subject: [PATCH 305/848] PSP kernel: Improve logging when accessing bad kernel object handles. --- Core/HLE/HLE.cpp | 2 +- Core/HLE/sceHeap.cpp | 2 +- Core/HLE/sceIo.cpp | 6 ++++-- Core/HLE/sceKernel.h | 8 ++++---- Core/HLE/sceKernelAlarm.cpp | 3 ++- Core/HLE/sceKernelEventFlag.cpp | 3 ++- Core/HLE/sceKernelHeap.cpp | 2 ++ Core/HLE/sceKernelMbx.cpp | 3 ++- Core/HLE/sceKernelMemory.cpp | 12 ++++++++---- Core/HLE/sceKernelModule.cpp | 3 ++- Core/HLE/sceKernelMsgPipe.cpp | 3 ++- Core/HLE/sceKernelMutex.cpp | 6 ++++-- Core/HLE/sceKernelSemaphore.cpp | 3 ++- Core/HLE/sceKernelThread.cpp | 12 +++++++----- Core/HLE/sceKernelVTimer.cpp | 3 ++- Core/HLE/scePsmf.cpp | 2 +- 16 files changed, 46 insertions(+), 27 deletions(-) diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index cde8b2cf37..d12ba73955 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -112,7 +112,7 @@ void hleDelayResultFinish(u64 userdata, int cycleslate) __KernelReSchedule("woke from hle delay"); } else - WARN_LOG(HLE, "Someone else woke up HLE-blocked thread?"); + WARN_LOG(HLE, "Someone else woke up HLE-blocked thread %d?", threadID); } void HLEInit() { diff --git a/Core/HLE/sceHeap.cpp b/Core/HLE/sceHeap.cpp index 5a70358e34..72873edbbd 100644 --- a/Core/HLE/sceHeap.cpp +++ b/Core/HLE/sceHeap.cpp @@ -26,7 +26,7 @@ #include struct Heap { - Heap():alloc(4) {} + Heap() : alloc(4) {} u32 size; u32 address; diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index d49005228a..49d14f0c36 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -209,7 +209,8 @@ public: pgd_close(pgdInfo); } const char *GetName() override { return fullpath.c_str(); } - const char *GetTypeName() override { return "OpenFile"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "OpenFile"; } void GetQuickInfo(char *ptr, int size) override { sprintf(ptr, "Seekpos: %08x", (u32)pspFileSystem.GetSeekPos(handle)); } @@ -2232,7 +2233,8 @@ static u32 sceIoPollAsync(int id, u32 address) { class DirListing : public KernelObject { public: const char *GetName() override { return name.c_str(); } - const char *GetTypeName() override { return "DirListing"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "DirListing"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_BADF; } static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_DirList; } int GetIDType() const override { return PPSSPP_KERNEL_TMID_DirList; } diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 78c7b746bf..787804912f 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -458,17 +458,17 @@ public: if (handle < handleOffset || handle >= handleOffset+maxCount || !occupied[handle-handleOffset]) { // Tekken 6 spams 0x80020001 gets wrong with no ill effects, also on the real PSP if (handle != 0 && (u32)handle != 0x80020001) { - WARN_LOG(SCEKERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); + WARN_LOG(SCEKERNEL, "Kernel: Bad %s handle %d (%08x)", T::GetStaticTypeName(), handle, handle); } outError = T::GetMissingErrorCode(); return 0; } else { // Previously we had a dynamic_cast here, but since RTTI was disabled traditionally, - // it just acted as a static case and everything worked. This means that we will never + // it just acted as a static cast and everything worked. This means that we will never // see the Wrong type object error below, but we'll just have to live with that danger. T* t = static_cast(pool[handle - handleOffset]); - if (t == 0 || t->GetIDType() != T::GetStaticIDType()) { - WARN_LOG(SCEKERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle); + if (t == nullptr || t->GetIDType() != T::GetStaticIDType()) { + WARN_LOG(SCEKERNEL, "Kernel: Wrong object type for %d (%08x), was %s, should have been %s", handle, handle, t->GetTypeName(), T::GetStaticTypeName()); outError = T::GetMissingErrorCode(); return 0; } diff --git a/Core/HLE/sceKernelAlarm.cpp b/Core/HLE/sceKernelAlarm.cpp index de9c5435ff..edce430446 100644 --- a/Core/HLE/sceKernelAlarm.cpp +++ b/Core/HLE/sceKernelAlarm.cpp @@ -39,7 +39,8 @@ struct NativeAlarm struct PSPAlarm : public KernelObject { const char *GetName() override {return "[Alarm]";} - const char *GetTypeName() override {return "Alarm";} + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "Alarm"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_ALMID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_Alarm; } int GetIDType() const override { return SCE_KERNEL_TMID_Alarm; } diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index 47fb2c05e3..0dde6fb966 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -53,7 +53,8 @@ struct EventFlagTh { class EventFlag : public KernelObject { public: const char *GetName() override { return nef.name; } - const char *GetTypeName() override { return "EventFlag"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "EventFlag"; } void GetQuickInfo(char *ptr, int size) override { sprintf(ptr, "init=%08x cur=%08x numwait=%i", nef.initPattern, diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index a7385d537c..95509c52cd 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -23,6 +23,8 @@ struct Heap : public KernelObject { static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_UID; } static int GetStaticIDType() { return PPSSPP_KERNEL_TMID_Heap; } int GetIDType() const override { return PPSSPP_KERNEL_TMID_Heap; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "Heap"; } void DoState(PointerWrap &p) override { p.Do(uid); diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index 0eb6bc89b3..38dd9687f0 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -61,7 +61,8 @@ struct NativeMbx struct Mbx : public KernelObject { const char *GetName() override { return nmb.name; } - const char *GetTypeName() override { return "Mbx"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "Mbx"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MBXID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_Mbox; } int GetIDType() const override { return SCE_KERNEL_TMID_Mbox; } diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 7d2e7e4241..50792c39ff 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -93,7 +93,8 @@ struct FPL : public KernelObject } } const char *GetName() override { return nf.name; } - const char *GetTypeName() override { return "FPL"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "FPL"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_FPLID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_Fpl; } int GetIDType() const override { return SCE_KERNEL_TMID_Fpl; } @@ -375,7 +376,8 @@ struct SceKernelVplHeader { struct VPL : public KernelObject { const char *GetName() override { return nv.name; } - const char *GetTypeName() override { return "VPL"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "VPL"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VPLID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_Vpl; } int GetIDType() const override { return SCE_KERNEL_TMID_Vpl; } @@ -899,7 +901,8 @@ class PartitionMemoryBlock : public KernelObject { public: const char *GetName() override { return name; } - const char *GetTypeName() override { return "MemoryPart"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "MemoryPart"; } void GetQuickInfo(char *ptr, int size) override { int sz = alloc->GetBlockSizeFromAddress(address); @@ -1869,7 +1872,8 @@ struct NativeTlspl struct TLSPL : public KernelObject { const char *GetName() override { return ntls.name; } - const char *GetTypeName() override { return "TLS"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "TLS"; } static u32 GetMissingErrorCode() { return PSP_ERROR_UNKNOWN_TLSPL_ID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_Tlspl; } int GetIDType() const override { return SCE_KERNEL_TMID_Tlspl; } diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 2c3b7aef08..77bf264e44 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -244,7 +244,8 @@ public: } } const char *GetName() override { return nm.name; } - const char *GetTypeName() override { return "Module"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "Module"; } void GetQuickInfo(char *ptr, int size) override { // ignore size diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index a521c680a1..543afbb3fe 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -131,7 +131,8 @@ static bool __KernelMsgPipeThreadSortPriority(MsgPipeWaitingThread thread1, MsgP struct MsgPipe : public KernelObject { const char *GetName() override { return nmp.name; } - const char *GetTypeName() override { return "MsgPipe"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "MsgPipe"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MPPID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_Mpipe; } int GetIDType() const override { return SCE_KERNEL_TMID_Mpipe; } diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index 7418a68f05..fe958ade6d 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -65,7 +65,8 @@ struct NativeMutex struct PSPMutex : public KernelObject { const char *GetName() override { return nm.name; } - const char *GetTypeName() override { return "Mutex"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "Mutex"; } static u32 GetMissingErrorCode() { return PSP_MUTEX_ERROR_NO_SUCH_MUTEX; } static int GetStaticIDType() { return SCE_KERNEL_TMID_Mutex; } int GetIDType() const override { return SCE_KERNEL_TMID_Mutex; } @@ -130,7 +131,8 @@ struct NativeLwMutex struct LwMutex : public KernelObject { const char *GetName() override { return nm.name; } - const char *GetTypeName() override { return "LwMutex"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "LwMutex"; } static u32 GetMissingErrorCode() { return PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX; } static int GetStaticIDType() { return SCE_KERNEL_TMID_LwMutex; } int GetIDType() const override { return SCE_KERNEL_TMID_LwMutex; } diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 6d96dec8e8..f6de056d2e 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -55,7 +55,8 @@ struct NativeSemaphore struct PSPSemaphore : public KernelObject { const char *GetName() override { return ns.name; } - const char *GetTypeName() override { return "Semaphore"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "Semaphore"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_SEMID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_Semaphore; } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 58cd5dd873..194fd2082c 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -138,7 +138,8 @@ struct NativeCallback class PSPCallback : public KernelObject { public: const char *GetName() override { return nc.name; } - const char *GetTypeName() override { return "CallBack"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "CallBack"; } void GetQuickInfo(char *ptr, int size) override { sprintf(ptr, "thread=%i, argument= %08x", @@ -376,9 +377,9 @@ public: PSPThread() : debug(currentMIPS, context) {} const char *GetName() override { return nt.name; } - const char *GetTypeName() override { return "Thread"; } - void GetQuickInfo(char *ptr, int size) override - { + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "Thread"; } + void GetQuickInfo(char *ptr, int size) override { sprintf(ptr, "pc= %08x sp= %08x %s %s %s %s %s %s (wt=%i wid=%i wv= %08x )", context.pc, context.r[MIPS_REG_SP], (nt.status & THREADSTATUS_RUNNING) ? "RUN" : "", @@ -3659,7 +3660,8 @@ struct NativeThreadEventHandler { struct ThreadEventHandler : public KernelObject { const char *GetName() { return nteh.name; } - const char *GetTypeName() { return "ThreadEventHandler"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "ThreadEventHandler"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_TEID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_ThreadEventHandler; } int GetIDType() const { return SCE_KERNEL_TMID_ThreadEventHandler; } diff --git a/Core/HLE/sceKernelVTimer.cpp b/Core/HLE/sceKernelVTimer.cpp index 276f5db13d..7b5a272358 100644 --- a/Core/HLE/sceKernelVTimer.cpp +++ b/Core/HLE/sceKernelVTimer.cpp @@ -43,7 +43,8 @@ struct NativeVTimer { struct VTimer : public KernelObject { const char *GetName() override { return nvt.name; } - const char *GetTypeName() override { return "VTimer"; } + const char *GetTypeName() override { return GetStaticTypeName(); } + static const char *GetStaticTypeName() { return "VTimer"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VTID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_VTimer; } int GetIDType() const override { return SCE_KERNEL_TMID_VTimer; } diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 7d3eee9680..f89fa524dd 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -1734,7 +1734,7 @@ static u32 scePsmfPlayerGetCurrentPts(u32 psmfPlayer, u32 currentPtsAddr) return ERROR_PSMFPLAYER_INVALID_STATUS; } if (psmfplayer->psmfPlayerAvcAu.pts < 0) { - WARN_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x, %08x): no frame yet", psmfPlayer, currentPtsAddr); + VERBOSE_LOG(ME, "scePsmfPlayerGetCurrentPts(%08x, %08x): no frame yet", psmfPlayer, currentPtsAddr); return ERROR_PSMFPLAYER_NO_MORE_DATA; } From 82af304699ed291b9189e693bcacad4aec72c555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 11:59:34 +0200 Subject: [PATCH 306/848] Silence secondary instances. --- Core/Config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Core/Config.cpp b/Core/Config.cpp index 5ef4f6c26b..606f3321be 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1297,6 +1297,11 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { g_Config.iCpuCore = (int)CPUCore::INTERPRETER; } + // Automatically silence secondary instances. Could be an option I guess, but meh. + if (PPSSPP_ID > 1) { + g_Config.iGlobalVolume = 0; + } + INFO_LOG(LOADER, "Config loaded: '%s'", iniFilename_.c_str()); } From 4f3b473f2950a7cc62567efdb61a573fe85a87d0 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 12 Nov 2019 02:20:46 +0700 Subject: [PATCH 307/848] Making sure adhoc callbacks runs on AdhocThread --- Core/HLE/sceNetAdhoc.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 705e438ace..13edc82328 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -168,15 +168,6 @@ u32 sceNetAdhocInit() { // Library initialized netAdhocInited = true; - // Create fake PSP Thread for callback - // 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 :( - // TODO: This should probably be a user thread, but maybe from sceNetAdhocctlInit? - threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, 0x10, 0x1000, PSP_THREAD_ATTR_KERNEL, 0, true); - if (threadAdhocID > 0) { - __KernelStartThread(threadAdhocID, 0, 0); - } - // Return Success return hleLogSuccessInfoI(SCENET, 0, "at %08x", currentMIPS->pc); } @@ -189,9 +180,20 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { if (netAdhocctlInited) return ERROR_NET_ADHOCCTL_ALREADY_INITIALIZED; + + // Create fake PSP Thread for callback + // 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 // Using constants instead of numbers for readability reason, since PSP_THREAD_ATTR_KERNEL/USER is located in sceKernelThread.cpp instead of sceKernelThread.h +#define PSP_THREAD_ATTR_USER 0x80000000 + + threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, prio, stackSize, PSP_THREAD_ATTR_USER, 0, false); + if (threadAdhocID > 0) { + __KernelStartThread(threadAdhocID, 0, 0); + } if(g_Config.bEnableWlan) { if (initNetwork((SceNetAdhocctlAdhocId *)Memory::GetPointer(productAddr)) == 0) { + // TODO: Merging friendFinder (real) thread to AdhocThread (fake) thread on PSP side if (!friendFinderRunning) { friendFinderRunning = true; friendFinderThread = std::thread(friendFinder); @@ -1138,6 +1140,12 @@ int sceNetAdhocctlTerm() { // Free stuff here closesocket(metasocket); metasocket = (int)INVALID_SOCKET; + // Delete fake PSP Thread + if (threadAdhocID != 0) { + __KernelStopThread(threadAdhocID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocThread stopped"); + __KernelDeleteThread(threadAdhocID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocThread deleted"); + threadAdhocID = 0; + } /*#ifdef _MSC_VER WSACleanup(); // Might be better to call WSAStartup/WSACleanup from sceNetInit/sceNetTerm isn't? since it's the first/last network function being used, even better to put it in __NetInit/__NetShutdown as it's only called once #endif*/ @@ -1426,12 +1434,6 @@ int sceNetAdhocTerm() { // Library is initialized if (netAdhocInited) { - // Delete fake PSP Thread - if (threadAdhocID != 0) { - __KernelStopThread(threadAdhocID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocThread stopped"); - __KernelDeleteThread(threadAdhocID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocThread deleted"); - } - // Delete PDP Sockets deleteAllPDP(); @@ -3489,6 +3491,7 @@ void __NetTriggerCallbacks() for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { args[2] = it->second.argument; + __KernelSwitchToThread(threadAdhocID, "AdhocctlHandler Mipscall"); __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 3, true); } } @@ -3499,6 +3502,8 @@ void __NetTriggerCallbacks() u32_le *args = (u32_le *) param; AfterMatchingMipsCall *after = (AfterMatchingMipsCall *) __KernelCreateAction(actionAfterMatchingMipsCall); after->SetContextID(args[0], args[1]); + // Need to make sure currentThread is AdhocMatching's eventThread before calling the callback + __KernelSwitchToThread(threadAdhocID, "AdhocMatchingEvent Mipscall"); __KernelDirectMipsCall(args[5], after, args, 5, true); } matchingEvents.clear(); From da5b54e630ba98b3837666156dc213c156db69cc Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 13 Nov 2019 12:56:29 +0700 Subject: [PATCH 308/848] Separate each AdhocMatching callback's buffer, since callback aren't immediately executed thus using shared memory address may corrupt previous data --- Core/HLE/proAdhoc.cpp | 36 +++++++++++++++++++++--------------- Core/HLE/proAdhoc.h | 6 ++++-- Core/HLE/sceNetAdhoc.cpp | 37 +++++++++++++++++++------------------ Core/HLE/sceNetAdhoc.h | 6 +++++- 4 files changed, 49 insertions(+), 36 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a7619de4a9..2a770c2d7f 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -935,11 +935,13 @@ void AfterMatchingMipsCall::run(MipsCall &call) { } context->eventlock->unlock(); //peerlock.unlock(); //call.setReturnValue(v0); + if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); DEBUG_LOG(SCENET, "Leaving AfterMatchingMipsCall::run [ID=%i][Event=%d] [retV0: %08x]", context->id, EventID, currentMIPS->r[MIPS_REG_V0]); } -void AfterMatchingMipsCall::SetContextID(u32 ContextID, u32 eventId) { +void AfterMatchingMipsCall::SetContextID(u32 ContextID, u32 eventId, u32_le BufAddr) { EventID = eventId; + bufAddr = BufAddr; peerlock.lock(); context = findMatchingContext(ContextID); peerlock.unlock(); @@ -949,7 +951,7 @@ void AfterMatchingMipsCall::SetContextID(u32 ContextID, u32 eventId) { void notifyAdhocctlHandlers(u32 flag, u32 error) { __UpdateAdhocctlHandlers(flag, error); // TODO: We should use after action instead of guessing the time like this - sleep_ms(20); // Ugly workaround to give time for the mips callback to fully executed, usually only need <16ms + //sleep_ms(20); // Ugly workaround to give time for the mips callback to fully executed, usually only need <16ms } // Matching callback is void function: typedef void(*SceNetAdhocMatchingHandler)(int id, int event, SceNetEtherAddr * peer, int optlen, void * opt); @@ -957,33 +959,37 @@ void notifyAdhocctlHandlers(u32 flag, u32 error) { // Note: Must not lock peerlock within this function to prevent race-condition with other thread whos owning peerlock and trying to lock context->eventlock owned by this thread void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32 &bufAddr, u32 &bufLen, u32_le * args) { //u32_le args[5] = { 0, 0, 0, 0, 0 }; - if ((s32)bufLen < (msg->optlen + 8)) { + /*if ((s32)bufLen < (msg->optlen + 8)) { bufLen = msg->optlen + 8; if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); - bufAddr = userMemory.Alloc(bufLen); + bufAddr = userMemory.Alloc(bufLen); // Max bufLen should be context->rxbuflen INFO_LOG(SCENET, "MatchingHandler: Alloc(%i -> %i) = %08x", msg->optlen + 8, bufLen, bufAddr); - } + }*/ + MatchingArgs argsNew; + bufAddr = userMemory.Alloc(bufLen); // We will free this after returning from mipscall u8 * optPtr = Memory::GetPointer(bufAddr); memcpy(optPtr, &msg->mac, sizeof(msg->mac)); if (msg->optlen > 0) memcpy(optPtr + 8, opt, msg->optlen); - args[0] = context->id; - args[1] = msg->opcode; - args[2] = bufAddr; // PSP_GetScratchpadMemoryBase() + 0x6000; - args[3] = msg->optlen; - args[4] = args[2] + 8; - args[5] = context->handler.entryPoint; //not part of callback argument, just borrowing a space to store callback address so i don't need to search the context first later + argsNew.data[0] = context->id; + argsNew.data[1] = msg->opcode; + argsNew.data[2] = bufAddr; // PSP_GetScratchpadMemoryBase() + 0x6000; + argsNew.data[3] = msg->optlen; + argsNew.data[4] = argsNew.data[2] + 8; // OptData Addr + argsNew.data[5] = context->handler.entryPoint; //not part of callback argument, just borrowing a space to store callback address so i don't need to search the context first later + context->eventlock->lock(); context->IsMatchingInCB = true; + context->eventlock->unlock(); // ScheduleEvent_Threadsafe_Immediate seems to get mixed up with interrupt (returning from mipscall inside an interrupt) and getting invalid address before returning from interrupt - __UpdateMatchingHandler((u64) args); + __UpdateMatchingHandler(argsNew); // Make sure MIPS call have been fully executed before the next notifyMatchingHandler - int count = 0; - while (/*(after != NULL) &&*/ IsMatchingInCallback(context) && (count < 250)) { + /*int count = 0; + while ( IsMatchingInCallback(context) && (count < 250)) { sleep_ms(1); count++; } - if (count >= 250) ERROR_LOG(SCENET, "MatchingHandler: Callback Failed to Return within %dms!", count); + if (count >= 250) ERROR_LOG(SCENET, "MatchingHandler: Callback Failed to Return within %dms! [ID=%i][Opcode=%d][OptSize=%d][MAC=%012X]", count, context->id, msg->opcode, msg->optlen, htonl(*(u_long*)&msg->mac));*/ //sleep_ms(20); // Wait a little more (for context switching may be?) to prevent DBZ Tag Team from getting connection lost, but this will cause lags on Lord of Arcana } diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 21470fc7a3..239f275e80 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -443,7 +443,7 @@ typedef struct SceNetAdhocMatchingContext { SceNetAdhocMatchingHandler handler; // Event Handler Args - u32_le handlerArgs[6]; // actual arguments only 5, the 6th one is just for borrowing a space to store the callback address to use later + u32_le handlerArgs[6]; //MatchingArgs handlerArgs; // actual arguments only 5, the 6th one is just for borrowing a space to store the callback address to use later //SceNetAdhocMatchingHandlerArgs handlerArgs; // Hello Data Length @@ -776,11 +776,13 @@ public: //context = NULL; } void run(MipsCall &call) override; - void SetContextID(u32 ContextID, u32 eventId); + void SetContextID(u32 ContextID, u32 eventId, u32_le BufAddr); + void SetContext(SceNetAdhocMatchingContext* Context, u32 eventId, u32_le BufAddr) { context = Context; EventID = eventId; bufAddr = BufAddr; } private: u32 EventID = 0; SceNetAdhocMatchingContext *context = nullptr; + u32_le bufAddr = 0; }; extern int actionAfterMatchingMipsCall; diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 13edc82328..52dbcd9d8f 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -50,7 +50,7 @@ SceUID threadAdhocID; std::mutex adhocEvtMtx; std::vector> adhocctlEvents; -std::vector matchingEvents; +std::vector matchingEvents; u32 dummyThreadHackAddr = 0; u32_le dummyThreadCode[3]; @@ -124,7 +124,7 @@ void __UpdateAdhocctlHandlers(u32 flag, u32 error) { } // TODO: MipsCall needs to be called from it's own PSP Thread instead of from any random PSP Thread -void __UpdateMatchingHandler(u64 ArgsPtr) { +void __UpdateMatchingHandler(MatchingArgs ArgsPtr) { std::lock_guard adhocGuard(adhocEvtMtx); matchingEvents.push_back(ArgsPtr); } @@ -2667,7 +2667,7 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle context->hello_int = hello_int; // client might set this to 0 if (keepalive_int < 1) context->keepalive_int = PSP_ADHOCCTL_PING_TIMEOUT; else context->keepalive_int = keepalive_int; // client might set this to 0 context->keepalivecounter = init_count; // used to multiply keepalive_int as timeout - context->timeout = (keepalive_int * init_count); + context->timeout = ((u64_le)keepalive_int * (u64_le)init_count); if (context->timeout < 5000000) context->timeout = 5000000; // For internet play we need higher timeout than what the game wanted context->handler = handler; @@ -3491,22 +3491,24 @@ void __NetTriggerCallbacks() for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { args[2] = it->second.argument; - __KernelSwitchToThread(threadAdhocID, "AdhocctlHandler Mipscall"); - __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 3, true); + __KernelSwitchToThread(threadAdhocID, "AdhocctlHandler Mipscall"); // it's not guaranteed to switch successfully tho + //while (__KernelInCallback()) sleep_ms(1); + __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 3, false); } } - adhocctlEvents.clear(); + adhocctlEvents.clear(); // We should only clear this after making sure all callbacks are placed on the right thread tho for (auto ¶m : matchingEvents) { - u32_le *args = (u32_le *) param; + u32_le *args = (u32_le*)¶m; AfterMatchingMipsCall *after = (AfterMatchingMipsCall *) __KernelCreateAction(actionAfterMatchingMipsCall); - after->SetContextID(args[0], args[1]); - // Need to make sure currentThread is AdhocMatching's eventThread before calling the callback - __KernelSwitchToThread(threadAdhocID, "AdhocMatchingEvent Mipscall"); - __KernelDirectMipsCall(args[5], after, args, 5, true); + after->SetContextID(args[0], args[1], args[2]); + // Need to make sure currentThread is AdhocMatching's eventThread before calling the callback, and not in the middle of callback + __KernelSwitchToThread(threadAdhocID, "AdhocMatchingEvent Mipscall"); // it's not guaranteed to switch successfully tho + //while (__KernelInCallback()) sleep_ms(1); + __KernelDirectMipsCall(args[5], after, args, 5, false); } - matchingEvents.clear(); + matchingEvents.clear(); // We should only clear this after making sure all callbacks are placed on the right thread tho } //magically make this work hleDelayResult(0, "Prevent Adhoc thread from blocking", 1000); @@ -4775,9 +4777,6 @@ void actOnByePacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * send */ int matchingEventThread(int matchingId) { - u32 bufLen = 0; - u32 bufAddr = 0; - // Multithreading Lock peerlock.lock(); // Cast Context @@ -4790,6 +4789,8 @@ int matchingEventThread(int matchingId) // Run while needed... if (context != NULL) { + u32 bufLen = context->rxbuflen; //0; + u32 bufAddr = 0; //userMemory.Alloc(bufLen); //static u32_le args[5] = { 0, 0, 0, 0, 0 }; // Need to be global/static so it can be accessed from a different thread u32_le * args = context->handlerArgs; @@ -4867,6 +4868,9 @@ int matchingEventThread(int matchingId) context->eventlock->unlock(); } + // Free memory + //if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); + // Delete Pointer Reference (and notify caller about finished cleanup) //context->eventThread = NULL; } @@ -4874,9 +4878,6 @@ int matchingEventThread(int matchingId) // Log Shutdown INFO_LOG(SCENET, "EventLoop: End of EventLoop[%i] Thread", matchingId); - // Free memory - if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); - // Return Zero to shut up Compiler (never reached anyway) return 0; } diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 829c973ebd..0f30ebe6b8 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -17,6 +17,10 @@ #pragma once +typedef struct MatchingArgs { + u32_le data[6]; //ContextID, Opcode, bufAddr[ to MAC], OptLen, OptAddr[, EntryPoint] +} PACK; + class PointerWrap; void Register_sceNetAdhoc(); @@ -25,7 +29,7 @@ void __NetAdhocInit(); void __NetAdhocShutdown(); void __NetAdhocDoState(PointerWrap &p); void __UpdateAdhocctlHandlers(u32 flags, u32 error); -void __UpdateMatchingHandler(u64 params); +void __UpdateMatchingHandler(MatchingArgs params); // I have to call this from netdialog int sceNetAdhocctlCreate(const char * groupName); From 7858980cbfa01a1526e093bf50f5f59623fd6e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 13:11:11 +0200 Subject: [PATCH 309/848] Buildfix --- Core/Instance.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Core/Instance.cpp b/Core/Instance.cpp index 93d4002492..42cb38fdd5 100644 --- a/Core/Instance.cpp +++ b/Core/Instance.cpp @@ -107,13 +107,15 @@ void InitInstanceCounter() { if ((ftruncate(hIDMapFile, BUF_SIZE)) == -1) { // Set the size ERROR_LOG(SCENET, "ftruncate(%s) failure.", ID_SHM_NAME); - return 1; + PPSSPP_ID = 1; + return; } pIDBuf = (int32_t*)mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hIDMapFile, 0); if (pIDBuf == MAP_FAILED) { // Set the size ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME); pIDBuf = NULL; + PPSSPP_ID = 1; return 1; } @@ -128,7 +130,7 @@ void InitInstanceCounter() { //status = close(hIDMapFile); // Close file, should be called when program exits? //status = shm_unlink(ID_SHM_NAME); // Unlink [& delete] shared-memory object, should be called when program exits - return id; + PPSSPP_ID = id; #endif } From fb0b3b3351955a766c221437210fe6da77378005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 14:09:08 +0200 Subject: [PATCH 310/848] Another buildfix --- Core/Instance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Instance.cpp b/Core/Instance.cpp index 42cb38fdd5..70976427de 100644 --- a/Core/Instance.cpp +++ b/Core/Instance.cpp @@ -116,7 +116,7 @@ void InitInstanceCounter() { ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME); pIDBuf = NULL; PPSSPP_ID = 1; - return 1; + return; } int id = 1; From fb7d50e5c20a6b3dc9eb0f83d84ae17f684620f5 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 24 Dec 2019 00:04:03 +0700 Subject: [PATCH 311/848] Improved multiplayer compatibility on some games (ie. GTA VCS, Naruto Ultimate Ninja Heroes 3, DBZ Shin Budokai 2, Power Stone Collection, .hack//Link, etc) --- Core/HLE/proAdhoc.cpp | 456 +++++++----- Core/HLE/proAdhoc.h | 114 ++- Core/HLE/proAdhocServer.cpp | 72 +- Core/HLE/proAdhocServer.h | 6 +- Core/HLE/sceNet.cpp | 100 ++- Core/HLE/sceNet.h | 18 +- Core/HLE/sceNetAdhoc.cpp | 1309 ++++++++++++++++++++++++----------- Core/HLE/sceNetAdhoc.h | 10 + 8 files changed, 1428 insertions(+), 657 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index c64b50a04e..043ca79e6e 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -27,6 +27,7 @@ #include #include "util/text/parsers.h" +#include "thread/threadutil.h" #include "Core/Core.h" #include "Core/Host.h" #include "Core/HLE/sceKernelInterrupt.h" @@ -46,7 +47,7 @@ SceNetAdhocctlScanInfo * networks = NULL; SceNetAdhocctlScanInfo * newnetworks = NULL; int threadStatus = ADHOCCTL_STATE_DISCONNECTED; -bool IsAdhocctlInCB = false; +int actionAfterAdhocMipsCall; int actionAfterMatchingMipsCall; // Broadcast MAC @@ -59,7 +60,6 @@ std::thread friendFinderThread; std::recursive_mutex peerlock; SceNetAdhocPdpStat * pdp[255]; SceNetAdhocPtpStat * ptp[255]; -uint32_t localip; std::vector chatLog; std::string name = ""; std::string incoming = ""; @@ -67,11 +67,10 @@ std::string message = ""; bool chatScreenVisible = false; bool updateChatScreen = false; int newChat = 0; - bool isLocalServer = false; sockaddr localIP; // This might serves the same purpose with existing "localip" above, but since this is copied from my old code so here it is (too lazy to rewrite the code) -int isLocalMAC(const SceNetEtherAddr * addr) { +bool isLocalMAC(const SceNetEtherAddr * addr) { SceNetEtherAddr saddr; getLocalMac(&saddr); @@ -82,32 +81,59 @@ int isLocalMAC(const SceNetEtherAddr * addr) { return (match == 0); } -int isPDPPortInUse(uint16_t port) { +bool isPDPPortInUse(uint16_t port) { // Iterate Elements - int i = 0; for (; i < 255; i++) if (pdp[i] != NULL && pdp[i]->lport == port) return 1; + for (int i = 0; i < 255; i++) if (pdp[i] != NULL && pdp[i]->lport == port) return true; // Unused Port - return 0; + return false; } -int isPTPPortInUse(uint16_t port) { +bool isPTPPortInUse(uint16_t port) { // Iterate Sockets - int i = 0; for(; i < 255; i++) if(ptp[i] != NULL && ptp[i]->lport == port) return 1; + for(int i = 0; i < 255; i++) if(ptp[i] != NULL && ptp[i]->lport == port) return true; // Unused Port - return 0; + return false; +} + +char* mac2str(SceNetEtherAddr* mac) { + if (mac == NULL) return ":::::"; +#if defined(_WIN32) + static __declspec(thread) char str[18]; +#else + static __thread char str[18]; +#endif + snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]); + + return str; +} + +char* mac2str(SceNetEtherAddr* mac, char* str, size_t size) { + if (mac == NULL || str == NULL || size < 18) return NULL; + + snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]); + + return str; } SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac) { if (context == NULL || mac == NULL) return NULL; SceNetAdhocMatchingMemberInternal * peer = findPeer(context, mac); + // Already existed + if (peer != NULL) { + char tmpmac[18]; + WARN_LOG(SCENET, "Member Peer Already Existed! Updating [%s]", mac2str(mac, tmpmac)); + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + } // Member is not added yet - if (peer == NULL) { + else { peer = (SceNetAdhocMatchingMemberInternal *)malloc(sizeof(SceNetAdhocMatchingMemberInternal)); if (peer != NULL) { memset(peer, 0, sizeof(SceNetAdhocMatchingMemberInternal)); peer->mac = *mac; + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); peer->next = context->peerlist; context->peerlist = peer; } @@ -124,14 +150,15 @@ void addFriend(SceNetAdhocctlConnectPacketS2C * packet) { SceNetAdhocctlPeerInfo * peer = findFriend(&packet->mac); // Already existed if (peer != NULL) { + char tmpmac[18]; + WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", packet->name.data, mac2str(&packet->mac, tmpmac), inet_ntoa(*(in_addr*)&packet->ip)); peer->nickname = packet->name; peer->mac_addr = packet->mac; peer->ip_addr = packet->ip; // Update TimeStamp peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); } - else - { + else { // Allocate Structure peer = (SceNetAdhocctlPeerInfo *)malloc(sizeof(SceNetAdhocctlPeerInfo)); // Allocated Structure @@ -198,7 +225,7 @@ void changeBlockingMode(int fd, int nonblocking) { #endif } -int countAvailableNetworks(void) { +int countAvailableNetworks() { // Network Count int count = 0; @@ -236,11 +263,12 @@ void freeGroupsRecursive(SceNetAdhocctlScanInfo * node) { // Free Memory free(node); + node = NULL; } -void deleteAllPDP(void) { +void deleteAllPDP() { // Iterate Element - int i = 0; for (; i < 255; i++) { + for (int i = 0; i < 255; i++) { // Active Socket if (pdp[i] != NULL) { // Close Socket @@ -255,9 +283,9 @@ void deleteAllPDP(void) { } } -void deleteAllPTP(void) { +void deleteAllPTP() { // Iterate Element - int i = 0; for (; i < 255; i++) { + for (int i = 0; i < 255; i++) { // Active Socket if (ptp[i] != NULL) { // Close Socket @@ -283,36 +311,39 @@ void deleteFriendByIP(uint32_t ip) { for (; peer != NULL; peer = peer->next) { // Found Peer if (peer->ip_addr == ip) { - // Instead of removing it from the list we'll make it timeout since most Matching games are moving group and may still need the peer data - peer->last_recv = 0; - + // Multithreading Lock peerlock.lock(); // Unlink Left (Beginning) - if(prev == NULL)friends = peer->next; + /*if (prev == NULL) friends = peer->next; // Unlink Left (Other) else prev->next = peer->next; + */ + + char tmpmac[18]; + INFO_LOG(SCENET, "Removing Friend Peer %s [%s]", mac2str(&peer->mac_addr, tmpmac), inet_ntoa(*(in_addr*)&peer->ip_addr)); + + // Free Memory + //free(peer); + //peer = NULL; + // Instead of removing it from the list we'll make it timed out since most Matching games are moving group and may still need the peer data thus not recognizing it as Unknown peer + peer->last_recv = 0; //CoreTiming::GetGlobalTimeUsScaled(); // Multithreading Unlock peerlock.unlock(); - // Free Memory - free(peer); - peer = NULL; - // Stop Search break; } // Set Previous Reference - // TODO: Should this be used by something? prev = peer; } } -int findFreeMatchingID(void) { +int findFreeMatchingID() { // Minimum Matching ID int min = 1; @@ -320,13 +351,15 @@ int findFreeMatchingID(void) { int max = 0; // Find highest Matching ID - SceNetAdhocMatchingContext * item = contexts; for (; item != NULL; item = item->next) { + SceNetAdhocMatchingContext * item = contexts; + for (; item != NULL; item = item->next) { // New Maximum if (max < item->id) max = item->id; } // Find unoccupied ID - int i = min; for (; i < max; i++) { + int i = min; + for (; i < max; i++) { // Found unoccupied ID if (findMatchingContext(i) == NULL) return i; } @@ -337,7 +370,8 @@ int findFreeMatchingID(void) { SceNetAdhocMatchingContext * findMatchingContext(int id) { // Iterate Matching Context List - SceNetAdhocMatchingContext * item = contexts; for (; item != NULL; item = item->next) { // Found Matching ID + SceNetAdhocMatchingContext * item = contexts; + for (; item != NULL; item = item->next) { // Found Matching ID if (item->id == id) return item; } @@ -353,7 +387,8 @@ SceNetAdhocMatchingContext * findMatchingContext(int id) { SceNetAdhocMatchingMemberInternal * findOutgoingRequest(SceNetAdhocMatchingContext * context) { // Iterate Peer List for Matching Target - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + for (; peer != NULL; peer = peer->next) { // Found Peer in List if (peer->state == PSP_ADHOC_MATCHING_PEER_OUTGOING_REQUEST) return peer; @@ -369,6 +404,8 @@ SceNetAdhocMatchingMemberInternal * findOutgoingRequest(SceNetAdhocMatchingConte */ void postAcceptCleanPeerList(SceNetAdhocMatchingContext * context) { + int delcount = 0; + int peercount = 0; // Acquire Peer Lock peerlock.lock(); @@ -380,14 +417,20 @@ void postAcceptCleanPeerList(SceNetAdhocMatchingContext * context) SceNetAdhocMatchingMemberInternal * next = peer->next; // Unneeded Peer - if (peer->state != PSP_ADHOC_MATCHING_PEER_CHILD && peer->state != PSP_ADHOC_MATCHING_PEER_P2P && peer->state != PSP_ADHOC_MATCHING_PEER_PARENT) deletePeer(context, peer); + if (peer->state != PSP_ADHOC_MATCHING_PEER_CHILD && peer->state != PSP_ADHOC_MATCHING_PEER_P2P && peer->state != PSP_ADHOC_MATCHING_PEER_PARENT) { + deletePeer(context, peer); + delcount++; + } // Move to Next Peer peer = next; + peercount++; } // Free Peer Lock peerlock.unlock(); + + INFO_LOG(SCENET, "Removing Unneeded Peer (%i/%i)", delcount, peercount); } /** @@ -404,7 +447,7 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun uint8_t * siblings_u8 = (uint8_t *)siblings; // Iterate Siblings - int i = 0; for (; i < siblingcount; i++) + for (int i = 0; i < siblingcount; i++) { // Allocate Memory SceNetAdhocMatchingMemberInternal * sibling = (SceNetAdhocMatchingMemberInternal *)malloc(sizeof(SceNetAdhocMatchingMemberInternal)); @@ -431,7 +474,8 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun // Spawn Established Event spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); - INFO_LOG(SCENET, "Accepting Peer %02X:%02X:%02X:%02X:%02X:%02X", sibling->mac.data[0], sibling->mac.data[1], sibling->mac.data[2], sibling->mac.data[3], sibling->mac.data[4], sibling->mac.data[5]); + char tmpmac[18]; + INFO_LOG(SCENET, "Accepting Peer %s", mac2str(&sibling->mac, tmpmac)); } } } @@ -441,14 +485,17 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun * @param context Matching Context Pointer * @return Number of Children */ -s32_le countChildren(SceNetAdhocMatchingContext * context) +s32_le countChildren(SceNetAdhocMatchingContext * context, const bool excludeTimedout) { // Children Counter s32_le count = 0; // Iterate Peer List for Matching Target - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + for (; peer != NULL; peer = peer->next) { + // Exclude timedout members? + if (!excludeTimedout || peer->lastping != 0) // Increase Children Counter if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) count++; } @@ -466,7 +513,8 @@ s32_le countChildren(SceNetAdhocMatchingContext * context) SceNetAdhocMatchingMemberInternal * findPeer(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac) { // Iterate Peer List for Matching Target - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + for (; peer != NULL; peer = peer->next) { // Found Peer in List if (memcmp(&peer->mac, mac, sizeof(SceNetEtherAddr)) == 0) @@ -488,7 +536,8 @@ SceNetAdhocMatchingMemberInternal * findPeer(SceNetAdhocMatchingContext * contex SceNetAdhocMatchingMemberInternal * findParent(SceNetAdhocMatchingContext * context) { // Iterate Peer List for Matching Target - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + for (; peer != NULL; peer = peer->next) { // Found Peer in List if (peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) return peer; @@ -503,12 +552,14 @@ SceNetAdhocMatchingMemberInternal * findParent(SceNetAdhocMatchingContext * cont * @param context Matching Context Pointer * @return Internal Peer Reference or... NULL */ -SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context) +SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context, const bool excludeTimedout) { // Iterate Peer List for Matching Target SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) { + // Exclude timedout members? + if (!excludeTimedout || peer->lastping != 0) // Found Peer in List if (peer->state == PSP_ADHOC_MATCHING_PEER_P2P) return peer; } @@ -550,7 +601,8 @@ void deletePeer(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingMemberI // Beginning Item else context->peerlist = item->next; - INFO_LOG(SCENET, "Removing Peer %02X:%02X:%02X:%02X:%02X:%02X", peer->mac.data[0], peer->mac.data[1], peer->mac.data[2], peer->mac.data[3], peer->mac.data[4], peer->mac.data[5]); + char tmpmac[18]; + INFO_LOG(SCENET, "Removing Member Peer %s", mac2str(&peer->mac, tmpmac)); } // Free Peer Memory @@ -741,7 +793,7 @@ void sendDeathMessage(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingM * @param context Matching Context Pointer * @return Number of Connected Peers */ -uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context) +uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context, const bool excludeTimedout) { // Peer Count uint32_t count = 0; @@ -750,7 +802,7 @@ uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context) if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { // Number of Children + 1 Parent (Self) - count = countChildren(context) + 1; + count = countChildren(context, excludeTimedout) + 1; } // Child Mode @@ -763,7 +815,7 @@ uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context) if (findParent(context) != NULL) { // Add Number of Siblings + 1 Parents - count += countChildren(context) + 1; + count += countChildren(context, excludeTimedout) + 1; } } @@ -774,7 +826,7 @@ uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context) count = 1; // Connected to another P2P Client - if (findP2P(context) != NULL) + if (findP2P(context, excludeTimedout) != NULL) { // Add P2P Brother count++; @@ -801,31 +853,35 @@ void spawnLocalEvent(SceNetAdhocMatchingContext * context, int event, SceNetEthe /** * Handle Timeouts in Matching Context -* @param context Matchi]ng Context Pointer +* @param context Matching Context Pointer */ void handleTimeout(SceNetAdhocMatchingContext * context) { peerlock.lock(); // Iterate Peer List - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; while (peer != NULL) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + while (peer != NULL && contexts != NULL && coreState != CORE_POWERDOWN) { // Get Next Pointer (to avoid crash on memory freeing) SceNetAdhocMatchingMemberInternal * next = peer->next; u64_le now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0 - // Timeout! + // Timeout!, may be we shouldn't kick timedout members ourself and let the game do it if ((now - peer->lastping) >= context->timeout) { // Spawn Timeout Event if ((context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD || peer->state == PSP_ADHOC_MATCHING_PEER_PARENT)) || (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT && peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) || - (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && peer->state == PSP_ADHOC_MATCHING_PEER_P2P)) - spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); + (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && peer->state == PSP_ADHOC_MATCHING_PEER_P2P)) { + spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); // This is the only code that use PSP_ADHOC_MATCHING_EVENT_TIMEOUT, should we let it timedout? + } - INFO_LOG(SCENET, "TimedOut Peer %02X:%02X:%02X:%02X:%02X:%02X (%lldms)", peer->mac.data[0], peer->mac.data[1], peer->mac.data[2], peer->mac.data[3], peer->mac.data[4], peer->mac.data[5], (context->timeout/1000)); + char tmpmac[18]; + INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac, tmpmac), (context->timeout/1000)); // Delete Peer from List deletePeer(context, peer); + //peer->lastping = 0; //Let's just make the game kick timedout members during sceNetAdhocMatchingGetMembers } // Move Pointer @@ -845,6 +901,7 @@ void clearStackRecursive(ThreadMessage * node) // Free Last Existing Node of List (NULL is handled in _free) free(node); + node = NULL; } /** @@ -901,6 +958,8 @@ void clearPeerList(SceNetAdhocMatchingContext * context) // Delete Peer free(peer); //deletePeer(context, peer); + // Instead of removing peer immediately, We should give a little time before removing the peer and let it timed out? just in case the game is in the middle of communicating with the peer on another thread so it won't recognize it as Unknown peer + //peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); // Move Pointer peer = context->peerlist; //peer = next; @@ -910,36 +969,23 @@ void clearPeerList(SceNetAdhocMatchingContext * context) peerlock.unlock(); } -bool IsMatchingInCallback(SceNetAdhocMatchingContext * context) { - bool inCB = false; - if (context == NULL) return inCB; - context->eventlock->lock(); //peerlock.lock(); - inCB = (/*context != NULL &&*/ context->IsMatchingInCB); - context->eventlock->unlock(); //peerlock.unlock(); - return inCB; -} - +// It seems After Actions being called in reverse order of Mipscall order (ie. MipsCall order of ACCEPT(6)->ESTABLISH(7) getting AfterAction order of ESTABLISH(7)->ACCEPT(6) void AfterMatchingMipsCall::run(MipsCall &call) { - if (!context || !context->eventlock) - return; - - DEBUG_LOG(SCENET, "Entering AfterMatchingMipsCall::run [ID=%i][Event=%d] [cbId: %u]", context->id, EventID, call.cbId); - //u32 v0 = currentMIPS->r[MIPS_REG_V0]; - if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", context->id, EventID); - //while (__IsInInterrupt()) sleep_ms(1); // Must not sleep inside callback handler - context->eventlock->lock(); //peerlock.lock(); - //SceNetAdhocMatchingContext * context = findMatchingContext(ID); - //if (context != NULL) - { - context->IsMatchingInCB = false; + if (context == NULL) { + peerlock.lock(); + context = findMatchingContext(contextID); + peerlock.unlock(); } - context->eventlock->unlock(); //peerlock.unlock(); - //call.setReturnValue(v0); + u32 v0 = currentMIPS->r[MIPS_REG_V0]; + if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", contextID, EventID); if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); - DEBUG_LOG(SCENET, "Leaving AfterMatchingMipsCall::run [ID=%i][Event=%d] [retV0: %08x]", context->id, EventID, currentMIPS->r[MIPS_REG_V0]); + SetMatchingInCallback(context, false); + DEBUG_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] [cbId: %u][retV0: %08x]", contextID, EventID, call.cbId, v0); + //call.setReturnValue(v0); } -void AfterMatchingMipsCall::SetContextID(u32 ContextID, u32 eventId, u32_le BufAddr) { +void AfterMatchingMipsCall::SetData(int ContextID, int eventId, u32_le BufAddr) { + contextID = ContextID; EventID = eventId; bufAddr = BufAddr; peerlock.lock(); @@ -947,61 +993,100 @@ void AfterMatchingMipsCall::SetContextID(u32 ContextID, u32 eventId, u32_le BufA peerlock.unlock(); } +bool SetMatchingInCallback(SceNetAdhocMatchingContext* context, bool IsInCB) { + if (context == NULL) return false; + context->eventlock->lock(); //peerlock.lock(); + context->IsMatchingInCB = IsInCB; + context->eventlock->unlock(); //peerlock.unlock(); + return IsInCB; +} + +bool IsMatchingInCallback(SceNetAdhocMatchingContext* context) { + bool inCB = false; + if (context == NULL) return inCB; + context->eventlock->lock(); //peerlock.lock(); + inCB = (context->IsMatchingInCB); + context->eventlock->unlock(); //peerlock.unlock(); + return inCB; +} + +void AfterAdhocMipsCall::run(MipsCall& call) { + u32 v0 = currentMIPS->r[MIPS_REG_V0]; + if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterAdhocMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", HandlerID, EventID); + SetAdhocctlInCallback(false); + DEBUG_LOG(SCENET, "AfterAdhocMipsCall::run [ID=%i][Event=%d] [cbId: %u][retV0: %08x]", HandlerID, EventID, call.cbId, v0); + //call.setReturnValue(v0); +} + +void AfterAdhocMipsCall::SetData(int handlerID, int eventId, u32_le ArgsAddr) { + HandlerID = handlerID; + EventID = eventId; + argsAddr = ArgsAddr; +} + +int SetAdhocctlInCallback(bool IsInCB) { + std::lock_guard adhocGuard(adhocEvtMtx); + IsAdhocctlInCB += (IsInCB?1:-1); + return IsAdhocctlInCB; +} + +int IsAdhocctlInCallback() { + std::lock_guard adhocGuard(adhocEvtMtx); + int inCB = IsAdhocctlInCB; + return inCB; +} + // Make sure MIPS calls have been fully executed before the next notifyAdhocctlHandlers void notifyAdhocctlHandlers(u32 flag, u32 error) { __UpdateAdhocctlHandlers(flag, error); - // TODO: We should use after action instead of guessing the time like this - //sleep_ms(20); // Ugly workaround to give time for the mips callback to fully executed, usually only need <16ms } // Matching callback is void function: typedef void(*SceNetAdhocMatchingHandler)(int id, int event, SceNetEtherAddr * peer, int optlen, void * opt); // Important! The MIPS call need to be fully executed before the next MIPS call invoked, as the game (ie. DBZ Tag Team) may need to prepare something for the next callback event to use // Note: Must not lock peerlock within this function to prevent race-condition with other thread whos owning peerlock and trying to lock context->eventlock owned by this thread -void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32 &bufAddr, u32 &bufLen, u32_le * args) { - //u32_le args[5] = { 0, 0, 0, 0, 0 }; - /*if ((s32)bufLen < (msg->optlen + 8)) { - bufLen = msg->optlen + 8; - if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); - bufAddr = userMemory.Alloc(bufLen); // Max bufLen should be context->rxbuflen - INFO_LOG(SCENET, "MatchingHandler: Alloc(%i -> %i) = %08x", msg->optlen + 8, bufLen, bufAddr); - }*/ +void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32_le &bufAddr, u32_le &bufLen, u32_le * args) { + // Don't share buffer address space with other mipscall in the queue since mipscalls aren't immediately executed MatchingArgs argsNew; - bufAddr = userMemory.Alloc(bufLen); // We will free this after returning from mipscall - u8 * optPtr = Memory::GetPointer(bufAddr); - memcpy(optPtr, &msg->mac, sizeof(msg->mac)); - if (msg->optlen > 0) memcpy(optPtr + 8, opt, msg->optlen); + u32_le dataBufLen = msg->optlen + 8; //max(bufLen, msg->optlen + 8); + u32_le dataBufAddr = userMemory.Alloc(dataBufLen); // We will free this memory after returning from mipscall + uint8_t * dataPtr = Memory::GetPointer(dataBufAddr); + memcpy(dataPtr, &msg->mac, sizeof(msg->mac)); + if (msg->optlen > 0) + memcpy(dataPtr + 8, opt, msg->optlen); argsNew.data[0] = context->id; argsNew.data[1] = msg->opcode; - argsNew.data[2] = bufAddr; // PSP_GetScratchpadMemoryBase() + 0x6000; + argsNew.data[2] = dataBufAddr; argsNew.data[3] = msg->optlen; - argsNew.data[4] = argsNew.data[2] + 8; // OptData Addr + argsNew.data[4] = dataBufAddr + 8; // OptData Addr argsNew.data[5] = context->handler.entryPoint; //not part of callback argument, just borrowing a space to store callback address so i don't need to search the context first later - context->eventlock->lock(); - context->IsMatchingInCB = true; - context->eventlock->unlock(); // ScheduleEvent_Threadsafe_Immediate seems to get mixed up with interrupt (returning from mipscall inside an interrupt) and getting invalid address before returning from interrupt __UpdateMatchingHandler(argsNew); - - // Make sure MIPS call have been fully executed before the next notifyMatchingHandler - /*int count = 0; - while ( IsMatchingInCallback(context) && (count < 250)) { - sleep_ms(1); - count++; - } - if (count >= 250) ERROR_LOG(SCENET, "MatchingHandler: Callback Failed to Return within %dms! [ID=%i][Opcode=%d][OptSize=%d][MAC=%012X]", count, context->id, msg->opcode, msg->optlen, htonl(*(u_long*)&msg->mac));*/ - //sleep_ms(20); // Wait a little more (for context switching may be?) to prevent DBZ Tag Team from getting connection lost, but this will cause lags on Lord of Arcana } -void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node) { +void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count) { // End of List if (node == NULL) return; // Increase Recursion Depth - freeFriendsRecursive(node->next); + freeFriendsRecursive(node->next, count); // Free Memory free(node); + node = NULL; + if (count != NULL) (*count)++; +} + +void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo* node, int32_t* count) { + // End of List + if (node == NULL) return; + + // Increase Recursion Depth + timeoutFriendsRecursive(node->next, count); + + // Set last timestamp + node->last_recv = 0; + if (count != NULL) (*count)++; } void sendChat(std::string chatString) { @@ -1044,6 +1129,7 @@ std::vector getChatLog() { } int friendFinder(){ + setCurrentThreadName("FriendFinder"); // Receive Buffer int rxpos = 0; uint8_t rx[1024]; @@ -1069,7 +1155,7 @@ int friendFinder(){ //_acquireNetworkLock(); // Ping Server - now = real_time_now()*1000000.0; // should be in microseconds, but it seems real_time_now() returns in seconds + now = real_time_now() * 1000000.0; // CoreTiming::GetGlobalTimeUsScaled(); // Use real_time_now()*1000000.0 if the game gets disconnected from AdhocServer too fast when FPS wasn't stable if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { //100 // We need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet // original code : ((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT) // Update Ping Time @@ -1106,18 +1192,33 @@ int friendFinder(){ if (rxpos > 0) { // BSSID Packet if (rx[0] == OPCODE_CONNECT_BSSID) { - INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID"); // Enough Data available if (rxpos >= (int)sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) { // Cast Packet SceNetAdhocctlConnectBSSIDPacketS2C * packet = (SceNetAdhocctlConnectBSSIDPacketS2C *)rx; - // Update BSSID - parameter.bssid.mac_addr = packet->mac; + + char tmpmac[18]; + INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac, tmpmac)); + // from JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?) + /*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { + setState(ADHOCCTL_STATE_GAMEMODE); + notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0); + } + else { + setState(ADHOCCTL_STATE_CONNECTED); + notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); + }*/ + + // Update User BSSID + //parameter.bssid.mac_addr = packet->mac; // The MAC address in this packet seems to Always be the First player joining the Group (group Creator?), Shouldn't it be it self? + // Notify Event Handlers + //notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); // Change State threadStatus = ADHOCCTL_STATE_CONNECTED; - // Notify Event Handlers - notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); - + // Give time a little time + //sceKernelDelayThread(adhocEventDelayMS * 1000); + //sleep_ms(adhocEventDelayMS); + // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)); @@ -1128,11 +1229,16 @@ int friendFinder(){ // Chat Packet else if (rx[0] == OPCODE_CHAT) { - INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CHAT"); // Enough Data available if (rxpos >= (int)sizeof(SceNetAdhocctlChatPacketS2C)) { // Cast Packet SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx; + INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CHAT"); + + // Fix strings with null-terminated + packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; + packet->base.message[ADHOCCTL_MESSAGE_LEN - 1] = 0; + // Add Incoming Chat to HUD NOTICE_LOG(SCENET, "Received chat message %s", packet->base.message); incoming = ""; @@ -1150,6 +1256,7 @@ int friendFinder(){ newChat += 1; } } + // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C)); @@ -1160,17 +1267,28 @@ int friendFinder(){ // Connect Packet else if (rx[0] == OPCODE_CONNECT) { - DEBUG_LOG(SCENET, "FriendFinder: OPCODE_CONNECT"); // Enough Data available if (rxpos >= (int)sizeof(SceNetAdhocctlConnectPacketS2C)) { - // Log Incoming Peer - INFO_LOG(SCENET, "Incoming Peer Data..."); - // Cast Packet SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx; + DEBUG_LOG(SCENET, "FriendFinder: OPCODE_CONNECT"); + + // Fix strings with null-terminated + packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; + + // Log Incoming Peer + INFO_LOG(SCENET, "Incoming Peer Data..."); + // Add User addFriend(packet); + + /* // Make sure GameMode participants are all joined (including self MAC) + if (adhocctlCurrentMode == PSP_ADHOCCTL_MODE_GAMEMODE) { + // From JPCSP: Join complete when all the required MACs have joined + }*/ + + // Update HUD User Count incoming = ""; incoming.append((char *)packet->name.data); incoming.append(" Joined "); @@ -1181,7 +1299,7 @@ int friendFinder(){ if (chatScreenVisible) { updateChatScreen = true; } - // Update HUD User Count + #ifdef LOCALHOST_AS_PEER setUserCount(getActivePeerCount()); #else @@ -1198,15 +1316,16 @@ int friendFinder(){ // Disconnect Packet else if (rx[0] == OPCODE_DISCONNECT) { - DEBUG_LOG(SCENET, "FriendFinder: OPCODE_DISCONNECT"); // Enough Data available if (rxpos >= (int)sizeof(SceNetAdhocctlDisconnectPacketS2C)) { - // Log Incoming Peer Delete Request - INFO_LOG(SCENET, "FriendFinder: Incoming Peer Data Delete Request..."); - // Cast Packet SceNetAdhocctlDisconnectPacketS2C * packet = (SceNetAdhocctlDisconnectPacketS2C *)rx; + DEBUG_LOG(SCENET, "FriendFinder: OPCODE_DISCONNECT"); + + // Log Incoming Peer Delete Request + INFO_LOG(SCENET, "FriendFinder: Incoming Peer Data Delete Request..."); + // Delete User by IP, should delete by MAC since IP can be shared (behind NAT) isn't? deleteFriendByIP(packet->ip); @@ -1227,14 +1346,16 @@ int friendFinder(){ // Scan Packet else if (rx[0] == OPCODE_SCAN) { - DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN"); // Enough Data available if (rxpos >= (int)sizeof(SceNetAdhocctlScanPacketS2C)) { - // Log Incoming Network Information - INFO_LOG(SCENET, "Incoming Group Information..."); // Cast Packet SceNetAdhocctlScanPacketS2C * packet = (SceNetAdhocctlScanPacketS2C *)rx; + DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN"); + + // Log Incoming Network Information + INFO_LOG(SCENET, "Incoming Group Information..."); + // Multithreading Lock peerlock.lock(); @@ -1242,20 +1363,17 @@ int friendFinder(){ SceNetAdhocctlScanInfo * group = findGroup(&packet->mac); if (group != NULL) { - // Copy Group Name - group->group_name = packet->group; + // Copy Group Name + group->group_name = packet->group; - // Set Group Host - group->bssid.mac_addr = packet->mac; - } - else - { + // Set Group Host + group->bssid.mac_addr = packet->mac; + } else { // Allocate Structure Data SceNetAdhocctlScanInfo * group = (SceNetAdhocctlScanInfo *)malloc(sizeof(SceNetAdhocctlScanInfo)); // Allocated Structure Data - if (group != NULL) - { + if (group != NULL) { // Clear Memory, should this be done only when allocating new group? memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); @@ -1268,6 +1386,10 @@ int friendFinder(){ // Set Group Host group->bssid.mac_addr = packet->mac; + // Set group parameters + group->channel = parameter.channel; + group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode; + // Link into Group List newnetworks = group; } @@ -1297,16 +1419,18 @@ int friendFinder(){ newnetworks = NULL; peerlock.unlock(); - // Change State - threadStatus = ADHOCCTL_STATE_DISCONNECTED; - // Notify Event Handlers - notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); + //notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) //{ // // Active Handler // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); //} + // Change State + threadStatus = ADHOCCTL_STATE_DISCONNECTED; + // Give time a little time + //sceKernelDelayThread(adhocEventDelayMS * 1000); + //sleep_ms(adhocEventDelayMS); // Move RX Buffer memmove(rx, rx + 1, sizeof(rx) - 1); @@ -1315,11 +1439,11 @@ int friendFinder(){ rxpos -= 1; } } - // Original value was 10 ms, I think 100 is just fine - sleep_ms(1); // Using 1ms for faster response just like AdhocServer + // This delay time should be 100ms when there is an event otherwise 500ms ? + sleep_ms(1); // Using 1ms for faster response just like AdhocServer? // Don't do anything if it's paused, otherwise the log will be flooded - while (Core_IsStepping() && friendFinderRunning) sleep_ms(1); + while (Core_IsStepping() && coreState != CORE_POWERDOWN && friendFinderRunning) sleep_ms(1); } // Groups/Networks should be deallocated isn't? @@ -1334,7 +1458,7 @@ int friendFinder(){ return 0; } -int getActivePeerCount(void) { +int getActivePeerCount(const bool excludeTimedout) { // Counter int count = 0; @@ -1348,8 +1472,9 @@ int getActivePeerCount(void) { // Iterate Peers for (; peer != NULL; peer = peer->next) { - // Increase Counter - count++; + // Increase Counter, Should we exclude peers pending for timed out? + if (!excludeTimedout || peer->last_recv != 0) + count++; } // Return Result @@ -1365,7 +1490,7 @@ int getLocalIp(sockaddr_in * SocketAddress){ // Error handling } // Get local IP addresses - struct hostent *pHost = 0; + struct hostent *pHost = 0; pHost = ::gethostbyname(szHostName); if(pHost) { memcpy(&SocketAddress->sin_addr, pHost->h_addr_list[0], pHost->h_length); @@ -1376,7 +1501,6 @@ int getLocalIp(sockaddr_in * SocketAddress){ } return -1; #else - memcpy(&SocketAddress->sin_addr, &localip, sizeof(uint32_t)); char szHostName[256] = ""; gethostname(szHostName, sizeof(szHostName)); struct hostent* pHost = 0; @@ -1388,8 +1512,7 @@ int getLocalIp(sockaddr_in * SocketAddress){ } return 0; } - //return -1; - return 0; + return -1; #endif } @@ -1468,36 +1591,37 @@ int getNicknameCount(const char * nickname) * PDP Socket Counter * @return Number of internal PDP Sockets */ -int getPDPSocketCount(void) +int getPDPSocketCount() { // Socket Counter int counter = 0; // Count Sockets - int i = 0; for (; i < 255; i++) if (pdp[i] != NULL) counter++; + for (int i = 0; i < 255; i++) if (pdp[i] != NULL) counter++; // Return Socket Count return counter; } -int getPTPSocketCount(void) { +int getPTPSocketCount() { // Socket Counter int counter = 0; // Count Sockets - int i = 0; for (; i < 255; i++) if (ptp[i] != NULL) counter++; + for (int i = 0; i < 255; i++) if (ptp[i] != NULL) counter++; // Return Socket Count return counter; } int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ + auto n = GetI18NCategory("Networking"); int iResult = 0; metasocket = (int)INVALID_SOCKET; metasocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (metasocket == INVALID_SOCKET){ ERROR_LOG(SCENET, "Invalid socket"); - return -1; + return SOCKET_ERROR; } struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; @@ -1512,7 +1636,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ iResult = getaddrinfo(g_Config.proAdhocServer.c_str(),0,NULL,&resultAddr); if (iResult != 0) { ERROR_LOG(SCENET, "DNS Error (%s)\n", g_Config.proAdhocServer.c_str()); - host->NotifyUserMessage("DNS Error connecting to " + g_Config.proAdhocServer, 8.0f); + host->NotifyUserMessage(n->T("DNS Error connecting to ") + g_Config.proAdhocServer, 5.0f, 0x0000ff); return iResult; } for (ptr = resultAddr; ptr != NULL; ptr = ptr->ai_next) { @@ -1537,26 +1661,31 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ iResult = bind(metasocket, (struct sockaddr*) & localIP, sizeof(sockaddr)); if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "Bind to alternate localhost[%s] failed(%i).", inet_ntoa(((struct sockaddr_in*) & localIP)->sin_addr), iResult); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Localhost IP")) + " " + inet_ntoa(((struct sockaddr_in*) & localIP)->sin_addr), 3.0, 0x0000ff); } } + // Default/Initial Network memset(¶meter, 0, sizeof(parameter)); strcpy((char *)¶meter.nickname.data, g_Config.sNickName.c_str()); - parameter.channel = 1; // Fake Channel 1 + parameter.channel = g_Config.iWlanAdhocChannel; // Fake Channel, 0 = Auto where JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11) + if (parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) parameter.channel = 1; getLocalMac(¶meter.bssid.mac_addr); + + // Default ProductId + product_code.type = adhoc_id->type; + memcpy(product_code.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); + // Connect to Adhoc Server server_addr.sin_addr = serverIp; iResult = connect(metasocket,(sockaddr *)&server_addr,sizeof(server_addr)); if (iResult == SOCKET_ERROR) { - uint8_t * sip = (uint8_t *)&server_addr.sin_addr.s_addr; char buffer[512]; - snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to %s/%u.%u.%u.%u:%u", errno, g_Config.proAdhocServer.c_str(), sip[0], sip[1], sip[2], sip[3], ntohs(server_addr.sin_port)); + snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errno, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); ERROR_LOG(SCENET, "%s", buffer); - host->NotifyUserMessage(buffer, 8.0f); + host->NotifyUserMessage(buffer, 5.0f, 0x0000ff); return iResult; } - //grab local ip for later use better than constant ip on non windows platform - localip = getLocalIp(metasocket); // Prepare Login Packet SceNetAdhocctlLoginPacketC2S packet; @@ -1569,12 +1698,11 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ int sent = send(metasocket, (char*)&packet, sizeof(packet), 0); changeBlockingMode(metasocket, 1); // Change to non-blocking if (sent > 0) { - auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(n->T("Network Initialized"), 1.0); return 0; } else{ - return -1; + return SOCKET_ERROR; } } @@ -1665,7 +1793,7 @@ bool validNetworkName(const SceNetAdhocctlGroupName * group_name) { // Name given if (group_name != NULL) { // Iterate Name Characters - int i = 0; for (; i < ADHOCCTL_GROUPNAME_LEN && valid; i++) { + for (int i = 0; i < ADHOCCTL_GROUPNAME_LEN && valid; i++) { // End of Name if (group_name->data[i] == 0) break; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index fe370c23e3..e4bae1266f 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -27,6 +27,7 @@ #include "Core/CoreTiming.h" #include "Core/MemMap.h" #include "Core/HLE/HLE.h" +#include "Core/HLE/HLEHelperThread.h" #include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernel.h" @@ -73,7 +74,7 @@ class PointerWrap; #define EINPROGRESS WSAEWOULDBLOCK #define EISCONN WSAEISCONN #define EALREADY WSAEALREADY -inline bool connectInProgress(int errcode){ return (errcode == WSAEWOULDBLOCK || errcode == WSAEINVAL || errcode == WSAEALREADY); } +inline bool connectInProgress(int errcode){ return (errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS || errcode == WSAEALREADY); } #else #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 @@ -101,19 +102,32 @@ inline bool connectInProgress(int errcode){ return (errcode == EINPROGRESS || er #define SERVER_PORT 27312 // psp strutcs and definitions -#define ADHOCCTL_MODE_ADHOC 0 +#define ADHOCCTL_MODE_NONE -1 +#define ADHOCCTL_MODE_ADHOC 0 //ADHOCCTL_MODE_NORMAL #define ADHOCCTL_MODE_GAMEMODE 1 // Event Types for Event Handler +#define ADHOCCTL_EVENT_ERROR 0 #define ADHOCCTL_EVENT_CONNECT 1 #define ADHOCCTL_EVENT_DISCONNECT 2 #define ADHOCCTL_EVENT_SCAN 3 +#define ADHOCCTL_EVENT_GAME 4 +#define ADHOCCTL_EVENT_DISCOVER 5 +#define ADHOCCTL_EVENT_WOL 6 +#define ADHOCCTL_EVENT_WOL_INTERRUPT 7 // Internal Thread States #define ADHOCCTL_STATE_DISCONNECTED 0 #define ADHOCCTL_STATE_CONNECTED 1 #define ADHOCCTL_STATE_SCANNING 2 #define ADHOCCTL_STATE_GAMEMODE 3 +#define ADHOCCTL_STATE_DISCOVER 4 +#define ADHOCCTL_STATE_WOL 5 + +// ProductType ( extracted from SSID along with ProductId & GroupName, Pattern = "PSP_([AXS])(.........)_([LG])_(.*)" ) +#define PSP_ADHOCCTL_TYPE_COMMERCIAL 0 +#define PSP_ADHOCCTL_TYPE_DEBUG 1 +#define PSP_ADHOCCTL_TYPE_SYSTEM 2 // Kernel Utility Netconf Adhoc Types #define UTILITY_NETCONF_TYPE_CONNECT_ADHOC 2 @@ -186,8 +200,8 @@ extern uint8_t broadcastMAC[ETHER_ADDR_LEN]; // Malloc Pool Information typedef struct SceNetMallocStat { - s32_le pool; // Pointer to the pool? - s32_le maximum; // Maximum size of the pool? + s32_le pool; // Pointer to the pool? // This should be the poolSize isn't? + s32_le maximum; // Maximum size of the pool? Maximum usage (ie. pool- free) ? s32_le free; // How much memory is free } PACK SceNetMallocStat; @@ -321,9 +335,6 @@ typedef struct SceNetAdhocGameModeBufferStat { u32_le master; SceNetAdhocGameModeOptData opt; } PACK SceNetAdhocGameModeBufferStat; -#ifdef _MSC_VER -#pragma pack(pop) -#endif // Adhoc ID (Game Product Key) #define ADHOCCTL_ADHOCID_LEN 9 @@ -331,7 +342,11 @@ typedef struct SceNetAdhocctlAdhocId { s32_le type; uint8_t data[ADHOCCTL_ADHOCID_LEN]; uint8_t padding[3]; -} SceNetAdhocctlAdhocId; // should this be packed? +} PACK SceNetAdhocctlAdhocId; // should this be packed? +#ifdef _MSC_VER +#pragma pack(pop) +#endif + // Internal Matching Peer Information typedef struct SceNetAdhocMatchingMemberInternal { @@ -459,8 +474,8 @@ typedef struct SceNetAdhocMatchingContext { u64_le timeout; // Helper Thread (fake PSP Thread) needed to execute callback - //HLEHelperThread *matchingThread; - //SceUID matching_thid; + HLEHelperThread *matchingThread; + SceUID matching_thid; // Event Caller Thread std::thread eventThread; // s32_le event_thid; @@ -704,10 +719,11 @@ typedef struct { SceNetAdhocctlGroupName group; } PACK SceNetAdhocctlConnectPacketC2S; +#define ADHOCCTL_MESSAGE_LEN 64 // C2S Chat Packet typedef struct { SceNetAdhocctlPacketBase base; - char message[64]; + char message[ADHOCCTL_MESSAGE_LEN]; } PACK SceNetAdhocctlChatPacketC2S; // S2C Connect Packet @@ -763,30 +779,56 @@ typedef struct { #pragma pack(pop) #endif +class AfterAdhocMipsCall : public PSPAction { +public: + AfterAdhocMipsCall() {} + static PSPAction* Create() { return new AfterAdhocMipsCall(); } + void DoState(PointerWrap& p) override { + auto s = p.Section("AfterAdhocMipsCall", 4, 4); + if (!s) + return; + + p.Do(HandlerID); + p.Do(EventID); + p.Do(argsAddr); + } + void run(MipsCall& call) override; + void SetData(int handlerID, int eventId, u32_le argsAddr); + +private: + int HandlerID = -1; + int EventID = -1; + u32_le argsAddr = 0; +}; + class AfterMatchingMipsCall : public PSPAction { public: AfterMatchingMipsCall() {} static PSPAction *Create() { return new AfterMatchingMipsCall(); } void DoState(PointerWrap &p) override { - auto s = p.Section("AfterMatchingMipsCall", 1, 2); + auto s = p.Section("AfterMatchingMipsCall", 1, 4); if (!s) return; p.Do(EventID); + if (s >= 4) { + p.Do(contextID); + p.Do(bufAddr); + } //context = NULL; } void run(MipsCall &call) override; - void SetContextID(u32 ContextID, u32 eventId, u32_le BufAddr); - void SetContext(SceNetAdhocMatchingContext* Context, u32 eventId, u32_le BufAddr) { context = Context; EventID = eventId; bufAddr = BufAddr; } + void SetData(int ContextID, int eventId, u32_le BufAddr); private: - u32 EventID = 0; - SceNetAdhocMatchingContext *context = nullptr; + int contextID = -1; + int EventID = -1; u32_le bufAddr = 0; + SceNetAdhocMatchingContext* context = nullptr; }; +extern int actionAfterAdhocMipsCall; extern int actionAfterMatchingMipsCall; -extern bool IsAdhocctlInCB; // Aux vars extern int metasocket; @@ -796,7 +838,6 @@ extern std::thread friendFinderThread; extern std::recursive_mutex peerlock; extern SceNetAdhocPdpStat * pdp[255]; extern SceNetAdhocPtpStat * ptp[255]; -extern std::map adhocctlHandlers; extern uint16_t portOffset; extern bool isLocalServer; @@ -812,27 +853,34 @@ extern int threadStatus; // Check if Matching callback is running bool IsMatchingInCallback(SceNetAdhocMatchingContext * context); +bool SetMatchingInCallback(SceNetAdhocMatchingContext* context, bool IsInCB); + +int IsAdhocctlInCallback(); +int SetAdhocctlInCallback(bool IsInCB); /** * Local MAC Check * @param saddr To-be-checked MAC Address * @return 1 if valid or... 0 */ -int isLocalMAC(const SceNetEtherAddr * addr); +bool isLocalMAC(const SceNetEtherAddr * addr); /** * PDP Port Check * @param port To-be-checked Port * @return 1 if in use or... 0 */ -int isPDPPortInUse(uint16_t port); +bool isPDPPortInUse(uint16_t port); /** * Check whether PTP Port is in use or not * @param port To-be-checked Port Number * @return 1 if in use or... 0 */ -int isPTPPortInUse(uint16_t port); +bool isPTPPortInUse(uint16_t port); + +char* mac2str(SceNetEtherAddr* mac); +char* mac2str(SceNetEtherAddr* mac, char* str, size_t size = 18); /* * Matching Members @@ -890,12 +938,12 @@ void freeGroupsRecursive(SceNetAdhocctlScanInfo * node); /** * Closes & Deletes all PDP Sockets */ -void deleteAllPDP(void); +void deleteAllPDP(); /** * Closes & Deletes all PTP sockets */ -void deleteAllPTP(void); +void deleteAllPTP(); /** * Delete Friend from Local List @@ -907,7 +955,9 @@ void deleteFriendByIP(uint32_t ip); * Recursive Memory Freeing-Helper for Friend-Structures * @param node Current Node in List */ -void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node); +void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count); + +void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo* node, int32_t* count); /** * Friend Finder Thread (Receives Peer Information) @@ -921,7 +971,7 @@ int friendFinder(); * Find Free Matching ID * @return First unoccupied Matching ID */ -int findFreeMatchingID(void); +int findFreeMatchingID(); /** * Find Internal Matching Context for Matching ID @@ -933,7 +983,7 @@ SceNetAdhocMatchingContext * findMatchingContext(int id); /* * Notify Matching Event Handler */ -void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32 &bufAddr, u32 &bufLen, u32_le * args); +void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32_le &bufAddr, u32_le &bufLen, u32_le * args); // Notifiy Adhocctl Handlers void notifyAdhocctlHandlers(u32 flag, u32 error); @@ -1030,7 +1080,7 @@ void sendDeathMessage(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingM * @param context Matching Context Pointer * @return Number of Children */ -s32_le countChildren(SceNetAdhocMatchingContext * context); +s32_le countChildren(SceNetAdhocMatchingContext * context, const bool excludeTimedout = false); /** * Delete Peer from List @@ -1059,14 +1109,14 @@ SceNetAdhocMatchingMemberInternal * findParent(SceNetAdhocMatchingContext * cont * @param context Matching Context Pointer * @return Internal Peer Reference or... NULL */ -SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context); +SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context, const bool excludeTimedout = false); /** * Return Number of Connected Peers * @param context Matching Context Pointer * @return Number of Connected Peers */ -uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context); +uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context, const bool excludeTimedout = false); /** * Spawn Local Event for Event Thread @@ -1093,7 +1143,7 @@ void spawnLocalEvent(SceNetAdhocMatchingContext * context, int event, SceNetEthe * Return Number of active Peers in the same Network as the Local Player * @return Number of active Peers */ -int getActivePeerCount(void); +int getActivePeerCount(const bool excludeTimedout = true); /** * Returns the locall Ip of this machine, TODO: Implement the linux version @@ -1152,13 +1202,13 @@ uint16_t getLocalPort(int sock); * PDP Socket Counter * @return Number of internal PDP Sockets */ -int getPDPSocketCount(void); +int getPDPSocketCount(); /** * PTP Socket Counter * @return Number of internal PTP Sockets */ -int getPTPSocketCount(void); +int getPTPSocketCount(); /** * Initialize Networking Components for Adhocctl Emulator diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 54eeefd09f..f509ba59ad 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -42,9 +42,12 @@ #include #include //#include +#include "thread/threadutil.h" #include "Common/FileUtil.h" #include "Core/Core.h" +#include "Core/Host.h" #include "Core/HLE/proAdhocServer.h" +#include "i18n/i18n.h" // User Count @@ -497,8 +500,7 @@ void login_user_stream(int fd, uint32_t ip) while(u != NULL && u->resolver.ip != ip) u = u->next; if (u != NULL) { // IP Already existed - uint8_t * ip4 = (uint8_t *)&u->resolver.ip; - WARN_LOG(SCENET, "AdhocServer: Already Existing IP: %u.%u.%u.%u\n", ip4[0], ip4[1], ip4[2], ip4[3]); + WARN_LOG(SCENET, "AdhocServer: Already Existing IP: %s\n", inet_ntoa(*(in_addr*)&u->resolver.ip)); } // Unique IP Address @@ -528,8 +530,7 @@ void login_user_stream(int fd, uint32_t ip) user->last_recv = time(NULL); // Notify User - uint8_t * ipa = (uint8_t *)&user->resolver.ip; - INFO_LOG(SCENET, "AdhocServer: New Connection from %u.%u.%u.%u", ipa[0], ipa[1], ipa[2], ipa[3]); + INFO_LOG(SCENET, "AdhocServer: New Connection from %s", inet_ntoa(*(in_addr*)&user->resolver.ip)); // Fix User Counter _db_user_count++; @@ -572,8 +573,7 @@ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S while (u != NULL && !IsMatch(u->resolver.mac, data->mac)) u = u->next; if (u != NULL) { // MAC Already existed - uint8_t* ip4 = (uint8_t*)&u->resolver.ip; - WARN_LOG(SCENET, "AdhocServer: Already Existing MAC: %02X:%02X:%02X:%02X:%02X:%02X [%u.%u.%u.%u]\n", data->mac.data[0], data->mac.data[1], data->mac.data[2], data->mac.data[3], data->mac.data[4], data->mac.data[5], ip4[0], ip4[1], ip4[2], ip4[3]); + WARN_LOG(SCENET, "AdhocServer: Already Existing MAC: %02x:%02x:%02x:%02x:%02x:%02x [%s]\n", data->mac.data[0], data->mac.data[1], data->mac.data[2], data->mac.data[3], data->mac.data[4], data->mac.data[5], inet_ntoa(*(in_addr*)&u->resolver.ip)); } // Game Product Override @@ -621,11 +621,10 @@ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S user->game = game; // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, game->game.data, PRODUCT_CODE_LENGTH); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) started playing %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); + INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) started playing %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr); // Update Status Log update_status(); @@ -639,8 +638,7 @@ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; - WARN_LOG(SCENET, "AdhocServer: Invalid Login Packet Contents from %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + WARN_LOG(SCENET, "AdhocServer: Invalid Login Packet Contents from %s", inet_ntoa(*(in_addr*)&user->resolver.ip)); } // Logout User - Out of Memory or Invalid Arguments @@ -672,11 +670,10 @@ void logout_user(SceNetAdhocctlUserNode * user) if(user->game != NULL) { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) stopped playing %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); + INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) stopped playing %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr); // Fix Game Player Count user->game->playercount--; @@ -702,8 +699,7 @@ void logout_user(SceNetAdhocctlUserNode * user) else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; - WARN_LOG(SCENET, "AdhocServer: Dropped Connection to %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + WARN_LOG(SCENET, "AdhocServer: Dropped Connection to %s", inet_ntoa(*(in_addr*)&user->resolver.ip)); } // Free Memory @@ -719,7 +715,7 @@ void logout_user(SceNetAdhocctlUserNode * user) /** * Free Database Memory */ -void free_database(void) +void free_database() { // There are users playing if(_db_user_count > 0) @@ -885,14 +881,13 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: connect_user[send user bssid] (Socket error %d)", errno); // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) joined %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); + INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) joined %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr); // Update Status Log update_status(); @@ -906,7 +901,6 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); @@ -916,7 +910,7 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group char safegroupstr2[9]; memset(safegroupstr2, 0, sizeof(safegroupstr2)); strncpy(safegroupstr2, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); - WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join %s group %s without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr, safegroupstr2); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to join %s group %s without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr, safegroupstr2); } } @@ -924,14 +918,13 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)group->data, ADHOCCTL_GROUPNAME_LEN); - WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join invalid %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to join invalid %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr); } // Invalid State, Out of Memory or Invalid Group Name @@ -984,14 +977,13 @@ void disconnect_user(SceNetAdhocctlUserNode * user) } // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) left %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); + INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) left %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr); // Empty Group if(user->group->playercount == 0) @@ -1028,11 +1020,10 @@ void disconnect_user(SceNetAdhocctlUserNode * user) else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); - WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to leave %s group without joining one first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to leave %s group without joining one first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr); } // Delete User @@ -1087,11 +1078,10 @@ void send_scan_results(SceNetAdhocctlUserNode * user) if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: send_scan_result[send peer complete] (Socket error %d)", errno); // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) requested information on %d %s groups", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], user->game->groupcount, safegamestr); + INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) requested information on %d %s groups", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), user->game->groupcount, safegamestr); // Exit Function return; @@ -1101,14 +1091,13 @@ void send_scan_results(SceNetAdhocctlUserNode * user) else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); - WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to scan for %s groups without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to scan for %s groups without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr); } // Delete User @@ -1200,14 +1189,13 @@ void spread_message(SceNetAdhocctlUserNode *user, const char *message) if(counter > 0) { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); char safegroupstr[9]; memset(safegroupstr, 0, sizeof(safegroupstr)); strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN); - INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) sent \"%s\" to %d players in %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], message, counter, safegamestr, safegroupstr); + INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) sent \"%s\" to %d players in %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), message, counter, safegamestr, safegroupstr); } // Exit Function @@ -1218,11 +1206,10 @@ void spread_message(SceNetAdhocctlUserNode *user, const char *message) else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; char safegamestr[10]; memset(safegamestr, 0, sizeof(safegamestr)); strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH); - WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to send a text message without joining a %s group first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr); + WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to send a text message without joining a %s group first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr); } // Delete User @@ -1417,7 +1404,7 @@ void game_product_override(SceNetAdhocctlProductCode * product) /** * Update Status Logfile */ -void update_status(void) +void update_status() { // Open Logfile FILE * log = File::OpenCFile(SERVER_STATUS_XMLOUT, "w"); @@ -1672,6 +1659,7 @@ const char * strcpyxml(char * out, const char * in, uint32_t size) */ int proAdhocServerThread(int port) // (int argc, char * argv[]) { + setCurrentThreadName("AdhocServer"); // Result int result = 0; @@ -1806,7 +1794,7 @@ int create_listen_socket(uint16_t port) int bindresult = bind(fd, (struct sockaddr *)&local, sizeof(local)); // Bound Local Address to Socket - if(bindresult != -1) + if(bindresult != SOCKET_ERROR) { // Switch Socket into Listening Mode listen(fd, SERVER_LISTEN_BACKLOG); @@ -1816,7 +1804,11 @@ int create_listen_socket(uint16_t port) } // Notify User - else ERROR_LOG(SCENET, "AdhocServer: Bind returned %i (Socket error %d)", bindresult, errno); + else { + ERROR_LOG(SCENET, "AdhocServer: Bind returned %i (Socket error %d)", bindresult, errno); + I18NCategory* n = GetI18NCategory("Networking"); + host->NotifyUserMessage(std::string(n->T("AdhocServer Failed to Bind Port")) + " " + std::to_string(port), 3.0, 0x0000ff); + } // Close Socket closesocket(fd); @@ -1880,7 +1872,7 @@ int server_loop(int server) u8 *pip = (u8*)&sip; if (gethostbyname(str)->h_addrtype == AF_INET && gethostbyname(str)->h_addr_list[0] != NULL) pip = (u8*)gethostbyname(str)->h_addr_list[0]; sip = *(u32_le*)pip; - WARN_LOG(SCENET, "AdhocServer: Replacing IP %s with %u.%u.%u.%u", inet_ntoa(addr.sin_addr), pip[0], pip[1], pip[2], pip[3]); + WARN_LOG(SCENET, "AdhocServer: Replacing IP %s with %s", inet_ntoa(addr.sin_addr), inet_ntoa(*(in_addr*)&pip)); } */ login_user_stream(loginresult, sip); @@ -1942,8 +1934,7 @@ int server_loop(int server) else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; - WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Waiting State from %u.%u.%u.%u", user->rx[0], ip[0], ip[1], ip[2], ip[3]); + WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Waiting State from %s", user->rx[0], inet_ntoa(*(in_addr*)&user->resolver.ip)); // Logout User logout_user(user); @@ -2026,8 +2017,7 @@ int server_loop(int server) else { // Notify User - uint8_t * ip = (uint8_t *)&user->resolver.ip; - WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Logged-In State from %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u)", user->rx[0], (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3]); + WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Logged-In State from %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s)", user->rx[0], (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip)); // Logout User logout_user(user); diff --git a/Core/HLE/proAdhocServer.h b/Core/HLE/proAdhocServer.h index c86e33cf6f..3773749eea 100644 --- a/Core/HLE/proAdhocServer.h +++ b/Core/HLE/proAdhocServer.h @@ -46,7 +46,7 @@ #define SERVER_STATUS_XMLOUT "www/status.xml" // Server Shutdown Message -#define SERVER_SHUTDOWN_MESSAGE "PROMETHEUS HUB IS SHUTTING DOWN!" +#define SERVER_SHUTDOWN_MESSAGE "ADHOC SERVER HUB IS SHUTTING DOWN!" typedef struct db_crosslink{ char id_from[PRODUCT_CODE_LENGTH + 1]; //SceNetAdhocctlProductCode id_from; @@ -298,7 +298,7 @@ void logout_user(SceNetAdhocctlUserNode * user); /** * Free Database Memory */ -void free_database(void); +void free_database(); /** * Connect User to Game Group @@ -358,7 +358,7 @@ void game_product_override(SceNetAdhocctlProductCode * product); /** * Update Status Logfile */ -void update_status(void); +void update_status(); /** * Server Entry Point diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index e9996c464e..b9f9238200 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -45,8 +45,8 @@ #include "Core/Instance.h" static bool netInited; -static bool netInetInited; -static bool netApctlInited; +bool netInetInited; +bool netApctlInited; u32 netDropRate = 0; u32 netDropDuration = 0; u32 netPoolAddr = 0; @@ -118,12 +118,25 @@ void __NetInit() { net::Init(); InitLocalIP(); - INFO_LOG(SCENET, "LocalHost IP will be %s", inet_ntoa(((sockaddr_in*)&localIP)->sin_addr)); + + char tmpmac[18]; + SceNetEtherAddr mac; + getLocalMac(&mac); + INFO_LOG(SCENET, "LocalHost IP will be %s [MAC: %s]", inet_ntoa(((sockaddr_in*)&localIP)->sin_addr), mac2str(&mac, tmpmac)); //net::Init(); __ResetInitNetLib(); } void __NetShutdown() { + // Checks to avoid confusing logspam + if (netAdhocctlInited) sceNetAdhocctlTerm(); + if (netAdhocInited) sceNetAdhocTerm(); + + if (netApctlInited) sceNetApctlTerm(); + if (netInetInited) sceNetInetTerm(); + + if (netInited) sceNetTerm(); + __ResetInitNetLib(); net::Shutdown(); @@ -149,6 +162,10 @@ void __NetDoState(PointerWrap &p) { if (!s) return; + auto cur_netInited = netInited; + auto cur_netInetInited = netInetInited; + auto cur_netApctlInited = netApctlInited; + p.Do(netInited); p.Do(netInetInited); p.Do(netApctlInited); @@ -170,6 +187,12 @@ void __NetDoState(PointerWrap &p) { p.Do(netThread1Addr); p.Do(netThread2Addr); } + // Let's not change "Inited" value when Loading SaveState in the middle of multiplayer to prevent memory & port leaks + if (p.mode == p.MODE_READ) { + netApctlInited = cur_netApctlInited; + netInetInited = cur_netInetInited; + netInited = cur_netInited; + } } static inline u32 AllocUser(u32 size, bool fromTop, const char *name) { @@ -186,10 +209,32 @@ static inline void FreeUser(u32 &addr) { } static u32 sceNetTerm() { - //May also need to Terminate netAdhocctl and netAdhoc since the game (ie. GTA:VCS, Wipeout Pulse, etc) might not called them before calling sceNetTerm and causing them to behave strangely on the next sceNetInit+sceNetAdhocInit + // May also need to Terminate netAdhocctl and netAdhoc to free some resources & threads, since the game (ie. GTA:VCS, Wipeout Pulse, etc) might not called them before calling sceNetTerm and causing them to behave strangely on the next sceNetInit & sceNetAdhocInit if (netAdhocctlInited) sceNetAdhocctlTerm(); if (netAdhocInited) sceNetAdhocTerm(); + if (netApctlInited) sceNetApctlTerm(); + if (netInetInited) sceNetInetTerm(); + + // Library is initialized + if (netInited) { + // Delete PDP Sockets + deleteAllPDP(); + + // Delete PTP Sockets + deleteAllPTP(); + + // Delete GameMode Buffer + //deleteAllGMB(); + + // Terminate Internet Library + //sceNetInetTerm(); + + // Unload Internet Modules (Just keep it in memory... unloading crashes?!) + // if (_manage_modules != 0) sceUtilityUnloadModule(PSP_MODULE_NET_INET); + // Library shutdown + } + WARN_LOG(SCENET, "sceNetTerm()"); netInited = false; FreeUser(netPoolAddr); @@ -199,12 +244,20 @@ static u32 sceNetTerm() { return 0; } -// TODO: should that struct actually be initialized here? -static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) { +/* +Parameters: + poolsize - Memory pool size (appears to be for the whole of the networking library). + calloutprio - Priority of the SceNetCallout thread. + calloutstack - Stack size of the SceNetCallout thread (defaults to 4096 on non 1.5 firmware regardless of what value is passed). + netintrprio - Priority of the SceNetNetintr thread. + netintrstack - Stack size of the SceNetNetintr thread (defaults to 4096 on non 1.5 firmware regardless of what value is passed). +*/ +static u32 sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) { + // TODO: Create Network Threads using given priority & stack // TODO: The correct behavior is actually to allocate more and leak the other threads/pool. // But we reset here for historic reasons (GTA:VCS potentially triggers this.) if (netInited) - sceNetTerm(); + sceNetTerm(); // This cleanup attempt might not worked when SaveState were loaded in the middle of multiplayer game and re-entering multiplayer, thus causing memory leaks & wasting binded ports. May be we shouldn't save/load "Inited" vars on SaveState? if (poolSize == 0) { return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE, "invalid pool size"); @@ -236,13 +289,32 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini WARN_LOG(SCENET, "sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d) at %08x", poolSize, calloutPri, calloutStack, netinitPri, netinitStack, currentMIPS->pc); netInited = true; - netMallocStat.maximum = poolSize; - netMallocStat.free = poolSize; - netMallocStat.pool = 0; + netMallocStat.pool = poolSize; // This should be the poolSize isn't? + netMallocStat.maximum = poolSize/2; // According to JPCSP's sceNetGetMallocStat this is Currently Used size = (poolSize - free), faked to half the pool + netMallocStat.free = poolSize - netMallocStat.maximum; + + // Clear Socket Translator Memory + memset(&pdp, 0, sizeof(pdp)); + memset(&ptp, 0, sizeof(ptp)); return hleLogSuccessI(SCENET, 0); } +// Free(delete) thread info / data. +// Normal usage: sceKernelDeleteThread followed by sceNetFreeThreadInfo with the same threadID as argument +static int sceNetFreeThreadinfo(SceUID thid) { + ERROR_LOG(SCENET, "UNIMPL sceNetFreeThreadinfo(%i)", thid); + + return 0; +} + +// Abort a thread. +static int sceNetThreadAbort(SceUID thid) { + ERROR_LOG(SCENET, "UNIMPL sceNetThreadAbort(%i)", thid); + + return 0; +} + static u32 sceWlanGetEtherAddr(u32 addrAddr) { if (!Memory::IsValidRange(addrAddr, 6)) { // More correctly, it should crash. @@ -364,7 +436,7 @@ static int sceNetInetInit() { return 0; } -static int sceNetInetTerm() { +int sceNetInetTerm() { ERROR_LOG(SCENET, "UNIMPL sceNetInetTerm()"); netInetInited = false; @@ -380,7 +452,7 @@ static int sceNetApctlInit() { return 0; } -static int sceNetApctlTerm() { +int sceNetApctlTerm() { ERROR_LOG(SCENET, "UNIMPL sceNeApctlTerm()"); netApctlInited = false; @@ -602,9 +674,9 @@ const HLEFunction sceNet[] = { {0X89360950, &WrapI_UU, "sceNetEtherNtostr", 'i', "xx" }, {0XD27961C9, &WrapI_UU, "sceNetEtherStrton", 'i', "xx" }, {0X0BF0A3AE, &WrapU_U, "sceNetGetLocalEtherAddr", 'x', "x" }, - {0X50647530, nullptr, "sceNetFreeThreadinfo", '?', "" }, + {0X50647530, &WrapI_I, "sceNetFreeThreadinfo", 'i', "i" }, {0XCC393E48, &WrapI_U, "sceNetGetMallocStat", 'i', "x" }, - {0XAD6844C6, nullptr, "sceNetThreadAbort", '?', "" }, + {0XAD6844C6, &WrapI_I, "sceNetThreadAbort", 'i', "i" }, }; const HLEFunction sceNetResolver[] = { diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index f5cec1206c..bf7d006884 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -60,7 +60,7 @@ typedef struct SceNetInetSockaddr { uint8_t sa_len; uint8_t sa_family; uint8_t sa_data[14]; -} SceNetInetSockaddr; +} PACK SceNetInetSockaddr; // Sockaddr_in typedef struct SceNetInetSockaddrIn { @@ -69,19 +69,19 @@ typedef struct SceNetInetSockaddrIn { u16_le sin_port; //uint16_t u32_le sin_addr; //uint32_t uint8_t sin_zero[8]; -} SceNetInetSockaddrIn; +} PACK SceNetInetSockaddrIn; // Polling Event Field typedef struct SceNetInetPollfd { //similar format to pollfd in 32bit (pollfd in 64bit have different size) s32_le fd; s16_le events; s16_le revents; -} SceNetInetPollfd; +} PACK SceNetInetPollfd; -struct ProductStruct { +typedef struct ProductStruct { // Similar to SceNetAdhocctlAdhocId ? s32_le unknown; // Unknown, set to 0 // Product Type ? char product[PRODUCT_CODE_LENGTH]; // Game ID (Example: ULUS10000) -}; +} PACK ProductStruct; struct ApctlHandler { u32 entryPoint; @@ -90,6 +90,9 @@ struct ApctlHandler { class PointerWrap; +extern bool netInetInited; +extern bool netApctlInited; + void Register_sceNet(); void Register_sceWlanDrv(); void Register_sceNetUpnp(); @@ -100,4 +103,7 @@ void __NetInit(); void __NetShutdown(); void __NetDoState(PointerWrap &p); -int sceNetInetPoll(void *fds, u32 nfds, int timeout); \ No newline at end of file +int sceNetInetPoll(void *fds, u32 nfds, int timeout); +int sceNetInetTerm(); +int sceNetApctlTerm(); +static u32 sceNetTerm(); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 52dbcd9d8f..ce16cee15e 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -16,11 +16,13 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include "thread/threadutil.h" // sceNetAdhoc // This is a direct port of Coldbird's code from http://code.google.com/p/aemu/ // All credit goes to him! #include "Core/Core.h" +#include "Core/Host.h" #include "Core/MemMapHelpers.h" #include "Common/ChunkFile.h" #include "Core/MIPS/MIPSCodeUtils.h" @@ -28,14 +30,18 @@ #include "Core/HLE/HLEHelperThread.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernelThread.h" -#include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelMemory.h" #include "Core/HLE/sceKernelModule.h" #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/proAdhoc.h" +#include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/sceNet.h" #include "Core/HLE/proAdhocServer.h" +#include "i18n/i18n.h" + +#define PSP_THREAD_ATTR_KERNEL 0x00001000 // Using constants instead of numbers for readability reason, since PSP_THREAD_ATTR_KERNEL/USER is located in sceKernelThread.cpp instead of sceKernelThread.h +#define PSP_THREAD_ATTR_USER 0x80000000 // shared in sceNetAdhoc.h since it need to be used from sceNet.cpp also // TODO: Make accessor functions instead, and throw all this state in a struct. @@ -45,16 +51,23 @@ bool networkInited; static bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; +int adhocDefaultTimeout = 5000; +int adhocEventPollDelayMS = 10; // 16; +int adhocMatchingEventDelayMS = 100; // 33; +int adhocEventDelayMS = 500; // This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 SceUID threadAdhocID; -std::mutex adhocEvtMtx; -std::vector> adhocctlEvents; -std::vector matchingEvents; +std::recursive_mutex adhocEvtMtx; +std::deque> adhocctlEvents; +std::deque matchingEvents; +std::map adhocctlHandlers; +int IsAdhocctlInCB = 0; + u32 dummyThreadHackAddr = 0; u32_le dummyThreadCode[3]; - -std::map adhocctlHandlers; +u32 matchingThreadHackAddr = 0; +u32_le matchingThreadCode[3]; int matchingEventThread(int matchingId); int matchingInputThread(int matchingId); @@ -65,7 +78,7 @@ int sceNetAdhocMatchingTerm(); int sceNetAdhocMatchingSetHelloOpt(int matchingId, int optLenAddr, u32 optDataAddr); void __NetAdhocShutdown() { - //Kill AdhocServer Thread + // Kill AdhocServer Thread if (adhocServerRunning) { adhocServerRunning = false; if (adhocServerThread.joinable()) { @@ -80,22 +93,28 @@ void __NetAdhocShutdown() { sceNetAdhocctlTerm(); } if (netAdhocInited) { - // Should not really call HLE funcs from shutdown. - // Prevent attempting to delete the thread, already deleted by shutdown. - threadAdhocID = 0; + // Should not really call HLE funcs from shutdown, but we need to cleanup sceNetAdhocTerm(); } if (dummyThreadHackAddr) { kernelMemory.Free(dummyThreadHackAddr); dummyThreadHackAddr = 0; } + if (matchingThreadHackAddr) { + kernelMemory.Free(matchingThreadHackAddr); + matchingThreadHackAddr = 0; + } } void __NetAdhocDoState(PointerWrap &p) { - auto s = p.Section("sceNetAdhoc", 1, 2); + auto s = p.Section("sceNetAdhoc", 1, 3); if (!s) return; + auto cur_netAdhocInited = netAdhocInited; + auto cur_netAdhocctlInited = netAdhocctlInited; + auto cur_netAdhocMatchingInited = netAdhocMatchingInited; + p.Do(netAdhocInited); p.Do(netAdhocctlInited); p.Do(netAdhocMatchingInited); @@ -106,26 +125,44 @@ void __NetAdhocDoState(PointerWrap &p) { __KernelRestoreActionType(actionAfterMatchingMipsCall, AfterMatchingMipsCall::Create); p.Do(dummyThreadHackAddr); - } else if (p.mode == p.MODE_READ) { + } + if (s >= 3) { + //p.Do(IsAdhocctlInCB); // This will cause a crash if adhocEvtMtx was locked + p.Do(actionAfterAdhocMipsCall); + __KernelRestoreActionType(actionAfterAdhocMipsCall, AfterAdhocMipsCall::Create); + + p.Do(matchingThreadHackAddr); + } + + if (p.mode == p.MODE_READ) { // Previously, this wasn't being saved. It needs its own space. - if (strcmp("dummythreadhack", kernelMemory.GetBlockTag(dummyThreadHackAddr)) != 0) { + if (dummyThreadHackAddr && strcmp("dummythreadhack", kernelMemory.GetBlockTag(dummyThreadHackAddr)) != 0) { u32 blockSize = sizeof(dummyThreadCode); dummyThreadHackAddr = kernelMemory.Alloc(blockSize, false, "dummythreadhack"); } - } - if (dummyThreadHackAddr) { - Memory::Memcpy(dummyThreadHackAddr, dummyThreadCode, sizeof(dummyThreadCode)); + if (matchingThreadHackAddr && strcmp("matchingThreadHack", kernelMemory.GetBlockTag(matchingThreadHackAddr)) != 0) { + u32 blockSize = sizeof(matchingThreadCode); + matchingThreadHackAddr = kernelMemory.Alloc(blockSize, false, "matchingThreadHack"); + } + + // Restore dummy Loop MIPS code to prevent crashes after loading from SaveState + if (dummyThreadHackAddr) Memory::Memcpy(dummyThreadHackAddr, dummyThreadCode, sizeof(dummyThreadCode)); + if (matchingThreadHackAddr) Memory::Memcpy(matchingThreadHackAddr, matchingThreadCode, sizeof(matchingThreadCode)); + + // Let's not change "Inited" value when Loading SaveState to prevent memory & port leaks + netAdhocMatchingInited = cur_netAdhocMatchingInited; + netAdhocctlInited = cur_netAdhocctlInited; + netAdhocInited = cur_netAdhocInited; } } void __UpdateAdhocctlHandlers(u32 flag, u32 error) { - std::lock_guard adhocGuard(adhocEvtMtx); + std::lock_guard adhocGuard(adhocEvtMtx); adhocctlEvents.push_back({ flag, error }); } -// TODO: MipsCall needs to be called from it's own PSP Thread instead of from any random PSP Thread void __UpdateMatchingHandler(MatchingArgs ArgsPtr) { - std::lock_guard adhocGuard(adhocEvtMtx); + std::lock_guard adhocGuard(adhocEvtMtx); matchingEvents.push_back(ArgsPtr); } @@ -138,6 +175,19 @@ static int getBlockingFlag(int id) { #endif } +u32_le __CreateHLELoop(u32_le *loopAddr, const char *sceFuncName, const char *hleFuncName, const char *tagName) { + if (loopAddr == NULL || sceFuncName == NULL || hleFuncName == NULL) + return 0; + + loopAddr[0] = MIPS_MAKE_SYSCALL(sceFuncName, hleFuncName); + loopAddr[1] = MIPS_MAKE_B(-2); + loopAddr[2] = MIPS_MAKE_NOP(); + u32 blockSize = sizeof(u32_le)*3; + u32_le dummyThreadHackAddr = kernelMemory.Alloc(blockSize, false, tagName); // blockSize will be rounded to 256 granularity + Memory::Memcpy(dummyThreadHackAddr, loopAddr, sizeof(u32_le) * 3); // This area will be cleared again after loading an old savestate :( + return dummyThreadHackAddr; +} + void __NetAdhocInit() { friendFinderRunning = false; netAdhocInited = false; @@ -145,13 +195,13 @@ void __NetAdhocInit() { netAdhocMatchingInited = false; adhocctlHandlers.clear(); __AdhocServerInit(); - dummyThreadCode[0] = MIPS_MAKE_SYSCALL("sceNetAdhoc", "__NetTriggerCallbacks"); - dummyThreadCode[1] = MIPS_MAKE_B(-2); - dummyThreadCode[2] = MIPS_MAKE_NOP(); - u32 blockSize = sizeof(dummyThreadCode); - dummyThreadHackAddr = kernelMemory.Alloc(blockSize, false, "dummythreadhack"); - Memory::Memcpy(dummyThreadHackAddr, dummyThreadCode, sizeof(dummyThreadCode)); // This area will be cleared again after loading an old savestate :( + + // Init Adhoc Callbacks + dummyThreadHackAddr = __CreateHLELoop(dummyThreadCode, "sceNetAdhoc", "__NetTriggerCallbacks", "dummythreadhack"); + matchingThreadHackAddr = __CreateHLELoop(matchingThreadCode, "sceNetAdhocMatching", "__NetMatchingCallbacks", "matchingThreadHack"); actionAfterMatchingMipsCall = __KernelRegisterActionType(AfterMatchingMipsCall::Create); + actionAfterAdhocMipsCall = __KernelRegisterActionType(AfterAdhocMipsCall::Create); + // Create built-in AdhocServer Thread if (g_Config.bEnableWlan && g_Config.bEnableAdhocServer) { adhocServerRunning = true; @@ -161,10 +211,6 @@ void __NetAdhocInit() { u32 sceNetAdhocInit() { if (!netAdhocInited) { - // Clear Translator Memory - memset(&pdp, 0, sizeof(pdp)); - memset(&ptp, 0, sizeof(ptp)); - // Library initialized netAdhocInited = true; @@ -183,22 +229,25 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { // Create fake PSP Thread for callback // 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 // Using constants instead of numbers for readability reason, since PSP_THREAD_ATTR_KERNEL/USER is located in sceKernelThread.cpp instead of sceKernelThread.h -#define PSP_THREAD_ATTR_USER 0x80000000 - - threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, prio, stackSize, PSP_THREAD_ATTR_USER, 0, false); + threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, prio, stackSize, PSP_THREAD_ATTR_USER, 0, true); if (threadAdhocID > 0) { __KernelStartThread(threadAdhocID, 0, 0); } if(g_Config.bEnableWlan) { - if (initNetwork((SceNetAdhocctlAdhocId *)Memory::GetPointer(productAddr)) == 0) { + SceNetAdhocctlAdhocId* product = NULL; + if (Memory::IsValidAddress(productAddr)) product = (SceNetAdhocctlAdhocId*)Memory::GetPointer(productAddr); + + if (initNetwork(product) == 0) { // TODO: Merging friendFinder (real) thread to AdhocThread (fake) thread on PSP side if (!friendFinderRunning) { friendFinderRunning = true; friendFinderThread = std::thread(friendFinder); } networkInited = true; + + sleep_ms(adhocEventPollDelayMS); + //hleDelayResult(0, "give some time", adhocEventDelayMS * 1000); // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? } else { WARN_LOG(SCENET, "sceNetAdhocctlInit: Failed to init the network but faking success"); networkInited = false; // TODO: What needs to check this? Pretty much everything? Maybe we should just set netAdhocctlInited to false.. @@ -237,8 +286,9 @@ static int sceNetAdhocctlGetState(u32 ptrToStatus) { * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_SOCKET_ID_NOT_AVAIL, ADHOC_INVALID_ADDR, ADHOC_PORT_NOT_AVAIL, ADHOC_INVALID_PORT, ADHOC_PORT_IN_USE, NET_NO_SPACE */ // When choosing AdHoc menu in Wipeout Pulse sometimes it's saying that "WLAN is turned off" on game screen and getting "kUnityCommandCode_MediaDisconnected" error in the Log Console when calling sceNetAdhocPdpCreate, probably it needed to wait something from the thread before calling this (ie. need to receives 7 bytes from adhoc server 1st?) -static int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 unknown) { - INFO_LOG(SCENET, "sceNetAdhocPdpCreate(%s, %u, %u, %u) at %08x", mac, port, bufferSize, unknown, currentMIPS->pc); +static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 unknown) { + char tmpmac[18]; + INFO_LOG(SCENET, "sceNetAdhocPdpCreate(%s, %u, %u, %u) at %08x", mac2str((SceNetEtherAddr*)mac, tmpmac), port, bufferSize, unknown, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; } @@ -249,6 +299,12 @@ static int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 u if (netAdhocInited) { // Valid Arguments are supplied if (mac != NULL && bufferSize > 0) { + //sport 0 should be shifted back to 0 when using offset Phantasy Star Portable 2 use this + if (port == 0) port = -(int)portOffset; + // Some games (ie. DBZ Shin Budokai 2) might be getting the saddr/srcmac content from SaveState and causing problems :( So we try to fix it here + if (saddr != NULL) { + getLocalMac(saddr); + } // Valid MAC supplied if (isLocalMAC(saddr)) { //// Unused Port supplied @@ -276,18 +332,19 @@ static int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 u getLocalIp(&addr); } - //if (port < 7) addr.sin_port = htons(port + 1341); else // <= 443 - addr.sin_port = htons(port + portOffset ); // This not safe in any way... + addr.sin_port = htons(port + portOffset ); // The port might be under 1024 (ie. GTA:VCS use port 1, Ford Street Racing use port 0 (UNUSED_PORT), etc) and already used by other application/host OS, should we add 1024 to the port whenever it tried to use an already used port? // Bound Socket to local Port int iResult = bind(usocket, (sockaddr *)&addr, sizeof(addr)); - /*if (iResult == SOCKET_ERROR && errno == 10048) { //Forcing PdpCreate to be successfull using a different Port might not works and might affect other players sharing the same IP due to "deleteFriendByIP" (should delete by MAC instead of IP) - addr.sin_port = 0; //UNUSED_PORT - iResult = bind(usocket, (sockaddr *)&addr, sizeof(addr)); - WARN_LOG(SCENET, "Port %u is already used, replaced with UNUSED_PORT(%u)", port, ntohs(addr.sin_port)); - }*/ + if (iResult == 0) { + // Update sport with the port assigned internal->lport = ntohs(local.sin_port) + socklen_t len = sizeof(addr); + if (getsockname(usocket, (sockaddr*)&addr, &len) == 0) { + port = ntohs(addr.sin_port) - portOffset; + } + // Allocate Memory for Internal Data SceNetAdhocPdpStat * internal = (SceNetAdhocPdpStat *)malloc(sizeof(SceNetAdhocPdpStat)); @@ -297,21 +354,22 @@ static int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 u memset(internal, 0, sizeof(SceNetAdhocPdpStat)); // Find Free Translator Index - int i = 0; for (; i < 255; i++) if (pdp[i] == NULL) break; + int i = 0; + for (; i < 255; i++) if (pdp[i] == NULL) break; // Found Free Translator Index if (i < 255) { // Fill in Data internal->id = usocket; internal->laddr = *saddr; - internal->lport = getLocalPort(usocket) - portOffset; //should use the port given to the socket (in case it's UNUSED_PORT port) isn't? + internal->lport = port; //getLocalPort(usocket) - portOffset; //should use the port given to the socket (in case it's UNUSED_PORT port) isn't? internal->rcv_sb_cc = bufferSize; // Link Socket to Translator ID pdp[i] = internal; // Forward Port on Router - //sceNetPortOpen("UDP", sport); // I need to figure out how to use this in windows/linux + //sceNetPortOpen("UDP", port); // I need to figure out how to use this in windows/linux // Success return i + 1; @@ -326,6 +384,8 @@ static int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 u retval = ERROR_NET_ADHOC_PORT_IN_USE; if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "Socket error (%i) when binding port %u", errno, ntohs(addr.sin_port)); + I18NCategory* n = GetI18NCategory("Networking"); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(port + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); } } @@ -355,7 +415,10 @@ static int sceNetAdhocPdpCreate(const char *mac, u32 port, int bufferSize, u32 u * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG */ static int sceNetAdhocctlGetParameter(u32 paramAddr) { - DEBUG_LOG(SCENET, "sceNetAdhocctlGetParameter(%08x)",paramAddr); + char grpName[9] = { 0 }; char tmpmac[18]; + memcpy(grpName, parameter.group_name.data, ADHOCCTL_GROUPNAME_LEN); + parameter.nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; + DEBUG_LOG(SCENET, "sceNetAdhocctlGetParameter(%08x) [Ch=%i][Group=%s][BSSID=%s][name=%s]", paramAddr, parameter.channel, grpName, mac2str(¶meter.bssid.mac_addr, tmpmac), parameter.nickname.data); if (!g_Config.bEnableWlan) { return ERROR_NET_ADHOCCTL_DISCONNECTED; } @@ -390,7 +453,12 @@ static int sceNetAdhocctlGetParameter(u32 paramAddr) { * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT, ADHOC_INVALID_DATALEN, ADHOC_SOCKET_ALERTED, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_WOULD_BLOCK, NET_NO_SPACE, NET_INTERNAL */ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int len, int timeout, int flag) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i)", id, mac, port, data, len, timeout, flag); + char tmpmac[18]; + if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac, tmpmac), port, data, len, timeout, flag, currentMIPS->pc); + } else { + VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac, tmpmac), port, data, len, timeout, flag, currentMIPS->pc); + } if (!g_Config.bEnableWlan) { return -1; } @@ -442,15 +510,14 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int if (sent == SOCKET_ERROR) { DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u] (size=%i)", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); } - changeBlockingMode(socket->id, 0); + //changeBlockingMode(socket->id, 0); // Free Network Lock //_freeNetworkLock(); - uint8_t * sip = (uint8_t *)&target.sin_addr.s_addr; // Sent Data if (sent == len) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Sent %u bytes to %u.%u.%u.%u:%u\n", id, getLocalPort(socket->id), sent, sip[0], sip[1], sip[2], sip[3], ntohs(target.sin_port)); + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Sent %u bytes to %s:%u\n", id, getLocalPort(socket->id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); // Success return 0; @@ -462,6 +529,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Timeout return ERROR_NET_ADHOC_TIMEOUT; //-1; } + //VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Unknown Target Peer %s:%u\n", id, getLocalPort(socket->id), mac2str(daddr, tmpmac), ntohs(target.sin_port)); } // Broadcast Target @@ -507,8 +575,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int } changeBlockingMode(socket->id, 0); if (sent >= 0) { - uint8_t * sip = (uint8_t *)&target.sin_addr.s_addr; - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Sent %u bytes to %u.%u.%u.%u:%u\n", id, getLocalPort(socket->id), sent, sip[0], sip[1], sip[2], sip[3], ntohs(target.sin_port)); + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Sent %u bytes to %s:%u\n", id, getLocalPort(socket->id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); } } @@ -561,7 +628,12 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_NOT_ENOUGH_SPACE, ADHOC_THREAD_ABORTED, NET_INTERNAL */ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void *dataLength, u32 timeout, int flag) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv(%i, %p, %p, %p, %p, %i, %i) at %08x", id, addr, port, buf, dataLength, timeout, flag, currentMIPS->pc); + if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket + DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv(%i, %p, %p, %p, %p, %i, %i) at %08x", id, addr, port, buf, dataLength, timeout, flag, currentMIPS->pc); + } else { + VERBOSE_LOG(SCENET, "sceNetAdhocPdpRecv(%i, %p, %p, %p, %p, %i, %i) at %08x", id, addr, port, buf, dataLength, timeout, flag, currentMIPS->pc); + } + if (!g_Config.bEnableWlan) { return -1; } @@ -613,19 +685,36 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Acquire Network Lock //_acquireNetworkLock(); + // TODO: Use a different thread (similar to sceIo) for recvfrom, recv & accept to prevent blocking-socket from blocking emulation (ie. Hot Shots Tennis:GaG) + int received = 0; + int error = 0; + // Receive Data - changeBlockingMode(socket->id, flag); - int received = recvfrom(socket->id, (char *)buf, *len,0,(sockaddr *)&sin, &sinlen); - int error = errno; - if (received == SOCKET_ERROR) { - VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv [size=%i]", error, *len); + changeBlockingMode(socket->id, 1); + received = recvfrom(socket->id, (char*)buf, *len, 0, (sockaddr*)&sin, &sinlen); + error = errno; + + if (flag == 0) { + // Simulate blocking behaviour with non-blocking socket + uint32_t starttime = (uint32_t)(real_time_now() * 1000.0); + // Wait for Connection + while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && connectInProgress(error)) { + received = recvfrom(socket->id, (char*)buf, *len, 0, (sockaddr*)&sin, &sinlen); + error = errno; + // Wait 1ms + sleep_ms(1); + } } - changeBlockingMode(socket->id, 0); + + if (received == SOCKET_ERROR) { + VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", id, socket->lport, error, *len); + } + changeBlockingMode(socket->id, 0); + // Received Data - if (received >= 0) { - uint8_t * sip = (uint8_t *)&sin.sin_addr.s_addr; - DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %u.%u.%u.%u:%u\n", id, getLocalPort(socket->id), received, sip[0], sip[1], sip[2], sip[3], ntohs(sin.sin_port)); + if (received > 0) { + DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, getLocalPort(socket->id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); // Peer MAC SceNetEtherAddr mac; @@ -645,8 +734,11 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Return Success return 0; } - WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %i bytes from Unknown Peer %u.%u.%u.%u:%u [%02X:%02X:%02X:%02X:%02X:%02X]", id, getLocalPort(socket->id), received, sip[0], sip[1], sip[2], sip[3], ntohs(sin.sin_port), mac.data[0], mac.data[1], mac.data[2], mac.data[3], mac.data[4], mac.data[5]); - + // Unknown Peer, let's not give any data + else { + *len = 0; + WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %i bytes from Unknown Peer %s:%u", id, getLocalPort(socket->id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + } // Free Network Lock //_freeNetworkLock(); @@ -663,8 +755,16 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * #endif // Nothing received - if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; - return ERROR_NET_ADHOC_TIMEOUT; + if (received == SOCKET_ERROR && error == EAGAIN) { + // Blocking Situation + if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; + + // Timeout + return ERROR_NET_ADHOC_TIMEOUT; + } + + // Disconnected + return ERROR_NET_ADHOC_DISCONNECTED; } // Invalid Argument @@ -699,7 +799,7 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb if (sds != NULL && count > 0) { // Socket Check - int i = 0; for (; i < count; i++) + for (int i = 0; i < count; i++) { // Invalid Socket if (sds[i].id < 1 || sds[i].id > 255 || (pdp[sds[i].id - 1] == NULL && ptp[sds[i].id - 1] == NULL)) return ERROR_NET_ADHOC_INVALID_SOCKET_ID; @@ -873,7 +973,15 @@ static int sceNetAdhocctlScan() { // Library initialized if (netAdhocctlInited) { - // Not connected + // Wait until Not connected + if (friendFinderRunning) { + int cnt = 0; + while ((threadStatus != ADHOCCTL_STATE_DISCONNECTED) && (cnt < adhocDefaultTimeout)) { + sleep_ms(1); + cnt++; + } + } + if (threadStatus == ADHOCCTL_STATE_DISCONNECTED) { threadStatus = ADHOCCTL_STATE_SCANNING; @@ -890,15 +998,22 @@ static int sceNetAdhocctlScan() { return ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY } + // Does Connected Event's mipscall need be executed after returning from sceNetAdhocctlScan ? + notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); + // Wait for Status to be connected to prevent Ford Street Racing from Failed to find game session + // TODO: Do this async while Delaying HLE Result if (friendFinderRunning) { int cnt = 0; - while ((threadStatus == ADHOCCTL_STATE_SCANNING) && (cnt < 5000)) { + while ((threadStatus == ADHOCCTL_STATE_SCANNING) && (cnt < adhocDefaultTimeout)) { sleep_ms(1); cnt++; } } + //sceKernelDelayThread(adhocEventDelayMS * 1000); + hleDelayResult(0, "give time to init/cleanup", adhocEventDelayMS * 1000); + // Return Success return 0; } @@ -917,7 +1032,7 @@ static int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { SceNetAdhocctlScanInfoEmu *buf = NULL; if (Memory::IsValidAddress(bufAddr)) buf = (SceNetAdhocctlScanInfoEmu *)Memory::GetPointer(bufAddr); - INFO_LOG(SCENET, "sceNetAdhocctlGetScanInfo([%08x]=%i, %08x)", sizeAddr, buflen ? *buflen : -1, bufAddr); + INFO_LOG(SCENET, "sceNetAdhocctlGetScanInfo([%08x]=%i, %08x)", sizeAddr, /*buflen ? *buflen : -1*/Memory::Read_U32(sizeAddr), bufAddr); if (!g_Config.bEnableWlan) { return 0; } @@ -933,8 +1048,11 @@ static int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { peerlock.lock(); // Length Returner Mode - if (buf == NULL) *buflen = countAvailableNetworks() * sizeof(SceNetAdhocctlScanInfoEmu); - + if (buf == NULL) { + int availNetworks = countAvailableNetworks(); + *buflen = availNetworks * sizeof(SceNetAdhocctlScanInfoEmu); + DEBUG_LOG(SCENET, "NetworkList [Available: %i]", availNetworks); + } // Normal Information Mode else { // Clear Memory @@ -963,17 +1081,14 @@ static int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { // sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_ADHOC_CHANNEL, &buf[discovered].channel); // Fake Channel Number 1 on Automatic Channel - // if (buf[discovered].channel == 0) buf[discovered].channel = 1; - - //Always Fake Channel 1 - buf[discovered].channel = 1; + buf[discovered].channel = group->channel; //parameter.channel // Increase Discovery Counter discovered++; } // Link List - int i = 0; for (; i < discovered - 1; i++) { + for (int i = 0; i < discovered - 1; i++) { // Link Network buf[i].next = bufAddr + (sizeof(SceNetAdhocctlScanInfoEmu)*i) + sizeof(SceNetAdhocctlScanInfoEmu); // buf[i].next = &buf[i + 1]; } @@ -984,6 +1099,7 @@ static int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { // Fix Size *buflen = discovered * sizeof(SceNetAdhocctlScanInfoEmu); + DEBUG_LOG(SCENET, "NetworkList [Requested: %i][Discovered: %i]", requestcount, discovered); } // Multithreading Unlock @@ -1006,7 +1122,7 @@ static int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { static u32 sceNetAdhocctlAddHandler(u32 handlerPtr, u32 handlerArg) { bool foundHandler = false; u32 retval = 0; - struct AdhocctlHandler handler; + AdhocctlHandler handler; memset(&handler, 0, sizeof(handler)); while (adhocctlHandlers.find(retval) != adhocctlHandlers.end()) @@ -1044,12 +1160,9 @@ static u32 sceNetAdhocctlAddHandler(u32 handlerPtr, u32 handlerArg) { static u32 sceNetAdhocctlDisconnect() { // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? - INFO_LOG(SCENET, "sceNetAdhocctlDisconnect() at %08x [group=%s]", currentMIPS->pc, parameter.group_name.data); - /* - if (!g_Config.bEnableWlan) { - return 0; - } - */ + char grpName[9] = { 0 }; + memcpy(grpName, parameter.group_name.data, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + INFO_LOG(SCENET, "sceNetAdhocctlDisconnect() at %08x [group=%s]", currentMIPS->pc, grpName); // Library initialized if (netAdhocctlInited) { @@ -1058,9 +1171,6 @@ static u32 sceNetAdhocctlDisconnect() { // Clear Network Name memset(¶meter.group_name, 0, sizeof(parameter.group_name)); - // Set Disconnected State - threadStatus = ADHOCCTL_STATE_DISCONNECTED; - // Set HUD Connection Status //setConnectionStatus(0); @@ -1076,34 +1186,37 @@ static u32 sceNetAdhocctlDisconnect() { ERROR_LOG(SCENET, "Socket error (%i) when sending", errno); } + // Set Disconnected State + threadStatus = ADHOCCTL_STATE_DISCONNECTED; + // Free Network Lock //_freeNetworkLock(); - - // Multithreading Lock - //peerlock.lock(); - - // Clear Peer List - freeFriendsRecursive(friends); - INFO_LOG(SCENET, "Cleared Peer List."); - - // Delete Peer Reference - friends = NULL; - - // Clear Group List - //freeGroupsRecursive(networks); - - // Delete Group Reference - //networks = NULL; - - // Multithreading Unlock - //peerlock.unlock(); } + + // Multithreading Lock + //peerlock.lock(); + + // Clear Peer List, since games are moving to a different a group when the mission started may be we shouldn't free all peers yet + int32_t peercount = 0; + timeoutFriendsRecursive(friends, &peercount); + INFO_LOG(SCENET, "Marked for Timedout Peer List (%i)", peercount); + // Delete Peer Reference + //friends = NULL; + + // Clear Group List + //freeGroupsRecursive(networks); + + // Delete Group Reference + //networks = NULL; + + // Multithreading Unlock + //peerlock.unlock(); // Notify Event Handlers (even if we weren't connected, not doing this will freeze games like God Eater, which expect this behaviour) - { - std::lock_guard adhocGuard(adhocEvtMtx); - adhocctlEvents.push_back({ ADHOCCTL_EVENT_DISCONNECT, 0 }); - } + notifyAdhocctlHandlers(ADHOCCTL_EVENT_DISCONNECT, 0); + + hleCheckCurrentCallbacks(); + // Return Success, some games might ignore returned value and always treat it as success, otherwise repeatedly calling this function return 0; } @@ -1115,9 +1228,9 @@ static u32 sceNetAdhocctlDisconnect() { static u32 sceNetAdhocctlDelHandler(u32 handlerID) { if (adhocctlHandlers.find(handlerID) != adhocctlHandlers.end()) { adhocctlHandlers.erase(handlerID); - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlDelHandler(%d): deleted handler %d", handlerID, handlerID); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlDelHandler(%d)", handlerID); } else { - ERROR_LOG(SCENET, "UNTESTED sceNetAdhocctlDelHandler(%d): asked to delete invalid handler %d", handlerID, handlerID); + ERROR_LOG(SCENET, "UNTESTED sceNetAdhocctlDelHandler(%d): Invalid Handler ID", handlerID); } return 0; @@ -1127,14 +1240,23 @@ int sceNetAdhocctlTerm() { // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? INFO_LOG(SCENET, "sceNetAdhocctlTerm()"); - if (netAdhocMatchingInited) sceNetAdhocMatchingTerm(); + //if (netAdhocMatchingInited) sceNetAdhocMatchingTerm(); if (netAdhocctlInited) { - netAdhocctlInited = false; - friendFinderRunning = false; - if (friendFinderThread.joinable()) { - friendFinderThread.join(); + if (threadStatus != ADHOCCTL_STATE_DISCONNECTED) sceNetAdhocctlDisconnect(); + if (networkInited) { + // Terminate Adhoc Threads + friendFinderRunning = false; + if (friendFinderThread.joinable()) { + friendFinderThread.join(); + } } + // Clear Peer List + int32_t peercount = 0; + freeFriendsRecursive(friends, &peercount); + INFO_LOG(SCENET, "Cleared Peer List (%i)", peercount); + // Delete Peer Reference + friends = NULL; //May also need to clear Handlers adhocctlHandlers.clear(); // Free stuff here @@ -1146,16 +1268,15 @@ int sceNetAdhocctlTerm() { __KernelDeleteThread(threadAdhocID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocThread deleted"); threadAdhocID = 0; } -/*#ifdef _MSC_VER - WSACleanup(); // Might be better to call WSAStartup/WSACleanup from sceNetInit/sceNetTerm isn't? since it's the first/last network function being used, even better to put it in __NetInit/__NetShutdown as it's only called once -#endif*/ + netAdhocctlInited = false; } return 0; } static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { - DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x)", mac, nameAddr); + char tmpmac[18]; + DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x)", mac2str((SceNetEtherAddr*)mac, tmpmac), nameAddr); // Library initialized if (netAdhocctlInited) @@ -1244,7 +1365,8 @@ static int sceNetAdhocctlJoin(u32 scanInfoAddr) { } int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { - VERBOSE_LOG(SCENET, "sceNetAdhocctlGetPeerInfo(%s, %i, %08x) at %08x", mac, size, peerInfoAddr, currentMIPS->pc); + char tmpmac[18]; + VERBOSE_LOG(SCENET, "sceNetAdhocctlGetPeerInfo(%s, %i, %08x) at %08x", mac2str((SceNetEtherAddr*)mac, tmpmac), size, peerInfoAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; } @@ -1272,7 +1394,7 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { buf->nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char buf->mac_addr = *maddr; buf->ip_addr = addr.sin_addr.s_addr; // 0x11111111; - //buf->padding = 0x1111; //0; + buf->padding = 0; buf->last_recv = CoreTiming::GetGlobalTimeUsScaled(); // Success @@ -1294,7 +1416,7 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { buf->nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char buf->mac_addr = *maddr; buf->ip_addr = peer->ip_addr; // 0x11111111; - //buf->padding = /*0;*/ 0x1111; + buf->padding = 0; buf->last_recv = peer->last_recv; //CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; //(uint64_t)time(NULL); //This timestamp is important issue on Dissidia 012 // Success @@ -1317,7 +1439,9 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG, ADHOCCTL_BUSY */ int sceNetAdhocctlCreate(const char *groupName) { - INFO_LOG(SCENET, "sceNetAdhocctlCreate(%s) at %08x", groupName, currentMIPS->pc); + char grpName[9] = { 0 }; + memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + INFO_LOG(SCENET, "sceNetAdhocctlCreate(%s) at %08x", grpName, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; } @@ -1327,6 +1451,15 @@ int sceNetAdhocctlCreate(const char *groupName) { if (netAdhocctlInited) { // Valid Argument if (validNetworkName(groupNameStruct)) { + // Wait until Not connected + if (friendFinderRunning) { + int cnt = 0; + while ((threadStatus != ADHOCCTL_STATE_DISCONNECTED && threadStatus != ADHOCCTL_STATE_SCANNING) && (cnt < adhocDefaultTimeout)) { + sleep_ms(1); + cnt++; + } + } + // Disconnected State, may also need to check for Scanning state to prevent some games from failing to host a game session if ((threadStatus == ADHOCCTL_STATE_DISCONNECTED) || (threadStatus == ADHOCCTL_STATE_SCANNING)) { // Set Network Name @@ -1366,15 +1499,23 @@ int sceNetAdhocctlCreate(const char *groupName) { // Set HUD Connection Status //setConnectionStatus(1); + // Connected Event's mipscall need be executed before returning from sceNetAdhocctlCreate (or before the next sceNet function?) + notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); + // Wait for Status to be connected to prevent Ford Street Racing from Failed to create game session - if (friendFinderRunning) { + // TODO: Do this async while Delaying HLE Result + if (friendFinderRunning) { // This is thread-unsafe int cnt = 0; - while ((threadStatus != ADHOCCTL_STATE_CONNECTED) && (cnt < 5000)) { + while ((threadStatus != ADHOCCTL_STATE_CONNECTED) && (cnt < adhocDefaultTimeout)) { // This is thread-unsafe sleep_ms(1); cnt++; } } + //sceKernelDelayThreadCB(adhocEventDelayMS * 1000); + //hleCheckCurrentCallbacks(); + hleDelayResult(0, "give time to init/cleanup", adhocEventDelayMS * 1000); + // Return Success return 0; } @@ -1392,21 +1533,41 @@ int sceNetAdhocctlCreate(const char *groupName) { static int sceNetAdhocctlConnect(u32 ptrToGroupName) { if (Memory::IsValidAddress(ptrToGroupName)) { - INFO_LOG(SCENET, "sceNetAdhocctlConnect(groupName=%s) at %08x", Memory::GetCharPointer(ptrToGroupName), currentMIPS->pc); - return sceNetAdhocctlCreate(Memory::GetCharPointer(ptrToGroupName)); + const char* groupName = Memory::GetCharPointer(ptrToGroupName); + char grpName[9] = { 0 }; + memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + + INFO_LOG(SCENET, "sceNetAdhocctlConnect(groupName=%s) at %08x", grpName, currentMIPS->pc); + return sceNetAdhocctlCreate(groupName); } return ERROR_NET_ADHOC_INVALID_ARG; // ERROR_NET_ADHOC_INVALID_ADDR; } +// Connect to the Adhoc control game mode (as a Host) static int sceNetAdhocctlCreateEnterGameMode(const char *groupName, int unknown, int playerNum, u32 macsAddr, int timeout, int unknown2) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", groupName, unknown, playerNum, macsAddr, timeout, unknown2, currentMIPS->pc); - return -1; + char grpName[9] = { 0 }; + memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + + SceNetEtherAddr* addrs = NULL; // List of participating MAC addresses (started from host) + if (Memory::IsValidAddress(macsAddr)) { + addrs = PSPPointer::Create(macsAddr); + } + + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, unknown, playerNum, macsAddr, timeout, unknown2, currentMIPS->pc); + + return 0; } +// Connect to the Adhoc control game mode (as a Client) static int sceNetAdhocctlJoinEnterGameMode(const char *groupName, const char *macAddr, int timeout, int unknown2) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", groupName, macAddr, timeout, unknown2, currentMIPS->pc); - return -1; + char grpName[9] = { 0 }; + memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + + char tmpmac[18]; + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)macAddr, tmpmac), timeout, unknown2, currentMIPS->pc); + + return 0; } /** @@ -1422,14 +1583,18 @@ static int sceNetAdhocctlJoinEnterGameMode(const char *groupName, const char *ma */ int sceNetAdhocctlCreateEnterGameModeMin(const char *group_name, int game_type, int min_members, int num_members, u32 membersAddr, u32 timeout, int flag) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", group_name, game_type, min_members, num_members, membersAddr, timeout, flag, currentMIPS->pc); + char grpName[9] = { 0 }; + memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", grpName, game_type, min_members, num_members, membersAddr, timeout, flag, currentMIPS->pc); // We don't really need the Minimum User Check - return sceNetAdhocctlCreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); + return sceNetAdhocctlCreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); //0; } int sceNetAdhocTerm() { // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup all the sockets right? + // Since Adhocctl & AdhocMatching uses Sockets & Threads we should terminate them also to release their resources + if (netAdhocMatchingInited) sceNetAdhocMatchingTerm(); if (netAdhocctlInited) sceNetAdhocctlTerm(); // Library is initialized @@ -1449,6 +1614,7 @@ int sceNetAdhocTerm() { // Unload Internet Modules (Just keep it in memory... unloading crashes?!) // if (_manage_modules != 0) sceUtilityUnloadModule(PSP_MODULE_NET_INET); // Library shutdown + netAdhocInited = false; return hleLogSuccessInfoI(SCENET, 0); } else { @@ -1493,7 +1659,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { int i = 0; // Iterate Translation Table - int j = 0; for (; j < 255 && i < count; j++) + for (int j = 0; j < 255 && i < count; j++) { // Valid Socket Entry if (pdp[j] != NULL) @@ -1571,7 +1737,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { int i = 0; // Iterate Sockets - int j = 0; for (; j < 255 && i < count; j++) { + for (int j = 0; j < 255 && i < count; j++) { // Active Socket if (ptp[j] != NULL) { // Copy Socket Data from internal Memory @@ -1621,7 +1787,8 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT */ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, int dport, int bufsize, int rexmt_int, int rexmt_cnt, int unknown) { - INFO_LOG(SCENET, "sceNetAdhocPtpOpen(%s,%d,%s,%d,%d,%d,%d,%d)", srcmac, sport, dstmac,dport,bufsize, rexmt_int, rexmt_cnt, unknown); + char tmpmac[18]; + INFO_LOG(SCENET, "sceNetAdhocPtpOpen(%s, %d, %s, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac, tmpmac), sport, mac2str((SceNetEtherAddr*)dstmac, tmpmac),dport,bufsize, rexmt_int, rexmt_cnt, unknown, currentMIPS->pc); if (!g_Config.bEnableWlan) { return 0; } @@ -1629,6 +1796,10 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, SceNetEtherAddr * daddr = (SceNetEtherAddr *)dstmac; // Library is initialized if (netAdhocInited) { + // Some games (ie. DBZ Shin Budokai 2) might be getting the saddr/srcmac content from SaveState and causing problems :( So we try to fix it here + if (saddr != NULL) { + getLocalMac(saddr); + } // Valid Addresses if (saddr != NULL && isLocalMAC(saddr) && daddr != NULL && !isBroadcastMAC(daddr)) { // Random Port required @@ -1670,7 +1841,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Bound Socket to local Port if (bind(tcpsocket, (sockaddr *)&addr, sizeof(addr)) == 0) { - // Update sport with the port assigned binternal->lport = ntohs(local.sin_port)y bind + // Update sport with the port assigned internal->lport = ntohs(local.sin_port) socklen_t len = sizeof(addr); if (getsockname(tcpsocket, (sockaddr *)&addr, &len) == 0) { sport = ntohs(addr.sin_port) - portOffset; @@ -1682,7 +1853,8 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Allocated Memory if (internal != NULL) { // Find Free Translator ID - int i = 0; for (; i < 255; i++) if (ptp[i] == NULL) break; + int i = 0; + for (; i < 255; i++) if (ptp[i] == NULL) break; // Found Free Translator ID if (i < 255) { @@ -1715,6 +1887,11 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, free(internal); } } + else { + ERROR_LOG(SCENET, "Socket error (%i) when binding port %u", errno, ntohs(addr.sin_port)); + I18NCategory* n = GetI18NCategory("Networking"); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(sport + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); + } // Close Socket closesocket(tcpsocket); @@ -1756,8 +1933,12 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int if (Memory::IsValidAddress(peerPortPtr)) { port = (uint16_t *)Memory::GetPointer(peerPortPtr); } - - DEBUG_LOG(SCENET, "sceNetAdhocPtpAccept(%d,%08x,[%08x]=%u,%d,%u) at %08x", id, peerMacAddrPtr, peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); + char tmpmac[18]; + if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket + DEBUG_LOG(SCENET, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr, tmpmac), peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); + } else { + VERBOSE_LOG(SCENET, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr, tmpmac), peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); + } if (!g_Config.bEnableWlan) { return 0; } @@ -1790,18 +1971,21 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int changeBlockingMode(socket->id,1); } + // TODO: Use a different thread (similar to sceIo) for recvfrom, recv & accept to prevent blocking-socket from blocking emulation // Accept Connection int newsocket = accept(socket->id, (sockaddr *)&peeraddr, &peeraddrlen); + int error = errno; // Blocking Behaviour - if (!flag && newsocket == -1) { + if (!flag && newsocket == SOCKET_ERROR) { // Get Start Time - uint32_t starttime = (uint32_t)(real_time_now()*1000000.0); + uint32_t starttime = (uint32_t)(real_time_now()*1000.0); // Retry until Timeout hits - while ((timeout == 0 ||((uint32_t)(real_time_now()*1000000.0) - starttime) < (uint32_t)timeout) && newsocket == -1) { + while ((timeout == 0 || ((uint32_t)(real_time_now()*1000.0) - starttime) < (uint32_t)timeout) && (newsocket == SOCKET_ERROR) && connectInProgress(error)) { // Accept Connection newsocket = accept(socket->id, (sockaddr *)&peeraddr, &peeraddrlen); + error = errno; // Wait a bit... sleep_ms(1); @@ -1809,8 +1993,12 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int } if (newsocket == SOCKET_ERROR) { - int error = errno; - DEBUG_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Socket Error (%i)", id, error); + if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket + DEBUG_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Socket Error (%i)", id, error); + } + else { + VERBOSE_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Socket Error (%i)", id, error); + } } // Restore Blocking Behaviour @@ -1839,7 +2027,8 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Allocated Memory if (internal != NULL) { // Find Free Translator ID - int i = 0; for (; i < 255; i++) if (ptp[i] == NULL) break; + int i = 0; + for (; i < 255; i++) if (ptp[i] == NULL) break; // Found Free Translator ID if (i < 255) { @@ -1876,8 +2065,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Add Port Forward to Router // sceNetPortOpen("TCP", internal->lport); - uint8_t * pip = (uint8_t *)&peeraddr.sin_addr.s_addr; - INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%u.%u.%u.%u:%u)", id, i+1, internal->lport, pip[0], pip[1], pip[2], pip[3], internal->pport); + INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", id, i+1, internal->lport, inet_ntoa(peeraddr.sin_addr), internal->pport); // Return Socket return i + 1; @@ -1941,7 +2129,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { SceNetAdhocPtpStat * socket = ptp[id - 1]; // Valid Client Socket - if (socket->state == 0) { + if (socket->state == ADHOC_PTP_STATE_CLOSED) { // Target Address sockaddr_in sin; memset(&sin, 0, sizeof(sin)); @@ -1978,7 +2166,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { } // Instant Connection (Lucky!) - if (connectresult == 0 || (connectresult == -1 && (errorcode == EISCONN /*|| errorcode == EALREADY)*/))) { + if (connectresult == 0 || (connectresult == SOCKET_ERROR && (errorcode == EISCONN /*|| errorcode == EALREADY)*/))) { // Set Connected State socket->state = ADHOC_PTP_STATE_ESTABLISHED; @@ -1988,21 +2176,23 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { } // Connection in Progress - else if (connectresult == -1 && connectInProgress(errorcode)) { + else if (connectresult == SOCKET_ERROR && connectInProgress(errorcode)) { // Nonblocking Mode - if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; - + if (flag) { + //if (errorcode == EALREADY) return ERROR_NET_ADHOC_BUSY; + return ERROR_NET_ADHOC_WOULD_BLOCK; + } // Blocking Mode else { // Grab Connection Start Time - uint32_t starttime = (uint32_t)(real_time_now()*1000000.0); + uint32_t starttime = (uint32_t)(real_time_now()*1000.0); // Peer Information (for Connection-Polling) sockaddr_in peer; memset(&peer, 0, sizeof(peer)); socklen_t peerlen = sizeof(peer); // Wait for Connection - while ((timeout == 0 || ( (uint32_t)(real_time_now()*1000000.0) - starttime) < (uint32_t)timeout) && getpeername(socket->id, (sockaddr *)&peer, &peerlen) != 0) { + while ((timeout == 0 || ( (uint32_t)(real_time_now()*1000.0) - starttime) < (uint32_t)timeout) && getpeername(socket->id, (sockaddr *)&peer, &peerlen) != 0) { // Wait 1ms sleep_ms(1); } @@ -2012,8 +2202,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Set Connected State socket->state = ADHOC_PTP_STATE_ESTABLISHED; - uint8_t * pip = (uint8_t *)&peer.sin_addr.s_addr; - INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Established (%u.%u.%u.%u:%u)", id, socket->lport, pip[0], pip[1], pip[2], pip[3], socket->pport); + INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Established (%s:%u)", id, socket->lport, inet_ntoa(peer.sin_addr), socket->pport); // Success return 0; @@ -2097,16 +2286,20 @@ static int sceNetAdhocPtpClose(int id, int unknown) { * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT, ADHOC_SOCKET_ID_NOT_AVAIL, ADHOC_PORT_NOT_AVAIL, ADHOC_PORT_IN_USE, NET_NO_SPACE */ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int rexmt_int, int rexmt_cnt, int backlog, int unk) { - INFO_LOG(SCENET, "sceNetAdhocPtpListen(%s,%d,%d,%d,%d,%d,%d)",srcmac,sport,bufsize,rexmt_int,rexmt_cnt,backlog,unk); + char tmpmac[18]; + INFO_LOG(SCENET, "sceNetAdhocPtpListen(%s, %d, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac, tmpmac), sport,bufsize,rexmt_int,rexmt_cnt,backlog,unk, currentMIPS->pc); if (!g_Config.bEnableWlan) { return 0; } // Library is initialized SceNetEtherAddr * saddr = (SceNetEtherAddr *)srcmac; if (netAdhocInited) { + // Some games (ie. DBZ Shin Budokai 2) might be getting the saddr/srcmac content from SaveState and causing problems :( So we try to fix it here + if (saddr != NULL) { + getLocalMac(saddr); + } // Valid Address - if (saddr != NULL && isLocalMAC(saddr)) - { + if (saddr != NULL && isLocalMAC(saddr)) { // Random Port required if (sport == 0) { // Find unused Port @@ -2119,6 +2312,8 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Valid Ports if (!isPTPPortInUse(sport)) { + //sport 0 should be shifted back to 0 when using offset Phantasy Star Portable 2 use this + if (sport == 0) sport = -(int)portOffset; // Valid Arguments if (bufsize > 0 && rexmt_int > 0 && rexmt_cnt > 0 && backlog > 0) { @@ -2146,6 +2341,11 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int int iResult = 0; // Bound Socket to local Port if ((iResult = bind(tcpsocket, (sockaddr *)&addr, sizeof(addr))) == 0) { + // Update sport with the port assigned internal->lport = ntohs(local.sin_port) + socklen_t len = sizeof(addr); + if (getsockname(tcpsocket, (sockaddr*)&addr, &len) == 0) { + sport = ntohs(addr.sin_port) - portOffset; + } // Switch into Listening Mode if ((iResult = listen(tcpsocket, backlog)) == 0) { // Allocate Memory @@ -2154,7 +2354,8 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Allocated Memory if (internal != NULL) { // Find Free Translator ID - int i = 0; for (; i < 255; i++) if (ptp[i] == NULL) break; + int i = 0; + for (; i < 255; i++) if (ptp[i] == NULL) break; // Found Free Translator ID if (i < 255) { @@ -2189,6 +2390,10 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int } } } + else { + I18NCategory* n = GetI18NCategory("Networking"); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(sport + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); + } if (iResult == SOCKET_ERROR) { int error = errno; @@ -2272,15 +2477,15 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Save Length *len = sent; - uint8_t * smac = (uint8_t *)&socket->paddr; - INFO_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %02X:%02X:%02X:%02X:%02X:%02X:%u", id, socket->lport, sent, smac[0], smac[1], smac[2], smac[3], smac[4], smac[5], socket->pport); + char tmpmac[18]; + DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u", id, socket->lport, sent, mac2str(&socket->paddr, tmpmac), socket->pport); // Return Success return 0; } // Non-Critical Error - else if (sent == -1 && error == EAGAIN) { + else if (sent == SOCKET_ERROR && error == EAGAIN) { // Blocking Situation if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; @@ -2322,7 +2527,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou * @return 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_DISCONNECTED, NET_INTERNAL */ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeout, int flag) { - DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv(%d,%08x,%08x,%d,%d)", id, dataAddr, dataSizeAddr, timeout, flag); + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv(%d,%08x,%08x,%d,%d) at %08x", id, dataAddr, dataSizeAddr, timeout, flag, currentMIPS->pc); if (!g_Config.bEnableWlan) { return 0; } @@ -2346,10 +2551,30 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Acquire Network Lock // _acquireNetworkLock(); + // TODO: Use a different thread (similar to sceIo) for recvfrom, recv & accept to prevent blocking-socket from blocking emulation + int received = 0; + int error = 0; + // Receive Data - changeBlockingMode(socket->id, flag); - int received = recv(socket->id, (char *)buf, *len, 0); - int error = errno; + changeBlockingMode(socket->id, 1); + received = recv(socket->id, (char*)buf, *len, 0); + error = errno; + + if (flag == 0) { + // Simulate blocking behaviour with non-blocking socket + uint32_t starttime = (uint32_t)(real_time_now() * 1000.0); + // Wait for Connection + while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && connectInProgress(error)) { + received = recv(socket->id, (char*)buf, *len, 0); + error = errno; + // Wait 1ms + sleep_ms(1); + } + } + + if (received == SOCKET_ERROR) { + VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPtpRecv[%i:%u] [size=%i]", id, socket->lport, error, *len); + } changeBlockingMode(socket->id, 0); // Free Network Lock @@ -2360,15 +2585,15 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Save Length *len = received; - uint8_t * smac = (uint8_t *)&socket->paddr; - INFO_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %02X:%02X:%02X:%02X:%02X:%02X:%u", id, socket->lport, received, smac[0], smac[1], smac[2], smac[3], smac[4], smac[5], socket->pport); + char tmpmac[18]; + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u", id, socket->lport, received, mac2str(&socket->paddr, tmpmac), socket->pport); // Return Success return 0; } // Non-Critical Error - else if (received == -1 && error == EAGAIN) { + else if (received == SOCKET_ERROR /*&& error == EAGAIN*/) { // Blocking Situation if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; @@ -2412,6 +2637,31 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { if (netAdhocInited) { // Valid Socket if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { + // Cast Socket + SceNetAdhocPtpStat* socket = ptp[id - 1]; + + // Connected Socket + if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) { + // Get original Nagle algo value + int n = 0; + socklen_t m = sizeof(n); + getsockopt(socket->id, IPPROTO_TCP, TCP_NODELAY, (char*)&n, &m); + + // Disable Nagle Algo to send immediately + int flag = 1; + setsockopt(socket->id, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)); + + // Send Empty Data just to trigger Nagle on/off effect to flush the send buffer, Do we need to trigger this at all or is it automatically flushed? + changeBlockingMode(socket->id, nonblock); + int sent = send(socket->id, NULL, NULL, 0); + int error = errno; + changeBlockingMode(socket->id, 0); + + // Enable Nagle Algo + flag = n; //0; + setsockopt(socket->id, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)); + } + // Dummy Result return 0; } @@ -2425,32 +2675,33 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { static int sceNetAdhocGameModeCreateMaster(u32 data, int size) { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeCreateMaster(%08x, %i) at %08x", data, size, currentMIPS->pc); - return -1; + return 0; } static int sceNetAdhocGameModeCreateReplica(const char *mac, u32 data, int size) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeCreateReplica(%s, %08x, %i) at %08x", mac, data, size, currentMIPS->pc); - return -1; + char tmpmac[18]; + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeCreateReplica(%s, %08x, %i) at %08x", mac2str((SceNetEtherAddr*)mac, tmpmac), data, size, currentMIPS->pc); + return 0; } static int sceNetAdhocGameModeUpdateMaster() { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeUpdateMaster()"); - return -1; + return 0; } static int sceNetAdhocGameModeDeleteMaster() { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeDeleteMaster()"); - return -1; + return 0; } static int sceNetAdhocGameModeUpdateReplica(int id, u32 infoAddr) { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeUpdateReplica(%i, %08x)", id, infoAddr); - return -1; + return 0; } static int sceNetAdhocGameModeDeleteReplica(int id) { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeDeleteReplica(%i)", id); - return -1; + return 0; } int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { @@ -2468,8 +2719,6 @@ int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { int sceNetAdhocMatchingStop(int matchingId) { WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStop(%i) at %08x", matchingId, currentMIPS->pc); - //if (!g_Config.bEnableWlan) - // return -1; SceNetAdhocMatchingContext * item = findMatchingContext(matchingId); @@ -2485,8 +2734,16 @@ int sceNetAdhocMatchingStop(int matchingId) { } // Stop fake PSP Thread - //__KernelStopThread(item->matching_thid, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocMatching stopped"); - //item->matchingThread->Terminate(); + if (item->matching_thid > 0) { + __KernelStopThread(item->matching_thid, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocMatching stopped"); + __KernelDeleteThread(item->matching_thid, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocMatching deleted"); + /*item->matchingThread->Terminate(); + if (item->matchingThread && item->matchingThread->Stopped()) { + delete item->matchingThread; + item->matchingThread = nullptr; + }*/ + } + item->matching_thid = 0; // Multithreading Lock peerlock.lock(); @@ -2589,22 +2846,22 @@ int sceNetAdhocMatchingInit(u32 memsize) { } int sceNetAdhocMatchingTerm() { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingTerm()"); // Should we cleanup all created matching contexts first? just in case there are games that doesn't delete them before calling this if (netAdhocMatchingInited) { // Delete all Matching contexts - SceNetAdhocMatchingContext * next = NULL; + SceNetAdhocMatchingContext* next = NULL; SceNetAdhocMatchingContext * context = contexts; while (context != NULL) { next = context->next; - if (context->running) sceNetAdhocMatchingStop(context->id); + //if (context->running) sceNetAdhocMatchingStop(context->id); sceNetAdhocMatchingDelete(context->id); context = next; } + contexts = NULL; } - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingTerm()"); netAdhocMatchingInited = false; - return 0; } @@ -2624,11 +2881,21 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle // Valid Member Limit if (maxnum > 1 && maxnum <= 16) { // Valid Receive Buffer size - if (rxbuflen >= 1024) { + if (rxbuflen >= 1) { //1024 //200 on DBZ Shin Budokai 2 // Valid Arguments if (mode >= 1 && mode <= 3) { + // Wait until Adhoc is fully connected (mipscall of ADHOCCTL_EVENT_CONNECT event is fully executed ?) + if (friendFinderRunning) { + int cnt = 0; + while ((threadStatus != ADHOCCTL_STATE_CONNECTED) && (cnt < adhocDefaultTimeout)) { + sleep_ms(1); + cnt++; + } + } + // Iterate Matching Contexts - SceNetAdhocMatchingContext * item = contexts; for (; item != NULL; item = item->next) { + SceNetAdhocMatchingContext * item = contexts; + for (; item != NULL; item = item->next) { // Port Match found if (item->port == port) return ERROR_NET_ADHOC_MATCHING_PORT_IN_USE; } @@ -2679,11 +2946,6 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle context->eventlock = new std::recursive_mutex; context->inputlock = new std::recursive_mutex; - // Create fake thread - //#define PSP_THREAD_ATTR_KERNEL 0x00001000 // PSP_THREAD_ATTR_KERNEL is located in sceKernelThread.cpp instead of sceKernelThread.h :( - //context->matching_thid = __KernelCreateThreadInternal("AdhocMatching", 0, idleThreadHackAddr, 0x7f, 4096, PSP_THREAD_ATTR_KERNEL); - //context->matchingThread = new HLEHelperThread("AdhocMatching", "AdhocMatchingMod", "AdhocMatchingFunc", 0x7f, 4096); //8192 - // Multithreading Lock peerlock.lock(); //contextlock.lock(); @@ -2732,7 +2994,7 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; } -// TODO: Should we execute the callback used to create the Matching Id if it's a valid address? +// This should be similar with sceNetAdhocMatchingStart2 but using USER_PARTITION_ID (2) for PartitionId params static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, int inthPri, int inthStack, int optLen, u32 optDataAddr) { WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStart(%i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthStack, inthPri, inthStack, optLen, optDataAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) @@ -2771,9 +3033,14 @@ static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, peer->state = PSP_ADHOC_MATCHING_PEER_P2P; }*/ - // Start the Fake PSP Thread - //__KernelStartThread(item->matching_thid, 0, 0); - //item->matchingThread->Start(0, 0); + // Create & Start the Fake PSP Thread + std::string thrname = std::string("MatchingThr") + std::to_string(matchingId); + item->matching_thid = __KernelCreateThread(thrname.c_str(), __KernelGetCurThreadModuleId(), matchingThreadHackAddr, evthPri, evthStack, PSP_THREAD_ATTR_USER, 0, true); + //item->matchingThread = new HLEHelperThread(thrname, "sceNetAdhocMatching", "AdhocMatchingFunc", inthPri, inthStack); + if (item->matching_thid > 0) { + __KernelStartThread(item->matching_thid, 0, 0); + //item->matchingThread->Start(0, 0); + } //Create the threads if (!item->eventRunning) { @@ -2793,11 +3060,88 @@ static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, // Multithreading Unlock peerlock.unlock(); + sleep_ms(adhocEventPollDelayMS); + //hleDelayResult(0, "give some time", adhocMatchingEventDelayMS * 1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? + return 0; } +// With params for Partition ID for the event & input handler stack +static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartitionId, int evthStack, int inthPri, int inthPartitionId, int inthStack, int optLen, u32 optDataAddr) { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStart2(%i, %i, %i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthPartitionId, evthStack, inthPri, inthPartitionId, inthStack, optLen, optDataAddr, currentMIPS->pc); + if (!g_Config.bEnableWlan) + return -1; + + // Multithreading Lock + peerlock.lock(); + + SceNetAdhocMatchingContext* item = findMatchingContext(matchingId); + + if (item != NULL) { + //sceNetAdhocMatchingSetHelloOpt(matchingId, optLen, optDataAddr); //SetHelloOpt only works when context is running + if ((optLen > 0) && Memory::IsValidAddress(optDataAddr)) { + // Allocate the memory and copy the content + if (item->hello != NULL) free(item->hello); + item->hello = (uint8_t*)malloc(optLen); + if (item->hello != NULL) { + Memory::Memcpy(item->hello, optDataAddr, optLen); + item->hellolen = optLen; + item->helloAddr = optDataAddr; + } + //else return ERROR_NET_ADHOC_MATCHING_NO_SPACE; //Faking success to prevent GTA:VCS from stuck unable to choose host/join menu + } + //else return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; // ERROR_NET_ADHOC_MATCHING_INVALID_OPTLEN; // Returning Not Success will cause GTA:VC stuck unable to choose host/join menu + + //Add your own MAC as a member (only if it's empty?) + /*SceNetAdhocMatchingMemberInternal * peer = addMember(item, &item->mac); + switch (item->mode) { + case PSP_ADHOC_MATCHING_MODE_PARENT: + peer->state = PSP_ADHOC_MATCHING_PEER_OFFER; + break; + case PSP_ADHOC_MATCHING_MODE_CHILD: + peer->state = PSP_ADHOC_MATCHING_PEER_CHILD; + break; + case PSP_ADHOC_MATCHING_MODE_P2P: + peer->state = PSP_ADHOC_MATCHING_PEER_P2P; + }*/ + + // Create & Start the Fake PSP Thread + std::string thrname = std::string("MatchingThr") + std::to_string(matchingId); + item->matching_thid = __KernelCreateThread(thrname.c_str(), __KernelGetCurThreadModuleId(), matchingThreadHackAddr, evthPri, evthStack, PSP_THREAD_ATTR_USER, 0, true); + //item->matchingThread = new HLEHelperThread(thrname, "sceNetAdhocMatching", "AdhocMatchingFunc", inthPri, inthStack); + if (item->matching_thid > 0) { + __KernelStartThread(item->matching_thid, 0, 0); + //item->matchingThread->Start(0, 0); + } + + //Create the threads + if (!item->eventRunning) { + item->eventRunning = true; + item->eventThread = std::thread(matchingEventThread, matchingId); + } + if (!item->inputRunning) { + item->inputRunning = true; + item->inputThread = std::thread(matchingInputThread, matchingId); + } + + item->running = 1; + netAdhocMatchingStarted++; + } + //else return ERROR_NET_ADHOC_MATCHING_INVALID_ID; //Faking success to prevent GTA:VCS from stuck unable to choose host/join menu + + // Multithreading Unlock + peerlock.unlock(); + + sleep_ms(adhocEventPollDelayMS); + //hleDelayResult(0,"give some time",adhocEventDelayMS*1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? + + return 0; +} + + static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSelectTarget(%i, %s, %i, %08x) at %08x", matchingId, macAddress, optLen, optDataPtr, currentMIPS->pc); + char tmpmac[18]; + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSelectTarget(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress, tmpmac), optLen, optDataPtr, currentMIPS->pc); if (!g_Config.bEnableWlan) return -1; @@ -2950,7 +3294,8 @@ static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddres } int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingCancelTargetWithOpt(%i, %s, %i, %08x) at %08x", matchingId, macAddress, optLen, optDataPtr, currentMIPS->pc); + char tmpmac[18]; + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingCancelTargetWithOpt(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress, tmpmac), optLen, optDataPtr, currentMIPS->pc); if (!g_Config.bEnableWlan) return -1; @@ -3029,7 +3374,8 @@ int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddres } int sceNetAdhocMatchingCancelTarget(int matchingId, const char *macAddress) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingCancelTarget(%i, %s)", matchingId, macAddress); + char tmpmac[18]; + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingCancelTarget(%i, %s)", matchingId, mac2str((SceNetEtherAddr*)macAddress, tmpmac)); if (!g_Config.bEnableWlan) return -1; return sceNetAdhocMatchingCancelTargetWithOpt(matchingId, macAddress, 0, 0); @@ -3067,7 +3413,7 @@ int sceNetAdhocMatchingGetHelloOpt(int matchingId, u32 optLenAddr, u32 optDataAd } int sceNetAdhocMatchingSetHelloOpt(int matchingId, int optLenAddr, u32 optDataAddr) { - DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSetHelloOpt(%i, %i, %08x) at %08x", matchingId, optLenAddr, optDataAddr, currentMIPS->pc); + VERBOSE_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSetHelloOpt(%i, %i, %08x) at %08x", matchingId, optLenAddr, optDataAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) return -1; @@ -3182,8 +3528,9 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) buf2 = (SceNetAdhocMatchingMemberInfoEmu *)Memory::GetPointer(buf); } - // Number of Connected Peers - uint32_t peercount = countConnectedPeers(context); + // Number of Connected Peers, should we exclude timeout members? + bool excludeTimedout = false; + uint32_t peercount = countConnectedPeers(context, excludeTimedout); // Calculate Connected Peer Bytesize int available = sizeof(SceNetAdhocMatchingMemberInfoEmu) * peercount; @@ -3193,6 +3540,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) { // Get Connected Peer Count *buflen = available; + DEBUG_LOG(SCENET, "MemberList [Connected: %i]", peercount); } // Normal Mode @@ -3226,7 +3574,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) if (context->mode == PSP_ADHOC_MATCHING_MODE_P2P) { // Find P2P Brother - SceNetAdhocMatchingMemberInternal * p2p = findP2P(context); + SceNetAdhocMatchingMemberInternal * p2p = findP2P(context, excludeTimedout); // P2P Brother found if (p2p != NULL) @@ -3240,8 +3588,11 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) else { // Iterate Peer List - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL && filledpeers < requestedpeers; peer = peer->next) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + for (; peer != NULL && filledpeers < requestedpeers; peer = peer->next) { + // Should we exclude timedout members? + if (!excludeTimedout || peer->lastping != 0) // Parent Mode if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { @@ -3269,8 +3620,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) } // Link Result List - int i = 0; - for (; i < filledpeers - 1; i++) + for (int i = 0; i < filledpeers - 1; i++) { // Link Next Element //buf2[i].next = &buf2[i + 1]; @@ -3282,6 +3632,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Fix Buffer Size *buflen = sizeof(SceNetAdhocMatchingMemberInfoEmu) * filledpeers; + DEBUG_LOG(SCENET, "MemberList [Requested: %i][Discovered: %i]", requestedpeers, filledpeers); } // Return Success @@ -3301,7 +3652,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) } int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u32 dataAddr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x)", matchingId, mac, dataLen, dataAddr); + char tmpmac[18]; + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x)", matchingId, mac2str((SceNetEtherAddr*)mac, tmpmac), dataLen, dataAddr); if (!g_Config.bEnableWlan) return -1; @@ -3377,7 +3729,8 @@ int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u3 } int sceNetAdhocMatchingAbortSendData(int matchingId, const char *mac) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingAbortSendData(%i, %s)", matchingId, mac); + char tmpmac[18]; + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingAbortSendData(%i, %s)", matchingId, mac2str((SceNetEtherAddr*)mac, tmpmac)); if (!g_Config.bEnableWlan) return -1; @@ -3436,13 +3789,14 @@ int sceNetAdhocMatchingAbortSendData(int matchingId, const char *mac) { return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; } +// Get the maximum memory usage by the matching library static int sceNetAdhocMatchingGetPoolMaxAlloc() { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocMatchingGetPoolMaxAlloc()"); if (!g_Config.bEnableWlan) return -1; // Lazy way out - hardcoded return value - return (50 * 1024); + return fakePoolSize/2; // (50 * 1024); } int sceNetAdhocMatchingGetPoolStat(u32 poolstatPtr) { @@ -3461,8 +3815,8 @@ int sceNetAdhocMatchingGetPoolStat(u32 poolstatPtr) { { // Fill Poolstat with Fake Data poolstat->pool = fakePoolSize; - poolstat->maximum = fakePoolSize / 8 * 6; - poolstat->free = fakePoolSize / 8 * 7; + poolstat->maximum = fakePoolSize / 2; // Max usage faked to halt the pool + poolstat->free = fakePoolSize - poolstat->maximum; // Return Success return 0; @@ -3478,12 +3832,13 @@ int sceNetAdhocMatchingGetPoolStat(u32 poolstatPtr) { void __NetTriggerCallbacks() { - { - std::lock_guard adhocGuard(adhocEvtMtx); + std::lock_guard adhocGuard(adhocEvtMtx); + int delayus = 1000; //adhocEventPollDelayMS * 1000; - for (auto ¶ms : adhocctlEvents) + /*if (__KernelGetCurThread() == threadAdhocID && (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && IsAdhocctlInCallback() == 0) { + for (auto& params : adhocctlEvents) //(auto params = adhocctlEvents.rbegin(); params != adhocctlEvents.rend(); ++params) { - int flags = params.first; + int flags = params.first; //params->first; int error = params.second; u32_le args[3] = { 0, 0, 0 }; args[0] = flags; @@ -3491,34 +3846,96 @@ void __NetTriggerCallbacks() for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { args[2] = it->second.argument; - __KernelSwitchToThread(threadAdhocID, "AdhocctlHandler Mipscall"); // it's not guaranteed to switch successfully tho - //while (__KernelInCallback()) sleep_ms(1); - __KernelDirectMipsCall(it->second.entryPoint, NULL, args, 3, false); + AfterAdhocMipsCall* after = (AfterAdhocMipsCall*)__KernelCreateAction(actionAfterAdhocMipsCall); + after->SetData(it->first, flags, args[2]); + SetAdhocctlInCallback(true); //IsAdhocctlInCB++; // + __KernelDirectMipsCall(it->second.entryPoint, after, args, 3, false); } } - adhocctlEvents.clear(); // We should only clear this after making sure all callbacks are placed on the right thread tho + adhocctlEvents.clear(); + }*/ + + auto params = adhocctlEvents.begin(); + if (params != adhocctlEvents.end()) + { + u32 flags = params->first; + u32 error = params->second; + u32_le args[3] = { 0, 0, 0 }; + args[0] = flags; + args[1] = error; - for (auto ¶m : matchingEvents) - { - u32_le *args = (u32_le*)¶m; - AfterMatchingMipsCall *after = (AfterMatchingMipsCall *) __KernelCreateAction(actionAfterMatchingMipsCall); - after->SetContextID(args[0], args[1], args[2]); - // Need to make sure currentThread is AdhocMatching's eventThread before calling the callback, and not in the middle of callback - __KernelSwitchToThread(threadAdhocID, "AdhocMatchingEvent Mipscall"); // it's not guaranteed to switch successfully tho - //while (__KernelInCallback()) sleep_ms(1); - __KernelDirectMipsCall(args[5], after, args, 5, false); + if (__KernelGetCurThread() == threadAdhocID && (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && IsAdhocctlInCallback() == 0) { // IsAdhocctlInCB + for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { + DEBUG_LOG(SCENET, "AdhocctlCallback: EVENT[%i] [ID=%i]", flags, it->first); + args[2] = it->second.argument; + AfterAdhocMipsCall* after = (AfterAdhocMipsCall*)__KernelCreateAction(actionAfterAdhocMipsCall); + after->SetData(it->first, flags, args[2]); + SetAdhocctlInCallback(true); //IsAdhocctlInCB++; // + __KernelDirectMipsCall(it->second.entryPoint, after, args, 3, true); + } + adhocctlEvents.pop_front(); + delayus = adhocEventDelayMS * 1000; } - matchingEvents.clear(); // We should only clear this after making sure all callbacks are placed on the right thread tho } - //magically make this work - hleDelayResult(0, "Prevent Adhoc thread from blocking", 1000); + + // Must be delayed long enough whenever there is a pending callback. Should it be 100-500ms for Adhocctl Events? or Not Less than the delays on sceNetAdhocctl HLE? + sceKernelDelayThreadCB(delayus); + //sceKernelDelayThreadCB(adhocEventDelayMS * 1000); + //hleCheckCurrentCallbacks(); + //hleDelayResult(0, "Prevent Adhoc thread from blocking", delayus); + //hleDelayResult(0, "Prevent Adhoc thread from blocking", adhocEventDelayMS * 1000); +} + +void __NetMatchingCallbacks() +{ + std::lock_guard adhocGuard(adhocEvtMtx); + int delayus = 1000; // adhocEventPollDelayMS * 1000; //adhocMatchingEventPollDelayMS * 1000; + + /*if (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) { + for (auto& params : matchingEvents) //(auto ¶ms = matchingEvents.rbegin(); params != matchingEvents.rend(); ++params) + { + u32_le* args = (u32_le*)¶ms; //(u32_le*)& (*params); + auto context = findMatchingContext(args[0]); + //if (__KernelGetCurThread() == context->matching_thid && !IsMatchingInCallback(context)) + { + AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); + after->SetData(args[0], args[1], args[2]); + __KernelDirectMipsCall(args[5], after, args, 5, false); + } + } + matchingEvents.clear(); + }*/ + + auto params = matchingEvents.begin(); + if (params != matchingEvents.end()) + { + u32_le* args = (u32_le*)&(*params); + auto context = findMatchingContext(args[0]); + + if (__KernelGetCurThread() == context->matching_thid && (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && !IsMatchingInCallback(context)) { + DEBUG_LOG(SCENET, "AdhocMatchingCallback: EVENT[%i] [ID=%i]", args[1], args[0]); + AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); + after->SetData(args[0], args[1], args[2]); + SetMatchingInCallback(context, true); + __KernelDirectMipsCall(args[5], after, args, 5, true); + matchingEvents.pop_front(); + delayus = adhocMatchingEventDelayMS * 1000; //adhocEventPollDelayMS * 1000; + } + } + + // Must be delayed long enough whenever there is a pending callback. Should it be 10-100ms for Matching Events? or Not Less than the delays on sceNetAdhocMatching HLE? + sceKernelDelayThreadCB(delayus); + //sceKernelDelayThreadCB(adhocMatchingEventDelayMS * 1000); + //hleCheckCurrentCallbacks(); + //hleDelayResult(0, "Prevent AdhocMatching thread from blocking", delayus); + //hleDelayResult(0, "Prevent Adhoc thread from blocking", adhocEventPollDelayMS * 1000); } const HLEFunction sceNetAdhoc[] = { {0XE1D621D7, &WrapU_V, "sceNetAdhocInit", 'x', "" }, {0XA62C6F57, &WrapI_V, "sceNetAdhocTerm", 'i', "" }, {0X0AD043ED, &WrapI_U, "sceNetAdhocctlConnect", 'i', "x" }, - {0X6F92741B, &WrapI_CUIU, "sceNetAdhocPdpCreate", 'i', "sxix" }, + {0X6F92741B, &WrapI_CIIU, "sceNetAdhocPdpCreate", 'i', "siix" }, {0XABED3790, &WrapI_ICUVIII, "sceNetAdhocPdpSend", 'i', "isxpiii" }, {0XDFE53E03, &WrapI_IVVVVUI, "sceNetAdhocPdpRecv", 'i', "ippppxi" }, {0X7F27BB5E, &WrapI_II, "sceNetAdhocPdpDelete", 'i', "ii" }, @@ -3550,6 +3967,7 @@ const HLEFunction sceNetAdhocMatching[] = { {0X7945ECDA, &WrapI_V, "sceNetAdhocMatchingTerm", 'i', "" }, {0XCA5EDA6F, &WrapI_IIIIIIIIU, "sceNetAdhocMatchingCreate", 'i', "iiiiiiiix"}, {0X93EF3843, &WrapI_IIIIIIU, "sceNetAdhocMatchingStart", 'i', "iiiiiix" }, + {0xE8454C65, &WrapI_IIIIIIIIU, "sceNetAdhocMatchingStart2", 'i', "iiiiiiiix"}, {0X32B156B3, &WrapI_I, "sceNetAdhocMatchingStop", 'i', "i" }, {0XF16EAF4F, &WrapI_I, "sceNetAdhocMatchingDelete", 'i', "i" }, {0X5E3D4B79, &WrapI_ICIU, "sceNetAdhocMatchingSelectTarget", 'i', "isix" }, @@ -3562,6 +3980,8 @@ const HLEFunction sceNetAdhocMatching[] = { {0XEC19337D, &WrapI_IC, "sceNetAdhocMatchingAbortSendData", 'i', "is" }, {0X40F8F435, &WrapI_V, "sceNetAdhocMatchingGetPoolMaxAlloc", 'i', "" }, {0X9C5CFB7D, &WrapI_U, "sceNetAdhocMatchingGetPoolStat", 'i', "x" }, + // Fake function for PPSSPP's use. + {0X756E6F00, &WrapV_V<__NetMatchingCallbacks>, "__NetMatchingCallbacks", 'v', "" }, }; static int sceNetAdhocctlExitGameMode() { @@ -3571,7 +3991,12 @@ static int sceNetAdhocctlExitGameMode() { static int sceNetAdhocctlGetGameModeInfo(u32 infoAddr) { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlGetGameModeInfo(%08x)", infoAddr); - return -1; + + SceNetAdhocctlGameModeInfo* gmInfo = NULL; + if (Memory::IsValidAddress(infoAddr)) gmInfo = (SceNetAdhocctlGameModeInfo*)Memory::GetPointer(infoAddr); + // TODO: Writes number of participants and each participating MAC address into infoAddr/gmInfo + + return 0; } static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { @@ -3580,7 +4005,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { SceNetAdhocctlPeerInfoEmu *buf = NULL; if (Memory::IsValidAddress(bufAddr)) buf = (SceNetAdhocctlPeerInfoEmu *)Memory::GetPointer(bufAddr); - DEBUG_LOG(SCENET, "sceNetAdhocctlGetPeerList([%08x]=%i, %08x) at %08x", sizeAddr, buflen ? *buflen : -1, bufAddr, currentMIPS->pc); + DEBUG_LOG(SCENET, "sceNetAdhocctlGetPeerList([%08x]=%i, %08x) at %08x", sizeAddr, /*buflen ? *buflen : -1*/Memory::Read_U32(sizeAddr), bufAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; } @@ -3593,8 +4018,11 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { peerlock.lock(); // Length Calculation Mode - if (buf == NULL) *buflen = getActivePeerCount() * sizeof(SceNetAdhocctlPeerInfoEmu); - + if (buf == NULL) { + int activePeers = getActivePeerCount(); + *buflen = activePeers * sizeof(SceNetAdhocctlPeerInfoEmu); + DEBUG_LOG(SCENET, "PeerList [Active: %i]", activePeers); + } // Normal Mode else { // Discovery Counter @@ -3613,20 +4041,23 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { // Iterate Peers for (; peer != NULL && discovered < requestcount; peer = peer->next) { - // Fake Receive Time - if (peer->last_recv != 0) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); - - // Copy Peer Info - buf[discovered].nickname = peer->nickname; - buf[discovered].mac_addr = peer->mac_addr; - buf[discovered].ip_addr = peer->ip_addr; - buf[discovered].last_recv = peer->last_recv; - discovered++; + // Exclude Soon to be timedout peers + if (peer->last_recv != 0) { + // Fake Receive Time + //if (peer->last_recv != 0) + peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + // Copy Peer Info + buf[discovered].nickname = peer->nickname; + buf[discovered].mac_addr = peer->mac_addr; + buf[discovered].ip_addr = peer->ip_addr; + buf[discovered].last_recv = peer->last_recv; + discovered++; + } } // Link List - int i = 0; for (; i < discovered - 1; i++) { + for (int i = 0; i < discovered - 1; i++) { // Link Network buf[i].next = bufAddr+(sizeof(SceNetAdhocctlPeerInfoEmu)*i) + sizeof(SceNetAdhocctlPeerInfoEmu); } @@ -3636,6 +4067,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { // Fix Size *buflen = discovered * sizeof(SceNetAdhocctlPeerInfoEmu); + DEBUG_LOG(SCENET, "PeerList [Requested: %i][Discovered: %i]", requestcount, discovered); } // Multithreading Unlock @@ -3656,8 +4088,12 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 bufAddr) { s32_le *buflen = NULL; //int32_t if (Memory::IsValidAddress(sizeAddr)) buflen = (s32_le *)Memory::GetPointer(sizeAddr); + + char nckName[ADHOCCTL_NICKNAME_LEN]; + memcpy(nckName, nickName, ADHOCCTL_NICKNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + nckName[ADHOCCTL_NICKNAME_LEN - 1] = 0; - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlGetPeerList(%s, [%08x]=%i, %08x)", nickName, sizeAddr, buflen ? *buflen : -1, bufAddr); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlGetAddrByName(%s, [%08x]=%i/%i, %08x)", nckName, sizeAddr, buflen ? *buflen : -1, sizeof(SceNetAdhocctlPeerInfoEmu), bufAddr); // Library initialized if (netAdhocctlInited) @@ -3727,7 +4163,7 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b } // Link List - int i = 0; for (; i < discovered - 1; i++) + for (int i = 0; i < discovered - 1; i++) { // Link Network buf[i].next = bufAddr + (sizeof(SceNetAdhocctlPeerInfoEmu)*i) + sizeof(SceNetAdhocctlPeerInfoEmu); @@ -3806,7 +4242,7 @@ int sceNetAdhocDiscoverGetStatus() { return 0; } -int sceNetAdhocDiscoverRequestSuspend(void) +int sceNetAdhocDiscoverRequestSuspend() { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocDiscoverRequestSuspend()"); return 0; @@ -3854,8 +4290,11 @@ void broadcastHelloMessage(SceNetAdhocMatchingContext * context) // Allocate Hello Message Buffer, reuse when necessary if ((int32_t)context->hellolen > len) { - hello = (uint8_t *)realloc(hello, 5 + context->hellolen); - len = context->hellolen; + uint8_t* tmp = (uint8_t *)realloc(hello, 5 + context->hellolen); + if (tmp != NULL) { + hello = tmp; + len = context->hellolen; + } } // Allocated Hello Message Buffer @@ -3905,7 +4344,7 @@ void sendAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * ma int siblingcount = siblingbuflen / sizeof(SceNetEtherAddr); // Allocate Accept Message Buffer - uint8_t * accept = (uint8_t *)malloc(9 + optlen + siblingbuflen); + uint8_t * accept = (uint8_t *)malloc(9 + (uint32_t)optlen + siblingbuflen); // Allocated Accept Message Buffer if (accept != NULL) @@ -3932,7 +4371,8 @@ void sendAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * ma int i = 0; // Iterate Peer List - SceNetAdhocMatchingMemberInternal * item = context->peerlist; for (; item != NULL; item = item->next) + SceNetAdhocMatchingMemberInternal * item = context->peerlist; + for (; item != NULL; item = item->next) { // Ignore Target if (item == peer) continue; @@ -4127,7 +4567,8 @@ void sendBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac memcpy(packet + 1, mac, sizeof(SceNetEtherAddr)); // Iterate Peers - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + for (; peer != NULL; peer = peer->next) { // Skip Newborn Child if (peer == newborn) continue; @@ -4141,10 +4582,11 @@ void sendBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac context->socketlock->unlock(); // Log Send Success + char tmpmac[18]; if (sent >= 0) - INFO_LOG(SCENET, "InputLoop: Sending BIRTH to %02X:%02X:%02X:%02X:%02X:%02X", peer->mac.data[0], peer->mac.data[1], peer->mac.data[2], peer->mac.data[3], peer->mac.data[4], peer->mac.data[5]); + INFO_LOG(SCENET, "InputLoop: Sending BIRTH to %s", mac2str(&peer->mac, tmpmac)); else - WARN_LOG(SCENET, "InputLoop: Failed to Send BIRTH to %02X:%02X:%02X:%02X:%02X:%02X", peer->mac.data[0], peer->mac.data[1], peer->mac.data[2], peer->mac.data[3], peer->mac.data[4], peer->mac.data[5]); + WARN_LOG(SCENET, "InputLoop: Failed to Send BIRTH to %s", mac2str(&peer->mac, tmpmac)); } } } @@ -4173,7 +4615,8 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac memcpy(packet + 1, mac, sizeof(SceNetEtherAddr)); // Iterate Peers - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + for (; peer != NULL; peer = peer->next) { // Skip dead Child if (peer == deadkid) continue; @@ -4197,7 +4640,8 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac void sendByePacket(SceNetAdhocMatchingContext * context) { // Iterate Peers - SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) + SceNetAdhocMatchingMemberInternal * peer = context->peerlist; + for (; peer != NULL; peer = peer->next) { // Peer of Interest if (peer->state == PSP_ADHOC_MATCHING_PEER_PARENT || peer->state == PSP_ADHOC_MATCHING_PEER_CHILD || peer->state == PSP_ADHOC_MATCHING_PEER_P2P) @@ -4519,7 +4963,8 @@ void actOnCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * s else if (parent == peer) { // Iterate Peers - SceNetAdhocMatchingMemberInternal * item = context->peerlist; for (; item != NULL; item = item->next) + SceNetAdhocMatchingMemberInternal * item = context->peerlist; + for (; item != NULL; item = item->next) { // Established Peer if (item->state == PSP_ADHOC_MATCHING_PEER_CHILD || item->state == PSP_ADHOC_MATCHING_PEER_PARENT) @@ -4746,13 +5191,16 @@ void actOnByePacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * send // Delete Peer deletePeer(context, peer); + // Instead of removing peer immediately, We should give a little time before removing the peer and let it timed out? just in case the game is in the middle of communicating with the peer on another thread so it won't recognize it as Unknown peer + //peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); } // Parent Bye else if (context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) { // Iterate Peers - SceNetAdhocMatchingMemberInternal * item = context->peerlist; for (; item != NULL; item = item->next) + SceNetAdhocMatchingMemberInternal * item = context->peerlist; + for (; item != NULL; item = item->next) { // Established Peer if (item->state == PSP_ADHOC_MATCHING_PEER_CHILD || item->state == PSP_ADHOC_MATCHING_PEER_PARENT) @@ -4777,6 +5225,7 @@ void actOnByePacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * send */ int matchingEventThread(int matchingId) { + setCurrentThreadName("MatchingEvent"); // Multithreading Lock peerlock.lock(); // Cast Context @@ -4790,26 +5239,34 @@ int matchingEventThread(int matchingId) // Run while needed... if (context != NULL) { u32 bufLen = context->rxbuflen; //0; - u32 bufAddr = 0; //userMemory.Alloc(bufLen); + u32 bufAddr = 0; //= userMemory.Alloc(bufLen); //context->rxbuf; //static u32_le args[5] = { 0, 0, 0, 0, 0 }; // Need to be global/static so it can be accessed from a different thread - u32_le * args = context->handlerArgs; + u32_le * args = context->handlerArgs; //MatchingArgs - while (context->eventRunning) // (context->eventThread.get_id() != NULL) + while (contexts != NULL && context->eventRunning) // (context->eventThread.get_id() != NULL) { + // Multithreading Lock + peerlock.lock(); + // Cast Context + context = findMatchingContext(matchingId); + // Multithreading Unlock + peerlock.unlock(); + // Messages on Stack ready for processing - if (context->event_stack != NULL) + if (context != NULL && context->event_stack != NULL) { // Claim Stack context->eventlock->lock(); // Iterate Message List - ThreadMessage * msg = context->event_stack; for (; msg != NULL; msg = msg->next) + ThreadMessage * msg = context->event_stack; + /*for (; msg != NULL; msg = msg->next) { // Default Optional Data - void * opt = NULL; + void* opt = NULL; // Grab Optional Data - if (msg->optlen > 0) opt = ((u8 *)msg) + sizeof(ThreadMessage); //&msg[1] + if (msg->optlen > 0) opt = ((u8*)msg) + sizeof(ThreadMessage); //&msg[1] // Log Matching Events INFO_LOG(SCENET, "EventLoop[%d]: Matching Event [%d=%s] OptSize=%d", matchingId, msg->opcode, getMatchingEventStr(msg->opcode), msg->optlen); @@ -4820,30 +5277,73 @@ int matchingEventThread(int matchingId) // Notify Event Handlers notifyMatchingHandler(context, msg, opt, bufAddr, bufLen, args); context->eventlock->lock(); // Lock again + + // Give some time before executing the next mipscall to prevent event ACCEPT(6)->ESTABLISH(7) getting reversed After Action ESTABLISH(7)->ACCEPT(6) + sleep_ms(adhocEventPollDelayMS); // If we're using shared Buffer & Args for all Events We should wait for the Mipscall to be fully executed before processing the next event } // Clear Event Message Stack clearStack(context, PSP_ADHOC_MATCHING_EVENT_STACK); + */ + if (msg != NULL) + { + // Default Optional Data + void* opt = NULL; + + // Grab Optional Data + if (msg->optlen > 0) opt = ((u8*)msg) + sizeof(ThreadMessage); //&msg[1] + + // Log Matching Events + INFO_LOG(SCENET, "EventLoop[%d]: Matching Event [%d=%s] OptSize=%d", matchingId, msg->opcode, getMatchingEventStr(msg->opcode), msg->optlen); + + // Unlock to prevent race-condition with other threads due to recursive lock + context->eventlock->unlock(); + // Call Event Handler + //context->handler(context->id, msg->opcode, &msg->mac, msg->optlen, opt); + // Notify Event Handlers + notifyMatchingHandler(context, msg, opt, bufAddr, bufLen, args); // If we're using shared Buffer & Args for All Events We should wait for the Mipscall to be fully executed before processing the next event. GTA VCS need this delay/sleep. + + // Give some time before executing the next mipscall to prevent event ACCEPT(6)->ESTABLISH(7) getting reversed After Action ESTABLISH(7)->ACCEPT(6) + //do { + // //sceKernelDelayThread(adhocEventPollDelayMS * 1000); //adhocMatchingEventDelayMS * 1000 + // sleep_ms(1); + //} while (IsMatchingInCallback(context)); + + // Must Not be delayed too long to prevent desync/disconnect. Not longer than the delays on callback's HLE? + //sleep_ms(adhocEventPollDelayMS); //adhocMatchingEventDelayMS //adhocEventPollDelayMS //sceKernelDelayThread(10000); + + // Lock again + context->eventlock->lock(); + + // Pop event stack from front (this should be queue instead of stack?) + context->event_stack = msg->next; + free(msg); + msg = NULL; + } + + // Clear Event Message Stack + //clearStack(context, PSP_ADHOC_MATCHING_EVENT_STACK); // Free Stack context->eventlock->unlock(); } // Share CPU Time - sleep_ms(1); //10 //sceKernelDelayThread(10000); + sleep_ms(1); // Don't do anything if it's paused, otherwise the log will be flooded - while (Core_IsStepping() && context->eventRunning) sleep_ms(1); + while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->eventRunning) sleep_ms(1); } // Process Last Messages - if (context->event_stack != NULL) + if (contexts != NULL && context->event_stack != NULL) { // Claim Stack context->eventlock->lock(); // Iterate Message List - ThreadMessage * msg = context->event_stack; for (; msg != NULL; msg = msg->next) + ThreadMessage * msg = context->event_stack; + for (; msg != NULL; msg = msg->next) { // Default Optional Data void * opt = NULL; @@ -4888,8 +5388,9 @@ int matchingEventThread(int matchingId) * @param argp SceNetAdhocMatchingContext * * @return Exit Point is never reached... */ -int matchingInputThread(int matchingId) +int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is using sceNetAdhocPdpRecv & sceNetAdhocPdpSend functions so it might be better to run this on PSP thread instead of real thread { + setCurrentThreadName("MatchingInput"); // Multithreading Lock peerlock.lock(); // Cast Context @@ -4910,157 +5411,171 @@ int matchingInputThread(int matchingId) // Run while needed... if (context != NULL) { - while (context->inputRunning) + while (contexts != NULL && context->inputRunning) { - now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + // Multithreading Lock + peerlock.lock(); + // Cast Context + context = findMatchingContext(matchingId); + // Multithreading Unlock + peerlock.unlock(); - // Hello Message Sending Context with unoccupied Slots - if ((context->mode == PSP_ADHOC_MATCHING_MODE_PARENT && (countChildren(context) < (context->maxpeers - 1))) || (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && findP2P(context) == NULL)) - { - // Hello Message Broadcast necessary because of Hello Interval - if (context->hello_int > 0) - if ((now - lasthello) >= context->hello_int) + if (context != NULL) { + now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + + // Hello Message Sending Context with unoccupied Slots + if ((context->mode == PSP_ADHOC_MATCHING_MODE_PARENT && (countChildren(context) < (context->maxpeers - 1))) || (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && findP2P(context) == NULL)) { - // Broadcast Hello Message - broadcastHelloMessage(context); + // Hello Message Broadcast necessary because of Hello Interval + if (context->hello_int > 0) + if ((now - lasthello) >= context->hello_int) + { + // Broadcast Hello Message + broadcastHelloMessage(context); - // Update Hello Timer - lasthello = now; + // Update Hello Timer + lasthello = now; + } } - } - // Ping Required - if (context->keepalive_int > 0) - if ((now - lastping) >= context->keepalive_int) - { - // Broadcast Ping Message - broadcastPingMessage(context); + // Ping Required + if (context->keepalive_int > 0) + if ((now - lastping) >= context->keepalive_int) + { + // Broadcast Ping Message + broadcastPingMessage(context); - // Update Ping Timer - lastping = now; - } + // Update Ping Timer + lastping = now; + } - // Messages on Stack ready for processing - if (context->input_stack != NULL) - { - // Claim Stack - context->inputlock->lock(); - - // Iterate Message List - ThreadMessage * msg = context->input_stack; - for (; msg != NULL; msg = msg->next) + // Messages on Stack ready for processing + if (context->input_stack != NULL) { - // Default Optional Data - void * opt = NULL; + // Claim Stack + context->inputlock->lock(); - // Grab Optional Data - if (msg->optlen > 0) opt = ((u8 *)msg) + sizeof(ThreadMessage); + // Iterate Message List + ThreadMessage* msg = context->input_stack; + for (; msg != NULL; msg = msg->next) + { + // Default Optional Data + void* opt = NULL; - context->inputlock->unlock(); // Unlock to prevent race condition when locking peerlock + // Grab Optional Data + if (msg->optlen > 0) opt = ((u8*)msg) + sizeof(ThreadMessage); - // Send Accept Packet - if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_ACCEPT) sendAcceptPacket(context, &msg->mac, msg->optlen, opt); + context->inputlock->unlock(); // Unlock to prevent race condition when locking peerlock - // Send Join Packet - else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_JOIN) sendJoinPacket(context, &msg->mac, msg->optlen, opt); + // Send Accept Packet + if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_ACCEPT) sendAcceptPacket(context, &msg->mac, msg->optlen, opt); - // Send Cancel Packet - else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_CANCEL) sendCancelPacket(context, &msg->mac, msg->optlen, opt); + // Send Join Packet + else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_JOIN) sendJoinPacket(context, &msg->mac, msg->optlen, opt); - // Send Bulk Data Packet - else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_BULK) sendBulkDataPacket(context, &msg->mac, msg->optlen, opt); + // Send Cancel Packet + else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_CANCEL) sendCancelPacket(context, &msg->mac, msg->optlen, opt); - // Send Birth Packet - else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_BIRTH) sendBirthPacket(context, &msg->mac); + // Send Bulk Data Packet + else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_BULK) sendBulkDataPacket(context, &msg->mac, msg->optlen, opt); - // Cancel Bulk Data Transfer (does nothing as of now as we fire and forget anyway) // Do we need to check DeathPacket and BytePacket here? - // else if(msg->opcode == PSP_ADHOC_MATCHING_PACKET_BULK_ABORT) blabla; + // Send Birth Packet + else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_BIRTH) sendBirthPacket(context, &msg->mac); - context->inputlock->lock(); // Lock again + // Cancel Bulk Data Transfer (does nothing as of now as we fire and forget anyway) // Do we need to check DeathPacket and ByePacket here? + //else if(msg->opcode == PSP_ADHOC_MATCHING_PACKET_BULK_ABORT) sendAbortBulkDataPacket(context, &msg->mac, msg->optlen, opt); + + context->inputlock->lock(); // Lock again + } + + // Clear IO Message Stack + clearStack(context, PSP_ADHOC_MATCHING_INPUT_STACK); + + // Free Stack + context->inputlock->unlock(); } - // Clear IO Message Stack - clearStack(context, PSP_ADHOC_MATCHING_INPUT_STACK); + // Receive PDP Datagram + SceNetEtherAddr sendermac; + uint16_t senderport; + int rxbuflen = context->rxbuflen; + context->socketlock->lock(); + int recvresult = sceNetAdhocPdpRecv(context->socket, &sendermac, &senderport, context->rxbuf, &rxbuflen, 0, ADHOC_F_NONBLOCK); + context->socketlock->unlock(); - // Free Stack - context->inputlock->unlock(); + // Received Data from a Sender that interests us + if (recvresult == 0 && rxbuflen > 0 && context->port == senderport) + { + // Log Receive Success + if (context->rxbuf[0] > 1) { + INFO_LOG(SCENET, "InputLoop[%d]: Received %d Bytes (Opcode[%d]=%s)", matchingId, rxbuflen, context->rxbuf[0], getMatchingOpcodeStr(context->rxbuf[0])); + } + + // Update Peer Timestamp + peerlock.lock(); + SceNetAdhocctlPeerInfo* peer = findFriend(&sendermac); + if (peer != NULL) { + now = CoreTiming::GetGlobalTimeUsScaled(); + u64_le delta = now - peer->last_recv; + char tmpmac[18]; + DEBUG_LOG(SCENET, "Timestamp Delta: %llu (%llu - %llu) from %s", delta, now, peer->last_recv, mac2str(&sendermac, tmpmac)); + if (/*context->rxbuf[0] > 0 &&*/ peer->last_recv != 0) peer->last_recv = now; // - context->keepalive_int; // May need to deduce by ping interval to prevent Dissidia 012 unable to see other players (ie. disappearing issue) + } + peerlock.unlock(); + + // Ping Packet + if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_PING) actOnPingPacket(context, &sendermac); + + // Hello Packet + else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_HELLO) actOnHelloPacket(context, &sendermac, rxbuflen); + + // Join Packet + else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_JOIN) actOnJoinPacket(context, &sendermac, rxbuflen); + + // Accept Packet + else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_ACCEPT) actOnAcceptPacket(context, &sendermac, rxbuflen); + + // Cancel Packet + else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_CANCEL) actOnCancelPacket(context, &sendermac, rxbuflen); + + // Bulk Data Packet + else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_BULK) actOnBulkDataPacket(context, &sendermac, rxbuflen); + + // Abort Bulk Data Packet + //else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_BULK_ABORT) actOnAbortBulkDataPacket(context, &sendermac, rxbuflen); + + // Birth Packet + else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_BIRTH) actOnBirthPacket(context, &sendermac, rxbuflen); + + // Death Packet + else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_DEATH) actOnDeathPacket(context, &sendermac, rxbuflen); + + // Bye Packet + else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_BYE) actOnByePacket(context, &sendermac); + + // Ignore Incoming Trash Data + } + + // Handle Peer Timeouts + handleTimeout(context); } - - // Receive PDP Datagram - SceNetEtherAddr sendermac; - uint16_t senderport; - int rxbuflen = context->rxbuflen; - context->socketlock->lock(); - int recvresult = sceNetAdhocPdpRecv(context->socket, &sendermac, &senderport, context->rxbuf, &rxbuflen, 0, ADHOC_F_NONBLOCK); - context->socketlock->unlock(); - - // Received Data from a Sender that interests us - if (recvresult == 0 && rxbuflen > 0 && context->port == senderport) - { - // Log Receive Success - if (context->rxbuf[0] > 1) { - INFO_LOG(SCENET, "InputLoop[%d]: Received %d Bytes (Opcode[%d]=%s)", matchingId, rxbuflen, context->rxbuf[0], getMatchingOpcodeStr(context->rxbuf[0])); - } - - // Update Peer Timestamp - peerlock.lock(); - SceNetAdhocctlPeerInfo * peer = findFriend(&sendermac); - if (peer != NULL) { - now = CoreTiming::GetGlobalTimeUsScaled(); - u64_le delta = now - peer->last_recv; - DEBUG_LOG(SCENET, "Timestamp Delta: %llu (%llu - %llu)", delta, now, peer->last_recv); - if (/*context->rxbuf[0] > 0 &&*/ peer->last_recv != 0) peer->last_recv = now; // - context->keepalive_int; // May need to deduce by ping interval to prevent Dissidia 012 unable to see other players (ie. disappearing issue) - } - peerlock.unlock(); - - // Ping Packet - if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_PING) actOnPingPacket(context, &sendermac); - - // Hello Packet - else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_HELLO) actOnHelloPacket(context, &sendermac, rxbuflen); - - // Join Packet - else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_JOIN) actOnJoinPacket(context, &sendermac, rxbuflen); - - // Accept Packet - else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_ACCEPT) actOnAcceptPacket(context, &sendermac, rxbuflen); - - // Cancel Packet - else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_CANCEL) actOnCancelPacket(context, &sendermac, rxbuflen); - - // Bulk Data Packet - else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_BULK) actOnBulkDataPacket(context, &sendermac, rxbuflen); - - // Birth Packet - else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_BIRTH) actOnBirthPacket(context, &sendermac, rxbuflen); - - // Death Packet - else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_DEATH) actOnDeathPacket(context, &sendermac, rxbuflen); - - // Bye Packet - else if (context->rxbuf[0] == PSP_ADHOC_MATCHING_PACKET_BYE) actOnByePacket(context, &sendermac); - - // Ignore Incoming Trash Data - } - - // Handle Peer Timeouts - handleTimeout(context); - // Share CPU Time sleep_ms(1); //10 //sceKernelDelayThread(10000); // Don't do anything if it's paused, otherwise the log will be flooded - while (Core_IsStepping() && context->inputRunning) sleep_ms(1); + while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->inputRunning) sleep_ms(1); } - // Send Bye Messages - sendByePacket(context); + if (contexts != NULL) { + // Send Bye Messages + sendByePacket(context); - // Free Peer List Buffer - clearPeerList(context); //deleteAllMembers(context); + // Free Peer List Buffer + clearPeerList(context); //deleteAllMembers(context); - // Delete Pointer Reference (and notify caller about finished cleanup) - //context->inputThread = NULL; + // Delete Pointer Reference (and notify caller about finished cleanup) + //context->inputThread = NULL; + } } // Log Shutdown diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 0f30ebe6b8..73720e15a3 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -17,6 +17,8 @@ #pragma once +#include "Core/HLE/proAdhoc.h" + typedef struct MatchingArgs { u32_le data[6]; //ContextID, Opcode, bufAddr[ to MAC], OptLen, OptAddr[, EntryPoint] } PACK; @@ -25,6 +27,7 @@ class PointerWrap; void Register_sceNetAdhoc(); +u32_le __CreateHLELoop(u32_le* loopAddr, const char* sceFuncName, const char* hleFuncName, const char* tagName = NULL); void __NetAdhocInit(); void __NetAdhocShutdown(); void __NetAdhocDoState(PointerWrap &p); @@ -37,5 +40,12 @@ int sceNetAdhocctlCreate(const char * groupName); // May need to use these from sceNet.cpp extern bool netAdhocInited; extern bool netAdhocctlInited; +extern int adhocDefaultTimeout; +extern int adhocEventPollDelayMS; +extern int adhocMatchingEventDelayMS; +extern int adhocEventDelayMS; +extern std::recursive_mutex adhocEvtMtx; +extern int IsAdhocctlInCB; + int sceNetAdhocctlTerm(); int sceNetAdhocTerm(); From d8186a83307b111880c2eed5456f36c85a36bd40 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 10 Feb 2020 13:35:11 +0700 Subject: [PATCH 312/848] Fix i18n type --- Core/HLE/proAdhocServer.cpp | 2 +- Core/HLE/sceNet.cpp | 2 +- Core/HLE/sceNetAdhoc.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index f509ba59ad..f073865270 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -1806,7 +1806,7 @@ int create_listen_socket(uint16_t port) // Notify User else { ERROR_LOG(SCENET, "AdhocServer: Bind returned %i (Socket error %d)", bindresult, errno); - I18NCategory* n = GetI18NCategory("Networking"); + auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(std::string(n->T("AdhocServer Failed to Bind Port")) + " " + std::to_string(port), 3.0, 0x0000ff); } diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index b9f9238200..da1110c1f4 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -252,7 +252,7 @@ Parameters: netintrprio - Priority of the SceNetNetintr thread. netintrstack - Stack size of the SceNetNetintr thread (defaults to 4096 on non 1.5 firmware regardless of what value is passed). */ -static u32 sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) { +static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) { // TODO: Create Network Threads using given priority & stack // TODO: The correct behavior is actually to allocate more and leak the other threads/pool. // But we reset here for historic reasons (GTA:VCS potentially triggers this.) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index ce16cee15e..5cd8e052d4 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -384,7 +384,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u retval = ERROR_NET_ADHOC_PORT_IN_USE; if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "Socket error (%i) when binding port %u", errno, ntohs(addr.sin_port)); - I18NCategory* n = GetI18NCategory("Networking"); + auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(port + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); } } @@ -1889,7 +1889,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, } else { ERROR_LOG(SCENET, "Socket error (%i) when binding port %u", errno, ntohs(addr.sin_port)); - I18NCategory* n = GetI18NCategory("Networking"); + auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(sport + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); } @@ -2391,7 +2391,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int } } else { - I18NCategory* n = GetI18NCategory("Networking"); + auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(sport + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); } From fa36c2edabc139beea49d70250a796835c64820c Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 25 Dec 2019 22:30:39 +0700 Subject: [PATCH 313/848] Improved multiplayer stability regardless of I/O Timing method --- Core/HLE/proAdhoc.cpp | 6 ++--- Core/HLE/proAdhoc.h | 39 ++++++++++++++++--------------- Core/HLE/sceNet.h | 6 +++++ Core/HLE/sceNetAdhoc.cpp | 50 +++++++++++++++++++++------------------- Core/HLE/sceNetAdhoc.h | 8 ++++++- 5 files changed, 62 insertions(+), 47 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 043ca79e6e..48850e5ad8 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -98,12 +98,12 @@ bool isPTPPortInUse(uint16_t port) { } char* mac2str(SceNetEtherAddr* mac) { - if (mac == NULL) return ":::::"; #if defined(_WIN32) - static __declspec(thread) char str[18]; + static __declspec(thread) char str[18] = ":::::"; #else - static __thread char str[18]; + static __thread char str[18] = ":::::"; #endif + if (mac == NULL) return str; snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]); return str; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index e4bae1266f..7dc32fd8d7 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -17,25 +17,6 @@ #pragma once -#include -#include - -#include "base/timeutil.h" -#include "net/resolve.h" -#include "Common/ChunkFile.h" - -#include "Core/CoreTiming.h" -#include "Core/MemMap.h" -#include "Core/HLE/HLE.h" -#include "Core/HLE/HLEHelperThread.h" -#include "Core/HLE/sceNetAdhoc.h" -#include "Core/HLE/sceKernelThread.h" -#include "Core/HLE/sceKernel.h" -#include "Core/HLE/sceKernelMutex.h" -#include "Core/HLE/sceUtility.h" - -class PointerWrap; - // Net stuff #if defined(_WIN32) #include @@ -57,6 +38,24 @@ class PointerWrap; #define PACK __attribute__((packed)) #endif +#include +#include + +#include "base/timeutil.h" +#include "net/resolve.h" +#include "Common/ChunkFile.h" + +#include "Core/Config.h" +#include "Core/CoreTiming.h" +#include "Core/MemMap.h" +#include "Core/HLE/HLE.h" +#include "Core/HLE/HLEHelperThread.h" +#include "Core/HLE/sceNetAdhoc.h" +#include "Core/HLE/sceKernelThread.h" +#include "Core/HLE/sceKernel.h" +#include "Core/HLE/sceKernelMutex.h" +#include "Core/HLE/sceUtility.h" + #ifdef _WIN32 #undef errno #undef ECONNABORTED @@ -779,6 +778,8 @@ typedef struct { #pragma pack(pop) #endif +class PointerWrap; + class AfterAdhocMipsCall : public PSPAction { public: AfterAdhocMipsCall() {} diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index bf7d006884..2f7a9044bd 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -55,6 +55,9 @@ enum { PSP_NET_APCTL_EVENT_DISCONNECT_REQUEST = 5, }; +#ifdef _MSC_VER +#pragma pack(push,1) +#endif // Sockaddr typedef struct SceNetInetSockaddr { uint8_t sa_len; @@ -82,6 +85,9 @@ typedef struct ProductStruct { // Similar to SceNetAdhocctlAdhocId ? s32_le unknown; // Unknown, set to 0 // Product Type ? char product[PRODUCT_CODE_LENGTH]; // Game ID (Example: ULUS10000) } PACK ProductStruct; +#ifdef _MSC_VER +#pragma pack(pop) +#endif struct ApctlHandler { u32 entryPoint; diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 5cd8e052d4..f8df05435e 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -15,6 +15,10 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#if !defined(_WIN32) +#include +#endif + #include #include "thread/threadutil.h" // sceNetAdhoc @@ -52,8 +56,8 @@ bool networkInited; static bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; int adhocDefaultTimeout = 5000; -int adhocEventPollDelayMS = 10; // 16; -int adhocMatchingEventDelayMS = 100; // 33; +int adhocEventPollDelayMS = 10; +int adhocMatchingEventDelayMS = 100; int adhocEventDelayMS = 500; // This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 SceUID threadAdhocID; @@ -2653,7 +2657,7 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { // Send Empty Data just to trigger Nagle on/off effect to flush the send buffer, Do we need to trigger this at all or is it automatically flushed? changeBlockingMode(socket->id, nonblock); - int sent = send(socket->id, NULL, NULL, 0); + int sent = send(socket->id, 0, 0, 0); int error = errno; changeBlockingMode(socket->id, 0); @@ -3592,26 +3596,24 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) for (; peer != NULL && filledpeers < requestedpeers; peer = peer->next) { // Should we exclude timedout members? - if (!excludeTimedout || peer->lastping != 0) - // Parent Mode - if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) - { - // Interested in Children (Michael Jackson Style) - if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) - { - // Add Child MAC - buf2[filledpeers++].mac_addr = peer->mac; + if (!excludeTimedout || peer->lastping != 0) { + // Parent Mode + if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { + // Interested in Children (Michael Jackson Style) + if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) { + // Add Child MAC + buf2[filledpeers++].mac_addr = peer->mac; + } } - } - // Children Mode - else - { - // Interested in Parent & Siblings - if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD || peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) - { - // Add Peer MAC - buf2[filledpeers++].mac_addr = peer->mac; + // Children Mode + else { + // Interested in Parent & Siblings + if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD || + peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) { + // Add Peer MAC + buf2[filledpeers++].mac_addr = peer->mac; + } } } } @@ -3874,7 +3876,7 @@ void __NetTriggerCallbacks() __KernelDirectMipsCall(it->second.entryPoint, after, args, 3, true); } adhocctlEvents.pop_front(); - delayus = adhocEventDelayMS * 1000; + delayus = (adhocEventDelayMS + adhocEventPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection } } @@ -3919,7 +3921,7 @@ void __NetMatchingCallbacks() SetMatchingInCallback(context, true); __KernelDirectMipsCall(args[5], after, args, 5, true); matchingEvents.pop_front(); - delayus = adhocMatchingEventDelayMS * 1000; //adhocEventPollDelayMS * 1000; + delayus = (adhocMatchingEventDelayMS + adhocEventPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection } } @@ -4093,7 +4095,7 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b memcpy(nckName, nickName, ADHOCCTL_NICKNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs nckName[ADHOCCTL_NICKNAME_LEN - 1] = 0; - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlGetAddrByName(%s, [%08x]=%i/%i, %08x)", nckName, sizeAddr, buflen ? *buflen : -1, sizeof(SceNetAdhocctlPeerInfoEmu), bufAddr); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlGetAddrByName(%s, [%08x]=%d/%zu, %08x)", nckName, sizeAddr, buflen ? *buflen : -1, sizeof(SceNetAdhocctlPeerInfoEmu), bufAddr); // Library initialized if (netAdhocctlInited) diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 73720e15a3..83f1f5d5a0 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -19,9 +19,15 @@ #include "Core/HLE/proAdhoc.h" +#ifdef _MSC_VER +#pragma pack(push,1) +#endif typedef struct MatchingArgs { u32_le data[6]; //ContextID, Opcode, bufAddr[ to MAC], OptLen, OptAddr[, EntryPoint] -} PACK; +} PACK MatchingArgs; +#ifdef _MSC_VER +#pragma pack(pop) +#endif class PointerWrap; From bcbfefc337c8a9ee158ecf30fe116e5c2c01427e Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 28 Dec 2019 02:37:27 +0700 Subject: [PATCH 314/848] making sure there are no alignment warnings related to member of packed struct on android --- Core/HLE/proAdhoc.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 48850e5ad8..808e6bab96 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -151,7 +151,8 @@ void addFriend(SceNetAdhocctlConnectPacketS2C * packet) { // Already existed if (peer != NULL) { char tmpmac[18]; - WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", packet->name.data, mac2str(&packet->mac, tmpmac), inet_ntoa(*(in_addr*)&packet->ip)); + u32 tmpip = packet->ip; + WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", packet->name.data, mac2str(&packet->mac, tmpmac), inet_ntoa(*(struct in_addr*)&tmpip)); //inet_ntoa(*(in_addr*)&packet->ip) peer->nickname = packet->name; peer->mac_addr = packet->mac; peer->ip_addr = packet->ip; @@ -323,7 +324,8 @@ void deleteFriendByIP(uint32_t ip) { */ char tmpmac[18]; - INFO_LOG(SCENET, "Removing Friend Peer %s [%s]", mac2str(&peer->mac_addr, tmpmac), inet_ntoa(*(in_addr*)&peer->ip_addr)); + u32 tmpip = peer->ip_addr; + INFO_LOG(SCENET, "Removing Friend Peer %s [%s]", mac2str(&peer->mac_addr, tmpmac), inet_ntoa(*(struct in_addr *)&tmpip)); //inet_ntoa(*(in_addr*)&peer->ip_addr) // Free Memory //free(peer); From c783aaf40d4534c30f1a85b790a631fc7b512333 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 2 Jan 2020 20:53:06 +0700 Subject: [PATCH 315/848] Increasing the extra delays on Adhoc's callbacks just to be on the safe side, also decreasing the default network's timeout to be noticed sooner --- Core/HLE/sceNetAdhoc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index f8df05435e..a8b0eea9bd 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -55,7 +55,7 @@ bool networkInited; static bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; -int adhocDefaultTimeout = 5000; +int adhocDefaultTimeout = 2000; int adhocEventPollDelayMS = 10; int adhocMatchingEventDelayMS = 100; int adhocEventDelayMS = 500; // This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 @@ -3876,7 +3876,7 @@ void __NetTriggerCallbacks() __KernelDirectMipsCall(it->second.entryPoint, after, args, 3, true); } adhocctlEvents.pop_front(); - delayus = (adhocEventDelayMS + adhocEventPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection + delayus = (adhocEventDelayMS + 4*adhocEventPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection } } @@ -3921,7 +3921,7 @@ void __NetMatchingCallbacks() SetMatchingInCallback(context, true); __KernelDirectMipsCall(args[5], after, args, 5, true); matchingEvents.pop_front(); - delayus = (adhocMatchingEventDelayMS + adhocEventPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection + delayus = (adhocMatchingEventDelayMS + 4*adhocEventPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection } } From b58f4a6e908217afffedae5dd3a0fb47fb0d7537 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 4 Jan 2020 07:41:54 +0700 Subject: [PATCH 316/848] Enabling KeepAlive on sockets --- Core/HLE/proAdhoc.cpp | 21 +++++++++++++++++++++ Core/HLE/proAdhoc.h | 5 +++++ Core/HLE/proAdhocServer.cpp | 16 ++++++++++++++++ Core/HLE/sceNetAdhoc.cpp | 10 ++++++++++ 4 files changed, 52 insertions(+) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 808e6bab96..68efeb0b21 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -23,6 +23,7 @@ #if !defined(_WIN32) #include +#include #endif #include @@ -1562,6 +1563,24 @@ int setSockBufferSize(int sock, int opt, int size) { // opt = SO_RCVBUF/SO_SNDBU return setsockopt(sock, SOL_SOCKET, opt, (char *)&n, sizeof(n)); } +int setSockKeepAlive(int sock, bool keepalive, const int keepcnt, const int keepidle, const int keepinvl) { + int optval = keepalive ? 1 : 0; + int optlen = sizeof(optval); + int result = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, optlen); + if (result == 0 && keepalive) { + if (getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&optval, (socklen_t*)&optlen) == 0 && optval == SOCK_STREAM) { + optlen = sizeof(optval); + optval = keepcnt; //20 + setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (char*)&optval, optlen); + optval = keepidle; //180 + setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&optval, optlen); + optval = keepinvl; //60 + setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&optval, optlen); + } + } + return result; +} + /** * Return the Number of Players with the chosen Nickname in the Local Users current Network * @param nickname To-be-searched Nickname @@ -1625,6 +1644,8 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ ERROR_LOG(SCENET, "Invalid socket"); return SOCKET_ERROR; } + setSockKeepAlive(metasocket, true); + struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); //27312 // Maybe read this from config too diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 7dc32fd8d7..33b4ed466c 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -1163,6 +1163,11 @@ int getSockBufferSize(int sock, int opt); */ int setSockBufferSize(int sock, int opt, int size); +/* +* Set Socket KeepAlive (opt = SO_KEEPALIVE) +*/ +int setSockKeepAlive(int sock, bool keepalive, const int keepcnt = 20, const int keepidle = 180, const int keepinvl = 60); + /** * Return the Number of Players with the chosen Nickname in the Local Users current Network * @param nickname To-be-searched Nickname diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index f073865270..f559c73419 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -1723,6 +1723,19 @@ void enable_address_reuse(int fd) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); } +/** + * Enable KeepAlive on Socket + * @param fd Socket + */ +void enable_keepalive(int fd) +{ + // Enable Value + int on = 1; + + // Enable Port Reuse + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(on)); +} + /** * Change Socket Blocking Mode * @param fd Socket @@ -1770,6 +1783,9 @@ int create_listen_socket(uint16_t port) // Created Socket if(fd != -1) { + // Enable KeepAlive + enable_keepalive(fd); + // Enable Address Reuse enable_address_reuse(fd); // Shouldn't Reuse the port for built-in AdhocServer to prevent conflict with Dedicated AdhocServer diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index a8b0eea9bd..89d2d286d8 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -325,9 +325,13 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u if (getSockBufferSize(usocket, SO_SNDBUF) < bufferSize) setSockBufferSize(usocket, SO_SNDBUF, bufferSize); if (getSockBufferSize(usocket, SO_RCVBUF) < bufferSize) setSockBufferSize(usocket, SO_RCVBUF, bufferSize); + // Enable KeepAlive + setSockKeepAlive(usocket, true); + // Enable Port Re-use, this will allow binding to an already used port, but only one of them can read the data (shared receive buffer?) int one = 1; setsockopt(usocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); // NO idea if we need this + // Binding Information for local Port sockaddr_in addr; addr.sin_family = AF_INET; @@ -1830,6 +1834,9 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, if (getSockBufferSize(tcpsocket, SO_SNDBUF) < bufsize) setSockBufferSize(tcpsocket, SO_SNDBUF, bufsize); if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); + // Enable KeepAlive + setSockKeepAlive(tcpsocket, true); + // Enable Port Re-use setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); @@ -2330,6 +2337,9 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int if (getSockBufferSize(tcpsocket, SO_SNDBUF) < bufsize) setSockBufferSize(tcpsocket, SO_SNDBUF, bufsize); if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); + // Enable KeepAlive + setSockKeepAlive(tcpsocket, true); + // Enable Port Re-use setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); From 0d0ccf3b738a5ed48ebe09b1d4294c1a1951fe00 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 5 Jan 2020 01:23:06 +0700 Subject: [PATCH 317/848] Making sure Adhoc codes doesn't have compilation warnings --- Core/HLE/sceNetAdhoc.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 89d2d286d8..d1a43a5749 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1683,7 +1683,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { // Link Previous Element if (i > 0) - buf[i - 1].next = structAddr + ((i - 1) * sizeof(SceNetAdhocPdpStat)) + sizeof(SceNetAdhocPdpStat); //buf[i - 1].next = &buf[i]; + buf[i - 1].next = structAddr + ((i - 1LL) * sizeof(SceNetAdhocPdpStat)) + sizeof(SceNetAdhocPdpStat); // Increment Counter i++; @@ -1759,7 +1759,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Link previous Element to this one if (i > 0) - buf[i - 1].next = structAddr + ((i - 1) * sizeof(SceNetAdhocPtpStat)) + sizeof(SceNetAdhocPtpStat); + buf[i - 1].next = structAddr + ((i - 1LL) * sizeof(SceNetAdhocPtpStat)) + sizeof(SceNetAdhocPtpStat); // Increment Counter i++; @@ -4302,7 +4302,7 @@ void broadcastHelloMessage(SceNetAdhocMatchingContext * context) // Allocate Hello Message Buffer, reuse when necessary if ((int32_t)context->hellolen > len) { - uint8_t* tmp = (uint8_t *)realloc(hello, 5 + context->hellolen); + uint8_t* tmp = (uint8_t *)realloc(hello, 5LL + context->hellolen); if (tmp != NULL) { hello = tmp; len = context->hellolen; @@ -4356,7 +4356,7 @@ void sendAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * ma int siblingcount = siblingbuflen / sizeof(SceNetEtherAddr); // Allocate Accept Message Buffer - uint8_t * accept = (uint8_t *)malloc(9 + (uint32_t)optlen + siblingbuflen); + uint8_t * accept = (uint8_t *)malloc(9LL + optlen + siblingbuflen); // Allocated Accept Message Buffer if (accept != NULL) @@ -4428,7 +4428,7 @@ void sendJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac, if (peer != NULL && peer->state == PSP_ADHOC_MATCHING_PEER_OUTGOING_REQUEST) { // Allocate Join Message Buffer - uint8_t * join = (uint8_t *)malloc(5 + optlen); + uint8_t * join = (uint8_t *)malloc(5LL + optlen); // Allocated Join Message Buffer if (join != NULL) @@ -4463,7 +4463,7 @@ void sendJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac, void sendCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac, int optlen, void * opt) { // Allocate Cancel Message Buffer - uint8_t * cancel = (uint8_t *)malloc(5 + optlen); + uint8_t * cancel = (uint8_t *)malloc(5LL + optlen); // Allocated Cancel Message Buffer if (cancel != NULL) @@ -4525,7 +4525,7 @@ void sendBulkDataPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * //if (peer->sending == 0) return; // Allocate Send Message Buffer - uint8_t * send = (uint8_t *)malloc(5 + datalen); + uint8_t * send = (uint8_t *)malloc(5LL + datalen); // Allocated Send Message Buffer if (send != NULL) @@ -4869,7 +4869,7 @@ void actOnAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * s int siblingcount = 0; memcpy(&siblingcount, context->rxbuf + 5, sizeof(siblingcount)); // Complete Valid Packet available - if (optlen >= 0 && length >= (9 + optlen + sizeof(SceNetEtherAddr) * siblingcount)) + if (optlen >= 0 && length >= (9LL + optlen + static_cast(sizeof(SceNetEtherAddr)) * siblingcount)) { // Set Default Null Data void * opt = NULL; From 6c267dff9efcd8ec9275589642d35f4d4af78a17 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 25 Feb 2020 16:29:06 +0700 Subject: [PATCH 318/848] Fix Local IP detection on non-Windows system (Note: Had to delete a UPnP related line) --- Core/HLE/proAdhoc.cpp | 112 ++++++++++++++++++++++++++++-------- Core/HLE/proAdhoc.h | 6 +- Core/HLE/proAdhocServer.cpp | 2 +- Core/HLE/sceNet.cpp | 24 ++++---- 4 files changed, 103 insertions(+), 41 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 68efeb0b21..b3570f152f 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -24,6 +24,10 @@ #if !defined(_WIN32) #include #include +#include +#include +#include +#include #endif #include @@ -54,7 +58,7 @@ int actionAfterMatchingMipsCall; // Broadcast MAC uint8_t broadcastMAC[ETHER_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -int metasocket; +int metasocket = (int)INVALID_SOCKET; SceNetAdhocctlParameter parameter; SceNetAdhocctlAdhocId product_code; std::thread friendFinderThread; @@ -69,7 +73,8 @@ bool chatScreenVisible = false; bool updateChatScreen = false; int newChat = 0; bool isLocalServer = false; -sockaddr localIP; // This might serves the same purpose with existing "localip" above, but since this is copied from my old code so here it is (too lazy to rewrite the code) +sockaddr LocalhostIP; +sockaddr LocalIP; bool isLocalMAC(const SceNetEtherAddr * addr) { SceNetEtherAddr saddr; @@ -1484,38 +1489,92 @@ int getActivePeerCount(const bool excludeTimedout) { return count; } -int getLocalIp(sockaddr_in * SocketAddress){ +int getLocalIp(sockaddr_in* SocketAddress) { + if (metasocket != (int)INVALID_SOCKET) { + struct sockaddr_in localAddr; + localAddr.sin_addr.s_addr = INADDR_ANY; + socklen_t addrLen = sizeof(localAddr); + if (SOCKET_ERROR != getsockname(metasocket, (struct sockaddr*) & localAddr, &addrLen)) { + if (isLocalServer) { + localAddr.sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; + } + SocketAddress->sin_addr = localAddr.sin_addr; + return 0; + } + } + +// Fallback if not connected to AdhocServer #if defined(_WIN32) // Get local host name char szHostName[256] = ""; - if(::gethostname(szHostName, sizeof(szHostName))) { + if (::gethostname(szHostName, sizeof(szHostName))) { // Error handling } // Get local IP addresses - struct hostent *pHost = 0; - pHost = ::gethostbyname(szHostName); - if(pHost) { + struct hostent* pHost = 0; + pHost = ::gethostbyname(szHostName); // On Non-Windows (UNIX/POSIX) gethostbyname("localhost") will always returns a useless 127.0.0.1, while on Windows it returns LAN IP when available + if (pHost) { memcpy(&SocketAddress->sin_addr, pHost->h_addr_list[0], pHost->h_length); if (isLocalServer) { - SocketAddress->sin_addr = ((sockaddr_in*)&localIP)->sin_addr; + SocketAddress->sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; } return 0; } return -1; -#else - char szHostName[256] = ""; - gethostname(szHostName, sizeof(szHostName)); - struct hostent* pHost = 0; - pHost = gethostbyname(szHostName); - if (pHost) { - memcpy(&SocketAddress->sin_addr, pHost->h_addr_list[0], pHost->h_length); + +#elif defined(getifaddrs) // On Android: Requires __ANDROID_API__ >= 24 + struct ifaddrs* ifAddrStruct = NULL; + struct ifaddrs* ifa = NULL; + + getifaddrs(&ifAddrStruct); + if (ifAddrStruct != NULL) { + for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { + if (!ifa->ifa_addr) { + continue; + } + if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4 + // is a valid IP4 Address + SocketAddress->sin_addr = ((struct sockaddr_in*)ifa->ifa_addr)->sin_addr; + break; + } + } + freeifaddrs(ifAddrStruct); if (isLocalServer) { - SocketAddress->sin_addr = ((sockaddr_in*)&localIP)->sin_addr; + SocketAddress->sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; } return 0; } return -1; + +#else // Alternative way + int sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock != SOCKET_ERROR) { + const char* kGoogleDnsIp = "8.8.8.8"; // Needs to be an IP string so it can be resolved as fast as possible to IP, doesn't need to be reachable + uint16_t kDnsPort = 53; + struct sockaddr_in serv; + memset(&serv, 0, sizeof(serv)); + serv.sin_family = AF_INET; + serv.sin_addr.s_addr = inet_addr(kGoogleDnsIp); + serv.sin_port = htons(kDnsPort); + + int err = connect(sock, (const sockaddr*)&serv, sizeof(serv)); + if (err != SOCKET_ERROR) { + sockaddr_in name; + socklen_t namelen = sizeof(name); + err = getsockname(sock, (sockaddr*)&name, &namelen); + if (err != SOCKET_ERROR) { + SocketAddress->sin_addr = name.sin_addr; // May be we should cache this so it doesn't need to use connect all the time, or even better cache it when connecting to adhoc server to get an accurate IP + closesocket(sock); + if (isLocalServer) { + SocketAddress->sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; + } + return 0; + } + } + closesocket(sock); + } + return -1; #endif } @@ -1525,7 +1584,7 @@ uint32_t getLocalIp(int sock) { socklen_t addrLen = sizeof(localAddr); getsockname(sock, (struct sockaddr*)&localAddr, &addrLen); if (isLocalServer) { - localAddr.sin_addr = ((sockaddr_in*)&localIP)->sin_addr; + localAddr.sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; } return localAddr.sin_addr.s_addr; } @@ -1679,18 +1738,19 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ setsockopt(metasocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); setsockopt(metasocket, SOL_SOCKET, SO_DONTROUTE, (const char*)&on, sizeof(on)); - ((struct sockaddr_in*) & localIP)->sin_port = 0; + ((struct sockaddr_in*) & LocalhostIP)->sin_port = 0; // Bind Local Address to Socket - iResult = bind(metasocket, (struct sockaddr*) & localIP, sizeof(sockaddr)); + iResult = bind(metasocket, (struct sockaddr*) & LocalhostIP, sizeof(sockaddr)); if (iResult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "Bind to alternate localhost[%s] failed(%i).", inet_ntoa(((struct sockaddr_in*) & localIP)->sin_addr), iResult); - host->NotifyUserMessage(std::string(n->T("Failed to Bind Localhost IP")) + " " + inet_ntoa(((struct sockaddr_in*) & localIP)->sin_addr), 3.0, 0x0000ff); + ERROR_LOG(SCENET, "Bind to alternate localhost[%s] failed(%i).", inet_ntoa(((struct sockaddr_in*) & LocalhostIP)->sin_addr), iResult); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Localhost IP")) + " " + inet_ntoa(((struct sockaddr_in*) & LocalhostIP)->sin_addr), 3.0, 0x0000ff); } } // Default/Initial Network memset(¶meter, 0, sizeof(parameter)); - strcpy((char *)¶meter.nickname.data, g_Config.sNickName.c_str()); + strncpy((char *)¶meter.nickname.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN); + parameter.nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; parameter.channel = g_Config.iWlanAdhocChannel; // Fake Channel, 0 = Auto where JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11) if (parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) parameter.channel = 1; getLocalMac(¶meter.bssid.mac_addr); @@ -1716,11 +1776,15 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ SceNetEtherAddr addres; getLocalMac(&addres); packet.mac = addres; - strcpy((char *)packet.name.data, g_Config.sNickName.c_str()); + strncpy((char *)&packet.name.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN); + packet.name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; memcpy(packet.game.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); int sent = send(metasocket, (char*)&packet, sizeof(packet), 0); changeBlockingMode(metasocket, 1); // Change to non-blocking if (sent > 0) { + socklen_t addrLen = sizeof(LocalIP); + memset(&LocalIP, 0, addrLen); + getsockname(metasocket, &LocalIP, &addrLen); host->NotifyUserMessage(n->T("Network Initialized"), 1.0); return 0; } @@ -1741,7 +1805,7 @@ bool resolveIP(uint32_t ip, SceNetEtherAddr * mac) { getLocalIp(&addr); uint32_t localIp = addr.sin_addr.s_addr; - if (ip == localIp || ip == ((sockaddr_in*)&localIP)->sin_addr.s_addr){ + if (ip == localIp || ip == ((sockaddr_in*)&LocalhostIP)->sin_addr.s_addr){ getLocalMac(mac); return true; } diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 33b4ed466c..94518d3cdd 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -842,7 +842,9 @@ extern SceNetAdhocPtpStat * ptp[255]; extern uint16_t portOffset; extern bool isLocalServer; -extern sockaddr localIP; +extern sockaddr LocalhostIP; // Used to differentiate localhost IP on multiple-instance +extern sockaddr LocalIP; // IP of Network Adapter used to connect to Adhoc Server (LAN/WAN) + extern uint32_t fakePoolSize; extern SceNetAdhocMatchingContext * contexts; extern int one; @@ -1147,7 +1149,7 @@ void spawnLocalEvent(SceNetAdhocMatchingContext * context, int event, SceNetEthe int getActivePeerCount(const bool excludeTimedout = true); /** - * Returns the locall Ip of this machine, TODO: Implement the linux version + * Returns the locall Ip of this machine * @param SocketAddres OUT: local ip */ int getLocalIp(sockaddr_in * SocketAddress); diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index f559c73419..faa78331d3 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -1802,7 +1802,7 @@ int create_listen_socket(uint16_t port) //Should only bind to specific IP for the 2nd or more instance of PPSSPP to prevent communication interference issue when sharing the same port. Doesn't work well when PPSSPP_ID reseted everytime emulation restarted. /* if (PPSSPP_ID > 1) { - local.sin_addr = ((sockaddr_in *)&localIP)->sin_addr; + local.sin_addr = ((sockaddr_in *)&LocalhostIP)->sin_addr; } */ diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index da1110c1f4..466c4e3a18 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -57,7 +57,7 @@ static struct SceNetMallocStat netMallocStat; static std::map apctlHandlers; -static int InitLocalIP() { +static int InitLocalhostIP() { // find local IP addrinfo* localAddr; addrinfo* ptr; @@ -67,19 +67,19 @@ static int InitLocalIP() { if (iResult != 0) { ERROR_LOG(SCENET, "DNS Error (%s) result: %d\n", ipstr, iResult); //osm.Show("DNS Error, can't resolve client bind " + ipstr, 8.0f); - ((sockaddr_in*)&localIP)->sin_family = AF_INET; - ((sockaddr_in*)&localIP)->sin_addr.s_addr = inet_addr(ipstr); //"127.0.0.1" - ((sockaddr_in*)&localIP)->sin_port = 0; + ((sockaddr_in*)&LocalhostIP)->sin_family = AF_INET; + ((sockaddr_in*)&LocalhostIP)->sin_addr.s_addr = inet_addr(ipstr); //"127.0.0.1" + ((sockaddr_in*)&LocalhostIP)->sin_port = 0; return iResult; } for (ptr = localAddr; ptr != NULL; ptr = ptr->ai_next) { switch (ptr->ai_family) { case AF_INET: - memcpy(&localIP, ptr->ai_addr, sizeof(sockaddr)); + memcpy(&LocalhostIP, ptr->ai_addr, sizeof(sockaddr)); break; } } - ((sockaddr_in*)&localIP)->sin_port = 0; + ((sockaddr_in*)&LocalhostIP)->sin_port = 0; freeaddrinfo(localAddr); // Resolve server dns @@ -100,7 +100,7 @@ static int InitLocalIP() { } } freeaddrinfo(resultAddr); - isLocalServer = (((uint8_t*)&serverIp.s_addr)[0] == 0x7f); // (serverIp.S_un.S_un_b.s_b1 = 0x7f); + isLocalServer = (((uint8_t*)&serverIp.s_addr)[0] == 0x7f); return 0; } @@ -116,14 +116,13 @@ static void __ResetInitNetLib() { void __NetInit() { portOffset = g_Config.iPortOffset; - net::Init(); - InitLocalIP(); + InitLocalhostIP(); char tmpmac[18]; SceNetEtherAddr mac; getLocalMac(&mac); - INFO_LOG(SCENET, "LocalHost IP will be %s [MAC: %s]", inet_ntoa(((sockaddr_in*)&localIP)->sin_addr), mac2str(&mac, tmpmac)); - //net::Init(); + INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac)); + __ResetInitNetLib(); } @@ -138,9 +137,6 @@ void __NetShutdown() { if (netInited) sceNetTerm(); __ResetInitNetLib(); - - net::Shutdown(); - //PPSSPPIDCleanup(); // To make the ID/IP persistent on every reset, we should just let the OS closes all open handles instead of calling PPSSPPIDCleanup() on every reset } static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) { From 0cbcbaecf8a0276eae904335ed54c176166927df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 22:52:07 +0200 Subject: [PATCH 319/848] Backport a macOS buildfix from later --- Core/HLE/proAdhoc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index b3570f152f..ee9c2775ae 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1622,6 +1622,9 @@ int setSockBufferSize(int sock, int opt, int size) { // opt = SO_RCVBUF/SO_SNDBU return setsockopt(sock, SOL_SOCKET, opt, (char *)&n, sizeof(n)); } +#if !defined(TCP_KEEPIDLE) +#define TCP_KEEPIDLE TCP_KEEPALIVE //TCP_KEEPIDLE on Linux is equivalent to TCP_KEEPALIVE on macOS +#endif int setSockKeepAlive(int sock, bool keepalive, const int keepcnt, const int keepidle, const int keepinvl) { int optval = keepalive ? 1 : 0; int optlen = sizeof(optval); From 97cfb64272ead1d27d9c97ab0b5b284225b0c500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 22:55:32 +0200 Subject: [PATCH 320/848] Warning fixes --- Core/HLE/sceKernelThread.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 194fd2082c..83c8fb6635 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -3659,14 +3659,14 @@ struct NativeThreadEventHandler { }; struct ThreadEventHandler : public KernelObject { - const char *GetName() { return nteh.name; } + const char *GetName() override { return nteh.name; } const char *GetTypeName() override { return GetStaticTypeName(); } static const char *GetStaticTypeName() { return "ThreadEventHandler"; } static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_TEID; } static int GetStaticIDType() { return SCE_KERNEL_TMID_ThreadEventHandler; } - int GetIDType() const { return SCE_KERNEL_TMID_ThreadEventHandler; } + int GetIDType() const override { return SCE_KERNEL_TMID_ThreadEventHandler; } - virtual void DoState(PointerWrap &p) { + void DoState(PointerWrap &p) override { auto s = p.Section("ThreadEventHandler", 1); if (!s) return; From ed98785831c2638d0f4ea518a8c5123b94508607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 23:05:00 +0200 Subject: [PATCH 321/848] Temporary buildfix --- Core/HLE/proAdhoc.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index ee9c2775ae..e27b74e80e 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -106,8 +106,11 @@ bool isPTPPortInUse(uint16_t port) { char* mac2str(SceNetEtherAddr* mac) { #if defined(_WIN32) static __declspec(thread) char str[18] = ":::::"; -#else +#elif !PPSSPP_PLATFORM(MAC) && !PPSSPP_PLATFORM(IOS) static __thread char str[18] = ":::::"; +#else + // Temporary hack to avoid huge rebase conflicts. Remove this when applying the mac2str rewrite. + static char str[18] = ":::::"; #endif if (mac == NULL) return str; snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]); From 3c29545014d41cd591b7ac83f7f37e3f581fee71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 20 Jul 2020 23:25:34 +0200 Subject: [PATCH 322/848] Windows: Add command to load up a new identical instance of PPSSPP. Useful for debugging adhoc multiplayer locally with the new multi-instance support. --- Windows/MainWindowMenu.cpp | 5 +++++ Windows/W32Util/Misc.cpp | 10 ++++++---- Windows/W32Util/Misc.h | 1 + Windows/ppsspp.rc | 3 +++ Windows/resource.h | 1 + 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index fe06b18d83..e95816204a 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -227,6 +227,7 @@ namespace MainWindow { TranslateMenuItem(menu, ID_FILE_LOAD); TranslateMenuItem(menu, ID_FILE_LOAD_DIR); TranslateMenuItem(menu, ID_FILE_LOAD_MEMSTICK); + TranslateMenuItem(menu, ID_FILE_OPEN_NEW_INSTANCE); TranslateMenuItem(menu, ID_FILE_MEMSTICK); TranslateMenuItem(menu, ID_FILE_SAVESTATE_SLOT_MENU, useDefHotkey(VIRTKEY_NEXT_SLOT) ? L"\tF3" : L""); TranslateMenuItem(menu, ID_FILE_QUICKLOADSTATE, useDefHotkey(VIRTKEY_LOAD_STATE) ? L"\tF4" : L""); @@ -569,6 +570,10 @@ namespace MainWindow { BrowseAndBoot(GetSysDirectory(DIRECTORY_GAME)); break; + case ID_FILE_OPEN_NEW_INSTANCE: + W32Util::SpawnNewInstance(false); + break; + case ID_FILE_MEMSTICK: ShellExecute(NULL, L"open", ConvertUTF8ToWString(g_Config.memStickDirectory).c_str(), 0, 0, SW_SHOW); break; diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index 3bb86f6bf6..c4f9ec1310 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -154,6 +154,12 @@ namespace W32Util } void ExitAndRestart(bool overrideArgs, const std::string &args) { + SpawnNewInstance(overrideArgs, args); + + ExitProcess(0); + } + + void SpawnNewInstance(bool overrideArgs, const std::string &args) { // This preserves arguments (for example, config file) and working directory. std::wstring workingDirectory; std::wstring moduleFilename; @@ -168,13 +174,9 @@ namespace W32Util cmdline = RemoveExecutableFromCommandLine(GetCommandLineW()); } ShellExecute(nullptr, nullptr, moduleFilename.c_str(), cmdline, workingDirectory.c_str(), SW_SHOW); - - ExitProcess(0); } } - - GenericListControl::GenericListControl(HWND hwnd, const GenericListViewDef& def) : handle(hwnd), columns(def.columns),columnCount(def.columnCount),valid(false), inResizeColumns(false),updating(false) diff --git a/Windows/W32Util/Misc.h b/Windows/W32Util/Misc.h index 623de73233..fa447de78d 100644 --- a/Windows/W32Util/Misc.h +++ b/Windows/W32Util/Misc.h @@ -12,6 +12,7 @@ namespace W32Util BOOL CopyTextToClipboard(HWND hwnd, const std::wstring &wtext); void MakeTopMost(HWND hwnd, bool topMost); void ExitAndRestart(bool overrideArgs = false, const std::string &args = ""); + void SpawnNewInstance(bool overrideArgs = false, const std::string &args = ""); void GetSelfExecuteParams(std::wstring &workingDirectory, std::wstring &moduleFilename); } diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 07c3c49fd6..f47d373935 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -65,6 +65,7 @@ IDB_IMAGE_PSP IMAGE "pspmode.png" IDR_ACCELS ACCELERATORS BEGIN "O", ID_FILE_LOAD, VIRTKEY, CONTROL, NOINVERT + "I", ID_FILE_OPEN_NEW_INSTANCE, VIRTKEY, CONTROL, NOINVERT "W", ID_EMULATION_STOP, VIRTKEY, CONTROL, NOINVERT "B", ID_EMULATION_RESET, VIRTKEY, CONTROL, NOINVERT "T", ID_EMULATION_CHEATS, VIRTKEY, CONTROL, NOINVERT @@ -480,6 +481,8 @@ BEGIN MENUITEM "", 0, MFT_SEPARATOR MENUITEM "Open Memory Stick", ID_FILE_MEMSTICK MENUITEM "", 0, MFT_SEPARATOR + MENUITEM "Open New Instance", ID_FILE_OPEN_NEW_INSTANCE + MENUITEM "", 0, MFT_SEPARATOR POPUP "Savestate Slot", ID_FILE_SAVESTATE_SLOT_MENU BEGIN diff --git a/Windows/resource.h b/Windows/resource.h index e5e3307fae..adb597eab7 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -22,6 +22,7 @@ #define WHEEL_DELTA 120 #define ID_DEBUG_LOG 121 #define ID_DEBUG_BREAKPOINTS 122 +#define ID_FILE_OPEN_NEW_INSTANCE 123 #define ID_FILE_LOADSTATEFILE 126 #define ID_FILE_SAVESTATEFILE 127 #define ID_EMULATION_RESET 130 From 33d3ac28de814b70e07b6b4e6d20de728ae8f354 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 18 Jan 2020 02:32:09 +0700 Subject: [PATCH 323/848] Added UPnP Support Fix i18n type --- .gitmodules | 3 + CMakeLists.txt | 77 +++++++ Core/Config.cpp | 3 + Core/Config.h | 1 + Core/Core.vcxproj | 13 +- Core/Core.vcxproj.filters | 6 + Core/HLE/proAdhoc.cpp | 17 +- Core/HLE/proAdhocServer.cpp | 9 +- Core/HLE/sceNet.cpp | 15 +- Core/HLE/sceNetAdhoc.cpp | 23 ++- Core/Util/PortManager.cpp | 379 ++++++++++++++++++++++++++++++++++ Core/Util/PortManager.h | 99 +++++++++ UI/GameSettingsScreen.cpp | 1 + Windows/PPSSPP.sln | 14 ++ ext/miniupnp | 1 + ext/miniupnpc.vcxproj | 251 ++++++++++++++++++++++ ext/miniupnpc.vcxproj.filters | 44 ++++ 17 files changed, 938 insertions(+), 18 deletions(-) create mode 100644 Core/Util/PortManager.cpp create mode 100644 Core/Util/PortManager.h create mode 160000 ext/miniupnp create mode 100644 ext/miniupnpc.vcxproj create mode 100644 ext/miniupnpc.vcxproj.filters diff --git a/.gitmodules b/.gitmodules index fe342fd22f..390dd8b41f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "ext/native/tools/prebuilt"] path = ext/native/tools/prebuilt url = https://github.com/hrydgard/ppsspp-freetype.git +[submodule "ext/miniupnp"] + path = ext/miniupnp + url = https://github.com/miniupnp/miniupnp.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 0dc6e2114d..d43cb98324 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,6 +119,7 @@ option(LIBRETRO "Set to ON to generate the libretro target" OFF) # :: Options option(USE_FFMPEG "Build with FFMPEG support" ON) option(USE_DISCORD "Build with Discord support" ON) +option(USE_MINIUPNPC "Build with miniUPnPc support" ON) option(USE_SYSTEM_SNAPPY "Dynamically link against system snappy" ${USE_SYSTEM_SNAPPY}) option(USE_SYSTEM_FFMPEG "Dynamically link against system FFMPEG" ${USE_SYSTEM_FFMPEG}) option(USE_SYSTEM_LIBZIP "Dynamically link against system libzip" ${USE_SYSTEM_LIBZIP}) @@ -1768,6 +1769,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/Util/AudioFormatNEON.h Core/Util/GameManager.cpp Core/Util/GameManager.h + Core/Util/PortManager.cpp + Core/Util/PortManager.h Core/Util/BlockAllocator.cpp Core/Util/BlockAllocator.h Core/Util/PPGeDraw.cpp @@ -1820,6 +1823,80 @@ if(USE_DISCORD AND NOT IOS AND NOT LIBRETRO) target_link_libraries(${CoreLibName} discord-rpc) endif() +# miniUPnPc integration (MiniUPnPc supposed to works on any POSIX system, not sure if some of these are redundant/not needed tho) +if(USE_MINIUPNPC) + set (MINIUPNPC_VERSION 2.1) # used by miniupnpcstrings.h.cmake + set (MINIUPNPC_API_VERSION 17) + option(UPNPC_BUILD_STATIC "Build static library" TRUE) + option(NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE) + mark_as_advanced(NO_GETADDRINFO) + if (NO_GETADDRINFO) + add_definitions(-DNO_GETADDRINFO) + endif() + + if (NOT WIN32) + add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT) + add_definitions (-D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L) + else() + add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends + endif() + if (MACOSX) + add_definitions (-D_DARWIN_C_SOURCE) + endif() + if(WIN32) + add_definitions(-DWIN32 -DMINIUPNP_EXPORTS ) + else() + add_definitions(-fPIC) + endif() + + add_definitions(-DMINIUPNP_STATICLIB) + set(MINIUPNP_DIR "ext/miniupnp/miniupnpc") + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + configure_file(${MINIUPNP_DIR}/miniupnpcstrings.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h) # by default miniupnp repo doesn't contains miniupnpcstrings.h and need to be generated + set(MINIUPNPC_SOURCES + # the needed bits of miniupnpc (no python module, no tests, no cli) + ${MINIUPNP_DIR}/connecthostport.c + ${MINIUPNP_DIR}/igd_desc_parse.c + ${MINIUPNP_DIR}/minisoap.c + ${MINIUPNP_DIR}/minissdpc.c + ${MINIUPNP_DIR}/miniupnpc.c + ${MINIUPNP_DIR}/miniwget.c + ${MINIUPNP_DIR}/minixml.c + ${MINIUPNP_DIR}/minixmlvalid.c + ${MINIUPNP_DIR}/portlistingparse.c + ${MINIUPNP_DIR}/receivedata.c + #${MINIUPNP_DIR}/upnpc.c # causing an error due to already existing _main() + ${MINIUPNP_DIR}/upnpcommands.c + ${MINIUPNP_DIR}/upnpdev.c + ${MINIUPNP_DIR}/upnperrors.c + ${MINIUPNP_DIR}/upnpreplyparse.c + ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h + ) + if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") + #set(MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c) # causing an error due to duplication in MINIUPNPC_SOURCES? + endif() + if (WIN32) + set_source_files_properties(${MINIUPNPC_SOURCES} PROPERTIES COMPILE_DEFINITIONS "MINIUPNP_STATICLIB;MINIUPNP_EXPORTS") + find_library(WINSOCK2_LIBRARY NAMES ws2_32 WS2_32 Ws2_32) + find_library(IPHLPAPI_LIBRARY NAMES iphlpapi) + set(LDLIBS ${WINSOCK2_LIBRARY} ${IPHLPAPI_LIBRARY} ${LDLIBS}) + #elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris") + # find_library (SOCKET_LIBRARY NAMES socket) + # find_library (NSL_LIBRARY NAMES nsl) + # find_library (RESOLV_LIBRARY NAMES resolv) + # set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS}) + endif() + if (MSVC) + # Suppress noise warnings + target_compile_definitions(miniupnpc _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS) + endif() + if (UPNPC_BUILD_STATIC) + add_library(miniupnpc STATIC ${MINIUPNPC_SOURCES}) + target_link_libraries(${CoreLibName} miniupnpc ${LDLIBS}) + set(UPNPC_LIBRARY miniupnpc) + endif() +endif() + setup_target_project(${CoreLibName} Core) # Generate git-version.cpp at build time. diff --git a/Core/Config.cpp b/Core/Config.cpp index 606f3321be..5250751855 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -955,6 +955,8 @@ static ConfigSetting controlSettings[] = { static ConfigSetting networkSettings[] = { ConfigSetting("EnableWlan", &g_Config.bEnableWlan, false, true, true), ConfigSetting("EnableAdhocServer", &g_Config.bEnableAdhocServer, false, true, true), + ConfigSetting("EnableUPnP", &g_Config.bEnableUPnP, false, true, true), + ConfigSetting("EnableNetworkChat", &g_Config.bEnableNetworkChat, false, true, true), ConfigSetting("ChatButtonPosition",&g_Config.iChatButtonPosition,BOTTOM_LEFT,true,true), ConfigSetting("ChatScreenPosition",&g_Config.iChatScreenPosition,BOTTOM_LEFT,true,true), @@ -964,6 +966,7 @@ static ConfigSetting networkSettings[] = { ConfigSetting("QuickChat3", &g_Config.sQuickChat2, "Quick Chat 3", true, true), ConfigSetting("QuickChat4", &g_Config.sQuickChat3, "Quick Chat 4", true, true), ConfigSetting("QuickChat5", &g_Config.sQuickChat4, "Quick Chat 5", true, true), + ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index d858b85804..077e75ada4 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -412,6 +412,7 @@ public: // Networking bool bEnableWlan; bool bEnableAdhocServer; + bool bEnableUPnP; int iWlanAdhocChannel; bool bWlanPowerSave; bool bEnableNetworkChat; diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 6ad9a0c3c0..91f0fd5830 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -139,7 +139,7 @@ Level3 ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../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) + _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) StreamingSIMDExtensions2 Precise true @@ -162,7 +162,7 @@ Level3 ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../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) + _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) NotSet Precise false @@ -241,7 +241,7 @@ false StreamingSIMDExtensions2 Precise - USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_LIB;NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_LIB;NDEBUG;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) Speed MultiThreaded true @@ -276,7 +276,7 @@ Speed false true - USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_LIB;NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_LIB;NDEBUG;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) false MultiThreaded true @@ -847,6 +847,7 @@ + MaxSpeed @@ -1181,6 +1182,7 @@ + @@ -1198,6 +1200,9 @@ {129e5e2b-39c1-4d84-96fe-dfd22dbb4a25} + + {d8a71225-178b-424e-96c1-cc3be2c1b047} + {457f45d2-556f-47bc-a31d-aff0d15beaed} diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index b99fc00e07..f3e5bea144 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -745,6 +745,9 @@ Core + + + Util Core @@ -1387,6 +1390,9 @@ Core + + + Util Core diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index e27b74e80e..855f991300 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1765,14 +1765,23 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ product_code.type = adhoc_id->type; memcpy(product_code.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); + // Switch to Nonblocking Behaviour + changeBlockingMode(metasocket, 1); // Connect to Adhoc Server server_addr.sin_addr = serverIp; - iResult = connect(metasocket,(sockaddr *)&server_addr,sizeof(server_addr)); - if (iResult == SOCKET_ERROR) { + int errorcode = 0; + int cnt = 0; + while ((iResult = connect(metasocket, (sockaddr*)&server_addr, sizeof(server_addr))) == SOCKET_ERROR && (errorcode = errno) != EISCONN && cnt < adhocDefaultTimeout) { + sleep_ms(1); + cnt++; + } + // Switch back to Blocking Behaviour + changeBlockingMode(metasocket, 0); + if (iResult == SOCKET_ERROR && errorcode != EISCONN) { char buffer[512]; - snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errno, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); + snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); ERROR_LOG(SCENET, "%s", buffer); - host->NotifyUserMessage(buffer, 5.0f, 0x0000ff); + host->NotifyUserMessage(n->T("Failed to connect to Adhoc Server"), 6.0f, 0x0000ff); return iResult; } diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index faa78331d3..a385e7d8e5 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -44,6 +44,7 @@ //#include #include "thread/threadutil.h" #include "Common/FileUtil.h" +#include "Core/Util/PortManager.h" #include "Core/Core.h" #include "Core/Host.h" #include "Core/HLE/proAdhocServer.h" @@ -1675,14 +1676,20 @@ int proAdhocServerThread(int port) // (int argc, char * argv[]) int server = create_listen_socket(port); //SERVER_PORT // Created Listening Socket - if(server != -1) + if(server != SOCKET_ERROR) { // Notify User INFO_LOG(SCENET, "AdhocServer: Listening for Connections on TCP Port %u", port); //SERVER_PORT + // Port forward + g_PortManager.Add(port, IP_PROTOCOL_TCP); + // Enter Server Loop result = server_loop(server); + // Remove Port mapping + g_PortManager.Remove(port, IP_PROTOCOL_TCP); + // Notify User INFO_LOG(SCENET, "AdhocServer: Shutdown complete"); } diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 466c4e3a18..e13c234c4b 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -32,6 +32,7 @@ #include "Core/MIPS/MIPS.h" #include "Core/Config.h" #include "Core/MemMapHelpers.h" +#include "Core/Util/PortManager.h" #include "sceKernel.h" #include "sceKernelThread.h" @@ -121,7 +122,11 @@ void __NetInit() { char tmpmac[18]; SceNetEtherAddr mac; getLocalMac(&mac); - INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac)); + INFO_LOG(SCENET, "LocalHost IP will be %s [MAC: %s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac)); + // Only initialize when UPnP is enabled since it takes a few seconds to detect UPnP device (may affect people who don't have UPnP device) + if (g_Config.bEnableUPnP) { + g_PortManager.Init(); + } __ResetInitNetLib(); } @@ -137,6 +142,14 @@ void __NetShutdown() { if (netInited) sceNetTerm(); __ResetInitNetLib(); + + if (g_Config.bEnableUPnP) { + g_PortManager.Clear(); + g_PortManager.Restore(); + g_PortManager.Deinit(); + } + + //PPSSPPIDCleanup(); // To make the ID/IP persistent on every reset, we should just let the OS closes all open handles instead of calling PPSSPPIDCleanup() on every reset } static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) { diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index d1a43a5749..e9ba3a4268 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -30,6 +30,7 @@ #include "Core/MemMapHelpers.h" #include "Common/ChunkFile.h" #include "Core/MIPS/MIPSCodeUtils.h" +#include "Core/Util/PortManager.h" #include "Core/HLE/HLEHelperThread.h" #include "Core/HLE/FunctionWrappers.h" @@ -55,7 +56,7 @@ bool networkInited; static bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; -int adhocDefaultTimeout = 2000; +int adhocDefaultTimeout = 2000; //5000 int adhocEventPollDelayMS = 10; int adhocMatchingEventDelayMS = 100; int adhocEventDelayMS = 500; // This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 @@ -340,7 +341,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u getLocalIp(&addr); } - addr.sin_port = htons(port + portOffset ); + addr.sin_port = htons(port + portOffset); // The port might be under 1024 (ie. GTA:VCS use port 1, Ford Street Racing use port 0 (UNUSED_PORT), etc) and already used by other application/host OS, should we add 1024 to the port whenever it tried to use an already used port? // Bound Socket to local Port @@ -377,7 +378,8 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u pdp[i] = internal; // Forward Port on Router - //sceNetPortOpen("UDP", port); // I need to figure out how to use this in windows/linux + //sceNetPortOpen("UDP", port); + g_PortManager.Add(port + portOffset, IP_PROTOCOL_UDP); // Success return i + 1; @@ -927,9 +929,10 @@ static int sceNetAdhocPdpDelete(int id, int unknown) { // Remove Port Forward from Router //sceNetPortClose("UDP", sock->lport); + //g_PortManager.Remove(sock->lport + portOffset, IP_PROTOCOL_UDP); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers // Free Memory - // free(sock); + free(sock); // Free Translation Slot pdp[id - 1] = NULL; @@ -1888,7 +1891,8 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, ptp[i] = internal; // Add Port Forward to Router - // sceNetPortOpen("TCP", sport); + //sceNetPortOpen("TCP", sport); + g_PortManager.Add(sport + portOffset, IP_PROTOCOL_TCP); // Return PTP Socket Pointer return i + 1; @@ -2074,7 +2078,8 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int ptp[i] = internal; // Add Port Forward to Router - // sceNetPortOpen("TCP", internal->lport); + //sceNetPortOpen("TCP", internal->lport); + g_PortManager.Add(internal->lport + portOffset, IP_PROTOCOL_TCP); INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", id, i+1, internal->lport, inet_ntoa(peeraddr.sin_addr), internal->pport); @@ -2264,7 +2269,8 @@ static int sceNetAdhocPtpClose(int id, int unknown) { closesocket(socket->id); // Remove Port Forward from Router - // sceNetPortClose("TCP", socket->lport); + //sceNetPortClose("TCP", socket->lport); + //g_PortManager.Remove(socket->lport + portOffset, IP_PROTOCOL_TCP); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers // Free Memory free(socket); @@ -2393,7 +2399,8 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int ptp[i] = internal; // Add Port Forward to Router - // sceNetPortOpen("TCP", sport); + //sceNetPortOpen("TCP", sport); + g_PortManager.Add(sport + portOffset, IP_PROTOCOL_TCP); // Return PTP Socket Pointer return i + 1; diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp new file mode 100644 index 0000000000..99e619d0b6 --- /dev/null +++ b/Core/Util/PortManager.cpp @@ -0,0 +1,379 @@ +// Copyright (c) 2013- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +// Most of the code are based on https://github.com/RJ/libportfwd and updated to the latest miniupnp library +// All credit goes to him and the official miniupnp project! http://miniupnp.free.fr/ + + +#include +#include +#include +#include +#include "Core/HLE/proAdhoc.h" // This import is only used to get product id that was used to connect to adhoc server +#include "Core/Util/PortManager.h" +#include "i18n/i18n.h" + + +PortManager g_PortManager; + +PortManager::PortManager(): + urls(0), + datas(0), + m_InitState(UPNP_INITSTATE_NONE), + m_LocalPort(UPNP_LOCAL_PORT_ANY) { +} + +PortManager::~PortManager() { + Clear(); + Restore(); + Deinit(); +} + +void PortManager::Deinit() { + if (urls) { + FreeUPNPUrls(urls); + free(urls); + urls = NULL; + } + if (datas) { + free(datas); + datas = NULL; + } + m_otherPortList.clear(); m_otherPortList.shrink_to_fit(); + m_portList.clear(); m_portList.shrink_to_fit(); + m_lanip.clear(); + m_defaultDesc.clear(); + m_LocalPort = UPNP_LOCAL_PORT_ANY; + m_InitState = UPNP_INITSTATE_DONE; +} + +bool PortManager::Init(const unsigned int timeout) { + // Windows: Assuming WSAStartup already called beforehand + struct UPNPDev* devlist; + struct UPNPDev* dev; + char* descXML; + int descXMLsize = 0; + int descXMLstatus = 0; + int localport = m_LocalPort; // UPNP_LOCAL_PORT_ANY (0), or UPNP_LOCAL_PORT_SAME (1) as an alias for 1900 for backwards compatability? + int ipv6 = 0; // 0 = IPv4, 1 = IPv6 + unsigned char ttl = 2; // defaulting to 2 + int error = 0; + + INFO_LOG(SCENET, "PortManager::Init(%d)", timeout); + if (!g_Config.bEnableUPnP) { + ERROR_LOG(SCENET, "PortManager::Init - UPnP is Disabled on Networking Settings"); + return false; + } + + if (m_InitState != UPNP_INITSTATE_NONE) { + switch (m_InitState) + { + case UPNP_INITSTATE_BUSY: { + WARN_LOG(SCENET, "PortManager - Initialization already in progress"); + return false; + } + // We should redetect UPnP just in case the player switched to a different network in the middle + /*case UPNP_INITSTATE_DONE: { + WARN_LOG(SCENET, "PortManager - Already Initialized"); + return false; + } + */ + default: + break; + } + } + m_InitState = UPNP_INITSTATE_BUSY; + urls = (UPNPUrls*)malloc(sizeof(struct UPNPUrls)); + datas = (IGDdatas*)malloc(sizeof(struct IGDdatas)); + memset(urls, 0, sizeof(struct UPNPUrls)); + memset(datas, 0, sizeof(struct IGDdatas)); + + devlist = upnpDiscover(timeout, NULL, NULL, localport, ipv6, ttl, &error); + if (devlist) + { + dev = devlist; + while (dev) + { + if (strstr(dev->st, "InternetGatewayDevice")) + break; + dev = dev->pNext; + } + if (!dev) + dev = devlist; // defaulting to first device + + INFO_LOG(SCENET, "PortManager - UPnP device: [desc: %s] [st: %s]", dev->descURL, dev->st); + + descXML = (char*)miniwget(dev->descURL, &descXMLsize, dev->scope_id, &descXMLstatus); + if (descXML) + { + parserootdesc(descXML, descXMLsize, datas); + free(descXML); descXML = 0; + GetUPNPUrls(urls, datas, dev->descURL, dev->scope_id); + } + + // Get LAN IP address + char lanaddr[64] = "unset"; + int status = UPNP_GetValidIGD(devlist, urls, datas, lanaddr, sizeof(lanaddr)); //possible "status" values, 0 = NO IGD found, 1 = A valid connected IGD has been found, 2 = A valid IGD has been found but it reported as not connected, 3 = an UPnP device has been found but was not recognized as an IGD + m_lanip = std::string(lanaddr); + INFO_LOG(SCENET, "PortManager - Detected LAN IP: %s", m_lanip.c_str()); + + // Additional Info + char connectionType[64] = ""; + if (UPNP_GetConnectionTypeInfo(urls->controlURL, datas->first.servicetype, connectionType) != UPNPCOMMAND_SUCCESS) { + WARN_LOG(SCENET, "PortManager - GetConnectionTypeInfo failed"); + } + else { + INFO_LOG(SCENET, "PortManager - Connection Type: %s", connectionType); + } + + // Using Game ID & Player Name as default description for mapping (prioritizing the ID sent by the game to Adhoc server) + char productid[10] = { 0 }; + memcpy(productid, product_code.data, sizeof(product_code.data)); + std::string gameID = std::string(productid); + if (productid[0] == '\0') { + gameID = g_paramSFO.GetDiscID(); + } + m_defaultDesc = "PPSSPP:" + gameID + ":" + g_Config.sNickName; + + freeUPNPDevlist(devlist); + + //m_LocalPort = localport; // We shouldn't keep the right port for the next game reset if we wanted to redetect UPnP + m_InitState = UPNP_INITSTATE_DONE; + RefreshPortList(); + return true; + } + ERROR_LOG(SCENET, "PortManager - upnpDiscover failed (error: %d) or No UPnP device detected", error); + auto n = GetI18NCategory("Networking"); + host->NotifyUserMessage(n->T("Unable to find UPnP device"), 6.0f, 0x0000ff); + m_InitState = UPNP_INITSTATE_NONE; + return false; +} + +int PortManager::GetInitState() { + return m_InitState; +} + +bool PortManager::Add(unsigned short port, const char* protocol) { + char port_str[16]; + std::string leaseDuration = "43200"; // range(0-604800) in seconds (0 = Indefinite/permanent). Some routers doesn't support non-zero value + int r; + + INFO_LOG(SCENET, "PortManager::Add(%d, %s)", port, protocol); + if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') + { + if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Add - the init was not done !"); + return false; + } + sprintf(port_str, "%d", port); + // Only add new port map if it's not previously created by PPSSPP for current IP + auto el_it = std::find_if(m_portList.begin(), m_portList.end(), + [port_str, protocol](const std::pair &el) { return el.first == port_str && el.second == protocol; }); + if (el_it == m_portList.end()) { + auto el_it = std::find_if(m_otherPortList.begin(), m_otherPortList.end(), + [port_str, protocol](const PortMap& el) { return el.extPort_str == port_str && el.protocol == protocol; }); + if (el_it != m_otherPortList.end()) { + // Try to delete the port mapping before we create it, just in case we have dangling port mapping from the daemon not being shut down correctly or the port was taken by other + r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str, protocol, NULL); + } + r = UPNP_AddPortMapping(urls->controlURL, datas->first.servicetype, + port_str, port_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, leaseDuration.c_str()); + if (r != 0) + { + ERROR_LOG(SCENET, "PortManager - AddPortMapping failed (error: %d)", r); + auto n = GetI18NCategory("Networking"); + host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); + Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts + return false; + } + m_portList.push_front({ port_str, protocol }); + // Keep tracks of it to be restored later if it belongs to others + if (el_it != m_otherPortList.end()) el_it->taken = true; + } + return true; +} + +bool PortManager::Remove(unsigned short port, const char* protocol) { + char port_str[16]; + + INFO_LOG(SCENET, "PortManager::Remove(%d, %s)", port, protocol); + if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') + { + if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Remove - the init was not done !"); + return false; + } + sprintf(port_str, "%d", port); + int r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str, protocol, NULL); + if (r != 0) + { + ERROR_LOG(SCENET, "PortManager - DeletePortMapping failed (error: %d)", r); + auto n = GetI18NCategory("Networking"); + host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); + Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts + return false; + } + for (auto it = m_portList.begin(); it != m_portList.end(); ) { + (it->first == port_str && it->second == protocol) ? it = m_portList.erase(it) : ++it; + } + return true; +} + +bool PortManager::Restore() { + int r; + INFO_LOG(SCENET, "PortManager::Restore()"); + if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') + { + if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Remove - the init was not done !"); + return false; + } + for (auto it = m_otherPortList.begin(); it != m_otherPortList.end(); ++it) { + if (it->taken) { + auto port_str = it->extPort_str; + auto protocol = it->protocol; + // Remove it first if it's still being taken by PPSSPP + auto el_it = std::find_if(m_portList.begin(), m_portList.end(), + [port_str, protocol](const std::pair& el) { return el.first == port_str && el.second == protocol; }); + if (el_it != m_portList.end()) { + r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str.c_str(), protocol.c_str(), NULL); + if (r == 0) { + m_portList.erase(el_it); + } + else { + ERROR_LOG(SCENET, "PortManager::Restore - DeletePortMapping failed (error: %d)", r); + return false; // Might be better not to exit here, but exiting a loop will avoid long timeouts in the case the router is no longer reachable + } + } + // Add the original owner back + r = UPNP_AddPortMapping(urls->controlURL, datas->first.servicetype, + it->extPort_str.c_str(), it->intPort_str.c_str(), it->lanip.c_str(), it->desc.c_str(), it->protocol.c_str(), it->remoteHost.c_str(), it->duration.c_str()); + if (r == 0) { + it->taken = false; + } + else { + ERROR_LOG(SCENET, "PortManager::Restore - AddPortMapping failed (error: %d)", r); + return false; // Might be better not to exit here, but exiting a loop will avoid long timeouts in the case the router is no longer reachable + } + } + } + return true; +} + +bool PortManager::Clear() { + int r; + int i = 0; + char index[6]; + char intAddr[40]; + char intPort[6]; + char extPort[6]; + char protocol[4]; + char desc[80]; + char enabled[6]; + char rHost[64]; + char duration[16]; + + INFO_LOG(SCENET, "PortManager::Clear()"); + if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') + { + if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Clear - the init was not done !"); + return false; + } + //unsigned int num = 0; + //UPNP_GetPortMappingNumberOfEntries(urls->controlURL, datas->first.servicetype, &num); // Not supported by many routers + do { + snprintf(index, 6, "%d", i); + rHost[0] = '\0'; enabled[0] = '\0'; + duration[0] = '\0'; desc[0] = '\0'; + extPort[0] = '\0'; intPort[0] = '\0'; intAddr[0] = '\0'; + r = UPNP_GetGenericPortMappingEntry(urls->controlURL, + datas->first.servicetype, + index, + extPort, intAddr, intPort, + protocol, desc, enabled, + rHost, duration); + // Only removes port mappings created by PPSSPP for current LAN IP + if (r == 0 && intAddr == m_lanip && std::strncmp(desc, "PPSSPP", 6) == 0) { + int r2 = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, extPort, protocol, rHost); + if (r2 != 0) + { + ERROR_LOG(SCENET, "PortManager::Clear - DeletePortMapping(%s, %s) failed (error: %d)", extPort, protocol, r2); + return false; + } + else { + i--; + for (auto it = m_portList.begin(); it != m_portList.end(); ) { + (it->first == extPort && it->second == protocol) ? it = m_portList.erase(it) : ++it; + } + } + } + i++; + } while (r == 0); + return true; +} + +bool PortManager::RefreshPortList() { + int r; + int i = 0; + char index[6]; + char intAddr[40]; + char intPort[6]; + char extPort[6]; + char protocol[4]; + char desc[80]; + char enabled[6]; + char rHost[64]; + char duration[16]; + + INFO_LOG(SCENET, "PortManager::RefreshPortList()"); + if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') + { + if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::RefreshPortList - the init was not done !"); + return false; + } + m_portList.clear(); + m_otherPortList.clear(); + //unsigned int num = 0; + //UPNP_GetPortMappingNumberOfEntries(urls->controlURL, datas->first.servicetype, &num); // Not supported by many routers + do { + snprintf(index, 6, "%d", i); + rHost[0] = '\0'; enabled[0] = '\0'; + duration[0] = '\0'; desc[0] = '\0'; + extPort[0] = '\0'; intPort[0] = '\0'; intAddr[0] = '\0'; + r = UPNP_GetGenericPortMappingEntry(urls->controlURL, + datas->first.servicetype, + index, + extPort, intAddr, intPort, + protocol, desc, enabled, + rHost, duration); + if (r == 0) { + // Only include port mappings created by PPSSPP for current LAN IP + if (intAddr == m_lanip && std::strncmp(desc, "PPSSPP", 6) == 0) { + m_portList.push_back({ extPort, protocol }); + } + // Port mappings belong to others that might be taken by PPSSPP later + else { + m_otherPortList.push_back({ false, protocol, extPort, intPort, intAddr, rHost, desc, duration, enabled }); + } + } + i++; + } while (r == 0); + return true; +} diff --git a/Core/Util/PortManager.h b/Core/Util/PortManager.h new file mode 100644 index 0000000000..176200c53e --- /dev/null +++ b/Core/Util/PortManager.h @@ -0,0 +1,99 @@ +// Copyright (c) 2013- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +// Most of the code are based on https://github.com/RJ/libportfwd and updated to the latest miniupnp library +// All credit goes to him and the official miniupnp project! http://miniupnp.free.fr/ + + +#pragma once + + +#ifndef MINIUPNP_STATICLIB +#define MINIUPNP_STATICLIB +#endif + +#include "ext/miniupnp/miniupnpc/miniwget.h" +#include "ext/miniupnp/miniupnpc/miniupnpc.h" +#include "ext/miniupnp/miniupnpc/upnpcommands.h" + +#include +#include + +#define IP_PROTOCOL_TCP "TCP" +#define IP_PROTOCOL_UDP "UDP" +#define UPNP_INITSTATE_NONE 0 +#define UPNP_INITSTATE_BUSY 1 +#define UPNP_INITSTATE_DONE 2 + +struct UPNPUrls; +struct IGDdatas; + +struct PortMap { + bool taken; + std::string protocol; + std::string extPort_str; + std::string intPort_str; + std::string lanip; + std::string remoteHost; + std::string desc; + std::string duration; + std::string enabled; +}; + +class PortManager { +public: + PortManager(); + ~PortManager(); + + // Initialize UPnP + // timeout: milliseconds to wait for a router to respond (default = 2000 ms) + bool Init(const unsigned int timeout = 2000); + + // Uninitialize/Reset the state + void Deinit(); + + // Get UPnP Initialization status + int GetInitState(); + + // Add a port & protocol (TCP, UDP or vendor-defined) to map for forwarding + bool Add(unsigned short port, const char* protocol); + + // Remove a port mapping + bool Remove(unsigned short port, const char* protocol); + + // Removes any lingering mapped ports from previous crashes + bool Clear(); + + // Restore ports mapped by others that were taken by PPSSPP, better used after Clear() + bool Restore(); + + // Get port list mapped by PPSSPP for current LAN IP & others + bool RefreshPortList(); + +protected: + struct UPNPUrls* urls = NULL; + struct IGDdatas* datas = NULL; + + int m_InitState = UPNP_INITSTATE_NONE; + int m_LocalPort = UPNP_LOCAL_PORT_ANY; + std::string m_lanip; + std::string m_defaultDesc; + std::deque> m_portList; + std::deque m_otherPortList; +}; + +extern PortManager g_PortManager; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 44d6f52151..78d860f234 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -690,6 +690,7 @@ void GameSettingsScreen::CreateViews() { networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.proAdhocServer, n->T("Change proAdhocServer Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeproAdhocServerAddress); networkingSettings->Add(new CheckBox(&g_Config.bEnableAdhocServer, n->T("Enable built-in PRO Adhoc Server", "Enable built-in PRO Adhoc Server"))); + networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)"))); networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress); networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset(0 = PSP compatibility)"), 100, screenManager())); diff --git a/Windows/PPSSPP.sln b/Windows/PPSSPP.sln index daf8a56189..a0bacf19db 100644 --- a/Windows/PPSSPP.sln +++ b/Windows/PPSSPP.sln @@ -83,6 +83,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AtlasTool", "..\ext\native\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZimTool", "..\ext\native\tools\ZimTool\ZimTool.vcxproj", "{B7DED405-40A2-48F8-9382-538F10D442F1}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "..\ext\miniupnpc.vcxproj", "{D8A71225-178B-424E-96C1-CC3BE2C1B047}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -337,6 +339,18 @@ Global {B7DED405-40A2-48F8-9382-538F10D442F1}.Release|Win32.ActiveCfg = Release|x64 {B7DED405-40A2-48F8-9382-538F10D442F1}.Release|x64.ActiveCfg = Release|x64 {B7DED405-40A2-48F8-9382-538F10D442F1}.Release|x64.Build.0 = Release|x64 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|ARM.ActiveCfg = Debug|Win32 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|ARM64.ActiveCfg = Debug|Win32 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|Win32.ActiveCfg = Debug|Win32 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|Win32.Build.0 = Debug|Win32 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|x64.ActiveCfg = Debug|x64 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Debug|x64.Build.0 = Debug|x64 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|ARM.ActiveCfg = Release|Win32 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|ARM64.ActiveCfg = Release|Win32 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|Win32.ActiveCfg = Release|Win32 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|Win32.Build.0 = Release|Win32 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|x64.ActiveCfg = Release|x64 + {D8A71225-178B-424E-96C1-CC3BE2C1B047}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ext/miniupnp b/ext/miniupnp new file mode 160000 index 0000000000..927e2f3666 --- /dev/null +++ b/ext/miniupnp @@ -0,0 +1 @@ +Subproject commit 927e2f36666f543d59a8080686921069832a3393 diff --git a/ext/miniupnpc.vcxproj b/ext/miniupnpc.vcxproj new file mode 100644 index 0000000000..ef4015103d --- /dev/null +++ b/ext/miniupnpc.vcxproj @@ -0,0 +1,251 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + 16.0 + {D8A71225-178B-424E-96C1-CC3BE2C1B047} + Win32Proj + miniupnpc + 10.0 + + + + StaticLibrary + true + $(DefaultPlatformToolset) + Unicode + + + StaticLibrary + false + $(DefaultPlatformToolset) + false + Unicode + + + StaticLibrary + true + $(DefaultPlatformToolset) + Unicode + + + StaticLibrary + false + $(DefaultPlatformToolset) + false + Unicode + + + + + + + + + + + + + + + + + + + + + true + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + + + true + $(Platform)\$(Configuration)\$(ProjectName)\ + + + false + $(Configuration)\$(ProjectName)\ + + + false + $(Platform)\$(Configuration)\$(ProjectName)\ + + + + NotUsing + Level3 + + + false + stdafx.h + DEBUG;_DEBUG;WIN32;_LIB;MINIUPNP_STATICLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + Default + false + ProgramDatabase + true + MultiThreadedDebug + + + Windows + true + + + cd miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd..\..\.. + + + $(OutDir)$(TargetName)$(TargetExt) + iphlpapi.lib + + + + + NotUsing + Level3 + + + DEBUG;_DEBUG;WIN32;_LIB;MINIUPNP_STATICLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + false + stdafx.h + ProgramDatabase + true + Default + MultiThreadedDebug + false + + + Windows + true + + + cd miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd..\..\.. + + + iphlpapi.lib + + + + + NotUsing + Level3 + true + true + + + false + stdafx.h + NDEBUG;WIN32;_LIB;MINIUPNP_STATICLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + Speed + false + true + false + MultiThreaded + + + Windows + true + true + true + + + cd miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd..\..\.. + + + $(OutDir)$(TargetName)$(TargetExt) + iphlpapi.lib + + + + + NotUsing + Level3 + true + true + + + NDEBUG;WIN32;_LIB;MINIUPNP_STATICLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + false + stdafx.h + true + Speed + MultiThreaded + false + false + + + Windows + true + true + true + + + iphlpapi.lib + + + cd miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd..\..\.. + + + + + + \ No newline at end of file diff --git a/ext/miniupnpc.vcxproj.filters b/ext/miniupnpc.vcxproj.filters new file mode 100644 index 0000000000..bda1ac6d7d --- /dev/null +++ b/ext/miniupnpc.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {c82edf03-bf88-478d-aaf5-2854df756cab} + + + + + scripts + + + \ No newline at end of file From 088e489c914239ff9b798fdda843d602eb0c7293 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 25 Feb 2020 16:04:15 +0700 Subject: [PATCH 324/848] Fix UPnP error detection Fix Local IP detection on non-Windows system --- Core/HLE/sceNet.cpp | 1 + Core/Util/PortManager.cpp | 56 ++++++++++++++++++++++++--------------- Core/Util/PortManager.h | 1 + 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index e13c234c4b..7b6a5aea78 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -123,6 +123,7 @@ void __NetInit() { SceNetEtherAddr mac; getLocalMac(&mac); INFO_LOG(SCENET, "LocalHost IP will be %s [MAC: %s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac)); + // Only initialize when UPnP is enabled since it takes a few seconds to detect UPnP device (may affect people who don't have UPnP device) if (g_Config.bEnableUPnP) { g_PortManager.Init(); diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index 99e619d0b6..cd531043d7 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -40,7 +40,8 @@ PortManager::PortManager(): urls(0), datas(0), m_InitState(UPNP_INITSTATE_NONE), - m_LocalPort(UPNP_LOCAL_PORT_ANY) { + m_LocalPort(UPNP_LOCAL_PORT_ANY), + m_leaseDuration("43200") { } PortManager::~PortManager() { @@ -63,6 +64,7 @@ void PortManager::Deinit() { m_portList.clear(); m_portList.shrink_to_fit(); m_lanip.clear(); m_defaultDesc.clear(); + m_leaseDuration.clear(); m_LocalPort = UPNP_LOCAL_PORT_ANY; m_InitState = UPNP_INITSTATE_DONE; } @@ -102,6 +104,7 @@ bool PortManager::Init(const unsigned int timeout) { break; } } + m_leaseDuration = "43200"; // 12 hours m_InitState = UPNP_INITSTATE_BUSY; urls = (UPNPUrls*)malloc(sizeof(struct UPNPUrls)); datas = (IGDdatas*)malloc(sizeof(struct IGDdatas)); @@ -131,7 +134,7 @@ bool PortManager::Init(const unsigned int timeout) { GetUPNPUrls(urls, datas, dev->descURL, dev->scope_id); } - // Get LAN IP address + // Get LAN IP address that connects to the router char lanaddr[64] = "unset"; int status = UPNP_GetValidIGD(devlist, urls, datas, lanaddr, sizeof(lanaddr)); //possible "status" values, 0 = NO IGD found, 1 = A valid connected IGD has been found, 2 = A valid IGD has been found but it reported as not connected, 3 = an UPnP device has been found but was not recognized as an IGD m_lanip = std::string(lanaddr); @@ -162,7 +165,7 @@ bool PortManager::Init(const unsigned int timeout) { RefreshPortList(); return true; } - ERROR_LOG(SCENET, "PortManager - upnpDiscover failed (error: %d) or No UPnP device detected", error); + ERROR_LOG(SCENET, "PortManager - upnpDiscover failed (error: %i) or No UPnP device detected", error); auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(n->T("Unable to find UPnP device"), 6.0f, 0x0000ff); m_InitState = UPNP_INITSTATE_NONE; @@ -175,7 +178,6 @@ int PortManager::GetInitState() { bool PortManager::Add(unsigned short port, const char* protocol) { char port_str[16]; - std::string leaseDuration = "43200"; // range(0-604800) in seconds (0 = Indefinite/permanent). Some routers doesn't support non-zero value int r; INFO_LOG(SCENET, "PortManager::Add(%d, %s)", port, protocol); @@ -196,14 +198,21 @@ bool PortManager::Add(unsigned short port, const char* protocol) { r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str, protocol, NULL); } r = UPNP_AddPortMapping(urls->controlURL, datas->first.servicetype, - port_str, port_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, leaseDuration.c_str()); + port_str, port_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, m_leaseDuration.c_str()); + if (r == 725 && m_leaseDuration != "0") { + m_leaseDuration = "0"; + r = UPNP_AddPortMapping(urls->controlURL, datas->first.servicetype, + port_str, port_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, m_leaseDuration.c_str()); + } if (r != 0) { - ERROR_LOG(SCENET, "PortManager - AddPortMapping failed (error: %d)", r); - auto n = GetI18NCategory("Networking"); - host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); - Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts - return false; + ERROR_LOG(SCENET, "PortManager - AddPortMapping failed (error: %i)", r); + if (r == UPNPCOMMAND_HTTP_ERROR) { + auto n = GetI18NCategory("Networking"); + host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); + Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts + return false; + } } m_portList.push_front({ port_str, protocol }); // Keep tracks of it to be restored later if it belongs to others @@ -225,11 +234,13 @@ bool PortManager::Remove(unsigned short port, const char* protocol) { int r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str, protocol, NULL); if (r != 0) { - ERROR_LOG(SCENET, "PortManager - DeletePortMapping failed (error: %d)", r); - auto n = GetI18NCategory("Networking"); - host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); - Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts - return false; + ERROR_LOG(SCENET, "PortManager - DeletePortMapping failed (error: %i)", r); + if (r == UPNPCOMMAND_HTTP_ERROR) { + auto n = GetI18NCategory("Networking"); + host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); + Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts + return false; + } } for (auto it = m_portList.begin(); it != m_portList.end(); ) { (it->first == port_str && it->second == protocol) ? it = m_portList.erase(it) : ++it; @@ -258,8 +269,9 @@ bool PortManager::Restore() { m_portList.erase(el_it); } else { - ERROR_LOG(SCENET, "PortManager::Restore - DeletePortMapping failed (error: %d)", r); - return false; // Might be better not to exit here, but exiting a loop will avoid long timeouts in the case the router is no longer reachable + ERROR_LOG(SCENET, "PortManager::Restore - DeletePortMapping failed (error: %i)", r); + if (r == UPNPCOMMAND_HTTP_ERROR) + return false; // Might be better not to exit here, but exiting a loop will avoid long timeouts in the case the router is no longer reachable } } // Add the original owner back @@ -269,8 +281,9 @@ bool PortManager::Restore() { it->taken = false; } else { - ERROR_LOG(SCENET, "PortManager::Restore - AddPortMapping failed (error: %d)", r); - return false; // Might be better not to exit here, but exiting a loop will avoid long timeouts in the case the router is no longer reachable + ERROR_LOG(SCENET, "PortManager::Restore - AddPortMapping failed (error: %i)", r); + if (r == UPNPCOMMAND_HTTP_ERROR) + return false; // Might be better not to exit here, but exiting a loop will avoid long timeouts in the case the router is no longer reachable } } } @@ -314,8 +327,9 @@ bool PortManager::Clear() { int r2 = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, extPort, protocol, rHost); if (r2 != 0) { - ERROR_LOG(SCENET, "PortManager::Clear - DeletePortMapping(%s, %s) failed (error: %d)", extPort, protocol, r2); - return false; + ERROR_LOG(SCENET, "PortManager::Clear - DeletePortMapping(%s, %s) failed (error: %i)", extPort, protocol, r2); + if (r2 == UPNPCOMMAND_HTTP_ERROR) + return false; } else { i--; diff --git a/Core/Util/PortManager.h b/Core/Util/PortManager.h index 176200c53e..9a4cdedf05 100644 --- a/Core/Util/PortManager.h +++ b/Core/Util/PortManager.h @@ -92,6 +92,7 @@ protected: int m_LocalPort = UPNP_LOCAL_PORT_ANY; std::string m_lanip; std::string m_defaultDesc; + std::string m_leaseDuration = "43200"; // range(0-604800) in seconds (0 = Indefinite/permanent). Some routers doesn't support non-zero value std::deque> m_portList; std::deque m_otherPortList; }; From e2035bf241d48dfbc572b729bb09857ecf0059ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 21 Jul 2020 23:07:10 +0200 Subject: [PATCH 325/848] MiniUPNPC: Windows: Try to fix build on VS 2017, add more platforms. --- ext/miniupnpc.vcxproj | 56 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/ext/miniupnpc.vcxproj b/ext/miniupnpc.vcxproj index ef4015103d..eee8b70595 100644 --- a/ext/miniupnpc.vcxproj +++ b/ext/miniupnpc.vcxproj @@ -1,18 +1,34 @@ + + Debug + ARM + + + Debug + ARM64 + Debug Win32 - - Release - Win32 - Debug x64 + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + Release x64 @@ -61,6 +77,38 @@ miniupnpc 10.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StaticLibrary From 91c7210757d5b34611d328f6fb757fa46038501c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 21 Jul 2020 23:23:59 +0200 Subject: [PATCH 326/848] Set up Windows UWP project for miniupnpc. Gets all the way to linking where it's missing 'in6addr_any' for some reason. --- UWP/CoreUWP/CoreUWP.vcxproj | 7 +- UWP/CoreUWP/CoreUWP.vcxproj.filters | 8 +- UWP/PPSSPP_UWP.sln | 32 ++ UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj | 427 ++++++++++++++++++ .../miniupnpc_UWP.vcxproj.filters | 94 ++++ UWP/miniupnpc_UWP/pch.c | 1 + UWP/miniupnpc_UWP/pch.h | 4 + UWP/miniupnpc_UWP/targetver.h | 8 + 8 files changed, 579 insertions(+), 2 deletions(-) create mode 100644 UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj create mode 100644 UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj.filters create mode 100644 UWP/miniupnpc_UWP/pch.c create mode 100644 UWP/miniupnpc_UWP/pch.h create mode 100644 UWP/miniupnpc_UWP/targetver.h diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 80830c4cc3..8d706d5566 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -565,6 +565,7 @@ + @@ -804,6 +805,7 @@ + @@ -947,8 +949,11 @@ {acb316ca-3ecb-48e5-be0a-91e72d5b0f12} + + {d31fd4f0-53eb-477c-9dc7-149796f628e2} + - + \ No newline at end of file diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 5e9b91ec56..b4eaac21a4 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -708,6 +708,9 @@ HW + + Util + @@ -1307,5 +1310,8 @@ HW + + Util + - + \ No newline at end of file diff --git a/UWP/PPSSPP_UWP.sln b/UWP/PPSSPP_UWP.sln index 73a916158b..63a8e5f693 100644 --- a/UWP/PPSSPP_UWP.sln +++ b/UWP/PPSSPP_UWP.sln @@ -5,6 +5,9 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonUWP", "CommonUWP\CommonUWP.vcxproj", "{ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoreUWP", "CoreUWP\CoreUWP.vcxproj", "{40B76674-02DE-40EF-889B-FAD1489685E7}" + ProjectSection(ProjectDependencies) = postProject + {D31FD4F0-53EB-477C-9DC7-149796F628E2} = {D31FD4F0-53EB-477C-9DC7-149796F628E2} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPU_UWP", "GPU_UWP\GPU_UWP.vcxproj", "{5D271429-C288-4534-98AF-94475D940058}" EndProject @@ -17,6 +20,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib_UWP", "zlib_UWP\zlib_UWP.vcxproj", "{DDF90203-0AAE-4F38-B589-2E9637658CE6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPP_UWP", "UWP.vcxproj", "{01D7D581-09A3-4A26-94BD-A7C529B29329}" + ProjectSection(ProjectDependencies) = postProject + {D31FD4F0-53EB-477C-9DC7-149796F628E2} = {D31FD4F0-53EB-477C-9DC7-149796F628E2} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang_UWP", "glslang_UWP\glslang_UWP.vcxproj", "{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}" EndProject @@ -24,6 +30,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPIRVCross_UWP", "SPIRVCros EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Armips_UWP", "Armips_UWP\Armips_UWP.vcxproj", "{75286959-E7A2-4CBE-8B95-BF05C9C540FF}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc_UWP", "miniupnpc_UWP\miniupnpc_UWP.vcxproj", "{D31FD4F0-53EB-477C-9DC7-149796F628E2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -316,6 +324,30 @@ Global {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|Win32.Build.0 = Release|Win32 {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|x64.ActiveCfg = Release|x64 {75286959-E7A2-4CBE-8B95-BF05C9C540FF}.UWP Gold|x64.Build.0 = Release|x64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Debug|ARM.ActiveCfg = Debug|ARM + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Debug|ARM.Build.0 = Debug|ARM + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Debug|ARM64.Build.0 = Debug|ARM64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Debug|Win32.ActiveCfg = Debug|Win32 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Debug|Win32.Build.0 = Debug|Win32 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Debug|x64.ActiveCfg = Debug|x64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Debug|x64.Build.0 = Debug|x64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Release|ARM.ActiveCfg = Release|ARM + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Release|ARM.Build.0 = Release|ARM + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Release|ARM64.ActiveCfg = Release|ARM64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Release|ARM64.Build.0 = Release|ARM64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Release|Win32.ActiveCfg = Release|Win32 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Release|Win32.Build.0 = Release|Win32 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Release|x64.ActiveCfg = Release|x64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.Release|x64.Build.0 = Release|x64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.UWP Gold|ARM.ActiveCfg = UWP Gold|ARM + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.UWP Gold|ARM.Build.0 = UWP Gold|ARM + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.UWP Gold|ARM64.ActiveCfg = UWP Gold|ARM64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.UWP Gold|ARM64.Build.0 = UWP Gold|ARM64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.UWP Gold|Win32.ActiveCfg = UWP Gold|Win32 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.UWP Gold|Win32.Build.0 = UWP Gold|Win32 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.UWP Gold|x64.ActiveCfg = UWP Gold|x64 + {D31FD4F0-53EB-477C-9DC7-149796F628E2}.UWP Gold|x64.Build.0 = UWP Gold|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj b/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj new file mode 100644 index 0000000000..836bc5b430 --- /dev/null +++ b/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj @@ -0,0 +1,427 @@ + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + UWP Gold + ARM + + + UWP Gold + ARM64 + + + UWP Gold + Win32 + + + UWP Gold + x64 + + + + {d31fd4f0-53eb-477c-9dc7-149796f628e2} + StaticLibrary + miniupnpc_UWP + en-US + 14.0 + true + Windows Store + 10.0.15063.0 + 10.0 + 10.0.17763.0 + + + + StaticLibrary + true + + + StaticLibrary + true + + + StaticLibrary + true + + + StaticLibrary + true + + + StaticLibrary + false + true + + + StaticLibrary + false + true + + + StaticLibrary + false + false + + + StaticLibrary + false + false + + + StaticLibrary + false + false + + + StaticLibrary + false + false + + + StaticLibrary + false + true + + + StaticLibrary + false + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + Use + false + true + pch.h + _CRT_SECURE_NO_WARNINGS;NOMINMAX;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) + ../../ext/miniupnpc;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + + + Console + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj.filters b/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj.filters new file mode 100644 index 0000000000..7c2633456f --- /dev/null +++ b/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj.filters @@ -0,0 +1,94 @@ + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + + + {3e20a98f-6a6c-4ba1-8b5a-d44430460dd1} + + + \ No newline at end of file diff --git a/UWP/miniupnpc_UWP/pch.c b/UWP/miniupnpc_UWP/pch.c new file mode 100644 index 0000000000..bcb5590be1 --- /dev/null +++ b/UWP/miniupnpc_UWP/pch.c @@ -0,0 +1 @@ +#include "pch.h" diff --git a/UWP/miniupnpc_UWP/pch.h b/UWP/miniupnpc_UWP/pch.h new file mode 100644 index 0000000000..be721813fc --- /dev/null +++ b/UWP/miniupnpc_UWP/pch.h @@ -0,0 +1,4 @@ +#pragma once + +#include "targetver.h" + diff --git a/UWP/miniupnpc_UWP/targetver.h b/UWP/miniupnpc_UWP/targetver.h new file mode 100644 index 0000000000..a66ecb00f1 --- /dev/null +++ b/UWP/miniupnpc_UWP/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include From c3afdaf99f6e1e8f8bceee2feb8f23cca858e779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 21 Jul 2020 23:30:32 +0200 Subject: [PATCH 327/848] UWP: Unify linker options --- UWP/UWP.vcxproj | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 66644179d0..67e2def6bd 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -195,7 +195,7 @@ - libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm @@ -220,7 +220,7 @@ - libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm @@ -245,7 +245,7 @@ - xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm @@ -270,7 +270,7 @@ - xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm @@ -295,7 +295,7 @@ - libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm @@ -320,7 +320,7 @@ - libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/ARM64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm @@ -345,7 +345,7 @@ - libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x86/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib @@ -370,7 +370,7 @@ - xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x86/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib @@ -395,7 +395,7 @@ - libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x86/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib @@ -420,7 +420,7 @@ - libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 @@ -445,7 +445,7 @@ - xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 @@ -470,7 +470,7 @@ - libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies) + xinputuap.lib;libavcodec.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;d2d1.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;dwrite.lib; %(AdditionalDependencies) ../ffmpeg/Windows10/x64/lib;%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64 From eb7b6b38f6ce5e25ec4972a2415a91ba82fb3389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 21 Jul 2020 23:43:32 +0200 Subject: [PATCH 328/848] Switch to my miniupnpc fork with a UWP fix --- .gitmodules | 2 +- ext/miniupnp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 390dd8b41f..7513c5e5e3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -30,4 +30,4 @@ url = https://github.com/hrydgard/ppsspp-freetype.git [submodule "ext/miniupnp"] path = ext/miniupnp - url = https://github.com/miniupnp/miniupnp.git + url = https://github.com/hrydgard/miniupnp.git diff --git a/ext/miniupnp b/ext/miniupnp index 927e2f3666..7e229ddd63 160000 --- a/ext/miniupnp +++ b/ext/miniupnp @@ -1 +1 @@ -Subproject commit 927e2f36666f543d59a8080686921069832a3393 +Subproject commit 7e229ddd635933239583ab190d9b614bde018157 From 47f0031f5709ffb81faa76d3cc4c8a10ef43a9a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 00:13:52 +0200 Subject: [PATCH 329/848] Add PortManager.cpp to Android.mk --- android/jni/Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 7aa1cd2d4a..1e71a2e5e1 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -421,6 +421,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/MIPS/JitCommon/JitBlockCache.cpp \ $(SRC)/Core/MIPS/JitCommon/JitState.cpp \ $(SRC)/Core/Util/AudioFormat.cpp \ + $(SRC)/Core/Util/PortManager.cpp \ $(SRC)/Core/Util/GameManager.cpp \ $(SRC)/Core/Util/BlockAllocator.cpp \ $(SRC)/Core/Util/PPGeDraw.cpp \ From 8b37ba8d25b686511f9bd2b985434b0070e85166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 00:17:16 +0200 Subject: [PATCH 330/848] Update the gradle version again. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c28ec21af5..dad9ef0a6c 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.0.0' + classpath 'com.android.tools.build:gradle:4.0.1' } } From 5f2156fa2704120efb4475e9b86974a725c51e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 00:26:43 +0200 Subject: [PATCH 331/848] Windows: Run the upnp string gen script regardless of architecture, and in UWP. --- UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj | 63 +++++++++++++++++++ .../miniupnpc_UWP.vcxproj.filters | 8 +++ ext/miniupnpc.vcxproj | 30 ++++++++- 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj b/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj index 836bc5b430..2ea37b7570 100644 --- a/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj +++ b/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj @@ -212,6 +212,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -227,6 +232,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -242,6 +252,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -257,6 +272,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -272,6 +292,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -287,6 +312,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -302,6 +332,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -317,6 +352,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -332,6 +372,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -347,6 +392,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -362,6 +412,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -377,6 +432,11 @@ false false + + cd ..\..\ext\miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd ..\..\..\..\UWP\miniupnpc_UWP + @@ -421,6 +481,9 @@ Create + + + diff --git a/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj.filters b/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj.filters index 7c2633456f..b6e77744fd 100644 --- a/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj.filters +++ b/UWP/miniupnpc_UWP/miniupnpc_UWP.vcxproj.filters @@ -90,5 +90,13 @@ {3e20a98f-6a6c-4ba1-8b5a-d44430460dd1} + + {f940ecfb-a971-43b3-9f9d-afe3545e9798} + + + + + scripts + \ No newline at end of file diff --git a/ext/miniupnpc.vcxproj b/ext/miniupnpc.vcxproj index eee8b70595..686ca48b1d 100644 --- a/ext/miniupnpc.vcxproj +++ b/ext/miniupnpc.vcxproj @@ -77,7 +77,7 @@ miniupnpc 10.0 - + @@ -290,6 +290,34 @@ cd..\..\.. cd miniupnp\miniupnpc\msvc genminiupnpcstrings.vbs +cd..\..\.. + + + + + cd miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd..\..\.. + + + + + cd miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd..\..\.. + + + + + cd miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs +cd..\..\.. + + + + + cd miniupnp\miniupnpc\msvc +genminiupnpcstrings.vbs cd..\..\.. From 597647a2eb36594b323420b8aee9725e9c5ad37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 01:19:40 +0200 Subject: [PATCH 332/848] Create an Android.mk for miniupnp --- android/jni/Android.mk | 1 + android/jni/Locals.mk | 3 ++- ext/miniupnp-build/Android.mk | 42 +++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 ext/miniupnp-build/Android.mk diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 1e71a2e5e1..f8651f3146 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -593,6 +593,7 @@ endif $(call import-module,libzip) $(call import-module,native) $(call import-module,glslang-build) +$(call import-module,miniupnp-build) ifeq ($(ANDROID_NDK_PROFILER),1) $(call import-module,android-ndk-profiler) diff --git a/android/jni/Locals.mk b/android/jni/Locals.mk index c8a209cf85..eb31e47e41 100644 --- a/android/jni/Locals.mk +++ b/android/jni/Locals.mk @@ -11,6 +11,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/../../ext \ $(LOCAL_PATH)/../../ext/snappy \ $(LOCAL_PATH)/../../ext/glslang \ + $(LOCAL_PATH)/../../ext/miniupnp \ $(LOCAL_PATH)/$(NATIVE)/base \ $(LOCAL_PATH)/$(NATIVE)/ext \ $(LOCAL_PATH)/$(NATIVE)/ext/libpng17 \ @@ -18,7 +19,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/$(NATIVE) \ $(LOCAL_PATH) -LOCAL_STATIC_LIBRARIES := native libzip glslang-build +LOCAL_STATIC_LIBRARIES := native libzip glslang-build miniupnp-build LOCAL_LDLIBS := -lz -landroid -lGLESv2 -lOpenSLES -lEGL -ldl -llog -latomic ifneq ($(NDK_DEBUG),1) # Prettier stack traces are nice on other platforms. diff --git a/ext/miniupnp-build/Android.mk b/ext/miniupnp-build/Android.mk new file mode 100644 index 0000000000..d5403d1c52 --- /dev/null +++ b/ext/miniupnp-build/Android.mk @@ -0,0 +1,42 @@ +# Basic Android.mk for miniupnpc in PPSSPP + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libupnp-build +LOCAL_ARM_MODE := arm +LOCAL_SRC_FILES := \ + ../miniupnp/miniupnpc/connecthostport.c \ + ../miniupnp/miniupnpc/igd_desc_parse.c \ + ../miniupnp/miniupnpc/minisoap.c \ + ../miniupnp/miniupnpc/minissdpc.c \ + ../miniupnp/miniupnpc/miniupnpc.c \ + ../miniupnp/miniupnpc/miniwget.c \ + ../miniupnp/miniupnpc/minixml.c \ + ../miniupnp/miniupnpc/minixmlvalid.c \ + ../miniupnp/miniupnpc/portlistingparse.c \ + ../miniupnp/miniupnpc/receivedata.c \ + ../miniupnp/miniupnpc/upnpcommands.c \ + ../miniupnp/miniupnpc/upnpdev.c \ + ../miniupnp/miniupnpc/upnperrors.c \ + ../miniupnp/miniupnpc/upnpreplyparse.c + +LOCAL_CFLAGS := -O3 -fsigned-char -fno-strict-aliasing -Wall -Wno-multichar -D__STDC_CONSTANT_MACROS +LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder +# Note: LOCAL_PATH is the directory this file is in. +LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. $(LOCAL_PATH)/../miniupnp .. + +ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A +else ifeq ($(TARGET_ARCH_ABI),armeabi) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 +else ifeq ($(TARGET_ARCH_ABI),arm64-v8a) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_ARCH_64 -DARM64 +else ifeq ($(TARGET_ARCH_ABI),x86) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86 +else ifeq ($(TARGET_ARCH_ABI),x86_64) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_X64 +endif + +include $(BUILD_STATIC_LIBRARY) From e1069da10a2b22776de93813a4c3f6bf148cd90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 01:40:54 +0200 Subject: [PATCH 333/848] Oops --- ext/miniupnp-build/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/miniupnp-build/Android.mk b/ext/miniupnp-build/Android.mk index d5403d1c52..e2d7fd1c28 100644 --- a/ext/miniupnp-build/Android.mk +++ b/ext/miniupnp-build/Android.mk @@ -4,7 +4,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE := libupnp-build +LOCAL_MODULE := libminiupnp-build LOCAL_ARM_MODE := arm LOCAL_SRC_FILES := \ ../miniupnp/miniupnpc/connecthostport.c \ From 31e861132bf3349abd74bb60a68b6737442a5b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 10:26:21 +0200 Subject: [PATCH 334/848] Implement ANR2ME's solution for miniupnpcstring.h --- android/jni/Locals.mk | 1 + ext/miniupnp-build/miniupnpcstrings.h | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 ext/miniupnp-build/miniupnpcstrings.h diff --git a/android/jni/Locals.mk b/android/jni/Locals.mk index eb31e47e41..8493c67b05 100644 --- a/android/jni/Locals.mk +++ b/android/jni/Locals.mk @@ -12,6 +12,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/../../ext/snappy \ $(LOCAL_PATH)/../../ext/glslang \ $(LOCAL_PATH)/../../ext/miniupnp \ + $(LOCAL_PATH)/../../ext/miniupnp-build \ $(LOCAL_PATH)/$(NATIVE)/base \ $(LOCAL_PATH)/$(NATIVE)/ext \ $(LOCAL_PATH)/$(NATIVE)/ext/libpng17 \ diff --git a/ext/miniupnp-build/miniupnpcstrings.h b/ext/miniupnp-build/miniupnpcstrings.h new file mode 100644 index 0000000000..1489a91134 --- /dev/null +++ b/ext/miniupnp-build/miniupnpcstrings.h @@ -0,0 +1,23 @@ +/* $Id: miniupnpcstrings.h.in,v 1.6 2014/11/04 22:31:55 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2014 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef MINIUPNPCSTRINGS_H_INCLUDED +#define MINIUPNPCSTRINGS_H_INCLUDED + +#define OS_STRING "Android" +#define MINIUPNPC_VERSION_STRING "2.1" + +#if 0 +/* according to "UPnP Device Architecture 1.0" */ +#define UPNP_VERSION_STRING "UPnP/1.0" +#else +/* according to "UPnP Device Architecture 1.1" */ +#define UPNP_VERSION_STRING "UPnP/1.1" +#endif + +#endif + From d0045947f1129ec69d5fcb8053295b3fc7dfbe73 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 18 Jan 2020 02:32:09 +0700 Subject: [PATCH 335/848] An attempt to fix socket's behavior inconsistencies across platforms. Added an option to override minimum socket's timeout to prevent getting timeouts on high latency networks. --- Core/Config.cpp | 5 ++- Core/Config.h | 5 ++- Core/HLE/proAdhoc.cpp | 73 +++++++++++++++++++++++++++++++------ Core/HLE/proAdhoc.h | 27 +++++++++++++- Core/HLE/proAdhocServer.cpp | 17 +++++++++ Core/HLE/sceNet.cpp | 4 +- Core/Util/PortManager.cpp | 2 + UI/GameSettingsScreen.cpp | 1 + 8 files changed, 115 insertions(+), 19 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 5250751855..a61ea02740 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -955,7 +955,10 @@ static ConfigSetting controlSettings[] = { static ConfigSetting networkSettings[] = { ConfigSetting("EnableWlan", &g_Config.bEnableWlan, false, true, true), ConfigSetting("EnableAdhocServer", &g_Config.bEnableAdhocServer, false, true, true), + ConfigSetting("proAdhocServer", &g_Config.proAdhocServer, "myneighborsushicat.com", true, true), + ConfigSetting("PortOffset", &g_Config.iPortOffset, 0, true, true), ConfigSetting("EnableUPnP", &g_Config.bEnableUPnP, false, true, true), + ConfigSetting("MinTimeout", &g_Config.iMinTimeout, 1, true, true), ConfigSetting("EnableNetworkChat", &g_Config.bEnableNetworkChat, false, true, true), ConfigSetting("ChatButtonPosition",&g_Config.iChatButtonPosition,BOTTOM_LEFT,true,true), @@ -995,9 +998,7 @@ static ConfigSetting systemParamSettings[] = { ReportedConfigSetting("PSPModel", &g_Config.iPSPModel, &DefaultPSPModel, true, true), ReportedConfigSetting("PSPFirmwareVersion", &g_Config.iFirmwareVersion, PSP_DEFAULT_FIRMWARE, true, true), ConfigSetting("NickName", &g_Config.sNickName, "PPSSPP", true, true), - ConfigSetting("proAdhocServer", &g_Config.proAdhocServer, "myneighborsushicat.com", true, true), ConfigSetting("MacAddress", &g_Config.sMACAddress, "", true, true), - ConfigSetting("PortOffset", &g_Config.iPortOffset, 0, true, true), ReportedConfigSetting("Language", &g_Config.iLanguage, &DefaultSystemParamLanguage, true, true), ConfigSetting("ParamTimeFormat", &g_Config.iTimeFormat, PSP_SYSTEMPARAM_TIME_FORMAT_24HR, true, true), ConfigSetting("ParamDateFormat", &g_Config.iDateFormat, PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD, true, true), diff --git a/Core/Config.h b/Core/Config.h index 077e75ada4..8ef4696b4f 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -396,9 +396,7 @@ public: // SystemParam std::string sNickName; - std::string proAdhocServer; std::string sMACAddress; - int iPortOffset; int iLanguage; int iTimeFormat; int iDateFormat; @@ -410,9 +408,12 @@ public: bool bSavedataUpgrade; // Networking + std::string proAdhocServer; bool bEnableWlan; bool bEnableAdhocServer; bool bEnableUPnP; + int iPortOffset; + int iMinTimeout; int iWlanAdhocChannel; bool bWlanPowerSave; bool bEnableNetworkChat; diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 855f991300..f0d1de9be4 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -42,7 +42,8 @@ #include "proAdhoc.h" #include "i18n/i18n.h" -uint16_t portOffset = g_Config.iPortOffset; +uint16_t portOffset; +uint32_t minSocketTimeoutUS; uint32_t fakePoolSize = 0; SceNetAdhocMatchingContext * contexts = NULL; int one = 1; @@ -215,8 +216,8 @@ SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC) { void changeBlockingMode(int fd, int nonblocking) { unsigned long on = 1; unsigned long off = 0; -#ifdef _WIN32 - if (nonblocking){ +#if defined(_WIN32) + if (nonblocking) { // Change to Non-Blocking Mode ioctlsocket(fd, FIONBIO, &on); } @@ -224,14 +225,31 @@ void changeBlockingMode(int fd, int nonblocking) { // Change to Blocking Mode ioctlsocket(fd, FIONBIO, &off); } +// If they have O_NONBLOCK, use the POSIX way to do it. On POSIX sockets Error code would be EINPROGRESS instead of EAGAIN +//#elif defined(O_NONBLOCK) #else - if(nonblocking == 1) fcntl(fd, F_SETFL, O_NONBLOCK); + int flags = fcntl(fd, F_GETFL, 0); + // Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. + if (flags == -1) + flags = 0; + if (nonblocking) { + // Set Non-Blocking Flag + fcntl(fd, F_SETFL, flags | O_NONBLOCK); + } else { - // Get Flags - int flags = fcntl(fd, F_GETFL); // Remove Non-Blocking Flag fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); } +// Otherwise, use the old way of doing it (UNIX way). On UNIX sockets Error code would be EAGAIN instead of EINPROGRESS +/*#else + if (nonblocking) { + // Change to Non - Blocking Mode + ioctl(fd, FIONBIO, (char*)&on); + } + else { + // Change to Blocking Mode + ioctl(fd, FIONBIO, (char*)&off); + }*/ #endif } @@ -1613,6 +1631,16 @@ uint16_t getLocalPort(int sock) { return ntohs(localAddr.sin_port); } +int getSockMaxSize(int udpsock) { +#if !defined(SO_MAX_MSG_SIZE) +#define SO_MAX_MSG_SIZE 0x2003 +#endif + int n = 1500; // Typical MTU size as default + socklen_t m = sizeof(n); + getsockopt(udpsock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*)&n, &m); + return n; +} + int getSockBufferSize(int sock, int opt) { // opt = SO_RCVBUF/SO_SNDBUF int n = 16384; socklen_t m = sizeof(n); @@ -1625,22 +1653,45 @@ int setSockBufferSize(int sock, int opt, int size) { // opt = SO_RCVBUF/SO_SNDBU return setsockopt(sock, SOL_SOCKET, opt, (char *)&n, sizeof(n)); } +int setSockTimeout(int sock, int opt, unsigned long timeout_usec) { // opt = SO_SNDTIMEO/SO_RCVTIMEO + if (timeout_usec > 0 && timeout_usec < minSocketTimeoutUS) timeout_usec = minSocketTimeoutUS; // Override timeout for high latency multiplayer +#if defined(_WIN32) + unsigned long optval = timeout_usec / 1000UL; + if (timeout_usec > 0 && optval == 0) optval = 1; // Since there are games that use 100 usec timeout, we should set it to minimum value on Windows (1 msec) instead of using 0 (0 = indefinitely timeout) +#else + struct timeval optval = { static_cast(timeout_usec) / 1000000L, static_cast(timeout_usec) % 1000000L }; +#endif + return setsockopt(sock, SOL_SOCKET, opt, (char*)&optval, sizeof(optval)); +} + +int getSockNoDelay(int tcpsock) { + int opt = 0; + socklen_t optlen = sizeof(opt); + getsockopt(tcpsock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, &optlen); + return opt; +} + +int setSockNoDelay(int tcpsock, int flag) { + int opt = flag; + return setsockopt(tcpsock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt)); +} + #if !defined(TCP_KEEPIDLE) #define TCP_KEEPIDLE TCP_KEEPALIVE //TCP_KEEPIDLE on Linux is equivalent to TCP_KEEPALIVE on macOS #endif -int setSockKeepAlive(int sock, bool keepalive, const int keepcnt, const int keepidle, const int keepinvl) { +int setSockKeepAlive(int sock, bool keepalive, const int keepinvl, const int keepcnt, const int keepidle) { int optval = keepalive ? 1 : 0; int optlen = sizeof(optval); int result = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, optlen); if (result == 0 && keepalive) { if (getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&optval, (socklen_t*)&optlen) == 0 && optval == SOCK_STREAM) { optlen = sizeof(optval); + optval = keepidle; //180 sec + setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&optval, optlen); + optval = keepinvl; //60 sec + setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&optval, optlen); optval = keepcnt; //20 setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (char*)&optval, optlen); - optval = keepidle; //180 - setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&optval, optlen); - optval = keepinvl; //60 - setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&optval, optlen); } } return result; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 94518d3cdd..3b0b58b9d0 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -65,6 +65,7 @@ #undef EINPROGRESS #undef EISCONN #undef EALREADY +#undef ETIMEDOUT #define errno WSAGetLastError() #define ECONNABORTED WSAECONNABORTED #define ECONNRESET WSAECONNRESET @@ -73,12 +74,13 @@ #define EINPROGRESS WSAEWOULDBLOCK #define EISCONN WSAEISCONN #define EALREADY WSAEALREADY +#define ETIMEDOUT WSAETIMEDOUT inline bool connectInProgress(int errcode){ return (errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS || errcode == WSAEALREADY); } #else #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #define closesocket close -inline bool connectInProgress(int errcode){ return (errcode == EINPROGRESS || errcode == EALREADY); } +inline bool connectInProgress(int errcode){ return (errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EALREADY); } #endif #ifndef POLL_ERR @@ -841,6 +843,7 @@ extern SceNetAdhocPdpStat * pdp[255]; extern SceNetAdhocPtpStat * ptp[255]; extern uint16_t portOffset; +extern uint32_t minSocketTimeoutUS; extern bool isLocalServer; extern sockaddr LocalhostIP; // Used to differentiate localhost IP on multiple-instance extern sockaddr LocalIP; // IP of Network Adapter used to connect to Adhoc Server (LAN/WAN) @@ -1155,6 +1158,11 @@ int getActivePeerCount(const bool excludeTimedout = true); int getLocalIp(sockaddr_in * SocketAddress); uint32_t getLocalIp(int sock); +/* + * Get UDP Socket Max Message Size + */ +int getSockMaxSize(int udpsock); + /* * Get Socket Buffer Size (opt = SO_RCVBUF/SO_SNDBUF) */ @@ -1165,10 +1173,25 @@ int getSockBufferSize(int sock, int opt); */ int setSockBufferSize(int sock, int opt, int size); +/* +* Set Socket TimeOut (opt = SO_SNDTIMEO/SO_RCVTIMEO) +*/ +int setSockTimeout(int sock, int opt, unsigned long timeout_usec); + +/* + * Get TCP Socket TCP_NODELAY (Nagle Algo) + */ +int getSockNoDelay(int tcpsock); + +/* +* Set TCP Socket TCP_NODELAY (Nagle Algo) +*/ +int setSockNoDelay(int tcpsock, int flag); + /* * Set Socket KeepAlive (opt = SO_KEEPALIVE) */ -int setSockKeepAlive(int sock, bool keepalive, const int keepcnt = 20, const int keepidle = 180, const int keepinvl = 60); +int setSockKeepAlive(int sock, bool keepalive, const int keepinvl = 60, const int keepcnt = 20, const int keepidle = 180); /** * Return the Number of Players with the chosen Nickname in the Local Users current Network diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index a385e7d8e5..c8ef8ea79c 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -37,6 +37,7 @@ #else #include #include +#include #endif #include @@ -476,6 +477,8 @@ const char * strcpyxml(char * out, const char * in, uint32_t size); // Function Prototypes void interrupt(int sig); void enable_address_reuse(int fd); +void enable_keepalive(int fd); +void change_nodelay_mode(int fd, int flag); void change_blocking_mode(int fd, int nonblocking); int create_listen_socket(uint16_t port); int server_loop(int server); @@ -1743,6 +1746,17 @@ void enable_keepalive(int fd) setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(on)); } +/** + * Change TCP Socket TCP_NODELAY (Nagle Algo) mode + * @param fd Socket + * @param nonblocking 1 for Nonblocking, 0 for Blocking + */ +void change_nodelay_mode(int fd, int flag) +{ + int opt = flag; + setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt)); +} + /** * Change Socket Blocking Mode * @param fd Socket @@ -1799,6 +1813,9 @@ int create_listen_socket(uint16_t port) // Make Socket Nonblocking change_blocking_mode(fd, 1); + // Make TCP Socket send immediately + change_nodelay_mode(fd, 1); + // Prepare Local Address Information struct sockaddr_in local; memset(&local, 0, sizeof(local)); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 7b6a5aea78..24bd5fd38b 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -115,7 +115,9 @@ static void __ResetInitNetLib() { } void __NetInit() { + // Windows: Assuming WSAStartup already called beforehand portOffset = g_Config.iPortOffset; + minSocketTimeoutUS = g_Config.iMinTimeout * 1000UL; InitLocalhostIP(); @@ -149,8 +151,6 @@ void __NetShutdown() { g_PortManager.Restore(); g_PortManager.Deinit(); } - - //PPSSPPIDCleanup(); // To make the ID/IP persistent on every reset, we should just let the OS closes all open handles instead of calling PPSSPPIDCleanup() on every reset } static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) { diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index cd531043d7..cb518ec275 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -104,6 +104,7 @@ bool PortManager::Init(const unsigned int timeout) { break; } } + m_leaseDuration = "43200"; // 12 hours m_InitState = UPNP_INITSTATE_BUSY; urls = (UPNPUrls*)malloc(sizeof(struct UPNPUrls)); @@ -165,6 +166,7 @@ bool PortManager::Init(const unsigned int timeout) { RefreshPortList(); return true; } + ERROR_LOG(SCENET, "PortManager - upnpDiscover failed (error: %i) or No UPnP device detected", error); auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(n->T("Unable to find UPnP device"), 6.0f, 0x0000ff); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 78d860f234..a7088a829d 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -693,6 +693,7 @@ void GameSettingsScreen::CreateViews() { networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)"))); networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress); networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset(0 = PSP compatibility)"), 100, screenManager())); + networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 1, 15000, n->T("Minimum Timeout", "Minimum Timeout (override low latency communication in milliseconds)"), 100, screenManager())); networkingSettings->Add(new ItemHeader(n->T("Chat"))); networkingSettings->Add(new CheckBox(&g_Config.bEnableNetworkChat, n->T("Enable network chat", "Enable network chat"))); From 8daf2ff66eb97a884466f59b8f19dffe23decc00 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 2 Mar 2020 03:59:13 +0700 Subject: [PATCH 336/848] Added UI to change WLAN Channel. Currently Ridge Racer 2 doesn't works with Auto channel (TODO: Making sure sceUtilityGetSystemParamInt doesn't returns channel 0 when connected to a network for Ridge Racer 2 to works with Auto channel) --- Core/HLE/proAdhoc.cpp | 11 +++++++---- Core/HLE/proAdhoc.h | 5 +++-- Core/HLE/sceNet.cpp | 3 +++ Core/HLE/sceNetAdhoc.cpp | 2 +- UI/GameSettingsScreen.cpp | 6 ++++++ 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index f0d1de9be4..bb672ac939 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -76,6 +76,7 @@ int newChat = 0; bool isLocalServer = false; sockaddr LocalhostIP; sockaddr LocalIP; +int defaultWlanChannel = 1; bool isLocalMAC(const SceNetEtherAddr * addr) { SceNetEtherAddr saddr; @@ -1239,7 +1240,7 @@ int friendFinder(){ }*/ // Update User BSSID - //parameter.bssid.mac_addr = packet->mac; // The MAC address in this packet seems to Always be the First player joining the Group (group Creator?), Shouldn't it be it self? + //parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address // Notify Event Handlers //notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); // Change State @@ -1416,7 +1417,8 @@ int friendFinder(){ group->bssid.mac_addr = packet->mac; // Set group parameters - group->channel = parameter.channel; + // Since 0 is not a valid active channel we fake the channel for Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?) + group->channel = parameter.channel; //(parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) ? defaultWlanChannel : parameter.channel; group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode; // Link into Group List @@ -1808,8 +1810,9 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ memset(¶meter, 0, sizeof(parameter)); strncpy((char *)¶meter.nickname.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN); parameter.nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; - parameter.channel = g_Config.iWlanAdhocChannel; // Fake Channel, 0 = Auto where JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11) - if (parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) parameter.channel = 1; + parameter.channel = g_Config.iWlanAdhocChannel; + // Assign a Valid Channel when connected to AP/AdhocGroup if it's Auto. JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11) + if (parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) parameter.channel = defaultWlanChannel; // Faked Active channel to default channel getLocalMac(¶meter.bssid.mac_addr); // Default ProductId diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 3b0b58b9d0..8375d8a105 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -242,10 +242,10 @@ typedef struct SceNetAdhocctlNickname { uint8_t data[ADHOCCTL_NICKNAME_LEN]; } PACK SceNetAdhocctlNickname; -// Active Virtual Network Information +// Active Virtual Network Information (Adhoc Group Host/Creator's device info, similar to AP?) typedef struct SceNetAdhocctlParameter { s32_le channel; - SceNetAdhocctlGroupName group_name; + SceNetAdhocctlGroupName group_name; // This group name is probably similar to SSID name on AP SceNetAdhocctlBSSId bssid; SceNetAdhocctlNickname nickname; } PACK SceNetAdhocctlParameter; @@ -847,6 +847,7 @@ extern uint32_t minSocketTimeoutUS; extern bool isLocalServer; extern sockaddr LocalhostIP; // Used to differentiate localhost IP on multiple-instance extern sockaddr LocalIP; // IP of Network Adapter used to connect to Adhoc Server (LAN/WAN) +extern int defaultWlanChannel; // Default WLAN Channel for Auto, JPCSP uses 11 extern uint32_t fakePoolSize; extern SceNetAdhocMatchingContext * contexts; diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 24bd5fd38b..e4e3013a2a 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -112,6 +112,7 @@ static void __ResetInitNetLib() { netInetInited = false; memset(&netMallocStat, 0, sizeof(netMallocStat)); + memset(¶meter, 0, sizeof(parameter)); } void __NetInit() { @@ -251,6 +252,8 @@ static u32 sceNetTerm() { FreeUser(netThread1Addr); FreeUser(netThread2Addr); + // Give time to make sure everything are cleaned up + hleDelayResult(0, "give time to init/cleanup", adhocEventDelayMS * 1000); return 0; } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index e9ba3a4268..36cb37766e 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1091,7 +1091,7 @@ static int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { // Exchange Adhoc Channel // sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_ADHOC_CHANNEL, &buf[discovered].channel); - // Fake Channel Number 1 on Automatic Channel + // Fake Channel Number 1 on Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?) buf[discovered].channel = group->channel; //parameter.channel // Increase Discovery Counter diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index a7088a829d..4090861c53 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -692,6 +692,12 @@ void GameSettingsScreen::CreateViews() { networkingSettings->Add(new CheckBox(&g_Config.bEnableAdhocServer, n->T("Enable built-in PRO Adhoc Server", "Enable built-in PRO Adhoc Server"))); networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)"))); networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress); + static const char* wlanChannels[] = { "Auto", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" }; + auto wlanChannelChoice = networkingSettings->Add(new PopupMultiChoice(&g_Config.iWlanAdhocChannel, gr->T("WLAN Channel"), wlanChannels, 0, ARRAY_SIZE(wlanChannels), gr->GetName(), screenManager())); + for (int i = 0; i < 4; i++) { + wlanChannelChoice->HideChoice(i+2); + wlanChannelChoice->HideChoice(i+7); + } networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset(0 = PSP compatibility)"), 100, screenManager())); networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 1, 15000, n->T("Minimum Timeout", "Minimum Timeout (override low latency communication in milliseconds)"), 100, screenManager())); From d1cafd103c8a14a0f5e47b8b97e36eddb76762dd Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Wed, 22 Jul 2020 23:47:29 +0800 Subject: [PATCH 337/848] Use the alloc size from real PSP for FONT_OPEN_INTERNAL_STINGY mode. the --- Core/HLE/sceFont.cpp | 45 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 0bb70b5bfb..c742134ecd 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -89,30 +89,31 @@ struct FontRegistryEntry { int expireDate; int shadow_option; u32 fontFileSize; + u32 stingySize; // for the FONT_OPEN_INTERNAL_STINGY mode, from pspautotests. bool ignoreIfMissing; }; static const FontRegistryEntry fontRegistry[] = { // This was added for Chinese translations and is not normally loaded on a PSP. - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_CHINESE, 0, 1, "zh_gb.pgf", "FTT-NewRodin Pro DB", 0, 0, 1581700, true }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_JAPANESE, 0, 1, "jpn0.pgf", "FTT-NewRodin Pro DB", 0, 0, 1581700 }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn0.pgf", "FTT-NewRodin Pro Latin", 0, 0, 69108 }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn1.pgf", "FTT-Matisse Pro Latin", 0, 0, 65124 }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn2.pgf", "FTT-NewRodin Pro Latin", 0, 0, 72948 }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn3.pgf", "FTT-Matisse Pro Latin", 0, 0, 67700}, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn4.pgf", "FTT-NewRodin Pro Latin", 0, 0, 72828 }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn5.pgf", "FTT-Matisse Pro Latin", 0, 0, 68220 }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn6.pgf", "FTT-NewRodin Pro Latin", 0, 0, 77032 }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn7.pgf", "FTT-Matisse Pro Latin", 0, 0, 71144 }, - { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn8.pgf", "FTT-NewRodin Pro Latin", 0, 0, 41000 }, - { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn9.pgf", "FTT-Matisse Pro Latin", 0, 0, 40164 }, - { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn10.pgf", "FTT-NewRodin Pro Latin", 0, 0, 42692 }, - { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn11.pgf", "FTT-Matisse Pro Latin", 0, 0, 41488 }, - { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn12.pgf", "FTT-NewRodin Pro Latin", 0, 0, 43136 }, - { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn13.pgf", "FTT-Matisse Pro Latin", 0, 0, 41772 }, - { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn14.pgf", "FTT-NewRodin Pro Latin", 0, 0, 45184 }, - { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn15.pgf", "FTT-Matisse Pro Latin", 0, 0, 43044 }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_KOREAN, 0, 3, "kr0.pgf", "AsiaNHH(512Johab)", 0, 0, 394192 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_CHINESE, 0, 1, "zh_gb.pgf", "FTT-NewRodin Pro DB", 0, 0, 1581700, 145844, true }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_JAPANESE, 0, 1, "jpn0.pgf", "FTT-NewRodin Pro DB", 0, 0, 1581700, 145844 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn0.pgf", "FTT-NewRodin Pro Latin", 0, 0, 69108, 16680 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn1.pgf", "FTT-Matisse Pro Latin", 0, 0, 65124, 16920 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn2.pgf", "FTT-NewRodin Pro Latin", 0, 0, 72948, 16872 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn3.pgf", "FTT-Matisse Pro Latin", 0, 0, 67700, 17112 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn4.pgf", "FTT-NewRodin Pro Latin", 0, 0, 72828, 16648 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn5.pgf", "FTT-Matisse Pro Latin", 0, 0, 68220, 16928 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn6.pgf", "FTT-NewRodin Pro Latin", 0, 0, 77032, 16792 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn7.pgf", "FTT-Matisse Pro Latin", 0, 0, 71144, 17160 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn8.pgf", "FTT-NewRodin Pro Latin", 0, 0, 41000, 16192 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn9.pgf", "FTT-Matisse Pro Latin", 0, 0, 40164, 16476 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn10.pgf", "FTT-NewRodin Pro Latin", 0, 0, 42692, 16300 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn11.pgf", "FTT-Matisse Pro Latin", 0, 0, 41488, 16656 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn12.pgf", "FTT-NewRodin Pro Latin", 0, 0, 43136, 16176 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn13.pgf", "FTT-Matisse Pro Latin", 0, 0, 41772, 16436 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn14.pgf", "FTT-NewRodin Pro Latin", 0, 0, 45184, 16272 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn15.pgf", "FTT-Matisse Pro Latin", 0, 0, 43044, 16704 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_KOREAN, 0, 3, "kr0.pgf", "AsiaNHH(512Johab)", 0, 0, 394192, 51856 }, }; static const float pointDPI = 72.f; @@ -212,6 +213,7 @@ public: PGF *GetPGF() { return &pgf_; } const PGF *GetPGF() const { return &pgf_; } u32 getSize() const { return dataSize_; } + u32 getStingySize() const { return stingySize_; } bool IsValid() const { return valid_; } void DoState(PointerWrap &p) { @@ -237,6 +239,7 @@ private: style_.fontHRes = (float)pgf_.header.hResolution / 64.0f; style_.fontVRes = (float)pgf_.header.vResolution / 64.0f; this->dataSize_ = (u32)dataSize; + this->stingySize_ = 0; // Unused } void Init(const u8 *data, size_t dataSize, const FontRegistryEntry &entry) { @@ -257,12 +260,14 @@ private: style_.fontAttributes = entry.extraAttributes; style_.fontExpire = entry.expireDate; this->dataSize_ = entry.fontFileSize; + this->stingySize_ = entry.stingySize; } PGF pgf_; PGFFontStyle style_; bool valid_; u32 dataSize_; + u32 stingySize_; DISALLOW_COPY_AND_ASSIGN(Font); }; @@ -613,7 +618,7 @@ public: u32 allocSize = 12; if (mode == FONT_OPEN_INTERNAL_STINGY) { - allocSize = 0x239B4; + allocSize = loadedFont->GetFont()->getStingySize(); } else if (mode == FONT_OPEN_INTERNAL_FULL) { allocSize += loadedFont->GetFont()->getSize(); } From cc96e9ad11a3fbff2732f7ac96c54526dc475949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 18:41:32 +0200 Subject: [PATCH 338/848] Backport Mac/iOS buildfix from a later commit --- Core/HLE/proAdhoc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index bb672ac939..18bdc89090 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1660,6 +1660,10 @@ int setSockTimeout(int sock, int opt, unsigned long timeout_usec) { // opt = SO_ #if defined(_WIN32) unsigned long optval = timeout_usec / 1000UL; if (timeout_usec > 0 && optval == 0) optval = 1; // Since there are games that use 100 usec timeout, we should set it to minimum value on Windows (1 msec) instead of using 0 (0 = indefinitely timeout) +#elif defined(__APPLE__) + struct timeval optval; + optval.tv_sec = static_cast(timeout_usec) / 1000000L; + optval.tv_usec = static_cast(timeout_usec) % 1000000L; #else struct timeval optval = { static_cast(timeout_usec) / 1000000L, static_cast(timeout_usec) % 1000000L }; #endif From 62c37a3481136983b9d308e90981dce9587ab0b1 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 10 Mar 2020 19:14:17 +0700 Subject: [PATCH 339/848] Fix Blinking game room issue on NFS Most Wanted, this will also fix lobby issue on Ridge Racer 2, Naruto Kizuna Drive, etc. --- Core/HLE/proAdhoc.cpp | 62 +++++++++++++++++++------------------------ Core/HLE/proAdhoc.h | 8 +++--- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 18bdc89090..a9a60c477c 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -283,7 +283,7 @@ SceNetAdhocctlScanInfo * findGroup(SceNetEtherAddr * MAC) { return group; } -void freeGroupsRecursive(SceNetAdhocctlScanInfo * node) { +void freeGroupsRecursive(SceNetAdhocctlScanInfo *& node) { // End of List if (node == NULL) return; @@ -603,7 +603,7 @@ SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context * @param context Matching Context Pointer * @param peer Internal Peer Reference */ -void deletePeer(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingMemberInternal * peer) +void deletePeer(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingMemberInternal *& peer) { // Valid Arguments if (context != NULL && peer != NULL) @@ -729,7 +729,8 @@ void sendGenericMessage(SceNetAdhocMatchingContext * context, int stack, SceNetE peerlock.lock(); // Out of Memory Emergency Delete - deletePeer(context, findPeer(context, mac)); + auto peer = findPeer(context, mac); + deletePeer(context, peer); peerlock.unlock(); } @@ -924,7 +925,7 @@ void handleTimeout(SceNetAdhocMatchingContext * context) * Recursive Stack Cleaner * @param node Current Thread Message Node */ -void clearStackRecursive(ThreadMessage * node) +void clearStackRecursive(ThreadMessage *& node) { // Not End of List if (node != NULL) clearStackRecursive(node->next); @@ -1094,7 +1095,7 @@ void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * __UpdateMatchingHandler(argsNew); } -void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count) { +void freeFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count) { // End of List if (node == NULL) return; @@ -1107,7 +1108,7 @@ void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count) { if (count != NULL) (*count)++; } -void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo* node, int32_t* count) { +void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count) { // End of List if (node == NULL) return; @@ -1389,41 +1390,30 @@ int friendFinder(){ // Multithreading Lock peerlock.lock(); - // Should only add non-existing group (or replace an existing group) to prevent Ford Street Racing from showing a strange game session list - SceNetAdhocctlScanInfo * group = findGroup(&packet->mac); + // Allocate Structure Data + SceNetAdhocctlScanInfo* group = (SceNetAdhocctlScanInfo*)malloc(sizeof(SceNetAdhocctlScanInfo)); + // Allocated Structure Data if (group != NULL) { + // Clear Memory, should this be done only when allocating new group? + memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); + + // Link to existing Groups + group->next = newnetworks; + // Copy Group Name group->group_name = packet->group; // Set Group Host group->bssid.mac_addr = packet->mac; - } else { - // Allocate Structure Data - SceNetAdhocctlScanInfo * group = (SceNetAdhocctlScanInfo *)malloc(sizeof(SceNetAdhocctlScanInfo)); - // Allocated Structure Data - if (group != NULL) { - // Clear Memory, should this be done only when allocating new group? - memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); + // Set group parameters + // Since 0 is not a valid active channel we fake the channel for Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?) + group->channel = parameter.channel; //(parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) ? defaultWlanChannel : parameter.channel; + group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode; - // Link to existing Groups - group->next = newnetworks; - - // Copy Group Name - group->group_name = packet->group; - - // Set Group Host - group->bssid.mac_addr = packet->mac; - - // Set group parameters - // Since 0 is not a valid active channel we fake the channel for Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?) - group->channel = parameter.channel; //(parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) ? defaultWlanChannel : parameter.channel; - group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode; - - // Link into Group List - newnetworks = group; - } + // Link into Group List + newnetworks = group; } // Multithreading Unlock @@ -1443,10 +1433,12 @@ int friendFinder(){ // Log Scan Completion INFO_LOG(SCENET, "FriendFinder: Incoming Scan complete response..."); - // Reset current networks to prevent leaving host to be listed again + // Reset current networks to prevent disbanded host to be listed again peerlock.lock(); - freeGroupsRecursive(networks); - networks = newnetworks; + if (networks != newnetworks) { + freeGroupsRecursive(networks); + networks = newnetworks; + } newnetworks = NULL; peerlock.unlock(); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 8375d8a105..5970e4936a 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -940,7 +940,7 @@ SceNetAdhocctlScanInfo * findGroup(SceNetEtherAddr * MAC); /* * Deletes all groups in networks */ -void freeGroupsRecursive(SceNetAdhocctlScanInfo * node); +void freeGroupsRecursive(SceNetAdhocctlScanInfo *& node); /** * Closes & Deletes all PDP Sockets @@ -962,9 +962,9 @@ void deleteFriendByIP(uint32_t ip); * Recursive Memory Freeing-Helper for Friend-Structures * @param node Current Node in List */ -void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count); +void freeFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count); -void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo* node, int32_t* count); +void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count); /** * Friend Finder Thread (Receives Peer Information) @@ -1094,7 +1094,7 @@ s32_le countChildren(SceNetAdhocMatchingContext * context, const bool excludeTim * @param context Matching Context Pointer * @param peer Internal Peer Reference */ -void deletePeer(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingMemberInternal * peer); +void deletePeer(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingMemberInternal *& peer); /** * Find Peer in Context by MAC From d12218e8da537a50f3dca2f0f1a1527d2d395766 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 13 Jul 2020 04:11:36 +0700 Subject: [PATCH 340/848] Attempt to fix compilation error on Linux --- Core/HLE/proAdhoc.cpp | 6 +++--- Core/HLE/proAdhoc.h | 6 +++--- Core/Util/PortManager.cpp | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a9a60c477c..eab69f3a6d 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -283,7 +283,7 @@ SceNetAdhocctlScanInfo * findGroup(SceNetEtherAddr * MAC) { return group; } -void freeGroupsRecursive(SceNetAdhocctlScanInfo *& node) { +void freeGroupsRecursive(SceNetAdhocctlScanInfo * node) { // End of List if (node == NULL) return; @@ -1095,7 +1095,7 @@ void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * __UpdateMatchingHandler(argsNew); } -void freeFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count) { +void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count) { // End of List if (node == NULL) return; @@ -1108,7 +1108,7 @@ void freeFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count) { if (count != NULL) (*count)++; } -void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count) { +void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count) { // End of List if (node == NULL) return; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 5970e4936a..29ce58f2d1 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -940,7 +940,7 @@ SceNetAdhocctlScanInfo * findGroup(SceNetEtherAddr * MAC); /* * Deletes all groups in networks */ -void freeGroupsRecursive(SceNetAdhocctlScanInfo *& node); +void freeGroupsRecursive(SceNetAdhocctlScanInfo * node); /** * Closes & Deletes all PDP Sockets @@ -962,9 +962,9 @@ void deleteFriendByIP(uint32_t ip); * Recursive Memory Freeing-Helper for Friend-Structures * @param node Current Node in List */ -void freeFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count); +void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count); -void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo *& node, int32_t* count); +void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count); /** * Friend Finder Thread (Receives Peer Information) diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index cb518ec275..166944e75b 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -26,6 +26,7 @@ #include +#include #include #include #include From a6d49af6688c4eb725b10639d82e8134c13be116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 21:24:07 +0200 Subject: [PATCH 341/848] libretro buildfix? --- libretro/Makefile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index b9fe4993bc..dcfba1d130 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -485,6 +485,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/Util/BlockAllocator.cpp \ $(COREDIR)/Util/PPGeDraw.cpp \ $(COREDIR)/Util/AudioFormat.cpp \ + $(COREDIR)/Util/PortManager.cpp \ $(EXTDIR)/disarm.cpp \ $(CORE_DIR)/UI/TextureUtil.cpp \ $(CORE_DIR)/UI/GameInfoCache.cpp From 2ca6a4f0d76974c6e2460da4d927459ac1456435 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 19 Mar 2020 13:46:02 +0700 Subject: [PATCH 342/848] Fixed GvG Next Plus, Phantasy Star Portable 2, and some minor changes --- Core/HLE/proAdhoc.cpp | 22 +- Core/HLE/sceNet.cpp | 21 +- Core/HLE/sceNetAdhoc.cpp | 476 ++++++++++++++++++++++----------------- Core/HLE/sceNetAdhoc.h | 2 +- 4 files changed, 287 insertions(+), 234 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index eab69f3a6d..418612ee56 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -76,7 +76,7 @@ int newChat = 0; bool isLocalServer = false; sockaddr LocalhostIP; sockaddr LocalIP; -int defaultWlanChannel = 1; +int defaultWlanChannel = PSP_SYSTEMPARAM_ADHOC_CHANNEL_1; // Don't put 0(Auto) here, it needed to be a valid/actual channel number bool isLocalMAC(const SceNetEtherAddr * addr) { SceNetEtherAddr saddr; @@ -845,8 +845,8 @@ uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context, const bool ex // Connected to Parent if (findParent(context) != NULL) { - // Add Number of Siblings + 1 Parents - count += countChildren(context, excludeTimedout) + 1; + // Add Number of Siblings + 1 Parent + count += countChildren(context, excludeTimedout) + 1; // Since count is already started from 1, Do we need to +1 here? Ys vs. Sora no Kiseki seems to show wrong number of players without +1 here } } @@ -1186,8 +1186,8 @@ int friendFinder(){ //_acquireNetworkLock(); // Ping Server - now = real_time_now() * 1000000.0; // CoreTiming::GetGlobalTimeUsScaled(); // Use real_time_now()*1000000.0 if the game gets disconnected from AdhocServer too fast when FPS wasn't stable - if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { //100 // We need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet + now = real_time_now() * 1000000.0; // Use real_time_now()*1000000.0 instead of CoreTiming::GetGlobalTimeUsScaled() if the game gets disconnected from AdhocServer too soon when FPS wasn't stable + if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { // We may need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet // original code : ((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT) // Update Ping Time lastping = now; @@ -1230,7 +1230,7 @@ int friendFinder(){ char tmpmac[18]; INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac, tmpmac)); - // from JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?) + // From JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?) /*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { setState(ADHOCCTL_STATE_GAMEMODE); notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0); @@ -1241,7 +1241,7 @@ int friendFinder(){ }*/ // Update User BSSID - //parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address + parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address // Notify Event Handlers //notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); // Change State @@ -1706,7 +1706,7 @@ int getNicknameCount(const char * nickname) int count = 0; // Local Nickname Matches - if (strcmp((char *)parameter.nickname.data, nickname) == 0) count++; + if (strncmp((char *)¶meter.nickname.data, nickname, ADHOCCTL_NICKNAME_LEN) == 0) count++; // Peer Reference SceNetAdhocctlPeerInfo * peer = friends; @@ -1715,7 +1715,7 @@ int getNicknameCount(const char * nickname) for (; peer != NULL; peer = peer->next) { // Match found - if (strcmp((char *)peer->nickname.data, nickname) == 0) count++; + if (strncmp((char *)&peer->nickname.data, nickname, ADHOCCTL_NICKNAME_LEN) == 0) count++; } // Return Result @@ -1802,12 +1802,12 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ } } - // Default/Initial Network + // Default/Initial Network Parameters memset(¶meter, 0, sizeof(parameter)); strncpy((char *)¶meter.nickname.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN); parameter.nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; parameter.channel = g_Config.iWlanAdhocChannel; - // Assign a Valid Channel when connected to AP/AdhocGroup if it's Auto. JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11) + // Assign a Valid Channel when connected to AP/Adhoc if it's Auto. JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11) if (parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) parameter.channel = defaultWlanChannel; // Faked Active channel to default channel getLocalMac(¶meter.bssid.mac_addr); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index e4e3013a2a..208cbfebd3 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -363,7 +363,7 @@ static u32 sceWlanGetSwitchState() { } // Probably a void function, but often returns a useful value. -static int sceNetEtherNtostr(u32 macPtr, u32 bufferPtr) { +static void sceNetEtherNtostr(u32 macPtr, u32 bufferPtr) { DEBUG_LOG(SCENET, "sceNetEtherNtostr(%08x, %08x)", macPtr, bufferPtr); if (Memory::IsValidAddress(bufferPtr) && Memory::IsValidAddress(macPtr)) { @@ -371,11 +371,10 @@ static int sceNetEtherNtostr(u32 macPtr, u32 bufferPtr) { const u8 *mac = Memory::GetPointer(macPtr); // MAC address is always 6 bytes / 48 bits. - return sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", + sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - } else { - // Possibly a void function, seems to return this on bad args. - return 0x09d40000; + + VERBOSE_LOG(SCENET, "sceNetEtherNtostr - [%s]", buffer); } } @@ -390,7 +389,7 @@ static int hex_to_digit(int c) { } // Probably a void function, but sometimes returns a useful-ish value. -static int sceNetEtherStrton(u32 bufferPtr, u32 macPtr) { +static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) { DEBUG_LOG(SCENET, "sceNetEtherStrton(%08x, %08x)", bufferPtr, macPtr); if (Memory::IsValidAddress(bufferPtr) && Memory::IsValidAddress(macPtr)) { @@ -421,11 +420,9 @@ static int sceNetEtherStrton(u32 bufferPtr, u32 macPtr) { } } + VERBOSE_LOG(SCENET, "sceNetEtherStrton - [%s]", mac2str((SceNetEtherAddr*)Memory::GetPointer(macPtr))); // Seems to maybe kinda return the last value. Probably returns void. - return value; - } else { - // Possibly a void function, seems to return this on bad args (or crash.) - return 0; + //return value; } } @@ -684,8 +681,8 @@ static int sceNetSetDropRate(u32 dropRate, u32 dropDuration) const HLEFunction sceNet[] = { {0X39AF39A6, &WrapI_UUUUU, "sceNetInit", 'i', "xxxxx"}, {0X281928A9, &WrapU_V, "sceNetTerm", 'x', "" }, - {0X89360950, &WrapI_UU, "sceNetEtherNtostr", 'i', "xx" }, - {0XD27961C9, &WrapI_UU, "sceNetEtherStrton", 'i', "xx" }, + {0X89360950, &WrapV_UU, "sceNetEtherNtostr", 'v', "xx" }, + {0XD27961C9, &WrapV_UU, "sceNetEtherStrton", 'v', "xx" }, {0X0BF0A3AE, &WrapU_U, "sceNetGetLocalEtherAddr", 'x', "x" }, {0X50647530, &WrapI_I, "sceNetFreeThreadinfo", 'i', "i" }, {0XCC393E48, &WrapI_U, "sceNetGetMallocStat", 'i', "x" }, diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 36cb37766e..7105128bc3 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -45,8 +45,13 @@ #include "Core/HLE/proAdhocServer.h" #include "i18n/i18n.h" -#define PSP_THREAD_ATTR_KERNEL 0x00001000 // Using constants instead of numbers for readability reason, since PSP_THREAD_ATTR_KERNEL/USER is located in sceKernelThread.cpp instead of sceKernelThread.h +// Using constants instead of numbers for readability reason, since PSP_THREAD_ATTR_KERNEL/USER is located in sceKernelThread.cpp instead of sceKernelThread.h +#ifndef PSP_THREAD_ATTR_KERNEL +#define PSP_THREAD_ATTR_KERNEL 0x00001000 +#endif +#ifndef PSP_THREAD_ATTR_USER #define PSP_THREAD_ATTR_USER 0x80000000 +#endif // shared in sceNetAdhoc.h since it need to be used from sceNet.cpp also // TODO: Make accessor functions instead, and throw all this state in a struct. @@ -57,9 +62,10 @@ bool networkInited; static bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; int adhocDefaultTimeout = 2000; //5000 -int adhocEventPollDelayMS = 10; -int adhocMatchingEventDelayMS = 100; -int adhocEventDelayMS = 500; // This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 +int adhocExtraPollDelayMS = 10; //10 +int adhocEventPollDelayMS = 100; //100 +int adhocMatchingEventDelayMS = 30; //30 +int adhocEventDelayMS = 500; //500; This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 SceUID threadAdhocID; @@ -252,7 +258,7 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { networkInited = true; sleep_ms(adhocEventPollDelayMS); - //hleDelayResult(0, "give some time", adhocEventDelayMS * 1000); // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? + //hleDelayResult(0, "give some time", adhocEventPollDelayMS * 1000); // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? } else { WARN_LOG(SCENET, "sceNetAdhocctlInit: Failed to init the network but faking success"); networkInited = false; // TODO: What needs to check this? Pretty much everything? Maybe we should just set netAdhocctlInited to false.. @@ -458,7 +464,7 @@ static int sceNetAdhocctlGetParameter(u32 paramAddr) { * @param dport Target Port * @param data Data Payload * @param len Payload Length - * @param timeout Send Timeout + * @param timeout Send Timeout (microseconds) * @param flag Nonblocking Flag * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT, ADHOC_INVALID_DATALEN, ADHOC_SOCKET_ALERTED, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_WOULD_BLOCK, NET_NO_SPACE, NET_INTERNAL */ @@ -496,10 +502,13 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int if (daddr != NULL) { // Log Destination // Schedule Timeout Removal - if (flag) timeout = 0; + //if (flag) timeout = 0; // Apply Send Timeout Settings to Socket - setsockopt(socket->id, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); + if (timeout > 0) + setSockTimeout(socket->id, SO_SNDTIMEO, timeout); + + int maxlen = getSockMaxSize(socket->id); // Single Target if (!isBroadcastMAC(daddr)) { @@ -513,31 +522,33 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Acquire Network Lock //_acquireNetworkLock(); - // Send Data + // Send Data. UDP are guaranteed to be sent as a whole or nothing(failed if len > SO_MAX_MSG_SIZE), and never be partially sent/recv changeBlockingMode(socket->id, flag); int sent = sendto(socket->id, (const char *)data, len, 0, (sockaddr *)&target, sizeof(target)); int error = errno; if (sent == SOCKET_ERROR) { DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u] (size=%i)", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); } - //changeBlockingMode(socket->id, 0); + changeBlockingMode(socket->id, 0); // Free Network Lock //_freeNetworkLock(); // Sent Data - if (sent == len) { + if (sent >= 0) { DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Sent %u bytes to %s:%u\n", id, getLocalPort(socket->id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); // Success - return 0; + return 0; // sent; // MotorStorm will try to resend if return value is not 0 } // Blocking Situation if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; // Timeout - return ERROR_NET_ADHOC_TIMEOUT; //-1; + /*if (timeout > 0) + return ERROR_NET_ADHOC_TIMEOUT;*/ + return ERROR_NET_ADHOC_INVALID_ADDR; // There is no concept of Timeout when sending UDP due to no ACK, not sure about PDP since some games did use the timeout arg } //VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Unknown Target Peer %s:%u\n", id, getLocalPort(socket->id), mac2str(daddr, tmpmac), ntohs(target.sin_port)); } @@ -564,31 +575,34 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Acquire Peer Lock peerlock.lock(); + // Send Data + changeBlockingMode(socket->id, flag); // Do we need to switched to blocking-mode to make sure the data are fully sent? + // Iterate Peers SceNetAdhocctlPeerInfo * peer = friends; for (; peer != NULL; peer = peer->next) { - // Skip timed out friends - if (peer->last_recv == 0) continue; + // Does Skipping sending to timed out friends could cause desync when players moving group at the time MP game started? + //if (peer->last_recv == 0) continue; // Fill in Target Structure sockaddr_in target; target.sin_family = AF_INET; target.sin_addr.s_addr = peer->ip_addr; target.sin_port = htons(dport + portOffset); - - // Send Data - changeBlockingMode(socket->id, flag); + int sent = sendto(socket->id, (const char *)data, len, 0, (sockaddr *)&target, sizeof(target)); int error = errno; if (sent == SOCKET_ERROR) { DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](BC) [size=%i]", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); } - changeBlockingMode(socket->id, 0); + if (sent >= 0) { DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Sent %u bytes to %s:%u\n", id, getLocalPort(socket->id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); } } + changeBlockingMode(socket->id, 0); + // Free Peer Lock peerlock.unlock(); @@ -596,7 +610,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int //_freeNetworkLock(); // Success, Broadcast never fails! - return 0; + return 0; // len; } } @@ -625,17 +639,16 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int } - /** * Adhoc Emulator PDP Receive Call * @param id Socket File Descriptor * @param saddr OUT: Source MAC Address * @param sport OUT: Source Port - * @param buf OUT: Received Data + * @param buf OUT: Received Data. The caller has to provide enough space (the whole socket buffer size?) to fully read the available packet. * @param len IN: Buffer Size OUT: Received Data Length * @param timeout Receive Timeout * @param flag Nonblocking Flag - * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_NOT_ENOUGH_SPACE, ADHOC_THREAD_ABORTED, NET_INTERNAL + * @return 0 (or Number of bytes received?) on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_NOT_ENOUGH_SPACE, ADHOC_THREAD_ABORTED, NET_INTERNAL */ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void *dataLength, u32 timeout, int flag) { if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket @@ -661,13 +674,13 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * if (saddr != NULL && port != NULL && buf != NULL && len != NULL && *len > 0) { #ifndef PDP_DIRTY_MAGIC // Schedule Timeout Removal - if (flag == 1) timeout = 0; + //if (flag == 1) timeout = 0; #else // Nonblocking Simulator int wouldblock = 0; // Minimum Timeout - uint32_t mintimeout = 250000; + uint32_t mintimeout = minSocketTimeoutUS; // 250000; // Nonblocking Call if (flag == 1) { @@ -682,8 +695,9 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * } #endif - // Apply Receive Timeout Settings to Socket - setsockopt(socket->id, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)); + // Apply Receive Timeout Settings to Socket. Let's not wait forever (0 = indefinitely) + if (timeout > 0) + setSockTimeout(socket->id, SO_RCVTIMEO, timeout); // Sender Address sockaddr_in sin; @@ -699,16 +713,45 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * int received = 0; int error = 0; - // Receive Data + + // Receive Data. PDP always sent in full size or nothing(failed), recvfrom will always receive in full size as requested (blocking) or failed (non-blocking). If available UDP data is larger than buffer, excess data is lost. changeBlockingMode(socket->id, 1); + // Should peek first for the available data size if it's more than len return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE along with required size in len to prevent losing excess data + received = recvfrom(socket->id, (char*)buf, *len, MSG_PEEK, (sockaddr*)&sin, &sinlen); + if (received != SOCKET_ERROR && *len < received) { + changeBlockingMode(socket->id, 0); + WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Peeked %u/%u bytes from %s:%u\n", id, getLocalPort(socket->id), received, *len, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + *len = received; + + // Peer MAC + SceNetEtherAddr mac; + + // Find Peer MAC + if (resolveIP(sin.sin_addr.s_addr, &mac)) { + // Provide Sender Information + *saddr = mac; + *sport = ntohs(sin.sin_port) - portOffset; + + // Update last recv timestamp, may cause disconnection not detected properly tho + /*peerlock.lock(); + auto peer = findFriend(&mac); + if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + peerlock.unlock();*/ + } + + // Free Network Lock + //_freeNetworkLock(); + + return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE; //received; + } received = recvfrom(socket->id, (char*)buf, *len, 0, (sockaddr*)&sin, &sinlen); error = errno; if (flag == 0) { // Simulate blocking behaviour with non-blocking socket uint32_t starttime = (uint32_t)(real_time_now() * 1000.0); - // Wait for Connection - while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && connectInProgress(error)) { + // Wait for Connection. On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound), may need to disable SIO_UDP_CONNRESET + while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && (connectInProgress(error) || error == ECONNRESET)) { received = recvfrom(socket->id, (char*)buf, *len, 0, (sockaddr*)&sin, &sinlen); error = errno; // Wait 1ms @@ -717,12 +760,12 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * } if (received == SOCKET_ERROR) { - VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", id, socket->lport, error, *len); + VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); } changeBlockingMode(socket->id, 0); - // Received Data + // Received Data. UDP can also receives 0 data, while on TCP 0 data = connection gracefully closed, but not sure about PDP tho if (received > 0) { DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, getLocalPort(socket->id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); @@ -736,22 +779,30 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * *sport = ntohs(sin.sin_port) - portOffset; // Save Length - *len = received; + *len = received; // Kurok homebrew seems to use the new value of len than returned value as data length + + // Update last recv timestamp, may cause disconnection not detected properly tho + /*peerlock.lock(); + auto peer = findFriend(&mac); + if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + peerlock.unlock();*/ // Free Network Lock //_freeNetworkLock(); - // Return Success - return 0; + // Return Success. According to pspsdk-1.0+beta2 returned value is Number of bytes received, but JPCSP returning 0? + return 0; //received; // Returning number of bytes received will cause KH BBS unable to see the game event/room } // Unknown Peer, let's not give any data else { - *len = 0; + //*len = 0; // received; // Is this going to be okay since saddr may not be valid? WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %i bytes from Unknown Peer %s:%u", id, getLocalPort(socket->id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); } // Free Network Lock //_freeNetworkLock(); + //free(tmpbuf); + //Receiving data from unknown peer, ignore it ? //return ERROR_NET_ADHOC_WOULD_BLOCK; //ERROR_NET_ADHOC_NO_DATA_AVAILABLE } @@ -764,8 +815,8 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * if (wouldblock) flag = 1; #endif - // Nothing received - if (received == SOCKET_ERROR && error == EAGAIN) { + // Nothing received. On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound), may need to disable SIO_UDP_CONNRESET + if (received == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK || error == ECONNRESET || error == ETIMEDOUT)) { // Blocking Situation if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; @@ -996,6 +1047,12 @@ static int sceNetAdhocctlScan() { if (threadStatus == ADHOCCTL_STATE_DISCONNECTED) { threadStatus = ADHOCCTL_STATE_SCANNING; + // Reset Networks/Group list to prevent other threads from using these soon to be replaced networks + peerlock.lock(); + freeGroupsRecursive(networks); + networks = NULL; + peerlock.unlock(); + // Prepare Scan Request Packet uint8_t opcode = OPCODE_SCAN; @@ -1011,6 +1068,7 @@ static int sceNetAdhocctlScan() { // Does Connected Event's mipscall need be executed after returning from sceNetAdhocctlScan ? notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); + hleCheckCurrentCallbacks(); // Wait for Status to be connected to prevent Ford Street Racing from Failed to find game session // TODO: Do this async while Delaying HLE Result @@ -1022,8 +1080,8 @@ static int sceNetAdhocctlScan() { } } - //sceKernelDelayThread(adhocEventDelayMS * 1000); - hleDelayResult(0, "give time to init/cleanup", adhocEventDelayMS * 1000); + //sceKernelDelayThread(adhocEventPollDelayMS * 1000); + //hleDelayResult(0, "give time to init/cleanup", adhocEventPollDelayMS * 1000); // Return Success return 0; @@ -1224,8 +1282,7 @@ static u32 sceNetAdhocctlDisconnect() { //peerlock.unlock(); // Notify Event Handlers (even if we weren't connected, not doing this will freeze games like God Eater, which expect this behaviour) - notifyAdhocctlHandlers(ADHOCCTL_EVENT_DISCONNECT, 0); - + notifyAdhocctlHandlers(ADHOCCTL_EVENT_DISCONNECT, 0); hleCheckCurrentCallbacks(); // Return Success, some games might ignore returned value and always treat it as success, otherwise repeatedly calling this function @@ -1298,7 +1355,8 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { SceNetAdhocctlNickname * nickname = NULL; if (Memory::IsValidAddress(nameAddr)) nickname = (SceNetAdhocctlNickname *)Memory::GetPointer(nameAddr); // Get Local MAC Address - SceNetEtherAddr localmac; getLocalMac(&localmac); + SceNetEtherAddr localmac; + getLocalMac(&localmac); // Local MAC Matches if (memcmp(&localmac, mac, sizeof(SceNetEtherAddr)) == 0) @@ -1306,6 +1364,8 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { // Write Data *nickname = parameter.nickname; + DEBUG_LOG(SCENET, "sceNetAdhocctlGetNameByAddr - [PlayerName:%s]", nickname); + // Return Success return 0; } @@ -1328,6 +1388,8 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { // Multithreading Unlock peerlock.unlock(); + DEBUG_LOG(SCENET, "sceNetAdhocctlGetNameByAddr - [PeerName:%s]", nickname); + // Return Success return 0; } @@ -1336,6 +1398,7 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { // Multithreading Unlock peerlock.unlock(); + DEBUG_LOG(SCENET, "sceNetAdhocctlGetNameByAddr - PlayerName not found"); // Player not found return ERROR_NET_ADHOC_NO_ENTRY; } @@ -1364,6 +1427,7 @@ static int sceNetAdhocctlJoin(u32 scanInfoAddr) { //while (true) sleep_ms(1); // We can ignore minor connection process differences here + // TODO: Adhoc Server may need to be changed to differentiate between Host/Create and Join, otherwise it can't support multiple Host using the same Group name, thus causing one of the Host to be confused being treated as Join. return sceNetAdhocctlCreate((const char*)&sinfo->group_name); } @@ -1399,7 +1463,8 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { SceNetAdhocctlNickname nickname; getLocalIp(&addr); - strcpy((char*)nickname.data, g_Config.sNickName.c_str()); + strncpy((char*)&nickname.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN); + nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // making sure to be null-terminated since strncpy doesn't implicitly append null //buf->next = 0; buf->nickname = nickname; buf->nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char @@ -1799,15 +1864,15 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { */ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, int dport, int bufsize, int rexmt_int, int rexmt_cnt, int unknown) { char tmpmac[18]; - INFO_LOG(SCENET, "sceNetAdhocPtpOpen(%s, %d, %s, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac, tmpmac), sport, mac2str((SceNetEtherAddr*)dstmac, tmpmac),dport,bufsize, rexmt_int, rexmt_cnt, unknown, currentMIPS->pc); + INFO_LOG(SCENET, "sceNetAdhocPtpOpen(%s, %d, %s, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac), sport, mac2str((SceNetEtherAddr*)dstmac, tmpmac),dport,bufsize, rexmt_int, rexmt_cnt, unknown, currentMIPS->pc); if (!g_Config.bEnableWlan) { return 0; } - SceNetEtherAddr * saddr = (SceNetEtherAddr *)srcmac; - SceNetEtherAddr * daddr = (SceNetEtherAddr *)dstmac; + SceNetEtherAddr* saddr = (SceNetEtherAddr*)srcmac; + SceNetEtherAddr* daddr = (SceNetEtherAddr*)dstmac; // Library is initialized if (netAdhocInited) { - // Some games (ie. DBZ Shin Budokai 2) might be getting the saddr/srcmac content from SaveState and causing problems :( So we try to fix it here + // Some games (ie. DBZ Shin Budokai 2) might be getting the saddr/srcmac content from SaveState and causing problems if current MAC is different :( So we try to fix it here if (saddr != NULL) { getLocalMac(saddr); } @@ -1838,10 +1903,16 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); // Enable KeepAlive - setSockKeepAlive(tcpsocket, true); + setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); // Enable Port Re-use setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + + // Apply Default Send Timeout Settings to Socket + setSockTimeout(tcpsocket, SO_SNDTIMEO, rexmt_int); + + // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? + //setSockNoDelay(tcpsocket, 1); // Binding Information for local Port sockaddr_in addr; @@ -1890,9 +1961,9 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Link PTP Socket ptp[i] = internal; - // Add Port Forward to Router + // Add Port Forward to Router. We may not even need to forward this local port, since PtpOpen usually have port 0 (any port) as source port and followed by PtpConnect (which mean acting as Client), right? //sceNetPortOpen("TCP", sport); - g_PortManager.Add(sport + portOffset, IP_PROTOCOL_TCP); + //g_PortManager.Add(sport + portOffset, IP_PROTOCOL_TCP); // Return PTP Socket Pointer return i + 1; @@ -1910,6 +1981,9 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Close Socket closesocket(tcpsocket); + + // Port not available (exclusively in use?) + return ERROR_NET_ADHOC_PORT_IN_USE; // ERROR_NET_ADHOC_PORT_NOT_AVAIL; } } @@ -1918,17 +1992,16 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, } // Invalid Ports - return ERROR_NET_ADHOC_INVALID_PORT; + return ERROR_NET_ADHOC_PORT_IN_USE; // ERROR_NET_ADHOC_INVALID_PORT; } // Invalid Addresses - return ERROR_NET_ADHOC_INVALID_ADDR; + return ERROR_NET_ADHOC_INVALID_ARG; // ERROR_NET_ADHOC_INVALID_ADDR; } return 0; } - /** * Adhoc Emulator PTP Connection Acceptor * @param id Socket File Descriptor @@ -1983,7 +2056,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Switch to Nonblocking Behaviour if (nbio == 0) { // Overwrite Socket Option - changeBlockingMode(socket->id,1); + changeBlockingMode(socket->id, 1); } // TODO: Use a different thread (similar to sceIo) for recvfrom, recv & accept to prevent blocking-socket from blocking emulation @@ -2019,15 +2092,16 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Restore Blocking Behaviour if (nbio == 0) { // Restore Socket Option - changeBlockingMode(socket->id,0); + changeBlockingMode(socket->id, 0); } // Accepted New Connection if (newsocket > 0) { - // Do we need to Change socket buffer size to match the listener buffer size? - // Enable Port Re-use setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + + // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? + //setSockNoDelay(newsocket, 1); // Grab Local Address if (getsockname(newsocket, (sockaddr *)&local, &locallen) == 0) { @@ -2077,9 +2151,9 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Link PTP Socket ptp[i] = internal; - // Add Port Forward to Router + // Add Port Forward to Router. Or may be doesn't need to be forwarded since local port already accessible from outside if others were able to connect & get accepted at this point, right? //sceNetPortOpen("TCP", internal->lport); - g_PortManager.Add(internal->lport + portOffset, IP_PROTOCOL_TCP); + //g_PortManager.Add(internal->lport + portOffset, IP_PROTOCOL_TCP); INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", id, i+1, internal->lport, inet_ntoa(peeraddr.sin_addr), internal->pport); @@ -2122,7 +2196,6 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int return ERROR_NET_ADHOC_NOT_INITIALIZED; } - /** * Adhoc Emulator PTP Connection Opener * @param id Socket File Descriptor @@ -2131,7 +2204,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int * @return 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_CONNECTION_REFUSED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_NOT_OPENED, ADHOC_THREAD_ABORTED, NET_INTERNAL */ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { - INFO_LOG(SCENET, "sceNetAdhocPtpConnect(%i, %i, %08x) at %08x", id, timeout, flag, currentMIPS->pc); + INFO_LOG(SCENET, "sceNetAdhocPtpConnect(%i, %i, %i) at %08x", id, timeout, flag, currentMIPS->pc); if (!g_Config.bEnableWlan) { return 0; } @@ -2143,7 +2216,11 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { // Cast Socket SceNetAdhocPtpStat * socket = ptp[id - 1]; - + + // Phantasy Star Portable 2 will try to reconnect even when previous connect already success, so we should return success too if it's already connected + if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) + return 0; + // Valid Client Socket if (socket->state == ADHOC_PTP_STATE_CLOSED) { // Target Address @@ -2159,13 +2236,16 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { if (resolveMAC(&socket->paddr, (uint32_t *)&sin.sin_addr.s_addr)) { // Grab Nonblocking Flag uint32_t nbio = getBlockingFlag(socket->id); - // Switch to Nonblocking Behaviour - if (nbio == 0) { + + // Switch to Nonblocking Behaviour. Forcing blocking behaviour on the first connect may fix connection issue on GvG Next Plus, But i don't like using blocking socket with infinite timeout if the game it self were asking for non-blocking behaviour :( + /*if (nbio == 0) + { // Overwrite Socket Option changeBlockingMode(socket->id, 1); - } + }*/ // Connect Socket to Peer (Nonblocking) + // Fixme: The First Non-blocking POSIX connect will always returns EAGAIN/EWOULDBLOCK because it returns without waiting for ACK, But GvG Next Plus is treating non-blocking connect just like blocking connect, May be on a real PSP the first non-blocking sceNetAdhocPtpConnect can be successfull? int connectresult = connect(socket->id, (sockaddr *)&sin, sizeof(sin)); // Grab Error Code @@ -2176,13 +2256,14 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { } // Restore Blocking Behaviour - if (nbio == 0) { + if (nbio == 0) + { // Restore Socket Option - changeBlockingMode(socket->id,0); + changeBlockingMode(socket->id, 0); } // Instant Connection (Lucky!) - if (connectresult == 0 || (connectresult == SOCKET_ERROR && (errorcode == EISCONN /*|| errorcode == EALREADY)*/))) { + if (connectresult == 0 || (connectresult == SOCKET_ERROR && (errorcode == EISCONN))) { // Set Connected State socket->state = ADHOC_PTP_STATE_ESTABLISHED; @@ -2225,13 +2306,15 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { } // Timeout occured - return ERROR_NET_ADHOC_TIMEOUT; + return ERROR_NET_ADHOC_CONNECTION_REFUSED; // ERROR_NET_ADHOC_TIMEOUT; } } } // Peer not found - return ERROR_NET_ADHOC_CONNECTION_REFUSED; + if (flag) + return ERROR_NET_ADHOC_WOULD_BLOCK; + return ERROR_NET_ADHOC_CONNECTION_REFUSED; // ERROR_NET_ADHOC_TIMEOUT; } // Not a valid Client Socket @@ -2246,7 +2329,6 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { return ERROR_NET_ADHOC_NOT_INITIALIZED; } - /** * Adhoc Emulator PTP Socket Closer * @param id Socket File Descriptor @@ -2344,10 +2426,16 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); // Enable KeepAlive - setSockKeepAlive(tcpsocket, true); + setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); // Enable Port Re-use setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + + // Apply Default Receive Timeout Settings to Socket + setSockTimeout(tcpsocket, SO_RCVTIMEO, rexmt_int); + + // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? + //setSockNoDelay(tcpsocket, 1); // Binding Information for local Port sockaddr_in addr; @@ -2425,7 +2513,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int closesocket(tcpsocket); // Port not available (exclusively in use?) - return ERROR_NET_ADHOC_PORT_NOT_AVAIL; + return ERROR_NET_ADHOC_PORT_IN_USE; // ERROR_NET_ADHOC_PORT_NOT_AVAIL; } // Socket not available @@ -2476,16 +2564,17 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Valid Arguments if (data != NULL && len != NULL && *len > 0) { // Schedule Timeout Removal - if (flag) timeout = 0; + //if (flag) timeout = 0; // JPCSP seems to always Send PTP as blocking, also a possibility to send to multiple destination? // Apply Send Timeout Settings to Socket - setsockopt(socket->id, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); + if (timeout > 0) + setSockTimeout(socket->id, SO_SNDTIMEO, timeout); // Acquire Network Lock // _acquireNetworkLock(); // Send Data - changeBlockingMode(socket->id, flag); + //changeBlockingMode(socket->id, flag); int sent = send(socket->id, data, *len, 0); int error = errno; changeBlockingMode(socket->id, 0); @@ -2506,7 +2595,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou } // Non-Critical Error - else if (sent == SOCKET_ERROR && error == EAGAIN) { + else if (sent == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT)) { // Blocking Situation if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; @@ -2537,7 +2626,6 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou return ERROR_NET_ADHOC_NOT_INITIALIZED; } - /** * Adhoc Emulator PTP Receiver * @param id Socket File Descriptor @@ -2564,10 +2652,11 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Valid Arguments if (buf != NULL && len != NULL && *len > 0) { // Schedule Timeout Removal - if (flag) timeout = 0; + //if (flag) timeout = 0; - // Apply Send Timeout Settings to Socket - setsockopt(socket->id, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); + // Apply Receive Timeout Settings to Socket. Let's not wait forever (0 = indefinitely) + if (timeout > 0) + setSockTimeout(socket->id, SO_RCVTIMEO, timeout); // Acquire Network Lock // _acquireNetworkLock(); @@ -2594,7 +2683,7 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou } if (received == SOCKET_ERROR) { - VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPtpRecv[%i:%u] [size=%i]", id, socket->lport, error, *len); + VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPtpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); } changeBlockingMode(socket->id, 0); @@ -2606,6 +2695,12 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Save Length *len = received; + // Update last recv timestamp, may cause disconnection not detected properly tho + /*peerlock.lock(); + auto peer = findFriend(&socket->paddr); + if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + peerlock.unlock();*/ + char tmpmac[18]; DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u", id, socket->lport, received, mac2str(&socket->paddr, tmpmac), socket->pport); @@ -2614,7 +2709,7 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou } // Non-Critical Error - else if (received == SOCKET_ERROR /*&& error == EAGAIN*/) { + else if (received == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT)) { // Blocking Situation if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; @@ -2663,14 +2758,15 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { // Connected Socket if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) { + // There are two ways to flush, you can either set TCP_NODELAY to 1 or TCP_CORK to 0. + // Apply Send Timeout Settings to Socket + setSockTimeout(socket->id, SO_SNDTIMEO, timeout); + // Get original Nagle algo value - int n = 0; - socklen_t m = sizeof(n); - getsockopt(socket->id, IPPROTO_TCP, TCP_NODELAY, (char*)&n, &m); + int n = getSockNoDelay(socket->id); // Disable Nagle Algo to send immediately - int flag = 1; - setsockopt(socket->id, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)); + setSockNoDelay(socket->id, 1); // Send Empty Data just to trigger Nagle on/off effect to flush the send buffer, Do we need to trigger this at all or is it automatically flushed? changeBlockingMode(socket->id, nonblock); @@ -2678,12 +2774,11 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { int error = errno; changeBlockingMode(socket->id, 0); - // Enable Nagle Algo - flag = n; //0; - setsockopt(socket->id, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)); + // Restore/Enable Nagle Algo + setSockNoDelay(socket->id, n); } - // Dummy Result + // Dummy Result, Always success return 0; } @@ -2847,6 +2942,9 @@ int sceNetAdhocMatchingDelete(int matchingId) { peerlock.unlock(); //contextlock.unlock(); WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingDelete(%i) at %08x", matchingId, currentMIPS->pc); + + // Give a little time to make sure everything are cleaned up before the following AdhocMatchingCreate, Not too long tho, otherwise Naruto Ultimate Ninja Heroes 3 will have an issue + //hleDelayResult(0, "give time to init/cleanup", adhocExtraPollDelayMS * 1000); return 0; } @@ -2854,7 +2952,8 @@ int sceNetAdhocMatchingInit(u32 memsize) { WARN_LOG(SCENET, "sceNetAdhocMatchingInit(%d) at %08x", memsize, currentMIPS->pc); // Uninitialized Library - if (netAdhocMatchingInited) return ERROR_NET_ADHOC_MATCHING_ALREADY_INITIALIZED; + if (netAdhocMatchingInited) + return ERROR_NET_ADHOC_MATCHING_ALREADY_INITIALIZED; // Save Fake Pool Size fakePoolSize = memsize; @@ -2906,13 +3005,13 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle // Valid Arguments if (mode >= 1 && mode <= 3) { // Wait until Adhoc is fully connected (mipscall of ADHOCCTL_EVENT_CONNECT event is fully executed ?) - if (friendFinderRunning) { + /*if (friendFinderRunning) { int cnt = 0; while ((threadStatus != ADHOCCTL_STATE_CONNECTED) && (cnt < adhocDefaultTimeout)) { sleep_ms(1); cnt++; } - } + }*/ // Iterate Matching Contexts SceNetAdhocMatchingContext * item = contexts; @@ -2981,6 +3080,9 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle // Multithreading UnLock peerlock.unlock(); //contextlock.unlock(); + // Just to make sure Adhoc is already connected + //hleDelayResult(context->id, "give time to init/cleanup", adhocEventDelayMS * 1000); + // Return Matching ID return context->id; } @@ -3056,7 +3158,7 @@ static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, // Create & Start the Fake PSP Thread std::string thrname = std::string("MatchingThr") + std::to_string(matchingId); - item->matching_thid = __KernelCreateThread(thrname.c_str(), __KernelGetCurThreadModuleId(), matchingThreadHackAddr, evthPri, evthStack, PSP_THREAD_ATTR_USER, 0, true); + item->matching_thid = __KernelCreateThread(thrname.c_str(), __KernelGetCurThreadModuleId(), matchingThreadHackAddr, evthPri, evthStack, PSP_THREAD_ATTR_USER, 0, false); //item->matchingThread = new HLEHelperThread(thrname, "sceNetAdhocMatching", "AdhocMatchingFunc", inthPri, inthStack); if (item->matching_thid > 0) { __KernelStartThread(item->matching_thid, 0, 0); @@ -3081,7 +3183,7 @@ static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, // Multithreading Unlock peerlock.unlock(); - sleep_ms(adhocEventPollDelayMS); + sleep_ms(adhocMatchingEventDelayMS); //hleDelayResult(0, "give some time", adhocMatchingEventDelayMS * 1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? return 0; @@ -3128,7 +3230,7 @@ static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartit // Create & Start the Fake PSP Thread std::string thrname = std::string("MatchingThr") + std::to_string(matchingId); - item->matching_thid = __KernelCreateThread(thrname.c_str(), __KernelGetCurThreadModuleId(), matchingThreadHackAddr, evthPri, evthStack, PSP_THREAD_ATTR_USER, 0, true); + item->matching_thid = __KernelCreateThread(thrname.c_str(), __KernelGetCurThreadModuleId(), matchingThreadHackAddr, evthPri, evthStack, PSP_THREAD_ATTR_USER, 0, false); //item->matchingThread = new HLEHelperThread(thrname, "sceNetAdhocMatching", "AdhocMatchingFunc", inthPri, inthStack); if (item->matching_thid > 0) { __KernelStartThread(item->matching_thid, 0, 0); @@ -3153,8 +3255,8 @@ static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartit // Multithreading Unlock peerlock.unlock(); - sleep_ms(adhocEventPollDelayMS); - //hleDelayResult(0,"give some time",adhocEventDelayMS*1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? + sleep_ms(adhocMatchingEventDelayMS); + //hleDelayResult(0,"give some time",adhocMatchingEventDelayMS*1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? return 0; } @@ -3438,7 +3540,8 @@ int sceNetAdhocMatchingSetHelloOpt(int matchingId, int optLenAddr, u32 optDataAd if (!g_Config.bEnableWlan) return -1; - if (!netAdhocMatchingInited) return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; + if (!netAdhocMatchingInited) + return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; // Multithreading Lock peerlock.lock(); @@ -3522,10 +3625,15 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) if (!g_Config.bEnableWlan) return -1; - if (!netAdhocMatchingInited) return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; + // Ys vs. Sora no Kiseki seems to be using this function long after AdhocMatching is Terminated + if (!netAdhocMatchingInited) { + //WARN_LOG(SCENET, "sceNetAdhocMatchingGetMembers - AdhocMatching is Not Initialized"); + return 0; // ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; + } // Minimum Argument - if (!Memory::IsValidAddress(sizeAddr)) return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; + if (!Memory::IsValidAddress(sizeAddr)) + return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; // Multithreading Lock peerlock.lock(); @@ -3550,7 +3658,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) } // Number of Connected Peers, should we exclude timeout members? - bool excludeTimedout = false; + bool excludeTimedout = false; // false; uint32_t peercount = countConnectedPeers(context, excludeTimedout); // Calculate Connected Peer Bytesize @@ -3588,6 +3696,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Add Local MAC buf2[filledpeers++].mac_addr = context->mac; + DEBUG_LOG(SCENET, "MemberSelf [%s]", mac2str(&context->mac)); + // Room for more than local peer if (requestedpeers > 1) { @@ -3600,8 +3710,14 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // P2P Brother found if (p2p != NULL) { + // Faking lastping + if (p2p->lastping != 0) + p2p->lastping = CoreTiming::GetGlobalTimeUsScaled(); + // Add P2P Brother MAC buf2[filledpeers++].mac_addr = p2p->mac; + + DEBUG_LOG(SCENET, "MemberP2P [%s]", mac2str(&p2p->mac)); } } @@ -3614,12 +3730,18 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) { // Should we exclude timedout members? if (!excludeTimedout || peer->lastping != 0) { + // Faking lastping + if (peer->lastping != 0) + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + // Parent Mode if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { // Interested in Children (Michael Jackson Style) if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) { // Add Child MAC buf2[filledpeers++].mac_addr = peer->mac; + + DEBUG_LOG(SCENET, "MemberParent [%s]", mac2str(&peer->mac)); } } @@ -3630,6 +3752,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) { // Add Peer MAC buf2[filledpeers++].mac_addr = peer->mac; + + DEBUG_LOG(SCENET, "MemberChild [%s]", mac2str(&peer->mac)); } } } @@ -3852,27 +3976,7 @@ int sceNetAdhocMatchingGetPoolStat(u32 poolstatPtr) { void __NetTriggerCallbacks() { std::lock_guard adhocGuard(adhocEvtMtx); - int delayus = 1000; //adhocEventPollDelayMS * 1000; - - /*if (__KernelGetCurThread() == threadAdhocID && (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && IsAdhocctlInCallback() == 0) { - for (auto& params : adhocctlEvents) //(auto params = adhocctlEvents.rbegin(); params != adhocctlEvents.rend(); ++params) - { - int flags = params.first; //params->first; - int error = params.second; - u32_le args[3] = { 0, 0, 0 }; - args[0] = flags; - args[1] = error; - - for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { - args[2] = it->second.argument; - AfterAdhocMipsCall* after = (AfterAdhocMipsCall*)__KernelCreateAction(actionAfterAdhocMipsCall); - after->SetData(it->first, flags, args[2]); - SetAdhocctlInCallback(true); //IsAdhocctlInCB++; // - __KernelDirectMipsCall(it->second.entryPoint, after, args, 3, false); - } - } - adhocctlEvents.clear(); - }*/ + int delayus = 1000; auto params = adhocctlEvents.begin(); if (params != adhocctlEvents.end()) @@ -3883,71 +3987,53 @@ void __NetTriggerCallbacks() args[0] = flags; args[1] = error; - if (__KernelGetCurThread() == threadAdhocID && (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && IsAdhocctlInCallback() == 0) { // IsAdhocctlInCB + //if (/*__KernelGetCurThread() == threadAdhocID &&*/ (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && IsAdhocctlInCallback() == 0) + { for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { - DEBUG_LOG(SCENET, "AdhocctlCallback: EVENT[%i] [ID=%i]", flags, it->first); + DEBUG_LOG(SCENET, "AdhocctlCallback: [ID=%i][EVENT=%i]", it->first, flags); args[2] = it->second.argument; AfterAdhocMipsCall* after = (AfterAdhocMipsCall*)__KernelCreateAction(actionAfterAdhocMipsCall); after->SetData(it->first, flags, args[2]); - SetAdhocctlInCallback(true); //IsAdhocctlInCB++; // + SetAdhocctlInCallback(true); __KernelDirectMipsCall(it->second.entryPoint, after, args, 3, true); } adhocctlEvents.pop_front(); - delayus = (adhocEventDelayMS + 4*adhocEventPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection + if (flags == ADHOCCTL_EVENT_CONNECT) + delayus = (adhocEventDelayMS + 2*adhocExtraPollDelayMS) * 1000; + else + delayus = (adhocEventPollDelayMS + 2*adhocExtraPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection } } // Must be delayed long enough whenever there is a pending callback. Should it be 100-500ms for Adhocctl Events? or Not Less than the delays on sceNetAdhocctl HLE? - sceKernelDelayThreadCB(delayus); - //sceKernelDelayThreadCB(adhocEventDelayMS * 1000); - //hleCheckCurrentCallbacks(); - //hleDelayResult(0, "Prevent Adhoc thread from blocking", delayus); - //hleDelayResult(0, "Prevent Adhoc thread from blocking", adhocEventDelayMS * 1000); + hleDelayResult(0, "Prevent Adhocctl thread from blocking", delayus); } void __NetMatchingCallbacks() { std::lock_guard adhocGuard(adhocEvtMtx); - int delayus = 1000; // adhocEventPollDelayMS * 1000; //adhocMatchingEventPollDelayMS * 1000; + int delayus = 1000; - /*if (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) { - for (auto& params : matchingEvents) //(auto ¶ms = matchingEvents.rbegin(); params != matchingEvents.rend(); ++params) - { - u32_le* args = (u32_le*)¶ms; //(u32_le*)& (*params); - auto context = findMatchingContext(args[0]); - //if (__KernelGetCurThread() == context->matching_thid && !IsMatchingInCallback(context)) - { - AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); - after->SetData(args[0], args[1], args[2]); - __KernelDirectMipsCall(args[5], after, args, 5, false); - } - } - matchingEvents.clear(); - }*/ - auto params = matchingEvents.begin(); if (params != matchingEvents.end()) { u32_le* args = (u32_le*)&(*params); - auto context = findMatchingContext(args[0]); + //auto context = findMatchingContext(args[0]); - if (__KernelGetCurThread() == context->matching_thid && (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && !IsMatchingInCallback(context)) { - DEBUG_LOG(SCENET, "AdhocMatchingCallback: EVENT[%i] [ID=%i]", args[1], args[0]); + //if (/*__KernelGetCurThread() == context->matching_thid &&*/ (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) /*&& !IsMatchingInCallback(context)*/) + { + DEBUG_LOG(SCENET, "AdhocMatchingCallback: [ID=%i][EVENT=%i]", args[0], args[1]); AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); after->SetData(args[0], args[1], args[2]); - SetMatchingInCallback(context, true); + //SetMatchingInCallback(context, true); __KernelDirectMipsCall(args[5], after, args, 5, true); matchingEvents.pop_front(); - delayus = (adhocMatchingEventDelayMS + 4*adhocEventPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection + delayus = (adhocMatchingEventDelayMS + 2*adhocExtraPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection } } // Must be delayed long enough whenever there is a pending callback. Should it be 10-100ms for Matching Events? or Not Less than the delays on sceNetAdhocMatching HLE? - sceKernelDelayThreadCB(delayus); - //sceKernelDelayThreadCB(adhocMatchingEventDelayMS * 1000); - //hleCheckCurrentCallbacks(); - //hleDelayResult(0, "Prevent AdhocMatching thread from blocking", delayus); - //hleDelayResult(0, "Prevent Adhoc thread from blocking", adhocEventPollDelayMS * 1000); + hleDelayResult(0, "Prevent AdhocMatching thread from blocking", delayus); } const HLEFunction sceNetAdhoc[] = { @@ -4036,9 +4122,10 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { // Multithreading Lock peerlock.lock(); + bool excludeTimedout = false; //true; // Length Calculation Mode if (buf == NULL) { - int activePeers = getActivePeerCount(); + int activePeers = getActivePeerCount(excludeTimedout); *buflen = activePeers * sizeof(SceNetAdhocctlPeerInfoEmu); DEBUG_LOG(SCENET, "PeerList [Active: %i]", activePeers); } @@ -4060,11 +4147,11 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { // Iterate Peers for (; peer != NULL && discovered < requestcount; peer = peer->next) { - // Exclude Soon to be timedout peers - if (peer->last_recv != 0) { - // Fake Receive Time - //if (peer->last_recv != 0) - peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + // Exclude Soon to be timedout peers? + if (!excludeTimedout || peer->last_recv != 0) { + // Faking Last Receive Time + if (peer->last_recv != 0) + peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); // Copy Peer Info buf[discovered].nickname = peer->nickname; @@ -4072,6 +4159,9 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { buf[discovered].ip_addr = peer->ip_addr; buf[discovered].last_recv = peer->last_recv; discovered++; + + u32_le ipaddr = peer->ip_addr; + DEBUG_LOG(SCENET, "Peer [%s][%s][%s][%d]", mac2str(&peer->mac_addr), inet_ntoa(*(in_addr*)&ipaddr), (const char*)&peer->nickname.data, peer->last_recv); } } @@ -4145,7 +4235,7 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b if (requestcount > 0) { // Local Nickname Matches - if (strcmp((char *)parameter.nickname.data, nickName) == 0) + if (strncmp((char *)¶meter.nickname.data, nickName, ADHOCCTL_NICKNAME_LEN) == 0) { // Get Local IP Address sockaddr_in addr; @@ -4167,7 +4257,7 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b for (; peer != NULL && discovered < requestcount; peer = peer->next) { // Match found - if (strcmp((char *)peer->nickname.data, nickName) == 0) + if (strncmp((char *)&peer->nickname.data, nickName, ADHOCCTL_NICKNAME_LEN) == 0) { // Fake Receive Time if (peer->last_recv != 0) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); //sceKernelGetSystemTimeWide(); @@ -5259,10 +5349,9 @@ int matchingEventThread(int matchingId) if (context != NULL) { u32 bufLen = context->rxbuflen; //0; u32 bufAddr = 0; //= userMemory.Alloc(bufLen); //context->rxbuf; - //static u32_le args[5] = { 0, 0, 0, 0, 0 }; // Need to be global/static so it can be accessed from a different thread u32_le * args = context->handlerArgs; //MatchingArgs - while (contexts != NULL && context->eventRunning) // (context->eventThread.get_id() != NULL) + while (contexts != NULL && context->eventRunning) { // Multithreading Lock peerlock.lock(); @@ -5279,31 +5368,6 @@ int matchingEventThread(int matchingId) // Iterate Message List ThreadMessage * msg = context->event_stack; - /*for (; msg != NULL; msg = msg->next) - { - // Default Optional Data - void* opt = NULL; - - // Grab Optional Data - if (msg->optlen > 0) opt = ((u8*)msg) + sizeof(ThreadMessage); //&msg[1] - - // Log Matching Events - INFO_LOG(SCENET, "EventLoop[%d]: Matching Event [%d=%s] OptSize=%d", matchingId, msg->opcode, getMatchingEventStr(msg->opcode), msg->optlen); - - context->eventlock->unlock(); // Unlock to prevent race-condition with other threads due to recursive lock - // Call Event Handler - //context->handler(context->id, msg->opcode, &msg->mac, msg->optlen, opt); - // Notify Event Handlers - notifyMatchingHandler(context, msg, opt, bufAddr, bufLen, args); - context->eventlock->lock(); // Lock again - - // Give some time before executing the next mipscall to prevent event ACCEPT(6)->ESTABLISH(7) getting reversed After Action ESTABLISH(7)->ACCEPT(6) - sleep_ms(adhocEventPollDelayMS); // If we're using shared Buffer & Args for all Events We should wait for the Mipscall to be fully executed before processing the next event - } - - // Clear Event Message Stack - clearStack(context, PSP_ADHOC_MATCHING_EVENT_STACK); - */ if (msg != NULL) { // Default Optional Data @@ -5323,13 +5387,8 @@ int matchingEventThread(int matchingId) notifyMatchingHandler(context, msg, opt, bufAddr, bufLen, args); // If we're using shared Buffer & Args for All Events We should wait for the Mipscall to be fully executed before processing the next event. GTA VCS need this delay/sleep. // Give some time before executing the next mipscall to prevent event ACCEPT(6)->ESTABLISH(7) getting reversed After Action ESTABLISH(7)->ACCEPT(6) - //do { - // //sceKernelDelayThread(adhocEventPollDelayMS * 1000); //adhocMatchingEventDelayMS * 1000 - // sleep_ms(1); - //} while (IsMatchingInCallback(context)); - // Must Not be delayed too long to prevent desync/disconnect. Not longer than the delays on callback's HLE? - //sleep_ms(adhocEventPollDelayMS); //adhocMatchingEventDelayMS //adhocEventPollDelayMS //sceKernelDelayThread(10000); + //sleep_ms(10); //sceKernelDelayThread(10000); // Lock again context->eventlock->lock(); @@ -5340,15 +5399,12 @@ int matchingEventThread(int matchingId) msg = NULL; } - // Clear Event Message Stack - //clearStack(context, PSP_ADHOC_MATCHING_EVENT_STACK); - - // Free Stack + // Unlock Stack context->eventlock->unlock(); } // Share CPU Time - sleep_ms(1); + sleep_ms(1); //10 //sceKernelDelayThread(10000); // Don't do anything if it's paused, otherwise the log will be flooded while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->eventRunning) sleep_ms(1); @@ -5397,7 +5453,7 @@ int matchingEventThread(int matchingId) // Log Shutdown INFO_LOG(SCENET, "EventLoop: End of EventLoop[%i] Thread", matchingId); - // Return Zero to shut up Compiler (never reached anyway) + // Return Zero to shut up Compiler return 0; } @@ -5538,7 +5594,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi u64_le delta = now - peer->last_recv; char tmpmac[18]; DEBUG_LOG(SCENET, "Timestamp Delta: %llu (%llu - %llu) from %s", delta, now, peer->last_recv, mac2str(&sendermac, tmpmac)); - if (/*context->rxbuf[0] > 0 &&*/ peer->last_recv != 0) peer->last_recv = now; // - context->keepalive_int; // May need to deduce by ping interval to prevent Dissidia 012 unable to see other players (ie. disappearing issue) + if (/*context->rxbuf[0] > 0 &&*/ peer->last_recv != 0) peer->last_recv = now - 1; // - context->keepalive_int; // May need to deduce by ping interval to prevent Dissidia 012 unable to see other players (ie. disappearing issue) } peerlock.unlock(); @@ -5603,6 +5659,6 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi // Terminate Thread //sceKernelExitDeleteThread(0); - // Return Zero to shut up Compiler (never reached anyway) + // Return Zero to shut up Compiler return 0; } diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 83f1f5d5a0..e2e9a434a2 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -49,7 +49,7 @@ extern bool netAdhocctlInited; extern int adhocDefaultTimeout; extern int adhocEventPollDelayMS; extern int adhocMatchingEventDelayMS; -extern int adhocEventDelayMS; +extern int adhocEventDelayMS; // This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 extern std::recursive_mutex adhocEvtMtx; extern int IsAdhocctlInCB; From 3e2266e1c46d73513724d9cc889396882b0ef6da Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 12 Jul 2020 08:03:25 +0700 Subject: [PATCH 343/848] Making sure there are no warnings on adhoc code when building on android studio --- Core/HLE/sceNetAdhoc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7105128bc3..301c41d5c1 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1364,7 +1364,7 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { // Write Data *nickname = parameter.nickname; - DEBUG_LOG(SCENET, "sceNetAdhocctlGetNameByAddr - [PlayerName:%s]", nickname); + DEBUG_LOG(SCENET, "sceNetAdhocctlGetNameByAddr - [PlayerName:%s]", (char*)nickname); // Return Success return 0; @@ -1388,7 +1388,7 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { // Multithreading Unlock peerlock.unlock(); - DEBUG_LOG(SCENET, "sceNetAdhocctlGetNameByAddr - [PeerName:%s]", nickname); + DEBUG_LOG(SCENET, "sceNetAdhocctlGetNameByAddr - [PeerName:%s]", (char*)nickname); // Return Success return 0; @@ -4161,7 +4161,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { discovered++; u32_le ipaddr = peer->ip_addr; - DEBUG_LOG(SCENET, "Peer [%s][%s][%s][%d]", mac2str(&peer->mac_addr), inet_ntoa(*(in_addr*)&ipaddr), (const char*)&peer->nickname.data, peer->last_recv); + DEBUG_LOG(SCENET, "Peer [%s][%s][%s][%llu]", mac2str(&peer->mac_addr), inet_ntoa(*(in_addr*)&ipaddr), (const char*)&peer->nickname.data, peer->last_recv); } } From c5d912baa298ea1a1099df7c2e8adb4b062a7089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Jul 2020 22:49:03 +0200 Subject: [PATCH 344/848] Further libretro buildfix --- libretro/Makefile.common | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index dcfba1d130..624d3f837c 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -605,6 +605,22 @@ SOURCES_C += $(EXTDIR)/udis86/decode.c \ $(EXTDIR)/udis86/syn.c \ $(EXTDIR)/udis86/udis86.c +INCFLAGS += -I$(EXTDIR)/miniupnp-build +SOURCES_C += \ + $(EXTDIR)/miniupnp/miniupnpc/connecthostport.c \ + $(EXTDIR)/miniupnp/miniupnpc/igd_desc_parse.c \ + $(EXTDIR)/miniupnp/miniupnpc/minisoap.c \ + $(EXTDIR)/miniupnp/miniupnpc/minissdpc.c \ + $(EXTDIR)/miniupnp/miniupnpc/miniupnpc.c \ + $(EXTDIR)/miniupnp/miniupnpc/miniwget.c \ + $(EXTDIR)/miniupnp/miniupnpc/minixml.c \ + $(EXTDIR)/miniupnp/miniupnpc/minixmlvalid.c \ + $(EXTDIR)/miniupnp/miniupnpc/portlistingparse.c \ + $(EXTDIR)/miniupnp/miniupnpc/receivedata.c \ + $(EXTDIR)/miniupnp/miniupnpc/upnpcommands.c \ + $(EXTDIR)/miniupnp/miniupnpc/upnpdev.c \ + $(EXTDIR)/miniupnp/miniupnpc/upnperrors.c \ + $(EXTDIR)/miniupnp/miniupnpc/upnpreplyparse.c SOURCES_CXX += \ $(COMMONDIR)/Vulkan/VulkanContext.cpp \ From b9025b50bdbb281fd433b04fac5239dbe9394f65 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 19 Mar 2020 15:21:00 +0700 Subject: [PATCH 345/848] Added a UPnP option to use original port for external port instead of using the shifted port by port offset, to be compatible with real PSP or other PSP emulators --- Core/Config.cpp | 3 ++- Core/Config.h | 1 + Core/HLE/proAdhoc.cpp | 39 ++++++++++++++++++++++++++++--------- Core/HLE/proAdhoc.h | 6 ++++++ Core/HLE/proAdhocServer.cpp | 4 ++-- Core/HLE/sceNet.cpp | 1 + Core/HLE/sceNetAdhoc.cpp | 27 ++++++++++++++++--------- Core/Util/PortManager.cpp | 29 +++++++++++++-------------- Core/Util/PortManager.h | 12 ++++++------ UI/GameSettingsScreen.cpp | 9 ++++++--- 10 files changed, 86 insertions(+), 45 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index a61ea02740..3bc22a4a20 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -957,8 +957,9 @@ static ConfigSetting networkSettings[] = { ConfigSetting("EnableAdhocServer", &g_Config.bEnableAdhocServer, false, true, true), ConfigSetting("proAdhocServer", &g_Config.proAdhocServer, "myneighborsushicat.com", true, true), ConfigSetting("PortOffset", &g_Config.iPortOffset, 0, true, true), - ConfigSetting("EnableUPnP", &g_Config.bEnableUPnP, false, true, true), ConfigSetting("MinTimeout", &g_Config.iMinTimeout, 1, true, true), + ConfigSetting("EnableUPnP", &g_Config.bEnableUPnP, false, true, true), + ConfigSetting("UPnPUseOriginalPort", &g_Config.bUPnPUseOriginalPort, true, true, true), ConfigSetting("EnableNetworkChat", &g_Config.bEnableNetworkChat, false, true, true), ConfigSetting("ChatButtonPosition",&g_Config.iChatButtonPosition,BOTTOM_LEFT,true,true), diff --git a/Core/Config.h b/Core/Config.h index 8ef4696b4f..5bd145c601 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -412,6 +412,7 @@ public: bool bEnableWlan; bool bEnableAdhocServer; bool bEnableUPnP; + bool bUPnPUseOriginalPort; int iPortOffset; int iMinTimeout; int iWlanAdhocChannel; diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 418612ee56..1bbbf61714 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -73,6 +73,7 @@ std::string message = ""; bool chatScreenVisible = false; bool updateChatScreen = false; int newChat = 0; +bool isOriPort = false; bool isLocalServer = false; sockaddr LocalhostIP; sockaddr LocalIP; @@ -82,11 +83,7 @@ bool isLocalMAC(const SceNetEtherAddr * addr) { SceNetEtherAddr saddr; getLocalMac(&saddr); - // Compare MAC Addresses - int match = memcmp((const void *)addr, (const void *)&saddr, ETHER_ADDR_LEN); - - // Return Result - return (match == 0); + return (memcmp((const void*)addr, (const void*)&saddr, ETHER_ADDR_LEN) == 0); } bool isPDPPortInUse(uint16_t port) { @@ -1604,6 +1601,33 @@ uint32_t getLocalIp(int sock) { return localAddr.sin_addr.s_addr; } +static std::vector> InitPrivateIPRanges() { + struct sockaddr_in saNet, saMask; + std::vector> ip_ranges; + + if (1 == inet_pton(AF_INET, "192.168.0.0", &(saNet.sin_addr)) && 1 == inet_pton(AF_INET, "255.255.0.0", &(saMask.sin_addr))) + ip_ranges.push_back({saNet.sin_addr.s_addr, saMask.sin_addr.s_addr}); + if (1 == inet_pton(AF_INET, "172.16.0.0", &(saNet.sin_addr)) && 1 == inet_pton(AF_INET, "255.240.0.0", &(saMask.sin_addr))) + ip_ranges.push_back({ saNet.sin_addr.s_addr, saMask.sin_addr.s_addr }); + if (1 == inet_pton(AF_INET, "10.0.0.0", &(saNet.sin_addr)) && 1 == inet_pton(AF_INET, "255.0.0.0", &(saMask.sin_addr))) + ip_ranges.push_back({ saNet.sin_addr.s_addr, saMask.sin_addr.s_addr }); + if (1 == inet_pton(AF_INET, "127.0.0.0", &(saNet.sin_addr)) && 1 == inet_pton(AF_INET, "255.0.0.0", &(saMask.sin_addr))) + ip_ranges.push_back({ saNet.sin_addr.s_addr, saMask.sin_addr.s_addr }); + if (1 == inet_pton(AF_INET, "169.254.0.0", &(saNet.sin_addr)) && 1 == inet_pton(AF_INET, "255.255.0.0", &(saMask.sin_addr))) + ip_ranges.push_back({ saNet.sin_addr.s_addr, saMask.sin_addr.s_addr }); + + return ip_ranges; +} + +bool isPrivateIP(uint32_t ip) { + static const std::vector> ip_ranges = InitPrivateIPRanges(); + for (auto ipRange : ip_ranges) { + if ((ip & ipRange.second) == (ipRange.first & ipRange.second)) // We can just use ipRange.first directly if it's already correctly formatted + return true; + } + return false; +} + void getLocalMac(SceNetEtherAddr * addr){ // Read MAC Address from config uint8_t mac[ETHER_ADDR_LEN] = {0}; @@ -1859,10 +1883,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ } bool isBroadcastMAC(const SceNetEtherAddr * addr) { - // Broadcast MAC - if (memcmp(addr->data, "\xFF\xFF\xFF\xFF\xFF\xFF", ETHER_ADDR_LEN) == 0) return true; - // Normal MAC - return false; + return (memcmp(addr->data, "\xFF\xFF\xFF\xFF\xFF\xFF", ETHER_ADDR_LEN) == 0); } bool resolveIP(uint32_t ip, SceNetEtherAddr * mac) { diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 29ce58f2d1..c1d5fe8b25 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -844,6 +844,7 @@ extern SceNetAdhocPtpStat * ptp[255]; extern uint16_t portOffset; extern uint32_t minSocketTimeoutUS; +extern bool isOriPort; extern bool isLocalServer; extern sockaddr LocalhostIP; // Used to differentiate localhost IP on multiple-instance extern sockaddr LocalIP; // IP of Network Adapter used to connect to Adhoc Server (LAN/WAN) @@ -1159,6 +1160,11 @@ int getActivePeerCount(const bool excludeTimedout = true); int getLocalIp(sockaddr_in * SocketAddress); uint32_t getLocalIp(int sock); +/* + * Check if an IP (big-endian/network order) is Private or Public IP + */ +bool isPrivateIP(uint32_t ip); + /* * Get UDP Socket Max Message Size */ diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index c8ef8ea79c..7d663ba1d4 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -1685,13 +1685,13 @@ int proAdhocServerThread(int port) // (int argc, char * argv[]) INFO_LOG(SCENET, "AdhocServer: Listening for Connections on TCP Port %u", port); //SERVER_PORT // Port forward - g_PortManager.Add(port, IP_PROTOCOL_TCP); + g_PortManager.Add(IP_PROTOCOL_TCP, port); // Enter Server Loop result = server_loop(server); // Remove Port mapping - g_PortManager.Remove(port, IP_PROTOCOL_TCP); + g_PortManager.Remove(IP_PROTOCOL_TCP, port); // Notify User INFO_LOG(SCENET, "AdhocServer: Shutdown complete"); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 208cbfebd3..7a04f827cc 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -118,6 +118,7 @@ static void __ResetInitNetLib() { void __NetInit() { // Windows: Assuming WSAStartup already called beforehand portOffset = g_Config.iPortOffset; + isOriPort = g_Config.bEnableUPnP && g_Config.bUPnPUseOriginalPort; minSocketTimeoutUS = g_Config.iMinTimeout * 1000UL; InitLocalhostIP(); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 301c41d5c1..28dca3b32b 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -377,7 +377,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u // Fill in Data internal->id = usocket; internal->laddr = *saddr; - internal->lport = port; //getLocalPort(usocket) - portOffset; //should use the port given to the socket (in case it's UNUSED_PORT port) isn't? + internal->lport = port; //getLocalPort(usocket) - portOffset; internal->rcv_sb_cc = bufferSize; // Link Socket to Translator ID @@ -385,7 +385,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u // Forward Port on Router //sceNetPortOpen("UDP", port); - g_PortManager.Add(port + portOffset, IP_PROTOCOL_UDP); + g_PortManager.Add(IP_PROTOCOL_UDP, isOriPort ? port : port + portOffset, port + portOffset); // Success return i + 1; @@ -519,6 +519,9 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Get Peer IP if (resolveMAC((SceNetEtherAddr *)daddr, (uint32_t *)&target.sin_addr.s_addr)) { + // Some games (ie. PSP2) might try to talk to it's self, not sure if they talked through WAN or LAN when using public Adhoc Server tho + target.sin_port = htons(dport + ((isOriPort && !isPrivateIP(target.sin_addr.s_addr)) ? 0 : portOffset)); + // Acquire Network Lock //_acquireNetworkLock(); @@ -588,7 +591,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int sockaddr_in target; target.sin_family = AF_INET; target.sin_addr.s_addr = peer->ip_addr; - target.sin_port = htons(dport + portOffset); + target.sin_port = htons(dport + ((isOriPort && !isPrivateIP(peer->ip_addr)) ? 0 : portOffset)); int sent = sendto(socket->id, (const char *)data, len, 0, (sockaddr *)&target, sizeof(target)); int error = errno; @@ -980,7 +983,7 @@ static int sceNetAdhocPdpDelete(int id, int unknown) { // Remove Port Forward from Router //sceNetPortClose("UDP", sock->lport); - //g_PortManager.Remove(sock->lport + portOffset, IP_PROTOCOL_UDP); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers + //g_PortManager.Remove(IP_PROTOCOL_UDP, isOriPort ? sock->lport : sock->lport + portOffset); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers // Free Memory free(sock); @@ -1870,6 +1873,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, } SceNetEtherAddr* saddr = (SceNetEtherAddr*)srcmac; SceNetEtherAddr* daddr = (SceNetEtherAddr*)dstmac; + bool isClient = false; // Library is initialized if (netAdhocInited) { // Some games (ie. DBZ Shin Budokai 2) might be getting the saddr/srcmac content from SaveState and causing problems if current MAC is different :( So we try to fix it here @@ -1880,6 +1884,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, if (saddr != NULL && isLocalMAC(saddr) && daddr != NULL && !isBroadcastMAC(daddr)) { // Random Port required if (sport == 0) { + isClient = true; // Find unused Port // while (sport == 0 || _IsPTPPortInUse(sport)) { // // Generate Port Number @@ -1963,7 +1968,8 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Add Port Forward to Router. We may not even need to forward this local port, since PtpOpen usually have port 0 (any port) as source port and followed by PtpConnect (which mean acting as Client), right? //sceNetPortOpen("TCP", sport); - //g_PortManager.Add(sport + portOffset, IP_PROTOCOL_TCP); + if (!isClient) + g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // Return PTP Socket Pointer return i + 1; @@ -2153,7 +2159,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Add Port Forward to Router. Or may be doesn't need to be forwarded since local port already accessible from outside if others were able to connect & get accepted at this point, right? //sceNetPortOpen("TCP", internal->lport); - //g_PortManager.Add(internal->lport + portOffset, IP_PROTOCOL_TCP); + //g_PortManager.Add(IP_PROTOCOL_TCP, internal->lport + portOffset); INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", id, i+1, internal->lport, inet_ntoa(peeraddr.sin_addr), internal->pport); @@ -2234,6 +2240,9 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Grab Peer IP if (resolveMAC(&socket->paddr, (uint32_t *)&sin.sin_addr.s_addr)) { + // Some games (ie. PSP2) might try to talk to it's self, not sure if they talked through WAN or LAN when using public Adhoc Server tho + sin.sin_port = htons(socket->pport + ((isOriPort && !isPrivateIP(sin.sin_addr.s_addr)) ? 0 : portOffset)); + // Grab Nonblocking Flag uint32_t nbio = getBlockingFlag(socket->id); @@ -2245,7 +2254,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { }*/ // Connect Socket to Peer (Nonblocking) - // Fixme: The First Non-blocking POSIX connect will always returns EAGAIN/EWOULDBLOCK because it returns without waiting for ACK, But GvG Next Plus is treating non-blocking connect just like blocking connect, May be on a real PSP the first non-blocking sceNetAdhocPtpConnect can be successfull? + // NOTE: Based on what i read at stackoverflow, The First Non-blocking POSIX connect will always returns EAGAIN/EWOULDBLOCK because it returns without waiting for ACK/handshake, But GvG Next Plus is treating non-blocking PtpConnect just like blocking connect, May be on a real PSP the first non-blocking sceNetAdhocPtpConnect can be successfull? int connectresult = connect(socket->id, (sockaddr *)&sin, sizeof(sin)); // Grab Error Code @@ -2352,7 +2361,7 @@ static int sceNetAdhocPtpClose(int id, int unknown) { // Remove Port Forward from Router //sceNetPortClose("TCP", socket->lport); - //g_PortManager.Remove(socket->lport + portOffset, IP_PROTOCOL_TCP); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers + //g_PortManager.Remove(IP_PROTOCOL_TCP, isOriPort ? socket->lport : socket->lport + portOffset); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers // Free Memory free(socket); @@ -2488,7 +2497,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Add Port Forward to Router //sceNetPortOpen("TCP", sport); - g_PortManager.Add(sport + portOffset, IP_PROTOCOL_TCP); + g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // Return PTP Socket Pointer return i + 1; diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index 166944e75b..8e25cdca37 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -30,8 +30,8 @@ #include #include #include -#include "Core/HLE/proAdhoc.h" // This import is only used to get product id that was used to connect to adhoc server #include "Core/Util/PortManager.h" +#include #include "i18n/i18n.h" @@ -77,7 +77,7 @@ bool PortManager::Init(const unsigned int timeout) { char* descXML; int descXMLsize = 0; int descXMLstatus = 0; - int localport = m_LocalPort; // UPNP_LOCAL_PORT_ANY (0), or UPNP_LOCAL_PORT_SAME (1) as an alias for 1900 for backwards compatability? + int localport = m_LocalPort; // UPNP_LOCAL_PORT_ANY (0), or UPNP_LOCAL_PORT_SAME (1) as an alias for 1900 (for backwards compatability?) int ipv6 = 0; // 0 = IPv4, 1 = IPv6 unsigned char ttl = 2; // defaulting to 2 int error = 0; @@ -151,13 +151,8 @@ bool PortManager::Init(const unsigned int timeout) { INFO_LOG(SCENET, "PortManager - Connection Type: %s", connectionType); } - // Using Game ID & Player Name as default description for mapping (prioritizing the ID sent by the game to Adhoc server) - char productid[10] = { 0 }; - memcpy(productid, product_code.data, sizeof(product_code.data)); - std::string gameID = std::string(productid); - if (productid[0] == '\0') { - gameID = g_paramSFO.GetDiscID(); - } + // Using Game ID & Player Name as default description for mapping + std::string gameID = g_paramSFO.GetDiscID(); m_defaultDesc = "PPSSPP:" + gameID + ":" + g_Config.sNickName; freeUPNPDevlist(devlist); @@ -179,17 +174,21 @@ int PortManager::GetInitState() { return m_InitState; } -bool PortManager::Add(unsigned short port, const char* protocol) { +bool PortManager::Add(const char* protocol, unsigned short port, unsigned short intport) { char port_str[16]; + char intport_str[16]; int r; - INFO_LOG(SCENET, "PortManager::Add(%d, %s)", port, protocol); + if (intport == 0) + intport = port; + INFO_LOG(SCENET, "PortManager::Add(%s, %d, %d)", protocol, port, intport); if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') { if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Add - the init was not done !"); return false; } sprintf(port_str, "%d", port); + sprintf(intport_str, "%d", intport); // Only add new port map if it's not previously created by PPSSPP for current IP auto el_it = std::find_if(m_portList.begin(), m_portList.end(), [port_str, protocol](const std::pair &el) { return el.first == port_str && el.second == protocol; }); @@ -201,11 +200,11 @@ bool PortManager::Add(unsigned short port, const char* protocol) { r = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, port_str, protocol, NULL); } r = UPNP_AddPortMapping(urls->controlURL, datas->first.servicetype, - port_str, port_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, m_leaseDuration.c_str()); + port_str, intport_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, m_leaseDuration.c_str()); if (r == 725 && m_leaseDuration != "0") { m_leaseDuration = "0"; r = UPNP_AddPortMapping(urls->controlURL, datas->first.servicetype, - port_str, port_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, m_leaseDuration.c_str()); + port_str, intport_str, m_lanip.c_str(), m_defaultDesc.c_str(), protocol, NULL, m_leaseDuration.c_str()); } if (r != 0) { @@ -224,10 +223,10 @@ bool PortManager::Add(unsigned short port, const char* protocol) { return true; } -bool PortManager::Remove(unsigned short port, const char* protocol) { +bool PortManager::Remove(const char* protocol, unsigned short port) { char port_str[16]; - INFO_LOG(SCENET, "PortManager::Remove(%d, %s)", port, protocol); + INFO_LOG(SCENET, "PortManager::Remove(%s, %d)", protocol, port); if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') { if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Remove - the init was not done !"); diff --git a/Core/Util/PortManager.h b/Core/Util/PortManager.h index 9a4cdedf05..85a285a5eb 100644 --- a/Core/Util/PortManager.h +++ b/Core/Util/PortManager.h @@ -69,19 +69,19 @@ public: // Get UPnP Initialization status int GetInitState(); - // Add a port & protocol (TCP, UDP or vendor-defined) to map for forwarding - bool Add(unsigned short port, const char* protocol); + // Add a port & protocol (TCP, UDP or vendor-defined) to map for forwarding (intport = 0 : same as [external] port) + bool Add(const char* protocol, unsigned short port, unsigned short intport = 0); - // Remove a port mapping - bool Remove(unsigned short port, const char* protocol); + // Remove a port mapping (external port) + bool Remove(const char* protocol, unsigned short port); - // Removes any lingering mapped ports from previous crashes + // Removes any lingering mapped ports created by PPSSPP from previous crashes bool Clear(); // Restore ports mapped by others that were taken by PPSSPP, better used after Clear() bool Restore(); - // Get port list mapped by PPSSPP for current LAN IP & others + // Get port lists mapped by PPSSPP for current LAN IP & other's applications bool RefreshPortList(); protected: diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4090861c53..b26cb38035 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -690,7 +690,6 @@ void GameSettingsScreen::CreateViews() { networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.proAdhocServer, n->T("Change proAdhocServer Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeproAdhocServerAddress); networkingSettings->Add(new CheckBox(&g_Config.bEnableAdhocServer, n->T("Enable built-in PRO Adhoc Server", "Enable built-in PRO Adhoc Server"))); - networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)"))); networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress); static const char* wlanChannels[] = { "Auto", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" }; auto wlanChannelChoice = networkingSettings->Add(new PopupMultiChoice(&g_Config.iWlanAdhocChannel, gr->T("WLAN Channel"), wlanChannels, 0, ARRAY_SIZE(wlanChannels), gr->GetName(), screenManager())); @@ -698,8 +697,12 @@ void GameSettingsScreen::CreateViews() { wlanChannelChoice->HideChoice(i+2); wlanChannelChoice->HideChoice(i+7); } - networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset(0 = PSP compatibility)"), 100, screenManager())); - networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 1, 15000, n->T("Minimum Timeout", "Minimum Timeout (override low latency communication in milliseconds)"), 100, screenManager())); + networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset (0 = PSP compatibility)"), 100, screenManager())); + networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 1, 15000, n->T("Minimum Timeout", "Minimum Timeout (override low latency in ms)"), 100, screenManager())); + + networkingSettings->Add(new ItemHeader(n->T("UPnP"))); + networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)"))); + networkingSettings->Add(new CheckBox(&g_Config.bUPnPUseOriginalPort, n->T("UPnP use original port", "UPnP use original port (PSP compatibility)")))->SetEnabledPtr(&g_Config.bEnableUPnP); networkingSettings->Add(new ItemHeader(n->T("Chat"))); networkingSettings->Add(new CheckBox(&g_Config.bEnableNetworkChat, n->T("Enable network chat", "Enable network chat"))); From 68fa15784c31cf3e3a9d0dd8432f2c5dc2fe53cb Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 22 Mar 2020 03:08:01 +0700 Subject: [PATCH 346/848] Fixed UPnP port opened by PPSSPP detection, and Updated PortManager to be compliant to general purpose usage --- Core/HLE/sceNet.cpp | 8 +++++--- Core/Util/PortManager.cpp | 37 +++++++++++++++++++++---------------- Core/Util/PortManager.h | 8 ++++---- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 7a04f827cc..85077c1afa 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -130,7 +130,8 @@ void __NetInit() { // Only initialize when UPnP is enabled since it takes a few seconds to detect UPnP device (may affect people who don't have UPnP device) if (g_Config.bEnableUPnP) { - g_PortManager.Init(); + // TODO: May be we should initialize & cleanup somewhere else than here for PortManager to be used as general purpose for whatever port forwarding PPSSPP needed + g_PortManager.Initialize(); } __ResetInitNetLib(); @@ -148,10 +149,11 @@ void __NetShutdown() { __ResetInitNetLib(); - if (g_Config.bEnableUPnP) { + // Since PortManager supposed to be general purpose for whatever port forwarding PPSSPP needed, may be we shouldn't clear & restore ports in here? But currently there is an issue with UPnP functions used in PortManager's destructor :( + if (g_PortManager.GetInitState() == UPNP_INITSTATE_DONE) { g_PortManager.Clear(); g_PortManager.Restore(); - g_PortManager.Deinit(); + g_PortManager.Terminate(); } } diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index 8e25cdca37..0ba1f2a83b 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -46,12 +46,13 @@ PortManager::PortManager(): } PortManager::~PortManager() { + // FIXME: It seems using any UPnP functions in this destructor that gets triggered when exiting PPSSPP will resulting to UPNPCOMMAND_HTTP_ERROR :( Did miniUPnPc library already shutted down at this point? Clear(); Restore(); - Deinit(); + Terminate(); } -void PortManager::Deinit() { +void PortManager::Terminate() { if (urls) { FreeUPNPUrls(urls); free(urls); @@ -67,10 +68,10 @@ void PortManager::Deinit() { m_defaultDesc.clear(); m_leaseDuration.clear(); m_LocalPort = UPNP_LOCAL_PORT_ANY; - m_InitState = UPNP_INITSTATE_DONE; + m_InitState = UPNP_INITSTATE_NONE; } -bool PortManager::Init(const unsigned int timeout) { +bool PortManager::Initialize(const unsigned int timeout) { // Windows: Assuming WSAStartup already called beforehand struct UPNPDev* devlist; struct UPNPDev* dev; @@ -95,12 +96,11 @@ bool PortManager::Init(const unsigned int timeout) { WARN_LOG(SCENET, "PortManager - Initialization already in progress"); return false; } - // We should redetect UPnP just in case the player switched to a different network in the middle - /*case UPNP_INITSTATE_DONE: { + // Should we redetect UPnP? just in case the player switched to a different network in the middle + case UPNP_INITSTATE_DONE: { WARN_LOG(SCENET, "PortManager - Already Initialized"); - return false; + return true; } - */ default: break; } @@ -153,7 +153,7 @@ bool PortManager::Init(const unsigned int timeout) { // Using Game ID & Player Name as default description for mapping std::string gameID = g_paramSFO.GetDiscID(); - m_defaultDesc = "PPSSPP:" + gameID + ":" + g_Config.sNickName; + m_defaultDesc = "PPSSPP:" + gameID + ":" + g_Config.sNickName; // Some routers may automatically prefixed it with "UPnP:" freeUPNPDevlist(devlist); @@ -212,7 +212,7 @@ bool PortManager::Add(const char* protocol, unsigned short port, unsigned short if (r == UPNPCOMMAND_HTTP_ERROR) { auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); - Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts + Terminate(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts return false; } } @@ -240,7 +240,7 @@ bool PortManager::Remove(const char* protocol, unsigned short port) { if (r == UPNPCOMMAND_HTTP_ERROR) { auto n = GetI18NCategory("Networking"); host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); - Deinit(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts + Terminate(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts return false; } } @@ -316,8 +316,9 @@ bool PortManager::Clear() { do { snprintf(index, 6, "%d", i); rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; + duration[0] = '\0'; desc[0] = '\0'; protocol[0] = '\0'; extPort[0] = '\0'; intPort[0] = '\0'; intAddr[0] = '\0'; + // May gets UPNPCOMMAND_HTTP_ERROR when called while exiting PPSSPP (ie. used in destructor) r = UPNP_GetGenericPortMappingEntry(urls->controlURL, datas->first.servicetype, index, @@ -325,7 +326,7 @@ bool PortManager::Clear() { protocol, desc, enabled, rHost, duration); // Only removes port mappings created by PPSSPP for current LAN IP - if (r == 0 && intAddr == m_lanip && std::strncmp(desc, "PPSSPP", 6) == 0) { + if (r == 0 && intAddr == m_lanip && std::string(desc).find("PPSSPP:") != std::string::npos) { int r2 = UPNP_DeletePortMapping(urls->controlURL, datas->first.servicetype, extPort, protocol, rHost); if (r2 != 0) { @@ -371,7 +372,7 @@ bool PortManager::RefreshPortList() { do { snprintf(index, 6, "%d", i); rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; + duration[0] = '\0'; desc[0] = '\0'; protocol[0] = '\0'; extPort[0] = '\0'; intPort[0] = '\0'; intAddr[0] = '\0'; r = UPNP_GetGenericPortMappingEntry(urls->controlURL, datas->first.servicetype, @@ -380,13 +381,17 @@ bool PortManager::RefreshPortList() { protocol, desc, enabled, rHost, duration); if (r == 0) { + std::string desc_str = std::string(desc); + // Some router might prefix the description with "UPnP:" so we may need to truncate it to prevent it from getting multiple prefix when restored later + if (desc_str.find("UPnP:") == 0) + desc_str = desc_str.substr(5); // Only include port mappings created by PPSSPP for current LAN IP - if (intAddr == m_lanip && std::strncmp(desc, "PPSSPP", 6) == 0) { + if (intAddr == m_lanip && desc_str.find("PPSSPP:") != std::string::npos) { m_portList.push_back({ extPort, protocol }); } // Port mappings belong to others that might be taken by PPSSPP later else { - m_otherPortList.push_back({ false, protocol, extPort, intPort, intAddr, rHost, desc, duration, enabled }); + m_otherPortList.push_back({ false, protocol, extPort, intPort, intAddr, rHost, desc_str, duration, enabled }); } } i++; diff --git a/Core/Util/PortManager.h b/Core/Util/PortManager.h index 85a285a5eb..37040218dc 100644 --- a/Core/Util/PortManager.h +++ b/Core/Util/PortManager.h @@ -61,10 +61,10 @@ public: // Initialize UPnP // timeout: milliseconds to wait for a router to respond (default = 2000 ms) - bool Init(const unsigned int timeout = 2000); + bool Initialize(const unsigned int timeout = 2000); // Uninitialize/Reset the state - void Deinit(); + void Terminate(); // Get UPnP Initialization status int GetInitState(); @@ -75,13 +75,13 @@ public: // Remove a port mapping (external port) bool Remove(const char* protocol, unsigned short port); - // Removes any lingering mapped ports created by PPSSPP from previous crashes + // Removes any lingering mapped ports created by PPSSPP (including from previous crashes) bool Clear(); // Restore ports mapped by others that were taken by PPSSPP, better used after Clear() bool Restore(); - // Get port lists mapped by PPSSPP for current LAN IP & other's applications + // Retrieves port lists mapped by PPSSPP for current LAN IP & other's applications bool RefreshPortList(); protected: From 65bc68609c11f8550e7f6150d88217b9597460c2 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 22 Mar 2020 12:08:17 +0700 Subject: [PATCH 347/848] Added an option to Disable Nagle Algorithm (Enable TCP No Delay) --- Core/Config.cpp | 1 + Core/Config.h | 1 + Core/HLE/sceNetAdhoc.cpp | 6 +++--- UI/GameSettingsScreen.cpp | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 3bc22a4a20..0a4ada08f4 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -958,6 +958,7 @@ static ConfigSetting networkSettings[] = { ConfigSetting("proAdhocServer", &g_Config.proAdhocServer, "myneighborsushicat.com", true, true), ConfigSetting("PortOffset", &g_Config.iPortOffset, 0, true, true), ConfigSetting("MinTimeout", &g_Config.iMinTimeout, 1, true, true), + ConfigSetting("TCPNoDelay", &g_Config.bTCPNoDelay, false, true, true), ConfigSetting("EnableUPnP", &g_Config.bEnableUPnP, false, true, true), ConfigSetting("UPnPUseOriginalPort", &g_Config.bUPnPUseOriginalPort, true, true, true), diff --git a/Core/Config.h b/Core/Config.h index 5bd145c601..03e3b34584 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -411,6 +411,7 @@ public: std::string proAdhocServer; bool bEnableWlan; bool bEnableAdhocServer; + bool bTCPNoDelay; bool bEnableUPnP; bool bUPnPUseOriginalPort; int iPortOffset; diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 28dca3b32b..dee0dd28eb 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1917,7 +1917,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, setSockTimeout(tcpsocket, SO_SNDTIMEO, rexmt_int); // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - //setSockNoDelay(tcpsocket, 1); + if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1); // Binding Information for local Port sockaddr_in addr; @@ -2107,7 +2107,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - //setSockNoDelay(newsocket, 1); + if (g_Config.bTCPNoDelay) setSockNoDelay(newsocket, 1); // Grab Local Address if (getsockname(newsocket, (sockaddr *)&local, &locallen) == 0) { @@ -2444,7 +2444,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int setSockTimeout(tcpsocket, SO_RCVTIMEO, rexmt_int); // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - //setSockNoDelay(tcpsocket, 1); + if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1); // Binding Information for local Port sockaddr_in addr; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index b26cb38035..9d1012f97b 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -699,6 +699,7 @@ void GameSettingsScreen::CreateViews() { } networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset (0 = PSP compatibility)"), 100, screenManager())); networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 1, 15000, n->T("Minimum Timeout", "Minimum Timeout (override low latency in ms)"), 100, screenManager())); + networkingSettings->Add(new CheckBox(&g_Config.bTCPNoDelay, n->T("TCP No Delay", "TCP No Delay (faster TCP)"))); networkingSettings->Add(new ItemHeader(n->T("UPnP"))); networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)"))); From e21ea719e97e486f1092b7ac252c05fc8fdb86ba Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 23 Mar 2020 21:51:45 +0700 Subject: [PATCH 348/848] Fixed PortManager fallback Cleanup issue when exiting PPSSPP due to early WSACleanup --- Core/HLE/sceNet.cpp | 2 +- Core/Util/PortManager.cpp | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 85077c1afa..2af5ff7f03 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -149,7 +149,7 @@ void __NetShutdown() { __ResetInitNetLib(); - // Since PortManager supposed to be general purpose for whatever port forwarding PPSSPP needed, may be we shouldn't clear & restore ports in here? But currently there is an issue with UPnP functions used in PortManager's destructor :( + // Since PortManager supposed to be general purpose for whatever port forwarding PPSSPP needed, may be we shouldn't clear & restore ports in here? it will be cleared and restored by PortManager's destructor when exiting PPSSPP anyway if (g_PortManager.GetInitState() == UPNP_INITSTATE_DONE) { g_PortManager.Clear(); g_PortManager.Restore(); diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index 0ba1f2a83b..34819be5bc 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -33,6 +33,7 @@ #include "Core/Util/PortManager.h" #include #include "i18n/i18n.h" +#include "net/resolve.h" PortManager g_PortManager; @@ -43,16 +44,20 @@ PortManager::PortManager(): m_InitState(UPNP_INITSTATE_NONE), m_LocalPort(UPNP_LOCAL_PORT_ANY), m_leaseDuration("43200") { + // Since WSAStartup can be used multiple times it should be safe to do this right? + net::Init(); } PortManager::~PortManager() { - // FIXME: It seems using any UPnP functions in this destructor that gets triggered when exiting PPSSPP will resulting to UPNPCOMMAND_HTTP_ERROR :( Did miniUPnPc library already shutted down at this point? + // FIXME: On Windows it seems using any UPnP functions in this destructor that gets triggered when exiting PPSSPP will resulting to UPNPCOMMAND_HTTP_ERROR due to early WSACleanup (miniupnpc was getting WSANOTINITIALISED internally) Clear(); Restore(); Terminate(); + net::Shutdown(); } void PortManager::Terminate() { + INFO_LOG(SCENET, "PortManager::Terminate()"); if (urls) { FreeUPNPUrls(urls); free(urls); @@ -83,9 +88,9 @@ bool PortManager::Initialize(const unsigned int timeout) { unsigned char ttl = 2; // defaulting to 2 int error = 0; - INFO_LOG(SCENET, "PortManager::Init(%d)", timeout); + INFO_LOG(SCENET, "PortManager::Initialize(%d)", timeout); if (!g_Config.bEnableUPnP) { - ERROR_LOG(SCENET, "PortManager::Init - UPnP is Disabled on Networking Settings"); + ERROR_LOG(SCENET, "PortManager::Initialize - UPnP is Disabled on Networking Settings"); return false; } From 1d30a9efec770c99e6620d8f407da885aa72f5ed Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 26 Mar 2020 16:10:50 +0700 Subject: [PATCH 349/848] Fix possible crash issue during Networking Cleanup --- Core/HLE/sceNet.cpp | 35 +++--- Core/HLE/sceNet.h | 2 + Core/HLE/sceNetAdhoc.cpp | 224 +++++++++++++++++++++++---------------- Core/HLE/sceNetAdhoc.h | 5 +- 4 files changed, 157 insertions(+), 109 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 2af5ff7f03..fbe60def3d 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -138,14 +138,8 @@ void __NetInit() { } void __NetShutdown() { - // Checks to avoid confusing logspam - if (netAdhocctlInited) sceNetAdhocctlTerm(); - if (netAdhocInited) sceNetAdhocTerm(); - - if (netApctlInited) sceNetApctlTerm(); - if (netInetInited) sceNetInetTerm(); - - if (netInited) sceNetTerm(); + // Network Cleanup + Net_Term(); __ResetInitNetLib(); @@ -222,13 +216,14 @@ static inline void FreeUser(u32 &addr) { addr = 0; } -static u32 sceNetTerm() { +u32 Net_Term() { // May also need to Terminate netAdhocctl and netAdhoc to free some resources & threads, since the game (ie. GTA:VCS, Wipeout Pulse, etc) might not called them before calling sceNetTerm and causing them to behave strangely on the next sceNetInit & sceNetAdhocInit - if (netAdhocctlInited) sceNetAdhocctlTerm(); - if (netAdhocInited) sceNetAdhocTerm(); + NetAdhocctl_Term(); + NetAdhoc_Term(); - if (netApctlInited) sceNetApctlTerm(); - if (netInetInited) sceNetInetTerm(); + // TODO: Not implemented yet + //sceNetApctl_Term(); + //NetInet_Term(); // Library is initialized if (netInited) { @@ -249,15 +244,21 @@ static u32 sceNetTerm() { // Library shutdown } - WARN_LOG(SCENET, "sceNetTerm()"); - netInited = false; FreeUser(netPoolAddr); FreeUser(netThread1Addr); FreeUser(netThread2Addr); + netInited = false; + + return 0; +} + +static u32 sceNetTerm() { + WARN_LOG(SCENET, "sceNetTerm()"); + int retval = Net_Term(); // Give time to make sure everything are cleaned up - hleDelayResult(0, "give time to init/cleanup", adhocEventDelayMS * 1000); - return 0; + hleDelayResult(retval, "give time to init/cleanup", adhocEventDelayMS * 1000); + return retval; } /* diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index 2f7a9044bd..84615a2427 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -109,6 +109,8 @@ void __NetInit(); void __NetShutdown(); void __NetDoState(PointerWrap &p); +u32 Net_Term(); + int sceNetInetPoll(void *fds, u32 nfds, int timeout); int sceNetInetTerm(); int sceNetApctlTerm(); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index dee0dd28eb..8c34e64f0d 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -954,27 +954,13 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb return ERROR_NET_ADHOC_NOT_INITIALIZED; } -/** - * Adhoc Emulator PDP Socket Delete - * @param id Socket File Descriptor - * @param flag Bitflags (Unused) - * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID - */ -static int sceNetAdhocPdpDelete(int id, int unknown) { - // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? - INFO_LOG(SCENET, "sceNetAdhocPdpDelete(%d, %d) at %08x", id, unknown, currentMIPS->pc); - /* - if (!g_Config.bEnableWlan) { - return 0; - } - */ - +int NetAdhocPdp_Delete(int id, int unknown) { // Library is initialized if (netAdhocInited) { // Valid Arguments if (id > 0 && id <= 255) { // Cast Socket - SceNetAdhocPdpStat * sock = pdp[id - 1]; + SceNetAdhocPdpStat* sock = pdp[id - 1]; // Valid Socket if (sock != NULL) { @@ -1007,6 +993,24 @@ static int sceNetAdhocPdpDelete(int id, int unknown) { return ERROR_NET_ADHOC_NOT_INITIALIZED; } +/** + * Adhoc Emulator PDP Socket Delete + * @param id Socket File Descriptor + * @param flag Bitflags (Unused) + * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID + */ +static int sceNetAdhocPdpDelete(int id, int unknown) { + // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? + INFO_LOG(SCENET, "sceNetAdhocPdpDelete(%d, %d) at %08x", id, unknown, currentMIPS->pc); + /* + if (!g_Config.bEnableWlan) { + return 0; + } + */ + + return NetAdhocPdp_Delete(id, unknown); +} + static int sceNetAdhocctlGetAdhocId(u32 productStructAddr) { ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlGetAdhocId(%08x)", productStructAddr); @@ -1230,12 +1234,7 @@ static u32 sceNetAdhocctlAddHandler(u32 handlerPtr, u32 handlerArg) { return retval; } -static u32 sceNetAdhocctlDisconnect() { - // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? - char grpName[9] = { 0 }; - memcpy(grpName, parameter.group_name.data, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs - INFO_LOG(SCENET, "sceNetAdhocctlDisconnect() at %08x [group=%s]", currentMIPS->pc, grpName); - +u32 NetAdhocctl_Disconnect() { // Library initialized if (netAdhocctlInited) { // Connected State (Adhoc Mode) @@ -1253,7 +1252,7 @@ static u32 sceNetAdhocctlDisconnect() { //_acquireNetworkLock(); // Send Disconnect Request Packet - int iResult = send(metasocket, (const char *)&opcode, 1, 0); + int iResult = send(metasocket, (const char*)&opcode, 1, 0); if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "Socket error (%i) when sending", errno); } @@ -1283,9 +1282,9 @@ static u32 sceNetAdhocctlDisconnect() { // Multithreading Unlock //peerlock.unlock(); - + // Notify Event Handlers (even if we weren't connected, not doing this will freeze games like God Eater, which expect this behaviour) - notifyAdhocctlHandlers(ADHOCCTL_EVENT_DISCONNECT, 0); + notifyAdhocctlHandlers(ADHOCCTL_EVENT_DISCONNECT, 0); hleCheckCurrentCallbacks(); // Return Success, some games might ignore returned value and always treat it as success, otherwise repeatedly calling this function @@ -1296,6 +1295,15 @@ static u32 sceNetAdhocctlDisconnect() { return 0; //ERROR_NET_ADHOC_NOT_INITIALIZED; // Wipeout Pulse will repeatedly calling this function if returned value is ERROR_NET_ADHOC_NOT_INITIALIZED } +static u32 sceNetAdhocctlDisconnect() { + // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? + char grpName[9] = { 0 }; + memcpy(grpName, parameter.group_name.data, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + INFO_LOG(SCENET, "sceNetAdhocctlDisconnect() at %08x [group=%s]", currentMIPS->pc, grpName); + + return NetAdhocctl_Disconnect(); +} + static u32 sceNetAdhocctlDelHandler(u32 handlerID) { if (adhocctlHandlers.find(handlerID) != adhocctlHandlers.end()) { adhocctlHandlers.erase(handlerID); @@ -1307,14 +1315,11 @@ static u32 sceNetAdhocctlDelHandler(u32 handlerID) { return 0; } -int sceNetAdhocctlTerm() { - // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? - INFO_LOG(SCENET, "sceNetAdhocctlTerm()"); - - //if (netAdhocMatchingInited) sceNetAdhocMatchingTerm(); - +int NetAdhocctl_Term() { if (netAdhocctlInited) { - if (threadStatus != ADHOCCTL_STATE_DISCONNECTED) sceNetAdhocctlDisconnect(); + if (threadStatus != ADHOCCTL_STATE_DISCONNECTED) + NetAdhocctl_Disconnect(); + if (networkInited) { // Terminate Adhoc Threads friendFinderRunning = false; @@ -1345,6 +1350,15 @@ int sceNetAdhocctlTerm() { return 0; } +int sceNetAdhocctlTerm() { + // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? + INFO_LOG(SCENET, "sceNetAdhocctlTerm()"); + + //if (netAdhocMatchingInited) NetAdhocMatching_Term(); + + return NetAdhocctl_Term(); +} + static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { char tmpmac[18]; DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x)", mac2str((SceNetEtherAddr*)mac, tmpmac), nameAddr); @@ -1669,12 +1683,12 @@ int sceNetAdhocctlCreateEnterGameModeMin(const char *group_name, int game_type, return sceNetAdhocctlCreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); //0; } -int sceNetAdhocTerm() { - // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup all the sockets right? - +int NetAdhoc_Term() { // Since Adhocctl & AdhocMatching uses Sockets & Threads we should terminate them also to release their resources - if (netAdhocMatchingInited) sceNetAdhocMatchingTerm(); - if (netAdhocctlInited) sceNetAdhocctlTerm(); + if (netAdhocMatchingInited) + NetAdhocMatching_Term(); + if (netAdhocctlInited) + NetAdhocctl_Term(); // Library is initialized if (netAdhocInited) { @@ -1693,14 +1707,23 @@ int sceNetAdhocTerm() { // Unload Internet Modules (Just keep it in memory... unloading crashes?!) // if (_manage_modules != 0) sceUtilityUnloadModule(PSP_MODULE_NET_INET); // Library shutdown - + netAdhocInited = false; - return hleLogSuccessInfoI(SCENET, 0); - } else { + //return hleLogSuccessInfoI(SCENET, 0); + } + /*else { // TODO: Reportedly returns SCE_KERNEL_ERROR_LWMUTEX_NOT_FOUND in some cases? // Only seen returning 0 in tests. return hleLogWarning(SCENET, 0, "already uninitialized"); - } + }*/ + + return 0; +} + +int sceNetAdhocTerm() { + // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup all the sockets right? + + return hleLogSuccessInfoI(SCENET, NetAdhoc_Term()); } static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { @@ -2338,6 +2361,39 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { return ERROR_NET_ADHOC_NOT_INITIALIZED; } +int NetAdhocPtp_Close(int id, int unknown) { + // Library is initialized + if (netAdhocInited) { + // Valid Arguments & Atleast one Socket + if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { + // Cast Socket + SceNetAdhocPtpStat* socket = ptp[id - 1]; + + // Close Connection + closesocket(socket->id); + + // Remove Port Forward from Router + //sceNetPortClose("TCP", socket->lport); + //g_PortManager.Remove(IP_PROTOCOL_TCP, isOriPort ? socket->lport : socket->lport + portOffset); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers + + // Free Memory + free(socket); + + // Free Reference + ptp[id - 1] = NULL; + + // Success + return 0; + } + + // Invalid Argument + return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + } + + // Library is uninitialized + return ERROR_NET_ADHOC_NOT_INITIALIZED; +} + /** * Adhoc Emulator PTP Socket Closer * @param id Socket File Descriptor @@ -2346,39 +2402,11 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { */ static int sceNetAdhocPtpClose(int id, int unknown) { INFO_LOG(SCENET,"sceNetAdhocPtpClose(%d,%d) at %08x",id,unknown,currentMIPS->pc); - if (!g_Config.bEnableWlan) { + /*if (!g_Config.bEnableWlan) { return 0; - } - // Library is initialized - if (netAdhocInited) { - // Valid Arguments & Atleast one Socket - if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { - // Cast Socket - SceNetAdhocPtpStat * socket = ptp[id - 1]; - - // Close Connection - closesocket(socket->id); - - // Remove Port Forward from Router - //sceNetPortClose("TCP", socket->lport); - //g_PortManager.Remove(IP_PROTOCOL_TCP, isOriPort ? socket->lport : socket->lport + portOffset); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers - - // Free Memory - free(socket); - - // Free Reference - ptp[id - 1] = NULL; - - // Success - return 0; - } - - // Invalid Argument - return ERROR_NET_ADHOC_INVALID_SOCKET_ID; - } + }*/ - // Library is uninitialized - return ERROR_NET_ADHOC_NOT_INITIALIZED; + return NetAdhocPtp_Close(id, unknown); } @@ -2842,10 +2870,8 @@ int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { return 0; } -int sceNetAdhocMatchingStop(int matchingId) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStop(%i) at %08x", matchingId, currentMIPS->pc); - - SceNetAdhocMatchingContext * item = findMatchingContext(matchingId); +int NetAdhocMatching_Stop(int matchingId) { + SceNetAdhocMatchingContext* item = findMatchingContext(matchingId); if (item != NULL) { item->inputRunning = false; @@ -2887,17 +2913,21 @@ int sceNetAdhocMatchingStop(int matchingId) { return 0; } -int sceNetAdhocMatchingDelete(int matchingId) { - // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? +int sceNetAdhocMatchingStop(int matchingId) { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStop(%i) at %08x", matchingId, currentMIPS->pc); + return NetAdhocMatching_Stop(matchingId); +} + +int NetAdhocMatching_Delete(int matchingId) { // Previous Context Reference - SceNetAdhocMatchingContext * prev = NULL; + SceNetAdhocMatchingContext* prev = NULL; // Multithreading Lock peerlock.lock(); //contextlock.lock(); // Context Pointer - SceNetAdhocMatchingContext * item = contexts; + SceNetAdhocMatchingContext* item = contexts; // Iterate contexts for (; item != NULL; item = item->next) { @@ -2911,7 +2941,7 @@ int sceNetAdhocMatchingDelete(int matchingId) { // Stop it first if it's still running if (item->running) { - sceNetAdhocMatchingStop(matchingId); + NetAdhocMatching_Stop(matchingId); } // Delete the Fake PSP Thread //__KernelDeleteThread(item->matching_thid, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocMatching deleted"); @@ -2919,7 +2949,7 @@ int sceNetAdhocMatchingDelete(int matchingId) { // Make sure nobody locking/using the socket item->socketlock->lock(); // Delete the socket - sceNetAdhocPdpDelete(item->socket, 0); // item->connected = (sceNetAdhocPdpDelete(item->socket, 0) < 0); + NetAdhocPdp_Delete(item->socket, 0); // item->connected = (sceNetAdhocPdpDelete(item->socket, 0) < 0); item->socketlock->unlock(); // Free allocated memories free(item->hello); @@ -2928,10 +2958,10 @@ int sceNetAdhocMatchingDelete(int matchingId) { // Destroy locks item->eventlock->lock(); // Make sure it's not locked when being deleted item->eventlock->unlock(); - delete item->eventlock; + delete item->eventlock; item->inputlock->lock(); // Make sure it's not locked when being deleted item->inputlock->unlock(); - delete item->inputlock; + delete item->inputlock; item->socketlock->lock(); // Make sure it's not locked when being deleted item->socketlock->unlock(); delete item->socketlock; @@ -2950,6 +2980,14 @@ int sceNetAdhocMatchingDelete(int matchingId) { // Multithreading Unlock peerlock.unlock(); //contextlock.unlock(); + return 0; +} + +int sceNetAdhocMatchingDelete(int matchingId) { + // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? + + NetAdhocMatching_Delete(matchingId); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingDelete(%i) at %08x", matchingId, currentMIPS->pc); // Give a little time to make sure everything are cleaned up before the following AdhocMatchingCreate, Not too long tho, otherwise Naruto Ultimate Ninja Heroes 3 will have an issue @@ -2974,21 +3012,27 @@ int sceNetAdhocMatchingInit(u32 memsize) { return 0; } -int sceNetAdhocMatchingTerm() { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingTerm()"); - // Should we cleanup all created matching contexts first? just in case there are games that doesn't delete them before calling this +int NetAdhocMatching_Term() { if (netAdhocMatchingInited) { // Delete all Matching contexts SceNetAdhocMatchingContext* next = NULL; - SceNetAdhocMatchingContext * context = contexts; + SceNetAdhocMatchingContext* context = contexts; while (context != NULL) { next = context->next; - //if (context->running) sceNetAdhocMatchingStop(context->id); - sceNetAdhocMatchingDelete(context->id); + //if (context->running) NetAdhocMatching_Stop(context->id); + NetAdhocMatching_Delete(context->id); context = next; } contexts = NULL; } + + return 0; +} + +int sceNetAdhocMatchingTerm() { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingTerm()"); + // Should we cleanup all created matching contexts first? just in case there are games that doesn't delete them before calling this + NetAdhocMatching_Term(); netAdhocMatchingInited = false; return 0; diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index e2e9a434a2..0577caac50 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -53,5 +53,6 @@ extern int adhocEventDelayMS; // This will affect the duration of "Connecting... extern std::recursive_mutex adhocEvtMtx; extern int IsAdhocctlInCB; -int sceNetAdhocctlTerm(); -int sceNetAdhocTerm(); +int NetAdhocMatching_Term(); +int NetAdhocctl_Term(); +int NetAdhoc_Term(); From df268453889ecf16261d39abf8fcca50038defc6 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 4 May 2020 21:44:40 +0700 Subject: [PATCH 350/848] Minor fixes --- Core/HLE/proAdhoc.cpp | 8 +++--- Core/HLE/proAdhoc.h | 6 +++-- Core/HLE/sceNet.cpp | 2 +- Core/HLE/sceNetAdhoc.cpp | 56 +++++++++++++++++++++------------------- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 1bbbf61714..49806c1ce5 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -160,7 +160,7 @@ void addFriend(SceNetAdhocctlConnectPacketS2C * packet) { if (peer != NULL) { char tmpmac[18]; u32 tmpip = packet->ip; - WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", packet->name.data, mac2str(&packet->mac, tmpmac), inet_ntoa(*(struct in_addr*)&tmpip)); //inet_ntoa(*(in_addr*)&packet->ip) + WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", mac2str(&packet->mac, tmpmac), inet_ntoa(*(struct in_addr*)&tmpip), packet->name.data); //inet_ntoa(*(in_addr*)&packet->ip) peer->nickname = packet->name; peer->mac_addr = packet->mac; peer->ip_addr = packet->ip; @@ -1007,7 +1007,7 @@ void AfterMatchingMipsCall::run(MipsCall &call) { u32 v0 = currentMIPS->r[MIPS_REG_V0]; if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", contextID, EventID); if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); - SetMatchingInCallback(context, false); + //SetMatchingInCallback(context, false); DEBUG_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] [cbId: %u][retV0: %08x]", contextID, EventID, call.cbId, v0); //call.setReturnValue(v0); } @@ -1300,13 +1300,11 @@ int friendFinder(){ // Cast Packet SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx; - DEBUG_LOG(SCENET, "FriendFinder: OPCODE_CONNECT"); - // Fix strings with null-terminated packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // Log Incoming Peer - INFO_LOG(SCENET, "Incoming Peer Data..."); + INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT [%s][%s][%s]", mac2str(&packet->mac), inet_ntoa(*(in_addr*)&packet->ip), packet->name.data); // Add User addFriend(packet); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index c1d5fe8b25..4fa39b2690 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -479,12 +479,14 @@ typedef struct SceNetAdhocMatchingContext { SceUID matching_thid; // Event Caller Thread - std::thread eventThread; // s32_le event_thid; + std::thread eventThread; + //s32_le event_thid; bool eventRunning = false; bool IsMatchingInCB = false; // IO Handler Thread - std::thread inputThread; // s32_le input_thid; + std::thread inputThread; + //s32_le input_thid; bool inputRunning = false; // Event Caller Thread Message Stack diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index fbe60def3d..b001caeeed 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -274,7 +274,7 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini // TODO: The correct behavior is actually to allocate more and leak the other threads/pool. // But we reset here for historic reasons (GTA:VCS potentially triggers this.) if (netInited) - sceNetTerm(); // This cleanup attempt might not worked when SaveState were loaded in the middle of multiplayer game and re-entering multiplayer, thus causing memory leaks & wasting binded ports. May be we shouldn't save/load "Inited" vars on SaveState? + Net_Term(); // This cleanup attempt might not worked when SaveState were loaded in the middle of multiplayer game and re-entering multiplayer, thus causing memory leaks & wasting binded ports. May be we shouldn't save/load "Inited" vars on SaveState? if (poolSize == 0) { return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE, "invalid pool size"); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 8c34e64f0d..f12b4444ce 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -585,7 +585,8 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int SceNetAdhocctlPeerInfo * peer = friends; for (; peer != NULL; peer = peer->next) { // Does Skipping sending to timed out friends could cause desync when players moving group at the time MP game started? - //if (peer->last_recv == 0) continue; + if (peer->last_recv == 0) + continue; // Fill in Target Structure sockaddr_in target; @@ -736,10 +737,10 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * *sport = ntohs(sin.sin_port) - portOffset; // Update last recv timestamp, may cause disconnection not detected properly tho - /*peerlock.lock(); + peerlock.lock(); auto peer = findFriend(&mac); if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); - peerlock.unlock();*/ + peerlock.unlock(); } // Free Network Lock @@ -785,10 +786,10 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * *len = received; // Kurok homebrew seems to use the new value of len than returned value as data length // Update last recv timestamp, may cause disconnection not detected properly tho - /*peerlock.lock(); + peerlock.lock(); auto peer = findFriend(&mac); if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); - peerlock.unlock();*/ + peerlock.unlock(); // Free Network Lock //_freeNetworkLock(); @@ -1367,10 +1368,9 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { if (netAdhocctlInited) { // Valid Arguments - if (mac != NULL && nameAddr != 0) + if (mac != NULL && Memory::IsValidAddress(nameAddr)) { - SceNetAdhocctlNickname * nickname = NULL; - if (Memory::IsValidAddress(nameAddr)) nickname = (SceNetAdhocctlNickname *)Memory::GetPointer(nameAddr); + SceNetAdhocctlNickname * nickname = (SceNetAdhocctlNickname *)Memory::GetPointer(nameAddr); // Get Local MAC Address SceNetEtherAddr localmac; getLocalMac(&localmac); @@ -2733,10 +2733,10 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou *len = received; // Update last recv timestamp, may cause disconnection not detected properly tho - /*peerlock.lock(); + peerlock.lock(); auto peer = findFriend(&socket->paddr); if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); - peerlock.unlock();*/ + peerlock.unlock(); char tmpmac[18]; DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u", id, socket->lport, received, mac2str(&socket->paddr, tmpmac), socket->pport); @@ -3209,13 +3209,13 @@ static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, peer->state = PSP_ADHOC_MATCHING_PEER_P2P; }*/ - // Create & Start the Fake PSP Thread + // Create & Start the Fake PSP Thread ("matching_ev%d" and "matching_io%d") std::string thrname = std::string("MatchingThr") + std::to_string(matchingId); - item->matching_thid = __KernelCreateThread(thrname.c_str(), __KernelGetCurThreadModuleId(), matchingThreadHackAddr, evthPri, evthStack, PSP_THREAD_ATTR_USER, 0, false); - //item->matchingThread = new HLEHelperThread(thrname, "sceNetAdhocMatching", "AdhocMatchingFunc", inthPri, inthStack); + item->matching_thid = sceKernelCreateThread(thrname.c_str(), matchingThreadHackAddr, evthPri, evthStack, 0, 0); + //item->matchingThread = new HLEHelperThread(thrname.c_str(), "sceNetAdhocMatching", "__NetMatchingCallbacks", inthPri, inthStack); if (item->matching_thid > 0) { - __KernelStartThread(item->matching_thid, 0, 0); - //item->matchingThread->Start(0, 0); + sceKernelStartThread(item->matching_thid, 0, 0); //sceKernelStartThread(context->event_thid, sizeof(context), &context); + //item->matchingThread->Start(matchingId, 0); } //Create the threads @@ -4029,7 +4029,7 @@ int sceNetAdhocMatchingGetPoolStat(u32 poolstatPtr) { void __NetTriggerCallbacks() { std::lock_guard adhocGuard(adhocEvtMtx); - int delayus = 1000; + int delayus = 10000; auto params = adhocctlEvents.begin(); if (params != adhocctlEvents.end()) @@ -4047,14 +4047,15 @@ void __NetTriggerCallbacks() args[2] = it->second.argument; AfterAdhocMipsCall* after = (AfterAdhocMipsCall*)__KernelCreateAction(actionAfterAdhocMipsCall); after->SetData(it->first, flags, args[2]); - SetAdhocctlInCallback(true); - __KernelDirectMipsCall(it->second.entryPoint, after, args, 3, true); + //SetAdhocctlInCallback(true); + //__KernelDirectMipsCall(it->second.entryPoint, after, args, 3, true); + hleEnqueueCall(it->second.entryPoint, 3, args, after); } adhocctlEvents.pop_front(); if (flags == ADHOCCTL_EVENT_CONNECT) - delayus = (adhocEventDelayMS + 2*adhocExtraPollDelayMS) * 1000; + delayus = (adhocEventDelayMS + 2*adhocExtraPollDelayMS) * 1000; // May affects Dissidia 012 and GTA VCS else - delayus = (adhocEventPollDelayMS + 2*adhocExtraPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection + delayus = (adhocEventPollDelayMS + 2*adhocExtraPollDelayMS) * 1000; // Added an extra delay to prevent I/O Timing method from causing disconnection } } @@ -4062,10 +4063,10 @@ void __NetTriggerCallbacks() hleDelayResult(0, "Prevent Adhocctl thread from blocking", delayus); } -void __NetMatchingCallbacks() +void __NetMatchingCallbacks() //(int matchingId) { std::lock_guard adhocGuard(adhocEvtMtx); - int delayus = 1000; + int delayus = 10000; auto params = matchingEvents.begin(); if (params != matchingEvents.end()) @@ -4079,9 +4080,10 @@ void __NetMatchingCallbacks() AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); after->SetData(args[0], args[1], args[2]); //SetMatchingInCallback(context, true); - __KernelDirectMipsCall(args[5], after, args, 5, true); + //__KernelDirectMipsCall(args[5], after, args, 5, true); + hleEnqueueCall(args[5], 5, args, after); matchingEvents.pop_front(); - delayus = (adhocMatchingEventDelayMS + 2*adhocExtraPollDelayMS) * 1000; //Added an extra delay to prevent I/O Timing method from causing disconnection + delayus = (adhocMatchingEventDelayMS + 2*adhocExtraPollDelayMS) * 1000; // Added an extra delay to prevent I/O Timing method from causing disconnection } } @@ -4175,7 +4177,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { // Multithreading Lock peerlock.lock(); - bool excludeTimedout = false; //true; + bool excludeTimedout = true; // Length Calculation Mode if (buf == NULL) { int activePeers = getActivePeerCount(excludeTimedout); @@ -5457,7 +5459,7 @@ int matchingEventThread(int matchingId) } // Share CPU Time - sleep_ms(1); //10 //sceKernelDelayThread(10000); + sleep_ms(10); //1 //sceKernelDelayThread(10000); // Don't do anything if it's paused, otherwise the log will be flooded while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->eventRunning) sleep_ms(1); @@ -5688,7 +5690,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi handleTimeout(context); } // Share CPU Time - sleep_ms(1); //10 //sceKernelDelayThread(10000); + sleep_ms(10); //1 //sceKernelDelayThread(10000); // Don't do anything if it's paused, otherwise the log will be flooded while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->inputRunning) sleep_ms(1); From 6695001b94332be30d9220f8d9280b79874213d7 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 25 May 2020 11:59:39 +0700 Subject: [PATCH 351/848] Fix timeout comparison --- Core/HLE/sceNetAdhoc.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index f12b4444ce..c69dd24dab 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -753,9 +753,9 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * if (flag == 0) { // Simulate blocking behaviour with non-blocking socket - uint32_t starttime = (uint32_t)(real_time_now() * 1000.0); + uint32_t starttime = (uint32_t)(real_time_now() * 1000000.0); // Wait for Connection. On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound), may need to disable SIO_UDP_CONNRESET - while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && (connectInProgress(error) || error == ECONNRESET)) { + while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && (connectInProgress(error) || error == ECONNRESET)) { received = recvfrom(socket->id, (char*)buf, *len, 0, (sockaddr*)&sin, &sinlen); error = errno; // Wait 1ms @@ -2096,10 +2096,10 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Blocking Behaviour if (!flag && newsocket == SOCKET_ERROR) { // Get Start Time - uint32_t starttime = (uint32_t)(real_time_now()*1000.0); + uint32_t starttime = (uint32_t)(real_time_now()*1000000.0); // Retry until Timeout hits - while ((timeout == 0 || ((uint32_t)(real_time_now()*1000.0) - starttime) < (uint32_t)timeout) && (newsocket == SOCKET_ERROR) && connectInProgress(error)) { + while ((timeout == 0 || ((uint32_t)(real_time_now()*1000000.0) - starttime) < (uint32_t)timeout) && (newsocket == SOCKET_ERROR) && connectInProgress(error)) { // Accept Connection newsocket = accept(socket->id, (sockaddr *)&peeraddr, &peeraddrlen); error = errno; @@ -2314,14 +2314,14 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Blocking Mode else { // Grab Connection Start Time - uint32_t starttime = (uint32_t)(real_time_now()*1000.0); + uint32_t starttime = (uint32_t)(real_time_now()*1000000.0); // Peer Information (for Connection-Polling) sockaddr_in peer; memset(&peer, 0, sizeof(peer)); socklen_t peerlen = sizeof(peer); // Wait for Connection - while ((timeout == 0 || ( (uint32_t)(real_time_now()*1000.0) - starttime) < (uint32_t)timeout) && getpeername(socket->id, (sockaddr *)&peer, &peerlen) != 0) { + while ((timeout == 0 || ( (uint32_t)(real_time_now()*1000000.0) - starttime) < (uint32_t)timeout) && getpeername(socket->id, (sockaddr *)&peer, &peerlen) != 0) { // Wait 1ms sleep_ms(1); } @@ -2709,9 +2709,9 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou if (flag == 0) { // Simulate blocking behaviour with non-blocking socket - uint32_t starttime = (uint32_t)(real_time_now() * 1000.0); + uint32_t starttime = (uint32_t)(real_time_now() * 1000000.0); // Wait for Connection - while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && connectInProgress(error)) { + while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && connectInProgress(error)) { received = recv(socket->id, (char*)buf, *len, 0); error = errno; // Wait 1ms From de439f8cd78573dccd4b70ddce1e40101f99c7ad Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 22 Jul 2020 23:59:09 -0700 Subject: [PATCH 352/848] Correct a crash on a missing kernel object. --- Core/HLE/sceKernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 787804912f..9e2a8ff3ac 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -468,7 +468,7 @@ public: // see the Wrong type object error below, but we'll just have to live with that danger. T* t = static_cast(pool[handle - handleOffset]); if (t == nullptr || t->GetIDType() != T::GetStaticIDType()) { - WARN_LOG(SCEKERNEL, "Kernel: Wrong object type for %d (%08x), was %s, should have been %s", handle, handle, t->GetTypeName(), T::GetStaticTypeName()); + WARN_LOG(SCEKERNEL, "Kernel: Wrong object type for %d (%08x), was %s, should have been %s", handle, handle, t ? t->GetTypeName() : "null", T::GetStaticTypeName()); outError = T::GetMissingErrorCode(); return 0; } From 68ac1d306dba69cf4a4484c5fdaca276c229c91a Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 26 Mar 2020 15:01:41 +0700 Subject: [PATCH 353/848] Fix issue when loading save state created from previous test version --- Core/HLE/proAdhoc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 4fa39b2690..ceb78319b1 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -789,7 +789,7 @@ public: AfterAdhocMipsCall() {} static PSPAction* Create() { return new AfterAdhocMipsCall(); } void DoState(PointerWrap& p) override { - auto s = p.Section("AfterAdhocMipsCall", 4, 4); + auto s = p.Section("AfterAdhocMipsCall", 3, 4); if (!s) return; From a0f0973462d6d91d905e56b251e403b952e565b3 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 12 Jul 2020 08:04:55 +0700 Subject: [PATCH 354/848] Reconnect to Adhoc Server when disconnected while still having the AdhocCtl Inited (ie. due to timeout or network failure) so players doesn't need to reset the game to reconnect. --- Core/HLE/proAdhoc.cpp | 477 ++++++++++++++++++++------------------- Core/HLE/proAdhoc.h | 4 + Core/HLE/sceNetAdhoc.cpp | 42 ++-- Core/HLE/sceNetAdhoc.h | 1 + 4 files changed, 267 insertions(+), 257 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 49806c1ce5..33d2c1c3c3 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1182,280 +1182,293 @@ int friendFinder(){ // Acquire Network Lock //_acquireNetworkLock(); - // Ping Server - now = real_time_now() * 1000000.0; // Use real_time_now()*1000000.0 instead of CoreTiming::GetGlobalTimeUsScaled() if the game gets disconnected from AdhocServer too soon when FPS wasn't stable - if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { // We may need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet - // original code : ((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT) - // Update Ping Time - lastping = now; - - // Prepare Packet - uint8_t opcode = OPCODE_PING; - - // Send Ping to Server, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) - int iResult = send(metasocket, (const char *)&opcode, 1, 0); - /*if (iResult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "FriendFinder: Socket Error (%i) when sending OPCODE_PING", errno); - //friendFinderRunning = false; - }*/ + // Reconnect when disconnected while Adhocctl is still inited + if (metasocket == (int)INVALID_SOCKET && netAdhocctlInited) { + if (g_Config.bEnableWlan && initNetwork(&product_code) == 0) { + networkInited = true; + } } - // Wait for Incoming Data - int received = recv(metasocket, (char *)(rx + rxpos), sizeof(rx) - rxpos, 0); + if (networkInited) { + // Ping Server + now = real_time_now() * 1000000.0; // Use real_time_now()*1000000.0 instead of CoreTiming::GetGlobalTimeUsScaled() if the game gets disconnected from AdhocServer too soon when FPS wasn't stable + if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { // We may need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet + // original code : ((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT) + // Update Ping Time + lastping = now; - // Free Network Lock - //_freeNetworkLock(); + // Prepare Packet + uint8_t opcode = OPCODE_PING; - // Received Data - if (received > 0) { - // Fix Position - rxpos += received; - - // Log Incoming Traffic - //printf("Received %d Bytes of Data from Server\n", received); - INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received); - } - - // Handle Packets - if (rxpos > 0) { - // BSSID Packet - if (rx[0] == OPCODE_CONNECT_BSSID) { - // Enough Data available - if (rxpos >= (int)sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) { - // Cast Packet - SceNetAdhocctlConnectBSSIDPacketS2C * packet = (SceNetAdhocctlConnectBSSIDPacketS2C *)rx; - - char tmpmac[18]; - INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac, tmpmac)); - // From JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?) - /*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { - setState(ADHOCCTL_STATE_GAMEMODE); - notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0); - } - else { - setState(ADHOCCTL_STATE_CONNECTED); - notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); - }*/ - - // Update User BSSID - parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address - // Notify Event Handlers - //notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); - // Change State - threadStatus = ADHOCCTL_STATE_CONNECTED; - // Give time a little time - //sceKernelDelayThread(adhocEventDelayMS * 1000); - //sleep_ms(adhocEventDelayMS); - - // Move RX Buffer - memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)); - - // Fix RX Buffer Length - rxpos -= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C); + // Send Ping to Server, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) + int iResult = send(metasocket, (const char*)&opcode, 1, 0); + if (iResult == SOCKET_ERROR) { + ERROR_LOG(SCENET, "FriendFinder: Socket Error (%i) when sending OPCODE_PING", errno); + networkInited = false; + shutdown(metasocket, SD_BOTH); + closesocket(metasocket); + metasocket = (int)INVALID_SOCKET; } } - // Chat Packet - else if (rx[0] == OPCODE_CHAT) { - // Enough Data available - if (rxpos >= (int)sizeof(SceNetAdhocctlChatPacketS2C)) { - // Cast Packet - SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx; - INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CHAT"); - - // Fix strings with null-terminated - packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; - packet->base.message[ADHOCCTL_MESSAGE_LEN - 1] = 0; + // Wait for Incoming Data + int received = recv(metasocket, (char*)(rx + rxpos), sizeof(rx) - rxpos, 0); - // Add Incoming Chat to HUD - NOTICE_LOG(SCENET, "Received chat message %s", packet->base.message); - incoming = ""; - name = (char *)packet->name.data; - incoming.append(name.substr(0, 8)); - incoming.append(": "); - incoming.append((char *)packet->base.message); - chatLog.push_back(incoming); - //im new to pointer btw :( doesn't know its safe or not this should update the chat screen when data coming - if (chatScreenVisible) { - updateChatScreen = true; - } - else { - if (newChat < 50) { - newChat += 1; + // Free Network Lock + //_freeNetworkLock(); + + // Received Data + if (received > 0) { + // Fix Position + rxpos += received; + + // Log Incoming Traffic + //printf("Received %d Bytes of Data from Server\n", received); + INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received); + } + + // Handle Packets + if (rxpos > 0) { + // BSSID Packet + if (rx[0] == OPCODE_CONNECT_BSSID) { + // Enough Data available + if (rxpos >= (int)sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) { + // Cast Packet + SceNetAdhocctlConnectBSSIDPacketS2C* packet = (SceNetAdhocctlConnectBSSIDPacketS2C*)rx; + + char tmpmac[18]; + INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac, tmpmac)); + // From JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?) + /*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { + setState(ADHOCCTL_STATE_GAMEMODE); + notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0); } + else { + setState(ADHOCCTL_STATE_CONNECTED); + notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); + }*/ + + // Update User BSSID + parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address + // Notify Event Handlers + //notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); + // Change State + threadStatus = ADHOCCTL_STATE_CONNECTED; + // Give time a little time + //sceKernelDelayThread(adhocEventDelayMS * 1000); + //sleep_ms(adhocEventDelayMS); + + // Move RX Buffer + memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)); + + // Fix RX Buffer Length + rxpos -= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C); } - - // Move RX Buffer - memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C)); - - // Fix RX Buffer Length - rxpos -= sizeof(SceNetAdhocctlChatPacketS2C); } - } - // Connect Packet - else if (rx[0] == OPCODE_CONNECT) { - // Enough Data available - if (rxpos >= (int)sizeof(SceNetAdhocctlConnectPacketS2C)) { - // Cast Packet - SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx; + // Chat Packet + else if (rx[0] == OPCODE_CHAT) { + // Enough Data available + if (rxpos >= (int)sizeof(SceNetAdhocctlChatPacketS2C)) { + // Cast Packet + SceNetAdhocctlChatPacketS2C* packet = (SceNetAdhocctlChatPacketS2C*)rx; + INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CHAT"); - // Fix strings with null-terminated - packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; + // Fix strings with null-terminated + packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; + packet->base.message[ADHOCCTL_MESSAGE_LEN - 1] = 0; - // Log Incoming Peer - INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT [%s][%s][%s]", mac2str(&packet->mac), inet_ntoa(*(in_addr*)&packet->ip), packet->name.data); + // Add Incoming Chat to HUD + NOTICE_LOG(SCENET, "Received chat message %s", packet->base.message); + incoming = ""; + name = (char*)packet->name.data; + incoming.append(name.substr(0, 8)); + incoming.append(": "); + incoming.append((char*)packet->base.message); + chatLog.push_back(incoming); + //im new to pointer btw :( doesn't know its safe or not this should update the chat screen when data coming + if (chatScreenVisible) { + updateChatScreen = true; + } + else { + if (newChat < 50) { + newChat += 1; + } + } - // Add User - addFriend(packet); + // Move RX Buffer + memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C)); - /* // Make sure GameMode participants are all joined (including self MAC) - if (adhocctlCurrentMode == PSP_ADHOCCTL_MODE_GAMEMODE) { - // From JPCSP: Join complete when all the required MACs have joined - }*/ - - // Update HUD User Count - incoming = ""; - incoming.append((char *)packet->name.data); - incoming.append(" Joined "); - //do we need ip? - //joined.append((char *)packet->ip); - chatLog.push_back(incoming); - //im new to pointer btw :( doesn't know its safe or not this should update the chat screen when data coming - if (chatScreenVisible) { - updateChatScreen = true; + // Fix RX Buffer Length + rxpos -= sizeof(SceNetAdhocctlChatPacketS2C); } - + } + + // Connect Packet + else if (rx[0] == OPCODE_CONNECT) { + // Enough Data available + if (rxpos >= (int)sizeof(SceNetAdhocctlConnectPacketS2C)) { + // Cast Packet + SceNetAdhocctlConnectPacketS2C* packet = (SceNetAdhocctlConnectPacketS2C*)rx; + + // Fix strings with null-terminated + packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; + + // Log Incoming Peer + u32_le ipaddr = packet->ip; + INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT [%s][%s][%s]", mac2str(&packet->mac), inet_ntoa(*(in_addr*)&ipaddr), packet->name.data); + + // Add User + addFriend(packet); + + /* // Make sure GameMode participants are all joined (including self MAC) + if (adhocctlCurrentMode == PSP_ADHOCCTL_MODE_GAMEMODE) { + // From JPCSP: Join complete when all the required MACs have joined + }*/ + + // Update HUD User Count + incoming = ""; + incoming.append((char*)packet->name.data); + incoming.append(" Joined "); + //do we need ip? + //joined.append((char *)packet->ip); + chatLog.push_back(incoming); + //im new to pointer btw :( doesn't know its safe or not this should update the chat screen when data coming + if (chatScreenVisible) { + updateChatScreen = true; + } + #ifdef LOCALHOST_AS_PEER - setUserCount(getActivePeerCount()); + setUserCount(getActivePeerCount()); #else - // setUserCount(getActivePeerCount()+1); + // setUserCount(getActivePeerCount()+1); #endif // Move RX Buffer - memmove(rx, rx + sizeof(SceNetAdhocctlConnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectPacketS2C)); + memmove(rx, rx + sizeof(SceNetAdhocctlConnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectPacketS2C)); - // Fix RX Buffer Length - rxpos -= sizeof(SceNetAdhocctlConnectPacketS2C); + // Fix RX Buffer Length + rxpos -= sizeof(SceNetAdhocctlConnectPacketS2C); + } } - } - // Disconnect Packet - else if (rx[0] == OPCODE_DISCONNECT) { - // Enough Data available - if (rxpos >= (int)sizeof(SceNetAdhocctlDisconnectPacketS2C)) { - // Cast Packet - SceNetAdhocctlDisconnectPacketS2C * packet = (SceNetAdhocctlDisconnectPacketS2C *)rx; + // Disconnect Packet + else if (rx[0] == OPCODE_DISCONNECT) { + // Enough Data available + if (rxpos >= (int)sizeof(SceNetAdhocctlDisconnectPacketS2C)) { + // Cast Packet + SceNetAdhocctlDisconnectPacketS2C* packet = (SceNetAdhocctlDisconnectPacketS2C*)rx; - DEBUG_LOG(SCENET, "FriendFinder: OPCODE_DISCONNECT"); + DEBUG_LOG(SCENET, "FriendFinder: OPCODE_DISCONNECT"); - // Log Incoming Peer Delete Request - INFO_LOG(SCENET, "FriendFinder: Incoming Peer Data Delete Request..."); + // Log Incoming Peer Delete Request + INFO_LOG(SCENET, "FriendFinder: Incoming Peer Data Delete Request..."); - // Delete User by IP, should delete by MAC since IP can be shared (behind NAT) isn't? - deleteFriendByIP(packet->ip); + // Delete User by IP, should delete by MAC since IP can be shared (behind NAT) isn't? + deleteFriendByIP(packet->ip); - // Update HUD User Count + // Update HUD User Count #ifdef LOCALHOST_AS_PEER - setUserCount(_getActivePeerCount()); + setUserCount(_getActivePeerCount()); #else //setUserCount(_getActivePeerCount()+1); #endif // Move RX Buffer - memmove(rx, rx + sizeof(SceNetAdhocctlDisconnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlDisconnectPacketS2C)); + memmove(rx, rx + sizeof(SceNetAdhocctlDisconnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlDisconnectPacketS2C)); - // Fix RX Buffer Length - rxpos -= sizeof(SceNetAdhocctlDisconnectPacketS2C); - } - } - - // Scan Packet - else if (rx[0] == OPCODE_SCAN) { - // Enough Data available - if (rxpos >= (int)sizeof(SceNetAdhocctlScanPacketS2C)) { - // Cast Packet - SceNetAdhocctlScanPacketS2C * packet = (SceNetAdhocctlScanPacketS2C *)rx; - - DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN"); - - // Log Incoming Network Information - INFO_LOG(SCENET, "Incoming Group Information..."); - - // Multithreading Lock - peerlock.lock(); - - // Allocate Structure Data - SceNetAdhocctlScanInfo* group = (SceNetAdhocctlScanInfo*)malloc(sizeof(SceNetAdhocctlScanInfo)); - - // Allocated Structure Data - if (group != NULL) { - // Clear Memory, should this be done only when allocating new group? - memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); - - // Link to existing Groups - group->next = newnetworks; - - // Copy Group Name - group->group_name = packet->group; - - // Set Group Host - group->bssid.mac_addr = packet->mac; - - // Set group parameters - // Since 0 is not a valid active channel we fake the channel for Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?) - group->channel = parameter.channel; //(parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) ? defaultWlanChannel : parameter.channel; - group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode; - - // Link into Group List - newnetworks = group; + // Fix RX Buffer Length + rxpos -= sizeof(SceNetAdhocctlDisconnectPacketS2C); } + } - // Multithreading Unlock + // Scan Packet + else if (rx[0] == OPCODE_SCAN) { + // Enough Data available + if (rxpos >= (int)sizeof(SceNetAdhocctlScanPacketS2C)) { + // Cast Packet + SceNetAdhocctlScanPacketS2C* packet = (SceNetAdhocctlScanPacketS2C*)rx; + + DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN"); + + // Log Incoming Network Information + INFO_LOG(SCENET, "Incoming Group Information..."); + + // Multithreading Lock + peerlock.lock(); + + // Allocate Structure Data + SceNetAdhocctlScanInfo* group = (SceNetAdhocctlScanInfo*)malloc(sizeof(SceNetAdhocctlScanInfo)); + + // Allocated Structure Data + if (group != NULL) { + // Clear Memory, should this be done only when allocating new group? + memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); + + // Link to existing Groups + group->next = newnetworks; + + // Copy Group Name + group->group_name = packet->group; + + // Set Group Host + group->bssid.mac_addr = packet->mac; + + // Set group parameters + // Since 0 is not a valid active channel we fake the channel for Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?) + group->channel = parameter.channel; //(parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) ? defaultWlanChannel : parameter.channel; + group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode; + + // Link into Group List + newnetworks = group; + } + + // Multithreading Unlock + peerlock.unlock(); + + // Move RX Buffer + memmove(rx, rx + sizeof(SceNetAdhocctlScanPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlScanPacketS2C)); + + // Fix RX Buffer Length + rxpos -= sizeof(SceNetAdhocctlScanPacketS2C); + } + } + + // Scan Complete Packet + else if (rx[0] == OPCODE_SCAN_COMPLETE) { + DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN_COMPLETE"); + // Log Scan Completion + INFO_LOG(SCENET, "FriendFinder: Incoming Scan complete response..."); + + // Reset current networks to prevent disbanded host to be listed again + peerlock.lock(); + if (networks != newnetworks) { + freeGroupsRecursive(networks); + networks = newnetworks; + } + newnetworks = NULL; peerlock.unlock(); + // Notify Event Handlers + //notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); + //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) + //{ + // // Active Handler + // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); + //} + // Change State + threadStatus = ADHOCCTL_STATE_DISCONNECTED; + // Give time a little time + //sceKernelDelayThread(adhocEventDelayMS * 1000); + //sleep_ms(adhocEventDelayMS); + // Move RX Buffer - memmove(rx, rx + sizeof(SceNetAdhocctlScanPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlScanPacketS2C)); + memmove(rx, rx + 1, sizeof(rx) - 1); // Fix RX Buffer Length - rxpos -= sizeof(SceNetAdhocctlScanPacketS2C); + rxpos -= 1; } } - - // Scan Complete Packet - else if (rx[0] == OPCODE_SCAN_COMPLETE) { - DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN_COMPLETE"); - // Log Scan Completion - INFO_LOG(SCENET, "FriendFinder: Incoming Scan complete response..."); - - // Reset current networks to prevent disbanded host to be listed again - peerlock.lock(); - if (networks != newnetworks) { - freeGroupsRecursive(networks); - networks = newnetworks; - } - newnetworks = NULL; - peerlock.unlock(); - - // Notify Event Handlers - //notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); - //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) - //{ - // // Active Handler - // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); - //} - // Change State - threadStatus = ADHOCCTL_STATE_DISCONNECTED; - // Give time a little time - //sceKernelDelayThread(adhocEventDelayMS * 1000); - //sleep_ms(adhocEventDelayMS); - - // Move RX Buffer - memmove(rx, rx + 1, sizeof(rx) - 1); - - // Fix RX Buffer Length - rxpos -= 1; - } } // This delay time should be 100ms when there is an event otherwise 500ms ? sleep_ms(1); // Using 1ms for faster response just like AdhocServer? @@ -1795,7 +1808,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ iResult = getaddrinfo(g_Config.proAdhocServer.c_str(),0,NULL,&resultAddr); if (iResult != 0) { ERROR_LOG(SCENET, "DNS Error (%s)\n", g_Config.proAdhocServer.c_str()); - host->NotifyUserMessage(n->T("DNS Error connecting to ") + g_Config.proAdhocServer, 5.0f, 0x0000ff); + host->NotifyUserMessage(n->T("DNS Error connecting to ") + g_Config.proAdhocServer, 2.0f, 0x0000ff); return iResult; } for (ptr = resultAddr; ptr != NULL; ptr = ptr->ai_next) { @@ -1820,7 +1833,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ iResult = bind(metasocket, (struct sockaddr*) & LocalhostIP, sizeof(sockaddr)); if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "Bind to alternate localhost[%s] failed(%i).", inet_ntoa(((struct sockaddr_in*) & LocalhostIP)->sin_addr), iResult); - host->NotifyUserMessage(std::string(n->T("Failed to Bind Localhost IP")) + " " + inet_ntoa(((struct sockaddr_in*) & LocalhostIP)->sin_addr), 3.0, 0x0000ff); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Localhost IP")) + " " + inet_ntoa(((struct sockaddr_in*) & LocalhostIP)->sin_addr), 2.0, 0x0000ff); } } @@ -1853,7 +1866,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ char buffer[512]; snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); ERROR_LOG(SCENET, "%s", buffer); - host->NotifyUserMessage(n->T("Failed to connect to Adhoc Server"), 6.0f, 0x0000ff); + host->NotifyUserMessage(n->T("Failed to connect to Adhoc Server"), 1.0f, 0x0000ff); return iResult; } diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index ceb78319b1..a14e570746 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -97,6 +97,10 @@ inline bool connectInProgress(int errcode){ return (errcode == EAGAIN || errcode #define POLLPRI POLL_PRI #endif +#ifndef SD_BOTH +#define SD_BOTH 0x02 +#endif + #define IsMatch(buf1, buf2) (memcmp(&buf1, &buf2, sizeof(buf1)) == 0) // Server Listening Port diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index c69dd24dab..1a3859bb92 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -57,7 +57,7 @@ // TODO: Make accessor functions instead, and throw all this state in a struct. bool netAdhocInited; bool netAdhocctlInited; -bool networkInited; +bool networkInited = false; static bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; @@ -238,34 +238,25 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { if (netAdhocctlInited) return ERROR_NET_ADHOCCTL_ALREADY_INITIALIZED; + if (Memory::IsValidAddress(productAddr)) { + Memory::ReadStruct(productAddr, &product_code); + } + // Create fake PSP Thread for callback // TODO: Should use a separated threads for friendFinder, matchingEvent, and matchingInput and created on AdhocctlInit & AdhocMatchingStart instead of here threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, prio, stackSize, PSP_THREAD_ATTR_USER, 0, true); if (threadAdhocID > 0) { __KernelStartThread(threadAdhocID, 0, 0); } - - if(g_Config.bEnableWlan) { - SceNetAdhocctlAdhocId* product = NULL; - if (Memory::IsValidAddress(productAddr)) product = (SceNetAdhocctlAdhocId*)Memory::GetPointer(productAddr); - if (initNetwork(product) == 0) { - // TODO: Merging friendFinder (real) thread to AdhocThread (fake) thread on PSP side - if (!friendFinderRunning) { - friendFinderRunning = true; - friendFinderThread = std::thread(friendFinder); - } - networkInited = true; - - sleep_ms(adhocEventPollDelayMS); - //hleDelayResult(0, "give some time", adhocEventPollDelayMS * 1000); // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? - } else { - WARN_LOG(SCENET, "sceNetAdhocctlInit: Failed to init the network but faking success"); - networkInited = false; // TODO: What needs to check this? Pretty much everything? Maybe we should just set netAdhocctlInited to false.. - } + // TODO: Merging friendFinder (real) thread to AdhocThread (fake) thread on PSP side + if (!friendFinderRunning) { + friendFinderRunning = true; + friendFinderThread = std::thread(friendFinder); } netAdhocctlInited = true; //needed for cleanup during AdhocctlTerm even when it failed to connect to Adhoc Server (since it's being faked as success) + //hleDelayResult(0, "give some time", adhocEventPollDelayMS * 1000); // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? return 0; } @@ -1321,13 +1312,12 @@ int NetAdhocctl_Term() { if (threadStatus != ADHOCCTL_STATE_DISCONNECTED) NetAdhocctl_Disconnect(); - if (networkInited) { - // Terminate Adhoc Threads - friendFinderRunning = false; - if (friendFinderThread.joinable()) { - friendFinderThread.join(); - } + // Terminate Adhoc Threads + friendFinderRunning = false; + if (friendFinderThread.joinable()) { + friendFinderThread.join(); } + // Clear Peer List int32_t peercount = 0; freeFriendsRecursive(friends, &peercount); @@ -1337,6 +1327,8 @@ int NetAdhocctl_Term() { //May also need to clear Handlers adhocctlHandlers.clear(); // Free stuff here + networkInited = false; + shutdown(metasocket, SD_BOTH); closesocket(metasocket); metasocket = (int)INVALID_SOCKET; // Delete fake PSP Thread diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 0577caac50..75f8b71541 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -46,6 +46,7 @@ int sceNetAdhocctlCreate(const char * groupName); // May need to use these from sceNet.cpp extern bool netAdhocInited; extern bool netAdhocctlInited; +extern bool networkInited; extern int adhocDefaultTimeout; extern int adhocEventPollDelayMS; extern int adhocMatchingEventDelayMS; From d078a73278284663b4cb61c580671f206775ac36 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 13 Jul 2020 03:40:17 +0700 Subject: [PATCH 355/848] Need to make sure already connected to Adhoc Server before Creating/Joining a group. (Fix GTA VCS failed to join a group and unable to see any room) --- Core/HLE/sceNetAdhoc.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 1a3859bb92..40803220cd 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -242,6 +242,8 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { Memory::ReadStruct(productAddr, &product_code); } + netAdhocctlInited = true; //needed for cleanup during AdhocctlTerm even when it failed to connect to Adhoc Server (since it's being faked as success) + // Create fake PSP Thread for callback // TODO: Should use a separated threads for friendFinder, matchingEvent, and matchingInput and created on AdhocctlInit & AdhocMatchingStart instead of here threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, prio, stackSize, PSP_THREAD_ATTR_USER, 0, true); @@ -254,8 +256,14 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { friendFinderRunning = true; friendFinderThread = std::thread(friendFinder); } + + // Need to make sure to be connected to adhoc server before returning to prevent GTA VCS failed to create/join a group and unable to see any game room + int cnt = 0; + while (g_Config.bEnableWlan && !networkInited && (cnt < adhocDefaultTimeout)) { + sleep_ms(1); + cnt++; + } - netAdhocctlInited = true; //needed for cleanup during AdhocctlTerm even when it failed to connect to Adhoc Server (since it's being faked as success) //hleDelayResult(0, "give some time", adhocEventPollDelayMS * 1000); // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? return 0; } From 596fad3f424c05550a1fb664440c40409ba4eac6 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 17 Jul 2020 08:54:37 +0700 Subject: [PATCH 356/848] Provides quick IP fill on Adhoc Server IP address setting to makes player's life easier :) --- UI/GameSettingsScreen.cpp | 71 ++++++++++++++++++++++---- UI/GameSettingsScreen.h | 4 ++ ext/native/net/resolve.cpp | 100 +++++++++++++++++++++++++++++++++++++ ext/native/net/resolve.h | 2 + 4 files changed, 166 insertions(+), 11 deletions(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 9d1012f97b..0aaff82ee0 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -688,7 +688,7 @@ void GameSettingsScreen::CreateViews() { networkingSettings->Add(new CheckBox(&g_Config.bEnableWlan, n->T("Enable networking", "Enable networking/wlan (beta)"))); networkingSettings->Add(new CheckBox(&g_Config.bDiscordPresence, n->T("Send Discord Presence information"))); - networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.proAdhocServer, n->T("Change proAdhocServer Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeproAdhocServerAddress); + networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.proAdhocServer, n->T("Change proAdhocServer Address (localhost = multiple instance)"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeproAdhocServerAddress); networkingSettings->Add(new CheckBox(&g_Config.bEnableAdhocServer, n->T("Enable built-in PRO Adhoc Server", "Enable built-in PRO Adhoc Server"))); networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress); static const char* wlanChannels[] = { "Auto", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" }; @@ -1391,17 +1391,9 @@ UI::EventReturn GameSettingsScreen::OnChangeNickname(UI::EventParams &e) { } UI::EventReturn GameSettingsScreen::OnChangeproAdhocServerAddress(UI::EventParams &e) { - auto sy = GetI18NCategory("System"); + auto n = GetI18NCategory("Networking"); -#if defined(__ANDROID__) - System_InputBoxGetString(sy->T("proAdhocServer Address:"), g_Config.proAdhocServer, [](bool result, const std::string &value) { - if (result) { - g_Config.proAdhocServer = value; - } - }); -#else - screenManager()->push(new HostnameSelectScreen(&g_Config.proAdhocServer, sy->T("proAdhocServer Address:"))); -#endif + screenManager()->push(new HostnameSelectScreen(&g_Config.proAdhocServer, n->T("proAdhocServer Address:"))); return UI::EVENT_DONE; } @@ -1698,10 +1690,35 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) { buttonsRow1->Add(new Spacer(new LinearLayoutParams(1.0, G_RIGHT))); buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, G_LEFT))); +#if defined(__ANDROID__) + buttonsRow2->Add(new Button(di->T("Edit")))->OnClick.Handle(this, &HostnameSelectScreen::OnEditClick); // Since we don't have OnClick Event triggered from TextEdit's Touch().. here we go! +#endif buttonsRow2->Add(new Button(di->T("Delete")))->OnClick.Handle(this, &HostnameSelectScreen::OnDeleteClick); buttonsRow2->Add(new Button(di->T("Delete all")))->OnClick.Handle(this, &HostnameSelectScreen::OnDeleteAllClick); + buttonsRow2->Add(new Button(di->T("Toggle List")))->OnClick.Handle(this, &HostnameSelectScreen::OnShowIPListClick); buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, G_RIGHT))); + std::vector listIP = {"localhost","myneighborsushicat.com"}; + net::GetIPList(listIP); + ipRows_ = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0)); + ScrollView* scrollView = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + LinearLayout* innerView = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + if (listIP.size() > 0) { + for (const auto& label : listIP) { + // Filter out IP prefixed with "127." and "169.254." also "0." since they can be rendundant or unusable + if (label.find("127.") != 0 && label.find("169.254.") != 0 && label.find("0.") != 0) { + auto button = innerView->Add(new Button(label, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + button->OnClick.Handle(this, &HostnameSelectScreen::OnIPClick); + button->SetTag(label); + } + } + } + scrollView->Add(innerView); + ipRows_->Add(scrollView); + ipRows_->SetVisibility(V_GONE); + parent->Add(ipRows_); + listIP.clear(); listIP.shrink_to_fit(); + errorView_ = parent->Add(new TextView(n->T("Invalid IP or hostname"), ALIGN_HCENTER, false, new LinearLayoutParams(Margins(0, 10, 0, 0)))); errorView_->SetTextColor(0xFF3030FF); errorView_->SetVisibility(V_GONE); @@ -1741,6 +1758,38 @@ UI::EventReturn HostnameSelectScreen::OnDeleteAllClick(UI::EventParams &e) { return UI::EVENT_DONE; } +UI::EventReturn HostnameSelectScreen::OnEditClick(UI::EventParams& e) { + auto n = GetI18NCategory("Networking"); +#if defined(__ANDROID__) + System_InputBoxGetString(n->T("proAdhocServer Address:"), addrView_->GetText(), [this](bool result, const std::string& value) { + if (result) { + addrView_->SetText(value); + } + }); +#endif + return UI::EVENT_DONE; +} + +UI::EventReturn HostnameSelectScreen::OnShowIPListClick(UI::EventParams& e) { + if (ipRows_->GetVisibility() == UI::V_GONE) { + ipRows_->SetVisibility(UI::V_VISIBLE); + } + else { + ipRows_->SetVisibility(UI::V_GONE); + } + return UI::EVENT_DONE; +} + +UI::EventReturn HostnameSelectScreen::OnIPClick(UI::EventParams& e) { + std::string text = e.v ? e.v->Tag() : ""; + if (text.length() > 0) { + addrView_->SetText(text); + // TODO: Copy the IP to clipboard for the host to easily share their IP through chatting apps. + System_SendMessage("setclipboardtext", text.c_str()); // Doesn't seems to be working on windows (yet?) + } + return UI::EVENT_DONE; +} + void HostnameSelectScreen::ResolverThread() { std::unique_lock guard(resolverLock_); diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index cfcd7fae27..2279b620ce 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -208,6 +208,9 @@ private: UI::EventReturn OnPointClick(UI::EventParams &e); UI::EventReturn OnDeleteClick(UI::EventParams &e); UI::EventReturn OnDeleteAllClick(UI::EventParams &e); + UI::EventReturn OnEditClick(UI::EventParams& e); + UI::EventReturn OnShowIPListClick(UI::EventParams& e); + UI::EventReturn OnIPClick(UI::EventParams& e); enum class ResolverState { WAITING, @@ -221,6 +224,7 @@ private: UI::TextEdit *addrView_ = nullptr; UI::TextView *errorView_ = nullptr; UI::TextView *progressView_ = nullptr; + UI::LinearLayout *ipRows_ = nullptr; std::thread resolver_; ResolverState resolverState_ = ResolverState::WAITING; diff --git a/ext/native/net/resolve.cpp b/ext/native/net/resolve.cpp index a5bd024c7a..c4fc78fc62 100644 --- a/ext/native/net/resolve.cpp +++ b/ext/native/net/resolve.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef _WIN32 @@ -101,6 +102,105 @@ void DNSResolveFree(addrinfo *res) freeaddrinfo(res); } +bool GetIPList(std::vector& IP4s) { + char ipstr[INET6_ADDRSTRLEN]; // We use IPv6 length since it's longer than IPv4 +#if defined(getifaddrs) // On Android: Requires __ANDROID_API__ >= 24 + struct ifaddrs* ifAddrStruct = NULL; + struct ifaddrs* ifa = NULL; + + getifaddrs(&ifAddrStruct); + if (ifAddrStruct != NULL) { + for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { + if (!ifa->ifa_addr) { + continue; + } + if (ifa->ifa_addr->sa_family == AF_INET) { + // is a valid IP4 Address + if (inet_ntop(AF_INET, &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr, ipstr, sizeof(ipstr)) != 0) { + IP4s.push_back(ipstr); + } + } + /*else if (ifa->ifa_addr->sa_family == AF_INET6) { + // is a valid IP6 Address + if (inet_ntop(AF_INET6, &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr, ipstr, sizeof(ipstr)) != 0) { + IP6s.push_back(ipstr); + } + }*/ + } + + freeifaddrs(ifAddrStruct); + return true; + } +#elif defined(SIOCGIFCONF) // Better detection on Linux/UNIX/MacOS/some Android +#include + static struct ifreq ifreqs[32]; + struct ifconf ifconf; + memset(&ifconf, 0, sizeof(ifconf)); + ifconf.ifc_req = ifreqs; + ifconf.ifc_len = sizeof(ifreqs); + + int sd = socket(AF_INET, SOCK_DGRAM, 0); + if (sd < 0) return false; + + int r = ioctl(sd, SIOCGIFCONF, (char*)&ifconf); + if (r != 0) return false; + + for (int i = 0; i < ifconf.ifc_len / sizeof(struct ifreq); ++i) + { + if (ifreqs[i].ifr_addr.sa_family == AF_INET) { + // is a valid IP4 Address + if (inet_ntop(AF_INET, &((struct sockaddr_in*)&ifreqs[i].ifr_addr)->sin_addr, ipstr, sizeof(ipstr)) != 0) { + IP4s.push_back(ipstr); + } + } + /*else if (ifreqs[i].ifr_addr.sa_family == AF_INET6) { + // is a valid IP6 Address + if (inet_ntop(AF_INET6, &((struct sockaddr_in6*)&ifreqs[i].ifr_addr)->sin6_addr, ipstr, sizeof(ipstr)) != 0) { + IP6s.push_back(ipstr); + } + }*/ + } + + close(sd); + return true; +#else // Fallback to POSIX/Cross-platform way but may not works well on Linux (ie. only shows 127.0.0.1) + struct addrinfo hints, * res, * p; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version + hints.ai_socktype = SOCK_DGRAM; + + // Get local host name + char szHostName[256] = ""; + if (::gethostname(szHostName, sizeof(szHostName))) { + // Error handling + } + + int status; + if ((status = getaddrinfo(szHostName, NULL, &hints, &res)) != 0) { + //fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status)); + return false; + } + for (p = res; p != NULL; p = p->ai_next) { + if (p->ai_family == AF_INET) { + // is a valid IP4 Address + if (inet_ntop(p->ai_family, &(((struct sockaddr_in*)p->ai_addr)->sin_addr), ipstr, sizeof(ipstr)) != 0) { + IP4s.push_back(ipstr); + } + } + /*else if (p->ai_family == AF_INET6) { + // is a valid IP6 Address + if (inet_ntop(p->ai_family, &(((struct sockaddr_in6*)p->ai_addr)->sin6_addr), ipstr, sizeof(ipstr)) != 0) { + IP6s.push_back(ipstr); + } + }*/ + } + + freeaddrinfo(res); // free the linked list + return true; +#endif + return false; +} + int inet_pton(int af, const char* src, void* dst) { if (af == AF_INET) diff --git a/ext/native/net/resolve.h b/ext/native/net/resolve.h index 58ce0984d9..8cc9756392 100644 --- a/ext/native/net/resolve.h +++ b/ext/native/net/resolve.h @@ -1,6 +1,7 @@ #pragma once #include +#include struct addrinfo; @@ -22,6 +23,7 @@ enum class DNSType { bool DNSResolve(const std::string &host, const std::string &service, addrinfo **res, std::string &error, DNSType type = DNSType::ANY); void DNSResolveFree(addrinfo *res); +bool GetIPList(std::vector& IP4s); int inet_pton(int af, const char* src, void* dst); } // namespace net From bd36fdda0e49aaba57057b75c482a045dc3d5034 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 18 Jul 2020 08:19:43 +0700 Subject: [PATCH 357/848] Do UPnP stuff on it's own thread to prevent causing stutters/lags during multiplayer game due to blocking socket behavior on miniUPnP --- Core/HLE/proAdhocServer.cpp | 4 +- Core/HLE/sceNet.cpp | 19 +++----- Core/HLE/sceNetAdhoc.cpp | 6 +-- Core/Util/PortManager.cpp | 97 +++++++++++++++++++++++++++++++++++-- Core/Util/PortManager.h | 25 ++++++++++ 5 files changed, 130 insertions(+), 21 deletions(-) diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 7d663ba1d4..85d4f2d56a 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -1685,13 +1685,13 @@ int proAdhocServerThread(int port) // (int argc, char * argv[]) INFO_LOG(SCENET, "AdhocServer: Listening for Connections on TCP Port %u", port); //SERVER_PORT // Port forward - g_PortManager.Add(IP_PROTOCOL_TCP, port); + UPnP_Add(IP_PROTOCOL_TCP, port); // g_PortManager.Add(IP_PROTOCOL_TCP, port); // Enter Server Loop result = server_loop(server); // Remove Port mapping - g_PortManager.Remove(IP_PROTOCOL_TCP, port); + UPnP_Remove(IP_PROTOCOL_TCP, port); // g_PortManager.Remove(IP_PROTOCOL_TCP, port); // Notify User INFO_LOG(SCENET, "AdhocServer: Shutdown complete"); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index b001caeeed..fd1f4830ec 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -126,13 +126,10 @@ void __NetInit() { char tmpmac[18]; SceNetEtherAddr mac; getLocalMac(&mac); - INFO_LOG(SCENET, "LocalHost IP will be %s [MAC: %s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac)); - - // Only initialize when UPnP is enabled since it takes a few seconds to detect UPnP device (may affect people who don't have UPnP device) - if (g_Config.bEnableUPnP) { - // TODO: May be we should initialize & cleanup somewhere else than here for PortManager to be used as general purpose for whatever port forwarding PPSSPP needed - g_PortManager.Initialize(); - } + INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac)); + + // TODO: May be we should initialize & cleanup somewhere else than here for PortManager to be used as general purpose for whatever port forwarding PPSSPP needed + __UPnPInit(); __ResetInitNetLib(); } @@ -140,15 +137,11 @@ void __NetInit() { void __NetShutdown() { // Network Cleanup Net_Term(); - + __ResetInitNetLib(); // Since PortManager supposed to be general purpose for whatever port forwarding PPSSPP needed, may be we shouldn't clear & restore ports in here? it will be cleared and restored by PortManager's destructor when exiting PPSSPP anyway - if (g_PortManager.GetInitState() == UPNP_INITSTATE_DONE) { - g_PortManager.Clear(); - g_PortManager.Restore(); - g_PortManager.Terminate(); - } + __UPnPShutdown(); } static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) { diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 40803220cd..95aa652051 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -384,7 +384,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u // Forward Port on Router //sceNetPortOpen("UDP", port); - g_PortManager.Add(IP_PROTOCOL_UDP, isOriPort ? port : port + portOffset, port + portOffset); + UPnP_Add(IP_PROTOCOL_UDP, isOriPort ? port : port + portOffset, port + portOffset); // g_PortManager.Add(IP_PROTOCOL_UDP, isOriPort ? port : port + portOffset, port + portOffset); // Success return i + 1; @@ -1992,7 +1992,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Add Port Forward to Router. We may not even need to forward this local port, since PtpOpen usually have port 0 (any port) as source port and followed by PtpConnect (which mean acting as Client), right? //sceNetPortOpen("TCP", sport); if (!isClient) - g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); + UPnP_Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // Return PTP Socket Pointer return i + 1; @@ -2525,7 +2525,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Add Port Forward to Router //sceNetPortOpen("TCP", sport); - g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); + UPnP_Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // Return PTP Socket Pointer return i + 1; diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index 34819be5bc..d91e4fb428 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -32,11 +32,18 @@ #include #include "Core/Util/PortManager.h" #include +#include #include "i18n/i18n.h" #include "net/resolve.h" +#include "thread/threadutil.h" +#include "base/timeutil.h" PortManager g_PortManager; +bool upnpServiceRunning = false; +std::thread upnpServiceThread; +std::recursive_mutex upnpLock; +std::deque upnpReqs; PortManager::PortManager(): urls(0), @@ -170,7 +177,7 @@ bool PortManager::Initialize(const unsigned int timeout) { ERROR_LOG(SCENET, "PortManager - upnpDiscover failed (error: %i) or No UPnP device detected", error); auto n = GetI18NCategory("Networking"); - host->NotifyUserMessage(n->T("Unable to find UPnP device"), 6.0f, 0x0000ff); + host->NotifyUserMessage(n->T("Unable to find UPnP device"), 2.0f, 0x0000ff); m_InitState = UPNP_INITSTATE_NONE; return false; } @@ -216,7 +223,7 @@ bool PortManager::Add(const char* protocol, unsigned short port, unsigned short ERROR_LOG(SCENET, "PortManager - AddPortMapping failed (error: %i)", r); if (r == UPNPCOMMAND_HTTP_ERROR) { auto n = GetI18NCategory("Networking"); - host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); + host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 2.0f, 0x0000ff); Terminate(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts return false; } @@ -244,7 +251,7 @@ bool PortManager::Remove(const char* protocol, unsigned short port) { ERROR_LOG(SCENET, "PortManager - DeletePortMapping failed (error: %i)", r); if (r == UPNPCOMMAND_HTTP_ERROR) { auto n = GetI18NCategory("Networking"); - host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 6.0f, 0x0000ff); + host->NotifyUserMessage(n->T("UPnP need to be reinitialized"), 2.0f, 0x0000ff); Terminate(); // Most of the time errors occurred because the router is no longer reachable (ie. changed networks) so we should invalidate the state to prevent further lags due to timeouts return false; } @@ -403,3 +410,87 @@ bool PortManager::RefreshPortList() { } while (r == 0); return true; } + +int upnpService(const unsigned int timeout) +{ + setCurrentThreadName("UPnPService"); + INFO_LOG(SCENET, "UPnPService: Begin of UPnPService Thread"); + + // Service Loop + while (upnpServiceRunning && coreState != CORE_POWERDOWN) { + // Attempts to reconnect if not connected yet or got disconnected + if (g_Config.bEnableUPnP && g_PortManager.GetInitState() == UPNP_INITSTATE_NONE) { + g_PortManager.Initialize(timeout); + } + + if (g_Config.bEnableUPnP && g_PortManager.GetInitState() == UPNP_INITSTATE_DONE && !upnpReqs.empty()) { + upnpLock.lock(); + UPnPArgs arg = upnpReqs.front(); + upnpLock.unlock(); + + bool ok = true; + switch (arg.cmd) { + case UPNP_CMD_ADD: + ok = g_PortManager.Add(arg.protocol.c_str(), arg.port, arg.intport); + break; + case UPNP_CMD_REMOVE: + ok = g_PortManager.Remove(arg.protocol.c_str(), arg.port); + break; + default: + break; + } + + // It's only considered failed when disconnected (should be retried when reconnected) + if (ok) { + upnpLock.lock(); + upnpReqs.pop_front(); + upnpLock.unlock(); + } + } + + // Sleep for 1ms for faster response + sleep_ms(1); + } + + // Cleaning up regardless of g_Config.bEnableUPnP to prevent lingering open ports on the router + if (g_PortManager.GetInitState() == UPNP_INITSTATE_DONE) { + g_PortManager.Clear(); + g_PortManager.Restore(); + g_PortManager.Terminate(); + } + + // Should we ingore any leftover UPnP requests? instead of processing it on the next game start + upnpLock.lock(); + upnpReqs.clear(); + upnpLock.unlock(); + + INFO_LOG(SCENET, "UPnPService: End of UPnPService Thread"); + return 0; +} + +void __UPnPInit(const unsigned int timeout) { + if (!upnpServiceRunning) { + upnpServiceRunning = true; + upnpServiceThread = std::thread(upnpService, timeout); + } +} + +void __UPnPShutdown() { + if (upnpServiceRunning) { + upnpServiceRunning = false; + if (upnpServiceThread.joinable()) { + upnpServiceThread.join(); + } + } +} + +void UPnP_Add(const char* protocol, unsigned short port, unsigned short intport) { + std::lock_guard upnpGuard(upnpLock); + upnpReqs.push_back({ UPNP_CMD_ADD, protocol, port, intport }); +} + +void UPnP_Remove(const char* protocol, unsigned short port) { + std::lock_guard upnpGuard(upnpLock); + upnpReqs.push_back({ UPNP_CMD_REMOVE, protocol, port, port }); +} + diff --git a/Core/Util/PortManager.h b/Core/Util/PortManager.h index 37040218dc..a4c7df6c27 100644 --- a/Core/Util/PortManager.h +++ b/Core/Util/PortManager.h @@ -33,12 +33,28 @@ #include #include +#ifdef _MSC_VER +#pragma pack(push,1) +#endif +typedef struct UPnPArgs { + int cmd; + std::string protocol; + unsigned short port; + unsigned short intport; +} PACK; +#ifdef _MSC_VER +#pragma pack(pop) +#endif + #define IP_PROTOCOL_TCP "TCP" #define IP_PROTOCOL_UDP "UDP" #define UPNP_INITSTATE_NONE 0 #define UPNP_INITSTATE_BUSY 1 #define UPNP_INITSTATE_DONE 2 +#define UPNP_CMD_ADD 0 +#define UPNP_CMD_REMOVE 1 + struct UPNPUrls; struct IGDdatas; @@ -98,3 +114,12 @@ protected: }; extern PortManager g_PortManager; + +void __UPnPInit(const unsigned int timeout = 2000); +void __UPnPShutdown(); + +// Add a port & protocol (TCP, UDP or vendor-defined) to map for forwarding (intport = 0 : same as [external] port) +void UPnP_Add(const char* protocol, unsigned short port, unsigned short intport = 0); + +// Remove a port mapping (external port) +void UPnP_Remove(const char* protocol, unsigned short port); From a3b21b04ea74a686071f5d63858d8185841ab78b Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 23 Jul 2020 07:41:41 +0700 Subject: [PATCH 358/848] Making mac2str function easier/cleaner/safer to use for logging purpose --- Core/HLE/proAdhoc.cpp | 48 ++++++++------------------ Core/HLE/proAdhoc.h | 3 +- Core/HLE/sceNet.cpp | 5 ++- Core/HLE/sceNetAdhoc.cpp | 74 +++++++++++++++------------------------- 4 files changed, 45 insertions(+), 85 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 33d2c1c3c3..4e3cbdd1ac 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -102,27 +102,14 @@ bool isPTPPortInUse(uint16_t port) { return false; } -char* mac2str(SceNetEtherAddr* mac) { -#if defined(_WIN32) - static __declspec(thread) char str[18] = ":::::"; -#elif !PPSSPP_PLATFORM(MAC) && !PPSSPP_PLATFORM(IOS) - static __thread char str[18] = ":::::"; -#else - // Temporary hack to avoid huge rebase conflicts. Remove this when applying the mac2str rewrite. - static char str[18] = ":::::"; -#endif - if (mac == NULL) return str; - snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]); +std::string mac2str(SceNetEtherAddr* mac) { + char str[18] = ":::::"; - return str; -} + if (mac != NULL) { + snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]); + } -char* mac2str(SceNetEtherAddr* mac, char* str, size_t size) { - if (mac == NULL || str == NULL || size < 18) return NULL; - - snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]); - - return str; + return std::string(str); } SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac) { @@ -131,8 +118,7 @@ SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * contex SceNetAdhocMatchingMemberInternal * peer = findPeer(context, mac); // Already existed if (peer != NULL) { - char tmpmac[18]; - WARN_LOG(SCENET, "Member Peer Already Existed! Updating [%s]", mac2str(mac, tmpmac)); + WARN_LOG(SCENET, "Member Peer Already Existed! Updating [%s]", mac2str(mac).c_str()); peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); } // Member is not added yet @@ -158,9 +144,8 @@ void addFriend(SceNetAdhocctlConnectPacketS2C * packet) { SceNetAdhocctlPeerInfo * peer = findFriend(&packet->mac); // Already existed if (peer != NULL) { - char tmpmac[18]; u32 tmpip = packet->ip; - WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", mac2str(&packet->mac, tmpmac), inet_ntoa(*(struct in_addr*)&tmpip), packet->name.data); //inet_ntoa(*(in_addr*)&packet->ip) + WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", mac2str(&packet->mac).c_str(), inet_ntoa(*(struct in_addr*)&tmpip), packet->name.data); //inet_ntoa(*(in_addr*)&packet->ip) peer->nickname = packet->name; peer->mac_addr = packet->mac; peer->ip_addr = packet->ip; @@ -348,9 +333,8 @@ void deleteFriendByIP(uint32_t ip) { else prev->next = peer->next; */ - char tmpmac[18]; u32 tmpip = peer->ip_addr; - INFO_LOG(SCENET, "Removing Friend Peer %s [%s]", mac2str(&peer->mac_addr, tmpmac), inet_ntoa(*(struct in_addr *)&tmpip)); //inet_ntoa(*(in_addr*)&peer->ip_addr) + INFO_LOG(SCENET, "Removing Friend Peer %s [%s]", mac2str(&peer->mac_addr).c_str(), inet_ntoa(*(struct in_addr *)&tmpip)); //inet_ntoa(*(in_addr*)&peer->ip_addr) // Free Memory //free(peer); @@ -501,8 +485,7 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun // Spawn Established Event spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); - char tmpmac[18]; - INFO_LOG(SCENET, "Accepting Peer %s", mac2str(&sibling->mac, tmpmac)); + INFO_LOG(SCENET, "Accepting Peer %s", mac2str(&sibling->mac).c_str()); } } } @@ -628,8 +611,7 @@ void deletePeer(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingMemberI // Beginning Item else context->peerlist = item->next; - char tmpmac[18]; - INFO_LOG(SCENET, "Removing Member Peer %s", mac2str(&peer->mac, tmpmac)); + INFO_LOG(SCENET, "Removing Member Peer %s", mac2str(&peer->mac).c_str()); } // Free Peer Memory @@ -904,8 +886,7 @@ void handleTimeout(SceNetAdhocMatchingContext * context) spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); // This is the only code that use PSP_ADHOC_MATCHING_EVENT_TIMEOUT, should we let it timedout? } - char tmpmac[18]; - INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac, tmpmac), (context->timeout/1000)); + INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac).c_str(), (context->timeout/1000)); // Delete Peer from List deletePeer(context, peer); @@ -1236,8 +1217,7 @@ int friendFinder(){ // Cast Packet SceNetAdhocctlConnectBSSIDPacketS2C* packet = (SceNetAdhocctlConnectBSSIDPacketS2C*)rx; - char tmpmac[18]; - INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac, tmpmac)); + INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac).c_str()); // From JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?) /*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { setState(ADHOCCTL_STATE_GAMEMODE); @@ -1316,7 +1296,7 @@ int friendFinder(){ // Log Incoming Peer u32_le ipaddr = packet->ip; - INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT [%s][%s][%s]", mac2str(&packet->mac), inet_ntoa(*(in_addr*)&ipaddr), packet->name.data); + INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT [%s][%s][%s]", mac2str(&packet->mac).c_str(), inet_ntoa(*(in_addr*)&ipaddr), packet->name.data); // Add User addFriend(packet); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index a14e570746..860808960b 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -893,8 +893,7 @@ bool isPDPPortInUse(uint16_t port); */ bool isPTPPortInUse(uint16_t port); -char* mac2str(SceNetEtherAddr* mac); -char* mac2str(SceNetEtherAddr* mac, char* str, size_t size = 18); +std::string mac2str(SceNetEtherAddr* mac); /* * Matching Members diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index fd1f4830ec..0df11e5c63 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -123,10 +123,9 @@ void __NetInit() { InitLocalhostIP(); - char tmpmac[18]; SceNetEtherAddr mac; getLocalMac(&mac); - INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac, tmpmac)); + INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac).c_str()); // TODO: May be we should initialize & cleanup somewhere else than here for PortManager to be used as general purpose for whatever port forwarding PPSSPP needed __UPnPInit(); @@ -417,7 +416,7 @@ static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) { } } - VERBOSE_LOG(SCENET, "sceNetEtherStrton - [%s]", mac2str((SceNetEtherAddr*)Memory::GetPointer(macPtr))); + VERBOSE_LOG(SCENET, "sceNetEtherStrton - [%s]", mac2str((SceNetEtherAddr*)Memory::GetPointer(macPtr)).c_str()); // Seems to maybe kinda return the last value. Probably returns void. //return value; } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 95aa652051..792599cc5f 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -297,8 +297,7 @@ static int sceNetAdhocctlGetState(u32 ptrToStatus) { */ // When choosing AdHoc menu in Wipeout Pulse sometimes it's saying that "WLAN is turned off" on game screen and getting "kUnityCommandCode_MediaDisconnected" error in the Log Console when calling sceNetAdhocPdpCreate, probably it needed to wait something from the thread before calling this (ie. need to receives 7 bytes from adhoc server 1st?) static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 unknown) { - char tmpmac[18]; - INFO_LOG(SCENET, "sceNetAdhocPdpCreate(%s, %u, %u, %u) at %08x", mac2str((SceNetEtherAddr*)mac, tmpmac), port, bufferSize, unknown, currentMIPS->pc); + INFO_LOG(SCENET, "sceNetAdhocPdpCreate(%s, %u, %u, %u) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), port, bufferSize, unknown, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; } @@ -430,10 +429,10 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG */ static int sceNetAdhocctlGetParameter(u32 paramAddr) { - char grpName[9] = { 0 }; char tmpmac[18]; + char grpName[9] = { 0 }; memcpy(grpName, parameter.group_name.data, ADHOCCTL_GROUPNAME_LEN); parameter.nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; - DEBUG_LOG(SCENET, "sceNetAdhocctlGetParameter(%08x) [Ch=%i][Group=%s][BSSID=%s][name=%s]", paramAddr, parameter.channel, grpName, mac2str(¶meter.bssid.mac_addr, tmpmac), parameter.nickname.data); + DEBUG_LOG(SCENET, "sceNetAdhocctlGetParameter(%08x) [Ch=%i][Group=%s][BSSID=%s][name=%s]", paramAddr, parameter.channel, grpName, mac2str(¶meter.bssid.mac_addr).c_str(), parameter.nickname.data); if (!g_Config.bEnableWlan) { return ERROR_NET_ADHOCCTL_DISCONNECTED; } @@ -468,11 +467,10 @@ static int sceNetAdhocctlGetParameter(u32 paramAddr) { * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT, ADHOC_INVALID_DATALEN, ADHOC_SOCKET_ALERTED, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_WOULD_BLOCK, NET_NO_SPACE, NET_INTERNAL */ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int len, int timeout, int flag) { - char tmpmac[18]; if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac, tmpmac), port, data, len, timeout, flag, currentMIPS->pc); + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac).c_str(), port, data, len, timeout, flag, currentMIPS->pc); } else { - VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac, tmpmac), port, data, len, timeout, flag, currentMIPS->pc); + VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac).c_str(), port, data, len, timeout, flag, currentMIPS->pc); } if (!g_Config.bEnableWlan) { return -1; @@ -1361,8 +1359,7 @@ int sceNetAdhocctlTerm() { } static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { - char tmpmac[18]; - DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x)", mac2str((SceNetEtherAddr*)mac, tmpmac), nameAddr); + DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x)", mac2str((SceNetEtherAddr*)mac).c_str(), nameAddr); // Library initialized if (netAdhocctlInited) @@ -1457,8 +1454,7 @@ static int sceNetAdhocctlJoin(u32 scanInfoAddr) { } int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { - char tmpmac[18]; - VERBOSE_LOG(SCENET, "sceNetAdhocctlGetPeerInfo(%s, %i, %08x) at %08x", mac2str((SceNetEtherAddr*)mac, tmpmac), size, peerInfoAddr, currentMIPS->pc); + VERBOSE_LOG(SCENET, "sceNetAdhocctlGetPeerInfo(%s, %i, %08x) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), size, peerInfoAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; } @@ -1657,8 +1653,7 @@ static int sceNetAdhocctlJoinEnterGameMode(const char *groupName, const char *ma char grpName[9] = { 0 }; memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs - char tmpmac[18]; - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)macAddr, tmpmac), timeout, unknown2, currentMIPS->pc); + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)macAddr).c_str(), timeout, unknown2, currentMIPS->pc); return 0; } @@ -1889,8 +1884,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT */ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, int dport, int bufsize, int rexmt_int, int rexmt_cnt, int unknown) { - char tmpmac[18]; - INFO_LOG(SCENET, "sceNetAdhocPtpOpen(%s, %d, %s, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac), sport, mac2str((SceNetEtherAddr*)dstmac, tmpmac),dport,bufsize, rexmt_int, rexmt_cnt, unknown, currentMIPS->pc); + INFO_LOG(SCENET, "sceNetAdhocPtpOpen(%s, %d, %s, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac).c_str(), sport, mac2str((SceNetEtherAddr*)dstmac).c_str(),dport,bufsize, rexmt_int, rexmt_cnt, unknown, currentMIPS->pc); if (!g_Config.bEnableWlan) { return 0; } @@ -2050,11 +2044,10 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int if (Memory::IsValidAddress(peerPortPtr)) { port = (uint16_t *)Memory::GetPointer(peerPortPtr); } - char tmpmac[18]; if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket - DEBUG_LOG(SCENET, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr, tmpmac), peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); + DEBUG_LOG(SCENET, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr).c_str(), peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); } else { - VERBOSE_LOG(SCENET, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr, tmpmac), peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); + VERBOSE_LOG(SCENET, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr).c_str(), peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); } if (!g_Config.bEnableWlan) { return 0; @@ -2422,8 +2415,7 @@ static int sceNetAdhocPtpClose(int id, int unknown) { * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT, ADHOC_SOCKET_ID_NOT_AVAIL, ADHOC_PORT_NOT_AVAIL, ADHOC_PORT_IN_USE, NET_NO_SPACE */ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int rexmt_int, int rexmt_cnt, int backlog, int unk) { - char tmpmac[18]; - INFO_LOG(SCENET, "sceNetAdhocPtpListen(%s, %d, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac, tmpmac), sport,bufsize,rexmt_int,rexmt_cnt,backlog,unk, currentMIPS->pc); + INFO_LOG(SCENET, "sceNetAdhocPtpListen(%s, %d, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac).c_str(), sport,bufsize,rexmt_int,rexmt_cnt,backlog,unk, currentMIPS->pc); if (!g_Config.bEnableWlan) { return 0; } @@ -2624,8 +2616,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Save Length *len = sent; - char tmpmac[18]; - DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u", id, socket->lport, sent, mac2str(&socket->paddr, tmpmac), socket->pport); + DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u", id, socket->lport, sent, mac2str(&socket->paddr).c_str(), socket->pport); // Return Success return 0; @@ -2738,8 +2729,7 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); peerlock.unlock(); - char tmpmac[18]; - DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u", id, socket->lport, received, mac2str(&socket->paddr, tmpmac), socket->pport); + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u", id, socket->lport, received, mac2str(&socket->paddr).c_str(), socket->pport); // Return Success return 0; @@ -2832,8 +2822,7 @@ static int sceNetAdhocGameModeCreateMaster(u32 data, int size) { } static int sceNetAdhocGameModeCreateReplica(const char *mac, u32 data, int size) { - char tmpmac[18]; - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeCreateReplica(%s, %08x, %i) at %08x", mac2str((SceNetEtherAddr*)mac, tmpmac), data, size, currentMIPS->pc); + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeCreateReplica(%s, %08x, %i) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), data, size, currentMIPS->pc); return 0; } @@ -3316,8 +3305,7 @@ static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartit static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { - char tmpmac[18]; - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSelectTarget(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress, tmpmac), optLen, optDataPtr, currentMIPS->pc); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSelectTarget(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress).c_str(), optLen, optDataPtr, currentMIPS->pc); if (!g_Config.bEnableWlan) return -1; @@ -3470,8 +3458,7 @@ static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddres } int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { - char tmpmac[18]; - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingCancelTargetWithOpt(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress, tmpmac), optLen, optDataPtr, currentMIPS->pc); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingCancelTargetWithOpt(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress).c_str(), optLen, optDataPtr, currentMIPS->pc); if (!g_Config.bEnableWlan) return -1; @@ -3550,8 +3537,7 @@ int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddres } int sceNetAdhocMatchingCancelTarget(int matchingId, const char *macAddress) { - char tmpmac[18]; - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingCancelTarget(%i, %s)", matchingId, mac2str((SceNetEtherAddr*)macAddress, tmpmac)); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingCancelTarget(%i, %s)", matchingId, mac2str((SceNetEtherAddr*)macAddress).c_str()); if (!g_Config.bEnableWlan) return -1; return sceNetAdhocMatchingCancelTargetWithOpt(matchingId, macAddress, 0, 0); @@ -3749,7 +3735,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Add Local MAC buf2[filledpeers++].mac_addr = context->mac; - DEBUG_LOG(SCENET, "MemberSelf [%s]", mac2str(&context->mac)); + DEBUG_LOG(SCENET, "MemberSelf [%s]", mac2str(&context->mac).c_str()); // Room for more than local peer if (requestedpeers > 1) @@ -3770,7 +3756,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Add P2P Brother MAC buf2[filledpeers++].mac_addr = p2p->mac; - DEBUG_LOG(SCENET, "MemberP2P [%s]", mac2str(&p2p->mac)); + DEBUG_LOG(SCENET, "MemberP2P [%s]", mac2str(&p2p->mac).c_str()); } } @@ -3794,7 +3780,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Add Child MAC buf2[filledpeers++].mac_addr = peer->mac; - DEBUG_LOG(SCENET, "MemberParent [%s]", mac2str(&peer->mac)); + DEBUG_LOG(SCENET, "MemberParent [%s]", mac2str(&peer->mac).c_str()); } } @@ -3806,7 +3792,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Add Peer MAC buf2[filledpeers++].mac_addr = peer->mac; - DEBUG_LOG(SCENET, "MemberChild [%s]", mac2str(&peer->mac)); + DEBUG_LOG(SCENET, "MemberChild [%s]", mac2str(&peer->mac).c_str()); } } } @@ -3848,8 +3834,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) } int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u32 dataAddr) { - char tmpmac[18]; - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x)", matchingId, mac2str((SceNetEtherAddr*)mac, tmpmac), dataLen, dataAddr); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x)", matchingId, mac2str((SceNetEtherAddr*)mac).c_str(), dataLen, dataAddr); if (!g_Config.bEnableWlan) return -1; @@ -3925,8 +3910,7 @@ int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u3 } int sceNetAdhocMatchingAbortSendData(int matchingId, const char *mac) { - char tmpmac[18]; - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingAbortSendData(%i, %s)", matchingId, mac2str((SceNetEtherAddr*)mac, tmpmac)); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingAbortSendData(%i, %s)", matchingId, mac2str((SceNetEtherAddr*)mac).c_str()); if (!g_Config.bEnableWlan) return -1; @@ -4216,7 +4200,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { discovered++; u32_le ipaddr = peer->ip_addr; - DEBUG_LOG(SCENET, "Peer [%s][%s][%s][%llu]", mac2str(&peer->mac_addr), inet_ntoa(*(in_addr*)&ipaddr), (const char*)&peer->nickname.data, peer->last_recv); + DEBUG_LOG(SCENET, "Peer [%s][%s][%s][%llu]", mac2str(&peer->mac_addr).c_str(), inet_ntoa(*(in_addr*)&ipaddr), (const char*)&peer->nickname.data, peer->last_recv); } } @@ -4746,11 +4730,10 @@ void sendBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac context->socketlock->unlock(); // Log Send Success - char tmpmac[18]; if (sent >= 0) - INFO_LOG(SCENET, "InputLoop: Sending BIRTH to %s", mac2str(&peer->mac, tmpmac)); + INFO_LOG(SCENET, "InputLoop: Sending BIRTH to %s", mac2str(&peer->mac).c_str()); else - WARN_LOG(SCENET, "InputLoop: Failed to Send BIRTH to %s", mac2str(&peer->mac, tmpmac)); + WARN_LOG(SCENET, "InputLoop: Failed to Send BIRTH to %s", mac2str(&peer->mac).c_str()); } } } @@ -5647,8 +5630,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi if (peer != NULL) { now = CoreTiming::GetGlobalTimeUsScaled(); u64_le delta = now - peer->last_recv; - char tmpmac[18]; - DEBUG_LOG(SCENET, "Timestamp Delta: %llu (%llu - %llu) from %s", delta, now, peer->last_recv, mac2str(&sendermac, tmpmac)); + DEBUG_LOG(SCENET, "Timestamp Delta: %llu (%llu - %llu) from %s", delta, now, peer->last_recv, mac2str(&sendermac).c_str()); if (/*context->rxbuf[0] > 0 &&*/ peer->last_recv != 0) peer->last_recv = now - 1; // - context->keepalive_int; // May need to deduce by ping interval to prevent Dissidia 012 unable to see other players (ie. disappearing issue) } peerlock.unlock(); From a6e3bed150e82fa8add806dfda4298898d53bc8d Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 23 Jul 2020 08:09:20 +0700 Subject: [PATCH 359/848] Just to be safe since SO_MAX_MSG_SIZE may not be available on all platform and forcing the definition to what windows use might be a bad idea. --- Core/HLE/proAdhoc.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 4e3cbdd1ac..e3c107be9d 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1641,12 +1641,11 @@ uint16_t getLocalPort(int sock) { } int getSockMaxSize(int udpsock) { -#if !defined(SO_MAX_MSG_SIZE) -#define SO_MAX_MSG_SIZE 0x2003 -#endif int n = 1500; // Typical MTU size as default +#if defined(SO_MAX_MSG_SIZE) // May not be available on all platform socklen_t m = sizeof(n); getsockopt(udpsock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*)&n, &m); +#endif return n; } From e9d0b5b90fa92eb29ccb207c59a919909cad04bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 23 Jul 2020 22:23:55 +0200 Subject: [PATCH 360/848] D3D11 - don't forget to unbind secondary texture when we need to unbind. Fixes Patapon 3 error reported in #13132. --- GPU/D3D11/TextureCacheD3D11.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index def69c626a..4b342eb296 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -147,8 +147,8 @@ void TextureCacheD3D11::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { void TextureCacheD3D11::ForgetLastTexture() { InvalidateLastTexture(); gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); - ID3D11ShaderResourceView *nullTex = nullptr; - context_->PSSetShaderResources(0, 1, &nullTex); + ID3D11ShaderResourceView *nullTex[2]{}; + context_->PSSetShaderResources(0, 2, nullTex); } void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) { From dd8dd2c15d773f2c24bcaf0ab6aba63364c0c853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 23 Jul 2020 22:37:08 +0200 Subject: [PATCH 361/848] Libretro: Update minimum windows version to Vista. Committed on behalf of twinaphex To fix a build error. --- libretro/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro/Makefile b/libretro/Makefile index daeafa35dd..eaf1085a81 100644 --- a/libretro/Makefile +++ b/libretro/Makefile @@ -275,7 +275,7 @@ else ifneq (,$(findstring windows_msvc2017,$(platform))) PlatformSuffix = $(subst windows_msvc2017_,,$(platform)) ifneq (,$(findstring desktop,$(PlatformSuffix))) WinPartition = desktop - MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_UNICODE -DUNICODE -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 + MSVC2017CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_UNICODE -DUNICODE -DWINVER=0x0600 -D_WIN32_WINNT=0x0600 LDFLAGS += -MANIFEST -NXCOMPAT -DYNAMICBASE -DEBUG -OPT:REF -INCREMENTAL:NO -SUBSYSTEM:WINDOWS -MANIFESTUAC:"level='asInvoker' uiAccess='false'" -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 LIBS += kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib else ifneq (,$(findstring uwp,$(PlatformSuffix))) @@ -382,7 +382,7 @@ else ifneq (,$(findstring windows_msvc2019,$(platform))) PlatformSuffix = $(subst windows_msvc2019_,,$(platform)) ifneq (,$(findstring desktop,$(PlatformSuffix))) WinPartition = desktop - MSVC2019CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_UNICODE -DUNICODE -DWINVER=0x0501 -D_WIN32_WINNT=0x0501 + MSVC2019CompileFlags = -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP -D_UNICODE -DUNICODE -DWINVER=0x0600 -D_WIN32_WINNT=0x0600 LDFLAGS += -MANIFEST -NXCOMPAT -DYNAMICBASE -DEBUG -OPT:REF -INCREMENTAL:NO -SUBSYSTEM:WINDOWS -MANIFESTUAC:"level='asInvoker' uiAccess='false'" -OPT:ICF -ERRORREPORT:PROMPT -NOLOGO -TLBID:1 LIBS += kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib else ifneq (,$(findstring uwp,$(PlatformSuffix))) From 809fd6b8fa572ec1cf5ffea7d0581891562c7fc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 24 Jul 2020 00:05:36 +0200 Subject: [PATCH 362/848] Small perf optimization in debug mode (surprisingly expensive to do a vector lookup here). --- GPU/Debugger/Breakpoints.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/GPU/Debugger/Breakpoints.cpp b/GPU/Debugger/Breakpoints.cpp index 401acbcdd7..9d1f7049f8 100644 --- a/GPU/Debugger/Breakpoints.cpp +++ b/GPU/Debugger/Breakpoints.cpp @@ -26,7 +26,7 @@ namespace GPUBreakpoints { static std::mutex breaksLock; -static std::vector breakCmds; +static bool breakCmds[256]; static std::set breakPCs; static std::set breakTextures; static std::set breakRenderTargets; @@ -36,7 +36,7 @@ static size_t breakTexturesCount = 0; static size_t breakRenderTargetsCount = 0; // If these are set, the above are also, but they should be temporary. -static std::vector breakCmdsTemp; +static bool breakCmdsTemp[256]; static std::set breakPCsTemp; static std::set breakTexturesTemp; static std::set breakRenderTargetsTemp; @@ -373,14 +373,14 @@ void UpdateLastTexture(u32 addr) { void ClearAllBreakpoints() { std::lock_guard guard(breaksLock); - breakCmds.clear(); - breakCmds.resize(256, false); + for (int i = 0; i < 256; ++i) { + breakCmds[i] = false; + breakCmdsTemp[i] = false; + } breakPCs.clear(); breakTextures.clear(); breakRenderTargets.clear(); - breakCmdsTemp.clear(); - breakCmdsTemp.resize(256, false); breakPCsTemp.clear(); breakTexturesTemp.clear(); breakRenderTargetsTemp.clear(); From c8ea017e8c18a1960108993d0591a28267f3f592 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 24 Jul 2020 07:58:38 +0700 Subject: [PATCH 363/848] Fix an issue where a player got disconnected when another player tries to join. This should affects games that use AdhocMatching such as Patapon 3 --- Core/HLE/sceNetAdhoc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 792599cc5f..43ef73d5ea 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -5261,7 +5261,7 @@ void actOnBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * se sibling->state = PSP_ADHOC_MATCHING_PEER_CHILD; // Initialize Ping Timer - peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + sibling->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; peerlock.lock(); From 5153b606379586a1ebd4438e15205822915ee88d Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 24 Jul 2020 08:07:01 +0700 Subject: [PATCH 364/848] Fix some logs text --- Core/HLE/sceNetAdhoc.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 43ef73d5ea..e44f568611 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -3775,12 +3775,12 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Parent Mode if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { - // Interested in Children (Michael Jackson Style) + // Interested in Children if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) { // Add Child MAC buf2[filledpeers++].mac_addr = peer->mac; - DEBUG_LOG(SCENET, "MemberParent [%s]", mac2str(&peer->mac).c_str()); + DEBUG_LOG(SCENET, "MemberChild [%s]", mac2str(&peer->mac).c_str()); } } @@ -3792,7 +3792,10 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Add Peer MAC buf2[filledpeers++].mac_addr = peer->mac; - DEBUG_LOG(SCENET, "MemberChild [%s]", mac2str(&peer->mac).c_str()); + if (peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) + DEBUG_LOG(SCENET, "MemberParent [%s]", mac2str(&peer->mac).c_str()); + else + DEBUG_LOG(SCENET, "MemberSibling [%s]", mac2str(&peer->mac).c_str()); } } } From 581ba6c326dde125edbefba8be99e72a4fe362c3 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 24 Jul 2020 08:28:42 +0700 Subject: [PATCH 365/848] Added target/destination IP & port of sceNetAdhocPtpConnect in the log to get better insight --- Core/HLE/sceNetAdhoc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index e44f568611..d61dc4cd79 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2277,7 +2277,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { int errorcode = errno; if (connectresult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "sceNetAdhocPtpConnect[%i]: Socket Error (%i)", id, errorcode); + ERROR_LOG(SCENET, "sceNetAdhocPtpConnect[%i]: Socket Error (%i) to %s:%u", id, errorcode, inet_ntoa(sin.sin_addr), socket->pport); } // Restore Blocking Behaviour @@ -2292,7 +2292,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Set Connected State socket->state = ADHOC_PTP_STATE_ESTABLISHED; - INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Already Connected", id, socket->lport); + INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Already Connected to %s:%u", id, socket->lport, inet_ntoa(sin.sin_addr), socket->pport); // Success return 0; } From 20d10187cd9b0172b5ac98288c08856e3e8576d0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 24 Jul 2020 08:54:51 +0200 Subject: [PATCH 366/848] (Libretro Windows) Buildfix --- libretro/Makefile | 6 +++--- libretro/jni/Android.mk | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libretro/Makefile b/libretro/Makefile index eaf1085a81..8b2d15fa49 100644 --- a/libretro/Makefile +++ b/libretro/Makefile @@ -374,7 +374,7 @@ else ifneq (,$(findstring windows_msvc2017,$(platform))) FFMPEGLIBDIR := $(FFMPEGDIR)/Windows/$(TARGET_ARCH)/lib FFMPEGLDFLAGS += -LIBPATH:$(FFMPEGLIBDIR) GL_LIB := opengl32.lib - LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib d3d9.lib d3dx9.lib + LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib d3d9.lib d3dx9.lib Iphlpapi.lib # Windows MSVC 2019 all architectures else ifneq (,$(findstring windows_msvc2019,$(platform))) @@ -481,7 +481,7 @@ else ifneq (,$(findstring windows_msvc2019,$(platform))) FFMPEGLIBDIR := $(FFMPEGDIR)/Windows/$(TARGET_ARCH)/lib FFMPEGLDFLAGS += -LIBPATH:$(FFMPEGLIBDIR) GL_LIB := opengl32.lib - LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib d3d9.lib d3dx9.lib + LDFLAGS += ws2_32.lib user32.lib shell32.lib avcodec.lib avutil.lib swresample.lib swscale.lib avformat.lib advapi32.lib winmm.lib gdi32.lib d3d9.lib d3dx9.lib Iphlpapi.lib # Windows else ifneq (,$(findstring win,$(platform))) @@ -512,7 +512,7 @@ else GLFLAGS += -DHAVE_OPENGL endif -COREFLAGS += -D__LIBRETRO__ -DPPSSPP -DUSE_FFMPEG -DGLEW_STATIC -DGLEW_NO_GLU +COREFLAGS += -D__LIBRETRO__ -DPPSSPP -DUSE_FFMPEG -DGLEW_STATIC -DGLEW_NO_GLU -DMINIUPNP_STATICLIB ifeq ($(DEBUG), 1) ifneq (,$(findstring msvc,$(platform))) diff --git a/libretro/jni/Android.mk b/libretro/jni/Android.mk index e9b773c024..e1b48c2f7a 100644 --- a/libretro/jni/Android.mk +++ b/libretro/jni/Android.mk @@ -71,7 +71,7 @@ LOCAL_MODULE := retro 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) +COREFLAGS += -DINLINE="inline" -DPPSSPP -DUSE_FFMPEG -DMOBILE_DEVICE -DBAKE_IN_GIT -DDYNAREC -D__LIBRETRO__ -DUSING_GLES2 -D__STDC_CONSTANT_MACROS -DGLEW_NO_GLU -DMINIUPNP_STATICLIB $(INCFLAGS) LOCAL_SRC_FILES = $(SOURCES_CXX) $(SOURCES_C) $(ASMFILES) LOCAL_CPPFLAGS := -Wall -std=gnu++11 $(COREFLAGS) -DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS LOCAL_CFLAGS := -O2 -DANDROID $(COREFLAGS) From 87b712450f77cf51a4eb349d6b3c71c2382b1311 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 24 Jul 2020 10:13:27 +0700 Subject: [PATCH 367/848] Locking before changing peer linked list order, just to be safe. --- Core/HLE/proAdhoc.cpp | 2 ++ Core/HLE/sceNetAdhoc.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index e3c107be9d..c69b3aee45 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -478,9 +478,11 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun // Initialize Ping Timer sibling->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + peerlock.lock(); // Link Peer, should check whether it's already added before sibling->next = context->peerlist; context->peerlist = sibling; + peerlock.unlock(); // Spawn Established Event spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index d61dc4cd79..10255d917e 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -4875,9 +4875,11 @@ void actOnHelloPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * se // Initialize Ping Timer peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + peerlock.lock(); // Link Peer into List peer->next = context->peerlist; context->peerlist = peer; + peerlock.unlock(); } } @@ -4950,9 +4952,11 @@ void actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen // Initialize Ping Timer peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + peerlock.lock(); // Link Peer into List peer->next = context->peerlist; context->peerlist = peer; + peerlock.unlock(); // Spawn Request Event spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_REQUEST, sendermac, optlen, opt); From b6e98374d3d418c36691755326331a7ed1c8c3be Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 19 Jul 2020 17:02:01 -0700 Subject: [PATCH 368/848] UI: Fix consistency in vsync setting for iOS. --- GPU/GPUCommon.cpp | 2 +- UI/GameSettingsScreen.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index a73b09de25..190a4fd2db 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -467,7 +467,7 @@ void GPUCommon::Reinitialize() { } void GPUCommon::UpdateVsyncInterval(bool force) { -#if !(PPSSPP_PLATFORM(ANDROID) || USING_QT_UI || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS)) +#if !(PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS)) int desiredVSyncInterval = g_Config.bVSync ? 1 : 0; if (PSP_CoreParameter().unthrottle) { desiredVSyncInterval = 0; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 0aaff82ee0..97d0bd2f2a 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -350,7 +350,7 @@ void GameSettingsScreen::CreateViews() { } #endif -#if !(PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(IOS) +#if !(PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS)) CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync"))); vSync->OnClick.Add([=](EventParams &e) { NativeResized(); From 2f44495654e81e0c4411914f85ec32218c42c60d Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 25 Jul 2020 11:38:08 +0700 Subject: [PATCH 369/848] Added more info to AdhocMatching Logs to get a better insight --- Core/HLE/proAdhoc.cpp | 4 ++-- Core/HLE/sceNetAdhoc.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index c69b3aee45..ae35e82c9f 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -989,9 +989,9 @@ void AfterMatchingMipsCall::run(MipsCall &call) { } u32 v0 = currentMIPS->r[MIPS_REG_V0]; if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", contextID, EventID); - if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); //SetMatchingInCallback(context, false); - DEBUG_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] [cbId: %u][retV0: %08x]", contextID, EventID, call.cbId, v0); + DEBUG_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d][%s] [cbId: %u][retV0: %08x]", contextID, EventID, mac2str((SceNetEtherAddr*)Memory::GetPointer(bufAddr)).c_str(), call.cbId, v0); + if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr); //call.setReturnValue(v0); } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 10255d917e..d38fdc20a7 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -4063,7 +4063,7 @@ void __NetMatchingCallbacks() //(int matchingId) //if (/*__KernelGetCurThread() == context->matching_thid &&*/ (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) /*&& !IsMatchingInCallback(context)*/) { - DEBUG_LOG(SCENET, "AdhocMatchingCallback: [ID=%i][EVENT=%i]", args[0], args[1]); + DEBUG_LOG(SCENET, "AdhocMatchingCallback: [ID=%i][EVENT=%i][%s]", args[0], args[1], mac2str((SceNetEtherAddr*)Memory::GetPointer(args[2])).c_str()); AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); after->SetData(args[0], args[1], args[2]); //SetMatchingInCallback(context, true); @@ -4734,9 +4734,9 @@ void sendBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac // Log Send Success if (sent >= 0) - INFO_LOG(SCENET, "InputLoop: Sending BIRTH to %s", mac2str(&peer->mac).c_str()); + INFO_LOG(SCENET, "InputLoop: Sending BIRTH [%s] to %s", mac2str(mac).c_str(), mac2str(&peer->mac).c_str()); else - WARN_LOG(SCENET, "InputLoop: Failed to Send BIRTH to %s", mac2str(&peer->mac).c_str()); + WARN_LOG(SCENET, "InputLoop: Failed to Send BIRTH [%s] to %s", mac2str(mac).c_str(), mac2str(&peer->mac).c_str()); } } } @@ -5422,7 +5422,7 @@ int matchingEventThread(int matchingId) if (msg->optlen > 0) opt = ((u8*)msg) + sizeof(ThreadMessage); //&msg[1] // Log Matching Events - INFO_LOG(SCENET, "EventLoop[%d]: Matching Event [%d=%s] OptSize=%d", matchingId, msg->opcode, getMatchingEventStr(msg->opcode), msg->optlen); + INFO_LOG(SCENET, "EventLoop[%d]: Matching Event [%d=%s][%s] OptSize=%d", matchingId, msg->opcode, getMatchingEventStr(msg->opcode), mac2str(&msg->mac).c_str(), msg->optlen); // Unlock to prevent race-condition with other threads due to recursive lock context->eventlock->unlock(); From 30ea1087ddeb4e60cd3084690db788a97276617b Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 25 Jul 2020 11:46:47 +0700 Subject: [PATCH 370/848] Attempt to fix an issue when the 3rd player joined causing problem to other players on Patapon 3 (this may also affects other games that use AdhocMatching) --- Core/HLE/proAdhoc.cpp | 4 ++-- Core/HLE/sceNetAdhoc.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index ae35e82c9f..32cfdc15d2 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -484,8 +484,8 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun context->peerlist = sibling; peerlock.unlock(); - // Spawn Established Event - spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); + // Spawn Established Event. FIXME: ESTABLISHED event should only be triggered for Parent/P2P peer? + //spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); INFO_LOG(SCENET, "Accepting Peer %s", mac2str(&sibling->mac).c_str()); } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index d38fdc20a7..1cb6e29a86 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -5278,8 +5278,8 @@ void actOnBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * se peerlock.unlock(); - // Spawn Established Event - spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); + // Spawn Established Event. FIXME: ESTABLISHED event should only be triggered for Parent/P2P peer? + //spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); } } } From fd62d3077357cf410e8aaa40f1da1673623819c8 Mon Sep 17 00:00:00 2001 From: parport0 Date: Sun, 26 Jul 2020 01:18:16 +0300 Subject: [PATCH 371/848] Debugger: Add memory.read_*, memory write_* --- CMakeLists.txt | 2 + Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 6 + Core/Debugger/WebSocket.cpp | 2 + Core/Debugger/WebSocket/MemorySubscriber.cpp | 205 +++++++++++++++++++ Core/Debugger/WebSocket/MemorySubscriber.h | 29 +++ UWP/CoreUWP/CoreUWP.vcxproj | 2 + UWP/CoreUWP/CoreUWP.vcxproj.filters | 6 + android/jni/Android.mk | 1 + 9 files changed, 255 insertions(+) create mode 100644 Core/Debugger/WebSocket/MemorySubscriber.cpp create mode 100644 Core/Debugger/WebSocket/MemorySubscriber.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d43cb98324..8d4157062c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1482,6 +1482,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/Debugger/WebSocket/HLESubscriber.h Core/Debugger/WebSocket/LogBroadcaster.cpp Core/Debugger/WebSocket/LogBroadcaster.h + Core/Debugger/WebSocket/MemorySubscriber.cpp + Core/Debugger/WebSocket/MemorySubscriber.h Core/Debugger/WebSocket/SteppingBroadcaster.cpp Core/Debugger/WebSocket/SteppingBroadcaster.h Core/Debugger/WebSocket/SteppingSubscriber.cpp diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 91f0fd5830..baf1d89505 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -378,6 +378,7 @@ + @@ -909,6 +910,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index f3e5bea144..a5460b6d4f 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -713,6 +713,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket @@ -1352,6 +1355,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket diff --git a/Core/Debugger/WebSocket.cpp b/Core/Debugger/WebSocket.cpp index 6175279363..62d1879cda 100644 --- a/Core/Debugger/WebSocket.cpp +++ b/Core/Debugger/WebSocket.cpp @@ -55,6 +55,7 @@ #include "Core/Debugger/WebSocket/GPUBufferSubscriber.h" #include "Core/Debugger/WebSocket/GPURecordSubscriber.h" #include "Core/Debugger/WebSocket/HLESubscriber.h" +#include "Core/Debugger/WebSocket/MemorySubscriber.h" #include "Core/Debugger/WebSocket/SteppingSubscriber.h" typedef DebuggerSubscriber *(*SubscriberInit)(DebuggerEventHandlerMap &map); @@ -66,6 +67,7 @@ static const std::vector subscribers({ &WebSocketGPUBufferInit, &WebSocketGPURecordInit, &WebSocketHLEInit, + &WebSocketMemoryInit, &WebSocketSteppingInit, }); diff --git a/Core/Debugger/WebSocket/MemorySubscriber.cpp b/Core/Debugger/WebSocket/MemorySubscriber.cpp new file mode 100644 index 0000000000..6710b7492c --- /dev/null +++ b/Core/Debugger/WebSocket/MemorySubscriber.cpp @@ -0,0 +1,205 @@ +// Copyright (c) 2018- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "Common/StringUtils.h" +#include "Core/MemMap.h" +#include "Core/System.h" +#include "Core/Debugger/WebSocket/MemorySubscriber.h" +#include "Core/Debugger/WebSocket/WebSocketUtils.h" + +DebuggerSubscriber *WebSocketMemoryInit(DebuggerEventHandlerMap &map) { + // No need to bind or alloc state, these are all global. + map["memory.read_u8"] = &WebSocketMemoryReadU8; + map["memory.read_u16"] = &WebSocketMemoryReadU16; + map["memory.read_u32"] = &WebSocketMemoryReadU32; + map["memory.write_u8"] = &WebSocketMemoryWriteU8; + map["memory.write_u16"] = &WebSocketMemoryWriteU16; + map["memory.write_u32"] = &WebSocketMemoryWriteU32; + + return nullptr; +} + +// Read a byte from memory (memory.read_u8) +// +// Parameters: +// - address: unsigned integer +// +// Response (same event name): +// - value: unsigned integer +void WebSocketMemoryReadU8(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U8(addr)); +} + +// Read two bytes from memory (memory.read_u16) +// +// Parameters: +// - address: unsigned integer +// +// Response (same event name): +// - value: unsigned integer +void WebSocketMemoryReadU16(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U16(addr)); +} + +// Read four bytes from memory (memory.read_u32) +// +// Parameters: +// - address: unsigned integer +// +// Response (same event name): +// - value: unsigned integer +void WebSocketMemoryReadU32(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U32(addr)); +} + +// Write a byte to memory (memory.write_u8) +// +// Parameters: +// - address: unsigned integer +// - value: unsigned integer +// +// Response (same event name): +// - value: new value, unsigned integer +void WebSocketMemoryWriteU8(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr, val; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!req.ParamU32("value", &val, false)) { + req.Fail("No value given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + Memory::Write_U8(val, addr); + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U8(addr)); +} + +// Write two bytes to memory (memory.write_u16) +// +// Parameters: +// - address: unsigned integer +// - value: unsigned integer +// +// Response (same event name): +// - value: new value, unsigned integer +void WebSocketMemoryWriteU16(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr, val; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!req.ParamU32("value", &val, false)) { + req.Fail("No value given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + Memory::Write_U16(val, addr); + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U16(addr)); +} + +// Write four bytes to memory (memory.write_u32) +// +// Parameters: +// - address: unsigned integer +// - value: unsigned integer +// +// Response (same event name): +// - value: new value, unsigned integer +void WebSocketMemoryWriteU32(DebuggerRequest &req) { + auto memLock = Memory::Lock(); + uint32_t addr, val; + + if (!req.ParamU32("address", &addr, false)) { + req.Fail("No address given"); + return; + } + + if (!req.ParamU32("value", &val, false)) { + req.Fail("No value given"); + return; + } + + if (!Memory::IsValidAddress(addr)) { + req.Fail("Invalid address"); + return; + } + Memory::Write_U32(val, addr); + + JsonWriter &json = req.Respond(); + json.writeUint("value", Memory::Read_U32(addr)); +} diff --git a/Core/Debugger/WebSocket/MemorySubscriber.h b/Core/Debugger/WebSocket/MemorySubscriber.h new file mode 100644 index 0000000000..32e8e898c0 --- /dev/null +++ b/Core/Debugger/WebSocket/MemorySubscriber.h @@ -0,0 +1,29 @@ +// Copyright (c) 2018- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "Core/Debugger/WebSocket/WebSocketUtils.h" + +DebuggerSubscriber *WebSocketMemoryInit(DebuggerEventHandlerMap &map); + +void WebSocketMemoryReadU8(DebuggerRequest &req); +void WebSocketMemoryReadU16(DebuggerRequest &req); +void WebSocketMemoryReadU32(DebuggerRequest &req); +void WebSocketMemoryWriteU8(DebuggerRequest &req); +void WebSocketMemoryWriteU16(DebuggerRequest &req); +void WebSocketMemoryWriteU32(DebuggerRequest &req); diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 8d706d5566..4f9545c490 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -400,6 +400,7 @@ + @@ -618,6 +619,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index b4eaac21a4..781833645f 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -666,6 +666,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket @@ -1289,6 +1292,9 @@ Debugger\WebSocket + + Debugger\WebSocket + Debugger\WebSocket diff --git a/android/jni/Android.mk b/android/jni/Android.mk index f8651f3146..510c6a0a1d 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -324,6 +324,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/Debugger/WebSocket/GPURecordSubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/HLESubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/LogBroadcaster.cpp \ + $(SRC)/Core/Debugger/WebSocket/MemorySubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/SteppingBroadcaster.cpp \ $(SRC)/Core/Debugger/WebSocket/SteppingSubscriber.cpp \ $(SRC)/Core/Debugger/WebSocket/WebSocketUtils.cpp \ From 2f24a02323aba57850141326713891b05c07b2fc Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 26 Jul 2020 17:12:01 +0800 Subject: [PATCH 372/848] Add two ModuleMgrForKernel's nids used in Dissidia final fantasy chinese patch --- Core/HLE/sceKernelModule.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 77bf264e44..d53aea8e03 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2545,9 +2545,11 @@ const HLEFunction ModuleMgrForKernel[] = {0x50F0C1EC, &WrapV_UUUUU, "sceKernelStartModule", 'v', "xxxxx", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED | HLE_KERNEL_SYSCALL }, {0x977DE386, &WrapU_CUU, "sceKernelLoadModule", 'x', "sxx", HLE_KERNEL_SYSCALL }, {0xA1A78C58, &WrapU_CUU, "sceKernelLoadModuleForLoadExecVSHDisc", 'x', "sxx", HLE_KERNEL_SYSCALL }, //fix for tiger x dragon + {0xCC1D3699, &WrapU_UUU, "sceKernelSelfStopUnloadModule", 'x', "xxx", HLE_KERNEL_SYSCALL }, // used in Dissidia final fantasy chinese patch + {0XD1FF982A, &WrapU_UUUUU, "sceKernelStopModule", 'x', "xxxxx", HLE_KERNEL_SYSCALL | HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, // used in Dissidia final fantasy chinese patch {0x748CBED9, &WrapU_UU, "sceKernelQueryModuleInfo", 'x', "xx", HLE_KERNEL_SYSCALL }, {0x644395E2, &WrapU_UUU, "sceKernelGetModuleIdList", 'x', "xxx", HLE_KERNEL_SYSCALL }, - {0X2E0911AA, &WrapU_U, "sceKernelUnloadModule", 'x', "x" , HLE_KERNEL_SYSCALL }, + {0X2E0911AA, &WrapU_U, "sceKernelUnloadModule", 'x', "x" , HLE_KERNEL_SYSCALL }, }; void Register_ModuleMgrForUser() From eda5774408758ce1ee3b9e3360cb75effd279f0c Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 27 Jul 2020 09:51:53 +0700 Subject: [PATCH 373/848] Added more stub for some unimplemented sceNetApctl* functions --- Core/HLE/sceNet.cpp | 425 ++++++++++++++++++++++++++++++++++++++++++-- Core/HLE/sceNet.h | 98 +++++++++- 2 files changed, 511 insertions(+), 12 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 0df11e5c63..8851347ec4 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -48,6 +48,7 @@ static bool netInited; bool netInetInited; bool netApctlInited; +int netApctlStatus; u32 netDropRate = 0; u32 netDropDuration = 0; u32 netPoolAddr = 0; @@ -58,6 +59,8 @@ static struct SceNetMallocStat netMallocStat; static std::map apctlHandlers; +static struct SceNetApctlInfoInternal netApctlInfo; + static int InitLocalhostIP() { // find local IP addrinfo* localAddr; @@ -152,6 +155,7 @@ static void __UpdateApctlHandlers(int oldState, int newState, int flag, int erro for(std::map::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); ++it) { args[4] = it->second.argument; + // TODO: Need to make sure netApctlState is updated before calling the callback's mipscall so the game handler's subroutine can Get and make use the new state/info hleEnqueueCall(it->second.entryPoint, 5, args); } } @@ -195,6 +199,101 @@ void __NetDoState(PointerWrap &p) { } } +template std::string num2hex(I w, size_t hex_len) { + static const char* digits = "0123456789ABCDEF"; + std::string rc(hex_len, '0'); + for (size_t i = 0, j = (hex_len - 1) * 4; i < hex_len; ++i, j -= 4) + rc[i] = digits[(w >> j) & 0x0f]; + return rc; +} + +std::string error2str(u32 errorCode) { + std::string str = ""; + if (((errorCode >> 31) & 1) != 0) + str += "ERROR "; + if (((errorCode >> 30) & 1) != 0) + str += "CRITICAL "; + switch ((errorCode >> 16) & 0xfff) { + case 0x41: + str += "NET "; + break; + default: + str += "UNK"+num2hex(u16((errorCode >> 16) & 0xfff), 3)+" "; + } + switch ((errorCode >> 8) & 0xff) { + case 0x00: + str += "COMMON "; + break; + case 0x01: + str += "CORE "; + break; + case 0x02: + str += "INET "; + break; + case 0x03: + str += "POECLIENT "; + break; + case 0x04: + str += "RESOLVER "; + break; + case 0x05: + str += "DHCP "; + break; + case 0x06: + str += "ADHOC_AUTH "; + break; + case 0x07: + str += "ADHOC "; + break; + case 0x08: + str += "ADHOC_MATCHING "; + break; + case 0x09: + str += "NETCNF "; + break; + case 0x0a: + str += "APCTL "; + break; + case 0x0b: + str += "ADHOCCTL "; + break; + case 0x0c: + str += "UNKNOWN1 "; + break; + case 0x0d: + str += "WLAN "; + break; + case 0x0e: + str += "EAPOL "; + break; + case 0x0f: + str += "8021x "; + break; + case 0x10: + str += "WPA "; + break; + case 0x11: + str += "UNKNOWN2 "; + break; + case 0x12: + str += "TRANSFER "; + break; + case 0x13: + str += "ADHOC_DISCOVER "; + break; + case 0x14: + str += "ADHOC_DIALOG "; + break; + case 0x15: + str += "WISPR "; + break; + default: + str += "UNKNOWN"+num2hex(u8((errorCode >> 8) & 0xff))+" "; + } + str += num2hex(u8(errorCode & 0xff)); + return str; +} + static inline u32 AllocUser(u32 size, bool fromTop, const char *name) { u32 addr = userMemory.Alloc(size, fromTop, name); if (addr == -1) @@ -449,11 +548,38 @@ int sceNetInetTerm() { return 0; } -static int sceNetApctlInit() { +static int sceNetApctlInit(int stackSize, int initPriority) { ERROR_LOG(SCENET, "UNIMPL sceNetApctlInit()"); if (netApctlInited) return ERROR_NET_APCTL_ALREADY_INITIALIZED; + + memset(&netApctlInfo, 0, sizeof(netApctlInfo)); + // Set default values + truncate_cpy(netApctlInfo.name, sizeof(netApctlInfo.name), "Wifi"); + truncate_cpy(netApctlInfo.ssid, sizeof(netApctlInfo.ssid), "Wifi"); + memcpy(netApctlInfo.bssid, "\1\1\2\2\3\3", sizeof(netApctlInfo.bssid)); + netApctlInfo.ssidLength = 4; + netApctlInfo.strength = 99; + netApctlInfo.channel = g_Config.iWlanAdhocChannel; + if (netApctlInfo.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) netApctlInfo.channel = defaultWlanChannel; + // Get Local IP Address + sockaddr_in sockAddr; + getLocalIp(&sockAddr); + char ipstr[INET_ADDRSTRLEN] = "127.0.0.1"; // default + inet_ntop(AF_INET, &sockAddr.sin_addr, ipstr, sizeof(ipstr)); + truncate_cpy(netApctlInfo.ip, sizeof(netApctlInfo.ip), ipstr); + // Change the last number to 1 to indicate a common dns server/internet gateway + ((u8*)&sockAddr.sin_addr.s_addr)[3] = 1; + inet_ntop(AF_INET, &sockAddr.sin_addr, ipstr, sizeof(ipstr)); + truncate_cpy(netApctlInfo.gateway, sizeof(netApctlInfo.gateway), ipstr); + truncate_cpy(netApctlInfo.primaryDns, sizeof(netApctlInfo.primaryDns), ipstr); + truncate_cpy(netApctlInfo.secondaryDns, sizeof(netApctlInfo.secondaryDns), "8.8.8.8"); + truncate_cpy(netApctlInfo.subNetMask, sizeof(netApctlInfo.subNetMask), "255.255.255.0"); + + // TODO: Create APctl fake-Thread + netApctlInited = true; + netApctlStatus = PSP_NET_APCTL_STATE_DISCONNECTED; return 0; } @@ -461,10 +587,96 @@ static int sceNetApctlInit() { int sceNetApctlTerm() { ERROR_LOG(SCENET, "UNIMPL sceNeApctlTerm()"); netApctlInited = false; + netApctlStatus = PSP_NET_APCTL_STATE_DISCONNECTED; return 0; } +static int sceNetApctlGetInfo(int code, u32 pInfoAddr) { + WARN_LOG(SCENET, "UNTESTED %s(%i, %08x)", __FUNCTION__, code, pInfoAddr); + + if (!netApctlInited) + return hleLogError(SCENET, ERROR_NET_APCTL_NOT_IN_BSS, "apctl not in bss"); // Only have valid info after joining an AP and got an IP, right? + + if (!Memory::IsValidAddress(pInfoAddr)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + + u8* info = Memory::GetPointer(pInfoAddr); // FIXME: Points to a union instead of a struct thus each field have the same address + + switch (code) { + case PSP_NET_APCTL_INFO_PROFILE_NAME: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.name); + DEBUG_LOG(SCENET, "ApctlInfo - ProfileName: %s", netApctlInfo.name); + break; + case PSP_NET_APCTL_INFO_BSSID: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.bssid); + DEBUG_LOG(SCENET, "ApctlInfo - BSSID: %s", mac2str((SceNetEtherAddr*)&netApctlInfo.bssid).c_str()); + break; + case PSP_NET_APCTL_INFO_SSID: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.ssid); + DEBUG_LOG(SCENET, "ApctlInfo - SSID: %s", netApctlInfo.ssid); + break; + case PSP_NET_APCTL_INFO_SSID_LENGTH: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.ssidLength); + break; + case PSP_NET_APCTL_INFO_SECURITY_TYPE: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.securityType); + break; + case PSP_NET_APCTL_INFO_STRENGTH: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.strength); + break; + case PSP_NET_APCTL_INFO_CHANNEL: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.channel); + break; + case PSP_NET_APCTL_INFO_POWER_SAVE: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.powerSave); + break; + case PSP_NET_APCTL_INFO_IP: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.ip); + DEBUG_LOG(SCENET, "ApctlInfo - IP: %s", netApctlInfo.ip); + break; + case PSP_NET_APCTL_INFO_SUBNETMASK: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.subNetMask); + DEBUG_LOG(SCENET, "ApctlInfo - SubNet Mask: %s", netApctlInfo.subNetMask); + break; + case PSP_NET_APCTL_INFO_GATEWAY: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.gateway); + DEBUG_LOG(SCENET, "ApctlInfo - Gateway IP: %s", netApctlInfo.gateway); + break; + case PSP_NET_APCTL_INFO_PRIMDNS: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.primaryDns); + DEBUG_LOG(SCENET, "ApctlInfo - Primary DNS: %s", netApctlInfo.primaryDns); + break; + case PSP_NET_APCTL_INFO_SECDNS: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.secondaryDns); + DEBUG_LOG(SCENET, "ApctlInfo - Secondary DNS: %s", netApctlInfo.secondaryDns); + break; + case PSP_NET_APCTL_INFO_USE_PROXY: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.useProxy); + break; + case PSP_NET_APCTL_INFO_PROXY_URL: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.proxyUrl); + DEBUG_LOG(SCENET, "ApctlInfo - Proxy URL: %s", netApctlInfo.proxyUrl); + break; + case PSP_NET_APCTL_INFO_PROXY_PORT: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.proxyPort); + break; + case PSP_NET_APCTL_INFO_8021_EAP_TYPE: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.eapType); + break; + case PSP_NET_APCTL_INFO_START_BROWSER: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.startBrowser); + break; + case PSP_NET_APCTL_INFO_WIFISP: + Memory::WriteStruct(pInfoAddr, &netApctlInfo.wifisp); + break; + default: + return hleLogError(SCENET, ERROR_NET_APCTL_INVALID_CODE, "apctl invalid code"); + } + + return hleLogSuccessI(SCENET, 0); +} + // TODO: How many handlers can the PSP actually have for Apctl? // TODO: Should we allow the same handler to be added more than once? static u32 sceNetApctlAddHandler(u32 handlerPtr, u32 handlerArg) { @@ -615,20 +827,201 @@ static int sceNetInetConnect(int socket, u32 sockAddrInternetPtr, int addressLen return -1; } +static int sceNetApctlConnect(int connIndex) { + ERROR_LOG(SCENET, "UNIMPL %s(%i)", __FUNCTION__, connIndex); + + netApctlStatus = PSP_NET_APCTL_STATE_JOINING; + __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_CONNECT_REQUEST, 0); + return 0; +} + static int sceNetApctlDisconnect() { ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); // Like its 'sister' function sceNetAdhocctlDisconnect, we need to alert Apctl handlers that a disconnect took place // or else games like Phantasy Star Portable 2 will hang at certain points (e.g. returning to the main menu after trying to connect to PSN). + netApctlStatus = PSP_NET_APCTL_STATE_DISCONNECTED; __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_DISCONNECT_REQUEST, 0); return 0; } +static int sceNetApctlGetState(u32 pStateAddr) { + WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, pStateAddr); + + //if (!netApctlInited) return hleLogError(SCENET, ERROR_NET_APCTL_NOT_IN_BSS, "apctl not in bss"); + + // Valid Arguments + if (Memory::IsValidAddress(pStateAddr)) { + // Return Thread Status + Memory::Write_U32(netApctlStatus, pStateAddr); + // Return Success + return hleLogSuccessI(SCENET, 0); + } + + return hleLogError(SCENET, -1, "apctl invalid arg"); +} + +static int sceNetApctlScanUser() { + ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); + + // Scan probably only works when not in connected state, right? + if (netApctlStatus != PSP_NET_APCTL_STATE_DISCONNECTED) + return hleLogError(SCENET, ERROR_NET_APCTL_NOT_DISCONNECTED, "apctl not disconnected"); + + netApctlStatus = PSP_NET_APCTL_STATE_SCANNING; + __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_SCAN_REQUEST, 0); + return 0; +} + +static int sceNetApctlGetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) { + WARN_LOG(SCENET, "UNTESTED %s(%08x, %08x)", __FUNCTION__, sizeAddr, bufAddr); + + const int userInfoSize = 8; + int entries = 1; + if (!Memory::IsValidAddress(sizeAddr)) + hleLogError(SCENET, -1, "apctl invalid arg"); + + int size = Memory::Read_U32(sizeAddr); + // Return size required + Memory::Write_U32(entries * userInfoSize, sizeAddr); + + if (bufAddr != 0 && Memory::IsValidAddress(sizeAddr)) { + int offset = 0; + for (int i = 0; i < entries; i++) { + // Check if enough space available to write the next structure + if (offset + userInfoSize > size) { + break; + } + + DEBUG_LOG(SCENET, "%s returning %d at %08x", __FUNCTION__, i, bufAddr + offset); + + // Pointer to next Network structure in list + Memory::Write_U32((i+1)*userInfoSize + bufAddr, bufAddr + offset); + offset += 4; + + // Entry ID + Memory::Write_U32(i, bufAddr + offset); + offset += 4; + } + // Fix the last Pointer + if (offset > 0) + Memory::Write_U32(0, bufAddr + offset - userInfoSize); + } + + return hleLogWarning(SCENET, 0, "untested"); +} + +static int sceNetApctlGetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) { + WARN_LOG(SCENET, "UNTESTED %s(%i, %i, %08x)", __FUNCTION__, entryId, infoId, resultAddr); + + if (!Memory::IsValidAddress(resultAddr)) + hleLogError(SCENET, -1, "apctl invalid arg"); + + switch (infoId) { + case PSP_NET_APCTL_DESC_IBSS: // IBSS, 6 bytes + Memory::WriteStruct(resultAddr, &netApctlInfo.bssid); + break; + case PSP_NET_APCTL_DESC_SSID_NAME: + // Return 32 bytes + Memory::WriteStruct(resultAddr, &netApctlInfo.ssid); + break; + case PSP_NET_APCTL_DESC_SSID_NAME_LENGTH: + // Return one 32-bit value + Memory::WriteStruct(resultAddr, &netApctlInfo.ssidLength); + break; + case PSP_NET_APCTL_DESC_SIGNAL_STRENGTH: + // Return 1 byte + Memory::WriteStruct(resultAddr, &netApctlInfo.strength); + break; + case PSP_NET_APCTL_DESC_SECURITY: + // Return one 32-bit value + Memory::WriteStruct(resultAddr, &netApctlInfo.securityType); + break; + default: + return hleLogError(SCENET, ERROR_NET_APCTL_INVALID_CODE, "unknown info id"); + } + + return hleLogWarning(SCENET, 0, "untested"); +} + +static int sceNetApctlScanSSID2() { + ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); + + // Scan probably only works when not in connected state, right? + if (netApctlStatus != PSP_NET_APCTL_STATE_DISCONNECTED) + return hleLogError(SCENET, ERROR_NET_APCTL_NOT_DISCONNECTED, "apctl not disconnected"); + + netApctlStatus = PSP_NET_APCTL_STATE_SCANNING; + __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_SCAN_REQUEST, 0); + return 0; +} + +static int sceNetApctlGetBSSDescIDList2(u32 Arg1, u32 Arg2, u32 Arg3, u32 Arg4) { + return hleLogError(SCENET, 0, "unimplemented"); +} + +static int sceNetApctlGetBSSDescEntry2(u32 Arg1, u32 Arg2, u32 Arg3, u32 Arg4) { + return hleLogError(SCENET, 0, "unimplemented"); +} + static int sceNetResolverInit() { ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); return 0; } +static int sceNetApctlAddInternalHandler(u32 handlerPtr, u32 handlerArg) { + ERROR_LOG(SCENET, "UNIMPL %s(%08x, %08x)", __FUNCTION__, handlerPtr, handlerArg); + // This seems to be a 2nd kind of handler + return sceNetApctlAddHandler(handlerPtr, handlerArg); +} + +static int sceNetApctlDelInternalHandler(u32 handlerID) { + ERROR_LOG(SCENET, "UNIMPL %s(%i)", __FUNCTION__, handlerID); + // This seems to be a 2nd kind of handler + return sceNetApctlDelHandler(handlerID); +} + +static int sceNetApctl_A7BB73DF(u32 handlerPtr, u32 handlerArg) { + ERROR_LOG(SCENET, "UNIMPL %s(%08x, %08x)", __FUNCTION__, handlerPtr, handlerArg); + // This seems to be a 3rd kind of handler + return sceNetApctlAddHandler(handlerPtr, handlerArg); +} + +static int sceNetApctl_6F5D2981(u32 handlerID) { + ERROR_LOG(SCENET, "UNIMPL %s(%i)", __FUNCTION__, handlerID); + // This seems to be a 3rd kind of handler + return sceNetApctlDelHandler(handlerID); +} + +static int sceNetApctl_lib2_69745F0A(int handlerId) { + return hleLogError(SCENET, 0, "unimplemented"); +} + +static int sceNetApctl_lib2_4C19731F(int code, u32 pInfoAddr) { + ERROR_LOG(SCENET, "UNIMPL %s(%i, %08x)", __FUNCTION__, code, pInfoAddr); + return sceNetApctlGetInfo(code, pInfoAddr); +} + +static int sceNetApctlScan() { + ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); + return sceNetApctlScanUser(); +} + +static int sceNetApctlGetBSSDescIDList(u32 sizeAddr, u32 bufAddr) { + ERROR_LOG(SCENET, "UNIMPL %s(%08x, %08x)", __FUNCTION__, sizeAddr, bufAddr); + return sceNetApctlGetBSSDescIDListUser(sizeAddr, bufAddr); +} + +static int sceNetApctlGetBSSDescEntry(int entryId, int infoId, u32 resultAddr) { + ERROR_LOG(SCENET, "UNIMPL %s(%i, %i, %08x)", __FUNCTION__, entryId, infoId, resultAddr); + return sceNetApctlGetBSSDescEntryUser(entryId, infoId, resultAddr); +} + +static int sceNetApctl_lib2_C20A144C(int connIndex, u32 ps3MacAddressPtr) { + ERROR_LOG(SCENET, "UNIMPL %s(%i, %08x)", __FUNCTION__, connIndex, ps3MacAddressPtr); + return sceNetApctlConnect(connIndex); +} + static int sceNetUpnpInit(int unknown1,int unknown2) { @@ -734,20 +1127,30 @@ const HLEFunction sceNetInet[] = { }; const HLEFunction sceNetApctl[] = { - {0XCFB957C6, nullptr, "sceNetApctlConnect", '?', "" }, + {0XCFB957C6, &WrapI_I, "sceNetApctlConnect", 'i', "i" }, {0X24FE91A1, &WrapI_V, "sceNetApctlDisconnect", 'i', "" }, - {0X5DEAC81B, nullptr, "sceNetApctlGetState", '?', "" }, + {0X5DEAC81B, &WrapI_U, "sceNetApctlGetState", 'i', "x" }, {0X8ABADD51, &WrapU_UU, "sceNetApctlAddHandler", 'x', "xx" }, - {0XE2F91F9B, &WrapI_V, "sceNetApctlInit", 'i', "" }, + {0XE2F91F9B, &WrapI_II, "sceNetApctlInit", 'i', "ii" }, {0X5963991B, &WrapI_U, "sceNetApctlDelHandler", 'i', "x" }, {0XB3EDD0EC, &WrapI_V, "sceNetApctlTerm", 'i', "" }, - {0X2BEFDF23, nullptr, "sceNetApctlGetInfo", '?', "" }, - {0XA3E77E13, nullptr, "sceNetApctlScanSSID2", '?', "" }, - {0XE9B2E5E6, nullptr, "sceNetApctlScanUser", '?', "" }, - {0XF25A5006, nullptr, "sceNetApctlGetBSSDescIDList2", '?', "" }, - {0X2935C45B, nullptr, "sceNetApctlGetBSSDescEntry2", '?', "" }, - {0X04776994, nullptr, "sceNetApctlGetBSSDescEntryUser", '?', "" }, - {0X6BDDCB8C, nullptr, "sceNetApctlGetBSSDescIDListUser", '?', "" }, + {0X2BEFDF23, &WrapI_IU, "sceNetApctlGetInfo", 'i', "ix" }, + {0XA3E77E13, &WrapI_V, "sceNetApctlScanSSID2", 'i', "" }, + {0XE9B2E5E6, &WrapI_V, "sceNetApctlScanUser", 'i', "" }, + {0XF25A5006, &WrapI_UUUU, "sceNetApctlGetBSSDescIDList2", 'i', "xxxx" }, + {0X2935C45B, &WrapI_UUUU, "sceNetApctlGetBSSDescEntry2", 'i', "xxxx" }, + {0X04776994, &WrapI_IIU, "sceNetApctlGetBSSDescEntryUser", 'i', "iix" }, + {0X6BDDCB8C, &WrapI_UU, "sceNetApctlGetBSSDescIDListUser", 'i', "xx" }, + {0X7CFAB990, &WrapI_UU, "sceNetApctlAddInternalHandler", 'i', "xx" }, + {0XE11BAFAB, &WrapI_U, "sceNetApctlDelInternalHandler", 'i', "x" }, + {0XA7BB73DF, &WrapI_UU, "sceNetApctl_A7BB73DF", 'i', "xx" }, + {0X6F5D2981, &WrapI_U, "sceNetApctl_6F5D2981", 'i', "x" }, + {0X69745F0A, &WrapI_I, "sceNetApctl_lib2_69745F0A", 'i', "i" }, + {0X4C19731F, &WrapI_IU, "sceNetApctl_lib2_4C19731F", 'i', "ix" }, + {0XB3CF6849, &WrapI_V, "sceNetApctlScan", 'i', "" }, + {0X0C7FFA5C, &WrapI_UU, "sceNetApctlGetBSSDescIDList", 'i', "xx" }, + {0X96BEB231, &WrapI_IIU, "sceNetApctlGetBSSDescEntry", 'i', "iix" }, + {0XC20A144C, &WrapI_IU, "sceNetApctl_lib2_C20A144C", 'i', "ix" }, }; const HLEFunction sceWlanDrv[] = { diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index 84615a2427..d8514491f8 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -17,6 +17,7 @@ #pragma once +#include #include "Core/HLE/proAdhoc.h" // Option Names @@ -49,12 +50,74 @@ enum { ERROR_NET_RESOLVER_INVALID_HOST = 0x80410414, ERROR_NET_APCTL_ALREADY_INITIALIZED = 0x80410a01, + ERROR_NET_APCTL_INVALID_CODE = 0x80410a02, + ERROR_NET_APCTL_INVALID_IP = 0x80410a03, + ERROR_NET_APCTL_NOT_DISCONNECTED = 0x80410a04, + ERROR_NET_APCTL_NOT_IN_BSS = 0x80410a05, + ERROR_NET_APCTL_WLAN_SWITCH_OFF = 0x80410a06, + ERROR_NET_APCTL_WLAN_BEACON_LOST = 0x80410a07, + ERROR_NET_APCTL_WLAN_DISASSOCIATION = 0x80410a08, + ERROR_NET_APCTL_INVALID_ID = 0x80410a09, + ERROR_NET_APCTL_WLAN_SUSPENDED = 0x80410a0a, + ERROR_NET_APCTL_TIMEOUT = 0x80410a0b, }; enum { - PSP_NET_APCTL_EVENT_DISCONNECT_REQUEST = 5, + PSP_NET_APCTL_STATE_DISCONNECTED = 0, + PSP_NET_APCTL_STATE_SCANNING = 1, + PSP_NET_APCTL_STATE_JOINING = 2, + PSP_NET_APCTL_STATE_GETTING_IP = 3, + PSP_NET_APCTL_STATE_GOT_IP = 4, + PSP_NET_APCTL_STATE_EAP_AUTH = 5, + PSP_NET_APCTL_STATE_KEY_EXCHANGE = 6 }; +enum { + PSP_NET_APCTL_EVENT_CONNECT_REQUEST = 0, + PSP_NET_APCTL_EVENT_SCAN_REQUEST = 1, + PSP_NET_APCTL_EVENT_SCAN_COMPLETE = 2, + PSP_NET_APCTL_EVENT_ESTABLISHED = 3, + PSP_NET_APCTL_EVENT_GET_IP = 4, + PSP_NET_APCTL_EVENT_DISCONNECT_REQUEST = 5, + PSP_NET_APCTL_EVENT_ERROR = 6, + PSP_NET_APCTL_EVENT_INFO = 7, + PSP_NET_APCTL_EVENT_EAP_AUTH = 8, + PSP_NET_APCTL_EVENT_KEY_EXCHANGE = 9, + PSP_NET_APCTL_EVENT_RECONNECT = 10 +}; + +#define PSP_NET_APCTL_INFO_PROFILE_NAME 0 +#define PSP_NET_APCTL_INFO_BSSID 1 +#define PSP_NET_APCTL_INFO_SSID 2 +#define PSP_NET_APCTL_INFO_SSID_LENGTH 3 +#define PSP_NET_APCTL_INFO_SECURITY_TYPE 4 +#define PSP_NET_APCTL_INFO_STRENGTH 5 +#define PSP_NET_APCTL_INFO_CHANNEL 6 +#define PSP_NET_APCTL_INFO_POWER_SAVE 7 +#define PSP_NET_APCTL_INFO_IP 8 +#define PSP_NET_APCTL_INFO_SUBNETMASK 9 +#define PSP_NET_APCTL_INFO_GATEWAY 10 +#define PSP_NET_APCTL_INFO_PRIMDNS 11 +#define PSP_NET_APCTL_INFO_SECDNS 12 +#define PSP_NET_APCTL_INFO_USE_PROXY 13 +#define PSP_NET_APCTL_INFO_PROXY_URL 14 +#define PSP_NET_APCTL_INFO_PROXY_PORT 15 +#define PSP_NET_APCTL_INFO_8021_EAP_TYPE 16 +#define PSP_NET_APCTL_INFO_START_BROWSER 17 +#define PSP_NET_APCTL_INFO_WIFISP 18 + +#define PSP_NET_APCTL_INFO_SECURITY_TYPE_NONE 0 +#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WEP 1 +#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WPA 2 +#define PSP_NET_APCTL_INFO_SECURITY_TYPE_UNSUPPORTED 3 +#define PSP_NET_APCTL_INFO_SECURITY_TYPE_WPA_AES 4 + +#define PSP_NET_APCTL_DESC_IBSS 0 +#define PSP_NET_APCTL_DESC_SSID_NAME 1 +#define PSP_NET_APCTL_DESC_SSID_NAME_LENGTH 2 +#define PSP_NET_APCTL_DESC_SIGNAL_STRENGTH 4 +#define PSP_NET_APCTL_DESC_SECURITY 5 + #ifdef _MSC_VER #pragma pack(push,1) #endif @@ -85,10 +148,39 @@ typedef struct ProductStruct { // Similar to SceNetAdhocctlAdhocId ? s32_le unknown; // Unknown, set to 0 // Product Type ? char product[PRODUCT_CODE_LENGTH]; // Game ID (Example: ULUS10000) } PACK ProductStruct; + #ifdef _MSC_VER #pragma pack(pop) #endif +typedef void(*sceNetApctlHandler)(int oldState, int newState, int event, int error, void* pArg); + +#define APCTL_PROFILENAME_MAXLEN 64 +#define APCTL_SSID_MAXLEN 32 +#define APCTL_IPADDR_MAXLEN 16 +#define APCTL_URL_MAXLEN 128 +typedef struct SceNetApctlInfoInternal { // Using struct instead of union for internal use + char name[APCTL_PROFILENAME_MAXLEN]; + u8 bssid[ETHER_ADDR_LEN]; + char ssid[APCTL_SSID_MAXLEN]; + unsigned int ssidLength; // ssid string length (excluding null terminator) + unsigned int securityType; // a value of PSP_NET_APCTL_INFO_SECURITY_TYPE_NONE..PSP_NET_APCTL_INFO_SECURITY_TYPE_WPA? + u8 strength; // Signal strength in % + u8 channel; + u8 powerSave; // 1 on, 0 off + char ip[APCTL_IPADDR_MAXLEN]; // PSP's IP + char subNetMask[APCTL_IPADDR_MAXLEN]; + char gateway[APCTL_IPADDR_MAXLEN]; + char primaryDns[APCTL_IPADDR_MAXLEN]; + char secondaryDns[APCTL_IPADDR_MAXLEN]; + unsigned int useProxy; // 1 for proxy, 0 for no proxy + char proxyUrl[APCTL_URL_MAXLEN]; + unsigned short proxyPort; + unsigned int eapType; // 0 is none, 1 is EAP-MD5 + unsigned int startBrowser; // 1 = start browser + unsigned int wifisp; // 1 if connection is for Wifi service providers (WISP) for sharing internet connection +} SceNetApctlInfoInternal; + struct ApctlHandler { u32 entryPoint; u32 argument; @@ -98,6 +190,10 @@ class PointerWrap; extern bool netInetInited; extern bool netApctlInited; +extern int netApctlStatus; + +template std::string num2hex(I w, size_t hex_len = sizeof(I) << 1); +std::string error2str(u32 errorcode); void Register_sceNet(); void Register_sceWlanDrv(); From f025d2deeeafe313b5a927cb3d3f2a635e0177d0 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Mon, 27 Jul 2020 21:18:38 +0800 Subject: [PATCH 374/848] Add some threadman's nids used in #13205 --- Core/HLE/sceKernel.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 70d1f13ca6..3115991370 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -869,6 +869,11 @@ const HLEFunction ThreadManForUser[] = // Shouldn't hook this up. No games should import this function manually and call it. // {0x6E9EA350, _sceKernelReturnFromCallback,"_sceKernelReturnFromCallback"}, + {0X71EC4271, &WrapU_UU, "sceKernelLibcGettimeofday", 'x', "xx" }, + {0X79D1C3FA, &WrapI_V, "sceKernelDcacheWritebackAll", 'i', "" }, + {0X91E4F6A7, &WrapU_V, "sceKernelLibcClock", 'x', "" }, + {0XB435DEC5, &WrapI_V, "sceKernelDcacheWritebackInvalidateAll", 'i', "" }, + }; const HLEFunction ThreadManForKernel[] = From 49ab71dc7c44bb1f86be7470b07031bd1728ffa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 25 Jul 2020 19:07:57 +0200 Subject: [PATCH 375/848] ExceptionHandler uninstall: Don't crash if no exception handler already installed. --- Common/ExceptionHandlerSetup.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 9ff5255237..b73bcbdc44 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -77,9 +77,7 @@ static LONG NTAPI GlobalExceptionHandler(PEXCEPTION_POINTERS pPtrs) { } void InstallExceptionHandler(BadAccessHandler badAccessHandler) { - // Make sure this is only called once per process execution - // Instead, could make a Uninstall function, but whatever.. - if (g_badAccessHandler) { + if (g_vectoredExceptionHandle) { g_badAccessHandler = badAccessHandler; return; } @@ -90,9 +88,12 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { } void UninstallExceptionHandler() { - RemoveVectoredExceptionHandler(g_vectoredExceptionHandle); + if (g_vectoredExceptionHandle) { + RemoveVectoredExceptionHandler(g_vectoredExceptionHandle); + INFO_LOG(SYSTEM, "Removed exception handler"); + g_vectoredExceptionHandle = nullptr; + } g_badAccessHandler = nullptr; - INFO_LOG(SYSTEM, "Removed exception handler"); } #elif defined(__APPLE__) @@ -275,11 +276,15 @@ static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context) { } void InstallExceptionHandler(BadAccessHandler badAccessHandler) { + if (!badAccessHandler) { + return; + } if (g_badAccessHandler) { g_badAccessHandler = badAccessHandler; return; } - NOTICE_LOG(SYSTEM, "Installed exception handler"); + + INFO_LOG(SYSTEM, "Installed exception handler"); g_badAccessHandler = badAccessHandler; stack_t signal_stack; @@ -305,6 +310,9 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { } void UninstallExceptionHandler() { + if (!g_badAccessHandler) { + return; + } stack_t signal_stack, old_stack; signal_stack.ss_flags = SS_DISABLE; if (!sigaltstack(&signal_stack, &old_stack) && !(old_stack.ss_flags & SS_DISABLE)) { @@ -314,7 +322,7 @@ void UninstallExceptionHandler() { #ifdef __APPLE__ sigaction(SIGBUS, &old_sa_bus, nullptr); #endif - NOTICE_LOG(SYSTEM, "Uninstalled exception handler"); + INFO_LOG(SYSTEM, "Uninstalled exception handler"); g_badAccessHandler = nullptr; } From fbaba82c6834617eb50055f2ba47338af08d22d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 27 Jul 2020 11:33:23 +0200 Subject: [PATCH 376/848] Reduce use of multi-byte char switches.. saw this go wrong when stepping!?! --- Core/Loaders.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index a15b8e3c98..97eca751ee 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -127,17 +127,13 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader) { u32 psar_offset = 0, psar_id = 0; u32 _id = id; - switch (_id) { - case 'PBP\x00': + if (!memcmp(&_id, "PK\x03\x04", 4) || !memcmp(&_id, "PK\x05\x06", 4) || !memcmp(&_id, "PK\x07\x08", 4)) { + return IdentifiedFileType::ARCHIVE_ZIP; + } else if (!memcmp(&_id, "\x00PBP", 4)) { fileLoader->ReadAt(0x24, 4, 1, &psar_offset); fileLoader->ReadAt(psar_offset, 4, 1, &psar_id); - break; - case '!raR': + } else if (!memcmp(&_id, "Rar!", 4)) { return IdentifiedFileType::ARCHIVE_RAR; - case '\x04\x03KP': - case '\x06\x05KP': - case '\x08\x07KP': - return IdentifiedFileType::ARCHIVE_ZIP; } if (id == 'FLE\x7F') { From 0939804a23d27fd5feb1ca898f8971e68aeb85ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 27 Jul 2020 16:53:02 +0200 Subject: [PATCH 377/848] Don't trust the messy error checking in EmuScreen with figuring out what to do with zip files. Ran into multiple odd bugs, the PSP init process really needs a rework.. --- UI/EmuScreen.cpp | 9 --------- UI/MainScreen.cpp | 29 ++++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 5c34224cc0..31936b64dd 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -77,7 +77,6 @@ #include "UI/ControlMappingScreen.h" #include "UI/DisplayLayoutScreen.h" #include "UI/GameSettingsScreen.h" -#include "UI/InstallZipScreen.h" #include "UI/ProfilerDraw.h" #include "UI/DiscordIntegration.h" #include "UI/ChatScreen.h" @@ -1163,14 +1162,6 @@ void EmuScreen::update() { } if (errorMessage_.size()) { - // Special handling for ZIP files. It's not very robust to check an error message but meh, - // at least it's pre-translation. - if (errorMessage_.find("ZIP") != std::string::npos) { - screenManager()->push(new InstallZipScreen(gamePath_)); - errorMessage_ = ""; - quit_ = true; - return; - } auto err = GetI18NCategory("Error"); std::string errLoadingFile = gamePath_ + "\n"; errLoadingFile.append(err->T("Error loading file", "Could not load game")); diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 43535913d7..83c8b28afb 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -52,6 +52,7 @@ #include "UI/DisplayLayoutScreen.h" #include "UI/SavedataScreen.h" #include "UI/Store.h" +#include "UI/InstallZipScreen.h" #include "Core/Config.h" #include "Core/Loaders.h" #include "GPU/GPUInterface.h" @@ -74,6 +75,29 @@ bool MainScreen::showHomebrewTab = false; +bool LaunchFile(ScreenManager *screenManager, std::string path) { + // Depending on the file type, we don't want to launch EmuScreen at all. + auto loader = ConstructFileLoader(path); + if (!loader) { + return false; + } + + IdentifiedFileType type = Identify_File(loader); + delete loader; + + switch (type) { + case IdentifiedFileType::ARCHIVE_ZIP: + // Special handling for ZIP files. It's not very robust to check an error message but meh, + // at least it's pre-translation. + screenManager->push(new InstallZipScreen(path)); + break; + default: + // Let the EmuScreen take care of it. + screenManager->switchScreen(new EmuScreen(path)); + break; + } +} + static bool IsTempPath(const std::string &str) { std::string item = str; @@ -1155,7 +1179,7 @@ void MainScreen::sendMessage(const char *message, const char *value) { if (screenManager()->topScreen() == this) { if (!strcmp(message, "boot")) { - screenManager()->switchScreen(new EmuScreen(value)); + LaunchFile(screenManager(), std::string(value)); } if (!strcmp(message, "browse_folderSelect")) { int tab = tabHolder_->GetCurrentTab(); @@ -1304,8 +1328,7 @@ UI::EventReturn MainScreen::OnGameSelectedInstant(UI::EventParams &e) { #else std::string path = e.s; #endif - // Go directly into the game. - screenManager()->switchScreen(new EmuScreen(path)); + LaunchFile(screenManager(), path); return UI::EVENT_DONE; } From efdd597cd1aeb0a9df42d535fb267bd0fd53e505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 27 Jul 2020 17:00:46 +0200 Subject: [PATCH 378/848] Remove wrong comment --- UI/MainScreen.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 83c8b28afb..03d89ce7da 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -87,8 +87,6 @@ bool LaunchFile(ScreenManager *screenManager, std::string path) { switch (type) { case IdentifiedFileType::ARCHIVE_ZIP: - // Special handling for ZIP files. It's not very robust to check an error message but meh, - // at least it's pre-translation. screenManager->push(new InstallZipScreen(path)); break; default: From 51f080dfd08769d8bf3cb65c1abd6bb7dbed4a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 27 Jul 2020 18:22:23 +0200 Subject: [PATCH 379/848] Remove unnecessary vector from thin3d_gl texture handling. --- ext/native/thin3d/thin3d.h | 4 ++- ext/native/thin3d/thin3d_gl.cpp | 50 ++++++++++++++++----------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index f78dbf8f87..395687f433 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -301,6 +301,8 @@ enum class Event { PRESENTED, }; +constexpr uint32_t MAX_TEXTURE_SLOTS = 2; + struct FramebufferDesc { int width; int height; @@ -610,7 +612,7 @@ public: // Binding a zero render target means binding the backbuffer. virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) = 0; - // color must be 0, for now. + // binding must be < MAX_TEXTURE_SLOTS (0, 1 are okay if it's 2). virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) = 0; // deprecated diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 47d54cd354..6f697b251f 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -383,8 +383,8 @@ public: void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override; void BindSamplerStates(int start, int count, SamplerState **states) override { - if (boundSamplers_.size() < (size_t)(start + count)) { - boundSamplers_.resize(start + count); + if (start + count >= MAX_TEXTURE_SLOTS) { + return; } for (int i = 0; i < count; i++) { int index = i + start; @@ -488,9 +488,8 @@ private: GLRenderManager renderManager_; - std::vector boundSamplers_; - OpenGLTexture *boundTextures_[8]{}; - int maxTextures_ = 0; + OpenGLSamplerState *boundSamplers_[MAX_TEXTURE_SLOTS]{}; + OpenGLTexture *boundTextures_[MAX_TEXTURE_SLOTS]{}; DeviceCaps caps_{}; // Bound state @@ -604,7 +603,6 @@ OpenGLContext::~OpenGLContext() { for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { renderManager_.DeletePushBuffer(frameData_[i].push); } - boundSamplers_.clear(); } void OpenGLContext::BeginFrame() { @@ -998,7 +996,9 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { } void OpenGLContext::BindTextures(int start, int count, Texture **textures) { - maxTextures_ = std::max(maxTextures_, start + count); + if (start + count >= MAX_TEXTURE_SLOTS) { + return; + } for (int i = start; i < start + count; i++) { OpenGLTexture *glTex = static_cast(textures[i - start]); if (!glTex) { @@ -1012,25 +1012,24 @@ void OpenGLContext::BindTextures(int start, int count, Texture **textures) { } void OpenGLContext::ApplySamplers() { - for (int i = 0; i < maxTextures_; i++) { - if ((int)boundSamplers_.size() > i && boundSamplers_[i]) { - const OpenGLSamplerState *samp = boundSamplers_[i]; - const OpenGLTexture *tex = boundTextures_[i]; - if (!tex) - continue; - GLenum wrapS; - GLenum wrapT; - if (tex->CanWrap()) { - wrapS = samp->wrapU; - wrapT = samp->wrapV; - } else { - wrapS = GL_CLAMP_TO_EDGE; - wrapT = GL_CLAMP_TO_EDGE; - } - GLenum magFilt = samp->magFilt; - GLenum minFilt = tex->HasMips() ? samp->mipMinFilt : samp->minFilt; - renderManager_.SetTextureSampler(i, wrapS, wrapT, magFilt, minFilt, 0.0f); + for (int i = 0; i < MAX_TEXTURE_SLOTS; i++) { + const OpenGLSamplerState *samp = boundSamplers_[i]; + const OpenGLTexture *tex = boundTextures_[i]; + if (!samp || !tex) { + continue; } + GLenum wrapS; + GLenum wrapT; + if (tex->CanWrap()) { + wrapS = samp->wrapU; + wrapT = samp->wrapV; + } else { + wrapS = GL_CLAMP_TO_EDGE; + wrapT = GL_CLAMP_TO_EDGE; + } + GLenum magFilt = samp->magFilt; + GLenum minFilt = tex->HasMips() ? samp->mipMinFilt : samp->minFilt; + renderManager_.SetTextureSampler(i, wrapS, wrapT, magFilt, minFilt, 0.0f); } } @@ -1132,7 +1131,6 @@ void OpenGLContext::DrawUP(const void *vdata, int vertexCount) { size_t offset = frameData.push->Push(vdata, dataSize, &buf); ApplySamplers(); - renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, buf, offset); renderManager_.Draw(curPipeline_->prim, 0, vertexCount); } From 122a1acef9f8fb795f69ef2bc266d1de1b68604e Mon Sep 17 00:00:00 2001 From: sum2012 Date: Tue, 28 Jul 2020 10:22:04 +0800 Subject: [PATCH 380/848] Add two ThreadManForKernel 's nids used in #13205 --- Core/HLE/sceKernel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 3115991370..ca92dc8557 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -887,6 +887,8 @@ const HLEFunction ThreadManForKernel[] = {0X9944F31F, &WrapI_I, "sceKernelSuspendThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0X75156E8F, &WrapI_I, "sceKernelResumeThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0X94416130, &WrapU_UUUU, "sceKernelGetThreadmanIdList", 'x', "xxxx", HLE_KERNEL_SYSCALL }, + {0X28B6489C, &WrapI_I, "sceKernelDeleteSema", 'i', "i", HLE_KERNEL_SYSCALL }, + {0XEF9E4C70, &WrapU_I, "sceKernelDeleteEventFlag", 'x', "i", HLE_KERNEL_SYSCALL }, }; void Register_ThreadManForUser() From 74f710a228fe7b95371c71cba84435cd12f01d9a Mon Sep 17 00:00:00 2001 From: sum2012 Date: Tue, 28 Jul 2020 10:47:08 +0800 Subject: [PATCH 381/848] Add two SysMemForKernel's nids used in #13205 --- Core/HLE/sceKernelHeap.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index 95509c52cd..027857059c 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -99,6 +99,12 @@ static u32 sceKernelPartitionMaxFreeMemSize(int partitionId) { return userMemory.GetLargestFreeBlockSize(); } +static u32 SysMemForKernel_536AD5E1() +{ + ERROR_LOG(SCEKERNEL, "UNIMP SysMemForKernel_536AD5E1"); +} + + const HLEFunction SysMemForKernel[] = { { 0X636C953B, &WrapI_II, "sceKernelAllocHeapMemory", 'x', "ii", HLE_KERNEL_SYSCALL }, { 0XC9805775, &WrapI_I, "sceKernelDeleteHeap", 'i', "i" , HLE_KERNEL_SYSCALL }, @@ -108,6 +114,8 @@ const HLEFunction SysMemForKernel[] = { { 0X9D9A5BA1, &WrapU_I, "sceKernelGetBlockHeadAddr", 'x', "i", HLE_KERNEL_SYSCALL }, { 0x9697CD32, &WrapU_I, "sceKernelPartitionTotalFreeMemSize", 'x', "i",HLE_KERNEL_SYSCALL }, { 0xE6581468, &WrapU_I, "sceKernelPartitionMaxFreeMemSize", 'x', "i",HLE_KERNEL_SYSCALL }, + { 0X3FC9AE6A, &WrapU_V, "sceKernelDevkitVersion", 'x', "" ,HLE_KERNEL_SYSCALL }, + { 0x536AD5E1, &WrapU_V, "SysMemForKernel_536AD5E1", 'i', "i" ,HLE_KERNEL_SYSCALL }, }; void Register_SysMemForKernel() { From 3447cdf6dddb3ef7a61d1a1c0d03e62d5f68b17f Mon Sep 17 00:00:00 2001 From: sum2012 Date: Tue, 28 Jul 2020 10:50:06 +0800 Subject: [PATCH 382/848] oop --- Core/HLE/sceKernelHeap.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index 027857059c..36581f1e15 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -102,6 +102,7 @@ static u32 sceKernelPartitionMaxFreeMemSize(int partitionId) { static u32 SysMemForKernel_536AD5E1() { ERROR_LOG(SCEKERNEL, "UNIMP SysMemForKernel_536AD5E1"); + return 0; } From 118bb72037b6d75ceb99436b0d33179eb2eb1f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 28 Jul 2020 10:03:55 +0200 Subject: [PATCH 383/848] Forgetting "return true" fooled the optimizer into crashing. Fixes #13215. --- UI/MainScreen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 03d89ce7da..e9803ac0f6 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -94,6 +94,7 @@ bool LaunchFile(ScreenManager *screenManager, std::string path) { screenManager->switchScreen(new EmuScreen(path)); break; } + return true; } static bool IsTempPath(const std::string &str) { @@ -1326,7 +1327,8 @@ UI::EventReturn MainScreen::OnGameSelectedInstant(UI::EventParams &e) { #else std::string path = e.s; #endif - LaunchFile(screenManager(), path); + ScreenManager *screen = screenManager(); + LaunchFile(screen, path); return UI::EVENT_DONE; } From 06d57b1656ed127310f6ba9dc6baed3632f65aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 28 Jul 2020 13:24:02 +0200 Subject: [PATCH 384/848] GL: Add some paranoid checks. Remove a useless option. --- UI/NativeApp.cpp | 2 -- android/jni/app-android.cpp | 2 +- ext/native/thin3d/thin3d.h | 1 + ext/native/thin3d/thin3d_gl.cpp | 25 +++++++++++++++++++++++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index bb59188e86..dd3eb2794e 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -255,8 +255,6 @@ std::string NativeQueryConfig(std::string query) { int max_res = std::max(System_GetPropertyInt(SYSPROP_DISPLAY_XRES), System_GetPropertyInt(SYSPROP_DISPLAY_YRES)) / 480 + 1; snprintf(temp, sizeof(temp), "%d", std::min(scale, max_res)); return std::string(temp); - } else if (query == "force44khz") { - return std::string("0"); } else if (query == "androidJavaGL") { // If we're using Vulkan, we say no... need C++ to use Vulkan. if (GetGPUBackend() == GPUBackend::VULKAN) { diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 086371085d..1fafbf5de4 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -605,7 +605,7 @@ retry: extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioInit(JNIEnv *, jclass) { sampleRate = optimalSampleRate; - if (NativeQueryConfig("force44khz") != "0" || optimalSampleRate == 0) { + if (optimalSampleRate == 0) { sampleRate = 44100; } if (optimalFramesPerBuffer > 0) { diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index f78dbf8f87..862a6d2998 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -136,6 +136,7 @@ enum class Primitive { TRIANGLE_STRIP_ADJ, UNDEFINED, + PRIMITIVE_TYPE_COUNT, }; enum VertexShaderPreset : int { diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 47d54cd354..fda3a40f38 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -963,6 +963,15 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { ELOG("Pipeline requires at least one shader"); return nullptr; } + if ((int)desc.prim >= (int)Primitive::PRIMITIVE_TYPE_COUNT) { + ELOG("Invalid primitive type"); + return nullptr; + } + if (!desc.depthStencil || !desc.blend || !desc.raster || !desc.inputLayout) { + ELOG("Incomplete prim desciption"); + return nullptr; + } + OpenGLPipeline *pipeline = new OpenGLPipeline(&renderManager_); for (auto iter : desc.shaders) { if (iter) { @@ -1046,9 +1055,21 @@ ShaderModule *OpenGLContext::CreateShaderModule(ShaderStage stage, ShaderLanguag bool OpenGLPipeline::LinkShaders() { std::vector linkShaders; - for (auto iter : shaders) { - linkShaders.push_back(iter->GetShader()); + for (auto shaderModule : shaders) { + if (shaderModule) { + GLRShader *shader = shaderModule->GetShader(); + if (shader) { + linkShaders.push_back(shader); + } else { + ELOG("LinkShaders: Bad shader module"); + return false; + } + } else { + ELOG("LinkShaders: Bad shader in module"); + return false; + } } + std::vector semantics; // Bind all the common vertex data points. Mismatching ones will be ignored. semantics.push_back({ SEM_POSITION, "Position" }); From b6f6e954a30f191f612bfac945f3e0da4c6fd929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 28 Jul 2020 13:38:23 +0200 Subject: [PATCH 385/848] Android: Can't call AlertDialog.Builder.setOnDismissListener before JELLYBEAN_MR1 --- android/src/org/ppsspp/ppsspp/NativeActivity.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index ac272d2d75..386ed3870f 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -1065,7 +1065,7 @@ public abstract class NativeActivity extends Activity { else bld = createDialogBuilderNew(); - AlertDialog dlg = bld + AlertDialog.Builder builder = bld .setView(fl) .setTitle(title) .setPositiveButton(defaultAction, new DialogInterface.OnClickListener() { @@ -1081,15 +1081,17 @@ public abstract class NativeActivity extends Activity { NativeApp.sendInputBox(seqID, false, ""); d.cancel(); } - }) - .setOnDismissListener(new DialogInterface.OnDismissListener() { + }); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) { + builder.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface d) { NativeApp.sendInputBox(seqID, false, ""); updateSystemUiVisibility(); } - }) - .create(); + }); + } + AlertDialog dlg = builder.create(); dlg.setCancelable(true); dlg.show(); From aebbff55f12bb4beb07d904bb194a8c339ee94de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 28 Jul 2020 14:22:50 +0200 Subject: [PATCH 386/848] Some renaming and cleanup in the Android audio code --- CMakeLists.txt | 8 +-- Windows/PPSSPP.vcxproj | 8 +-- Windows/PPSSPP.vcxproj.filters | 24 ++++---- android/jni/Android.mk | 4 +- .../{native_audio.cpp => AndroidAudio.cpp} | 16 ++++- .../jni/{native_audio.h => AndroidAudio.h} | 16 ++++- ...{native-audio-so.cpp => OpenSLContext.cpp} | 58 ++++++++----------- .../{native-audio-so.h => OpenSLContext.h} | 15 +---- android/jni/app-android.cpp | 2 +- .../src/org/ppsspp/ppsspp/NativeActivity.java | 10 +++- 10 files changed, 84 insertions(+), 77 deletions(-) rename android/jni/{native_audio.cpp => AndroidAudio.cpp} (79%) rename android/jni/{native_audio.h => AndroidAudio.h} (55%) rename android/jni/{native-audio-so.cpp => OpenSLContext.cpp} (80%) rename android/jni/{native-audio-so.h => OpenSLContext.h} (73%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d4157062c..2b07111e86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -730,10 +730,10 @@ if(ANDROID) android/jni/AndroidVulkanContext.cpp android/jni/AndroidVulkanContext.h android/jni/AndroidGraphicsContext.h - android/jni/native_audio.cpp - android/jni/native_audio.h - android/jni/native-audio-so.cpp - android/jni/native-audio-so.h + android/jni/AndroidAudio.cpp + android/jni/AndroidAudio.h + android/jni/OpenSLContext.cpp + android/jni/OpenSLContext.h ) # No target elseif(IOS) diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index ed8abc3a30..def7547093 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -600,7 +600,7 @@ true true - + true true true @@ -610,7 +610,7 @@ true true - + true true true @@ -1028,7 +1028,7 @@ - + true true true @@ -1038,7 +1038,7 @@ true true - + true true true diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index 451be96f95..ffbdc51429 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -205,12 +205,6 @@ Other Platforms\Android - - Other Platforms\Android - - - Other Platforms\Android - Other Platforms\iOS @@ -271,6 +265,12 @@ Other Platforms\UWP + + Other Platforms\Android + + + Other Platforms\Android + @@ -430,12 +430,6 @@ Other Platforms\Android - - Other Platforms\Android - - - Other Platforms\Android - Other Platforms\iOS @@ -538,6 +532,12 @@ Other Platforms\UWP + + Other Platforms\Android + + + Other Platforms\Android + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 510c6a0a1d..3df8536529 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -499,8 +499,8 @@ LOCAL_SRC_FILES := \ $(SRC)/android/jni/AndroidEGLContext.cpp \ $(SRC)/android/jni/AndroidJavaGLContext.cpp \ $(SRC)/android/jni/AndroidVulkanContext.cpp \ - $(SRC)/android/jni/native_audio.cpp \ - $(SRC)/android/jni/native-audio-so.cpp \ + $(SRC)/android/jni/AndroidAudio.cpp \ + $(SRC)/android/jni/OpenSLContext.cpp \ $(SRC)/UI/BackgroundAudio.cpp \ $(SRC)/UI/DiscordIntegration.cpp \ $(SRC)/UI/ChatScreen.cpp \ diff --git a/android/jni/native_audio.cpp b/android/jni/AndroidAudio.cpp similarity index 79% rename from android/jni/native_audio.cpp rename to android/jni/AndroidAudio.cpp index a06159a89c..98cf3a87be 100644 --- a/android/jni/native_audio.cpp +++ b/android/jni/AndroidAudio.cpp @@ -1,6 +1,18 @@ #include "base/logging.h" -#include "android/jni/native_audio.h" -#include "android/jni/native-audio-so.h" +#include "android/jni/AndroidAudio.h" +#include "android/jni/OpenSLContext.h" + +AudioContext::AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate) + : audioCallback(cb), framesPerBuffer(_FramesPerBuffer), sampleRate(_SampleRate) { + if (framesPerBuffer == 0) + framesPerBuffer = 256; + if (framesPerBuffer < 32) + framesPerBuffer = 32; + if (framesPerBuffer > 4096) + framesPerBuffer = 4096; + + sampleRate = _SampleRate; +} struct AndroidAudioState { AudioContext *ctx = nullptr; diff --git a/android/jni/native_audio.h b/android/jni/AndroidAudio.h similarity index 55% rename from android/jni/native_audio.h rename to android/jni/AndroidAudio.h index 427f29ca36..a3d1ab8ee8 100644 --- a/android/jni/native_audio.h +++ b/android/jni/AndroidAudio.h @@ -1,8 +1,22 @@ #pragma once -#include "native-audio-so.h" #include +typedef int (*AndroidAudioCallback)(short *buffer, int num_samples); + +class AudioContext { +public: + AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate); + virtual bool Init() { return false; } + virtual ~AudioContext() {} + +protected: + AndroidAudioCallback audioCallback; + + int framesPerBuffer; + int sampleRate; +}; + struct AndroidAudioState; // It's okay for optimalFramesPerBuffer and optimalSampleRate to be 0. Defaults will be used. diff --git a/android/jni/native-audio-so.cpp b/android/jni/OpenSLContext.cpp similarity index 80% rename from android/jni/native-audio-so.cpp rename to android/jni/OpenSLContext.cpp index 17e665d2de..26965a72d5 100644 --- a/android/jni/native-audio-so.cpp +++ b/android/jni/OpenSLContext.cpp @@ -2,8 +2,7 @@ // // Loosely based on the Android NDK sample code. -#include -#include +#include #include // for native audio @@ -11,19 +10,8 @@ #include #include "base/logging.h" -#include "native-audio-so.h" - -AudioContext::AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate) - : audioCallback(cb), framesPerBuffer(_FramesPerBuffer), sampleRate(_SampleRate) { - if (framesPerBuffer == 0) - framesPerBuffer = 256; - if (framesPerBuffer < 32) - framesPerBuffer = 32; - if (framesPerBuffer > 4096) - framesPerBuffer = 4096; - - sampleRate = _SampleRate; -} +#include "Common/Log.h" +#include "OpenSLContext.h" // This callback handler is called every time a buffer finishes playing. // The documentation available is very unclear about how to best manage buffers. @@ -36,7 +24,7 @@ void OpenSLContext::bqPlayerCallbackWrap(SLAndroidSimpleBufferQueueItf bq, void void OpenSLContext::BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq) { if (bq != bqPlayerBufferQueue) { - ELOG("Wrong bq!"); + ELOG("OpenSL: Wrong bq!"); return; } @@ -53,7 +41,7 @@ void OpenSLContext::BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq) { // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, // which for this code example would indicate a programming error if (result != SL_RESULT_SUCCESS) { - ELOG("OpenSL ES: Failed to enqueue! %i %i", renderedFrames, sizeInBytes); + ELOG("OpenSL: Failed to enqueue! %i %i", renderedFrames, sizeInBytes); } curBuffer += 1; // Switch buffer @@ -70,24 +58,26 @@ bool OpenSLContext::Init() { // create engine result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); if (result != SL_RESULT_SUCCESS) { - ELOG("OpenSL ES: Failed to create the engine: %d", (int)result); + ELOG("OpenSL: Failed to create the engine: %d", (int)result); engineObject = nullptr; return false; } result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); + result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); + result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0); if (result != SL_RESULT_SUCCESS) { - ELOG("OpenSL ES: Failed to create output mix: %d", (int)result); + ELOG("OpenSL: Failed to create output mix: %d", (int)result); (*engineObject)->Destroy(engineObject); engineEngine = nullptr; engineObject = nullptr; return false; } result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); // The constants, such as SL_SAMPLINGRATE_44_1, are just 44100000. SLuint32 sr = (SLuint32)sampleRate * 1000; @@ -114,7 +104,7 @@ bool OpenSLContext::Init() { const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req); if (result != SL_RESULT_SUCCESS) { - ELOG("OpenSL ES: CreateAudioPlayer failed: %d", (int)result); + ELOG("OpenSL: CreateAudioPlayer failed: %d", (int)result); (*outputMixObject)->Destroy(outputMixObject); outputMixObject = nullptr; @@ -126,18 +116,18 @@ bool OpenSLContext::Init() { } result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, &bqPlayerBufferQueue); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, &bqPlayerCallbackWrap, this); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); - assert(SL_RESULT_SUCCESS == result); + _assert_(SL_RESULT_SUCCESS == result); // Allocate and enqueue N empty buffers. for (int i = 0; i < NUM_BUFFERS; i++) { @@ -159,7 +149,7 @@ bool OpenSLContext::Init() { // shut down the native audio system OpenSLContext::~OpenSLContext() { if (bqPlayerPlay) { - ILOG("OpenSLWrap_Shutdown - stopping playback"); + ILOG("OpenSL: Shutdown - stopping playback"); SLresult result; result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED); if (SL_RESULT_SUCCESS != result) { @@ -167,7 +157,7 @@ OpenSLContext::~OpenSLContext() { } } - ILOG("OpenSLWrap_Shutdown - deleting player object"); + ILOG("OpenSL: Shutdown - deleting player object"); if (bqPlayerObject) { (*bqPlayerObject)->Destroy(bqPlayerObject); @@ -177,14 +167,14 @@ OpenSLContext::~OpenSLContext() { bqPlayerVolume = nullptr; } - ILOG("OpenSLWrap_Shutdown - deleting mix object"); + ILOG("OpenSL: Shutdown - deleting mix object"); if (outputMixObject) { (*outputMixObject)->Destroy(outputMixObject); outputMixObject = nullptr; } - ILOG("OpenSLWrap_Shutdown - deleting engine object"); + ILOG("OpenSL: Shutdown - deleting engine object"); if (engineObject) { (*engineObject)->Destroy(engineObject); @@ -196,6 +186,6 @@ OpenSLContext::~OpenSLContext() { delete[] buffer[i]; buffer[i] = nullptr; } - ILOG("OpenSLWrap_Shutdown - finished"); + ILOG("OpenSL: Shutdown - finished"); } diff --git a/android/jni/native-audio-so.h b/android/jni/OpenSLContext.h similarity index 73% rename from android/jni/native-audio-so.h rename to android/jni/OpenSLContext.h index 9623e51709..3705f66b82 100644 --- a/android/jni/native-audio-so.h +++ b/android/jni/OpenSLContext.h @@ -3,20 +3,7 @@ #include #include -typedef int (*AndroidAudioCallback)(short *buffer, int num_samples); - -class AudioContext { -public: - AudioContext(AndroidAudioCallback cb, int _FramesPerBuffer, int _SampleRate); - virtual bool Init() { return false; } - virtual ~AudioContext() {} - -protected: - AndroidAudioCallback audioCallback; - - int framesPerBuffer; - int sampleRate; -}; +#include "AndroidAudio.h" class OpenSLContext : public AudioContext { public: diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 1fafbf5de4..85acaf674f 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -63,7 +63,7 @@ struct JNIEnv {}; #include "math/math_util.h" #include "net/resolve.h" #include "util/text/parsers.h" -#include "android/jni/native_audio.h" +#include "android/jni/AndroidAudio.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index 386ed3870f..a06d47fe59 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -630,19 +630,22 @@ public abstract class NativeActivity extends Activity { } Log.i(TAG, "onDestroy"); mGLSurfaceView.onDestroy(); - // Probably vain attempt to help the garbage collector... mGLSurfaceView = null; - audioFocusChangeListener = null; - audioManager = null; } else { mSurfaceView.onDestroy(); mSurfaceView = null; } + + // Probably vain attempt to help the garbage collector... + audioFocusChangeListener = null; + audioManager = null; + sizeManager.setSurfaceView(null); if (mPowerSaveModeReceiver != null) { mPowerSaveModeReceiver.destroy(this); mPowerSaveModeReceiver = null; } + // TODO: Can we ensure that the GL thread has stopped rendering here? // I've seen crashes that seem to indicate that sometimes it hasn't... NativeApp.audioShutdown(); @@ -697,6 +700,7 @@ public abstract class NativeActivity extends Activity { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { updateSystemUiVisibility(); } + // OK, config should be initialized, we can query for screen rotation. if (javaGL || Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { updateScreenRotation("onResume"); From 73166def93eea7b2d32d3dfa7a1453cb1f462980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 28 Jul 2020 19:06:29 +0200 Subject: [PATCH 387/848] Android: Reduce asserts during startup. --- UI/NativeApp.cpp | 103 ++++++++++-------- Windows/GPU/WindowsGLContext.cpp | 30 +++-- Windows/GPU/WindowsGLContext.h | 2 + android/jni/AndroidJavaGLContext.cpp | 8 +- android/jni/AndroidVulkanContext.cpp | 2 +- android/jni/app-android.cpp | 40 +++++-- .../src/org/ppsspp/ppsspp/NativeActivity.java | 2 +- .../src/org/ppsspp/ppsspp/NativeRenderer.java | 10 +- ext/native/thin3d/thin3d_gl.cpp | 1 - 9 files changed, 124 insertions(+), 74 deletions(-) diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index dd3eb2794e..20bddb0d1f 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -803,29 +803,34 @@ static void UIThemeInit() { } void RenderOverlays(UIContext *dc, void *userdata); +bool CreateGlobalPipelines(); bool NativeInitGraphics(GraphicsContext *graphicsContext) { ILOG("NativeInitGraphics"); - _assert_msg_(graphicsContext, "No graphics context!"); // We set this now so any resize during init is processed later. resized = false; - using namespace Draw; Core_SetGraphicsContext(graphicsContext); g_draw = graphicsContext->GetDrawContext(); - _assert_msg_(g_draw, "No draw context available!"); - _assert_msg_(g_draw->GetVshaderPreset(VS_COLOR_2D) != nullptr, "Failed to compile presets"); + + if (!CreateGlobalPipelines()) { + ERROR_LOG(G3D, "Failed to create global pipelines"); + return false; + } // Load the atlas. - size_t atlas_data_size = 0; if (!g_ui_atlas.IsMetadataLoaded()) { const uint8_t *atlas_data = VFSReadFile("ui_atlas.meta", &atlas_data_size); bool load_success = atlas_data != nullptr && g_ui_atlas.Load(atlas_data, atlas_data_size); - _assert_msg_(load_success, "Failed to load ui_atlas.meta"); + if (!load_success) { + ERROR_LOG(G3D, "Failed to load ui_atlas.meta - graphics will be broken."); + // Stumble along with broken visuals instead of dying. + } delete[] atlas_data; } + ui_draw2d.SetAtlas(&g_ui_atlas); ui_draw2d_front.SetAtlas(&g_ui_atlas); @@ -834,43 +839,10 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { uiContext = new UIContext(); uiContext->theme = &ui_theme; - Draw::InputLayout *inputLayout = ui_draw2d.CreateInputLayout(g_draw); - Draw::BlendState *blendNormal = g_draw->CreateBlendState({ true, 0xF, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA }); - Draw::DepthStencilState *depth = g_draw->CreateDepthStencilState({ false, false, Comparison::LESS }); - Draw::RasterState *rasterNoCull = g_draw->CreateRasterState({}); - - PipelineDesc colorDesc{ - Primitive::TRIANGLE_LIST, - { g_draw->GetVshaderPreset(VS_COLOR_2D), g_draw->GetFshaderPreset(FS_COLOR_2D) }, - inputLayout, depth, blendNormal, rasterNoCull, &vsColBufDesc, - }; - PipelineDesc texColorDesc{ - Primitive::TRIANGLE_LIST, - { g_draw->GetVshaderPreset(VS_TEXTURE_COLOR_2D), g_draw->GetFshaderPreset(FS_TEXTURE_COLOR_2D) }, - inputLayout, depth, blendNormal, rasterNoCull, &vsTexColBufDesc, - }; - - colorPipeline = g_draw->CreateGraphicsPipeline(colorDesc); - texColorPipeline = g_draw->CreateGraphicsPipeline(texColorDesc); - - _assert_(colorPipeline); - _assert_(texColorPipeline); - - // Release these now, reference counting should ensure that they get completely released - // once we delete both pipelines. - inputLayout->Release(); - rasterNoCull->Release(); - blendNormal->Release(); - depth->Release(); - ui_draw2d.Init(g_draw, texColorPipeline); ui_draw2d_front.Init(g_draw, texColorPipeline); uiContext->Init(g_draw, texColorPipeline, colorPipeline, &ui_draw2d, &ui_draw2d_front); - RasterStateDesc desc; - desc.cull = CullMode::NONE; - desc.frontFace = Facing::CCW; - if (uiContext->Text()) uiContext->Text()->SetFont("Tahoma", 20, 0); @@ -897,13 +869,54 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { g_gameInfoCache = new GameInfoCache(); - if (gpu) + if (gpu) { gpu->DeviceRestore(); + } ILOG("NativeInitGraphics completed"); return true; } +bool CreateGlobalPipelines() { + using namespace Draw; + + InputLayout *inputLayout = ui_draw2d.CreateInputLayout(g_draw); + BlendState *blendNormal = g_draw->CreateBlendState({ true, 0xF, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA }); + DepthStencilState *depth = g_draw->CreateDepthStencilState({ false, false, Comparison::LESS }); + RasterState *rasterNoCull = g_draw->CreateRasterState({}); + + PipelineDesc colorDesc{ + Primitive::TRIANGLE_LIST, + { g_draw->GetVshaderPreset(VS_COLOR_2D), g_draw->GetFshaderPreset(FS_COLOR_2D) }, + inputLayout, depth, blendNormal, rasterNoCull, &vsColBufDesc, + }; + PipelineDesc texColorDesc{ + Primitive::TRIANGLE_LIST, + { g_draw->GetVshaderPreset(VS_TEXTURE_COLOR_2D), g_draw->GetFshaderPreset(FS_TEXTURE_COLOR_2D) }, + inputLayout, depth, blendNormal, rasterNoCull, &vsTexColBufDesc, + }; + + colorPipeline = g_draw->CreateGraphicsPipeline(colorDesc); + if (!colorPipeline) { + // Something really critical is wrong, don't care much about correct releasing of the states. + return false; + } + + texColorPipeline = g_draw->CreateGraphicsPipeline(texColorDesc); + if (!texColorPipeline) { + // Something really critical is wrong, don't care much about correct releasing of the states. + return false; + } + + // Release these now, reference counting should ensure that they get completely released + // once we delete both pipelines. + inputLayout->Release(); + rasterNoCull->Release(); + blendNormal->Release(); + depth->Release(); + return true; +} + void NativeShutdownGraphics() { screenManager->deviceLost(); @@ -912,12 +925,12 @@ void NativeShutdownGraphics() { ILOG("NativeShutdownGraphics"); -#ifdef _WIN32 +#if PPSSPP_PLATFORM(WINDOWS) delete winAudioBackend; winAudioBackend = nullptr; #endif -#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) +#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP) if (winCamera) { winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::SHUTDOWN, nullptr }); while (!winCamera->isShutDown()) {};// Wait for shutting down. @@ -1086,7 +1099,7 @@ void NativeRender(GraphicsContext *graphicsContext) { screenManager->resized(); // TODO: Move this to the GraphicsContext objects for each backend. -#if !defined(_WIN32) && !defined(ANDROID) +#if !PPSSPP_PLATFORM(WINDOWS) && !defined(ANDROID) PSP_CoreParameter().pixelWidth = pixel_xres; PSP_CoreParameter().pixelHeight = pixel_yres; NativeMessageReceived("gpu_resized", ""); @@ -1133,7 +1146,7 @@ void HandleGlobalMessage(const std::string &msg, const std::string &value) { if (msg == "core_powerSaving") { if (value != "false") { auto sy = GetI18NCategory("System"); -#ifdef __ANDROID__ +#if PPSSPP_PLATFORM(ANDROID) osm.Show(sy->T("WARNING: Android battery save mode is on"), 2.0f, 0xFFFFFF, -1, true, "core_powerSaving"); #else osm.Show(sy->T("WARNING: Battery save mode is on"), 2.0f, 0xFFFFFF, -1, true, "core_powerSaving"); @@ -1142,7 +1155,7 @@ void HandleGlobalMessage(const std::string &msg, const std::string &value) { Core_SetPowerSaving(value != "false"); } if (msg == "permission_granted" && value == "storage") { -#ifdef __ANDROID__ +#if PPSSPP_PLATFORM(ANDROID) CreateDirectoriesAndroid(); #endif // We must have failed to load the config before, so load it now to avoid overwriting the old config diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index 9e5e028fc2..9646cf25e9 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -399,17 +399,23 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) { pauseRequested = false; resumeRequested = false; + CheckGLExtensions(); + draw_ = Draw::T3DCreateGLContext(); + bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these. + if (!success) { + delete draw_; + draw_ = nullptr; + ReleaseGLContext(); + return false; + } + // These are auto-reset events. pauseEvent = CreateEvent(NULL, FALSE, FALSE, NULL); resumeEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - CheckGLExtensions(); - draw_ = Draw::T3DCreateGLContext(); renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); renderManager_->SetInflightFrames(g_Config.iInflightFrames); SetGPUBackend(GPUBackend::OPENGL); - bool success = draw_->CreatePresets(); // if we get this far, there will always be a GLSL compiler capable of compiling these. - _assert_msg_(success, "Failed to compile preset shaders"); renderManager_->SetSwapFunction([&]() {::SwapBuffers(hDC); }); if (wglSwapIntervalEXT) { // glew loads wglSwapIntervalEXT if available @@ -430,14 +436,10 @@ void WindowsGLContext::Shutdown() { glslang::FinalizeProcess(); } -void WindowsGLContext::ShutdownFromRenderThread() { - delete draw_; - draw_ = nullptr; - CloseHandle(pauseEvent); - CloseHandle(resumeEvent); +void WindowsGLContext::ReleaseGLContext() { if (hRC) { // Are we able to release the DC and RC contexts? - if (!wglMakeCurrent(NULL,NULL)) { + if (!wglMakeCurrent(NULL, NULL)) { MessageBox(NULL, L"Release of DC and RC failed.", L"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } @@ -458,6 +460,14 @@ void WindowsGLContext::ShutdownFromRenderThread() { hWnd_ = NULL; } +void WindowsGLContext::ShutdownFromRenderThread() { + delete draw_; + draw_ = nullptr; + CloseHandle(pauseEvent); + CloseHandle(resumeEvent); + ReleaseGLContext(); +} + void WindowsGLContext::Resize() { } diff --git a/Windows/GPU/WindowsGLContext.h b/Windows/GPU/WindowsGLContext.h index 1303aece79..df8190f9dc 100644 --- a/Windows/GPU/WindowsGLContext.h +++ b/Windows/GPU/WindowsGLContext.h @@ -34,6 +34,8 @@ public: Draw::DrawContext *GetDrawContext() override { return draw_; } private: + void ReleaseGLContext(); + bool renderThread_; Draw::DrawContext *draw_; GLRenderManager *renderManager_; diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index afc5de6921..d1b8e17a6a 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -4,6 +4,7 @@ #include "base/display.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" +#include "Common/Log.h" #include "Core/ConfigValues.h" #include "Core/System.h" @@ -17,12 +18,11 @@ bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int // OpenGL handles rotated rendering in the driver. g_display_rotation = DisplayRotation::ROTATE_0; g_display_rot_matrix.setIdentity(); - draw_ = Draw::T3DCreateGLContext(); + draw_ = Draw::T3DCreateGLContext(); // Can't fail renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); renderManager_->SetInflightFrames(g_Config.iInflightFrames); - bool success = draw_->CreatePresets(); - _assert_msg_(success, "Failed to compile preset shaders"); - return success; + draw_->CreatePresets(); + return true; } void AndroidJavaEGLGraphicsContext::ShutdownFromRenderThread() { diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 06b09dae9b..76fc4d3e3c 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -71,7 +71,6 @@ bool AndroidVulkanContext::InitAPI() { } g_Vulkan->ChooseDevice(physicalDevice); - // Here we can enable device extensions if we like. ILOG("Creating Vulkan device"); if (g_Vulkan->CreateDevice() != VK_SUCCESS) { @@ -82,6 +81,7 @@ bool AndroidVulkanContext::InitAPI() { g_Vulkan = nullptr; return false; } + ILOG("Vulkan device created!"); return true; } diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 85acaf674f..0ac1036011 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -4,7 +4,6 @@ // It calls a set of methods defined in NativeApp.h. These should be implemented // by your game or app. -#include #include #include @@ -594,7 +593,6 @@ retry: ELOG("NativeApp.init(): iGPUBackend %d not supported. Switching to OpenGL.", (int)g_Config.iGPUBackend); g_Config.iGPUBackend = (int)GPUBackend::OPENGL; goto retry; - // Crash(); } if (useCPUThread) { @@ -688,7 +686,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) { } // JavaEGL -extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { +extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { // We should be running on the render thread here. std::string errorMessage; if (renderer_inited) { @@ -712,21 +710,34 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, ILOG("Shut down both threads. Now let's bring it up again!"); - graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0); + if (!graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0)) { + SystemToast("Graphics initialization failed. Quitting."); + return false; + } + if (useCPUThread) { EmuThreadStart(); } else { - NativeInitGraphics(graphicsContext); + if (!NativeInitGraphics(graphicsContext)) { + // Gonna be in a weird state here, not good. + SystemToast("Failed to initialize graphics."); + return false; + } } + graphicsContext->ThreadStart(); ILOG("Restored."); } else { ILOG("NativeApp.displayInit() first time"); - graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0); + if (!graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0)) { + SystemToast("Graphics initialization failed. Quitting."); + return false; + } graphicsContext->ThreadStart(); renderer_inited = true; } NativeMessageReceived("recreateviews", ""); + return true; } static void recalculateDpi() { @@ -1156,6 +1167,11 @@ static void ProcessFrameCommands(JNIEnv *env) { } extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) { + if (!graphicsContext) { + ELOG("runEGLRenderLoop: Tried to enter without a created graphics context."); + return false; + } + // Needed for Vulkan, even if we're not using the old EGL path. exitRenderLoop = false; @@ -1175,10 +1191,11 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J auto tryInit = [&]() { if (graphicsContext->InitFromRenderThread(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format, androidVersion)) { return true; + } else { + ELOG("Failed to initialize graphics context."); + SystemToast("Failed to initialize graphics context."); + return false; } - - ELOG("Failed to initialize graphics context."); - return false; }; bool initSuccess = tryInit(); @@ -1202,7 +1219,10 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J if (!exitRenderLoop) { if (!useCPUThread) { - NativeInitGraphics(graphicsContext); + if (!NativeInitGraphics(graphicsContext)) { + ELOG("Failed to initialize graphics."); + // Gonna be in a weird state here.. + } } graphicsContext->ThreadStart(); renderer_inited = true; diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index a06d47fe59..5cc6f64846 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -616,6 +616,7 @@ public abstract class NativeActivity extends Activity { @Override protected void onDestroy() { super.onDestroy(); + Log.i(TAG, "onDestroy"); if (javaGL) { if (nativeRenderer.isRenderingFrame()) { Log.i(TAG, "Waiting for renderer to finish."); @@ -628,7 +629,6 @@ public abstract class NativeActivity extends Activity { tries--; } while (nativeRenderer.isRenderingFrame() && tries > 0); } - Log.i(TAG, "onDestroy"); mGLSurfaceView.onDestroy(); mGLSurfaceView = null; } else { diff --git a/android/src/org/ppsspp/ppsspp/NativeRenderer.java b/android/src/org/ppsspp/ppsspp/NativeRenderer.java index 31df096943..5051b3eee0 100644 --- a/android/src/org/ppsspp/ppsspp/NativeRenderer.java +++ b/android/src/org/ppsspp/ppsspp/NativeRenderer.java @@ -13,6 +13,7 @@ public class NativeRenderer implements GLSurfaceView.Renderer { private static String TAG = "NativeRenderer"; private NativeActivity mActivity; private boolean inFrame; + private boolean failed = false; NativeRenderer(NativeActivity act) { mActivity = act; @@ -21,6 +22,7 @@ public class NativeRenderer implements GLSurfaceView.Renderer { public boolean isRenderingFrame() { return inFrame; } + public boolean hasFailedInit() { return failed; } public void onDrawFrame(GL10 unused /*use GLES20*/) { inFrame = true; @@ -29,6 +31,7 @@ public class NativeRenderer implements GLSurfaceView.Renderer { } public void onSurfaceCreated(GL10 gl, EGLConfig config) { + failed = false; Log.i(TAG, "NativeRenderer: onSurfaceCreated"); EGL10 egl = (EGL10)EGLContext.getEGL(); @@ -49,7 +52,10 @@ public class NativeRenderer implements GLSurfaceView.Renderer { } // Log.i(TAG, "onSurfaceCreated - EGL context is new or was lost"); // Actually, it seems that it is here we should recreate lost GL objects. - displayInit(); + if (!displayInit()) { + Log.e(TAG, "Display init failed"); + failed = true; + } } public void onSurfaceChanged(GL10 unused, int width, int height) { @@ -57,7 +63,7 @@ public class NativeRenderer implements GLSurfaceView.Renderer { // Note: This also means "device lost" and you should reload // all buffered objects. - public native void displayInit(); + public native boolean displayInit(); public native void displayRender(); } diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index fda3a40f38..946c7f99dc 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "base/logging.h" #include "math/dataconv.h" From d55a6052fa1c4538595dcda009dd6b981ae78b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 28 Jul 2020 20:18:45 +0200 Subject: [PATCH 388/848] Fix some lint warnings, and a "toast" on graphics init failure (instead of previous crashes) --- .../src/org/ppsspp/ppsspp/NativeActivity.java | 57 ++++++++----------- .../src/org/ppsspp/ppsspp/NativeRenderer.java | 13 +++-- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index 5cc6f64846..477d7b42cf 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -18,7 +18,6 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.database.Cursor; import android.graphics.PixelFormat; -import android.graphics.Point; import android.media.AudioManager; import android.net.Uri; import android.os.Build; @@ -51,11 +50,12 @@ import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; +@SuppressWarnings("ConstantConditions") public abstract class NativeActivity extends Activity { // Remember to loadLibrary your JNI .so in a static {} block // Adjust these as necessary - private static String TAG = "PPSSPPNativeActivity"; + private static final String TAG = "PPSSPPNativeActivity"; // Allows us to skip a lot of initialization on secondary calls to onCreate. private static boolean initialized = false; @@ -98,7 +98,7 @@ public abstract class NativeActivity extends Activity { // This is to avoid losing the game/menu state etc when we are just // switched-away from or rotated etc. private boolean shuttingDown; - private static int RESULT_LOAD_IMAGE = 1; + private static final int RESULT_LOAD_IMAGE = 1; // Allow for multiple connected gamepads but just consider them the same for now. // Actually this is not entirely true, see the code. @@ -132,10 +132,6 @@ public abstract class NativeActivity extends Activity { public native void registerCallbacks(); public native void unregisterCallbacks(); - public boolean useLowProfileButtons() { - return true; - } - NativeRenderer getRenderer() { return nativeRenderer; } @@ -209,7 +205,7 @@ public abstract class NativeActivity extends Activity { } @Override - public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, String [] permissions, int[] grantResults) { switch (requestCode) { case REQUEST_CODE_STORAGE_PERMISSION: if (permissionsGranted(permissions, grantResults)) { @@ -248,7 +244,7 @@ public abstract class NativeActivity extends Activity { } powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - if (powerManager.isSustainedPerformanceModeSupported()) { + if (powerManager != null && powerManager.isSustainedPerformanceModeSupported()) { sustainedPerfSupported = true; NativeApp.sendMessage("sustained_perf_supported", "1"); } @@ -259,10 +255,10 @@ public abstract class NativeActivity extends Activity { Log.d(TAG, "Landscape: " + landscape); // Get system information - ApplicationInfo appInfo = null; - PackageManager packMgmr = getPackageManager(); String packageName = getPackageName(); + + ApplicationInfo appInfo; try { appInfo = packMgmr.getApplicationInfo(packageName, 0); } catch (NameNotFoundException e) { @@ -345,22 +341,20 @@ public abstract class NativeActivity extends Activity { private void updateSustainedPerformanceMode() { if (sustainedPerfSupported) { // Query the native application on the desired rotation. - int enable = 0; String str = NativeApp.queryConfig("sustainedPerformanceMode"); try { - enable = Integer.parseInt(str); + int enable = Integer.parseInt(str); + getWindow().setSustainedPerformanceMode(enable != 0); } catch (NumberFormatException e) { Log.e(TAG, "Invalid perf mode: " + str); - return; } - getWindow().setSustainedPerformanceMode(enable != 0); } } @TargetApi(Build.VERSION_CODES.GINGERBREAD) private void updateScreenRotation(String cause) { // Query the native application on the desired rotation. - int rot = 0; + int rot; String rotString = NativeApp.queryConfig("screenRotation"); try { rot = Integer.parseInt(rotString); @@ -407,10 +401,7 @@ public abstract class NativeActivity extends Activity { } // Compute our _desired_ systemUiVisibility - int flags = 0; - if (useLowProfileButtons()) { - flags |= View.SYSTEM_UI_FLAG_LOW_PROFILE; - } + int flags = View.SYSTEM_UI_FLAG_LOW_PROFILE; if (useImmersive()) { flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; @@ -436,7 +427,7 @@ public abstract class NativeActivity extends Activity { } } - private Runnable mEmulationRunner = new Runnable() { + private final Runnable mEmulationRunner = new Runnable() { @Override public void run() { Log.i(TAG, "Starting the render loop: " + mSurface); @@ -995,30 +986,29 @@ public abstract class NativeActivity extends Activity { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) { Uri selectedImage = data.getData(); - String[] filePathColumn = {MediaStore.Images.Media.DATA}; - Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); - cursor.moveToFirst(); - int columnIndex = cursor.getColumnIndex(filePathColumn[0]); - String picturePath = cursor.getString(columnIndex); - cursor.close(); - NativeApp.sendMessage("bgImage_updated", picturePath); + if (selectedImage != null) { + String[] filePathColumn = {MediaStore.Images.Media.DATA}; + Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); + cursor.moveToFirst(); + int columnIndex = cursor.getColumnIndex(filePathColumn[0]); + String picturePath = cursor.getString(columnIndex); + cursor.close(); + NativeApp.sendMessage("bgImage_updated", picturePath); + } } } @TargetApi(Build.VERSION_CODES.HONEYCOMB) - @SuppressWarnings("deprecation") private AlertDialog.Builder createDialogBuilderWithTheme() { return new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_DARK); } @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - @SuppressWarnings("deprecation") private AlertDialog.Builder createDialogBuilderWithDeviceTheme() { return new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_DARK); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) - @SuppressWarnings("deprecation") private AlertDialog.Builder createDialogBuilderWithDeviceThemeAndUiVisibility() { AlertDialog.Builder bld = new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_DARK); bld.setOnDismissListener(new DialogInterface.OnDismissListener() { @@ -1194,11 +1184,10 @@ public abstract class NativeActivity extends Activity { inputMethodManager.toggleSoftInputFromWindow(surfView.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0); return true; } else if (command.equals("inputbox")) { - String seqID = ""; String title = "Input"; String defString = ""; String[] param = params.split(":@:", 3); - seqID = param[0]; + String seqID = param[0]; if (param.length > 1 && param[1].length() > 0) title = param[1]; if (param.length > 2) @@ -1208,7 +1197,7 @@ public abstract class NativeActivity extends Activity { return true; } else if (command.equals("vibrate")) { int milliseconds = -1; - if (params != "") { + if (!params.equals("")) { try { milliseconds = Integer.parseInt(params); } catch (NumberFormatException e) { diff --git a/android/src/org/ppsspp/ppsspp/NativeRenderer.java b/android/src/org/ppsspp/ppsspp/NativeRenderer.java index 5051b3eee0..58d4de48d8 100644 --- a/android/src/org/ppsspp/ppsspp/NativeRenderer.java +++ b/android/src/org/ppsspp/ppsspp/NativeRenderer.java @@ -2,6 +2,7 @@ package org.ppsspp.ppsspp; import android.opengl.GLSurfaceView; import android.util.Log; +import android.widget.Toast; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; @@ -12,7 +13,7 @@ import javax.microedition.khronos.opengles.GL10; public class NativeRenderer implements GLSurfaceView.Renderer { private static String TAG = "NativeRenderer"; private NativeActivity mActivity; - private boolean inFrame; + private boolean inFrame = false; private boolean failed = false; NativeRenderer(NativeActivity act) { @@ -22,6 +23,8 @@ public class NativeRenderer implements GLSurfaceView.Renderer { public boolean isRenderingFrame() { return inFrame; } + + // TODO: Make use of this somehow. public boolean hasFailedInit() { return failed; } public void onDrawFrame(GL10 unused /*use GLES20*/) { @@ -50,20 +53,18 @@ public class NativeRenderer implements GLSurfaceView.Renderer { } else { Log.e(TAG, "egl == null"); } - // Log.i(TAG, "onSurfaceCreated - EGL context is new or was lost"); - // Actually, it seems that it is here we should recreate lost GL objects. + if (!displayInit()) { Log.e(TAG, "Display init failed"); + Toast.makeText(mActivity, "Failed to initialize rendering. Close the app and try again.", Toast.LENGTH_LONG); failed = true; } } - public void onSurfaceChanged(GL10 unused, int width, int height) { - } + public void onSurfaceChanged(GL10 unused, int width, int height) {} // Note: This also means "device lost" and you should reload // all buffered objects. public native boolean displayInit(); - public native void displayRender(); } From f927ca795ccf97af6352af0f6265c66ce07edc60 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 28 Jul 2020 07:38:10 +0700 Subject: [PATCH 389/848] Added a fake thread to process Apctl Request Events into Apctl State Changes --- Core/HLE/proAdhoc.h | 15 +-- Core/HLE/sceNet.cpp | 261 ++++++++++++++++++++++++++++++++------- Core/HLE/sceNet.h | 44 ++++++- Core/HLE/sceNetAdhoc.cpp | 8 -- Core/HLE/sceNetAdhoc.h | 1 + 5 files changed, 267 insertions(+), 62 deletions(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 860808960b..69be2a20bf 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -796,10 +796,11 @@ public: auto s = p.Section("AfterAdhocMipsCall", 3, 4); if (!s) return; - - p.Do(HandlerID); - p.Do(EventID); - p.Do(argsAddr); + if (s >= 3) { + p.Do(HandlerID); + p.Do(EventID); + p.Do(argsAddr); + } } void run(MipsCall& call) override; void SetData(int handlerID, int eventId, u32_le argsAddr); @@ -818,13 +819,13 @@ public: auto s = p.Section("AfterMatchingMipsCall", 1, 4); if (!s) return; - - p.Do(EventID); + if (s >= 1) { + p.Do(EventID); + } if (s >= 4) { p.Do(contextID); p.Do(bufAddr); } - //context = NULL; } void run(MipsCall &call) override; void SetData(int ContextID, int eventId, u32_le BufAddr); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 8851347ec4..6661821202 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -47,8 +47,7 @@ static bool netInited; bool netInetInited; -bool netApctlInited; -int netApctlStatus; + u32 netDropRate = 0; u32 netDropDuration = 0; u32 netPoolAddr = 0; @@ -61,6 +60,34 @@ static std::map apctlHandlers; static struct SceNetApctlInfoInternal netApctlInfo; +bool netApctlInited; +u32 netApctlState; +u32 apctlThreadHackAddr = 0; +u32_le apctlThreadCode[3]; +SceUID apctlThreadID = 0; +int actionAfterApctlMipsCall; +std::recursive_mutex apctlEvtMtx; +std::deque apctlEvents; + +u32 Net_Term(); +int NetApctl_Term(); +void NetApctl_InitInfo(); + +void AfterApctlMipsCall::run(MipsCall& call) { + u32 v0 = currentMIPS->r[MIPS_REG_V0]; + DEBUG_LOG(SCENET, "AfterApctlMipsCall::run [ID=%i][OldState=%d][NewState=%d][Event=%d][Error=%d][ArgsPtr=%08x] [cbId: %u][retV0: %08x]", handlerID, oldState, newState, event, error, argsAddr, call.cbId, v0); + //call.setReturnValue(v0); +} + +void AfterApctlMipsCall::SetData(int HandlerID, int OldState, int NewState, int Event, int Error, u32_le ArgsAddr) { + handlerID = HandlerID; + oldState = OldState; + newState = NewState; + event = Event; + error = Error; + argsAddr = ArgsAddr; +} + static int InitLocalhostIP() { // find local IP addrinfo* localAddr; @@ -109,9 +136,19 @@ static int InitLocalhostIP() { return 0; } +void __NetApctlInit() { + netApctlInited = false; + netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; + apctlHandlers.clear(); + memset(&netApctlInfo, 0, sizeof(netApctlInfo)); + + // Init Apctl Callbacks + apctlThreadHackAddr = __CreateHLELoop(apctlThreadCode, "sceNetApctl", "__NetApctlCallbacks", "apctlThreadHack"); + actionAfterApctlMipsCall = __KernelRegisterActionType(AfterApctlMipsCall::Create); +} + static void __ResetInitNetLib() { netInited = false; - netApctlInited = false; netInetInited = false; memset(&netMallocStat, 0, sizeof(netMallocStat)); @@ -134,35 +171,40 @@ void __NetInit() { __UPnPInit(); __ResetInitNetLib(); + __NetApctlInit(); +} + +void __NetApctlShutdown() { + if (apctlThreadHackAddr) { + kernelMemory.Free(apctlThreadHackAddr); + apctlThreadHackAddr = 0; + } } void __NetShutdown() { // Network Cleanup Net_Term(); + __NetApctlShutdown(); __ResetInitNetLib(); // Since PortManager supposed to be general purpose for whatever port forwarding PPSSPP needed, may be we shouldn't clear & restore ports in here? it will be cleared and restored by PortManager's destructor when exiting PPSSPP anyway __UPnPShutdown(); } -static void __UpdateApctlHandlers(int oldState, int newState, int flag, int error) { - u32 args[5] = { 0, 0, 0, 0, 0 }; - args[0] = oldState; - args[1] = newState; - args[2] = flag; - args[3] = error; +static void __UpdateApctlHandlers(u32 oldState, u32 newState, u32 flag, u32 error) { + std::lock_guard apctlGuard(apctlEvtMtx); + apctlEvents.push_back({ oldState, newState, flag, error }); +} - for(std::map::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); ++it) { - args[4] = it->second.argument; - // TODO: Need to make sure netApctlState is updated before calling the callback's mipscall so the game handler's subroutine can Get and make use the new state/info - hleEnqueueCall(it->second.entryPoint, 5, args); - } +// Make sure MIPS calls have been fully executed before the next notifyApctlHandlers +void notifyApctlHandlers(int oldState, int newState, int flag, int error) { + __UpdateApctlHandlers(oldState, newState, flag, error); } // This feels like a dubious proposition, mostly... void __NetDoState(PointerWrap &p) { - auto s = p.Section("sceNet", 1, 3); + auto s = p.Section("sceNet", 1, 4); if (!s) return; @@ -191,11 +233,26 @@ void __NetDoState(PointerWrap &p) { p.Do(netThread1Addr); p.Do(netThread2Addr); } + if (s >= 4) { + p.Do(netApctlState); + p.Do(netApctlInfo); + p.Do(actionAfterApctlMipsCall); + __KernelRestoreActionType(actionAfterApctlMipsCall, AfterApctlMipsCall::Create); + p.Do(apctlThreadHackAddr); + } // Let's not change "Inited" value when Loading SaveState in the middle of multiplayer to prevent memory & port leaks if (p.mode == p.MODE_READ) { netApctlInited = cur_netApctlInited; netInetInited = cur_netInetInited; netInited = cur_netInited; + + // Previously, this wasn't being saved. It needs its own space. + if (apctlThreadHackAddr && strcmp("apctlThreadHack", kernelMemory.GetBlockTag(apctlThreadHackAddr)) != 0) { + u32 blockSize = sizeof(apctlThreadCode); + apctlThreadHackAddr = kernelMemory.Alloc(blockSize, false, "apctlThreadHack"); + } + // Restore Apctl Loop MIPS code to prevent crashes after loading from SaveState + if (apctlThreadHackAddr) Memory::Memcpy(apctlThreadHackAddr, apctlThreadCode, sizeof(apctlThreadCode)); } } @@ -294,6 +351,96 @@ std::string error2str(u32 errorCode) { return str; } +void __NetApctlCallbacks() +{ + std::lock_guard apctlGuard(apctlEvtMtx); + int delayus = 10000; + + // How AP works probably like this: Game use sceNetApctl function -> sceNetApctl let the hardware know and do their's thing and have a new State -> Let the game know the resulting State through Event on their handler + if (!apctlEvents.empty()) + { + auto args = apctlEvents.front(); + auto oldState = &args.data[0]; + auto newState = &args.data[1]; + auto event = &args.data[2]; + auto error = &args.data[3]; + apctlEvents.pop_front(); + + // Adjust delay according to current event. Added an extra delay to prevent I/O Timing method from causing disconnection + if (*event == PSP_NET_APCTL_EVENT_CONNECT_REQUEST) // || *event == PSP_NET_APCTL_EVENT_SCAN_REQUEST) + delayus = (adhocEventDelayMS + 2 * adhocExtraPollDelayMS) * 1000; + else + delayus = (adhocEventPollDelayMS + 2 * adhocExtraPollDelayMS) * 1000; + + // Do we need to change the oldState? even if there was error? + //if (*error == 0) + *oldState = netApctlState; + + // Need to make sure netApctlState is updated before calling the callback's mipscall so the game can GetState()/GetInfo() within their handler's subroutine and make use the new State/Info + // Should we update NewState & Error accordingly to Event before executing the mipscall ? sceNetApctl* functions might want to set the error value tho, so we probably should leave it untouched + //*error = 0; + switch (*event) { + case PSP_NET_APCTL_EVENT_CONNECT_REQUEST: + netApctlState = PSP_NET_APCTL_STATE_JOINING; // Should we set the State to PSP_NET_APCTL_STATE_DISCONNECTED if there was error? + if (*error == 0) apctlEvents.push_front({ netApctlState, netApctlState, PSP_NET_APCTL_EVENT_ESTABLISHED, 0 }); // Should we use PSP_NET_APCTL_EVENT_EAP_AUTH if securityType is not NONE? + break; + + case PSP_NET_APCTL_EVENT_ESTABLISHED: + netApctlState = PSP_NET_APCTL_STATE_GETTING_IP; + if (*error == 0) apctlEvents.push_front({ netApctlState, netApctlState, PSP_NET_APCTL_EVENT_GET_IP, 0 }); + break; + + case PSP_NET_APCTL_EVENT_GET_IP: + netApctlState = PSP_NET_APCTL_STATE_GOT_IP; + NetApctl_InitInfo(); + break; + + case PSP_NET_APCTL_EVENT_DISCONNECT_REQUEST: + netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; + break; + + case PSP_NET_APCTL_EVENT_SCAN_REQUEST: + netApctlState = PSP_NET_APCTL_STATE_SCANNING; + if (*error == 0) apctlEvents.push_front({ netApctlState, netApctlState, PSP_NET_APCTL_EVENT_SCAN_COMPLETE, 0 }); + break; + + case PSP_NET_APCTL_EVENT_SCAN_COMPLETE: + netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; + break; + + case PSP_NET_APCTL_EVENT_EAP_AUTH: // Is this suppose to happen between JOINING and ESTABLISHED ? + netApctlState = PSP_NET_APCTL_STATE_EAP_AUTH; + if (*error == 0) apctlEvents.push_front({ netApctlState, netApctlState, PSP_NET_APCTL_EVENT_KEY_EXCHANGE, 0 }); // not sure if KEY_EXCHANGE is the next step after AUTH or not tho + break; + + case PSP_NET_APCTL_EVENT_KEY_EXCHANGE: // Is this suppose to happen between JOINING and ESTABLISHED ? + netApctlState = PSP_NET_APCTL_STATE_KEY_EXCHANGE; + if (*error == 0) apctlEvents.push_front({ netApctlState, netApctlState, PSP_NET_APCTL_EVENT_ESTABLISHED, 0 }); + break; + + case PSP_NET_APCTL_EVENT_RECONNECT: + netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; + if (*error == 0) apctlEvents.push_front({ netApctlState, netApctlState, PSP_NET_APCTL_EVENT_CONNECT_REQUEST, 0 }); + break; + } + // Do we need to change the newState? even if there were error? + //if (*error == 0) + *newState = netApctlState; + + // Run mipscall. Should we skipped executing the mipscall if oldState == newState? + for (std::map::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); ++it) { + DEBUG_LOG(SCENET, "ApctlCallback [ID=%i][OldState=%d][NewState=%d][Event=%d][Error=%d][ArgsPtr=%08x]", it->first, *oldState, *newState, *event, *error, it->second.argument); + args.data[4] = it->second.argument; + AfterApctlMipsCall* after = (AfterApctlMipsCall*)__KernelCreateAction(actionAfterApctlMipsCall); + after->SetData(it->first, *oldState, *newState, *event, *error, it->second.argument); + hleEnqueueCall(it->second.entryPoint, 5, args.data, after); + } + } + + // Must be delayed long enough whenever there is a pending callback. + hleDelayResult(0, "Prevent Apctl thread from blocking", delayus); +} + static inline u32 AllocUser(u32 size, bool fromTop, const char *name) { u32 addr = userMemory.Alloc(size, fromTop, name); if (addr == -1) @@ -313,7 +460,7 @@ u32 Net_Term() { NetAdhoc_Term(); // TODO: Not implemented yet - //sceNetApctl_Term(); + NetApctl_Term(); //NetInet_Term(); // Library is initialized @@ -548,24 +695,21 @@ int sceNetInetTerm() { return 0; } -static int sceNetApctlInit(int stackSize, int initPriority) { - ERROR_LOG(SCENET, "UNIMPL sceNetApctlInit()"); - if (netApctlInited) - return ERROR_NET_APCTL_ALREADY_INITIALIZED; - +void NetApctl_InitInfo() { memset(&netApctlInfo, 0, sizeof(netApctlInfo)); - // Set default values - truncate_cpy(netApctlInfo.name, sizeof(netApctlInfo.name), "Wifi"); - truncate_cpy(netApctlInfo.ssid, sizeof(netApctlInfo.ssid), "Wifi"); - memcpy(netApctlInfo.bssid, "\1\1\2\2\3\3", sizeof(netApctlInfo.bssid)); - netApctlInfo.ssidLength = 4; + // Set dummy/fake values, these probably not suppose to have valid info before connected to an AP, right? + std::string APname = "Wifi"; // fake AP/hotspot + truncate_cpy(netApctlInfo.name, sizeof(netApctlInfo.name), APname.c_str()); + truncate_cpy(netApctlInfo.ssid, sizeof(netApctlInfo.ssid), APname.c_str()); + memcpy(netApctlInfo.bssid, "\1\1\2\2\3\3", sizeof(netApctlInfo.bssid)); // fake AP's mac address + netApctlInfo.ssidLength = static_cast(APname.length()); netApctlInfo.strength = 99; netApctlInfo.channel = g_Config.iWlanAdhocChannel; if (netApctlInfo.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) netApctlInfo.channel = defaultWlanChannel; // Get Local IP Address sockaddr_in sockAddr; - getLocalIp(&sockAddr); - char ipstr[INET_ADDRSTRLEN] = "127.0.0.1"; // default + getLocalIp(&sockAddr); // This will be valid IP, we probably not suppose to have a valid IP before connected to any AP, right? + char ipstr[INET_ADDRSTRLEN] = "127.0.0.1"; // Patapon 3 seems to try to get current IP using ApctlGetInfo() right after ApctlInit(), what kind of IP should we use as default before ApctlConnect()? it shouldn't be a valid IP, right? inet_ntop(AF_INET, &sockAddr.sin_addr, ipstr, sizeof(ipstr)); truncate_cpy(netApctlInfo.ip, sizeof(netApctlInfo.ip), ipstr); // Change the last number to 1 to indicate a common dns server/internet gateway @@ -575,21 +719,51 @@ static int sceNetApctlInit(int stackSize, int initPriority) { truncate_cpy(netApctlInfo.primaryDns, sizeof(netApctlInfo.primaryDns), ipstr); truncate_cpy(netApctlInfo.secondaryDns, sizeof(netApctlInfo.secondaryDns), "8.8.8.8"); truncate_cpy(netApctlInfo.subNetMask, sizeof(netApctlInfo.subNetMask), "255.255.255.0"); +} - // TODO: Create APctl fake-Thread +static int sceNetApctlInit(int stackSize, int initPriority) { + WARN_LOG(SCENET, "UNTESTED %s(%i, %i)", __FUNCTION__, stackSize, initPriority); + if (netApctlInited) + return ERROR_NET_APCTL_ALREADY_INITIALIZED; + + // Set default value before connected to an AP + memset(&netApctlInfo, 0, sizeof(netApctlInfo)); // NetApctl_InitInfo(); + truncate_cpy(netApctlInfo.ip, sizeof(netApctlInfo.ip), "0.0.0.0"); + truncate_cpy(netApctlInfo.gateway, sizeof(netApctlInfo.gateway), "0.0.0.0"); + truncate_cpy(netApctlInfo.primaryDns, sizeof(netApctlInfo.primaryDns), "0.0.0.0"); + truncate_cpy(netApctlInfo.secondaryDns, sizeof(netApctlInfo.secondaryDns), "0.0.0.0"); + truncate_cpy(netApctlInfo.subNetMask, sizeof(netApctlInfo.subNetMask), "0.0.0.0"); + + // Create APctl fake-Thread + apctlThreadID = __KernelCreateThread("ApctlThread", __KernelGetCurThreadModuleId(), apctlThreadHackAddr, initPriority, stackSize, PSP_THREAD_ATTR_USER, 0, true); + if (apctlThreadID > 0) { + __KernelStartThread(apctlThreadID, 0, 0); + } netApctlInited = true; - netApctlStatus = PSP_NET_APCTL_STATE_DISCONNECTED; + netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; + + return 0; +} + +int NetApctl_Term() { + // Cleanup Apctl resources + // Delete fake PSP Thread + if (apctlThreadID != 0) { + __KernelStopThread(apctlThreadID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "ApctlThread stopped"); + __KernelDeleteThread(apctlThreadID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "ApctlThread deleted"); + apctlThreadID = 0; + } + + netApctlInited = false; + netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; return 0; } int sceNetApctlTerm() { - ERROR_LOG(SCENET, "UNIMPL sceNeApctlTerm()"); - netApctlInited = false; - netApctlStatus = PSP_NET_APCTL_STATE_DISCONNECTED; - - return 0; + WARN_LOG(SCENET, "UNTESTED %s()", __FUNCTION__); + return NetApctl_Term(); } static int sceNetApctlGetInfo(int code, u32 pInfoAddr) { @@ -829,8 +1003,7 @@ static int sceNetInetConnect(int socket, u32 sockAddrInternetPtr, int addressLen static int sceNetApctlConnect(int connIndex) { ERROR_LOG(SCENET, "UNIMPL %s(%i)", __FUNCTION__, connIndex); - - netApctlStatus = PSP_NET_APCTL_STATE_JOINING; + // Is this connIndex is the index to the scanning's result data or sceNetApctlGetBSSDescIDListUser result? __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_CONNECT_REQUEST, 0); return 0; } @@ -839,7 +1012,7 @@ static int sceNetApctlDisconnect() { ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); // Like its 'sister' function sceNetAdhocctlDisconnect, we need to alert Apctl handlers that a disconnect took place // or else games like Phantasy Star Portable 2 will hang at certain points (e.g. returning to the main menu after trying to connect to PSN). - netApctlStatus = PSP_NET_APCTL_STATE_DISCONNECTED; + __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_DISCONNECT_REQUEST, 0); return 0; } @@ -852,7 +1025,7 @@ static int sceNetApctlGetState(u32 pStateAddr) { // Valid Arguments if (Memory::IsValidAddress(pStateAddr)) { // Return Thread Status - Memory::Write_U32(netApctlStatus, pStateAddr); + Memory::Write_U32(netApctlState, pStateAddr); // Return Success return hleLogSuccessI(SCENET, 0); } @@ -864,10 +1037,9 @@ static int sceNetApctlScanUser() { ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); // Scan probably only works when not in connected state, right? - if (netApctlStatus != PSP_NET_APCTL_STATE_DISCONNECTED) + if (netApctlState != PSP_NET_APCTL_STATE_DISCONNECTED) return hleLogError(SCENET, ERROR_NET_APCTL_NOT_DISCONNECTED, "apctl not disconnected"); - netApctlStatus = PSP_NET_APCTL_STATE_SCANNING; __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_SCAN_REQUEST, 0); return 0; } @@ -947,10 +1119,9 @@ static int sceNetApctlScanSSID2() { ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); // Scan probably only works when not in connected state, right? - if (netApctlStatus != PSP_NET_APCTL_STATE_DISCONNECTED) + if (netApctlState != PSP_NET_APCTL_STATE_DISCONNECTED) return hleLogError(SCENET, ERROR_NET_APCTL_NOT_DISCONNECTED, "apctl not disconnected"); - netApctlStatus = PSP_NET_APCTL_STATE_SCANNING; __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_SCAN_REQUEST, 0); return 0; } @@ -1150,7 +1321,9 @@ const HLEFunction sceNetApctl[] = { {0XB3CF6849, &WrapI_V, "sceNetApctlScan", 'i', "" }, {0X0C7FFA5C, &WrapI_UU, "sceNetApctlGetBSSDescIDList", 'i', "xx" }, {0X96BEB231, &WrapI_IIU, "sceNetApctlGetBSSDescEntry", 'i', "iix" }, - {0XC20A144C, &WrapI_IU, "sceNetApctl_lib2_C20A144C", 'i', "ix" }, + {0XC20A144C, &WrapI_IU, "sceNetApctl_lib2_C20A144C", 'i', "ix" }, + // Fake function for PPSSPP's use. + {0X756E6F10, &WrapV_V<__NetApctlCallbacks>, "__NetApctlCallbacks", 'v', "" }, }; const HLEFunction sceWlanDrv[] = { diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index d8514491f8..b6035e50d2 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -20,6 +20,14 @@ #include #include "Core/HLE/proAdhoc.h" +// Using constants instead of numbers for readability reason, since PSP_THREAD_ATTR_KERNEL/USER is located in sceKernelThread.cpp instead of sceKernelThread.h +#ifndef PSP_THREAD_ATTR_KERNEL +#define PSP_THREAD_ATTR_KERNEL 0x00001000 +#endif +#ifndef PSP_THREAD_ATTR_USER +#define PSP_THREAD_ATTR_USER 0x80000000 +#endif + // Option Names #define PSP_SO_REUSEPORT 0x0200 #define PSP_SO_NBIO 0x1009 @@ -186,11 +194,43 @@ struct ApctlHandler { u32 argument; }; +struct ApctlArgs { + u32_le data[5]; // OldState, NewState, Event, Error, ArgsAddr +}; + class PointerWrap; +class AfterApctlMipsCall : public PSPAction { +public: + AfterApctlMipsCall() {} + static PSPAction* Create() { return new AfterApctlMipsCall(); } + void DoState(PointerWrap& p) override { + auto s = p.Section("AfterApctlMipsCall", 1, 1); + if (!s) + return; + if (s >= 1) { + p.Do(handlerID); + p.Do(oldState); + p.Do(newState); + p.Do(event); + p.Do(error); + p.Do(argsAddr); + } + } + void run(MipsCall& call) override; + void SetData(int HandlerID, int OldState, int NewState, int Event, int Error, u32_le ArgsAddr); + +private: + int handlerID = -1; + int oldState = 0; + int newState = 0; + int event = 0; + int error = 0; + u32_le argsAddr = 0; +}; + extern bool netInetInited; extern bool netApctlInited; -extern int netApctlStatus; template std::string num2hex(I w, size_t hex_len = sizeof(I) << 1); std::string error2str(u32 errorcode); @@ -205,8 +245,6 @@ void __NetInit(); void __NetShutdown(); void __NetDoState(PointerWrap &p); -u32 Net_Term(); - int sceNetInetPoll(void *fds, u32 nfds, int timeout); int sceNetInetTerm(); int sceNetApctlTerm(); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 1cb6e29a86..f9a0fad274 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -45,14 +45,6 @@ #include "Core/HLE/proAdhocServer.h" #include "i18n/i18n.h" -// Using constants instead of numbers for readability reason, since PSP_THREAD_ATTR_KERNEL/USER is located in sceKernelThread.cpp instead of sceKernelThread.h -#ifndef PSP_THREAD_ATTR_KERNEL -#define PSP_THREAD_ATTR_KERNEL 0x00001000 -#endif -#ifndef PSP_THREAD_ATTR_USER -#define PSP_THREAD_ATTR_USER 0x80000000 -#endif - // shared in sceNetAdhoc.h since it need to be used from sceNet.cpp also // TODO: Make accessor functions instead, and throw all this state in a struct. bool netAdhocInited; diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 75f8b71541..3125294470 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -48,6 +48,7 @@ extern bool netAdhocInited; extern bool netAdhocctlInited; extern bool networkInited; extern int adhocDefaultTimeout; +extern int adhocExtraPollDelayMS; extern int adhocEventPollDelayMS; extern int adhocMatchingEventDelayMS; extern int adhocEventDelayMS; // This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 From 61fa4453dd93fc63290bfb2bb401bf825f38ec2c Mon Sep 17 00:00:00 2001 From: sum Date: Thu, 30 Jul 2020 02:14:10 +0800 Subject: [PATCH 390/848] Add two Kernel_Library's nids (#13218) * Add two Kernel_Library's nids Add HLE_KERNEL_SYSCALL flag used in #13205 * Remove HLE_KERNEL_SYSCALL flag as @unknownbrackets suggest * Add space * + "," --- Core/HLE/sceKernelInterrupt.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index e00b5ea875..7e3fab221d 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -678,6 +678,8 @@ const HLEFunction Kernel_Library[] = {0XD13BDE95, &WrapI_V, "sceKernelCheckThreadStack", 'i', "" }, {0X1839852A, &WrapU_UUU, "sceKernelMemcpy", 'x', "xxx" }, {0XFA835CDE, &WrapI_I, "sceKernelGetTlsAddr", 'i', "i" }, + {0X05572A5F, &WrapV_V, "sceKernelExitGame", 'v', "" }, + {0X4AC57943, &WrapI_I, "sceKernelRegisterExitCallback", 'i', "i" }, }; static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) { From b0a073b4bbb67302413d13f6a59728d121b443f7 Mon Sep 17 00:00:00 2001 From: BreadFish64 Date: Wed, 29 Jul 2020 16:23:05 -0500 Subject: [PATCH 391/848] Fix alpha channel handling in xBRZ texture filter shader --- GPU/Vulkan/TextureCacheVulkan.cpp | 65 +++++++++++++++---------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 8e1adacccf..57068030f5 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -65,11 +65,7 @@ static const VkComponentMapping VULKAN_8888_SWIZZLE = { VK_COMPONENT_SWIZZLE_R, // 4xBRZ shader - Copyright (C) 2014-2016 DeSmuME team (GPL2+) // Hyllian's xBR-vertex code and texel mapping // Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com -// TODO: Handles alpha badly for PSP. const char *shader4xbrz = R"( -vec4 premultiply_alpha(vec4 c) { float a = clamp(c.a, 0.0, 1.0); return vec4(c.rgb * a, a); } -vec4 postdivide_alpha(vec4 c) { return c.a < 0.001? vec4(0.0,0.0,0.0,0.0) : vec4(c.rgb / c.a, c.a); } - #define BLEND_ALPHA 1 #define BLEND_NONE 0 #define BLEND_NORMAL 1 @@ -84,15 +80,16 @@ float reduce(vec4 color) { } float DistYCbCr(vec4 pixA, vec4 pixB) { - const vec3 w = vec3(0.2627, 0.6780, 0.0593); - const float scaleB = 0.5 / (1.0 - w.b); - const float scaleR = 0.5 / (1.0 - w.r); + // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion + const vec3 K = vec3(0.2627, 0.6780, 0.0593); + const mat3 MATRIX = mat3(K, + -.5 * K.r / (1.0 - K.b), -.5 * K.g / (1.0 - K.b), .5, + .5, -.5 * K.g / (1.0 - K.r), -.5 * K.b / (1.0 - K.r)); vec4 diff = pixA - pixB; - float Y = dot(diff.rgb, w); - float Cb = scaleB * (diff.b - Y); - float Cr = scaleR * (diff.r - Y); - - return sqrt( ((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr) + (diff.a * diff.a)); + vec3 YCbCr = diff.rgb * MATRIX; + YCbCr.x *= LUMINANCE_WEIGHT; + float d = length(YCbCr); + return sqrt(pixA.a * pixB.a * d * d + diff.a * diff.a); } bool IsPixEqual(const vec4 pixA, const vec4 pixB) { @@ -133,27 +130,27 @@ vec4 applyScalingf(uvec2 origxy, uvec2 xy) { vec4 src[25]; - src[21] = premultiply_alpha(readColorf(t1.xw)); - src[22] = premultiply_alpha(readColorf(t1.yw)); - src[23] = premultiply_alpha(readColorf(t1.zw)); - src[ 6] = premultiply_alpha(readColorf(t2.xw)); - src[ 7] = premultiply_alpha(readColorf(t2.yw)); - src[ 8] = premultiply_alpha(readColorf(t2.zw)); - src[ 5] = premultiply_alpha(readColorf(t3.xw)); - src[ 0] = premultiply_alpha(readColorf(t3.yw)); - src[ 1] = premultiply_alpha(readColorf(t3.zw)); - src[ 4] = premultiply_alpha(readColorf(t4.xw)); - src[ 3] = premultiply_alpha(readColorf(t4.yw)); - src[ 2] = premultiply_alpha(readColorf(t4.zw)); - src[15] = premultiply_alpha(readColorf(t5.xw)); - src[14] = premultiply_alpha(readColorf(t5.yw)); - src[13] = premultiply_alpha(readColorf(t5.zw)); - src[19] = premultiply_alpha(readColorf(t6.xy)); - src[18] = premultiply_alpha(readColorf(t6.xz)); - src[17] = premultiply_alpha(readColorf(t6.xw)); - src[ 9] = premultiply_alpha(readColorf(t7.xy)); - src[10] = premultiply_alpha(readColorf(t7.xz)); - src[11] = premultiply_alpha(readColorf(t7.xw)); + src[21] = readColorf(t1.xw); + src[22] = readColorf(t1.yw); + src[23] = readColorf(t1.zw); + src[ 6] = readColorf(t2.xw); + src[ 7] = readColorf(t2.yw); + src[ 8] = readColorf(t2.zw); + src[ 5] = readColorf(t3.xw); + src[ 0] = readColorf(t3.yw); + src[ 1] = readColorf(t3.zw); + src[ 4] = readColorf(t4.xw); + src[ 3] = readColorf(t4.yw); + src[ 2] = readColorf(t4.zw); + src[15] = readColorf(t5.xw); + src[14] = readColorf(t5.yw); + src[13] = readColorf(t5.zw); + src[19] = readColorf(t6.xy); + src[18] = readColorf(t6.xz); + src[17] = readColorf(t6.xw); + src[ 9] = readColorf(t7.xy); + src[10] = readColorf(t7.xz); + src[11] = readColorf(t7.xw); float v[9]; v[0] = reduce(src[0]); @@ -339,7 +336,7 @@ vec4 applyScalingf(uvec2 origxy, uvec2 xy) { step(0.75, f.y)), step(0.50, f.y)); - return postdivide_alpha(res); + return res; } uint applyScalingu(uvec2 origxy, uvec2 xy) { From c7e2eba23179b1d114870506f0a6c724f4ea4f64 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 31 Jul 2020 10:24:17 +0800 Subject: [PATCH 392/848] Add basic Microphone support on Windows. --- Core/Config.h | 1 + Core/HLE/sceAudio.cpp | 8 +- Core/HLE/sceKernel.cpp | 5 +- Core/HLE/sceKernelThread.cpp | 1 + Core/HLE/sceKernelThread.h | 1 + Core/HLE/sceUsb.cpp | 2 +- Core/HLE/sceUsbMic.cpp | 323 +++++++++++++++++++++++++++++++++-- Core/HLE/sceUsbMic.h | 51 ++++++ UI/GameSettingsScreen.cpp | 13 ++ UI/GameSettingsScreen.h | 1 + UI/NativeApp.cpp | 8 + Windows/CaptureDevice.cpp | 260 +++++++++++++++++++++++----- Windows/CaptureDevice.h | 41 ++++- Windows/MainWindow.cpp | 5 +- 14 files changed, 661 insertions(+), 59 deletions(-) diff --git a/Core/Config.h b/Core/Config.h index 03e3b34584..497e7eae20 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -142,6 +142,7 @@ public: std::string sVulkanDevice; std::string sD3D11Device; // Windows only std::string sCameraDevice; + std::string sMicDevice; bool bSoftwareRendering; bool bHardwareTransform; // only used in the GLES backend diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index f3c355b655..f6bab60de0 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -23,6 +23,7 @@ #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceAudio.h" +#include "Core/HLE/sceUsbMic.h" #include "Core/HLE/__sceAudio.h" #include "Core/Reporting.h" @@ -471,6 +472,11 @@ static u32 sceAudioSRCOutputBlocking(u32 vol, u32 buf) { return hleLogSuccessI(SCEAUDIO, result); } +static int sceAudioInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr) { + ERROR_LOG(HLE, "sceAudioInputBlocking: maxSamples: %d, samplerate: %d, bufAddr: %08x", maxSamples, sampleRate, bufAddr); + return __MicInputBlocking(maxSamples, sampleRate, bufAddr); +} + static u32 sceAudioRoutingSetMode(u32 mode) { ERROR_LOG_REPORT(SCEAUDIO, "sceAudioRoutingSetMode(%08x)", mode); int previousMode = defaultRoutingMode; @@ -535,7 +541,7 @@ const HLEFunction sceAudio[] = {0X7DE61688, nullptr, "sceAudioInputInit", '?', "" }, {0XE926D3FB, nullptr, "sceAudioInputInitEx", '?', "" }, {0X6D4BEC68, nullptr, "sceAudioInput", '?', "" }, - {0X086E5895, nullptr, "sceAudioInputBlocking", '?', "" }, + {0X086E5895, &WrapI_UUU, "sceAudioInputBlocking", 'i', "xxx" }, {0XA708C6A6, nullptr, "sceAudioGetInputLength", '?', "" }, {0XA633048E, nullptr, "sceAudioPollInputEnd", '?', "" }, {0X87B2E651, nullptr, "sceAudioWaitInputEnd", '?', "" }, diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 70d1f13ca6..cedef16ed6 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -77,12 +77,13 @@ #include "sceImpose.h" #include "sceUsb.h" #include "sceUsbGps.h" +#include "sceUsbCam.h" +#include "sceUsbMic.h" #include "scePspNpDrm_user.h" #include "sceVaudio.h" #include "sceHeap.h" #include "sceDmac.h" #include "sceMp4.h" -#include "sceUsbCam.h" #include "../Util/PPGeDraw.h" @@ -146,6 +147,7 @@ void __KernelInit() __VideoPmpInit(); __UsbGpsInit(); __UsbCamInit(); + __UsbMicInit(); SaveState::Init(); // Must be after IO, as it may create a directory Reporting::Init(); @@ -170,6 +172,7 @@ void __KernelShutdown() kernelObjects.Clear(); __UsbCamShutdown(); + __UsbMicShutdown(); __UsbGpsShutdown(); __AudioCodecShutdown(); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 83c8fb6635..29c256b3db 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -79,6 +79,7 @@ const WaitTypeNames waitTypeNames[] = { { WAITTYPE_TLSPL, "TLS" }, { WAITTYPE_VMEM, "Volatile Mem" }, { WAITTYPE_ASYNCIO, "AsyncIO" }, + { WAITTYPE_MICINPUT, "Microphone input"}, }; const char *getWaitTypeName(WaitType type) diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 4c3041f65a..5c85ba661b 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -106,6 +106,7 @@ enum WaitType : int WAITTYPE_TLSPL = 21, WAITTYPE_VMEM = 22, WAITTYPE_ASYNCIO = 23, + WAITTYPE_MICINPUT = 24, // fake NUM_WAITTYPES }; diff --git a/Core/HLE/sceUsb.cpp b/Core/HLE/sceUsb.cpp index cd2e5e5e16..c29ef6e6b2 100644 --- a/Core/HLE/sceUsb.cpp +++ b/Core/HLE/sceUsb.cpp @@ -83,7 +83,7 @@ static int sceUsbGetState() { | (usbConnected ? USB_STATUS_CONNECTED : USB_STATUS_DISCONNECTED) | (usbActivated ? USB_STATUS_ACTIVATED : USB_STATUS_DEACTIVATED); } - INFO_LOG(HLE, "sceUsbGetState: 0x%x", state); + DEBUG_LOG(HLE, "sceUsbGetState: 0x%x", state); return state; } diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 306f527da1..e9f0b8f5c7 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -21,29 +21,328 @@ #include "Common/ChunkFile.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" +#include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceUsbMic.h" +#include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" +#include "Windows/CaptureDevice.h" -static int sceUsbMicInputBlocking(u32 size, u32 samplerate, u32 bufAddr) { - INFO_LOG(HLE, "UNIMPL sceUsbMicInputBlocking: size: %d, samplerate: %d", size, samplerate); - for (unsigned int i = 0; i < size; i++) { - if (Memory::IsValidAddress(bufAddr + i)) { - Memory::Write_U8(i & 0xFF, bufAddr + i); +#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) +#define HAVE_WIN32_MICROPHONE +#endif + +enum { + SCE_USBMIC_ERROR_INVALID_MAX_SAMPLES = 0x80243806, + SCE_USBMIC_ERROR_INVALID_SAMPLERATE = 0x8024380A, +}; + +int eventUsbMicAudioUpdate = -1; + +QueueBuf *audioBuf = nullptr; +u32 audioBufSize = 0; +u32 numNeedSamples = 0; +static std::vector waitingThreads; +std::mutex wtMutex; +bool isNeedInput = false; + +static void __UsbMicAudioUpdate(u64 userdata, int cyclesLate) { + SceUID threadID = (SceUID)userdata; + u32 error; + int count = 0; + std::unique_lock lock(wtMutex); + for (auto waitingThread : waitingThreads) { + if (waitingThread.threadID == threadID) { + SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_MICINPUT, error); + if (waitID == 0) + continue; + if (Microphone::isHaveDevice()) { + if (Microphone::availableAudioBufSize() >= waitingThread.needSize) { + u8 *tempbuf8 = new u8[waitingThread.needSize]; + Microphone::getAudioData(tempbuf8, waitingThread.needSize); + u16 *tempbuf16 = (u16*)tempbuf8; + for (u32 i = 0; i < waitingThread.needSize / 2; i++) { + if (Memory::IsValidAddress(waitingThread.addr + i * 2)) { + Memory::Write_U16(tempbuf16[i] & 0xFFFF, waitingThread.addr + i * 2); + } + } + delete[] tempbuf8; + u32 ret = __KernelGetWaitValue(threadID, error); + DEBUG_LOG(HLE, "sceUsbMic: Waking up thread(%d)", (int)waitingThread.threadID); + __KernelResumeThreadFromWait(threadID, ret); + waitingThreads.erase(waitingThreads.begin() + count); + if (waitingThreads.size() == 0) + isNeedInput = false; + } else { + u64 waitTimeus = (waitingThread.needSize - Microphone::availableAudioBufSize()) * 1000000 / 2 / waitingThread.sampleRate; + CoreTiming::ScheduleEvent(usToCycles(waitTimeus), eventUsbMicAudioUpdate, userdata); + } + } else { + for (u32 i = 0; i < waitingThread.needSize; i++) { + if (Memory::IsValidAddress(waitingThread.addr + i)) { + Memory::Write_U8(i & 0xFF, waitingThread.addr + i); + } + } + u32 ret = __KernelGetWaitValue(threadID, error); + DEBUG_LOG(HLE, "sceUsbMic: Waking up thread(%d)", (int)waitingThread.threadID); + __KernelResumeThreadFromWait(threadID, ret); + waitingThreads.erase(waitingThreads.begin() + count); + if (waitingThreads.size() == 0) + isNeedInput = false; + } } + ++count; } - hleEatMicro(1000000 / samplerate * (size / 2)); + lock.unlock(); +} + +void __UsbMicInit() { + eventUsbMicAudioUpdate = CoreTiming::RegisterEvent("UsbMicAudioUpdate", &__UsbMicAudioUpdate); +} + +void __UsbMicShutdown() { + if (audioBuf) { + delete audioBuf; + audioBuf = nullptr; + } + Microphone::stopMic(); +} + +QueueBuf::QueueBuf(u32 size) : start(0), end(0), capacity(size) { + buf_ = new u8[size]; +} + +QueueBuf::~QueueBuf() { + delete[] buf_; +} + +void QueueBuf::push(u8 *buf, u32 size) { + if (getRemainingSize() < size) { + resize((capacity + size - getRemainingSize()) * 3 / 2); + } + std::unique_lock lock(mutex); + if (end + size <= capacity) { + memcpy(buf_ + end, buf, size); + end += size; + } else { + memcpy(buf_ + end, buf, capacity - end); + size -= capacity - end; + memcpy(buf_, buf + capacity - end, size); + end = size; + } + lock.unlock(); +} + +u32 QueueBuf::pop(u8 *buf, u32 size) { + u32 ret = 0; + if (getAvailableSize() < size) + size = getAvailableSize(); + ret = size; + + std::unique_lock lock(mutex); + if (start + size <= capacity) { + memcpy(buf, buf_ + start, size); + start += size; + } else { + memcpy(buf, buf_ + start, capacity - start); + size -= capacity - start; + memcpy(buf + capacity - start, buf_, size); + start = size; + } + lock.unlock(); + return ret; +} + +void QueueBuf::resize(u32 newSize) { + u32 availableSize = getAvailableSize(); + u8 *oldbuf = buf_; + + std::unique_lock lock(mutex); + buf_ = new u8[newSize]; + if (end >= start) { + memcpy(buf_, oldbuf + start, availableSize); + } else { + memcpy(buf_, oldbuf + start, capacity - start); + memcpy(buf_ + capacity - start, oldbuf, availableSize - (capacity - start)); + } + start = 0; + end = availableSize; + capacity = newSize; + delete[] oldbuf; + lock.unlock(); +} + +u32 QueueBuf::getAvailableSize() { + u32 availableSize = 0; + if (end >= start) { + availableSize = end - start; + } else { + availableSize = end + capacity - start; + } + return availableSize; +} + +u32 QueueBuf::getRemainingSize() { + return capacity - getAvailableSize(); +} + +static int sceUsbMicPollInputEnd() { + ERROR_LOG(HLE, "UNIMPL sceUsbMicPollInputEnd"); + return 0; +} + +static int sceUsbMicInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr) { + INFO_LOG(HLE, "sceUsbMicInputBlocking: maxSamples: %d, samplerate: %d, bufAddr: %08x", maxSamples, sampleRate, bufAddr); + if (maxSamples <= 0 || (maxSamples & 0x3F) != 0) { + return SCE_USBMIC_ERROR_INVALID_MAX_SAMPLES; + } + + if (sampleRate != 44100 && sampleRate != 22050 && sampleRate != 11025) { + return SCE_USBMIC_ERROR_INVALID_SAMPLERATE; + } + return __MicInputBlocking(maxSamples, sampleRate, bufAddr); +} + +static int sceUsbMicInputInitEx(u32 paramAddr) { + ERROR_LOG(HLE, "UNIMPL sceUsbMicInputInitEx: %08x", paramAddr); + return 0; +} + +static int sceUsbMicInput() { + ERROR_LOG(HLE, "UNIMPL sceUsbMicInput"); + return 0; +} +static int sceUsbMicGetInputLength() { + int ret = Microphone::availableAudioBufSize() / 2; + ERROR_LOG(HLE, "UNTEST sceUsbMicGetInputLength(ret: %d)", ret); + return ret; +} + +static int sceUsbMicInputInit(int unknown1, int inputVolume, int unknown2) { + ERROR_LOG(HLE, "UNIMPL sceUsbMicInputInit(unknown1: %d, inputVolume: %d, unknown2: %d)", unknown1, inputVolume, unknown2); + return 0; +} + +static int sceUsbMicWaitInputEnd() { + ERROR_LOG(HLE, "UNIMPL sceUsbMicWaitInputEnd"); + return 0; +} + +int Microphone::startMic(void *param) { +#ifdef HAVE_WIN32_MICROPHONE + if (winMic) + winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::START, param }); +#endif + + return 0; +} + +int Microphone::stopMic() { +#ifdef HAVE_WIN32_MICROPHONE + if (winMic) + winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::STOP, nullptr }); +#endif + return 0; +} + +bool Microphone::isHaveDevice() { +#ifdef HAVE_WIN32_MICROPHONE + return winMic->getDeviceCounts() >= 1; +#endif + return false; +} + +bool Microphone::isMicStarted() { +#ifdef HAVE_WIN32_MICROPHONE + if(winMic) + return winMic->isStarted(); +#endif + return false; +} + +bool Microphone::isNeedInput() { + return ::isNeedInput; +} + +u32 Microphone::numNeedSamples() { + return ::numNeedSamples; +} + +u32 Microphone::availableAudioBufSize() { + return audioBuf->getAvailableSize(); +} + +int Microphone::addAudioData(u8 *buf, u32 size) { + if (audioBuf) + audioBuf->push(buf, size); + else + return 0; + return size; } +u32 Microphone::getAudioData(u8 *buf, u32 size) { + if(audioBuf) + return audioBuf->pop(buf, size); + + return 0; +} + +std::vector Microphone::getDeviceList() { +#ifdef HAVE_WIN32_MICROPHONE + if (winMic) { + return winMic->getDeviceList(); + } +#endif + return std::vector(); +} + +void Microphone::onMicDeviceChange() { + if (Microphone::isMicStarted()) { + Microphone::stopMic(); + // Just use the last param. + Microphone::startMic(nullptr); + } +} + +u32 __MicInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr) { + u32 size = maxSamples << 1; + numNeedSamples = maxSamples; + if (size != audioBufSize) { + if (audioBuf) { + delete audioBuf; + } + audioBuf = new QueueBuf(size); + audioBufSize = size; + } + if (!Microphone::isMicStarted()) { + std::vector *param = new std::vector({ sampleRate, 1 }); + Microphone::startMic(param); + } + u64 waitTimeus = 0; + if (Microphone::availableAudioBufSize() < size) { + waitTimeus = (size - Microphone::availableAudioBufSize()) * 1000000 / 2 / sampleRate; + isNeedInput = true; + } + CoreTiming::ScheduleEvent(usToCycles(waitTimeus), eventUsbMicAudioUpdate, __KernelGetCurThread()); + MicWaitInfo waitInfo = { __KernelGetCurThread(), bufAddr, size, sampleRate }; + std::unique_lock lock(wtMutex); + waitingThreads.push_back(waitInfo); + lock.unlock(); + DEBUG_LOG(HLE, "MicInputBlocking: blocking thread(%d)", (int)__KernelGetCurThread()); + __KernelWaitCurThread(WAITTYPE_MICINPUT, 1, size, 0, false, "blocking microphone"); + + return maxSamples; +} + const HLEFunction sceUsbMic[] = { - {0x06128E42, nullptr, "sceUsbMicPollInputEnd", '?', "" }, + {0x06128E42, &WrapI_V, "sceUsbMicPollInputEnd", 'i', "" }, {0x2E6DCDCD, &WrapI_UUU, "sceUsbMicInputBlocking", 'i', "xxx" }, - {0x45310F07, nullptr, "sceUsbMicInputInitEx", '?', "" }, - {0x5F7F368D, nullptr, "sceUsbMicInput", '?', "" }, - {0x63400E20, nullptr, "sceUsbMicGetInputLength", '?', "" }, - {0xB8E536EB, nullptr, "sceUsbMicInputInit", '?', "" }, - {0xF899001C, nullptr, "sceUsbMicWaitInputEnd", '?', "" }, + {0x45310F07, &WrapI_U, "sceUsbMicInputInitEx", 'i', "x" }, + {0x5F7F368D, &WrapI_V , "sceUsbMicInput", 'i', "" }, + {0x63400E20, &WrapI_V, "sceUsbMicGetInputLength", 'i', "" }, + {0xB8E536EB, &WrapI_III, "sceUsbMicInputInit", 'i', "iii" }, + {0xF899001C, &WrapI_V, "sceUsbMicWaitInputEnd", 'i', "" }, }; void Register_sceUsbMic() diff --git a/Core/HLE/sceUsbMic.h b/Core/HLE/sceUsbMic.h index 35e1132861..09d6a661c4 100644 --- a/Core/HLE/sceUsbMic.h +++ b/Core/HLE/sceUsbMic.h @@ -16,4 +16,55 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #pragma once + +#include "sceKernel.h" +#include + void Register_sceUsbMic(); + +void __UsbMicInit(); +void __UsbMicShutdown(); + +struct MicWaitInfo { + SceUID threadID; + u32 addr; + u32 needSize; + u32 sampleRate; +}; + +class QueueBuf { +public: + QueueBuf(u32 size); + ~QueueBuf(); + + void push(u8 *buf, u32 size); + u32 pop(u8 *buf, u32 size); + void resize(u32 newSize); + u32 getAvailableSize(); + u32 getRemainingSize(); + +private: + u32 start; + u32 end; + u32 capacity; + u8 *buf_; + std::mutex mutex; +}; + +namespace Microphone { + int startMic(void *param); + int stopMic(); + bool isHaveDevice(); + bool isMicStarted(); + bool isNeedInput(); + u32 numNeedSamples(); + u32 availableAudioBufSize(); + + int addAudioData(u8 *buf, u32 size); + u32 getAudioData(u8 *buf, u32 size); + + std::vector getDeviceList(); + void onMicDeviceChange(); +} + +u32 __MicInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 97d0bd2f2a..cab0032809 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -60,6 +60,7 @@ #include "Core/TextureReplacer.h" #include "Core/WebServer.h" #include "Core/HLE/sceUsbCam.h" +#include "Core/HLE/sceUsbMic.h" #include "GPU/Common/PostShader.h" #include "android/jni/TestRunner.h" #include "GPU/GPUInterface.h" @@ -547,6 +548,13 @@ void GameSettingsScreen::CreateViews() { } #endif + std::vector micList = Microphone::getDeviceList(); + if (micList.size() >= 1) { + audioSettings->Add(new ItemHeader(gr->T("Microphone"))); + PopupMultiChoiceDynamic *MicChoice = audioSettings->Add(new PopupMultiChoiceDynamic(&g_Config.sMicDevice, gr->T("Microphone Device"), micList, nullptr, screenManager())); + MicChoice->OnChoice.Handle(this, &GameSettingsScreen::OnMicDeviceChange); + } + #if defined(SDL) std::vector audioDeviceList; SplitString(System_GetProperty(SYSPROP_AUDIO_DEVICE_LIST), '\0', audioDeviceList); @@ -1309,6 +1317,11 @@ UI::EventReturn GameSettingsScreen::OnCameraDeviceChange(UI::EventParams& e) { return UI::EVENT_DONE; } +UI::EventReturn GameSettingsScreen::OnMicDeviceChange(UI::EventParams& e) { + Microphone::onMicDeviceChange(); + return UI::EVENT_DONE; +} + UI::EventReturn GameSettingsScreen::OnAudioDevice(UI::EventParams &e) { auto a = GetI18NCategory("Audio"); if (g_Config.sAudioDevice == a->T("Auto")) { diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index 2279b620ce..f2f27bc206 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -103,6 +103,7 @@ private: UI::EventReturn OnRenderingDevice(UI::EventParams &e); UI::EventReturn OnInflightFramesChoice(UI::EventParams &e); UI::EventReturn OnCameraDeviceChange(UI::EventParams& e); + UI::EventReturn OnMicDeviceChange(UI::EventParams& e); UI::EventReturn OnAudioDevice(UI::EventParams &e); UI::EventReturn OnJitAffectingSetting(UI::EventParams &e); #if PPSSPP_PLATFORM(ANDROID) diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index bb59188e86..b819476fcf 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -894,6 +894,8 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { if (IsWin7OrHigher()) { winCamera = new WindowsCaptureDevice(CAPTUREDEVIDE_TYPE::VIDEO); winCamera->sendMessage({ CAPTUREDEVIDE_COMMAND::INITIALIZE, nullptr }); + winMic = new WindowsCaptureDevice(CAPTUREDEVIDE_TYPE::AUDIO); + winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::INITIALIZE, nullptr }); } #endif @@ -926,6 +928,12 @@ void NativeShutdownGraphics() { delete winCamera; winCamera = nullptr; } + if (winMic) { + winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::SHUTDOWN, nullptr }); + while (!winMic->isShutDown()) {};// Wait for shutting down. + delete winMic; + winMic = nullptr; + } #endif UIBackgroundShutdown(); diff --git a/Windows/CaptureDevice.cpp b/Windows/CaptureDevice.cpp index d6c453c05d..e69f983e2b 100644 --- a/Windows/CaptureDevice.cpp +++ b/Windows/CaptureDevice.cpp @@ -24,8 +24,6 @@ #include "Core/HLE/sceUsbCam.h" #include "Core/Config.h" -bool isDeviceChanged = false; - namespace MFAPI { HINSTANCE Mflib; HINSTANCE Mfplatlib; @@ -87,6 +85,7 @@ bool unRegisterCMPTMFApis() { } WindowsCaptureDevice *winCamera; +WindowsCaptureDevice *winMic; // TODO: Add more formats, but need some tests. VideoFormatTransform g_VideoFormats[] = @@ -97,19 +96,28 @@ VideoFormatTransform g_VideoFormats[] = { MFVideoFormat_NV12, AV_PIX_FMT_NV12 } }; -const int g_cVideoFormats = 4; +AudioFormatTransform g_AudioFormats[] = { + { MFAudioFormat_PCM, 8, AV_SAMPLE_FMT_U8 }, + { MFAudioFormat_PCM, 16, AV_SAMPLE_FMT_S16 }, + { MFAudioFormat_PCM, 32, AV_SAMPLE_FMT_S32 }, + { MFAudioFormat_Float, 32, AV_SAMPLE_FMT_FLT } +}; + +const int g_cVideoFormats = ARRAYSIZE(g_VideoFormats); +const int g_cAudioFormats = ARRAYSIZE(g_AudioFormats); MediaParam defaultVideoParam = { 640, 480, 0, MFVideoFormat_RGB24 }; -MediaParam defaultAudioParam = { 44100, 2, 0, MFAudioFormat_PCM }; +MediaParam defaultAudioParam = { 44100, 2, 2, MFAudioFormat_PCM }; HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride); -ReaderCallback::ReaderCallback(WindowsCaptureDevice *device): img_convert_ctx(nullptr){ +ReaderCallback::ReaderCallback(WindowsCaptureDevice *device): img_convert_ctx(nullptr), resample_ctx(nullptr){ this->device = device; } ReaderCallback::~ReaderCallback() { sws_freeContext(img_convert_ctx); + swr_free(&resample_ctx); } HRESULT ReaderCallback::QueryInterface(REFIID riid, void** ppv) @@ -130,7 +138,6 @@ HRESULT ReaderCallback::OnReadSample( IMFSample *pSample) { HRESULT hr = S_OK; IMFMediaBuffer *pBuffer = nullptr; - LONG lStride = 0; std::lock_guard lock(device->sdMutex); if (device->isShutDown()) return hr; @@ -151,6 +158,7 @@ HRESULT ReaderCallback::OnReadSample( int imgJpegSize = device->imgJpegSize; unsigned char* invertedSrcImg = nullptr; LONG srcPadding = 0; + LONG lStride = 0; UINT32 srcW = device->deviceParam.width; UINT32 srcH = device->deviceParam.height; @@ -207,14 +215,53 @@ HRESULT ReaderCallback::OnReadSample( nullptr ); } - delete videoBuffer; break; } - case CAPTUREDEVIDE_TYPE::AUDIO: - // TODO: + case CAPTUREDEVIDE_TYPE::AUDIO: { + BYTE *sampleBuf = nullptr; + DWORD length = 0; + u32 sizeAfterResample = 0; + // pSample can be null, in this case ReadSample still should be called to request next frame. + if (pSample && Microphone::isNeedInput()) { + pBuffer->Lock(&sampleBuf, nullptr, &length); + if (!device->rawAudioBuf) { + device->rawAudioBuf = new QueueBuf(length * 2); // Alloc enough space. + } + device->rawAudioBuf->push(sampleBuf, length); + if (device->needResample()) { + sizeAfterResample = device->rawAudioBuf->getAvailableSize() * device->targetMediaParam.sampleRate / device->deviceParam.sampleRate / device->deviceParam.channels; + // Wait until have enough audio data. + if (sizeAfterResample + Microphone::availableAudioBufSize() >= Microphone::numNeedSamples() * 2) { + u32 rawAudioBufSize = device->rawAudioBuf->getAvailableSize(); + u8 *tempbuf = new u8[rawAudioBufSize]; + device->rawAudioBuf->pop(tempbuf, rawAudioBufSize); + sizeAfterResample = doResample( + &device->resampleBuf, device->targetMediaParam.sampleRate, device->targetMediaParam.channels, &device->resampleBufSize, + tempbuf, device->deviceParam.sampleRate, device->deviceParam.channels, device->deviceParam.audioFormat, rawAudioBufSize, device->deviceParam.bitsPerSample); + delete[] tempbuf; + if (device->resampleBuf) + Microphone::addAudioData(device->resampleBuf, sizeAfterResample); + } + } else { + Microphone::addAudioData(sampleBuf, length); + } + pBuffer->Unlock(); + } + // Request the next frame. + if (SUCCEEDED(hr)) { + hr = device->m_pReader->ReadSample( + (DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, + 0, + nullptr, + nullptr, + nullptr, + nullptr + ); + } break; } + } } SafeRelease(&pBuffer); @@ -229,6 +276,14 @@ AVPixelFormat ReaderCallback::getAVVideoFormatbyMFVideoFormat(const GUID &MFVide return AV_PIX_FMT_RGB24; } +AVSampleFormat ReaderCallback::getAVAudioFormatbyMFAudioFormat(const GUID &MFAudioFormat, const u32 &bitsPerSample) { + for (int i = 0; i < g_cAudioFormats; i++) { + if (MFAudioFormat == g_AudioFormats[i].MFAudioFormat && bitsPerSample == g_AudioFormats[i].bitsPerSample) + return g_AudioFormats[i].AVAudioFormat; + } + return AV_SAMPLE_FMT_S16; +} + void ReaderCallback::imgConvert( unsigned char *dst, unsigned int &dstW, unsigned int &dstH, int dstLineSizes[4], unsigned char *src, const unsigned int &srcW, const unsigned int &srcH, const GUID &srcFormat, @@ -237,9 +292,9 @@ void ReaderCallback::imgConvert( unsigned char *pSrc[4]; unsigned char *pDst[4]; - AVPixelFormat srcAvFormat = getAVVideoFormatbyMFVideoFormat(srcFormat); + AVPixelFormat srcAVFormat = getAVVideoFormatbyMFVideoFormat(srcFormat); - av_image_fill_linesizes(srcLineSizes, srcAvFormat, srcW); + av_image_fill_linesizes(srcLineSizes, srcAVFormat, srcW); // Is this correct? if (srcPadding != 0) { @@ -249,16 +304,14 @@ void ReaderCallback::imgConvert( } } - av_image_fill_pointers(pSrc, srcAvFormat, srcH, src, srcLineSizes); + av_image_fill_pointers(pSrc, srcAVFormat, srcH, src, srcLineSizes); av_image_fill_pointers(pDst, AV_PIX_FMT_RGB24, dstH, dst, dstLineSizes); - - if (img_convert_ctx == nullptr) { img_convert_ctx = sws_getContext( srcW, srcH, - srcAvFormat, + srcAVFormat, dstW, dstH, AV_PIX_FMT_RGB24, @@ -348,28 +401,68 @@ void ReaderCallback::imgInvertNV12(unsigned char *dst, int &dstStride, unsigned } } +u32 ReaderCallback::doResample(u8 **dst, u32 &dstSampleRate, u32 &dstChannels, u32 *dstSize, u8 *src, const u32 &srcSampleRate, const u32 &srcChannels, const GUID &srcFormat, const u32& srcSize, const u32& srcBitsPerSample) { + AVSampleFormat srcAVFormat = getAVAudioFormatbyMFAudioFormat(srcFormat, srcBitsPerSample); + int outSamplesCount = 0; + if (resample_ctx == nullptr) { + resample_ctx = swr_alloc_set_opts(nullptr, + av_get_default_channel_layout(dstChannels), + AV_SAMPLE_FMT_S16, + dstSampleRate, + av_get_default_channel_layout(srcChannels), + srcAVFormat, + srcSampleRate, + 0, + nullptr); + if (resample_ctx == nullptr || swr_init(resample_ctx) < 0) { + swr_free(&resample_ctx); + return 0; + } + } + int srcSamplesCount = srcSize / srcChannels / av_get_bytes_per_sample(srcAVFormat); // per channel. + int outCount = srcSamplesCount * dstSampleRate / srcSampleRate + 256; + unsigned int outSize = av_samples_get_buffer_size(nullptr, dstChannels, outCount, AV_SAMPLE_FMT_S16, 0); + + if (!*dst) { + *dst = (u8 *)av_malloc(outSize); + *dstSize = outSize; + } + if (!*dst) + return 0; + + if(*dstSize < outSize) + av_fast_malloc(dst, dstSize, outSize); + + outSamplesCount = swr_convert(resample_ctx, dst, outCount, (const uint8_t **)&src, srcSamplesCount); + if (outSamplesCount < 0) + return 0; + return av_samples_get_buffer_size(nullptr, dstChannels, outSamplesCount, AV_SAMPLE_FMT_S16, 0); +} + WindowsCaptureDevice::WindowsCaptureDevice(CAPTUREDEVIDE_TYPE type) : type(type), m_pCallback(nullptr), m_pSource(nullptr), m_pReader(nullptr), + imageRGB(nullptr), + imageJpeg(nullptr), + imgJpegSize(0), + resampleBuf(nullptr), + resampleBufSize(0), + rawAudioBuf(nullptr), error(CAPTUREDEVIDE_ERROR_NO_ERROR), errorMessage(""), + isDeviceChanged(false), state(CAPTUREDEVIDE_STATE::UNINITIALIZED) { param = { 0 }; + deviceParam = { 0 }; switch (type) { case CAPTUREDEVIDE_TYPE::VIDEO: targetMediaParam = defaultVideoParam; - imageRGB = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB24, targetMediaParam.width, targetMediaParam.height, 1)); - imgJpegSize = av_image_get_buffer_size(AV_PIX_FMT_YUVJ411P, targetMediaParam.width, targetMediaParam.height, 1); - imageJpeg = (unsigned char*)av_malloc(imgJpegSize); break; case CAPTUREDEVIDE_TYPE::AUDIO: - // TODO: targetMediaParam = defaultAudioParam; - imageRGB = nullptr; - imageJpeg = nullptr; break; } @@ -380,11 +473,12 @@ WindowsCaptureDevice::WindowsCaptureDevice(CAPTUREDEVIDE_TYPE type) : WindowsCaptureDevice::~WindowsCaptureDevice() { switch (type) { case CAPTUREDEVIDE_TYPE::VIDEO: - av_free(imageRGB); - av_free(imageJpeg); + av_freep(&imageRGB); + av_freep(&imageJpeg); break; case CAPTUREDEVIDE_TYPE::AUDIO: - // TODO: + av_freep(&resampleBuf); + delete rawAudioBuf; break; } } @@ -412,7 +506,7 @@ bool WindowsCaptureDevice::init() { return true; } -bool WindowsCaptureDevice::start(UINT32 width, UINT32 height) { +bool WindowsCaptureDevice::start(void *startParam) { HRESULT hr = S_OK; IMFAttributes *pAttributes = nullptr; IMFMediaType *pType = nullptr; @@ -434,16 +528,14 @@ bool WindowsCaptureDevice::start(UINT32 width, UINT32 height) { return false; } - targetMediaParam.width = width; - targetMediaParam.height = height; - av_image_fill_linesizes(imgRGBLineSizes, AV_PIX_FMT_RGB24, targetMediaParam.width); - m_pCallback = new ReaderCallback(this); + std::string selectedDeviceName = type == CAPTUREDEVIDE_TYPE::VIDEO ? g_Config.sCameraDevice : g_Config.sMicDevice; + switch (state) { case CAPTUREDEVIDE_STATE::STOPPED: for (auto &name : deviceList) { - if (name == g_Config.sCameraDevice) { + if (name == selectedDeviceName) { selection = count; break; } @@ -477,7 +569,21 @@ bool WindowsCaptureDevice::start(UINT32 width, UINT32 height) { if (SUCCEEDED(hr)) { switch (type) { - case CAPTUREDEVIDE_TYPE::VIDEO: + case CAPTUREDEVIDE_TYPE::VIDEO: { + if (startParam) { + std::vector *resolution = static_cast*>(startParam); + targetMediaParam.width = resolution->at(0); + targetMediaParam.height = resolution->at(1); + delete resolution; + } + + av_freep(&imageRGB); + av_freep(&imageJpeg); + imageRGB = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB24, targetMediaParam.width, targetMediaParam.height, 1)); + imgJpegSize = av_image_get_buffer_size(AV_PIX_FMT_YUVJ411P, targetMediaParam.width, targetMediaParam.height, 1); + imageJpeg = (unsigned char*)av_malloc(imgJpegSize); + av_image_fill_linesizes(imgRGBLineSizes, AV_PIX_FMT_RGB24, targetMediaParam.width); + for (DWORD i = 0; ; i++) { hr = m_pReader->GetNativeMediaType( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, @@ -512,13 +618,45 @@ bool WindowsCaptureDevice::start(UINT32 width, UINT32 height) { nullptr ); } - break; + } - case CAPTUREDEVIDE_TYPE::AUDIO: - // TODO: + case CAPTUREDEVIDE_TYPE::AUDIO: { + if (startParam) { + std::vector *micParam = static_cast*>(startParam); + targetMediaParam.sampleRate = micParam->at(0); + targetMediaParam.channels = micParam->at(1); + delete micParam; + } + + for (DWORD i = 0; ; i++) { + hr = m_pReader->GetNativeMediaType( + (DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, + i, + &pType + ); + + if (FAILED(hr)) { break; } + + hr = setDeviceParam(pType); + + if (SUCCEEDED(hr)) + break; + } + + if (SUCCEEDED(hr)) { + hr = m_pReader->ReadSample( + (DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, + 0, + nullptr, + nullptr, + nullptr, + nullptr + ); + } break; } + } } if (FAILED(hr)) { @@ -670,7 +808,46 @@ HRESULT WindowsCaptureDevice::setDeviceParam(IMFMediaType *pType) { break; case CAPTUREDEVIDE_TYPE::AUDIO: - // TODO: + hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype); + if (FAILED(hr)) + break; + + for (int i = 0; i < g_cVideoFormats; i++) { + if (subtype == g_AudioFormats[i].MFAudioFormat) { + deviceParam.audioFormat = subtype; + getFormat = true; + break; + } + } + + if (!getFormat) { + for (int i = 0; i < g_cAudioFormats; i++) { + hr = pType->SetGUID(MF_MT_SUBTYPE, g_AudioFormats[i].MFAudioFormat); + if (FAILED(hr)) + continue; + + hr = m_pReader->SetCurrentMediaType( + (DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, + NULL, + pType + ); + + if (SUCCEEDED(hr)) { + deviceParam.audioFormat = g_AudioFormats[i].MFAudioFormat; + getFormat = true; + break; + } + } + } + if (SUCCEEDED(hr)) + hr = pType->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &deviceParam.sampleRate); + + if (SUCCEEDED(hr)) + hr = pType->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &deviceParam.channels); + + if (SUCCEEDED(hr)) + hr = pType->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, (UINT32 *)&deviceParam.bitsPerSample); + break; } @@ -701,10 +878,11 @@ void WindowsCaptureDevice::messageHandler() { CoInitializeEx(NULL, COINIT_MULTITHREADED); MFStartup(MF_VERSION); CAPTUREDEVIDE_MESSAGE message; - std::vector* resolution; if (type == CAPTUREDEVIDE_TYPE::VIDEO) { setCurrentThreadName("Camera"); + } else if (type == CAPTUREDEVIDE_TYPE::AUDIO) { + setCurrentThreadName("Microphone"); } while ((message = getMessage()).command != CAPTUREDEVIDE_COMMAND::SHUTDOWN) { @@ -713,8 +891,7 @@ void WindowsCaptureDevice::messageHandler() { init(); break; case CAPTUREDEVIDE_COMMAND::START: - resolution = static_cast*>(message.opacity); - start(resolution->at(0), resolution->at(1)); + start(message.opacity); break; case CAPTUREDEVIDE_COMMAND::STOP: stop(); @@ -781,6 +958,13 @@ HRESULT WindowsCaptureDevice::enumDevices() { return hr; } +bool WindowsCaptureDevice::needResample() { + return deviceParam.sampleRate != targetMediaParam.sampleRate || + deviceParam.channels != targetMediaParam.channels || + deviceParam.audioFormat != targetMediaParam.audioFormat || + deviceParam.bitsPerSample != targetMediaParam.bitsPerSample; +} + //----------------------------------------------------------------------------- // GetDefaultStride // diff --git a/Windows/CaptureDevice.h b/Windows/CaptureDevice.h index aa0d0dc744..60f9b61b05 100644 --- a/Windows/CaptureDevice.h +++ b/Windows/CaptureDevice.h @@ -26,10 +26,13 @@ #include #include +#include "Core/HLE/sceUsbMic.h" + #ifdef __cplusplus extern "C" { #include "libavformat/avformat.h" #include "libswscale/swscale.h" +#include "libswresample/swresample.h" #include "libavutil/imgutils.h" } #endif // __cplusplus @@ -39,6 +42,12 @@ struct VideoFormatTransform { AVPixelFormat AVVideoFormat; }; +struct AudioFormatTransform { + GUID MFAudioFormat; + u32 bitsPerSample; + AVSampleFormat AVAudioFormat; +}; + enum class CAPTUREDEVIDE_TYPE { VIDEO, AUDIO @@ -90,8 +99,8 @@ union MediaParam { struct { UINT32 sampleRate; UINT32 channels; - LONG padding; - GUID audioFomat; + LONG bitsPerSample; + GUID audioFormat; }; }; @@ -127,9 +136,10 @@ public: STDMETHODIMP OnFlush(DWORD) { return S_OK; } AVPixelFormat getAVVideoFormatbyMFVideoFormat(const GUID &MFVideoFormat); + AVSampleFormat getAVAudioFormatbyMFAudioFormat(const GUID &MFAudioFormat, const u32 &bitsPerSample); /* - * Always convet the image to RGB24 + * Always convert the image to RGB24 * @param dst/src pointer to destination/source image * @param dstW/srcW, dstH/srcH destination/source image's width and height in pixels * @param dstLineSizes get the linesize of each plane by av_image_fill_linesizes() @@ -149,10 +159,20 @@ public: void imgInvertYUY2(unsigned char *dst, int &dstStride, unsigned char *src, const int &srcStride, const int &h); void imgInvertNV12(unsigned char *dst, int &dstStride, unsigned char *src, const int &srcStride, const int &h); + /* + * Always resample to uncompressed signed 16bits + * @param dst pointer to pointer of dst buffer could be a nullptr, would be overwritten by a new pointer if space too small or a nullptr, should be freed by av_free/av_freep by caller + * @param dstSize pointer to size of the dst buffer, could be modified after this func + * @param srcFormat MF_MT_SUBTYPE attribute of the source audio data + * @param srcSize size of valid data in the source buffer, in bytes + * @return size of output in bytes + */ + u32 doResample(u8 **dst, u32 &dstSampleRate, u32 &dstChannels, u32 *dstSize, u8 *src, const u32 &srcSampleRate, const u32 &srcChannels, const GUID &srcFormat, const u32 &srcSize, const u32& srcBitsPerSamples); protected: WindowsCaptureDevice *device; SwsContext *img_convert_ctx; + SwrContext *resample_ctx; }; class WindowsCaptureDevice { @@ -160,10 +180,10 @@ public: WindowsCaptureDevice(CAPTUREDEVIDE_TYPE type); ~WindowsCaptureDevice(); - static void CheckDevices(); + void CheckDevices(); bool init(); - bool start(UINT32 width, UINT32 height); + bool start(void *startParam); bool stop(); CAPTUREDEVIDE_ERROR getError() const { return error; } @@ -178,12 +198,15 @@ public: HRESULT setDeviceParam(IMFMediaType *pType); bool isShutDown() const { return state == CAPTUREDEVIDE_STATE::SHUTDOWN; } + bool isStarted() const { return state == CAPTUREDEVIDE_STATE::STARTED; } void sendMessage(CAPTUREDEVIDE_MESSAGE message); CAPTUREDEVIDE_MESSAGE getMessage(); HRESULT enumDevices(); + bool needResample(); + friend class ReaderCallback; protected: @@ -199,6 +222,8 @@ protected: CAPTUREDEVIDE_ERROR error; std::string errorMessage; + bool isDeviceChanged; + // MF interface. ReaderCallback *m_pCallback; IMFSourceReader *m_pReader; @@ -220,6 +245,12 @@ protected: int imgRGBLineSizes[4]; unsigned char *imageJpeg; int imgJpegSize; + +//Microphone only + u8 *resampleBuf; + u32 resampleBufSize; + QueueBuf *rawAudioBuf; }; extern WindowsCaptureDevice *winCamera; +extern WindowsCaptureDevice *winMic; diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 3d835c9ea0..a735878ba0 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -849,7 +849,10 @@ namespace MainWindow #ifndef _M_ARM DinputDevice::CheckDevices(); #endif - WindowsCaptureDevice::CheckDevices(); + if (winCamera) + winCamera->CheckDevices(); + if (winMic) + winMic->CheckDevices(); return DefWindowProc(hWnd, message, wParam, lParam); case WM_VERYSLEEPY_MSG: From 94aaf21ef268169e424d28e01f4a890542595b01 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 31 Jul 2020 10:25:26 +0800 Subject: [PATCH 393/848] Use UTF-8 code page to get the device names. --- Windows/CaptureDevice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/CaptureDevice.cpp b/Windows/CaptureDevice.cpp index e69f983e2b..4830e1a091 100644 --- a/Windows/CaptureDevice.cpp +++ b/Windows/CaptureDevice.cpp @@ -735,13 +735,13 @@ std::vector WindowsCaptureDevice::getDeviceList(bool forceEnum, int if (SUCCEEDED(hr)) { // Get the size needed first - dwMinSize = WideCharToMultiByte(CP_OEMCP, NULL, pwstrName, -1, nullptr, 0, nullptr, FALSE); + dwMinSize = WideCharToMultiByte(CP_UTF8, NULL, pwstrName, -1, nullptr, 0, nullptr, FALSE); if (dwMinSize == 0) hr = -1; } if (SUCCEEDED(hr)) { cstrName = new char[dwMinSize]; - WideCharToMultiByte(CP_OEMCP, NULL, pwstrName, -1, cstrName, dwMinSize, NULL, FALSE); + WideCharToMultiByte(CP_UTF8, NULL, pwstrName, -1, cstrName, dwMinSize, NULL, FALSE); strName = cstrName; delete[] cstrName; From 6d26bd6539b474e18c70f3c4d11f00d08e2c8e60 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 31 Jul 2020 15:52:03 +0800 Subject: [PATCH 394/848] Do state. --- Core/HLE/sceKernel.cpp | 1 + Core/HLE/sceUsbMic.cpp | 70 +++++++++++++++++++++++++++++++++++++++--- Core/HLE/sceUsbMic.h | 5 +++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index cedef16ed6..d84aad032a 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -272,6 +272,7 @@ void __KernelDoState(PointerWrap &p) __UmdDoState(p); __UtilityDoState(p); __UsbDoState(p); + __UsbMicDoState(p); __VaudioDoState(p); __HeapDoState(p); diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index e9f0b8f5c7..8041aed186 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -39,11 +39,13 @@ enum { int eventUsbMicAudioUpdate = -1; QueueBuf *audioBuf = nullptr; -u32 audioBufSize = 0; u32 numNeedSamples = 0; static std::vector waitingThreads; std::mutex wtMutex; bool isNeedInput = false; +u32 curSampleRate = 44100; +u32 curChannels = 1; +int micState = 0; // 0 means stopped, 1 means started, for save state. static void __UsbMicAudioUpdate(u64 userdata, int cyclesLate) { SceUID threadID = (SceUID)userdata; @@ -107,6 +109,35 @@ void __UsbMicShutdown() { Microphone::stopMic(); } +void __UsbMicDoState(PointerWrap &p) { + auto s = p.Section("sceUsbMic", 1, 1); + if (!s) { + return; + } + p.Do(numNeedSamples); + p.Do(waitingThreads); + p.Do(isNeedInput); + p.Do(curSampleRate); + p.Do(curChannels); + p.Do(micState); + // Maybe also need to save the state of audioBuf. + if (waitingThreads.size() != 0 && p.mode == PointerWrap::MODE_READ) { + u64 waitTimeus = (waitingThreads[0].needSize - Microphone::availableAudioBufSize()) * 1000000 / 2 / waitingThreads[0].sampleRate; + CoreTiming::ScheduleEvent(usToCycles(waitTimeus), eventUsbMicAudioUpdate, waitingThreads[0].threadID); + } + if (micState == 0) { + if (Microphone::isMicStarted()) + Microphone::stopMic(); + } else if (micState == 1) { + if (Microphone::isMicStarted()) { + Microphone::stopMic(); + Microphone::startMic(new std::vector({ curSampleRate, curChannels })); + } else { + Microphone::startMic(new std::vector({ curSampleRate, curChannels })); + } + } +} + QueueBuf::QueueBuf(u32 size) : start(0), end(0), capacity(size) { buf_ = new u8[size]; } @@ -115,6 +146,26 @@ QueueBuf::~QueueBuf() { delete[] buf_; } +QueueBuf::QueueBuf(const QueueBuf &buf) { + buf_ = new u8[buf.capacity]; + memcpy(buf_, buf.buf_, buf.capacity); + start = buf.start; + end = buf.end; + capacity = buf.capacity; +} + +QueueBuf& QueueBuf::operator=(const QueueBuf &buf) { + if (capacity < buf.capacity) { + resize(buf.capacity); + } + std::unique_lock lock(mutex); + memcpy(buf_, buf.buf_, buf.capacity); + start = buf.start; + end = buf.end; + lock.unlock(); + return *this; +} + void QueueBuf::push(u8 *buf, u32 size) { if (getRemainingSize() < size) { resize((capacity + size - getRemainingSize()) * 3 / 2); @@ -171,6 +222,13 @@ void QueueBuf::resize(u32 newSize) { lock.unlock(); } +void QueueBuf::flush() { + std::unique_lock lock(mutex); + start = 0; + end = 0; + lock.unlock(); +} + u32 QueueBuf::getAvailableSize() { u32 availableSize = 0; if (end >= start) { @@ -199,6 +257,8 @@ static int sceUsbMicInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr) { if (sampleRate != 44100 && sampleRate != 22050 && sampleRate != 11025) { return SCE_USBMIC_ERROR_INVALID_SAMPLERATE; } + curSampleRate = sampleRate; + curChannels = 1; return __MicInputBlocking(maxSamples, sampleRate, bufAddr); } @@ -232,7 +292,7 @@ int Microphone::startMic(void *param) { if (winMic) winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::START, param }); #endif - + micState = 1; return 0; } @@ -241,6 +301,7 @@ int Microphone::stopMic() { if (winMic) winMic->sendMessage({ CAPTUREDEVIDE_COMMAND::STOP, nullptr }); #endif + micState = 0; return 0; } @@ -306,14 +367,13 @@ void Microphone::onMicDeviceChange() { u32 __MicInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr) { u32 size = maxSamples << 1; - numNeedSamples = maxSamples; - if (size != audioBufSize) { + if (size != numNeedSamples << 1) { if (audioBuf) { delete audioBuf; } audioBuf = new QueueBuf(size); - audioBufSize = size; } + numNeedSamples = maxSamples; if (!Microphone::isMicStarted()) { std::vector *param = new std::vector({ sampleRate, 1 }); Microphone::startMic(param); diff --git a/Core/HLE/sceUsbMic.h b/Core/HLE/sceUsbMic.h index 09d6a661c4..e8ffea37c6 100644 --- a/Core/HLE/sceUsbMic.h +++ b/Core/HLE/sceUsbMic.h @@ -24,6 +24,7 @@ void Register_sceUsbMic(); void __UsbMicInit(); void __UsbMicShutdown(); +void __UsbMicDoState(PointerWrap &p); struct MicWaitInfo { SceUID threadID; @@ -37,9 +38,13 @@ public: QueueBuf(u32 size); ~QueueBuf(); + QueueBuf(const QueueBuf &buf); + QueueBuf& operator=(const QueueBuf &buf); + void push(u8 *buf, u32 size); u32 pop(u8 *buf, u32 size); void resize(u32 newSize); + void flush(); u32 getAvailableSize(); u32 getRemainingSize(); From d195cba8376953f7a5576b2f1b7f08f59ba32095 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 31 Jul 2020 17:10:00 +0800 Subject: [PATCH 395/848] Flush audio buffer when a transmission is completed. --- Core/HLE/sceAudio.cpp | 2 +- Core/HLE/sceUsbMic.cpp | 20 ++++++++++++++++---- Core/HLE/sceUsbMic.h | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index f6bab60de0..f75b66604c 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -473,7 +473,7 @@ static u32 sceAudioSRCOutputBlocking(u32 vol, u32 buf) { } static int sceAudioInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr) { - ERROR_LOG(HLE, "sceAudioInputBlocking: maxSamples: %d, samplerate: %d, bufAddr: %08x", maxSamples, sampleRate, bufAddr); + ERROR_LOG(HLE, "UNIMPL sceAudioInputBlocking: maxSamples: %d, samplerate: %d, bufAddr: %08x", maxSamples, sampleRate, bufAddr); return __MicInputBlocking(maxSamples, sampleRate, bufAddr); } diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 8041aed186..19607cdcc6 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -204,6 +204,9 @@ u32 QueueBuf::pop(u8 *buf, u32 size) { } void QueueBuf::resize(u32 newSize) { + if (capacity >= newSize) { + return; + } u32 availableSize = getAvailableSize(); u8 *oldbuf = buf_; @@ -348,6 +351,10 @@ u32 Microphone::getAudioData(u8 *buf, u32 size) { return 0; } +void Microphone::flushAudioData() { + audioBuf->flush(); +} + std::vector Microphone::getDeviceList() { #ifdef HAVE_WIN32_MICROPHONE if (winMic) { @@ -367,13 +374,18 @@ void Microphone::onMicDeviceChange() { u32 __MicInputBlocking(u32 maxSamples, u32 sampleRate, u32 bufAddr) { u32 size = maxSamples << 1; - if (size != numNeedSamples << 1) { - if (audioBuf) { - delete audioBuf; + if (size > numNeedSamples << 1) { + if (!audioBuf) { + audioBuf = new QueueBuf(size); + } else { + audioBuf->resize(size); } - audioBuf = new QueueBuf(size); } + if (!audioBuf) + return 0; + numNeedSamples = maxSamples; + Microphone::flushAudioData(); if (!Microphone::isMicStarted()) { std::vector *param = new std::vector({ sampleRate, 1 }); Microphone::startMic(param); diff --git a/Core/HLE/sceUsbMic.h b/Core/HLE/sceUsbMic.h index e8ffea37c6..c073d4cf56 100644 --- a/Core/HLE/sceUsbMic.h +++ b/Core/HLE/sceUsbMic.h @@ -67,6 +67,7 @@ namespace Microphone { int addAudioData(u8 *buf, u32 size); u32 getAudioData(u8 *buf, u32 size); + void flushAudioData(); std::vector getDeviceList(); void onMicDeviceChange(); From 107d58a74b76e343ab99f2b0ba45d451cbe64559 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 31 Jul 2020 18:26:21 +0800 Subject: [PATCH 396/848] Also partly implement in sceUsbCam. --- Core/HLE/sceUsbCam.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index c2d0ed1609..a5c4653335 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -23,6 +23,7 @@ #include "Common/ChunkFile.h" #include "Core/HLE/HLE.h" #include "Core/HLE/sceUsbCam.h" +#include "Core/HLE/sceUsbMic.h" #include "Core/HW/Camera.h" #include "Core/MemMapHelpers.h" @@ -112,7 +113,7 @@ static int getCameraResolution(Camera::ConfigType type, int *width, int *height) static int sceUsbCamSetupMic(u32 paramAddr, u32 workareaAddr, int wasize) { - INFO_LOG(HLE, "UNIMPL sceUsbCamSetupMic"); + INFO_LOG(HLE, "sceUsbCamSetupMic"); if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupMicParam))) { Memory::ReadStruct(paramAddr, &config->micParam); } @@ -131,13 +132,7 @@ static int sceUsbCamStopMic() { static int sceUsbCamReadMicBlocking(u32 bufAddr, u32 size) { INFO_LOG(HLE, "UNIMPL sceUsbCamReadMicBlocking: size: %d", size); - for (unsigned int i = 0; i < size; i++) { - if (Memory::IsValidAddress(bufAddr + i)) { - Memory::Write_U8(i & 0xFF, bufAddr + i); - } - } - hleEatMicro(1000000 / config->micParam.frequency * (size / 2)); - return size; + return __MicInputBlocking(size >> 1, config->micParam.frequency, bufAddr); } static int sceUsbCamSetupVideo(u32 paramAddr, u32 workareaAddr, int wasize) { From fd619c9fc5a5a3f7b79cf9969dc3263e365bfeb6 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 31 Jul 2020 19:19:51 +0800 Subject: [PATCH 397/848] BuildFix --- Core/HLE/sceUsbMic.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 19607cdcc6..7c8477f25a 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -25,12 +25,15 @@ #include "Core/HLE/sceUsbMic.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" -#include "Windows/CaptureDevice.h" #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) && !defined(__LIBRETRO__) #define HAVE_WIN32_MICROPHONE #endif +#ifdef HAVE_WIN32_MICROPHONE +#include "Windows/CaptureDevice.h" +#endif + enum { SCE_USBMIC_ERROR_INVALID_MAX_SAMPLES = 0x80243806, SCE_USBMIC_ERROR_INVALID_SAMPLERATE = 0x8024380A, From 5de721bb4cf3af93de92fc0ea172c5dddfb938f1 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sat, 1 Aug 2020 19:50:23 +0800 Subject: [PATCH 398/848] minor fix --- Core/HLE/sceKernel.cpp | 2 +- Windows/CaptureDevice.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index d84aad032a..685c624cef 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -272,7 +272,6 @@ void __KernelDoState(PointerWrap &p) __UmdDoState(p); __UtilityDoState(p); __UsbDoState(p); - __UsbMicDoState(p); __VaudioDoState(p); __HeapDoState(p); @@ -282,6 +281,7 @@ void __KernelDoState(PointerWrap &p) __VideoPmpDoState(p); __AACDoState(p); __UsbGpsDoState(p); + __UsbMicDoState(p); // IMPORTANT! Add new sections last! } diff --git a/Windows/CaptureDevice.cpp b/Windows/CaptureDevice.cpp index 4830e1a091..6ae0733e51 100644 --- a/Windows/CaptureDevice.cpp +++ b/Windows/CaptureDevice.cpp @@ -106,8 +106,8 @@ AudioFormatTransform g_AudioFormats[] = { const int g_cVideoFormats = ARRAYSIZE(g_VideoFormats); const int g_cAudioFormats = ARRAYSIZE(g_AudioFormats); -MediaParam defaultVideoParam = { 640, 480, 0, MFVideoFormat_RGB24 }; -MediaParam defaultAudioParam = { 44100, 2, 2, MFAudioFormat_PCM }; +MediaParam defaultVideoParam = { 640, 480, 0, MFVideoFormat_RGB24 }; +MediaParam defaultAudioParam = { 44100, 2, 16, MFAudioFormat_PCM }; HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride); From a897be92c74e1b36de9d4b8ae6d24d08de487763 Mon Sep 17 00:00:00 2001 From: sum Date: Sat, 1 Aug 2020 20:15:12 +0800 Subject: [PATCH 399/848] Imp sceUtilsBufferCopyWithRange and sceUtilsBufferCopyByPollingWithRange (#13206) * Imp sceUtilsBufferCopyWithRange Used in Shin Sangoku Musou 6 Special chinese patach #13205 * Fix sceUtilsBufferCopyByPollingWithRange * Add logging and reporting * Fix logging and remove report by @hrydgard --- Core/HLE/HLETables.cpp | 1 + Core/HLE/sceKernelSemaphore.cpp | 26 ++++++++++++++++++++++++++ Core/HLE/sceKernelSemaphore.h | 7 +++++++ 3 files changed, 34 insertions(+) diff --git a/Core/HLE/HLETables.cpp b/Core/HLE/HLETables.cpp index 843e4195aa..4c5ed553aa 100644 --- a/Core/HLE/HLETables.cpp +++ b/Core/HLE/HLETables.cpp @@ -303,6 +303,7 @@ void RegisterAllModules() { Register_sceUsbAcc(); Register_sceUsbMic(); Register_sceOpenPSID_driver(); + Register_semaphore(); // add new modules here. } diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index f6de056d2e..24a65e25fa 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -26,6 +26,7 @@ #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelSemaphore.h" #include "Core/HLE/KernelWaitHelpers.h" +#include "Core/HLE/FunctionWrappers.h" #define PSP_SEMA_ATTR_FIFO 0 #define PSP_SEMA_ATTR_PRIORITY 0x100 @@ -457,3 +458,28 @@ int sceKernelPollSema(SceUID id, int wantedCount) } } +static u32 hleUtilsBufferCopyWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) +{ + int temp = sceUtilsBufferCopyWithRange((u8*)outAddr, outSize, (u8*)inAddr, inSize, cmd); + if (temp != 0) { + ERROR_LOG(SCEKERNEL, "hleUtilsBufferCopyWithRange: Failed with %d", temp); + } + return 0; +} + +static int sceUtilsBufferCopyByPollingWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) +{ + return sceUtilsBufferCopyWithRange((u8*)outAddr, outSize, (u8*)inAddr, inSize, cmd); +} + +const HLEFunction semaphore[] = { + {0x4C537C72, &WrapU_UIUII, "sceUtilsBufferCopyWithRange", 'x', "xixii" }, + {0x77E97079, &WrapI_UIUII, "sceUtilsBufferCopyByPollingWithRange", 'i', "xixii" }, + +}; + + + +void Register_semaphore() { + RegisterModule("semaphore", ARRAY_SIZE(semaphore), semaphore); +} \ No newline at end of file diff --git a/Core/HLE/sceKernelSemaphore.h b/Core/HLE/sceKernelSemaphore.h index 14df34cbed..0165c0c739 100644 --- a/Core/HLE/sceKernelSemaphore.h +++ b/Core/HLE/sceKernelSemaphore.h @@ -31,3 +31,10 @@ void __KernelSemaTimeout(u64 userdata, int cycleslate); void __KernelSemaInit(); void __KernelSemaDoState(PointerWrap &p); KernelObject *__KernelSemaphoreObject(); + +void Register_semaphore(); + +extern "C" +{ +#include "ext/libkirk/kirk_engine.h" +} \ No newline at end of file From 1380c09cb865ff982ec51070648c3b25e7990e67 Mon Sep 17 00:00:00 2001 From: AdamN Date: Sat, 1 Aug 2020 20:24:21 +0700 Subject: [PATCH 400/848] Patapon 3 Fix (#13231) * Showing returned error code in the logs to give more info on the exact error with so many error code variations. * Fix an issue where players that got forcefully disconnected (ie. Resetting the game) are no longer recognized by the Host when trying to reJoin on Patapon 3 * Allows Optional data pointer to be non-zero/null even if Optional data Length is 0, since we're not even accessing the data if it's length is 0 anyway. TODO: Will need someone to confirm if this is really allowed or returning an error on a real PSP. * Fix Identity issue on Patapon 3 where all players became Player1. This should also fix other games with similar issue. --- Core/HLE/proAdhoc.h | 4 +- Core/HLE/sceNetAdhoc.cpp | 91 +++++++++++++++++++++------------------- Core/HLE/sceOpenPSID.cpp | 9 ++-- 3 files changed, 57 insertions(+), 47 deletions(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 860808960b..ad97a485cd 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -1231,8 +1231,8 @@ u64 join32(u32 num1, u32 num2); void split64(u64 num, int buff[]); /** - * Returns the local mac, TODO: Read from Config file - * @param addr OUT: Local Mac + * Returns the local mac + * @param addr OUT: 6-bytes of Local Mac */ void getLocalMac(SceNetEtherAddr * addr); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 1cb6e29a86..1c68dfbacc 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -3333,7 +3333,7 @@ static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddres if (peer != NULL) { // Valid Optional Data Length - if ((optLen == 0 && optDataPtr == 0) || (optLen > 0 && optDataPtr != 0)) + if ((optLen == 0) || (optLen > 0 && optDataPtr != 0)) { void * opt = NULL; if (Memory::IsValidAddress(optDataPtr)) opt = Memory::GetPointer(optDataPtr); @@ -3341,10 +3341,10 @@ static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddres if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { // Already Connected - if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) return ERROR_NET_ADHOC_MATCHING_ALREADY_ESTABLISHED; + if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_ALREADY_ESTABLISHED, "adhocmatching already established"); // Not enough space - if (countChildren(context) == (context->maxpeers - 1)) return ERROR_NET_ADHOC_MATCHING_EXCEED_MAXNUM; + if (countChildren(context) == (context->maxpeers - 1)) return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_EXCEED_MAXNUM, "adhocmatching exceed maxnum"); // Requesting Peer if (peer->state == PSP_ADHOC_MATCHING_PEER_INCOMING_REQUEST) @@ -3372,10 +3372,10 @@ static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddres else if (context->mode == PSP_ADHOC_MATCHING_MODE_CHILD) { // Already connected - if (findParent(context) != NULL) return ERROR_NET_ADHOC_MATCHING_ALREADY_ESTABLISHED; + if (findParent(context) != NULL) return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_ALREADY_ESTABLISHED, "adhocmatching already established"); // Outgoing Request in Progress - if (findOutgoingRequest(context) != NULL) return ERROR_NET_ADHOC_MATCHING_REQUEST_IN_PROGRESS; + if (findOutgoingRequest(context) != NULL) return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_REQUEST_IN_PROGRESS, "adhocmatching request in progress"); // Valid Offer if (peer->state == PSP_ADHOC_MATCHING_PEER_OFFER) @@ -3395,10 +3395,10 @@ static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddres else { // Already connected - if (findP2P(context) != NULL) return ERROR_NET_ADHOC_MATCHING_ALREADY_ESTABLISHED; + if (findP2P(context) != NULL) return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_ALREADY_ESTABLISHED, "adhocmatching already established"); // Outgoing Request in Progress - if (findOutgoingRequest(context) != NULL) return ERROR_NET_ADHOC_MATCHING_REQUEST_IN_PROGRESS; + if (findOutgoingRequest(context) != NULL) return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_REQUEST_IN_PROGRESS, "adhocmatching request in progress"); // Join Request Mode if (peer->state == PSP_ADHOC_MATCHING_PEER_OFFER) @@ -3430,31 +3430,31 @@ static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddres } // How did this happen?! It shouldn't! - return ERROR_NET_ADHOC_MATCHING_TARGET_NOT_READY; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_TARGET_NOT_READY, "adhocmatching target not ready"); } // Invalid Optional Data Length - return ERROR_NET_ADHOC_MATCHING_INVALID_OPTLEN; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_OPTLEN, "adhocmatching invalid optlen"); } // Peer not found - return ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET, "adhocmatching unknown target"); } // Idle Context - return ERROR_NET_ADHOC_MATCHING_NOT_RUNNING; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_RUNNING, "adhocmatching not running"); } // Invalid Matching ID - return ERROR_NET_ADHOC_MATCHING_INVALID_ID; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ID, "adhocmatching invalid id"); } // Invalid Arguments - return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "adhocmatching invalid arg"); } // Uninitialized Library - return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED, "adhocmatching not initialized"); } int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { @@ -3470,7 +3470,7 @@ int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddres if (Memory::IsValidAddress(optDataPtr)) opt = Memory::GetPointer(optDataPtr); // Valid Arguments - if (target != NULL && ((optLen == 0 && opt == NULL) || (optLen > 0 && opt != NULL))) + if (target != NULL && ((optLen == 0) || (optLen > 0 && opt != NULL))) { // Find Matching Context SceNetAdhocMatchingContext * context = findMatchingContext(matchingId); @@ -3508,6 +3508,8 @@ int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddres // Delete Peer from List // Can't delete here, Threads still need this data. // deletePeer(context, peer); + // Marking peer to be timedout instead of deleting immediately + peer->lastping = 0; // Return Success return 0; @@ -3515,25 +3517,25 @@ int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddres } // Peer not found - //return ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET; + //return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET, "adhocmatching unknown target"); // Faking success to prevent the game (ie. Soul Calibur) to repeatedly calling this function when the other player is disconnected return 0; } // Context not running - return ERROR_NET_ADHOC_MATCHING_NOT_RUNNING; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_RUNNING, "adhocmatching not running"); } // Invalid Matching ID - return ERROR_NET_ADHOC_MATCHING_INVALID_ID; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ID, "adhocmatching invalid id"); } // Invalid Arguments - return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "adhocmatching invalid arg"); } // Uninitialized Library - return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED, "adhocmatching not initialized"); } int sceNetAdhocMatchingCancelTarget(int matchingId, const char *macAddress) { @@ -3600,7 +3602,7 @@ int sceNetAdhocMatchingSetHelloOpt(int matchingId, int optLenAddr, u32 optDataAd if (context->running) { // Valid Optional Data Length - if ((optLenAddr == 0 && optDataAddr == 0) || (optLenAddr > 0 && optDataAddr != 0)) + if ((optLenAddr == 0) || (optLenAddr > 0 && optDataAddr != 0)) { // Grab Existing Hello Data void * hello = context->hello; @@ -3664,7 +3666,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) if (!g_Config.bEnableWlan) return -1; - // Ys vs. Sora no Kiseki seems to be using this function long after AdhocMatching is Terminated + // Ys vs. Sora no Kiseki seems to be using this function even after AdhocMatching is Terminated, May be member list persist even after AdhocMatching terminated until the next init? if (!netAdhocMatchingInited) { //WARN_LOG(SCENET, "sceNetAdhocMatchingGetMembers - AdhocMatching is Not Initialized"); return 0; // ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; @@ -3672,7 +3674,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Minimum Argument if (!Memory::IsValidAddress(sizeAddr)) - return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "adhocmatching invalid arg"); // Multithreading Lock peerlock.lock(); @@ -3750,7 +3752,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) if (p2p != NULL) { // Faking lastping - if (p2p->lastping != 0) + auto friendpeer = findFriend(&p2p->mac); + if (p2p->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) p2p->lastping = CoreTiming::GetGlobalTimeUsScaled(); // Add P2P Brother MAC @@ -3770,7 +3773,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Should we exclude timedout members? if (!excludeTimedout || peer->lastping != 0) { // Faking lastping - if (peer->lastping != 0) + auto friendpeer = findFriend(&peer->mac); + if (peer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); // Parent Mode @@ -3825,15 +3829,15 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) } // Invalid Arguments - return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "adhocmatching invalid arg"); } // Context not running - return ERROR_NET_ADHOC_MATCHING_NOT_RUNNING; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_RUNNING, "adhocmatching not running"); } // Invalid Matching ID - return ERROR_NET_ADHOC_MATCHING_INVALID_ID; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ID, "adhocmatching invalid id"); } int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u32 dataAddr) { @@ -3885,31 +3889,31 @@ int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u3 } // Not connected / accepted - return ERROR_NET_ADHOC_MATCHING_NOT_ESTABLISHED; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_ESTABLISHED, "adhocmatching not established"); } // Invalid Data Length - return ERROR_NET_ADHOC_MATCHING_INVALID_DATALEN; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_DATALEN, "adhocmatching invalid datalen"); } // Peer not found - return ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET, "adhocmatching unknown target"); } // Context not running - return ERROR_NET_ADHOC_MATCHING_NOT_RUNNING; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_RUNNING, "adhocmatching not running"); } // Invalid Matching ID - return ERROR_NET_ADHOC_MATCHING_INVALID_ID; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ID, "adhocmatching invalid id"); } // Invalid Arguments - return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "adhocmatching invalid arg"); } // Uninitialized Library - return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED, "adhocmatching not initialized"); } int sceNetAdhocMatchingAbortSendData(int matchingId, const char *mac) { @@ -3953,23 +3957,23 @@ int sceNetAdhocMatchingAbortSendData(int matchingId, const char *mac) { } // Peer not found - return ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET, "adhocmatching unknown target"); } // Context not running - return ERROR_NET_ADHOC_MATCHING_NOT_RUNNING; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_RUNNING, "adhocmatching not running"); } // Invalid Matching ID - return ERROR_NET_ADHOC_MATCHING_INVALID_ID; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ID, "adhocmatching invalid id"); } // Invalid Arguments - return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "adhocmatching invalid arg"); } // Uninitialized Library - return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED, "adhocmatching not initialized"); } // Get the maximum memory usage by the matching library @@ -4929,7 +4933,10 @@ void actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen // If we got the peer in the table already and are a parent, there is nothing left to be done. // This is because the only way a parent can know of a child is via a join request... // If we thus know of a possible child, then we already had a previous join request thus no need for double tapping. - if (peer != NULL && context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) return; + if (peer != NULL && context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { + WARN_LOG(SCENET, "Join Event(2) Ignored"); + return; + } // New Peer if (peer == NULL) @@ -4981,7 +4988,7 @@ void actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen } } } - INFO_LOG(SCENET, "Join Event(2) Rejected"); + WARN_LOG(SCENET, "Join Event(2) Rejected"); // Auto-Reject Player sendCancelPacket(context, sendermac, 0, NULL); } diff --git a/Core/HLE/sceOpenPSID.cpp b/Core/HLE/sceOpenPSID.cpp index 44e4af77ef..46d3a7890d 100644 --- a/Core/HLE/sceOpenPSID.cpp +++ b/Core/HLE/sceOpenPSID.cpp @@ -19,11 +19,14 @@ #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceOpenPSID.h" #include "Core/MemMap.h" +#include + +u8 dummyOpenPSID[16] = { 0x10, 0x02, 0xA3, 0x44, 0x13, 0xF5, 0x93, 0xB0, 0xCC, 0x6E, 0xD1, 0x32, 0x27, 0x85, 0x0F, 0x9D }; static int sceOpenPSIDGetOpenPSID(u32 OpenPSIDPtr) { ERROR_LOG(HLE, "UNTESTED sceOpenPSIDGetOpenPSID(%d)", OpenPSIDPtr); - u8 dummyOpenPSID[16] = {0x10, 0x02, 0xA3, 0x44, 0x13, 0xF5, 0x93, 0xB0, 0xCC, 0x6E, 0xD1, 0x32, 0x27, 0x85, 0x0F, 0x9D}; + getLocalMac((SceNetEtherAddr*)&dummyOpenPSID); if (Memory::IsValidAddress(OpenPSIDPtr)) { @@ -38,7 +41,7 @@ static int sceOpenPSIDGetOpenPSID(u32 OpenPSIDPtr) static int sceOpenPSID_driver_0x19D579F0(u32 OpenPSIDPtr,u32 unknown) { ERROR_LOG(HLE, "UNTESTED sceOpenPSID_driver_0x19D579F0(%d,%d)", OpenPSIDPtr,unknown); - u8 dummyOpenPSID[16] = { 0x10, 0x02, 0xA3, 0x44, 0x13, 0xF5, 0x93, 0xB0, 0xCC, 0x6E, 0xD1, 0x32, 0x27, 0x85, 0x0F, 0x9D }; + getLocalMac((SceNetEtherAddr*)&dummyOpenPSID); if (Memory::IsValidAddress(OpenPSIDPtr)) { @@ -68,4 +71,4 @@ const HLEFunction sceOpenPSID_driver[] = void Register_sceOpenPSID_driver() { RegisterModule("sceOpenPSID_driver", ARRAY_SIZE(sceOpenPSID_driver), sceOpenPSID_driver); -} \ No newline at end of file +} From e349eb803d91066c6b02b88bbc8ab3c34b825f89 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sun, 2 Aug 2020 00:22:22 +0800 Subject: [PATCH 401/848] Init parameters in __UsbMicInit to avoid incorrect initial state when you exit to menu from ingame. Also use memcpy instead of a loop. --- Core/HLE/sceUsbMic.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 7c8477f25a..13a041a71e 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -42,13 +42,13 @@ enum { int eventUsbMicAudioUpdate = -1; QueueBuf *audioBuf = nullptr; -u32 numNeedSamples = 0; +u32 numNeedSamples; static std::vector waitingThreads; std::mutex wtMutex; -bool isNeedInput = false; -u32 curSampleRate = 44100; -u32 curChannels = 1; -int micState = 0; // 0 means stopped, 1 means started, for save state. +bool isNeedInput; +u32 curSampleRate; +u32 curChannels; +int micState; // 0 means stopped, 1 means started, for save state. static void __UsbMicAudioUpdate(u64 userdata, int cyclesLate) { SceUID threadID = (SceUID)userdata; @@ -64,12 +64,7 @@ static void __UsbMicAudioUpdate(u64 userdata, int cyclesLate) { if (Microphone::availableAudioBufSize() >= waitingThread.needSize) { u8 *tempbuf8 = new u8[waitingThread.needSize]; Microphone::getAudioData(tempbuf8, waitingThread.needSize); - u16 *tempbuf16 = (u16*)tempbuf8; - for (u32 i = 0; i < waitingThread.needSize / 2; i++) { - if (Memory::IsValidAddress(waitingThread.addr + i * 2)) { - Memory::Write_U16(tempbuf16[i] & 0xFFFF, waitingThread.addr + i * 2); - } - } + Memory::Memcpy(waitingThread.addr, tempbuf8, waitingThread.needSize); delete[] tempbuf8; u32 ret = __KernelGetWaitValue(threadID, error); DEBUG_LOG(HLE, "sceUsbMic: Waking up thread(%d)", (int)waitingThread.threadID); @@ -101,6 +96,16 @@ static void __UsbMicAudioUpdate(u64 userdata, int cyclesLate) { } void __UsbMicInit() { + if (audioBuf) { + delete audioBuf; + audioBuf = nullptr; + } + numNeedSamples = 0; + waitingThreads.clear(); + isNeedInput = false; + curSampleRate = 44100; + curChannels = 1; + micState = 0; eventUsbMicAudioUpdate = CoreTiming::RegisterEvent("UsbMicAudioUpdate", &__UsbMicAudioUpdate); } From 04761c238f14ecbbd881ba57bd43a5c7ecab9cb1 Mon Sep 17 00:00:00 2001 From: AdamN Date: Sat, 1 Aug 2020 23:36:17 +0700 Subject: [PATCH 402/848] Reorganized Networking UI (#13232) --- UI/GameSettingsScreen.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 97d0bd2f2a..41b143e5bd 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -681,29 +681,27 @@ void GameSettingsScreen::CreateViews() { networkingSettingsScroll->Add(networkingSettings); tabHolder->AddTab(ms->T("Networking"), networkingSettingsScroll); - networkingSettings->Add(new ItemHeader(ms->T("Networking"))); + networkingSettings->Add(new ItemHeader(n->T("Networking"))); networkingSettings->Add(new Choice(n->T("Adhoc Multiplayer forum")))->OnClick.Handle(this, &GameSettingsScreen::OnAdhocGuides); networkingSettings->Add(new CheckBox(&g_Config.bEnableWlan, n->T("Enable networking", "Enable networking/wlan (beta)"))); + networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char*)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress); + static const char* wlanChannels[] = { "Auto", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" }; + auto wlanChannelChoice = networkingSettings->Add(new PopupMultiChoice(&g_Config.iWlanAdhocChannel, n->T("WLAN Channel"), wlanChannels, 0, ARRAY_SIZE(wlanChannels), n->GetName(), screenManager())); + for (int i = 0; i < 4; i++) { + wlanChannelChoice->HideChoice(i + 2); + wlanChannelChoice->HideChoice(i + 7); + } networkingSettings->Add(new CheckBox(&g_Config.bDiscordPresence, n->T("Send Discord Presence information"))); - networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.proAdhocServer, n->T("Change proAdhocServer Address (localhost = multiple instance)"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeproAdhocServerAddress); + networkingSettings->Add(new ItemHeader(n->T("AdHoc Server"))); networkingSettings->Add(new CheckBox(&g_Config.bEnableAdhocServer, n->T("Enable built-in PRO Adhoc Server", "Enable built-in PRO Adhoc Server"))); - networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sMACAddress, n->T("Change Mac Address"), (const char *)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeMacAddress); - static const char* wlanChannels[] = { "Auto", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" }; - auto wlanChannelChoice = networkingSettings->Add(new PopupMultiChoice(&g_Config.iWlanAdhocChannel, gr->T("WLAN Channel"), wlanChannels, 0, ARRAY_SIZE(wlanChannels), gr->GetName(), screenManager())); - for (int i = 0; i < 4; i++) { - wlanChannelChoice->HideChoice(i+2); - wlanChannelChoice->HideChoice(i+7); - } - networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset (0 = PSP compatibility)"), 100, screenManager())); - networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 1, 15000, n->T("Minimum Timeout", "Minimum Timeout (override low latency in ms)"), 100, screenManager())); - networkingSettings->Add(new CheckBox(&g_Config.bTCPNoDelay, n->T("TCP No Delay", "TCP No Delay (faster TCP)"))); + networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.proAdhocServer, n->T("Change proAdhocServer Address (localhost = multiple instance)"), (const char*)nullptr))->OnClick.Handle(this, &GameSettingsScreen::OnChangeproAdhocServerAddress); - networkingSettings->Add(new ItemHeader(n->T("UPnP"))); + networkingSettings->Add(new ItemHeader(n->T("UPnP (port-forwarding)"))); networkingSettings->Add(new CheckBox(&g_Config.bEnableUPnP, n->T("Enable UPnP", "Enable UPnP (need a few seconds to detect)"))); - networkingSettings->Add(new CheckBox(&g_Config.bUPnPUseOriginalPort, n->T("UPnP use original port", "UPnP use original port (PSP compatibility)")))->SetEnabledPtr(&g_Config.bEnableUPnP); + networkingSettings->Add(new CheckBox(&g_Config.bUPnPUseOriginalPort, n->T("UPnP use original port", "UPnP use original port (Enabled = PSP compatibility)")))->SetEnabledPtr(&g_Config.bEnableUPnP); networkingSettings->Add(new ItemHeader(n->T("Chat"))); networkingSettings->Add(new CheckBox(&g_Config.bEnableNetworkChat, n->T("Enable network chat", "Enable network chat"))); @@ -758,6 +756,11 @@ void GameSettingsScreen::CreateViews() { qc5->SetEnabledPtr(&g_Config.bEnableQuickChat); #endif + networkingSettings->Add(new ItemHeader(n->T("Misc (default = compatiblity)"))); + networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset (0 = PSP compatibility)"), 100, screenManager())); + networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 1, 15000, n->T("Minimum Timeout", "Minimum Timeout (override low latency in ms)"), 100, screenManager())); + networkingSettings->Add(new CheckBox(&g_Config.bTCPNoDelay, n->T("TCP No Delay", "TCP No Delay (faster TCP)"))); + ViewGroup *toolsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); toolsScroll->SetTag("GameSettingsTools"); LinearLayout *tools = new LinearLayout(ORIENT_VERTICAL); @@ -1698,7 +1701,7 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) { buttonsRow2->Add(new Button(di->T("Toggle List")))->OnClick.Handle(this, &HostnameSelectScreen::OnShowIPListClick); buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, G_RIGHT))); - std::vector listIP = {"localhost","myneighborsushicat.com"}; + std::vector listIP = {"myneighborsushicat.com", "localhost"}; net::GetIPList(listIP); ipRows_ = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0)); ScrollView* scrollView = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); From 0586338d5e8f3fd83af619a0ba07872e42508aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 1 Aug 2020 23:11:48 +0200 Subject: [PATCH 403/848] Add some comments and const-correctness, and a pointer type fix, to the "semaphore" crypto stuff. --- Core/ELF/PrxDecrypter.cpp | 10 +++++----- Core/HLE/sceChnnlsv.cpp | 6 +++--- Core/HLE/sceKernelSemaphore.cpp | 32 +++++++++++++++++++------------- ext/libkirk/amctrl.c | 10 +++++----- ext/libkirk/kirk_engine.c | 28 ++++++++++++++-------------- ext/libkirk/kirk_engine.h | 5 ++--- 6 files changed, 48 insertions(+), 43 deletions(-) diff --git a/Core/ELF/PrxDecrypter.cpp b/Core/ELF/PrxDecrypter.cpp index 5e6f6f5f26..f87fa91fd7 100644 --- a/Core/ELF/PrxDecrypter.cpp +++ b/Core/ELF/PrxDecrypter.cpp @@ -741,7 +741,7 @@ static int pspDecryptType0(const u8 *inbuf, u8 *outbuf, u32 size) memcpy(reinterpret_cast(header)+sizeof(KIRK_CMD1_HEADER), type0.prxHeader, sizeof(type0.prxHeader)); decryptKirkHeaderType0(reinterpret_cast(header), type0.kirkBlock, xorbuf, pti->code); - if (sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) { return -4; } @@ -796,7 +796,7 @@ static int pspDecryptType1(const u8 *inbuf, u8 *outbuf, u32 size) memcpy(reinterpret_cast(header)+sizeof(KIRK_CMD1_HEADER), type1.prxHeader, sizeof(type1.prxHeader)); decryptKirkHeaderType0(reinterpret_cast(header), type1.kirkBlock, xorbuf, pti->code); - if (sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) { return -4; } @@ -860,7 +860,7 @@ static int pspDecryptType2(const u8 *inbuf, u8 *outbuf, u32 size) decryptKirkHeader(reinterpret_cast(header), type2.kirkHeader, xorbuf.cbegin()+0x10, pti->code); header->mode = 1; - if (sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) { return -4; } @@ -924,7 +924,7 @@ static int pspDecryptType5(const u8 *inbuf, u8 *outbuf, u32 size, const u8 *seed decryptKirkHeader(reinterpret_cast(header), type5.kirkHeader, xorbuf.cbegin()+0x10, pti->code); header->mode = 1; - if (sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) { return -4; } @@ -991,7 +991,7 @@ static int pspDecryptType6(const u8 *inbuf, u8 *outbuf, u32 size) header->mode = 1; header->ecdsa_hash = 1; - if (sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) + if (kirk_sceUtilsBufferCopyWithRange(outbuf, size, reinterpret_cast(header), size - offset, KIRK_CMD_DECRYPT_PRIVATE) != 0) { return -4; } diff --git a/Core/HLE/sceChnnlsv.cpp b/Core/HLE/sceChnnlsv.cpp index 5fc9c4c965..475e2ed8d2 100644 --- a/Core/HLE/sceChnnlsv.cpp +++ b/Core/HLE/sceChnnlsv.cpp @@ -99,7 +99,7 @@ static int kirkSendCmd(u8* data, int length, int num, bool encrypt) *(int*)(data+12) = num; *(int*)(data+16) = length; - if (sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_0 : KIRK_CMD_DECRYPT_IV_0)) + if (kirk_sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_0 : KIRK_CMD_DECRYPT_IV_0)) return -257; return 0; @@ -114,7 +114,7 @@ static int kirkSendFuseCmd(u8* data, int length, bool encrypt) *(int*)(data+16) = length; // Note: CMD 5 and 8 are not available, will always return -1 - if (sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_FUSE : KIRK_CMD_DECRYPT_IV_FUSE)) + if (kirk_sceUtilsBufferCopyWithRange(data, length + 20, data, length + 20, encrypt ? KIRK_CMD_ENCRYPT_IV_FUSE : KIRK_CMD_DECRYPT_IV_FUSE)) return -258; return 0; @@ -209,7 +209,7 @@ static int sub_1510(u8* data, int size, u8* result , int num) static int sub_17A8(u8* data) { - if (sceUtilsBufferCopyWithRange(data, 20, 0, 0, 14) == 0) + if (kirk_sceUtilsBufferCopyWithRange(data, 20, 0, 0, 14) == 0) return 0; return -261; } diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 24a65e25fa..fe2f3c6c96 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -458,28 +458,34 @@ int sceKernelPollSema(SceUID id, int wantedCount) } } -static u32 hleUtilsBufferCopyWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) +// The below functions don't really belong to sceKernelSemaphore. They are the core crypto functionality, +// exposed through the confusingly named "sceUtilsBufferCopyWithRange" name, which Sony placed in the +// not-at-all-suspicious "semaphore" library, which has nothing to do with semaphores. + +static u32 sceUtilsBufferCopyWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) { - int temp = sceUtilsBufferCopyWithRange((u8*)outAddr, outSize, (u8*)inAddr, inSize, cmd); - if (temp != 0) { - ERROR_LOG(SCEKERNEL, "hleUtilsBufferCopyWithRange: Failed with %d", temp); - } - return 0; + u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointer(outAddr) : nullptr; + const u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointer(inAddr) : nullptr; + int temp = kirk_sceUtilsBufferCopyWithRange(outAddress, outSize, inAddress, inSize, cmd); + if (temp != 0) { + ERROR_LOG(SCEKERNEL, "hleUtilsBufferCopyWithRange: Failed with %d", temp); + } + return 0; } +// Note sure what difference there is between this and sceUtilsBufferCopyWithRange. static int sceUtilsBufferCopyByPollingWithRange(u32 outAddr, int outSize, u32 inAddr, int inSize, int cmd) { - return sceUtilsBufferCopyWithRange((u8*)outAddr, outSize, (u8*)inAddr, inSize, cmd); + u8 *outAddress = Memory::IsValidRange(outAddr, outSize) ? Memory::GetPointer(outAddr) : nullptr; + const u8 *inAddress = Memory::IsValidRange(inAddr, inSize) ? Memory::GetPointer(inAddr) : nullptr; + return kirk_sceUtilsBufferCopyWithRange(outAddress, outSize, inAddress, inSize, cmd); } const HLEFunction semaphore[] = { - {0x4C537C72, &WrapU_UIUII, "sceUtilsBufferCopyWithRange", 'x', "xixii" }, - {0x77E97079, &WrapI_UIUII, "sceUtilsBufferCopyByPollingWithRange", 'i', "xixii" }, - + {0x4C537C72, &WrapU_UIUII, "sceUtilsBufferCopyWithRange", 'x', "xixii" }, + {0x77E97079, &WrapI_UIUII, "sceUtilsBufferCopyByPollingWithRange", 'i', "xixii" }, }; - - void Register_semaphore() { RegisterModule("semaphore", ARRAY_SIZE(semaphore), semaphore); -} \ No newline at end of file +} diff --git a/ext/libkirk/amctrl.c b/ext/libkirk/amctrl.c index 86fbbf9b36..d144ca792c 100644 --- a/ext/libkirk/amctrl.c +++ b/ext/libkirk/amctrl.c @@ -41,7 +41,7 @@ static int do_kirk4(u8 *buf, int size, int type) header[3] = type; header[4] = size; - retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 4); + retv = kirk_sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 4); if(retv) return 0x80510311; @@ -60,7 +60,7 @@ static int do_kirk7(u8 *buf, int size, int type) header[3] = type; header[4] = size; - retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 7); + retv = kirk_sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 7); if(retv) return 0x80510311; @@ -78,7 +78,7 @@ static int kirk5(u8 *buf, int size) header[3] = 0x0100; header[4] = size; - retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 5); + retv = kirk_sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 5); if(retv) return 0x80510312; @@ -96,7 +96,7 @@ static int kirk8(u8 *buf, int size) header[3] = 0x0100; header[4] = size; - retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 8); + retv = kirk_sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 8); if(retv) return 0x80510312; @@ -107,7 +107,7 @@ static int kirk14(u8 *buf) { int retv; - retv = sceUtilsBufferCopyWithRange(buf, 0x14, 0, 0, 14); + retv = kirk_sceUtilsBufferCopyWithRange(buf, 0x14, 0, 0, 14); if(retv) return 0x80510315; diff --git a/ext/libkirk/kirk_engine.c b/ext/libkirk/kirk_engine.c index 1ff4c267e4..69a300a702 100644 --- a/ext/libkirk/kirk_engine.c +++ b/ext/libkirk/kirk_engine.c @@ -334,7 +334,7 @@ void kirk4(u8* outbuff, const u8* inbuff, size_t size, int keyId) AES_ctx aesKey; u8* key = kirk_4_7_get_key(keyId); AES_set_key(&aesKey, key, 128); - AES_cbc_encrypt(&aesKey, inbuff, outbuff, size); + AES_cbc_encrypt(&aesKey, inbuff, outbuff, (int)size); } int kirk_CMD7(u8* outbuff, u8* inbuff, int size) @@ -362,7 +362,7 @@ void kirk7(u8* outbuff, const u8* inbuff, size_t size, int keyId) AES_ctx aesKey; u8* key = kirk_4_7_get_key(keyId); AES_set_key(&aesKey, key, 128); - AES_cbc_decrypt(&aesKey, inbuff, outbuff, size); + AES_cbc_decrypt(&aesKey, inbuff, outbuff, (int)size); } int kirk_CMD10(u8* inbuff, int insize) @@ -725,21 +725,21 @@ int kirk_CMD1_ex(u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header) return ret; } - -int sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, u8* inbuff, int insize, int cmd) +int kirk_sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, const u8* inbuff, int insize, int cmd) { + // TODO: propagate const-correctness into all these functions. switch(cmd) { - case KIRK_CMD_DECRYPT_PRIVATE: return kirk_CMD1(outbuff, inbuff, insize); break; - case KIRK_CMD_ENCRYPT_IV_0: return kirk_CMD4(outbuff, inbuff, insize); break; - case KIRK_CMD_DECRYPT_IV_0: return kirk_CMD7(outbuff, inbuff, insize); break; - case KIRK_CMD_PRIV_SIGN_CHECK: return kirk_CMD10(inbuff, insize); break; - case KIRK_CMD_SHA1_HASH: return kirk_CMD11(outbuff, inbuff, insize); break; - case KIRK_CMD_ECDSA_GEN_KEYS: return kirk_CMD12(outbuff,outsize); break; - case KIRK_CMD_ECDSA_MULTIPLY_POINT: return kirk_CMD13(outbuff,outsize, inbuff, insize); break; - case KIRK_CMD_PRNG: return kirk_CMD14(outbuff,outsize); break; - case KIRK_CMD_ECDSA_SIGN: return kirk_CMD16(outbuff, outsize, inbuff, insize); break; - case KIRK_CMD_ECDSA_VERIFY: return kirk_CMD17(inbuff, insize); break; + case KIRK_CMD_DECRYPT_PRIVATE: return kirk_CMD1(outbuff, (u8 *)inbuff, insize); break; + case KIRK_CMD_ENCRYPT_IV_0: return kirk_CMD4(outbuff, (u8 *)inbuff, insize); break; + case KIRK_CMD_DECRYPT_IV_0: return kirk_CMD7(outbuff, (u8 *)inbuff, insize); break; + case KIRK_CMD_PRIV_SIGN_CHECK: return kirk_CMD10((u8 *)inbuff, insize); break; + case KIRK_CMD_SHA1_HASH: return kirk_CMD11(outbuff, (u8 *)inbuff, insize); break; + case KIRK_CMD_ECDSA_GEN_KEYS: return kirk_CMD12(outbuff, outsize); break; + case KIRK_CMD_ECDSA_MULTIPLY_POINT: return kirk_CMD13(outbuff, outsize, (u8 *)inbuff, insize); break; + case KIRK_CMD_PRNG: return kirk_CMD14(outbuff, outsize); break; + case KIRK_CMD_ECDSA_SIGN: return kirk_CMD16(outbuff, outsize, (u8 *)inbuff, insize); break; + case KIRK_CMD_ECDSA_VERIFY: return kirk_CMD17((u8 *)inbuff, insize); break; } return -1; } diff --git a/ext/libkirk/kirk_engine.h b/ext/libkirk/kirk_engine.h index c91795277c..5c7be012b7 100644 --- a/ext/libkirk/kirk_engine.h +++ b/ext/libkirk/kirk_engine.h @@ -218,9 +218,8 @@ u8* kirk_4_7_get_key(int key_type); //kirk "ex" functions int kirk_CMD1_ex(u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header); -//sce-like funcs -int sceUtilsSetFuseID(u8*fuse); -int sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, u8* inbuff, int insize, int cmd); +//sce-like func. sceUtilsBufferCopyWithRange is clearly intentionally confusingly named. +int kirk_sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, const u8* inbuff, int insize, int cmd); void decrypt_kirk16_private(u8 *dA_out, u8 *dA_enc); void encrypt_kirk16_private(u8 *dA_out, u8 *dA_dec); From ce31d3e375bb0ce4fae9a428a8c113ab320b776f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 1 Aug 2020 23:37:15 +0200 Subject: [PATCH 404/848] Update Vulkan headers to the latest, just to keep up. --- ext/native/thin3d/thin3d_vulkan.cpp | 5 - ext/vulkan/vk_platform.h | 2 +- ext/vulkan/vulkan.h | 7 +- ext/vulkan/vulkan_android.h | 2 +- ext/vulkan/vulkan_beta.h | 438 ++++ ext/vulkan/vulkan_core.h | 2998 ++++++++++++++++++--------- ext/vulkan/vulkan_fuchsia.h | 2 +- ext/vulkan/vulkan_ggp.h | 2 +- ext/vulkan/vulkan_ios.h | 2 +- ext/vulkan/vulkan_macos.h | 2 +- ext/vulkan/vulkan_metal.h | 2 +- ext/vulkan/vulkan_vi.h | 2 +- ext/vulkan/vulkan_wayland.h | 2 +- ext/vulkan/vulkan_win32.h | 5 +- ext/vulkan/vulkan_xcb.h | 2 +- ext/vulkan/vulkan_xlib.h | 2 +- ext/vulkan/vulkan_xlib_xrandr.h | 2 +- 17 files changed, 2425 insertions(+), 1052 deletions(-) create mode 100644 ext/vulkan/vulkan_beta.h diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index ea04100813..a0b3a5f1d4 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1409,11 +1409,6 @@ std::vector VKContext::GetFeatureList() const { features.push_back(std::string("Preferred depth buffer format: ") + VulkanFormatToString(vulkan_->GetDeviceInfo().preferredDepthStencilFormat)); - // Also list texture formats and their properties. - for (int i = VK_FORMAT_BEGIN_RANGE; i <= VK_FORMAT_END_RANGE; i++) { - // TODO - } - return features; } diff --git a/ext/vulkan/vk_platform.h b/ext/vulkan/vk_platform.h index 7289299240..dbb011285c 100644 --- a/ext/vulkan/vk_platform.h +++ b/ext/vulkan/vk_platform.h @@ -2,7 +2,7 @@ // File: vk_platform.h // /* -** Copyright (c) 2014-2017 The Khronos Group Inc. +** Copyright (c) 2014-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan.h b/ext/vulkan/vulkan.h index 5f853f9fc8..20ecd1016e 100644 --- a/ext/vulkan/vulkan.h +++ b/ext/vulkan/vulkan.h @@ -2,7 +2,7 @@ #define VULKAN_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -83,4 +83,9 @@ #include "vulkan_ggp.h" #endif + +#ifdef VK_ENABLE_BETA_EXTENSIONS +#include "vulkan_beta.h" +#endif + #endif // VULKAN_H_ diff --git a/ext/vulkan/vulkan_android.h b/ext/vulkan/vulkan_android.h index 9b8d3e276f..4f27750cd8 100644 --- a/ext/vulkan/vulkan_android.h +++ b/ext/vulkan/vulkan_android.h @@ -2,7 +2,7 @@ #define VULKAN_ANDROID_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_beta.h b/ext/vulkan/vulkan_beta.h new file mode 100644 index 0000000000..7380e39fe1 --- /dev/null +++ b/ext/vulkan/vulkan_beta.h @@ -0,0 +1,438 @@ +#ifndef VULKAN_BETA_H_ +#define VULKAN_BETA_H_ 1 + +/* +** Copyright (c) 2015-2020 The Khronos Group Inc. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define VK_KHR_deferred_host_operations 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeferredOperationKHR) +#define VK_KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION 2 +#define VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME "VK_KHR_deferred_host_operations" +typedef struct VkDeferredOperationInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeferredOperationKHR operationHandle; +} VkDeferredOperationInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDeferredOperationKHR)(VkDevice device, const VkAllocationCallbacks* pAllocator, VkDeferredOperationKHR* pDeferredOperation); +typedef void (VKAPI_PTR *PFN_vkDestroyDeferredOperationKHR)(VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks* pAllocator); +typedef uint32_t (VKAPI_PTR *PFN_vkGetDeferredOperationMaxConcurrencyKHR)(VkDevice device, VkDeferredOperationKHR operation); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeferredOperationResultKHR)(VkDevice device, VkDeferredOperationKHR operation); +typedef VkResult (VKAPI_PTR *PFN_vkDeferredOperationJoinKHR)(VkDevice device, VkDeferredOperationKHR operation); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDeferredOperationKHR( + VkDevice device, + const VkAllocationCallbacks* pAllocator, + VkDeferredOperationKHR* pDeferredOperation); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDeferredOperationKHR( + VkDevice device, + VkDeferredOperationKHR operation, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR uint32_t VKAPI_CALL vkGetDeferredOperationMaxConcurrencyKHR( + VkDevice device, + VkDeferredOperationKHR operation); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeferredOperationResultKHR( + VkDevice device, + VkDeferredOperationKHR operation); + +VKAPI_ATTR VkResult VKAPI_CALL vkDeferredOperationJoinKHR( + VkDevice device, + VkDeferredOperationKHR operation); +#endif + + +#define VK_KHR_pipeline_library 1 +#define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1 +#define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library" +typedef struct VkPipelineLibraryCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t libraryCount; + const VkPipeline* pLibraries; +} VkPipelineLibraryCreateInfoKHR; + + + +#define VK_KHR_ray_tracing 1 +#define VK_KHR_RAY_TRACING_SPEC_VERSION 8 +#define VK_KHR_RAY_TRACING_EXTENSION_NAME "VK_KHR_ray_tracing" + +typedef enum VkAccelerationStructureBuildTypeKHR { + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR = 0, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR = 1, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR = 2, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureBuildTypeKHR; +typedef union VkDeviceOrHostAddressKHR { + VkDeviceAddress deviceAddress; + void* hostAddress; +} VkDeviceOrHostAddressKHR; + +typedef union VkDeviceOrHostAddressConstKHR { + VkDeviceAddress deviceAddress; + const void* hostAddress; +} VkDeviceOrHostAddressConstKHR; + +typedef struct VkAccelerationStructureBuildOffsetInfoKHR { + uint32_t primitiveCount; + uint32_t primitiveOffset; + uint32_t firstVertex; + uint32_t transformOffset; +} VkAccelerationStructureBuildOffsetInfoKHR; + +typedef struct VkRayTracingShaderGroupCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkRayTracingShaderGroupTypeKHR type; + uint32_t generalShader; + uint32_t closestHitShader; + uint32_t anyHitShader; + uint32_t intersectionShader; + const void* pShaderGroupCaptureReplayHandle; +} VkRayTracingShaderGroupCreateInfoKHR; + +typedef struct VkRayTracingPipelineInterfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t maxPayloadSize; + uint32_t maxAttributeSize; + uint32_t maxCallableSize; +} VkRayTracingPipelineInterfaceCreateInfoKHR; + +typedef struct VkRayTracingPipelineCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + uint32_t groupCount; + const VkRayTracingShaderGroupCreateInfoKHR* pGroups; + uint32_t maxRecursionDepth; + VkPipelineLibraryCreateInfoKHR libraries; + const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkRayTracingPipelineCreateInfoKHR; + +typedef struct VkAccelerationStructureGeometryTrianglesDataKHR { + VkStructureType sType; + const void* pNext; + VkFormat vertexFormat; + VkDeviceOrHostAddressConstKHR vertexData; + VkDeviceSize vertexStride; + VkIndexType indexType; + VkDeviceOrHostAddressConstKHR indexData; + VkDeviceOrHostAddressConstKHR transformData; +} VkAccelerationStructureGeometryTrianglesDataKHR; + +typedef struct VkAccelerationStructureGeometryAabbsDataKHR { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR data; + VkDeviceSize stride; +} VkAccelerationStructureGeometryAabbsDataKHR; + +typedef struct VkAccelerationStructureGeometryInstancesDataKHR { + VkStructureType sType; + const void* pNext; + VkBool32 arrayOfPointers; + VkDeviceOrHostAddressConstKHR data; +} VkAccelerationStructureGeometryInstancesDataKHR; + +typedef union VkAccelerationStructureGeometryDataKHR { + VkAccelerationStructureGeometryTrianglesDataKHR triangles; + VkAccelerationStructureGeometryAabbsDataKHR aabbs; + VkAccelerationStructureGeometryInstancesDataKHR instances; +} VkAccelerationStructureGeometryDataKHR; + +typedef struct VkAccelerationStructureGeometryKHR { + VkStructureType sType; + const void* pNext; + VkGeometryTypeKHR geometryType; + VkAccelerationStructureGeometryDataKHR geometry; + VkGeometryFlagsKHR flags; +} VkAccelerationStructureGeometryKHR; + +typedef struct VkAccelerationStructureBuildGeometryInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureTypeKHR type; + VkBuildAccelerationStructureFlagsKHR flags; + VkBool32 update; + VkAccelerationStructureKHR srcAccelerationStructure; + VkAccelerationStructureKHR dstAccelerationStructure; + VkBool32 geometryArrayOfPointers; + uint32_t geometryCount; + const VkAccelerationStructureGeometryKHR* const* ppGeometries; + VkDeviceOrHostAddressKHR scratchData; +} VkAccelerationStructureBuildGeometryInfoKHR; + +typedef struct VkAccelerationStructureCreateGeometryTypeInfoKHR { + VkStructureType sType; + const void* pNext; + VkGeometryTypeKHR geometryType; + uint32_t maxPrimitiveCount; + VkIndexType indexType; + uint32_t maxVertexCount; + VkFormat vertexFormat; + VkBool32 allowsTransforms; +} VkAccelerationStructureCreateGeometryTypeInfoKHR; + +typedef struct VkAccelerationStructureCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceSize compactedSize; + VkAccelerationStructureTypeKHR type; + VkBuildAccelerationStructureFlagsKHR flags; + uint32_t maxGeometryCount; + const VkAccelerationStructureCreateGeometryTypeInfoKHR* pGeometryInfos; + VkDeviceAddress deviceAddress; +} VkAccelerationStructureCreateInfoKHR; + +typedef struct VkAccelerationStructureMemoryRequirementsInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureMemoryRequirementsTypeKHR type; + VkAccelerationStructureBuildTypeKHR buildType; + VkAccelerationStructureKHR accelerationStructure; +} VkAccelerationStructureMemoryRequirementsInfoKHR; + +typedef struct VkPhysicalDeviceRayTracingFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rayTracing; + VkBool32 rayTracingShaderGroupHandleCaptureReplay; + VkBool32 rayTracingShaderGroupHandleCaptureReplayMixed; + VkBool32 rayTracingAccelerationStructureCaptureReplay; + VkBool32 rayTracingIndirectTraceRays; + VkBool32 rayTracingIndirectAccelerationStructureBuild; + VkBool32 rayTracingHostAccelerationStructureCommands; + VkBool32 rayQuery; + VkBool32 rayTracingPrimitiveCulling; +} VkPhysicalDeviceRayTracingFeaturesKHR; + +typedef struct VkPhysicalDeviceRayTracingPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t shaderGroupHandleSize; + uint32_t maxRecursionDepth; + uint32_t maxShaderGroupStride; + uint32_t shaderGroupBaseAlignment; + uint64_t maxGeometryCount; + uint64_t maxInstanceCount; + uint64_t maxPrimitiveCount; + uint32_t maxDescriptorSetAccelerationStructures; + uint32_t shaderGroupHandleCaptureReplaySize; +} VkPhysicalDeviceRayTracingPropertiesKHR; + +typedef struct VkAccelerationStructureDeviceAddressInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR accelerationStructure; +} VkAccelerationStructureDeviceAddressInfoKHR; + +typedef struct VkAccelerationStructureVersionKHR { + VkStructureType sType; + const void* pNext; + const uint8_t* versionData; +} VkAccelerationStructureVersionKHR; + +typedef struct VkStridedBufferRegionKHR { + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize stride; + VkDeviceSize size; +} VkStridedBufferRegionKHR; + +typedef struct VkTraceRaysIndirectCommandKHR { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkTraceRaysIndirectCommandKHR; + +typedef struct VkCopyAccelerationStructureToMemoryInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR src; + VkDeviceOrHostAddressKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyAccelerationStructureToMemoryInfoKHR; + +typedef struct VkCopyMemoryToAccelerationStructureInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR src; + VkAccelerationStructureKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyMemoryToAccelerationStructureInfoKHR; + +typedef struct VkCopyAccelerationStructureInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR src; + VkAccelerationStructureKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyAccelerationStructureInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureKHR)(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure); +typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsKHR)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoKHR* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildOffsetInfoKHR* const* ppOffsetInfos); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureIndirectKHR)(VkCommandBuffer commandBuffer, const VkAccelerationStructureBuildGeometryInfoKHR* pInfo, VkBuffer indirectBuffer, VkDeviceSize indirectOffset, uint32_t indirectStride); +typedef VkResult (VKAPI_PTR *PFN_vkBuildAccelerationStructureKHR)(VkDevice device, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildOffsetInfoKHR* const* ppOffsetInfos); +typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureKHR)(VkDevice device, const VkCopyAccelerationStructureInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureToMemoryKHR)(VkDevice device, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToAccelerationStructureKHR)(VkDevice device, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkWriteAccelerationStructuresPropertiesKHR)(VkDevice device, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, size_t dataSize, void* pData, size_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureToMemoryKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysKHR)(VkCommandBuffer commandBuffer, const VkStridedBufferRegionKHR* pRaygenShaderBindingTable, const VkStridedBufferRegionKHR* pMissShaderBindingTable, const VkStridedBufferRegionKHR* pHitShaderBindingTable, const VkStridedBufferRegionKHR* pCallableShaderBindingTable, uint32_t width, uint32_t height, uint32_t depth); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesKHR)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetAccelerationStructureDeviceAddressKHR)(VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirectKHR)(VkCommandBuffer commandBuffer, const VkStridedBufferRegionKHR* pRaygenShaderBindingTable, const VkStridedBufferRegionKHR* pMissShaderBindingTable, const VkStridedBufferRegionKHR* pHitShaderBindingTable, const VkStridedBufferRegionKHR* pCallableShaderBindingTable, VkBuffer buffer, VkDeviceSize offset); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)(VkDevice device, const VkAccelerationStructureVersionKHR* version); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureKHR( + VkDevice device, + const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureKHR* pAccelerationStructure); + +VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsKHR( + VkDevice device, + const VkAccelerationStructureMemoryRequirementsInfoKHR* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildOffsetInfoKHR* const* ppOffsetInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureIndirectKHR( + VkCommandBuffer commandBuffer, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfo, + VkBuffer indirectBuffer, + VkDeviceSize indirectOffset, + uint32_t indirectStride); + +VKAPI_ATTR VkResult VKAPI_CALL vkBuildAccelerationStructureKHR( + VkDevice device, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildOffsetInfoKHR* const* ppOffsetInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureKHR( + VkDevice device, + const VkCopyAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureToMemoryKHR( + VkDevice device, + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToAccelerationStructureKHR( + VkDevice device, + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkWriteAccelerationStructuresPropertiesKHR( + VkDevice device, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + size_t dataSize, + void* pData, + size_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + const VkCopyAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureToMemoryKHR( + VkCommandBuffer commandBuffer, + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysKHR( + VkCommandBuffer commandBuffer, + const VkStridedBufferRegionKHR* pRaygenShaderBindingTable, + const VkStridedBufferRegionKHR* pMissShaderBindingTable, + const VkStridedBufferRegionKHR* pHitShaderBindingTable, + const VkStridedBufferRegionKHR* pCallableShaderBindingTable, + uint32_t width, + uint32_t height, + uint32_t depth); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesKHR( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetAccelerationStructureDeviceAddressKHR( + VkDevice device, + const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( + VkDevice device, + VkPipeline pipeline, + uint32_t firstGroup, + uint32_t groupCount, + size_t dataSize, + void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirectKHR( + VkCommandBuffer commandBuffer, + const VkStridedBufferRegionKHR* pRaygenShaderBindingTable, + const VkStridedBufferRegionKHR* pMissShaderBindingTable, + const VkStridedBufferRegionKHR* pHitShaderBindingTable, + const VkStridedBufferRegionKHR* pCallableShaderBindingTable, + VkBuffer buffer, + VkDeviceSize offset); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceAccelerationStructureCompatibilityKHR( + VkDevice device, + const VkAccelerationStructureVersionKHR* version); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ext/vulkan/vulkan_core.h b/ext/vulkan/vulkan_core.h index 01da6ede32..db2e5561ba 100644 --- a/ext/vulkan/vulkan_core.h +++ b/ext/vulkan/vulkan_core.h @@ -2,7 +2,7 @@ #define VULKAN_CORE_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -44,7 +44,10 @@ extern "C" { #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) // Version of this file -#define VK_HEADER_VERSION 123 +#define VK_HEADER_VERSION 141 + +// Complete version of this file +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION) #define VK_NULL_HANDLE 0 @@ -108,9 +111,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) typedef enum VkPipelineCacheHeaderVersion { VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, - VK_PIPELINE_CACHE_HEADER_VERSION_BEGIN_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, - VK_PIPELINE_CACHE_HEADER_VERSION_END_RANGE = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, - VK_PIPELINE_CACHE_HEADER_VERSION_RANGE_SIZE = (VK_PIPELINE_CACHE_HEADER_VERSION_ONE - VK_PIPELINE_CACHE_HEADER_VERSION_ONE + 1), VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF } VkPipelineCacheHeaderVersion; @@ -133,8 +133,11 @@ typedef enum VkResult { VK_ERROR_TOO_MANY_OBJECTS = -10, VK_ERROR_FORMAT_NOT_SUPPORTED = -11, VK_ERROR_FRAGMENTED_POOL = -12, + VK_ERROR_UNKNOWN = -13, VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, + VK_ERROR_FRAGMENTATION = -1000161000, + VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, VK_ERROR_SURFACE_LOST_KHR = -1000000000, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, VK_SUBOPTIMAL_KHR = 1000001003, @@ -142,16 +145,21 @@ typedef enum VkResult { VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, VK_ERROR_INVALID_SHADER_NV = -1000012000, + VK_ERROR_INCOMPATIBLE_VERSION_KHR = -1000150000, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - VK_ERROR_FRAGMENTATION_EXT = -1000161000, VK_ERROR_NOT_PERMITTED_EXT = -1000174001, - VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = -1000244000, VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, + VK_THREAD_IDLE_KHR = 1000268000, + VK_THREAD_DONE_KHR = 1000268001, + VK_OPERATION_DEFERRED_KHR = 1000268002, + VK_OPERATION_NOT_DEFERRED_KHR = 1000268003, + VK_PIPELINE_COMPILE_REQUIRED_EXT = 1000297000, VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, - VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL, - VK_RESULT_END_RANGE = VK_INCOMPLETE, - VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1), + VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, + VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED_EXT, VK_RESULT_MAX_ENUM = 0x7FFFFFFF } VkResult; @@ -270,6 +278,56 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, + VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002, + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, + VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004, + VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001, + VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, + VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, @@ -298,6 +356,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, @@ -329,14 +388,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = 1000082000, VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, - VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000, - VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001, - VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX = 1000086002, - VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003, - VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004, - VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005, VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000, VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000, @@ -353,23 +405,19 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = 1000108000, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = 1000108001, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = 1000108002, - VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = 1000108003, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002, - VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = 1000109003, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = 1000109004, - VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = 1000109005, - VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = 1000109006, VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000, VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001, + VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002, + VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003, + VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004, + VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR = 1000116005, + VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001, VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002, @@ -391,8 +439,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000, - VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, @@ -402,11 +448,30 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = 1000147000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, + VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR = 1000165006, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000165007, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR = 1000150001, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR = 1000150008, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_KHR = 1000150009, + VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010, + VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011, + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR = 1000150013, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_KHR = 1000150014, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015, + VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018, VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001, @@ -418,11 +483,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004, VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, @@ -432,8 +492,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003, VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004, VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005, - VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, @@ -443,12 +501,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = 1000175000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = 1000180000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000, VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000, VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, @@ -458,10 +514,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000, VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = 1000196000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = 1000197000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = 1000199000, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = 1000199001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, @@ -472,13 +524,12 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000, VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, - VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = 1000210000, + VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, VK_STRUCTURE_TYPE_PERFORMANCE_MARKER_INFO_INTEL = 1000210002, VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003, VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004, VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, @@ -487,7 +538,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000, VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002, @@ -499,9 +549,8 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, - VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = 1000244001, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, - VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000, VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, @@ -511,7 +560,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = 1000253000, VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002, VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001, @@ -519,8 +567,8 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000, VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = 1000261000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000, + VK_STRUCTURE_TYPE_DEFERRED_OPERATION_INFO_KHR = 1000268000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000, VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002, @@ -528,8 +576,30 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, + VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV = 1000277005, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, + VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, + VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, + VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, + VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, @@ -565,10 +635,22 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, @@ -576,15 +658,18 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO, VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, @@ -593,12 +678,44 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, + VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, + VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, + VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, - VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, - VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, - VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, + VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; @@ -608,17 +725,11 @@ typedef enum VkSystemAllocationScope { VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, - VK_SYSTEM_ALLOCATION_SCOPE_BEGIN_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_COMMAND, - VK_SYSTEM_ALLOCATION_SCOPE_END_RANGE = VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE, - VK_SYSTEM_ALLOCATION_SCOPE_RANGE_SIZE = (VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND + 1), VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF } VkSystemAllocationScope; typedef enum VkInternalAllocationType { VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, - VK_INTERNAL_ALLOCATION_TYPE_BEGIN_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, - VK_INTERNAL_ALLOCATION_TYPE_END_RANGE = VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE, - VK_INTERNAL_ALLOCATION_TYPE_RANGE_SIZE = (VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE + 1), VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF } VkInternalAllocationType; @@ -898,9 +1009,6 @@ typedef enum VkFormat { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, - VK_FORMAT_BEGIN_RANGE = VK_FORMAT_UNDEFINED, - VK_FORMAT_END_RANGE = VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - VK_FORMAT_RANGE_SIZE = (VK_FORMAT_ASTC_12x12_SRGB_BLOCK - VK_FORMAT_UNDEFINED + 1), VK_FORMAT_MAX_ENUM = 0x7FFFFFFF } VkFormat; @@ -908,9 +1016,6 @@ typedef enum VkImageType { VK_IMAGE_TYPE_1D = 0, VK_IMAGE_TYPE_2D = 1, VK_IMAGE_TYPE_3D = 2, - VK_IMAGE_TYPE_BEGIN_RANGE = VK_IMAGE_TYPE_1D, - VK_IMAGE_TYPE_END_RANGE = VK_IMAGE_TYPE_3D, - VK_IMAGE_TYPE_RANGE_SIZE = (VK_IMAGE_TYPE_3D - VK_IMAGE_TYPE_1D + 1), VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkImageType; @@ -918,9 +1023,6 @@ typedef enum VkImageTiling { VK_IMAGE_TILING_OPTIMAL = 0, VK_IMAGE_TILING_LINEAR = 1, VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT = 1000158000, - VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_LINEAR, - VK_IMAGE_TILING_RANGE_SIZE = (VK_IMAGE_TILING_LINEAR - VK_IMAGE_TILING_OPTIMAL + 1), VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF } VkImageTiling; @@ -930,9 +1032,6 @@ typedef enum VkPhysicalDeviceType { VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, VK_PHYSICAL_DEVICE_TYPE_CPU = 4, - VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = VK_PHYSICAL_DEVICE_TYPE_OTHER, - VK_PHYSICAL_DEVICE_TYPE_END_RANGE = VK_PHYSICAL_DEVICE_TYPE_CPU, - VK_PHYSICAL_DEVICE_TYPE_RANGE_SIZE = (VK_PHYSICAL_DEVICE_TYPE_CPU - VK_PHYSICAL_DEVICE_TYPE_OTHER + 1), VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkPhysicalDeviceType; @@ -941,20 +1040,17 @@ typedef enum VkQueryType { VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, VK_QUERY_TYPE_TIMESTAMP = 2, VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004, - VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, + VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR = 1000116000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR = 1000165000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR = 1000150000, VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL = 1000210000, - VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION, - VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_TIMESTAMP, - VK_QUERY_TYPE_RANGE_SIZE = (VK_QUERY_TYPE_TIMESTAMP - VK_QUERY_TYPE_OCCLUSION + 1), + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF } VkQueryType; typedef enum VkSharingMode { VK_SHARING_MODE_EXCLUSIVE = 0, VK_SHARING_MODE_CONCURRENT = 1, - VK_SHARING_MODE_BEGIN_RANGE = VK_SHARING_MODE_EXCLUSIVE, - VK_SHARING_MODE_END_RANGE = VK_SHARING_MODE_CONCURRENT, - VK_SHARING_MODE_RANGE_SIZE = (VK_SHARING_MODE_CONCURRENT - VK_SHARING_MODE_EXCLUSIVE + 1), VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF } VkSharingMode; @@ -970,15 +1066,20 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_PREINITIALIZED = 8, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = 1000164003, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED, - VK_IMAGE_LAYOUT_RANGE_SIZE = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1), + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF } VkImageLayout; @@ -990,9 +1091,6 @@ typedef enum VkImageViewType { VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, - VK_IMAGE_VIEW_TYPE_BEGIN_RANGE = VK_IMAGE_VIEW_TYPE_1D, - VK_IMAGE_VIEW_TYPE_END_RANGE = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, - VK_IMAGE_VIEW_TYPE_RANGE_SIZE = (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1), VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF } VkImageViewType; @@ -1004,18 +1102,12 @@ typedef enum VkComponentSwizzle { VK_COMPONENT_SWIZZLE_G = 4, VK_COMPONENT_SWIZZLE_B = 5, VK_COMPONENT_SWIZZLE_A = 6, - VK_COMPONENT_SWIZZLE_BEGIN_RANGE = VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_END_RANGE = VK_COMPONENT_SWIZZLE_A, - VK_COMPONENT_SWIZZLE_RANGE_SIZE = (VK_COMPONENT_SWIZZLE_A - VK_COMPONENT_SWIZZLE_IDENTITY + 1), VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF } VkComponentSwizzle; typedef enum VkVertexInputRate { VK_VERTEX_INPUT_RATE_VERTEX = 0, VK_VERTEX_INPUT_RATE_INSTANCE = 1, - VK_VERTEX_INPUT_RATE_BEGIN_RANGE = VK_VERTEX_INPUT_RATE_VERTEX, - VK_VERTEX_INPUT_RATE_END_RANGE = VK_VERTEX_INPUT_RATE_INSTANCE, - VK_VERTEX_INPUT_RATE_RANGE_SIZE = (VK_VERTEX_INPUT_RATE_INSTANCE - VK_VERTEX_INPUT_RATE_VERTEX + 1), VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF } VkVertexInputRate; @@ -1031,9 +1123,6 @@ typedef enum VkPrimitiveTopology { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, - VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - VK_PRIMITIVE_TOPOLOGY_END_RANGE = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, - VK_PRIMITIVE_TOPOLOGY_RANGE_SIZE = (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST - VK_PRIMITIVE_TOPOLOGY_POINT_LIST + 1), VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF } VkPrimitiveTopology; @@ -1042,18 +1131,12 @@ typedef enum VkPolygonMode { VK_POLYGON_MODE_LINE = 1, VK_POLYGON_MODE_POINT = 2, VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, - VK_POLYGON_MODE_BEGIN_RANGE = VK_POLYGON_MODE_FILL, - VK_POLYGON_MODE_END_RANGE = VK_POLYGON_MODE_POINT, - VK_POLYGON_MODE_RANGE_SIZE = (VK_POLYGON_MODE_POINT - VK_POLYGON_MODE_FILL + 1), VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF } VkPolygonMode; typedef enum VkFrontFace { VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, VK_FRONT_FACE_CLOCKWISE = 1, - VK_FRONT_FACE_BEGIN_RANGE = VK_FRONT_FACE_COUNTER_CLOCKWISE, - VK_FRONT_FACE_END_RANGE = VK_FRONT_FACE_CLOCKWISE, - VK_FRONT_FACE_RANGE_SIZE = (VK_FRONT_FACE_CLOCKWISE - VK_FRONT_FACE_COUNTER_CLOCKWISE + 1), VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF } VkFrontFace; @@ -1066,9 +1149,6 @@ typedef enum VkCompareOp { VK_COMPARE_OP_NOT_EQUAL = 5, VK_COMPARE_OP_GREATER_OR_EQUAL = 6, VK_COMPARE_OP_ALWAYS = 7, - VK_COMPARE_OP_BEGIN_RANGE = VK_COMPARE_OP_NEVER, - VK_COMPARE_OP_END_RANGE = VK_COMPARE_OP_ALWAYS, - VK_COMPARE_OP_RANGE_SIZE = (VK_COMPARE_OP_ALWAYS - VK_COMPARE_OP_NEVER + 1), VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF } VkCompareOp; @@ -1081,9 +1161,6 @@ typedef enum VkStencilOp { VK_STENCIL_OP_INVERT = 5, VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, - VK_STENCIL_OP_BEGIN_RANGE = VK_STENCIL_OP_KEEP, - VK_STENCIL_OP_END_RANGE = VK_STENCIL_OP_DECREMENT_AND_WRAP, - VK_STENCIL_OP_RANGE_SIZE = (VK_STENCIL_OP_DECREMENT_AND_WRAP - VK_STENCIL_OP_KEEP + 1), VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF } VkStencilOp; @@ -1104,9 +1181,6 @@ typedef enum VkLogicOp { VK_LOGIC_OP_OR_INVERTED = 13, VK_LOGIC_OP_NAND = 14, VK_LOGIC_OP_SET = 15, - VK_LOGIC_OP_BEGIN_RANGE = VK_LOGIC_OP_CLEAR, - VK_LOGIC_OP_END_RANGE = VK_LOGIC_OP_SET, - VK_LOGIC_OP_RANGE_SIZE = (VK_LOGIC_OP_SET - VK_LOGIC_OP_CLEAR + 1), VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF } VkLogicOp; @@ -1130,9 +1204,6 @@ typedef enum VkBlendFactor { VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, VK_BLEND_FACTOR_SRC1_ALPHA = 17, VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, - VK_BLEND_FACTOR_BEGIN_RANGE = VK_BLEND_FACTOR_ZERO, - VK_BLEND_FACTOR_END_RANGE = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, - VK_BLEND_FACTOR_RANGE_SIZE = (VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA - VK_BLEND_FACTOR_ZERO + 1), VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF } VkBlendFactor; @@ -1188,9 +1259,6 @@ typedef enum VkBlendOp { VK_BLEND_OP_RED_EXT = 1000148043, VK_BLEND_OP_GREEN_EXT = 1000148044, VK_BLEND_OP_BLUE_EXT = 1000148045, - VK_BLEND_OP_BEGIN_RANGE = VK_BLEND_OP_ADD, - VK_BLEND_OP_END_RANGE = VK_BLEND_OP_MAX, - VK_BLEND_OP_RANGE_SIZE = (VK_BLEND_OP_MAX - VK_BLEND_OP_ADD + 1), VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF } VkBlendOp; @@ -1211,9 +1279,6 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006, VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000, - VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_RANGE_SIZE = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1), VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF } VkDynamicState; @@ -1222,18 +1287,12 @@ typedef enum VkFilter { VK_FILTER_LINEAR = 1, VK_FILTER_CUBIC_IMG = 1000015000, VK_FILTER_CUBIC_EXT = VK_FILTER_CUBIC_IMG, - VK_FILTER_BEGIN_RANGE = VK_FILTER_NEAREST, - VK_FILTER_END_RANGE = VK_FILTER_LINEAR, - VK_FILTER_RANGE_SIZE = (VK_FILTER_LINEAR - VK_FILTER_NEAREST + 1), VK_FILTER_MAX_ENUM = 0x7FFFFFFF } VkFilter; typedef enum VkSamplerMipmapMode { VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, - VK_SAMPLER_MIPMAP_MODE_BEGIN_RANGE = VK_SAMPLER_MIPMAP_MODE_NEAREST, - VK_SAMPLER_MIPMAP_MODE_END_RANGE = VK_SAMPLER_MIPMAP_MODE_LINEAR, - VK_SAMPLER_MIPMAP_MODE_RANGE_SIZE = (VK_SAMPLER_MIPMAP_MODE_LINEAR - VK_SAMPLER_MIPMAP_MODE_NEAREST + 1), VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF } VkSamplerMipmapMode; @@ -1244,9 +1303,6 @@ typedef enum VkSamplerAddressMode { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, - VK_SAMPLER_ADDRESS_MODE_BEGIN_RANGE = VK_SAMPLER_ADDRESS_MODE_REPEAT, - VK_SAMPLER_ADDRESS_MODE_END_RANGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - VK_SAMPLER_ADDRESS_MODE_RANGE_SIZE = (VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER - VK_SAMPLER_ADDRESS_MODE_REPEAT + 1), VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF } VkSamplerAddressMode; @@ -1257,9 +1313,8 @@ typedef enum VkBorderColor { VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, - VK_BORDER_COLOR_BEGIN_RANGE = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - VK_BORDER_COLOR_END_RANGE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, - VK_BORDER_COLOR_RANGE_SIZE = (VK_BORDER_COLOR_INT_OPAQUE_WHITE - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1), + VK_BORDER_COLOR_FLOAT_CUSTOM_EXT = 1000287003, + VK_BORDER_COLOR_INT_CUSTOM_EXT = 1000287004, VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF } VkBorderColor; @@ -1276,10 +1331,8 @@ typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, - VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, - VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER, - VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - VK_DESCRIPTOR_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1), + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000165000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorType; @@ -1287,57 +1340,42 @@ typedef enum VkAttachmentLoadOp { VK_ATTACHMENT_LOAD_OP_LOAD = 0, VK_ATTACHMENT_LOAD_OP_CLEAR = 1, VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, - VK_ATTACHMENT_LOAD_OP_BEGIN_RANGE = VK_ATTACHMENT_LOAD_OP_LOAD, - VK_ATTACHMENT_LOAD_OP_END_RANGE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_LOAD_OP_RANGE_SIZE = (VK_ATTACHMENT_LOAD_OP_DONT_CARE - VK_ATTACHMENT_LOAD_OP_LOAD + 1), VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentLoadOp; typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_STORE = 0, VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, - VK_ATTACHMENT_STORE_OP_BEGIN_RANGE = VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_STORE_OP_END_RANGE = VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_RANGE_SIZE = (VK_ATTACHMENT_STORE_OP_DONT_CARE - VK_ATTACHMENT_STORE_OP_STORE + 1), + VK_ATTACHMENT_STORE_OP_NONE_QCOM = 1000301000, VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentStoreOp; typedef enum VkPipelineBindPoint { VK_PIPELINE_BIND_POINT_GRAPHICS = 0, VK_PIPELINE_BIND_POINT_COMPUTE = 1, - VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = 1000165000, - VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS, - VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE, - VK_PIPELINE_BIND_POINT_RANGE_SIZE = (VK_PIPELINE_BIND_POINT_COMPUTE - VK_PIPELINE_BIND_POINT_GRAPHICS + 1), + VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR = 1000165000, + VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF } VkPipelineBindPoint; typedef enum VkCommandBufferLevel { VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, - VK_COMMAND_BUFFER_LEVEL_BEGIN_RANGE = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - VK_COMMAND_BUFFER_LEVEL_END_RANGE = VK_COMMAND_BUFFER_LEVEL_SECONDARY, - VK_COMMAND_BUFFER_LEVEL_RANGE_SIZE = (VK_COMMAND_BUFFER_LEVEL_SECONDARY - VK_COMMAND_BUFFER_LEVEL_PRIMARY + 1), VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF } VkCommandBufferLevel; typedef enum VkIndexType { VK_INDEX_TYPE_UINT16 = 0, VK_INDEX_TYPE_UINT32 = 1, - VK_INDEX_TYPE_NONE_NV = 1000165000, + VK_INDEX_TYPE_NONE_KHR = 1000165000, VK_INDEX_TYPE_UINT8_EXT = 1000265000, - VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16, - VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32, - VK_INDEX_TYPE_RANGE_SIZE = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1), + VK_INDEX_TYPE_NONE_NV = VK_INDEX_TYPE_NONE_KHR, VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF } VkIndexType; typedef enum VkSubpassContents { VK_SUBPASS_CONTENTS_INLINE = 0, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, - VK_SUBPASS_CONTENTS_BEGIN_RANGE = VK_SUBPASS_CONTENTS_INLINE, - VK_SUBPASS_CONTENTS_END_RANGE = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, - VK_SUBPASS_CONTENTS_RANGE_SIZE = (VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - VK_SUBPASS_CONTENTS_INLINE + 1), VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF } VkSubpassContents; @@ -1375,17 +1413,16 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001, VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, - VK_OBJECT_TYPE_OBJECT_TABLE_NVX = 1000086000, - VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001, VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000, + VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000165000, VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, - VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, + VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000, + VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = 1000295000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, - VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN, - VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_COMMAND_POOL, - VK_OBJECT_TYPE_RANGE_SIZE = (VK_OBJECT_TYPE_COMMAND_POOL - VK_OBJECT_TYPE_UNKNOWN + 1), + VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR, VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } VkObjectType; @@ -1393,9 +1430,8 @@ typedef enum VkVendorId { VK_VENDOR_ID_VIV = 0x10001, VK_VENDOR_ID_VSI = 0x10002, VK_VENDOR_ID_KAZAN = 0x10003, - VK_VENDOR_ID_BEGIN_RANGE = VK_VENDOR_ID_VIV, - VK_VENDOR_ID_END_RANGE = VK_VENDOR_ID_KAZAN, - VK_VENDOR_ID_RANGE_SIZE = (VK_VENDOR_ID_KAZAN - VK_VENDOR_ID_VIV + 1), + VK_VENDOR_ID_CODEPLAY = 0x10004, + VK_VENDOR_ID_MESA = 0x10005, VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF } VkVendorId; typedef VkFlags VkInstanceCreateFlags; @@ -1423,11 +1459,13 @@ typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000, VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000, VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = 0x00010000, + VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000, VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000, VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, @@ -1551,13 +1589,15 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, - VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR = 0x00200000, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000, VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = 0x00400000, - VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = 0x00200000, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000, VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, + VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; typedef VkFlags VkPipelineStageFlags; @@ -1635,7 +1675,9 @@ typedef enum VkBufferCreateFlagBits { VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008, - VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = 0x00000010, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000010, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferCreateFlagBits; typedef VkFlags VkBufferCreateFlags; @@ -1650,11 +1692,14 @@ typedef enum VkBufferUsageFlagBits { VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 0x00020000, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000, VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200, - VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = 0x00000400, - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = 0x00020000, + VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR = 0x00000400, + VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkBufferUsageFlagBits; typedef VkFlags VkBufferUsageFlags; @@ -1670,6 +1715,11 @@ typedef enum VkShaderModuleCreateFlagBits { VK_SHADER_MODULE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkShaderModuleCreateFlagBits; typedef VkFlags VkShaderModuleCreateFlags; + +typedef enum VkPipelineCacheCreateFlagBits { + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheCreateFlagBits; typedef VkFlags VkPipelineCacheCreateFlags; typedef enum VkPipelineCreateFlagBits { @@ -1677,10 +1727,21 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, - VK_PIPELINE_CREATE_DISPATCH_BASE = 0x00000010, + VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR = 0x00020000, + VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000, + VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000, VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020, VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR = 0x00000040, VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080, + VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000, + VK_PIPELINE_CREATE_LIBRARY_BIT_KHR = 0x00000800, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = 0x00000100, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = 0x00000200, + VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF @@ -1703,14 +1764,20 @@ typedef enum VkShaderStageFlagBits { VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, VK_SHADER_STAGE_ALL = 0x7FFFFFFF, - VK_SHADER_STAGE_RAYGEN_BIT_NV = 0x00000100, - VK_SHADER_STAGE_ANY_HIT_BIT_NV = 0x00000200, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = 0x00000400, - VK_SHADER_STAGE_MISS_BIT_NV = 0x00000800, - VK_SHADER_STAGE_INTERSECTION_BIT_NV = 0x00001000, - VK_SHADER_STAGE_CALLABLE_BIT_NV = 0x00002000, + VK_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, + VK_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, + VK_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, + VK_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, + VK_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, VK_SHADER_STAGE_TASK_BIT_NV = 0x00000040, VK_SHADER_STAGE_MESH_BIT_NV = 0x00000080, + VK_SHADER_STAGE_RAYGEN_BIT_NV = VK_SHADER_STAGE_RAYGEN_BIT_KHR, + VK_SHADER_STAGE_ANY_HIT_BIT_NV = VK_SHADER_STAGE_ANY_HIT_BIT_KHR, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, + VK_SHADER_STAGE_MISS_BIT_NV = VK_SHADER_STAGE_MISS_BIT_KHR, + VK_SHADER_STAGE_INTERSECTION_BIT_NV = VK_SHADER_STAGE_INTERSECTION_BIT_KHR, + VK_SHADER_STAGE_CALLABLE_BIT_NV = VK_SHADER_STAGE_CALLABLE_BIT_KHR, VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkShaderStageFlagBits; typedef VkFlags VkPipelineVertexInputStateCreateFlags; @@ -1751,27 +1818,31 @@ typedef enum VkSamplerCreateFlagBits { typedef VkFlags VkSamplerCreateFlags; typedef enum VkDescriptorSetLayoutCreateFlagBits { + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorSetLayoutCreateFlagBits; typedef VkFlags VkDescriptorSetLayoutCreateFlags; typedef enum VkDescriptorPoolCreateFlagBits { VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, - VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 0x00000002, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorPoolCreateFlagBits; typedef VkFlags VkDescriptorPoolCreateFlags; typedef VkFlags VkDescriptorPoolResetFlags; typedef enum VkFramebufferCreateFlagBits { - VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = 0x00000001, + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001, + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkFramebufferCreateFlagBits; typedef VkFlags VkFramebufferCreateFlags; typedef enum VkRenderPassCreateFlagBits { + VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM = 0x00000002, VK_RENDER_PASS_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkRenderPassCreateFlagBits; typedef VkFlags VkRenderPassCreateFlags; @@ -1785,6 +1856,8 @@ typedef VkFlags VkAttachmentDescriptionFlags; typedef enum VkSubpassDescriptionFlagBits { VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001, VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, + VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004, + VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008, VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSubpassDescriptionFlagBits; typedef VkFlags VkSubpassDescriptionFlags; @@ -1811,13 +1884,15 @@ typedef enum VkAccessFlagBits { VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, - VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000, - VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000, VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000, VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000, - VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000, - VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000, VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, + VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000, + VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAccessFlagBits; typedef VkFlags VkAccessFlags; @@ -3942,9 +4017,6 @@ typedef enum VkPointClippingBehavior { VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1, VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, - VK_POINT_CLIPPING_BEHAVIOR_BEGIN_RANGE = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, - VK_POINT_CLIPPING_BEHAVIOR_END_RANGE = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, - VK_POINT_CLIPPING_BEHAVIOR_RANGE_SIZE = (VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES + 1), VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF } VkPointClippingBehavior; @@ -3953,9 +4025,6 @@ typedef enum VkTessellationDomainOrigin { VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_BEGIN_RANGE = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_END_RANGE = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_RANGE_SIZE = (VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT + 1), VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF } VkTessellationDomainOrigin; @@ -3970,9 +4039,6 @@ typedef enum VkSamplerYcbcrModelConversion { VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709, VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601, VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_BEGIN_RANGE = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_END_RANGE = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RANGE_SIZE = (VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + 1), VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7FFFFFFF } VkSamplerYcbcrModelConversion; @@ -3981,9 +4047,6 @@ typedef enum VkSamplerYcbcrRange { VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1, VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, - VK_SAMPLER_YCBCR_RANGE_BEGIN_RANGE = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, - VK_SAMPLER_YCBCR_RANGE_END_RANGE = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, - VK_SAMPLER_YCBCR_RANGE_RANGE_SIZE = (VK_SAMPLER_YCBCR_RANGE_ITU_NARROW - VK_SAMPLER_YCBCR_RANGE_ITU_FULL + 1), VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7FFFFFFF } VkSamplerYcbcrRange; @@ -3992,9 +4055,6 @@ typedef enum VkChromaLocation { VK_CHROMA_LOCATION_MIDPOINT = 1, VK_CHROMA_LOCATION_COSITED_EVEN_KHR = VK_CHROMA_LOCATION_COSITED_EVEN, VK_CHROMA_LOCATION_MIDPOINT_KHR = VK_CHROMA_LOCATION_MIDPOINT, - VK_CHROMA_LOCATION_BEGIN_RANGE = VK_CHROMA_LOCATION_COSITED_EVEN, - VK_CHROMA_LOCATION_END_RANGE = VK_CHROMA_LOCATION_MIDPOINT, - VK_CHROMA_LOCATION_RANGE_SIZE = (VK_CHROMA_LOCATION_MIDPOINT - VK_CHROMA_LOCATION_COSITED_EVEN + 1), VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF } VkChromaLocation; @@ -4002,9 +4062,6 @@ typedef enum VkDescriptorUpdateTemplateType { VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1, VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_END_RANGE = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_RANGE_SIZE = (VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET + 1), VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorUpdateTemplateType; @@ -4037,7 +4094,11 @@ typedef VkFlags VkPeerMemoryFeatureFlags; typedef enum VkMemoryAllocateFlagBits { VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004, VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkMemoryAllocateFlagBits; typedef VkFlags VkMemoryAllocateFlags; @@ -4804,11 +4865,764 @@ VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport( #endif +#define VK_VERSION_1_2 1 +// Vulkan 1.2 version number +#define VK_API_VERSION_1_2 VK_MAKE_VERSION(1, 2, 0)// Patch version should always be set to 0 + +typedef uint64_t VkDeviceAddress; +#define VK_MAX_DRIVER_NAME_SIZE 256 +#define VK_MAX_DRIVER_INFO_SIZE 256 + +typedef enum VkDriverId { + VK_DRIVER_ID_AMD_PROPRIETARY = 1, + VK_DRIVER_ID_AMD_OPEN_SOURCE = 2, + VK_DRIVER_ID_MESA_RADV = 3, + VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8, + VK_DRIVER_ID_ARM_PROPRIETARY = 9, + VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10, + VK_DRIVER_ID_GGP_PROPRIETARY = 11, + VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12, + VK_DRIVER_ID_MESA_LLVMPIPE = 13, + VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, + VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, + VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, + VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = VK_DRIVER_ID_NVIDIA_PROPRIETARY, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = VK_DRIVER_ID_IMAGINATION_PROPRIETARY, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = VK_DRIVER_ID_QUALCOMM_PROPRIETARY, + VK_DRIVER_ID_ARM_PROPRIETARY_KHR = VK_DRIVER_ID_ARM_PROPRIETARY, + VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = VK_DRIVER_ID_GOOGLE_SWIFTSHADER, + VK_DRIVER_ID_GGP_PROPRIETARY_KHR = VK_DRIVER_ID_GGP_PROPRIETARY, + VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY, + VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF +} VkDriverId; + +typedef enum VkShaderFloatControlsIndependence { + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF +} VkShaderFloatControlsIndependence; + +typedef enum VkSamplerReductionMode { + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0, + VK_SAMPLER_REDUCTION_MODE_MIN = 1, + VK_SAMPLER_REDUCTION_MODE_MAX = 2, + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE, + VK_SAMPLER_REDUCTION_MODE_MIN_EXT = VK_SAMPLER_REDUCTION_MODE_MIN, + VK_SAMPLER_REDUCTION_MODE_MAX_EXT = VK_SAMPLER_REDUCTION_MODE_MAX, + VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerReductionMode; + +typedef enum VkSemaphoreType { + VK_SEMAPHORE_TYPE_BINARY = 0, + VK_SEMAPHORE_TYPE_TIMELINE = 1, + VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY, + VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE, + VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreType; + +typedef enum VkResolveModeFlagBits { + VK_RESOLVE_MODE_NONE = 0, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001, + VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002, + VK_RESOLVE_MODE_MIN_BIT = 0x00000004, + VK_RESOLVE_MODE_MAX_BIT = 0x00000008, + VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, + VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT, + VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT, + VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT, + VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkResolveModeFlagBits; +typedef VkFlags VkResolveModeFlags; + +typedef enum VkDescriptorBindingFlagBits { + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001, + VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004, + VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008, + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, + VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT, + VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, + VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorBindingFlagBits; +typedef VkFlags VkDescriptorBindingFlags; + +typedef enum VkSemaphoreWaitFlagBits { + VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001, + VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT, + VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreWaitFlagBits; +typedef VkFlags VkSemaphoreWaitFlags; +typedef struct VkPhysicalDeviceVulkan11Features { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer16BitAccess; + VkBool32 uniformAndStorageBuffer16BitAccess; + VkBool32 storagePushConstant16; + VkBool32 storageInputOutput16; + VkBool32 multiview; + VkBool32 multiviewGeometryShader; + VkBool32 multiviewTessellationShader; + VkBool32 variablePointersStorageBuffer; + VkBool32 variablePointers; + VkBool32 protectedMemory; + VkBool32 samplerYcbcrConversion; + VkBool32 shaderDrawParameters; +} VkPhysicalDeviceVulkan11Features; + +typedef struct VkPhysicalDeviceVulkan11Properties { + VkStructureType sType; + void* pNext; + uint8_t deviceUUID[VK_UUID_SIZE]; + uint8_t driverUUID[VK_UUID_SIZE]; + uint8_t deviceLUID[VK_LUID_SIZE]; + uint32_t deviceNodeMask; + VkBool32 deviceLUIDValid; + uint32_t subgroupSize; + VkShaderStageFlags subgroupSupportedStages; + VkSubgroupFeatureFlags subgroupSupportedOperations; + VkBool32 subgroupQuadOperationsInAllStages; + VkPointClippingBehavior pointClippingBehavior; + uint32_t maxMultiviewViewCount; + uint32_t maxMultiviewInstanceIndex; + VkBool32 protectedNoFault; + uint32_t maxPerSetDescriptors; + VkDeviceSize maxMemoryAllocationSize; +} VkPhysicalDeviceVulkan11Properties; + +typedef struct VkPhysicalDeviceVulkan12Features { + VkStructureType sType; + void* pNext; + VkBool32 samplerMirrorClampToEdge; + VkBool32 drawIndirectCount; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; + VkBool32 descriptorIndexing; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; + VkBool32 samplerFilterMinmax; + VkBool32 scalarBlockLayout; + VkBool32 imagelessFramebuffer; + VkBool32 uniformBufferStandardLayout; + VkBool32 shaderSubgroupExtendedTypes; + VkBool32 separateDepthStencilLayouts; + VkBool32 hostQueryReset; + VkBool32 timelineSemaphore; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; + VkBool32 shaderOutputViewportIndex; + VkBool32 shaderOutputLayer; + VkBool32 subgroupBroadcastDynamicId; +} VkPhysicalDeviceVulkan12Features; + +typedef struct VkConformanceVersion { + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t patch; +} VkConformanceVersion; + +typedef struct VkPhysicalDeviceVulkan12Properties { + VkStructureType sType; + void* pNext; + VkDriverId driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; + VkConformanceVersion conformanceVersion; + VkShaderFloatControlsIndependence denormBehaviorIndependence; + VkShaderFloatControlsIndependence roundingModeIndependence; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; + VkResolveModeFlags supportedDepthResolveModes; + VkResolveModeFlags supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; + uint64_t maxTimelineSemaphoreValueDifference; + VkSampleCountFlags framebufferIntegerColorSampleCounts; +} VkPhysicalDeviceVulkan12Properties; + +typedef struct VkImageFormatListCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t viewFormatCount; + const VkFormat* pViewFormats; +} VkImageFormatListCreateInfo; + +typedef struct VkAttachmentDescription2 { + VkStructureType sType; + const void* pNext; + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription2; + +typedef struct VkAttachmentReference2 { + VkStructureType sType; + const void* pNext; + uint32_t attachment; + VkImageLayout layout; + VkImageAspectFlags aspectMask; +} VkAttachmentReference2; + +typedef struct VkSubpassDescription2 { + VkStructureType sType; + const void* pNext; + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t viewMask; + uint32_t inputAttachmentCount; + const VkAttachmentReference2* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference2* pColorAttachments; + const VkAttachmentReference2* pResolveAttachments; + const VkAttachmentReference2* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription2; + +typedef struct VkSubpassDependency2 { + VkStructureType sType; + const void* pNext; + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; + int32_t viewOffset; +} VkSubpassDependency2; + +typedef struct VkRenderPassCreateInfo2 { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription2* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription2* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency2* pDependencies; + uint32_t correlatedViewMaskCount; + const uint32_t* pCorrelatedViewMasks; +} VkRenderPassCreateInfo2; + +typedef struct VkSubpassBeginInfo { + VkStructureType sType; + const void* pNext; + VkSubpassContents contents; +} VkSubpassBeginInfo; + +typedef struct VkSubpassEndInfo { + VkStructureType sType; + const void* pNext; +} VkSubpassEndInfo; + +typedef struct VkPhysicalDevice8BitStorageFeatures { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; +} VkPhysicalDevice8BitStorageFeatures; + +typedef struct VkPhysicalDeviceDriverProperties { + VkStructureType sType; + void* pNext; + VkDriverId driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; + VkConformanceVersion conformanceVersion; +} VkPhysicalDeviceDriverProperties; + +typedef struct VkPhysicalDeviceShaderAtomicInt64Features { + VkStructureType sType; + void* pNext; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; +} VkPhysicalDeviceShaderAtomicInt64Features; + +typedef struct VkPhysicalDeviceShaderFloat16Int8Features { + VkStructureType sType; + void* pNext; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; +} VkPhysicalDeviceShaderFloat16Int8Features; + +typedef struct VkPhysicalDeviceFloatControlsProperties { + VkStructureType sType; + void* pNext; + VkShaderFloatControlsIndependence denormBehaviorIndependence; + VkShaderFloatControlsIndependence roundingModeIndependence; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; +} VkPhysicalDeviceFloatControlsProperties; + +typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t bindingCount; + const VkDescriptorBindingFlags* pBindingFlags; +} VkDescriptorSetLayoutBindingFlagsCreateInfo; + +typedef struct VkPhysicalDeviceDescriptorIndexingFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; +} VkPhysicalDeviceDescriptorIndexingFeatures; + +typedef struct VkPhysicalDeviceDescriptorIndexingProperties { + VkStructureType sType; + void* pNext; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; +} VkPhysicalDeviceDescriptorIndexingProperties; + +typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo { + VkStructureType sType; + const void* pNext; + uint32_t descriptorSetCount; + const uint32_t* pDescriptorCounts; +} VkDescriptorSetVariableDescriptorCountAllocateInfo; + +typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport { + VkStructureType sType; + void* pNext; + uint32_t maxVariableDescriptorCount; +} VkDescriptorSetVariableDescriptorCountLayoutSupport; + +typedef struct VkSubpassDescriptionDepthStencilResolve { + VkStructureType sType; + const void* pNext; + VkResolveModeFlagBits depthResolveMode; + VkResolveModeFlagBits stencilResolveMode; + const VkAttachmentReference2* pDepthStencilResolveAttachment; +} VkSubpassDescriptionDepthStencilResolve; + +typedef struct VkPhysicalDeviceDepthStencilResolveProperties { + VkStructureType sType; + void* pNext; + VkResolveModeFlags supportedDepthResolveModes; + VkResolveModeFlags supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; +} VkPhysicalDeviceDepthStencilResolveProperties; + +typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures { + VkStructureType sType; + void* pNext; + VkBool32 scalarBlockLayout; +} VkPhysicalDeviceScalarBlockLayoutFeatures; + +typedef struct VkImageStencilUsageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageUsageFlags stencilUsage; +} VkImageStencilUsageCreateInfo; + +typedef struct VkSamplerReductionModeCreateInfo { + VkStructureType sType; + const void* pNext; + VkSamplerReductionMode reductionMode; +} VkSamplerReductionModeCreateInfo; + +typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties { + VkStructureType sType; + void* pNext; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; +} VkPhysicalDeviceSamplerFilterMinmaxProperties; + +typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures { + VkStructureType sType; + void* pNext; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; +} VkPhysicalDeviceVulkanMemoryModelFeatures; + +typedef struct VkPhysicalDeviceImagelessFramebufferFeatures { + VkStructureType sType; + void* pNext; + VkBool32 imagelessFramebuffer; +} VkPhysicalDeviceImagelessFramebufferFeatures; + +typedef struct VkFramebufferAttachmentImageInfo { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageUsageFlags usage; + uint32_t width; + uint32_t height; + uint32_t layerCount; + uint32_t viewFormatCount; + const VkFormat* pViewFormats; +} VkFramebufferAttachmentImageInfo; + +typedef struct VkFramebufferAttachmentsCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t attachmentImageInfoCount; + const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos; +} VkFramebufferAttachmentsCreateInfo; + +typedef struct VkRenderPassAttachmentBeginInfo { + VkStructureType sType; + const void* pNext; + uint32_t attachmentCount; + const VkImageView* pAttachments; +} VkRenderPassAttachmentBeginInfo; + +typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures { + VkStructureType sType; + void* pNext; + VkBool32 uniformBufferStandardLayout; +} VkPhysicalDeviceUniformBufferStandardLayoutFeatures; + +typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupExtendedTypes; +} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures; + +typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures { + VkStructureType sType; + void* pNext; + VkBool32 separateDepthStencilLayouts; +} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures; + +typedef struct VkAttachmentReferenceStencilLayout { + VkStructureType sType; + void* pNext; + VkImageLayout stencilLayout; +} VkAttachmentReferenceStencilLayout; + +typedef struct VkAttachmentDescriptionStencilLayout { + VkStructureType sType; + void* pNext; + VkImageLayout stencilInitialLayout; + VkImageLayout stencilFinalLayout; +} VkAttachmentDescriptionStencilLayout; + +typedef struct VkPhysicalDeviceHostQueryResetFeatures { + VkStructureType sType; + void* pNext; + VkBool32 hostQueryReset; +} VkPhysicalDeviceHostQueryResetFeatures; + +typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures { + VkStructureType sType; + void* pNext; + VkBool32 timelineSemaphore; +} VkPhysicalDeviceTimelineSemaphoreFeatures; + +typedef struct VkPhysicalDeviceTimelineSemaphoreProperties { + VkStructureType sType; + void* pNext; + uint64_t maxTimelineSemaphoreValueDifference; +} VkPhysicalDeviceTimelineSemaphoreProperties; + +typedef struct VkSemaphoreTypeCreateInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreType semaphoreType; + uint64_t initialValue; +} VkSemaphoreTypeCreateInfo; + +typedef struct VkTimelineSemaphoreSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreValueCount; + const uint64_t* pWaitSemaphoreValues; + uint32_t signalSemaphoreValueCount; + const uint64_t* pSignalSemaphoreValues; +} VkTimelineSemaphoreSubmitInfo; + +typedef struct VkSemaphoreWaitInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreWaitFlags flags; + uint32_t semaphoreCount; + const VkSemaphore* pSemaphores; + const uint64_t* pValues; +} VkSemaphoreWaitInfo; + +typedef struct VkSemaphoreSignalInfo { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; +} VkSemaphoreSignalInfo; + +typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures { + VkStructureType sType; + void* pNext; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; +} VkPhysicalDeviceBufferDeviceAddressFeatures; + +typedef struct VkBufferDeviceAddressInfo { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferDeviceAddressInfo; + +typedef struct VkBufferOpaqueCaptureAddressCreateInfo { + VkStructureType sType; + const void* pNext; + uint64_t opaqueCaptureAddress; +} VkBufferOpaqueCaptureAddressCreateInfo; + +typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { + VkStructureType sType; + const void* pNext; + uint64_t opaqueCaptureAddress; +} VkMemoryOpaqueCaptureAddressAllocateInfo; + +typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; +} VkDeviceMemoryOpaqueCaptureAddressInfo; + +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); +typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2( + VkDevice device, + const VkRenderPassCreateInfo2* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + const VkSubpassBeginInfo* pSubpassBeginInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2( + VkCommandBuffer commandBuffer, + const VkSubpassBeginInfo* pSubpassBeginInfo, + const VkSubpassEndInfo* pSubpassEndInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2( + VkCommandBuffer commandBuffer, + const VkSubpassEndInfo* pSubpassEndInfo); + +VKAPI_ATTR void VKAPI_CALL vkResetQueryPool( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue( + VkDevice device, + VkSemaphore semaphore, + uint64_t* pValue); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores( + VkDevice device, + const VkSemaphoreWaitInfo* pWaitInfo, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore( + VkDevice device, + const VkSemaphoreSignalInfo* pSignalInfo); + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( + VkDevice device, + const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); +#endif + + #define VK_KHR_surface 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) #define VK_KHR_SURFACE_SPEC_VERSION 25 #define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" +typedef enum VkPresentModeKHR { + VK_PRESENT_MODE_IMMEDIATE_KHR = 0, + VK_PRESENT_MODE_MAILBOX_KHR = 1, + VK_PRESENT_MODE_FIFO_KHR = 2, + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, + VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, + VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPresentModeKHR; + typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001, @@ -4828,25 +5642,9 @@ typedef enum VkColorSpaceKHR { VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000, VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, - VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1), VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF } VkColorSpaceKHR; -typedef enum VkPresentModeKHR { - VK_PRESENT_MODE_IMMEDIATE_KHR = 0, - VK_PRESENT_MODE_MAILBOX_KHR = 1, - VK_PRESENT_MODE_FIFO_KHR = 2, - VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, - VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, - VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, - VK_PRESENT_MODE_BEGIN_RANGE_KHR = VK_PRESENT_MODE_IMMEDIATE_KHR, - VK_PRESENT_MODE_END_RANGE_KHR = VK_PRESENT_MODE_FIFO_RELAXED_KHR, - VK_PRESENT_MODE_RANGE_SIZE_KHR = (VK_PRESENT_MODE_FIFO_RELAXED_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1), - VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPresentModeKHR; - typedef enum VkSurfaceTransformFlagBitsKHR { VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, @@ -4859,7 +5657,6 @@ typedef enum VkSurfaceTransformFlagBitsKHR { VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkSurfaceTransformFlagBitsKHR; -typedef VkFlags VkSurfaceTransformFlagsKHR; typedef enum VkCompositeAlphaFlagBitsKHR { VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, @@ -4868,6 +5665,7 @@ typedef enum VkCompositeAlphaFlagBitsKHR { VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF } VkCompositeAlphaFlagBitsKHR; +typedef VkFlags VkSurfaceTransformFlagsKHR; typedef VkFlags VkCompositeAlphaFlagsKHR; typedef struct VkSurfaceCapabilitiesKHR { uint32_t minImageCount; @@ -5591,14 +6389,9 @@ VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( #define VK_KHR_shader_float16_int8 1 #define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1 #define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8" -typedef struct VkPhysicalDeviceShaderFloat16Int8FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderFloat16; - VkBool32 shaderInt8; -} VkPhysicalDeviceShaderFloat16Int8FeaturesKHR; +typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceShaderFloat16Int8FeaturesKHR; -typedef VkPhysicalDeviceShaderFloat16Int8FeaturesKHR VkPhysicalDeviceFloat16Int8FeaturesKHR; +typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceFloat16Int8FeaturesKHR; @@ -5672,144 +6465,58 @@ VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( #define VK_KHR_imageless_framebuffer 1 #define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1 #define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer" -typedef struct VkPhysicalDeviceImagelessFramebufferFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 imagelessFramebuffer; -} VkPhysicalDeviceImagelessFramebufferFeaturesKHR; +typedef VkPhysicalDeviceImagelessFramebufferFeatures VkPhysicalDeviceImagelessFramebufferFeaturesKHR; -typedef struct VkFramebufferAttachmentImageInfoKHR { - VkStructureType sType; - const void* pNext; - VkImageCreateFlags flags; - VkImageUsageFlags usage; - uint32_t width; - uint32_t height; - uint32_t layerCount; - uint32_t viewFormatCount; - const VkFormat* pViewFormats; -} VkFramebufferAttachmentImageInfoKHR; +typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR; -typedef struct VkFramebufferAttachmentsCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t attachmentImageInfoCount; - const VkFramebufferAttachmentImageInfoKHR* pAttachmentImageInfos; -} VkFramebufferAttachmentsCreateInfoKHR; +typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR; -typedef struct VkRenderPassAttachmentBeginInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t attachmentCount; - const VkImageView* pAttachments; -} VkRenderPassAttachmentBeginInfoKHR; +typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR; #define VK_KHR_create_renderpass2 1 #define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1 #define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2" -typedef struct VkAttachmentDescription2KHR { - VkStructureType sType; - const void* pNext; - VkAttachmentDescriptionFlags flags; - VkFormat format; - VkSampleCountFlagBits samples; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - VkImageLayout initialLayout; - VkImageLayout finalLayout; -} VkAttachmentDescription2KHR; +typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR; -typedef struct VkAttachmentReference2KHR { - VkStructureType sType; - const void* pNext; - uint32_t attachment; - VkImageLayout layout; - VkImageAspectFlags aspectMask; -} VkAttachmentReference2KHR; +typedef VkAttachmentDescription2 VkAttachmentDescription2KHR; -typedef struct VkSubpassDescription2KHR { - VkStructureType sType; - const void* pNext; - VkSubpassDescriptionFlags flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t viewMask; - uint32_t inputAttachmentCount; - const VkAttachmentReference2KHR* pInputAttachments; - uint32_t colorAttachmentCount; - const VkAttachmentReference2KHR* pColorAttachments; - const VkAttachmentReference2KHR* pResolveAttachments; - const VkAttachmentReference2KHR* pDepthStencilAttachment; - uint32_t preserveAttachmentCount; - const uint32_t* pPreserveAttachments; -} VkSubpassDescription2KHR; +typedef VkAttachmentReference2 VkAttachmentReference2KHR; -typedef struct VkSubpassDependency2KHR { - VkStructureType sType; - const void* pNext; - uint32_t srcSubpass; - uint32_t dstSubpass; - VkPipelineStageFlags srcStageMask; - VkPipelineStageFlags dstStageMask; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkDependencyFlags dependencyFlags; - int32_t viewOffset; -} VkSubpassDependency2KHR; +typedef VkSubpassDescription2 VkSubpassDescription2KHR; -typedef struct VkRenderPassCreateInfo2KHR { - VkStructureType sType; - const void* pNext; - VkRenderPassCreateFlags flags; - uint32_t attachmentCount; - const VkAttachmentDescription2KHR* pAttachments; - uint32_t subpassCount; - const VkSubpassDescription2KHR* pSubpasses; - uint32_t dependencyCount; - const VkSubpassDependency2KHR* pDependencies; - uint32_t correlatedViewMaskCount; - const uint32_t* pCorrelatedViewMasks; -} VkRenderPassCreateInfo2KHR; +typedef VkSubpassDependency2 VkSubpassDependency2KHR; -typedef struct VkSubpassBeginInfoKHR { - VkStructureType sType; - const void* pNext; - VkSubpassContents contents; -} VkSubpassBeginInfoKHR; +typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR; -typedef struct VkSubpassEndInfoKHR { - VkStructureType sType; - const void* pNext; -} VkSubpassEndInfoKHR; +typedef VkSubpassEndInfo VkSubpassEndInfoKHR; -typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo); -typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo); -typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR( VkDevice device, - const VkRenderPassCreateInfo2KHR* pCreateInfo, + const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR( VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, - const VkSubpassBeginInfoKHR* pSubpassBeginInfo); + const VkSubpassBeginInfo* pSubpassBeginInfo); VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR( VkCommandBuffer commandBuffer, - const VkSubpassBeginInfoKHR* pSubpassBeginInfo, - const VkSubpassEndInfoKHR* pSubpassEndInfo); + const VkSubpassBeginInfo* pSubpassBeginInfo, + const VkSubpassEndInfo* pSubpassEndInfo); VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR( VkCommandBuffer commandBuffer, - const VkSubpassEndInfoKHR* pSubpassEndInfo); + const VkSubpassEndInfo* pSubpassEndInfo); #endif @@ -5901,6 +6608,144 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR( #endif +#define VK_KHR_performance_query 1 +#define VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION 1 +#define VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME "VK_KHR_performance_query" + +typedef enum VkPerformanceCounterUnitKHR { + VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR = 0, + VK_PERFORMANCE_COUNTER_UNIT_PERCENTAGE_KHR = 1, + VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR = 2, + VK_PERFORMANCE_COUNTER_UNIT_BYTES_KHR = 3, + VK_PERFORMANCE_COUNTER_UNIT_BYTES_PER_SECOND_KHR = 4, + VK_PERFORMANCE_COUNTER_UNIT_KELVIN_KHR = 5, + VK_PERFORMANCE_COUNTER_UNIT_WATTS_KHR = 6, + VK_PERFORMANCE_COUNTER_UNIT_VOLTS_KHR = 7, + VK_PERFORMANCE_COUNTER_UNIT_AMPS_KHR = 8, + VK_PERFORMANCE_COUNTER_UNIT_HERTZ_KHR = 9, + VK_PERFORMANCE_COUNTER_UNIT_CYCLES_KHR = 10, + VK_PERFORMANCE_COUNTER_UNIT_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterUnitKHR; + +typedef enum VkPerformanceCounterScopeKHR { + VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0, + VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1, + VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2, + VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR, + VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR, + VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR, + VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterScopeKHR; + +typedef enum VkPerformanceCounterStorageKHR { + VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR = 0, + VK_PERFORMANCE_COUNTER_STORAGE_INT64_KHR = 1, + VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR = 2, + VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR = 3, + VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32_KHR = 4, + VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64_KHR = 5, + VK_PERFORMANCE_COUNTER_STORAGE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterStorageKHR; + +typedef enum VkPerformanceCounterDescriptionFlagBitsKHR { + VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR = 0x00000001, + VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR = 0x00000002, + VK_PERFORMANCE_COUNTER_DESCRIPTION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterDescriptionFlagBitsKHR; +typedef VkFlags VkPerformanceCounterDescriptionFlagsKHR; + +typedef enum VkAcquireProfilingLockFlagBitsKHR { + VK_ACQUIRE_PROFILING_LOCK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAcquireProfilingLockFlagBitsKHR; +typedef VkFlags VkAcquireProfilingLockFlagsKHR; +typedef struct VkPhysicalDevicePerformanceQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 performanceCounterQueryPools; + VkBool32 performanceCounterMultipleQueryPools; +} VkPhysicalDevicePerformanceQueryFeaturesKHR; + +typedef struct VkPhysicalDevicePerformanceQueryPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 allowCommandBufferQueryCopies; +} VkPhysicalDevicePerformanceQueryPropertiesKHR; + +typedef struct VkPerformanceCounterKHR { + VkStructureType sType; + const void* pNext; + VkPerformanceCounterUnitKHR unit; + VkPerformanceCounterScopeKHR scope; + VkPerformanceCounterStorageKHR storage; + uint8_t uuid[VK_UUID_SIZE]; +} VkPerformanceCounterKHR; + +typedef struct VkPerformanceCounterDescriptionKHR { + VkStructureType sType; + const void* pNext; + VkPerformanceCounterDescriptionFlagsKHR flags; + char name[VK_MAX_DESCRIPTION_SIZE]; + char category[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkPerformanceCounterDescriptionKHR; + +typedef struct VkQueryPoolPerformanceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t queueFamilyIndex; + uint32_t counterIndexCount; + const uint32_t* pCounterIndices; +} VkQueryPoolPerformanceCreateInfoKHR; + +typedef union VkPerformanceCounterResultKHR { + int32_t int32; + int64_t int64; + uint32_t uint32; + uint64_t uint64; + float float32; + double float64; +} VkPerformanceCounterResultKHR; + +typedef struct VkAcquireProfilingLockInfoKHR { + VkStructureType sType; + const void* pNext; + VkAcquireProfilingLockFlagsKHR flags; + uint64_t timeout; +} VkAcquireProfilingLockInfoKHR; + +typedef struct VkPerformanceQuerySubmitInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t counterPassIndex; +} VkPerformanceQuerySubmitInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterKHR* pCounters, VkPerformanceCounterDescriptionKHR* pCounterDescriptions); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)(VkPhysicalDevice physicalDevice, const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, uint32_t* pNumPasses); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireProfilingLockKHR)(VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkReleaseProfilingLockKHR)(VkDevice device); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + uint32_t* pCounterCount, + VkPerformanceCounterKHR* pCounters, + VkPerformanceCounterDescriptionKHR* pCounterDescriptions); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR( + VkPhysicalDevice physicalDevice, + const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, + uint32_t* pNumPasses); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireProfilingLockKHR( + VkDevice device, + const VkAcquireProfilingLockInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR( + VkDevice device); +#endif + + #define VK_KHR_maintenance2 1 #define VK_KHR_MAINTENANCE2_SPEC_VERSION 1 #define VK_KHR_MAINTENANCE2_EXTENSION_NAME "VK_KHR_maintenance2" @@ -6086,12 +6931,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR( #define VK_KHR_image_format_list 1 #define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1 #define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list" -typedef struct VkImageFormatListCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t viewFormatCount; - const VkFormat* pViewFormats; -} VkImageFormatListCreateInfoKHR; +typedef VkImageFormatListCreateInfo VkImageFormatListCreateInfoKHR; @@ -6205,147 +7045,68 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR( #define VK_KHR_shader_subgroup_extended_types 1 #define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION 1 #define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME "VK_KHR_shader_subgroup_extended_types" -typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderSubgroupExtendedTypes; -} VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR; +typedef VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR; #define VK_KHR_8bit_storage 1 #define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1 #define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage" -typedef struct VkPhysicalDevice8BitStorageFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 storageBuffer8BitAccess; - VkBool32 uniformAndStorageBuffer8BitAccess; - VkBool32 storagePushConstant8; -} VkPhysicalDevice8BitStorageFeaturesKHR; +typedef VkPhysicalDevice8BitStorageFeatures VkPhysicalDevice8BitStorageFeaturesKHR; #define VK_KHR_shader_atomic_int64 1 #define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1 #define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64" -typedef struct VkPhysicalDeviceShaderAtomicInt64FeaturesKHR { +typedef VkPhysicalDeviceShaderAtomicInt64Features VkPhysicalDeviceShaderAtomicInt64FeaturesKHR; + + + +#define VK_KHR_shader_clock 1 +#define VK_KHR_SHADER_CLOCK_SPEC_VERSION 1 +#define VK_KHR_SHADER_CLOCK_EXTENSION_NAME "VK_KHR_shader_clock" +typedef struct VkPhysicalDeviceShaderClockFeaturesKHR { VkStructureType sType; void* pNext; - VkBool32 shaderBufferInt64Atomics; - VkBool32 shaderSharedInt64Atomics; -} VkPhysicalDeviceShaderAtomicInt64FeaturesKHR; + VkBool32 shaderSubgroupClock; + VkBool32 shaderDeviceClock; +} VkPhysicalDeviceShaderClockFeaturesKHR; #define VK_KHR_driver_properties 1 -#define VK_MAX_DRIVER_NAME_SIZE_KHR 256 -#define VK_MAX_DRIVER_INFO_SIZE_KHR 256 #define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 #define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" +#define VK_MAX_DRIVER_NAME_SIZE_KHR VK_MAX_DRIVER_NAME_SIZE +#define VK_MAX_DRIVER_INFO_SIZE_KHR VK_MAX_DRIVER_INFO_SIZE +typedef VkDriverId VkDriverIdKHR; -typedef enum VkDriverIdKHR { - VK_DRIVER_ID_AMD_PROPRIETARY_KHR = 1, - VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = 2, - VK_DRIVER_ID_MESA_RADV_KHR = 3, - VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = 4, - VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = 5, - VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = 6, - VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7, - VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8, - VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9, - VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = 10, - VK_DRIVER_ID_GGP_PROPRIETARY_KHR = 11, - VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = 12, - VK_DRIVER_ID_BEGIN_RANGE_KHR = VK_DRIVER_ID_AMD_PROPRIETARY_KHR, - VK_DRIVER_ID_END_RANGE_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR, - VK_DRIVER_ID_RANGE_SIZE_KHR = (VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR - VK_DRIVER_ID_AMD_PROPRIETARY_KHR + 1), - VK_DRIVER_ID_MAX_ENUM_KHR = 0x7FFFFFFF -} VkDriverIdKHR; -typedef struct VkConformanceVersionKHR { - uint8_t major; - uint8_t minor; - uint8_t subminor; - uint8_t patch; -} VkConformanceVersionKHR; +typedef VkConformanceVersion VkConformanceVersionKHR; -typedef struct VkPhysicalDeviceDriverPropertiesKHR { - VkStructureType sType; - void* pNext; - VkDriverIdKHR driverID; - char driverName[VK_MAX_DRIVER_NAME_SIZE_KHR]; - char driverInfo[VK_MAX_DRIVER_INFO_SIZE_KHR]; - VkConformanceVersionKHR conformanceVersion; -} VkPhysicalDeviceDriverPropertiesKHR; +typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR; #define VK_KHR_shader_float_controls 1 #define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 4 #define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls" +typedef VkShaderFloatControlsIndependence VkShaderFloatControlsIndependenceKHR; -typedef enum VkShaderFloatControlsIndependenceKHR { - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = 0, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = 1, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = 2, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_BEGIN_RANGE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_END_RANGE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_RANGE_SIZE_KHR = (VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR + 1), - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkShaderFloatControlsIndependenceKHR; -typedef struct VkPhysicalDeviceFloatControlsPropertiesKHR { - VkStructureType sType; - void* pNext; - VkShaderFloatControlsIndependenceKHR denormBehaviorIndependence; - VkShaderFloatControlsIndependenceKHR roundingModeIndependence; - VkBool32 shaderSignedZeroInfNanPreserveFloat16; - VkBool32 shaderSignedZeroInfNanPreserveFloat32; - VkBool32 shaderSignedZeroInfNanPreserveFloat64; - VkBool32 shaderDenormPreserveFloat16; - VkBool32 shaderDenormPreserveFloat32; - VkBool32 shaderDenormPreserveFloat64; - VkBool32 shaderDenormFlushToZeroFloat16; - VkBool32 shaderDenormFlushToZeroFloat32; - VkBool32 shaderDenormFlushToZeroFloat64; - VkBool32 shaderRoundingModeRTEFloat16; - VkBool32 shaderRoundingModeRTEFloat32; - VkBool32 shaderRoundingModeRTEFloat64; - VkBool32 shaderRoundingModeRTZFloat16; - VkBool32 shaderRoundingModeRTZFloat32; - VkBool32 shaderRoundingModeRTZFloat64; -} VkPhysicalDeviceFloatControlsPropertiesKHR; +typedef VkPhysicalDeviceFloatControlsProperties VkPhysicalDeviceFloatControlsPropertiesKHR; #define VK_KHR_depth_stencil_resolve 1 #define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1 #define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve" +typedef VkResolveModeFlagBits VkResolveModeFlagBitsKHR; -typedef enum VkResolveModeFlagBitsKHR { - VK_RESOLVE_MODE_NONE_KHR = 0, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = 0x00000001, - VK_RESOLVE_MODE_AVERAGE_BIT_KHR = 0x00000002, - VK_RESOLVE_MODE_MIN_BIT_KHR = 0x00000004, - VK_RESOLVE_MODE_MAX_BIT_KHR = 0x00000008, - VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkResolveModeFlagBitsKHR; -typedef VkFlags VkResolveModeFlagsKHR; -typedef struct VkSubpassDescriptionDepthStencilResolveKHR { - VkStructureType sType; - const void* pNext; - VkResolveModeFlagBitsKHR depthResolveMode; - VkResolveModeFlagBitsKHR stencilResolveMode; - const VkAttachmentReference2KHR* pDepthStencilResolveAttachment; -} VkSubpassDescriptionDepthStencilResolveKHR; +typedef VkResolveModeFlags VkResolveModeFlagsKHR; -typedef struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR { - VkStructureType sType; - void* pNext; - VkResolveModeFlagsKHR supportedDepthResolveModes; - VkResolveModeFlagsKHR supportedStencilResolveModes; - VkBool32 independentResolveNone; - VkBool32 independentResolve; -} VkPhysicalDeviceDepthStencilResolvePropertiesKHR; +typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR; + +typedef VkPhysicalDeviceDepthStencilResolveProperties VkPhysicalDeviceDepthStencilResolvePropertiesKHR; @@ -6354,19 +7115,60 @@ typedef struct VkPhysicalDeviceDepthStencilResolvePropertiesKHR { #define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format" +#define VK_KHR_timeline_semaphore 1 +#define VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION 2 +#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME "VK_KHR_timeline_semaphore" +typedef VkSemaphoreType VkSemaphoreTypeKHR; + +typedef VkSemaphoreWaitFlagBits VkSemaphoreWaitFlagBitsKHR; + +typedef VkSemaphoreWaitFlags VkSemaphoreWaitFlagsKHR; + +typedef VkPhysicalDeviceTimelineSemaphoreFeatures VkPhysicalDeviceTimelineSemaphoreFeaturesKHR; + +typedef VkPhysicalDeviceTimelineSemaphoreProperties VkPhysicalDeviceTimelineSemaphorePropertiesKHR; + +typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR; + +typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR; + +typedef VkSemaphoreWaitInfo VkSemaphoreWaitInfoKHR; + +typedef VkSemaphoreSignalInfo VkSemaphoreSignalInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValueKHR)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); +typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValueKHR( + VkDevice device, + VkSemaphore semaphore, + uint64_t* pValue); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphoresKHR( + VkDevice device, + const VkSemaphoreWaitInfo* pWaitInfo, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphoreKHR( + VkDevice device, + const VkSemaphoreSignalInfo* pSignalInfo); +#endif + + #define VK_KHR_vulkan_memory_model 1 #define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 3 #define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model" -typedef struct VkPhysicalDeviceVulkanMemoryModelFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 vulkanMemoryModel; - VkBool32 vulkanMemoryModelDeviceScope; - VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; -} VkPhysicalDeviceVulkanMemoryModelFeaturesKHR; +typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryModelFeaturesKHR; +#define VK_KHR_spirv_1_4 1 +#define VK_KHR_SPIRV_1_4_SPEC_VERSION 1 +#define VK_KHR_SPIRV_1_4_EXTENSION_NAME "VK_KHR_spirv_1_4" + + #define VK_KHR_surface_protected_capabilities 1 #define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION 1 #define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME "VK_KHR_surface_protected_capabilities" @@ -6378,17 +7180,56 @@ typedef struct VkSurfaceProtectedCapabilitiesKHR { +#define VK_KHR_separate_depth_stencil_layouts 1 +#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION 1 +#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME "VK_KHR_separate_depth_stencil_layouts" +typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR; + +typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR; + +typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR; + + + #define VK_KHR_uniform_buffer_standard_layout 1 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout" -typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 uniformBufferStandardLayout; -} VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR; +typedef VkPhysicalDeviceUniformBufferStandardLayoutFeatures VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR; +#define VK_KHR_buffer_device_address 1 +#define VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 1 +#define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_KHR_buffer_device_address" +typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDeviceAddressFeaturesKHR; + +typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR; + +typedef VkBufferOpaqueCaptureAddressCreateInfo VkBufferOpaqueCaptureAddressCreateInfoKHR; + +typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR; + +typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR; + +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressKHR( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddressKHR( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddressKHR( + VkDevice device, + const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); +#endif + + #define VK_KHR_pipeline_executable_properties 1 #define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION 1 #define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME "VK_KHR_pipeline_executable_properties" @@ -6398,9 +7239,6 @@ typedef enum VkPipelineExecutableStatisticFormatKHR { VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR = 1, VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR = 2, VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR = 3, - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BEGIN_RANGE_KHR = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR, - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_END_RANGE_KHR = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR, - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_RANGE_SIZE_KHR = (VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR + 1), VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_MAX_ENUM_KHR = 0x7FFFFFFF } VkPipelineExecutableStatisticFormatKHR; typedef struct VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR { @@ -6482,6 +7320,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR #endif +#define VK_KHR_shader_non_semantic_info 1 +#define VK_KHR_SHADER_NON_SEMANTIC_INFO_SPEC_VERSION 1 +#define VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME "VK_KHR_shader_non_semantic_info" + + #define VK_EXT_debug_report 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) #define VK_EXT_DEBUG_REPORT_SPEC_VERSION 9 @@ -6519,19 +7362,15 @@ typedef enum VkDebugReportObjectTypeEXT { VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29, VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30, - VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31, - VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000, - VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000, + VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT = 1000165000, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT + 1), + VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDebugReportObjectTypeEXT; @@ -6612,9 +7451,6 @@ VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( typedef enum VkRasterizationOrderAMD { VK_RASTERIZATION_ORDER_STRICT_AMD = 0, VK_RASTERIZATION_ORDER_RELAXED_AMD = 1, - VK_RASTERIZATION_ORDER_BEGIN_RANGE_AMD = VK_RASTERIZATION_ORDER_STRICT_AMD, - VK_RASTERIZATION_ORDER_END_RANGE_AMD = VK_RASTERIZATION_ORDER_RELAXED_AMD, - VK_RASTERIZATION_ORDER_RANGE_SIZE_AMD = (VK_RASTERIZATION_ORDER_RELAXED_AMD - VK_RASTERIZATION_ORDER_STRICT_AMD + 1), VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF } VkRasterizationOrderAMD; typedef struct VkPipelineRasterizationStateRasterizationOrderAMD { @@ -6808,7 +7644,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT( #define VK_NVX_image_view_handle 1 -#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 1 +#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 2 #define VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME "VK_NVX_image_view_handle" typedef struct VkImageViewHandleInfoNVX { VkStructureType sType; @@ -6818,12 +7654,25 @@ typedef struct VkImageViewHandleInfoNVX { VkSampler sampler; } VkImageViewHandleInfoNVX; +typedef struct VkImageViewAddressPropertiesNVX { + VkStructureType sType; + void* pNext; + VkDeviceAddress deviceAddress; + VkDeviceSize size; +} VkImageViewAddressPropertiesNVX; + typedef uint32_t (VKAPI_PTR *PFN_vkGetImageViewHandleNVX)(VkDevice device, const VkImageViewHandleInfoNVX* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetImageViewAddressNVX)(VkDevice device, VkImageView imageView, VkImageViewAddressPropertiesNVX* pProperties); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR uint32_t VKAPI_CALL vkGetImageViewHandleNVX( VkDevice device, const VkImageViewHandleInfoNVX* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetImageViewAddressNVX( + VkDevice device, + VkImageView imageView, + VkImageViewAddressPropertiesNVX* pProperties); #endif @@ -6888,9 +7737,6 @@ typedef enum VkShaderInfoTypeAMD { VK_SHADER_INFO_TYPE_STATISTICS_AMD = 0, VK_SHADER_INFO_TYPE_BINARY_AMD = 1, VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD = 2, - VK_SHADER_INFO_TYPE_BEGIN_RANGE_AMD = VK_SHADER_INFO_TYPE_STATISTICS_AMD, - VK_SHADER_INFO_TYPE_END_RANGE_AMD = VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD, - VK_SHADER_INFO_TYPE_RANGE_SIZE_AMD = (VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD - VK_SHADER_INFO_TYPE_STATISTICS_AMD + 1), VK_SHADER_INFO_TYPE_MAX_ENUM_AMD = 0x7FFFFFFF } VkShaderInfoTypeAMD; typedef struct VkShaderResourceUsageAMD { @@ -7011,9 +7857,6 @@ typedef struct VkExportMemoryAllocateInfoNV { typedef enum VkValidationCheckEXT { VK_VALIDATION_CHECK_ALL_EXT = 0, VK_VALIDATION_CHECK_SHADERS_EXT = 1, - VK_VALIDATION_CHECK_BEGIN_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT, - VK_VALIDATION_CHECK_END_RANGE_EXT = VK_VALIDATION_CHECK_SHADERS_EXT, - VK_VALIDATION_CHECK_RANGE_SIZE_EXT = (VK_VALIDATION_CHECK_SHADERS_EXT - VK_VALIDATION_CHECK_ALL_EXT + 1), VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF } VkValidationCheckEXT; typedef struct VkValidationFlagsEXT { @@ -7040,7 +7883,7 @@ typedef struct VkValidationFlagsEXT { #define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME "VK_EXT_texture_compression_astc_hdr" typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT { VkStructureType sType; - const void* pNext; + void* pNext; VkBool32 textureCompressionASTC_HDR; } VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; @@ -7106,229 +7949,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdEndConditionalRenderingEXT( #endif -#define VK_NVX_device_generated_commands 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkObjectTableNVX) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX) -#define VK_NVX_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3 -#define VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NVX_device_generated_commands" - -typedef enum VkIndirectCommandsTokenTypeNVX { - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX = 0, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DESCRIPTOR_SET_NVX = 1, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NVX = 2, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NVX = 3, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NVX = 4, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NVX = 5, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NVX = 6, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX = 7, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_BEGIN_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_END_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_RANGE_SIZE_NVX = (VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NVX - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NVX + 1), - VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF -} VkIndirectCommandsTokenTypeNVX; - -typedef enum VkObjectEntryTypeNVX { - VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX = 0, - VK_OBJECT_ENTRY_TYPE_PIPELINE_NVX = 1, - VK_OBJECT_ENTRY_TYPE_INDEX_BUFFER_NVX = 2, - VK_OBJECT_ENTRY_TYPE_VERTEX_BUFFER_NVX = 3, - VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX = 4, - VK_OBJECT_ENTRY_TYPE_BEGIN_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX, - VK_OBJECT_ENTRY_TYPE_END_RANGE_NVX = VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX, - VK_OBJECT_ENTRY_TYPE_RANGE_SIZE_NVX = (VK_OBJECT_ENTRY_TYPE_PUSH_CONSTANT_NVX - VK_OBJECT_ENTRY_TYPE_DESCRIPTOR_SET_NVX + 1), - VK_OBJECT_ENTRY_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF -} VkObjectEntryTypeNVX; - -typedef enum VkIndirectCommandsLayoutUsageFlagBitsNVX { - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX = 0x00000001, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX = 0x00000002, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX = 0x00000004, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX = 0x00000008, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF -} VkIndirectCommandsLayoutUsageFlagBitsNVX; -typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNVX; - -typedef enum VkObjectEntryUsageFlagBitsNVX { - VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX = 0x00000001, - VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX = 0x00000002, - VK_OBJECT_ENTRY_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF -} VkObjectEntryUsageFlagBitsNVX; -typedef VkFlags VkObjectEntryUsageFlagsNVX; -typedef struct VkDeviceGeneratedCommandsFeaturesNVX { - VkStructureType sType; - const void* pNext; - VkBool32 computeBindingPointSupport; -} VkDeviceGeneratedCommandsFeaturesNVX; - -typedef struct VkDeviceGeneratedCommandsLimitsNVX { - VkStructureType sType; - const void* pNext; - uint32_t maxIndirectCommandsLayoutTokenCount; - uint32_t maxObjectEntryCounts; - uint32_t minSequenceCountBufferOffsetAlignment; - uint32_t minSequenceIndexBufferOffsetAlignment; - uint32_t minCommandsTokenBufferOffsetAlignment; -} VkDeviceGeneratedCommandsLimitsNVX; - -typedef struct VkIndirectCommandsTokenNVX { - VkIndirectCommandsTokenTypeNVX tokenType; - VkBuffer buffer; - VkDeviceSize offset; -} VkIndirectCommandsTokenNVX; - -typedef struct VkIndirectCommandsLayoutTokenNVX { - VkIndirectCommandsTokenTypeNVX tokenType; - uint32_t bindingUnit; - uint32_t dynamicCount; - uint32_t divisor; -} VkIndirectCommandsLayoutTokenNVX; - -typedef struct VkIndirectCommandsLayoutCreateInfoNVX { - VkStructureType sType; - const void* pNext; - VkPipelineBindPoint pipelineBindPoint; - VkIndirectCommandsLayoutUsageFlagsNVX flags; - uint32_t tokenCount; - const VkIndirectCommandsLayoutTokenNVX* pTokens; -} VkIndirectCommandsLayoutCreateInfoNVX; - -typedef struct VkCmdProcessCommandsInfoNVX { - VkStructureType sType; - const void* pNext; - VkObjectTableNVX objectTable; - VkIndirectCommandsLayoutNVX indirectCommandsLayout; - uint32_t indirectCommandsTokenCount; - const VkIndirectCommandsTokenNVX* pIndirectCommandsTokens; - uint32_t maxSequencesCount; - VkCommandBuffer targetCommandBuffer; - VkBuffer sequencesCountBuffer; - VkDeviceSize sequencesCountOffset; - VkBuffer sequencesIndexBuffer; - VkDeviceSize sequencesIndexOffset; -} VkCmdProcessCommandsInfoNVX; - -typedef struct VkCmdReserveSpaceForCommandsInfoNVX { - VkStructureType sType; - const void* pNext; - VkObjectTableNVX objectTable; - VkIndirectCommandsLayoutNVX indirectCommandsLayout; - uint32_t maxSequencesCount; -} VkCmdReserveSpaceForCommandsInfoNVX; - -typedef struct VkObjectTableCreateInfoNVX { - VkStructureType sType; - const void* pNext; - uint32_t objectCount; - const VkObjectEntryTypeNVX* pObjectEntryTypes; - const uint32_t* pObjectEntryCounts; - const VkObjectEntryUsageFlagsNVX* pObjectEntryUsageFlags; - uint32_t maxUniformBuffersPerDescriptor; - uint32_t maxStorageBuffersPerDescriptor; - uint32_t maxStorageImagesPerDescriptor; - uint32_t maxSampledImagesPerDescriptor; - uint32_t maxPipelineLayouts; -} VkObjectTableCreateInfoNVX; - -typedef struct VkObjectTableEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; -} VkObjectTableEntryNVX; - -typedef struct VkObjectTablePipelineEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipeline pipeline; -} VkObjectTablePipelineEntryNVX; - -typedef struct VkObjectTableDescriptorSetEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipelineLayout pipelineLayout; - VkDescriptorSet descriptorSet; -} VkObjectTableDescriptorSetEntryNVX; - -typedef struct VkObjectTableVertexBufferEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkBuffer buffer; -} VkObjectTableVertexBufferEntryNVX; - -typedef struct VkObjectTableIndexBufferEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkBuffer buffer; - VkIndexType indexType; -} VkObjectTableIndexBufferEntryNVX; - -typedef struct VkObjectTablePushConstantEntryNVX { - VkObjectEntryTypeNVX type; - VkObjectEntryUsageFlagsNVX flags; - VkPipelineLayout pipelineLayout; - VkShaderStageFlags stageFlags; -} VkObjectTablePushConstantEntryNVX; - -typedef void (VKAPI_PTR *PFN_vkCmdProcessCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo); -typedef void (VKAPI_PTR *PFN_vkCmdReserveSpaceForCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNVX)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout); -typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNVX)(VkDevice device, VkIndirectCommandsLayoutNVX indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateObjectTableNVX)(VkDevice device, const VkObjectTableCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkObjectTableNVX* pObjectTable); -typedef void (VKAPI_PTR *PFN_vkDestroyObjectTableNVX)(VkDevice device, VkObjectTableNVX objectTable, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkRegisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectTableEntryNVX* const* ppObjectTableEntries, const uint32_t* pObjectIndices); -typedef VkResult (VKAPI_PTR *PFN_vkUnregisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectEntryTypeNVX* pObjectEntryTypes, const uint32_t* pObjectIndices); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX)(VkPhysicalDevice physicalDevice, VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, VkDeviceGeneratedCommandsLimitsNVX* pLimits); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdProcessCommandsNVX( - VkCommandBuffer commandBuffer, - const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdReserveSpaceForCommandsNVX( - VkCommandBuffer commandBuffer, - const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNVX( - VkDevice device, - const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout); - -VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNVX( - VkDevice device, - VkIndirectCommandsLayoutNVX indirectCommandsLayout, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateObjectTableNVX( - VkDevice device, - const VkObjectTableCreateInfoNVX* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkObjectTableNVX* pObjectTable); - -VKAPI_ATTR void VKAPI_CALL vkDestroyObjectTableNVX( - VkDevice device, - VkObjectTableNVX objectTable, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkRegisterObjectsNVX( - VkDevice device, - VkObjectTableNVX objectTable, - uint32_t objectCount, - const VkObjectTableEntryNVX* const* ppObjectTableEntries, - const uint32_t* pObjectIndices); - -VKAPI_ATTR VkResult VKAPI_CALL vkUnregisterObjectsNVX( - VkDevice device, - VkObjectTableNVX objectTable, - uint32_t objectCount, - const VkObjectEntryTypeNVX* pObjectEntryTypes, - const uint32_t* pObjectIndices); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX( - VkPhysicalDevice physicalDevice, - VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, - VkDeviceGeneratedCommandsLimitsNVX* pLimits); -#endif - - #define VK_NV_clip_space_w_scaling 1 #define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1 #define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling" @@ -7411,25 +8031,16 @@ typedef enum VkDisplayPowerStateEXT { VK_DISPLAY_POWER_STATE_OFF_EXT = 0, VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1, VK_DISPLAY_POWER_STATE_ON_EXT = 2, - VK_DISPLAY_POWER_STATE_BEGIN_RANGE_EXT = VK_DISPLAY_POWER_STATE_OFF_EXT, - VK_DISPLAY_POWER_STATE_END_RANGE_EXT = VK_DISPLAY_POWER_STATE_ON_EXT, - VK_DISPLAY_POWER_STATE_RANGE_SIZE_EXT = (VK_DISPLAY_POWER_STATE_ON_EXT - VK_DISPLAY_POWER_STATE_OFF_EXT + 1), VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDisplayPowerStateEXT; typedef enum VkDeviceEventTypeEXT { VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0, - VK_DEVICE_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT, - VK_DEVICE_EVENT_TYPE_END_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT, - VK_DEVICE_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT - VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT + 1), VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDeviceEventTypeEXT; typedef enum VkDisplayEventTypeEXT { VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0, - VK_DISPLAY_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT, - VK_DISPLAY_EVENT_TYPE_END_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT, - VK_DISPLAY_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT - VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT + 1), VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDisplayEventTypeEXT; typedef struct VkDisplayPowerInfoEXT { @@ -7571,9 +8182,6 @@ typedef enum VkViewportCoordinateSwizzleNV { VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5, VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6, VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7, - VK_VIEWPORT_COORDINATE_SWIZZLE_BEGIN_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV, - VK_VIEWPORT_COORDINATE_SWIZZLE_END_RANGE_NV = VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV, - VK_VIEWPORT_COORDINATE_SWIZZLE_RANGE_SIZE_NV = (VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV + 1), VK_VIEWPORT_COORDINATE_SWIZZLE_MAX_ENUM_NV = 0x7FFFFFFF } VkViewportCoordinateSwizzleNV; typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV; @@ -7601,9 +8209,6 @@ typedef struct VkPipelineViewportSwizzleStateCreateInfoNV { typedef enum VkDiscardRectangleModeEXT { VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0, VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1, - VK_DISCARD_RECTANGLE_MODE_BEGIN_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT, - VK_DISCARD_RECTANGLE_MODE_END_RANGE_EXT = VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT, - VK_DISCARD_RECTANGLE_MODE_RANGE_SIZE_EXT = (VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT - VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT + 1), VK_DISCARD_RECTANGLE_MODE_MAX_ENUM_EXT = 0x7FFFFFFF } VkDiscardRectangleModeEXT; typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT; @@ -7641,9 +8246,6 @@ typedef enum VkConservativeRasterizationModeEXT { VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT = 0, VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT = 1, VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT = 2, - VK_CONSERVATIVE_RASTERIZATION_MODE_BEGIN_RANGE_EXT = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT, - VK_CONSERVATIVE_RASTERIZATION_MODE_END_RANGE_EXT = VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, - VK_CONSERVATIVE_RASTERIZATION_MODE_RANGE_SIZE_EXT = (VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT - VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT + 1), VK_CONSERVATIVE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF } VkConservativeRasterizationModeEXT; typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT; @@ -7740,10 +8342,9 @@ VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT( #define VK_EXT_debug_utils 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT) -#define VK_EXT_DEBUG_UTILS_SPEC_VERSION 1 +#define VK_EXT_DEBUG_UTILS_SPEC_VERSION 2 #define VK_EXT_DEBUG_UTILS_EXTENSION_NAME "VK_EXT_debug_utils" typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT; -typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT { VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001, @@ -7752,7 +8353,6 @@ typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT { VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000, VK_DEBUG_UTILS_MESSAGE_SEVERITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF } VkDebugUtilsMessageSeverityFlagBitsEXT; -typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; typedef enum VkDebugUtilsMessageTypeFlagBitsEXT { VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001, @@ -7761,6 +8361,15 @@ typedef enum VkDebugUtilsMessageTypeFlagBitsEXT { VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF } VkDebugUtilsMessageTypeFlagBitsEXT; typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT; +typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; +typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; +typedef struct VkDebugUtilsLabelEXT { + VkStructureType sType; + const void* pNext; + const char* pLabelName; + float color[4]; +} VkDebugUtilsLabelEXT; + typedef struct VkDebugUtilsObjectNameInfoEXT { VkStructureType sType; const void* pNext; @@ -7769,23 +8378,6 @@ typedef struct VkDebugUtilsObjectNameInfoEXT { const char* pObjectName; } VkDebugUtilsObjectNameInfoEXT; -typedef struct VkDebugUtilsObjectTagInfoEXT { - VkStructureType sType; - const void* pNext; - VkObjectType objectType; - uint64_t objectHandle; - uint64_t tagName; - size_t tagSize; - const void* pTag; -} VkDebugUtilsObjectTagInfoEXT; - -typedef struct VkDebugUtilsLabelEXT { - VkStructureType sType; - const void* pNext; - const char* pLabelName; - float color[4]; -} VkDebugUtilsLabelEXT; - typedef struct VkDebugUtilsMessengerCallbackDataEXT { VkStructureType sType; const void* pNext; @@ -7807,6 +8399,16 @@ typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)( const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData); +typedef struct VkDebugUtilsObjectTagInfoEXT { + VkStructureType sType; + const void* pNext; + VkObjectType objectType; + uint64_t objectHandle; + uint64_t tagName; + size_t tagSize; + const void* pTag; +} VkDebugUtilsObjectTagInfoEXT; + typedef struct VkDebugUtilsMessengerCreateInfoEXT { VkStructureType sType; const void* pNext; @@ -7882,28 +8484,11 @@ VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT( #define VK_EXT_sampler_filter_minmax 1 #define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 2 #define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax" +typedef VkSamplerReductionMode VkSamplerReductionModeEXT; -typedef enum VkSamplerReductionModeEXT { - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = 0, - VK_SAMPLER_REDUCTION_MODE_MIN_EXT = 1, - VK_SAMPLER_REDUCTION_MODE_MAX_EXT = 2, - VK_SAMPLER_REDUCTION_MODE_BEGIN_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, - VK_SAMPLER_REDUCTION_MODE_END_RANGE_EXT = VK_SAMPLER_REDUCTION_MODE_MAX_EXT, - VK_SAMPLER_REDUCTION_MODE_RANGE_SIZE_EXT = (VK_SAMPLER_REDUCTION_MODE_MAX_EXT - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT + 1), - VK_SAMPLER_REDUCTION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkSamplerReductionModeEXT; -typedef struct VkSamplerReductionModeCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkSamplerReductionModeEXT reductionMode; -} VkSamplerReductionModeCreateInfoEXT; +typedef VkSamplerReductionModeCreateInfo VkSamplerReductionModeCreateInfoEXT; -typedef struct VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT { - VkStructureType sType; - void* pNext; - VkBool32 filterMinmaxSingleComponentFormats; - VkBool32 filterMinmaxImageComponentMapping; -} VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; +typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; @@ -8044,9 +8629,6 @@ typedef enum VkBlendOverlapEXT { VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0, VK_BLEND_OVERLAP_DISJOINT_EXT = 1, VK_BLEND_OVERLAP_CONJOINT_EXT = 2, - VK_BLEND_OVERLAP_BEGIN_RANGE_EXT = VK_BLEND_OVERLAP_UNCORRELATED_EXT, - VK_BLEND_OVERLAP_END_RANGE_EXT = VK_BLEND_OVERLAP_CONJOINT_EXT, - VK_BLEND_OVERLAP_RANGE_SIZE_EXT = (VK_BLEND_OVERLAP_CONJOINT_EXT - VK_BLEND_OVERLAP_UNCORRELATED_EXT + 1), VK_BLEND_OVERLAP_MAX_ENUM_EXT = 0x7FFFFFFF } VkBlendOverlapEXT; typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT { @@ -8099,9 +8681,6 @@ typedef enum VkCoverageModulationModeNV { VK_COVERAGE_MODULATION_MODE_RGB_NV = 1, VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2, VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3, - VK_COVERAGE_MODULATION_MODE_BEGIN_RANGE_NV = VK_COVERAGE_MODULATION_MODE_NONE_NV, - VK_COVERAGE_MODULATION_MODE_END_RANGE_NV = VK_COVERAGE_MODULATION_MODE_RGBA_NV, - VK_COVERAGE_MODULATION_MODE_RANGE_SIZE_NV = (VK_COVERAGE_MODULATION_MODE_RGBA_NV - VK_COVERAGE_MODULATION_MODE_NONE_NV + 1), VK_COVERAGE_MODULATION_MODE_MAX_ENUM_NV = 0x7FFFFFFF } VkCoverageModulationModeNV; typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV; @@ -8208,9 +8787,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) typedef enum VkValidationCacheHeaderVersionEXT { VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT = 1, - VK_VALIDATION_CACHE_HEADER_VERSION_BEGIN_RANGE_EXT = VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT, - VK_VALIDATION_CACHE_HEADER_VERSION_END_RANGE_EXT = VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT, - VK_VALIDATION_CACHE_HEADER_VERSION_RANGE_SIZE_EXT = (VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT - VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT + 1), VK_VALIDATION_CACHE_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF } VkValidationCacheHeaderVersionEXT; typedef VkFlags VkValidationCacheCreateFlagsEXT; @@ -8262,87 +8838,19 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT( #define VK_EXT_descriptor_indexing 1 #define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2 #define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing" +typedef VkDescriptorBindingFlagBits VkDescriptorBindingFlagBitsEXT; -typedef enum VkDescriptorBindingFlagBitsEXT { - VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = 0x00000001, - VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = 0x00000002, - VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = 0x00000004, - VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008, - VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDescriptorBindingFlagBitsEXT; -typedef VkFlags VkDescriptorBindingFlagsEXT; -typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t bindingCount; - const VkDescriptorBindingFlagsEXT* pBindingFlags; -} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT; +typedef VkDescriptorBindingFlags VkDescriptorBindingFlagsEXT; -typedef struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderInputAttachmentArrayDynamicIndexing; - VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; - VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; - VkBool32 shaderUniformBufferArrayNonUniformIndexing; - VkBool32 shaderSampledImageArrayNonUniformIndexing; - VkBool32 shaderStorageBufferArrayNonUniformIndexing; - VkBool32 shaderStorageImageArrayNonUniformIndexing; - VkBool32 shaderInputAttachmentArrayNonUniformIndexing; - VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; - VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; - VkBool32 descriptorBindingUniformBufferUpdateAfterBind; - VkBool32 descriptorBindingSampledImageUpdateAfterBind; - VkBool32 descriptorBindingStorageImageUpdateAfterBind; - VkBool32 descriptorBindingStorageBufferUpdateAfterBind; - VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingUpdateUnusedWhilePending; - VkBool32 descriptorBindingPartiallyBound; - VkBool32 descriptorBindingVariableDescriptorCount; - VkBool32 runtimeDescriptorArray; -} VkPhysicalDeviceDescriptorIndexingFeaturesEXT; +typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT; -typedef struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxUpdateAfterBindDescriptorsInAllPools; - VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; - VkBool32 shaderSampledImageArrayNonUniformIndexingNative; - VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; - VkBool32 shaderStorageImageArrayNonUniformIndexingNative; - VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; - VkBool32 robustBufferAccessUpdateAfterBind; - VkBool32 quadDivergentImplicitLod; - uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; - uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; - uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; - uint32_t maxPerStageUpdateAfterBindResources; - uint32_t maxDescriptorSetUpdateAfterBindSamplers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindSampledImages; - uint32_t maxDescriptorSetUpdateAfterBindStorageImages; - uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; -} VkPhysicalDeviceDescriptorIndexingPropertiesEXT; +typedef VkPhysicalDeviceDescriptorIndexingFeatures VkPhysicalDeviceDescriptorIndexingFeaturesEXT; -typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t descriptorSetCount; - const uint32_t* pDescriptorCounts; -} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT; +typedef VkPhysicalDeviceDescriptorIndexingProperties VkPhysicalDeviceDescriptorIndexingPropertiesEXT; -typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT { - VkStructureType sType; - void* pNext; - uint32_t maxVariableDescriptorCount; -} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT; +typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT; + +typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT; @@ -8368,9 +8876,6 @@ typedef enum VkShadingRatePaletteEntryNV { VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9, VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10, VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11, - VK_SHADING_RATE_PALETTE_ENTRY_BEGIN_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV, - VK_SHADING_RATE_PALETTE_ENTRY_END_RANGE_NV = VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, - VK_SHADING_RATE_PALETTE_ENTRY_RANGE_SIZE_NV = (VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV - VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV + 1), VK_SHADING_RATE_PALETTE_ENTRY_MAX_ENUM_NV = 0x7FFFFFFF } VkShadingRatePaletteEntryNV; @@ -8379,9 +8884,6 @@ typedef enum VkCoarseSampleOrderTypeNV { VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1, VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2, VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3, - VK_COARSE_SAMPLE_ORDER_TYPE_BEGIN_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV, - VK_COARSE_SAMPLE_ORDER_TYPE_END_RANGE_NV = VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV, - VK_COARSE_SAMPLE_ORDER_TYPE_RANGE_SIZE_NV = (VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV - VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV + 1), VK_COARSE_SAMPLE_ORDER_TYPE_MAX_ENUM_NV = 0x7FFFFFFF } VkCoarseSampleOrderTypeNV; typedef struct VkShadingRatePaletteNV { @@ -8458,91 +8960,127 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV( #define VK_NV_ray_tracing 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) +typedef VkAccelerationStructureKHR VkAccelerationStructureNV; + #define VK_NV_RAY_TRACING_SPEC_VERSION 3 #define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing" -#define VK_SHADER_UNUSED_NV (~0U) +#define VK_SHADER_UNUSED_KHR (~0U) +#define VK_SHADER_UNUSED_NV VK_SHADER_UNUSED_KHR -typedef enum VkAccelerationStructureTypeNV { - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = 0, - VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = 1, - VK_ACCELERATION_STRUCTURE_TYPE_BEGIN_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV, - VK_ACCELERATION_STRUCTURE_TYPE_END_RANGE_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV, - VK_ACCELERATION_STRUCTURE_TYPE_RANGE_SIZE_NV = (VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV + 1), - VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkAccelerationStructureTypeNV; +typedef enum VkRayTracingShaderGroupTypeKHR { + VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR = 0, + VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR = 1, + VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR = 2, + VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkRayTracingShaderGroupTypeKHR; +typedef VkRayTracingShaderGroupTypeKHR VkRayTracingShaderGroupTypeNV; -typedef enum VkRayTracingShaderGroupTypeNV { - VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = 0, - VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = 1, - VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = 2, - VK_RAY_TRACING_SHADER_GROUP_TYPE_BEGIN_RANGE_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV, - VK_RAY_TRACING_SHADER_GROUP_TYPE_END_RANGE_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV, - VK_RAY_TRACING_SHADER_GROUP_TYPE_RANGE_SIZE_NV = (VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV - VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV + 1), - VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkRayTracingShaderGroupTypeNV; -typedef enum VkGeometryTypeNV { - VK_GEOMETRY_TYPE_TRIANGLES_NV = 0, - VK_GEOMETRY_TYPE_AABBS_NV = 1, - VK_GEOMETRY_TYPE_BEGIN_RANGE_NV = VK_GEOMETRY_TYPE_TRIANGLES_NV, - VK_GEOMETRY_TYPE_END_RANGE_NV = VK_GEOMETRY_TYPE_AABBS_NV, - VK_GEOMETRY_TYPE_RANGE_SIZE_NV = (VK_GEOMETRY_TYPE_AABBS_NV - VK_GEOMETRY_TYPE_TRIANGLES_NV + 1), - VK_GEOMETRY_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkGeometryTypeNV; +typedef enum VkGeometryTypeKHR { + VK_GEOMETRY_TYPE_TRIANGLES_KHR = 0, + VK_GEOMETRY_TYPE_AABBS_KHR = 1, + VK_GEOMETRY_TYPE_INSTANCES_KHR = 1000150000, + VK_GEOMETRY_TYPE_TRIANGLES_NV = VK_GEOMETRY_TYPE_TRIANGLES_KHR, + VK_GEOMETRY_TYPE_AABBS_NV = VK_GEOMETRY_TYPE_AABBS_KHR, + VK_GEOMETRY_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryTypeKHR; +typedef VkGeometryTypeKHR VkGeometryTypeNV; -typedef enum VkCopyAccelerationStructureModeNV { - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = 0, - VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = 1, - VK_COPY_ACCELERATION_STRUCTURE_MODE_BEGIN_RANGE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV, - VK_COPY_ACCELERATION_STRUCTURE_MODE_END_RANGE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV, - VK_COPY_ACCELERATION_STRUCTURE_MODE_RANGE_SIZE_NV = (VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV + 1), - VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_NV = 0x7FFFFFFF -} VkCopyAccelerationStructureModeNV; -typedef enum VkAccelerationStructureMemoryRequirementsTypeNV { - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = 0, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = 1, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV = 2, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BEGIN_RANGE_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_END_RANGE_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_RANGE_SIZE_NV = (VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV + 1), - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkAccelerationStructureMemoryRequirementsTypeNV; +typedef enum VkAccelerationStructureTypeKHR { + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR = 0, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR = 1, + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, + VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureTypeKHR; +typedef VkAccelerationStructureTypeKHR VkAccelerationStructureTypeNV; -typedef enum VkGeometryFlagBitsNV { - VK_GEOMETRY_OPAQUE_BIT_NV = 0x00000001, - VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = 0x00000002, - VK_GEOMETRY_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkGeometryFlagBitsNV; -typedef VkFlags VkGeometryFlagsNV; -typedef enum VkGeometryInstanceFlagBitsNV { - VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = 0x00000001, - VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = 0x00000002, - VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = 0x00000004, - VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = 0x00000008, - VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkGeometryInstanceFlagBitsNV; -typedef VkFlags VkGeometryInstanceFlagsNV; +typedef enum VkCopyAccelerationStructureModeKHR { + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR = 0, + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR = 1, + VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR = 2, + VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR = 3, + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR, + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR, + VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkCopyAccelerationStructureModeKHR; +typedef VkCopyAccelerationStructureModeKHR VkCopyAccelerationStructureModeNV; + + +typedef enum VkAccelerationStructureMemoryRequirementsTypeKHR { + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_KHR = 0, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR = 1, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR = 2, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_KHR, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureMemoryRequirementsTypeKHR; +typedef VkAccelerationStructureMemoryRequirementsTypeKHR VkAccelerationStructureMemoryRequirementsTypeNV; + + +typedef enum VkGeometryFlagBitsKHR { + VK_GEOMETRY_OPAQUE_BIT_KHR = 0x00000001, + VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR = 0x00000002, + VK_GEOMETRY_OPAQUE_BIT_NV = VK_GEOMETRY_OPAQUE_BIT_KHR, + VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, + VK_GEOMETRY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryFlagBitsKHR; +typedef VkFlags VkGeometryFlagsKHR; +typedef VkGeometryFlagsKHR VkGeometryFlagsNV; + +typedef VkGeometryFlagBitsKHR VkGeometryFlagBitsNV; + + +typedef enum VkGeometryInstanceFlagBitsKHR { + VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001, + VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = 0x00000002, + VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004, + VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008, + VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR, + VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryInstanceFlagBitsKHR; +typedef VkFlags VkGeometryInstanceFlagsKHR; +typedef VkGeometryInstanceFlagsKHR VkGeometryInstanceFlagsNV; + +typedef VkGeometryInstanceFlagBitsKHR VkGeometryInstanceFlagBitsNV; + + +typedef enum VkBuildAccelerationStructureFlagBitsKHR { + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR = 0x00000001, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR = 0x00000002, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR = 0x00000004, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR = 0x00000008, + VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR = 0x00000010, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkBuildAccelerationStructureFlagBitsKHR; +typedef VkFlags VkBuildAccelerationStructureFlagsKHR; +typedef VkBuildAccelerationStructureFlagsKHR VkBuildAccelerationStructureFlagsNV; + +typedef VkBuildAccelerationStructureFlagBitsKHR VkBuildAccelerationStructureFlagBitsNV; -typedef enum VkBuildAccelerationStructureFlagBitsNV { - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = 0x00000001, - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = 0x00000002, - VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = 0x00000004, - VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = 0x00000008, - VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = 0x00000010, - VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkBuildAccelerationStructureFlagBitsNV; -typedef VkFlags VkBuildAccelerationStructureFlagsNV; typedef struct VkRayTracingShaderGroupCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkRayTracingShaderGroupTypeNV type; - uint32_t generalShader; - uint32_t closestHitShader; - uint32_t anyHitShader; - uint32_t intersectionShader; + VkStructureType sType; + const void* pNext; + VkRayTracingShaderGroupTypeKHR type; + uint32_t generalShader; + uint32_t closestHitShader; + uint32_t anyHitShader; + uint32_t intersectionShader; } VkRayTracingShaderGroupCreateInfoNV; typedef struct VkRayTracingPipelineCreateInfoNV { @@ -8590,11 +9128,11 @@ typedef struct VkGeometryDataNV { } VkGeometryDataNV; typedef struct VkGeometryNV { - VkStructureType sType; - const void* pNext; - VkGeometryTypeNV geometryType; - VkGeometryDataNV geometry; - VkGeometryFlagsNV flags; + VkStructureType sType; + const void* pNext; + VkGeometryTypeKHR geometryType; + VkGeometryDataNV geometry; + VkGeometryFlagsKHR flags; } VkGeometryNV; typedef struct VkAccelerationStructureInfoNV { @@ -8614,22 +9152,26 @@ typedef struct VkAccelerationStructureCreateInfoNV { VkAccelerationStructureInfoNV info; } VkAccelerationStructureCreateInfoNV; -typedef struct VkBindAccelerationStructureMemoryInfoNV { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureNV accelerationStructure; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; - uint32_t deviceIndexCount; - const uint32_t* pDeviceIndices; -} VkBindAccelerationStructureMemoryInfoNV; +typedef struct VkBindAccelerationStructureMemoryInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR accelerationStructure; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + uint32_t deviceIndexCount; + const uint32_t* pDeviceIndices; +} VkBindAccelerationStructureMemoryInfoKHR; -typedef struct VkWriteDescriptorSetAccelerationStructureNV { - VkStructureType sType; - const void* pNext; - uint32_t accelerationStructureCount; - const VkAccelerationStructureNV* pAccelerationStructures; -} VkWriteDescriptorSetAccelerationStructureNV; +typedef VkBindAccelerationStructureMemoryInfoKHR VkBindAccelerationStructureMemoryInfoNV; + +typedef struct VkWriteDescriptorSetAccelerationStructureKHR { + VkStructureType sType; + const void* pNext; + uint32_t accelerationStructureCount; + const VkAccelerationStructureKHR* pAccelerationStructures; +} VkWriteDescriptorSetAccelerationStructureKHR; + +typedef VkWriteDescriptorSetAccelerationStructureKHR VkWriteDescriptorSetAccelerationStructureNV; typedef struct VkAccelerationStructureMemoryRequirementsInfoNV { VkStructureType sType; @@ -8651,17 +9193,49 @@ typedef struct VkPhysicalDeviceRayTracingPropertiesNV { uint32_t maxDescriptorSetAccelerationStructures; } VkPhysicalDeviceRayTracingPropertiesNV; +typedef struct VkTransformMatrixKHR { + float matrix[3][4]; +} VkTransformMatrixKHR; + +typedef VkTransformMatrixKHR VkTransformMatrixNV; + +typedef struct VkAabbPositionsKHR { + float minX; + float minY; + float minZ; + float maxX; + float maxY; + float maxZ; +} VkAabbPositionsKHR; + +typedef VkAabbPositionsKHR VkAabbPositionsNV; + +typedef struct VkAccelerationStructureInstanceKHR { + VkTransformMatrixKHR transform; + uint32_t instanceCustomIndex:24; + uint32_t mask:8; + uint32_t instanceShaderBindingTableRecordOffset:24; + VkGeometryInstanceFlagsKHR flags:8; + uint64_t accelerationStructureReference; +} VkAccelerationStructureInstanceKHR; + +typedef VkAccelerationStructureInstanceKHR VkAccelerationStructureInstanceNV; + typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNV)(VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure); -typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureKHR)(VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator); typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); -typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); -typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset); -typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeNV mode); +typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryKHR)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoKHR* pBindInfos); +typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoKHR* pBindInfos); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureKHR dst, VkAccelerationStructureKHR src, VkBuffer scratch, VkDeviceSize scratchOffset); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureKHR dst, VkAccelerationStructureKHR src, VkCopyAccelerationStructureModeKHR mode); typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNV)(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, uint32_t width, uint32_t height, uint32_t depth); typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesNV)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesNV)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); -typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void* pData); -typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureNV* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNV)(VkDevice device, VkAccelerationStructureKHR accelerationStructure, size_t dataSize, void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNV)(VkDevice device, VkPipeline pipeline, uint32_t shader); #ifndef VK_NO_PROTOTYPES @@ -8671,9 +9245,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureNV( const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure); +VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureKHR( + VkDevice device, + VkAccelerationStructureKHR accelerationStructure, + const VkAllocationCallbacks* pAllocator); + VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureNV( VkDevice device, - VkAccelerationStructureNV accelerationStructure, + VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator); VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNV( @@ -8681,10 +9260,15 @@ VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNV( const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); +VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryKHR( + VkDevice device, + uint32_t bindInfoCount, + const VkBindAccelerationStructureMemoryInfoKHR* pBindInfos); + VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNV( VkDevice device, uint32_t bindInfoCount, - const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); + const VkBindAccelerationStructureMemoryInfoKHR* pBindInfos); VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNV( VkCommandBuffer commandBuffer, @@ -8692,16 +9276,16 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNV( VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, - VkAccelerationStructureNV dst, - VkAccelerationStructureNV src, + VkAccelerationStructureKHR dst, + VkAccelerationStructureKHR src, VkBuffer scratch, VkDeviceSize scratchOffset); VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNV( VkCommandBuffer commandBuffer, - VkAccelerationStructureNV dst, - VkAccelerationStructureNV src, - VkCopyAccelerationStructureModeNV mode); + VkAccelerationStructureKHR dst, + VkAccelerationStructureKHR src, + VkCopyAccelerationStructureModeKHR mode); VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNV( VkCommandBuffer commandBuffer, @@ -8728,6 +9312,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV( const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesKHR( + VkDevice device, + VkPipeline pipeline, + uint32_t firstGroup, + uint32_t groupCount, + size_t dataSize, + void* pData); + VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV( VkDevice device, VkPipeline pipeline, @@ -8738,14 +9330,22 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV( VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureHandleNV( VkDevice device, - VkAccelerationStructureNV accelerationStructure, + VkAccelerationStructureKHR accelerationStructure, size_t dataSize, void* pData); +VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesKHR( + VkCommandBuffer commandBuffer, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery); + VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesNV( VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, - const VkAccelerationStructureNV* pAccelerationStructures, + const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); @@ -8775,7 +9375,7 @@ typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV { #define VK_EXT_filter_cubic 1 -#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 2 +#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 3 #define VK_EXT_FILTER_CUBIC_EXTENSION_NAME "VK_EXT_filter_cubic" typedef struct VkPhysicalDeviceImageViewImageFormatInfoEXT { VkStructureType sType; @@ -8787,11 +9387,16 @@ typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT { VkStructureType sType; void* pNext; VkBool32 filterCubic; - VkBool32 filterCubicMinmax ; + VkBool32 filterCubicMinmax; } VkFilterCubicImageViewImageFormatPropertiesEXT; +#define VK_QCOM_render_pass_shader_resolve 1 +#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_SPEC_VERSION 4 +#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_EXTENSION_NAME "VK_QCOM_render_pass_shader_resolve" + + #define VK_EXT_global_priority 1 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 #define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" @@ -8801,9 +9406,6 @@ typedef enum VkQueueGlobalPriorityEXT { VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = 256, VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = 512, VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = 1024, - VK_QUEUE_GLOBAL_PRIORITY_BEGIN_RANGE_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT, - VK_QUEUE_GLOBAL_PRIORITY_END_RANGE_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT, - VK_QUEUE_GLOBAL_PRIORITY_RANGE_SIZE_EXT = (VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT - VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT + 1), VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_EXT = 0x7FFFFFFF } VkQueueGlobalPriorityEXT; typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT { @@ -8887,9 +9489,6 @@ typedef enum VkTimeDomainEXT { VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT = 1, VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT = 2, VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT = 3, - VK_TIME_DOMAIN_BEGIN_RANGE_EXT = VK_TIME_DOMAIN_DEVICE_EXT, - VK_TIME_DOMAIN_END_RANGE_EXT = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT, - VK_TIME_DOMAIN_RANGE_SIZE_EXT = (VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT - VK_TIME_DOMAIN_DEVICE_EXT + 1), VK_TIME_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF } VkTimeDomainEXT; typedef struct VkCalibratedTimestampInfoEXT { @@ -8948,9 +9547,6 @@ typedef enum VkMemoryOverallocationBehaviorAMD { VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0, VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1, VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_BEGIN_RANGE_AMD = VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_END_RANGE_AMD = VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_RANGE_SIZE_AMD = (VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD - VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD + 1), VK_MEMORY_OVERALLOCATION_BEHAVIOR_MAX_ENUM_AMD = 0x7FFFFFFF } VkMemoryOverallocationBehaviorAMD; typedef struct VkDeviceMemoryOverallocationCreateInfoAMD { @@ -9188,40 +9784,28 @@ typedef struct VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL { #define VK_INTEL_performance_query 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPerformanceConfigurationINTEL) -#define VK_INTEL_PERFORMANCE_QUERY_SPEC_VERSION 1 +#define VK_INTEL_PERFORMANCE_QUERY_SPEC_VERSION 2 #define VK_INTEL_PERFORMANCE_QUERY_EXTENSION_NAME "VK_INTEL_performance_query" typedef enum VkPerformanceConfigurationTypeINTEL { VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL = 0, - VK_PERFORMANCE_CONFIGURATION_TYPE_BEGIN_RANGE_INTEL = VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL, - VK_PERFORMANCE_CONFIGURATION_TYPE_END_RANGE_INTEL = VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL, - VK_PERFORMANCE_CONFIGURATION_TYPE_RANGE_SIZE_INTEL = (VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL - VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL + 1), VK_PERFORMANCE_CONFIGURATION_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkPerformanceConfigurationTypeINTEL; typedef enum VkQueryPoolSamplingModeINTEL { VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL = 0, - VK_QUERY_POOL_SAMPLING_MODE_BEGIN_RANGE_INTEL = VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL, - VK_QUERY_POOL_SAMPLING_MODE_END_RANGE_INTEL = VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL, - VK_QUERY_POOL_SAMPLING_MODE_RANGE_SIZE_INTEL = (VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL - VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL + 1), VK_QUERY_POOL_SAMPLING_MODE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkQueryPoolSamplingModeINTEL; typedef enum VkPerformanceOverrideTypeINTEL { VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL = 0, VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL = 1, - VK_PERFORMANCE_OVERRIDE_TYPE_BEGIN_RANGE_INTEL = VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL, - VK_PERFORMANCE_OVERRIDE_TYPE_END_RANGE_INTEL = VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL, - VK_PERFORMANCE_OVERRIDE_TYPE_RANGE_SIZE_INTEL = (VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL - VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL + 1), VK_PERFORMANCE_OVERRIDE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkPerformanceOverrideTypeINTEL; typedef enum VkPerformanceParameterTypeINTEL { VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL = 0, VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL = 1, - VK_PERFORMANCE_PARAMETER_TYPE_BEGIN_RANGE_INTEL = VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL, - VK_PERFORMANCE_PARAMETER_TYPE_END_RANGE_INTEL = VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL, - VK_PERFORMANCE_PARAMETER_TYPE_RANGE_SIZE_INTEL = (VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL - VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL + 1), VK_PERFORMANCE_PARAMETER_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkPerformanceParameterTypeINTEL; @@ -9231,9 +9815,6 @@ typedef enum VkPerformanceValueTypeINTEL { VK_PERFORMANCE_VALUE_TYPE_FLOAT_INTEL = 2, VK_PERFORMANCE_VALUE_TYPE_BOOL_INTEL = 3, VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL = 4, - VK_PERFORMANCE_VALUE_TYPE_BEGIN_RANGE_INTEL = VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL, - VK_PERFORMANCE_VALUE_TYPE_END_RANGE_INTEL = VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL, - VK_PERFORMANCE_VALUE_TYPE_RANGE_SIZE_INTEL = (VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL - VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL + 1), VK_PERFORMANCE_VALUE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF } VkPerformanceValueTypeINTEL; typedef union VkPerformanceValueDataINTEL { @@ -9255,11 +9836,13 @@ typedef struct VkInitializePerformanceApiInfoINTEL { void* pUserData; } VkInitializePerformanceApiInfoINTEL; -typedef struct VkQueryPoolCreateInfoINTEL { +typedef struct VkQueryPoolPerformanceQueryCreateInfoINTEL { VkStructureType sType; const void* pNext; VkQueryPoolSamplingModeINTEL performanceCountersSampling; -} VkQueryPoolCreateInfoINTEL; +} VkQueryPoolPerformanceQueryCreateInfoINTEL; + +typedef VkQueryPoolPerformanceQueryCreateInfoINTEL VkQueryPoolCreateInfoINTEL; typedef struct VkPerformanceMarkerInfoINTEL { VkStructureType sType; @@ -9406,11 +9989,7 @@ typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT { #define VK_EXT_scalar_block_layout 1 #define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1 #define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout" -typedef struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 scalarBlockLayout; -} VkPhysicalDeviceScalarBlockLayoutFeaturesEXT; +typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLayoutFeaturesEXT; @@ -9520,7 +10099,6 @@ typedef struct VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV { #define VK_EXT_buffer_device_address 1 -typedef uint64_t VkDeviceAddress; #define VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 2 #define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address" typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT { @@ -9533,11 +10111,7 @@ typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT { typedef VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkPhysicalDeviceBufferAddressFeaturesEXT; -typedef struct VkBufferDeviceAddressInfoEXT { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; -} VkBufferDeviceAddressInfoEXT; +typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoEXT; typedef struct VkBufferDeviceAddressCreateInfoEXT { VkStructureType sType; @@ -9545,37 +10119,66 @@ typedef struct VkBufferDeviceAddressCreateInfoEXT { VkDeviceAddress deviceAddress; } VkBufferDeviceAddressCreateInfoEXT; -typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfoEXT* pInfo); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( VkDevice device, - const VkBufferDeviceAddressInfoEXT* pInfo); + const VkBufferDeviceAddressInfo* pInfo); +#endif + + +#define VK_EXT_tooling_info 1 +#define VK_EXT_TOOLING_INFO_SPEC_VERSION 1 +#define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info" + +typedef enum VkToolPurposeFlagBitsEXT { + VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = 0x00000001, + VK_TOOL_PURPOSE_PROFILING_BIT_EXT = 0x00000002, + VK_TOOL_PURPOSE_TRACING_BIT_EXT = 0x00000004, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = 0x00000008, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = 0x00000010, + VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, + VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, + VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkToolPurposeFlagBitsEXT; +typedef VkFlags VkToolPurposeFlagsEXT; +typedef struct VkPhysicalDeviceToolPropertiesEXT { + VkStructureType sType; + void* pNext; + char name[VK_MAX_EXTENSION_NAME_SIZE]; + char version[VK_MAX_EXTENSION_NAME_SIZE]; + VkToolPurposeFlagsEXT purposes; + char description[VK_MAX_DESCRIPTION_SIZE]; + char layer[VK_MAX_EXTENSION_NAME_SIZE]; +} VkPhysicalDeviceToolPropertiesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT( + VkPhysicalDevice physicalDevice, + uint32_t* pToolCount, + VkPhysicalDeviceToolPropertiesEXT* pToolProperties); #endif #define VK_EXT_separate_stencil_usage 1 #define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1 #define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage" -typedef struct VkImageStencilUsageCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkImageUsageFlags stencilUsage; -} VkImageStencilUsageCreateInfoEXT; +typedef VkImageStencilUsageCreateInfo VkImageStencilUsageCreateInfoEXT; #define VK_EXT_validation_features 1 -#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 2 +#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 3 #define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features" typedef enum VkValidationFeatureEnableEXT { VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0, VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1, VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2, - VK_VALIDATION_FEATURE_ENABLE_BEGIN_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT, - VK_VALIDATION_FEATURE_ENABLE_END_RANGE_EXT = VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, - VK_VALIDATION_FEATURE_ENABLE_RANGE_SIZE_EXT = (VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT + 1), + VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3, VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF } VkValidationFeatureEnableEXT; @@ -9587,9 +10190,6 @@ typedef enum VkValidationFeatureDisableEXT { VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4, VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5, VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6, - VK_VALIDATION_FEATURE_DISABLE_BEGIN_RANGE_EXT = VK_VALIDATION_FEATURE_DISABLE_ALL_EXT, - VK_VALIDATION_FEATURE_DISABLE_END_RANGE_EXT = VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT, - VK_VALIDATION_FEATURE_DISABLE_RANGE_SIZE_EXT = (VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT - VK_VALIDATION_FEATURE_DISABLE_ALL_EXT + 1), VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF } VkValidationFeatureDisableEXT; typedef struct VkValidationFeaturesEXT { @@ -9619,9 +10219,6 @@ typedef enum VkComponentTypeNV { VK_COMPONENT_TYPE_UINT16_NV = 8, VK_COMPONENT_TYPE_UINT32_NV = 9, VK_COMPONENT_TYPE_UINT64_NV = 10, - VK_COMPONENT_TYPE_BEGIN_RANGE_NV = VK_COMPONENT_TYPE_FLOAT16_NV, - VK_COMPONENT_TYPE_END_RANGE_NV = VK_COMPONENT_TYPE_UINT64_NV, - VK_COMPONENT_TYPE_RANGE_SIZE_NV = (VK_COMPONENT_TYPE_UINT64_NV - VK_COMPONENT_TYPE_FLOAT16_NV + 1), VK_COMPONENT_TYPE_MAX_ENUM_NV = 0x7FFFFFFF } VkComponentTypeNV; @@ -9630,9 +10227,6 @@ typedef enum VkScopeNV { VK_SCOPE_WORKGROUP_NV = 2, VK_SCOPE_SUBGROUP_NV = 3, VK_SCOPE_QUEUE_FAMILY_NV = 5, - VK_SCOPE_BEGIN_RANGE_NV = VK_SCOPE_DEVICE_NV, - VK_SCOPE_END_RANGE_NV = VK_SCOPE_QUEUE_FAMILY_NV, - VK_SCOPE_RANGE_SIZE_NV = (VK_SCOPE_QUEUE_FAMILY_NV - VK_SCOPE_DEVICE_NV + 1), VK_SCOPE_MAX_ENUM_NV = 0x7FFFFFFF } VkScopeNV; typedef struct VkCooperativeMatrixPropertiesNV { @@ -9678,9 +10272,6 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesNV( typedef enum VkCoverageReductionModeNV { VK_COVERAGE_REDUCTION_MODE_MERGE_NV = 0, VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV = 1, - VK_COVERAGE_REDUCTION_MODE_BEGIN_RANGE_NV = VK_COVERAGE_REDUCTION_MODE_MERGE_NV, - VK_COVERAGE_REDUCTION_MODE_END_RANGE_NV = VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV, - VK_COVERAGE_REDUCTION_MODE_RANGE_SIZE_NV = (VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV - VK_COVERAGE_REDUCTION_MODE_MERGE_NV + 1), VK_COVERAGE_REDUCTION_MODE_MAX_ENUM_NV = 0x7FFFFFFF } VkCoverageReductionModeNV; typedef VkFlags VkPipelineCoverageReductionStateCreateFlagsNV; @@ -9770,9 +10361,6 @@ typedef enum VkLineRasterizationModeEXT { VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT = 1, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT = 2, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT = 3, - VK_LINE_RASTERIZATION_MODE_BEGIN_RANGE_EXT = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, - VK_LINE_RASTERIZATION_MODE_END_RANGE_EXT = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, - VK_LINE_RASTERIZATION_MODE_RANGE_SIZE_EXT = (VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT - VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT + 1), VK_LINE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF } VkLineRasterizationModeEXT; typedef struct VkPhysicalDeviceLineRasterizationFeaturesEXT { @@ -9814,11 +10402,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEXT( #define VK_EXT_host_query_reset 1 #define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1 #define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset" -typedef struct VkPhysicalDeviceHostQueryResetFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 hostQueryReset; -} VkPhysicalDeviceHostQueryResetFeaturesEXT; +typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFeaturesEXT; typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); @@ -9853,6 +10437,196 @@ typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT { +#define VK_NV_device_generated_commands 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNV) +#define VK_NV_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3 +#define VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NV_device_generated_commands" + +typedef enum VkIndirectCommandsTokenTypeNV { + VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV = 0, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV = 1, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV = 2, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV = 3, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV = 4, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV = 5, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV = 6, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV = 7, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectCommandsTokenTypeNV; + +typedef enum VkIndirectStateFlagBitsNV { + VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV = 0x00000001, + VK_INDIRECT_STATE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectStateFlagBitsNV; +typedef VkFlags VkIndirectStateFlagsNV; + +typedef enum VkIndirectCommandsLayoutUsageFlagBitsNV { + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV = 0x00000001, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV = 0x00000002, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV = 0x00000004, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectCommandsLayoutUsageFlagBitsNV; +typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNV; +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxGraphicsShaderGroupCount; + uint32_t maxIndirectSequenceCount; + uint32_t maxIndirectCommandsTokenCount; + uint32_t maxIndirectCommandsStreamCount; + uint32_t maxIndirectCommandsTokenOffset; + uint32_t maxIndirectCommandsStreamStride; + uint32_t minSequencesCountBufferOffsetAlignment; + uint32_t minSequencesIndexBufferOffsetAlignment; + uint32_t minIndirectCommandsBufferOffsetAlignment; +} VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV; + +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 deviceGeneratedCommands; +} VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV; + +typedef struct VkGraphicsShaderGroupCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineTessellationStateCreateInfo* pTessellationState; +} VkGraphicsShaderGroupCreateInfoNV; + +typedef struct VkGraphicsPipelineShaderGroupsCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t groupCount; + const VkGraphicsShaderGroupCreateInfoNV* pGroups; + uint32_t pipelineCount; + const VkPipeline* pPipelines; +} VkGraphicsPipelineShaderGroupsCreateInfoNV; + +typedef struct VkBindShaderGroupIndirectCommandNV { + uint32_t groupIndex; +} VkBindShaderGroupIndirectCommandNV; + +typedef struct VkBindIndexBufferIndirectCommandNV { + VkDeviceAddress bufferAddress; + uint32_t size; + VkIndexType indexType; +} VkBindIndexBufferIndirectCommandNV; + +typedef struct VkBindVertexBufferIndirectCommandNV { + VkDeviceAddress bufferAddress; + uint32_t size; + uint32_t stride; +} VkBindVertexBufferIndirectCommandNV; + +typedef struct VkSetStateFlagsIndirectCommandNV { + uint32_t data; +} VkSetStateFlagsIndirectCommandNV; + +typedef struct VkIndirectCommandsStreamNV { + VkBuffer buffer; + VkDeviceSize offset; +} VkIndirectCommandsStreamNV; + +typedef struct VkIndirectCommandsLayoutTokenNV { + VkStructureType sType; + const void* pNext; + VkIndirectCommandsTokenTypeNV tokenType; + uint32_t stream; + uint32_t offset; + uint32_t vertexBindingUnit; + VkBool32 vertexDynamicStride; + VkPipelineLayout pushconstantPipelineLayout; + VkShaderStageFlags pushconstantShaderStageFlags; + uint32_t pushconstantOffset; + uint32_t pushconstantSize; + VkIndirectStateFlagsNV indirectStateFlags; + uint32_t indexTypeCount; + const VkIndexType* pIndexTypes; + const uint32_t* pIndexTypeValues; +} VkIndirectCommandsLayoutTokenNV; + +typedef struct VkIndirectCommandsLayoutCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkIndirectCommandsLayoutUsageFlagsNV flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t tokenCount; + const VkIndirectCommandsLayoutTokenNV* pTokens; + uint32_t streamCount; + const uint32_t* pStreamStrides; +} VkIndirectCommandsLayoutCreateInfoNV; + +typedef struct VkGeneratedCommandsInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineBindPoint pipelineBindPoint; + VkPipeline pipeline; + VkIndirectCommandsLayoutNV indirectCommandsLayout; + uint32_t streamCount; + const VkIndirectCommandsStreamNV* pStreams; + uint32_t sequencesCount; + VkBuffer preprocessBuffer; + VkDeviceSize preprocessOffset; + VkDeviceSize preprocessSize; + VkBuffer sequencesCountBuffer; + VkDeviceSize sequencesCountOffset; + VkBuffer sequencesIndexBuffer; + VkDeviceSize sequencesIndexOffset; +} VkGeneratedCommandsInfoNV; + +typedef struct VkGeneratedCommandsMemoryRequirementsInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineBindPoint pipelineBindPoint; + VkPipeline pipeline; + VkIndirectCommandsLayoutNV indirectCommandsLayout; + uint32_t maxSequencesCount; +} VkGeneratedCommandsMemoryRequirementsInfoNV; + +typedef void (VKAPI_PTR *PFN_vkGetGeneratedCommandsMemoryRequirementsNV)(VkDevice device, const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkCmdPreprocessGeneratedCommandsNV)(VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteGeneratedCommandsNV)(VkCommandBuffer commandBuffer, VkBool32 isPreprocessed, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBindPipelineShaderGroupNV)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline, uint32_t groupIndex); +typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNV)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNV)(VkDevice device, VkIndirectCommandsLayoutNV indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetGeneratedCommandsMemoryRequirementsNV( + VkDevice device, + const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkCmdPreprocessGeneratedCommandsNV( + VkCommandBuffer commandBuffer, + const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdExecuteGeneratedCommandsNV( + VkCommandBuffer commandBuffer, + VkBool32 isPreprocessed, + const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindPipelineShaderGroupNV( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline, + uint32_t groupIndex); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNV( + VkDevice device, + const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNV( + VkDevice device, + VkIndirectCommandsLayoutNV indirectCommandsLayout, + const VkAllocationCallbacks* pAllocator); +#endif + + #define VK_EXT_texel_buffer_alignment 1 #define VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION 1 #define VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME "VK_EXT_texel_buffer_alignment" @@ -9873,10 +10647,174 @@ typedef struct VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT { +#define VK_QCOM_render_pass_transform 1 +#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 1 +#define VK_QCOM_RENDER_PASS_TRANSFORM_EXTENSION_NAME "VK_QCOM_render_pass_transform" +typedef struct VkRenderPassTransformBeginInfoQCOM { + VkStructureType sType; + void* pNext; + VkSurfaceTransformFlagBitsKHR transform; +} VkRenderPassTransformBeginInfoQCOM; + +typedef struct VkCommandBufferInheritanceRenderPassTransformInfoQCOM { + VkStructureType sType; + void* pNext; + VkSurfaceTransformFlagBitsKHR transform; + VkRect2D renderArea; +} VkCommandBufferInheritanceRenderPassTransformInfoQCOM; + + + +#define VK_EXT_robustness2 1 +#define VK_EXT_ROBUSTNESS_2_SPEC_VERSION 1 +#define VK_EXT_ROBUSTNESS_2_EXTENSION_NAME "VK_EXT_robustness2" +typedef struct VkPhysicalDeviceRobustness2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 robustBufferAccess2; + VkBool32 robustImageAccess2; + VkBool32 nullDescriptor; +} VkPhysicalDeviceRobustness2FeaturesEXT; + +typedef struct VkPhysicalDeviceRobustness2PropertiesEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize robustStorageBufferAccessSizeAlignment; + VkDeviceSize robustUniformBufferAccessSizeAlignment; +} VkPhysicalDeviceRobustness2PropertiesEXT; + + + +#define VK_EXT_custom_border_color 1 +#define VK_EXT_CUSTOM_BORDER_COLOR_SPEC_VERSION 12 +#define VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME "VK_EXT_custom_border_color" +typedef struct VkSamplerCustomBorderColorCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkClearColorValue customBorderColor; + VkFormat format; +} VkSamplerCustomBorderColorCreateInfoEXT; + +typedef struct VkPhysicalDeviceCustomBorderColorPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxCustomBorderColorSamplers; +} VkPhysicalDeviceCustomBorderColorPropertiesEXT; + +typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 customBorderColors; + VkBool32 customBorderColorWithoutFormat; +} VkPhysicalDeviceCustomBorderColorFeaturesEXT; + + + #define VK_GOOGLE_user_type 1 #define VK_GOOGLE_USER_TYPE_SPEC_VERSION 1 #define VK_GOOGLE_USER_TYPE_EXTENSION_NAME "VK_GOOGLE_user_type" + +#define VK_EXT_private_data 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlotEXT) +#define VK_EXT_PRIVATE_DATA_SPEC_VERSION 1 +#define VK_EXT_PRIVATE_DATA_EXTENSION_NAME "VK_EXT_private_data" + +typedef enum VkPrivateDataSlotCreateFlagBitsEXT { + VK_PRIVATE_DATA_SLOT_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPrivateDataSlotCreateFlagBitsEXT; +typedef VkFlags VkPrivateDataSlotCreateFlagsEXT; +typedef struct VkPhysicalDevicePrivateDataFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 privateData; +} VkPhysicalDevicePrivateDataFeaturesEXT; + +typedef struct VkDevicePrivateDataCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t privateDataSlotRequestCount; +} VkDevicePrivateDataCreateInfoEXT; + +typedef struct VkPrivateDataSlotCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPrivateDataSlotCreateFlagsEXT flags; +} VkPrivateDataSlotCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlotEXT* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlotEXT privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT( + VkDevice device, + const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlotEXT* pPrivateDataSlot); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT( + VkDevice device, + VkPrivateDataSlotEXT privateDataSlot, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlotEXT privateDataSlot, + uint64_t data); + +VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlotEXT privateDataSlot, + uint64_t* pData); +#endif + + +#define VK_EXT_pipeline_creation_cache_control 1 +#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION 3 +#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME "VK_EXT_pipeline_creation_cache_control" +typedef struct VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pipelineCreationCacheControl; +} VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; + + + +#define VK_NV_device_diagnostics_config 1 +#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION 1 +#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME "VK_NV_device_diagnostics_config" + +typedef enum VkDeviceDiagnosticsConfigFlagBitsNV { + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV = 0x00000001, + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV = 0x00000002, + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV = 0x00000004, + VK_DEVICE_DIAGNOSTICS_CONFIG_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkDeviceDiagnosticsConfigFlagBitsNV; +typedef VkFlags VkDeviceDiagnosticsConfigFlagsNV; +typedef struct VkPhysicalDeviceDiagnosticsConfigFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 diagnosticsConfig; +} VkPhysicalDeviceDiagnosticsConfigFeaturesNV; + +typedef struct VkDeviceDiagnosticsConfigCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkDeviceDiagnosticsConfigFlagsNV flags; +} VkDeviceDiagnosticsConfigCreateInfoNV; + + + +#define VK_QCOM_render_pass_store_ops 1 +#define VK_QCOM_render_pass_store_ops_SPEC_VERSION 2 +#define VK_QCOM_render_pass_store_ops_EXTENSION_NAME "VK_QCOM_render_pass_store_ops" + #ifdef __cplusplus } #endif diff --git a/ext/vulkan/vulkan_fuchsia.h b/ext/vulkan/vulkan_fuchsia.h index 81ebe55d31..e97901480a 100644 --- a/ext/vulkan/vulkan_fuchsia.h +++ b/ext/vulkan/vulkan_fuchsia.h @@ -2,7 +2,7 @@ #define VULKAN_FUCHSIA_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_ggp.h b/ext/vulkan/vulkan_ggp.h index fd306131c3..09b337e6dd 100644 --- a/ext/vulkan/vulkan_ggp.h +++ b/ext/vulkan/vulkan_ggp.h @@ -2,7 +2,7 @@ #define VULKAN_GGP_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_ios.h b/ext/vulkan/vulkan_ios.h index 72ef1a8a82..9f81999381 100644 --- a/ext/vulkan/vulkan_ios.h +++ b/ext/vulkan/vulkan_ios.h @@ -2,7 +2,7 @@ #define VULKAN_IOS_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_macos.h b/ext/vulkan/vulkan_macos.h index e6e5deaa36..8c9684778b 100644 --- a/ext/vulkan/vulkan_macos.h +++ b/ext/vulkan/vulkan_macos.h @@ -2,7 +2,7 @@ #define VULKAN_MACOS_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_metal.h b/ext/vulkan/vulkan_metal.h index 3dec68c771..c85d24387f 100644 --- a/ext/vulkan/vulkan_metal.h +++ b/ext/vulkan/vulkan_metal.h @@ -2,7 +2,7 @@ #define VULKAN_METAL_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_vi.h b/ext/vulkan/vulkan_vi.h index 6fb66f9dd2..ee877d9b94 100644 --- a/ext/vulkan/vulkan_vi.h +++ b/ext/vulkan/vulkan_vi.h @@ -2,7 +2,7 @@ #define VULKAN_VI_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_wayland.h b/ext/vulkan/vulkan_wayland.h index 599d05b24a..5278c188b5 100644 --- a/ext/vulkan/vulkan_wayland.h +++ b/ext/vulkan/vulkan_wayland.h @@ -2,7 +2,7 @@ #define VULKAN_WAYLAND_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_win32.h b/ext/vulkan/vulkan_win32.h index 20a1dc0e58..4408d26de4 100644 --- a/ext/vulkan/vulkan_win32.h +++ b/ext/vulkan/vulkan_win32.h @@ -2,7 +2,7 @@ #define VULKAN_WIN32_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -272,9 +272,6 @@ typedef enum VkFullScreenExclusiveEXT { VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1, VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2, VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3, - VK_FULL_SCREEN_EXCLUSIVE_BEGIN_RANGE_EXT = VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT, - VK_FULL_SCREEN_EXCLUSIVE_END_RANGE_EXT = VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT, - VK_FULL_SCREEN_EXCLUSIVE_RANGE_SIZE_EXT = (VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT - VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT + 1), VK_FULL_SCREEN_EXCLUSIVE_MAX_ENUM_EXT = 0x7FFFFFFF } VkFullScreenExclusiveEXT; typedef struct VkSurfaceFullScreenExclusiveInfoEXT { diff --git a/ext/vulkan/vulkan_xcb.h b/ext/vulkan/vulkan_xcb.h index 4cc0bc0cec..43d1407a86 100644 --- a/ext/vulkan/vulkan_xcb.h +++ b/ext/vulkan/vulkan_xcb.h @@ -2,7 +2,7 @@ #define VULKAN_XCB_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_xlib.h b/ext/vulkan/vulkan_xlib.h index ee2b48accb..7beada9257 100644 --- a/ext/vulkan/vulkan_xlib.h +++ b/ext/vulkan/vulkan_xlib.h @@ -2,7 +2,7 @@ #define VULKAN_XLIB_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. diff --git a/ext/vulkan/vulkan_xlib_xrandr.h b/ext/vulkan/vulkan_xlib_xrandr.h index 08c4fd729c..8e9e150d84 100644 --- a/ext/vulkan/vulkan_xlib_xrandr.h +++ b/ext/vulkan/vulkan_xlib_xrandr.h @@ -2,7 +2,7 @@ #define VULKAN_XLIB_XRANDR_H_ 1 /* -** Copyright (c) 2015-2019 The Khronos Group Inc. +** Copyright (c) 2015-2020 The Khronos Group Inc. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. From 90ff382c59f1fd0588fd980d24922dd2ce31ecb9 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 2 Aug 2020 08:49:58 +0700 Subject: [PATCH 405/848] Rearranged network's After PSPAction creation/registration so that newer one have higher value to prevent network's callbacks triggering the wrong after action after loading from old save state. --- Core/HLE/sceNet.cpp | 17 +++++++++++++---- Core/HLE/sceNetAdhoc.cpp | 6 ------ Core/HLE/sceNetAdhoc.h | 5 +++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 6661821202..d9215a9ddb 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -141,10 +141,6 @@ void __NetApctlInit() { netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; apctlHandlers.clear(); memset(&netApctlInfo, 0, sizeof(netApctlInfo)); - - // Init Apctl Callbacks - apctlThreadHackAddr = __CreateHLELoop(apctlThreadCode, "sceNetApctl", "__NetApctlCallbacks", "apctlThreadHack"); - actionAfterApctlMipsCall = __KernelRegisterActionType(AfterApctlMipsCall::Create); } static void __ResetInitNetLib() { @@ -155,6 +151,18 @@ static void __ResetInitNetLib() { memset(¶meter, 0, sizeof(parameter)); } +void __NetCallbackInit() { + // Init Network Callbacks + dummyThreadHackAddr = __CreateHLELoop(dummyThreadCode, "sceNetAdhoc", "__NetTriggerCallbacks", "dummythreadhack"); + matchingThreadHackAddr = __CreateHLELoop(matchingThreadCode, "sceNetAdhocMatching", "__NetMatchingCallbacks", "matchingThreadHack"); + apctlThreadHackAddr = __CreateHLELoop(apctlThreadCode, "sceNetApctl", "__NetApctlCallbacks", "apctlThreadHack"); + + // Newer one should be placed last to prevent callbacks going to the wrong after action after loading from old save state + actionAfterMatchingMipsCall = __KernelRegisterActionType(AfterMatchingMipsCall::Create); + actionAfterAdhocMipsCall = __KernelRegisterActionType(AfterAdhocMipsCall::Create); + actionAfterApctlMipsCall = __KernelRegisterActionType(AfterApctlMipsCall::Create); +} + void __NetInit() { // Windows: Assuming WSAStartup already called beforehand portOffset = g_Config.iPortOffset; @@ -172,6 +180,7 @@ void __NetInit() { __ResetInitNetLib(); __NetApctlInit(); + __NetCallbackInit(); } void __NetApctlShutdown() { diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index f9a0fad274..b7fafe3a18 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -199,12 +199,6 @@ void __NetAdhocInit() { adhocctlHandlers.clear(); __AdhocServerInit(); - // Init Adhoc Callbacks - dummyThreadHackAddr = __CreateHLELoop(dummyThreadCode, "sceNetAdhoc", "__NetTriggerCallbacks", "dummythreadhack"); - matchingThreadHackAddr = __CreateHLELoop(matchingThreadCode, "sceNetAdhocMatching", "__NetMatchingCallbacks", "matchingThreadHack"); - actionAfterMatchingMipsCall = __KernelRegisterActionType(AfterMatchingMipsCall::Create); - actionAfterAdhocMipsCall = __KernelRegisterActionType(AfterAdhocMipsCall::Create); - // Create built-in AdhocServer Thread if (g_Config.bEnableWlan && g_Config.bEnableAdhocServer) { adhocServerRunning = true; diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 3125294470..68fb4e2bcc 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -55,6 +55,11 @@ extern int adhocEventDelayMS; // This will affect the duration of "Connecting... extern std::recursive_mutex adhocEvtMtx; extern int IsAdhocctlInCB; +extern u32 dummyThreadHackAddr; +extern u32_le dummyThreadCode[3]; +extern u32 matchingThreadHackAddr; +extern u32_le matchingThreadCode[3]; + int NetAdhocMatching_Term(); int NetAdhocctl_Term(); int NetAdhoc_Term(); From 5f550fdf73b08f2f804e1f249f50477f8f4d05b0 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 2 Aug 2020 09:50:37 +0700 Subject: [PATCH 406/848] Lowering minVer of AfterAdhocMipsCall section. --- Core/HLE/proAdhoc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 69be2a20bf..92fc3d8594 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -793,7 +793,7 @@ public: AfterAdhocMipsCall() {} static PSPAction* Create() { return new AfterAdhocMipsCall(); } void DoState(PointerWrap& p) override { - auto s = p.Section("AfterAdhocMipsCall", 3, 4); + auto s = p.Section("AfterAdhocMipsCall", 1, 4); if (!s) return; if (s >= 3) { From 5ff75f4ca805d3b72e7934f58f6199b5c1173582 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Aug 2020 21:26:41 -0700 Subject: [PATCH 407/848] UI: Add setting for texture upload shader. --- Core/Config.cpp | 1 + Core/Config.h | 1 + GPU/Common/PostShader.cpp | 47 ++++++++++++++++++++++++++++++++---- GPU/Common/PostShader.h | 18 ++++++++++++++ UI/GameSettingsScreen.cpp | 50 ++++++++++++++++++++++++++++++++++++--- UI/GameSettingsScreen.h | 2 ++ UI/MiscScreens.cpp | 20 ++++++++++++++++ UI/MiscScreens.h | 11 +++++++++ 8 files changed, 143 insertions(+), 7 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 0a4ada08f4..2a696abaf4 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -798,6 +798,7 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("SplineBezierQuality", &g_Config.iSplineBezierQuality, 2, true, true), ReportedConfigSetting("HardwareTessellation", &g_Config.bHardwareTessellation, false, true, true), ReportedConfigSetting("PostShader", &g_Config.sPostShaderName, "Off", true, true), + ConfigSetting("TextureShader", &g_Config.sTextureShaderName, "Off", true, true), ReportedConfigSetting("MemBlockTransferGPU", &g_Config.bBlockTransferGPU, true, true, true), ReportedConfigSetting("DisableSlowFramebufEffects", &g_Config.bDisableSlowFramebufEffects, false, true, true), diff --git a/Core/Config.h b/Core/Config.h index 497e7eae20..d288f62305 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -209,6 +209,7 @@ public: int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High bool bHardwareTessellation; std::string sPostShaderName; // Off for off. + std::string sTextureShaderName; std::map mPostShaderSetting; bool bGfxDebugOutput; bool bGfxDebugSplitSubmit; diff --git a/GPU/Common/PostShader.cpp b/GPU/Common/PostShader.cpp index c8aacbf843..5c24d48ee3 100644 --- a/GPU/Common/PostShader.cpp +++ b/GPU/Common/PostShader.cpp @@ -31,11 +31,12 @@ #include "GPU/Common/PostShader.h" static std::vector shaderInfo; +// Okay, not really "post" shaders, but related. +static std::vector textureShaderInfo; // Scans the directories for shader ini files and collects info about all the shaders found. -// Additionally, scan the VFS assets. (TODO) -void LoadPostShaderInfo(std::vector directories) { +void LoadPostShaderInfo(const std::vector &directories) { std::vector notVisible; shaderInfo.clear(); @@ -52,6 +53,12 @@ void LoadPostShaderInfo(std::vector directories) { } shaderInfo.push_back(off); + textureShaderInfo.clear(); + TextureShaderInfo textureOff{}; + textureOff.name = "Off"; + textureOff.section = "Off"; + textureShaderInfo.push_back(textureOff); + auto appendShader = [&](const ShaderInfo &info) { auto beginErase = std::remove(shaderInfo.begin(), shaderInfo.end(), info.name); if (beginErase != shaderInfo.end()) { @@ -60,12 +67,19 @@ void LoadPostShaderInfo(std::vector directories) { shaderInfo.push_back(info); }; + auto appendTextureShader = [&](const TextureShaderInfo &info) { + auto beginErase = std::remove(textureShaderInfo.begin(), textureShaderInfo.end(), info.name); + if (beginErase != textureShaderInfo.end()) { + textureShaderInfo.erase(beginErase, textureShaderInfo.end()); + } + textureShaderInfo.push_back(info); + }; + for (size_t d = 0; d < directories.size(); d++) { std::vector fileInfo; getFilesInDir(directories[d].c_str(), &fileInfo, "ini:"); if (fileInfo.size() == 0) { - // TODO: Really gotta fix the filter, now it's gonna open shaders as ini files.. VFSGetFileListing(directories[d].c_str(), &fileInfo, "ini:"); } @@ -90,7 +104,10 @@ void LoadPostShaderInfo(std::vector directories) { // Alright, let's loop through the sections and see if any is a shader. for (size_t i = 0; i < ini.Sections().size(); i++) { IniFile::Section §ion = ini.Sections()[i]; - if (section.Exists("Fragment") && section.Exists("Vertex")) { + std::string shaderType; + section.Get("Type", &shaderType, "render"); + + if (section.Exists("Fragment") && section.Exists("Vertex") && strncasecmp(shaderType.c_str(), "render", shaderType.size()) == 0) { // Valid shader! ShaderInfo info; std::string temp; @@ -135,6 +152,16 @@ void LoadPostShaderInfo(std::vector directories) { } else { notVisible.push_back(info); } + } else if (section.Exists("Compute") && strncasecmp(shaderType.c_str(), "texture", shaderType.size()) == 0) { + // This is a texture shader. + TextureShaderInfo info; + std::string temp; + info.section = section.name(); + section.Get("Name", &info.name, section.name().c_str()); + section.Get("Compute", &temp, ""); + info.computeShaderFile = path + "/" + temp; + + appendTextureShader(info); } } } @@ -189,3 +216,15 @@ std::vector GetPostShaderChain(const std::string &name) { const std::vector &GetAllPostShaderInfo() { return shaderInfo; } + +const TextureShaderInfo *GetTextureShaderInfo(const std::string &name) { + for (auto &info : textureShaderInfo) { + if (info.section == name) { + return &info; + } + } + return nullptr; +} +const std::vector &GetAllTextureShaderInfo() { + return textureShaderInfo; +} diff --git a/GPU/Common/PostShader.h b/GPU/Common/PostShader.h index 86fd7b77da..4f01d728f9 100644 --- a/GPU/Common/PostShader.h +++ b/GPU/Common/PostShader.h @@ -64,8 +64,26 @@ struct ShaderInfo { } }; +struct TextureShaderInfo { + std::string iniFile; + std::string section; + std::string name; + + std::string computeShaderFile; + + bool operator == (const std::string &other) { + return name == other; + } + bool operator == (const TextureShaderInfo &other) { + return name == other.name; + } +}; + void ReloadAllPostShaderInfo(); const ShaderInfo *GetPostShaderInfo(const std::string &name); std::vector GetPostShaderChain(const std::string &name); const std::vector &GetAllPostShaderInfo(); + +const TextureShaderInfo *GetTextureShaderInfo(const std::string &name); +const std::vector &GetAllTextureShaderInfo(); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index a9ae9f891f..d3846ba413 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -112,6 +112,21 @@ bool DoesBackendSupportHWTess() { } } +static bool UsingHardwareTextureScaling() { + // For now, Vulkan only. + return g_Config.bTexHardwareScaling && GetGPUBackend() == GPUBackend::VULKAN && !g_Config.bSoftwareRendering; +} + +static std::string TextureTranslateName(const char *value) { + auto ps = GetI18NCategory("TextureShaders"); + const TextureShaderInfo *info = GetTextureShaderInfo(value); + if (info) { + return ps->T(value, info ? info->name.c_str() : value); + } else { + return value; + } +} + static std::string PostShaderTranslateName(const char *value) { auto ps = GetI18NCategory("PostShaders"); const ShaderInfo *info = GetPostShaderInfo(value); @@ -450,7 +465,7 @@ void GameSettingsScreen::CreateViews() { texScalingChoice->HideChoice(5); // 5x } texScalingChoice->OnChoice.Add([=](EventParams &e) { - if (g_Config.iTexScalingLevel != 1) { + if (g_Config.iTexScalingLevel != 1 && !UsingHardwareTextureScaling()) { settingInfo_->Show(gr->T("UpscaleLevel Tip", "CPU heavy - some scaling may be delayed to avoid stutter"), e.v); } return UI::EVENT_CONTINUE; @@ -459,7 +474,9 @@ void GameSettingsScreen::CreateViews() { static const char *texScaleAlgos[] = { "xBRZ", "Hybrid", "Bicubic", "Hybrid + Bicubic", }; PopupMultiChoice *texScalingType = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iTexScalingType, gr->T("Upscale Type"), texScaleAlgos, 0, ARRAY_SIZE(texScaleAlgos), gr->GetName(), screenManager())); - texScalingType->SetDisabledPtr(&g_Config.bSoftwareRendering); + texScalingType->SetEnabledFunc([]() { + return !g_Config.bSoftwareRendering && !UsingHardwareTextureScaling(); + }); CheckBox *deposterize = graphicsSettings->Add(new CheckBox(&g_Config.bTexDeposterize, gr->T("Deposterize"))); deposterize->OnClick.Add([=](EventParams &e) { @@ -468,7 +485,18 @@ void GameSettingsScreen::CreateViews() { } return UI::EVENT_CONTINUE; }); - deposterize->SetDisabledPtr(&g_Config.bSoftwareRendering); + deposterize->SetEnabledFunc([]() { + return !g_Config.bSoftwareRendering && !UsingHardwareTextureScaling(); + }); + + CheckBox *texHardwareScaling = graphicsSettings->Add(new CheckBox(&g_Config.bTexHardwareScaling, gr->T("Hardware texture scaling"))); + texHardwareScaling->SetEnabledFunc([]() { + return GetGPUBackend() == GPUBackend::VULKAN && !g_Config.bSoftwareRendering; + }); + + ChoiceWithValueDisplay *textureShaderChoice = graphicsSettings->Add(new ChoiceWithValueDisplay(&g_Config.sTextureShaderName, gr->T("Texture Shader"), &TextureTranslateName)); + textureShaderChoice->OnClick.Handle(this, &GameSettingsScreen::OnTextureShader); + textureShaderChoice->SetEnabledFunc(UsingHardwareTextureScaling); graphicsSettings->Add(new ItemHeader(gr->T("Texture Filtering"))); static const char *anisoLevels[] = { "Off", "2x", "4x", "8x", "16x" }; @@ -1460,6 +1488,22 @@ UI::EventReturn GameSettingsScreen::OnPostProcShaderChange(UI::EventParams &e) { return UI::EVENT_DONE; } +UI::EventReturn GameSettingsScreen::OnTextureShader(UI::EventParams &e) { + auto gr = GetI18NCategory("Graphics"); + auto shaderScreen = new TextureShaderScreen(gr->T("Texture Shader")); + shaderScreen->OnChoice.Handle(this, &GameSettingsScreen::OnTextureShaderChange); + if (e.v) + shaderScreen->SetPopupOrigin(e.v); + screenManager()->push(shaderScreen); + return UI::EVENT_DONE; +} + +UI::EventReturn GameSettingsScreen::OnTextureShaderChange(UI::EventParams &e) { + NativeMessageReceived("gpu_resized", ""); + RecreateViews(); // Update setting name + return UI::EVENT_DONE; +} + UI::EventReturn GameSettingsScreen::OnDeveloperTools(UI::EventParams &e) { screenManager()->push(new DeveloperToolsScreen()); return UI::EVENT_DONE; diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index f2f27bc206..3b0859e0d0 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -82,6 +82,8 @@ private: UI::EventReturn OnAutoFrameskip(UI::EventParams &e); UI::EventReturn OnPostProcShader(UI::EventParams &e); UI::EventReturn OnPostProcShaderChange(UI::EventParams &e); + UI::EventReturn OnTextureShader(UI::EventParams &e); + UI::EventReturn OnTextureShaderChange(UI::EventParams &e); UI::EventReturn OnDeveloperTools(UI::EventParams &e); UI::EventReturn OnRemoteISO(UI::EventParams &e); UI::EventReturn OnChangeQuickChat0(UI::EventParams &e); diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index a6542c65d0..e88e244829 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -321,6 +321,26 @@ void PostProcScreen::OnCompleted(DialogResult result) { g_Config.sPostShaderName = shaders_[listView_->GetSelected()].section; } +TextureShaderScreen::TextureShaderScreen(const std::string &title) : ListPopupScreen(title) { + auto ps = GetI18NCategory("TextureShaders"); + ReloadAllPostShaderInfo(); + shaders_ = GetAllTextureShaderInfo(); + std::vector items; + int selected = -1; + for (int i = 0; i < (int)shaders_.size(); i++) { + if (shaders_[i].section == g_Config.sTextureShaderName) + selected = i; + items.push_back(ps->T(shaders_[i].section.c_str(), shaders_[i].name.c_str())); + } + adaptor_ = UI::StringVectorListAdaptor(items, selected); +} + +void TextureShaderScreen::OnCompleted(DialogResult result) { + if (result != DR_OK) + return; + g_Config.sTextureShaderName = shaders_[listView_->GetSelected()].section; +} + NewLanguageScreen::NewLanguageScreen(const std::string &title) : ListPopupScreen(title) { // Disable annoying encoding warning #ifdef _MSC_VER diff --git a/UI/MiscScreens.h b/UI/MiscScreens.h index 459974de48..b1c5881bc4 100644 --- a/UI/MiscScreens.h +++ b/UI/MiscScreens.h @@ -26,6 +26,7 @@ #include "ui/ui_screen.h" struct ShaderInfo; +struct TextureShaderInfo; extern std::string boot_filename; void UIBackgroundInit(UIContext &dc); @@ -112,6 +113,16 @@ private: std::vector shaders_; }; +class TextureShaderScreen : public ListPopupScreen { +public: + TextureShaderScreen(const std::string &title); + +private: + void OnCompleted(DialogResult result) override; + bool ShowButtons() const override { return true; } + std::vector shaders_; +}; + class LogoScreen : public UIScreen { public: LogoScreen(bool gotoGameSettings = false) From d99e67a061af473c855831945f44896f46f2f8dd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Aug 2020 22:00:04 -0700 Subject: [PATCH 408/848] Vulkan: Allow custom texture upscaling shaders. Let's not just hardcode. --- GPU/Common/TextureCacheCommon.h | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 347 +++++------------------------- GPU/Vulkan/TextureCacheVulkan.h | 5 + assets/shaders/defaultshaders.ini | 6 +- assets/shaders/tex_4xbrz.csh | 279 ++++++++++++++++++++++++ 5 files changed, 342 insertions(+), 297 deletions(-) create mode 100644 assets/shaders/tex_4xbrz.csh diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 13bfa647e6..166f378b26 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -198,7 +198,7 @@ public: // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to. void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg); - void NotifyConfigChanged(); + virtual void NotifyConfigChanged(); void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt); int AttachedDrawingHeight(); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 57068030f5..b46ca05710 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -19,6 +19,7 @@ #include #include "ext/xxhash.h" +#include "file/vfs.h" #include "i18n/i18n.h" #include "math/math_util.h" #include "profiler/profiler.h" @@ -38,6 +39,7 @@ #include "GPU/ge_constants.h" #include "GPU/GPUState.h" +#include "GPU/Common/PostShader.h" #include "GPU/Common/TextureCacheCommon.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/Vulkan/TextureCacheVulkan.h" @@ -62,288 +64,6 @@ static const VkComponentMapping VULKAN_1555_SWIZZLE = { VK_COMPONENT_SWIZZLE_B, static const VkComponentMapping VULKAN_565_SWIZZLE = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; static const VkComponentMapping VULKAN_8888_SWIZZLE = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; -// 4xBRZ shader - Copyright (C) 2014-2016 DeSmuME team (GPL2+) -// Hyllian's xBR-vertex code and texel mapping -// Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com -const char *shader4xbrz = R"( -#define BLEND_ALPHA 1 -#define BLEND_NONE 0 -#define BLEND_NORMAL 1 -#define BLEND_DOMINANT 2 -#define LUMINANCE_WEIGHT 1.0 -#define EQUAL_COLOR_TOLERANCE 30.0/255.0 -#define STEEP_DIRECTION_THRESHOLD 2.2 -#define DOMINANT_DIRECTION_THRESHOLD 3.6 - -float reduce(vec4 color) { - return dot(color.rgb, vec3(65536.0, 256.0, 1.0)); -} - -float DistYCbCr(vec4 pixA, vec4 pixB) { - // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion - const vec3 K = vec3(0.2627, 0.6780, 0.0593); - const mat3 MATRIX = mat3(K, - -.5 * K.r / (1.0 - K.b), -.5 * K.g / (1.0 - K.b), .5, - .5, -.5 * K.g / (1.0 - K.r), -.5 * K.b / (1.0 - K.r)); - vec4 diff = pixA - pixB; - vec3 YCbCr = diff.rgb * MATRIX; - YCbCr.x *= LUMINANCE_WEIGHT; - float d = length(YCbCr); - return sqrt(pixA.a * pixB.a * d * d + diff.a * diff.a); -} - -bool IsPixEqual(const vec4 pixA, const vec4 pixB) { - return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE); -} - -bool IsBlendingNeeded(const ivec4 blend) { - ivec4 diff = blend - ivec4(BLEND_NONE); - return diff.x != 0 || diff.y != 0 || diff.z != 0 || diff.w != 0; -} - -vec4 applyScalingf(uvec2 origxy, uvec2 xy) { - float dx = 1.0 / params.width; - float dy = 1.0 / params.height; - - // A1 B1 C1 - // A0 A B C C4 - // D0 D E F F4 - // G0 G H I I4 - // G5 H5 I5 - - uvec4 t1 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y - 2); // A1 B1 C1 - uvec4 t2 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y - 1); // A B C - uvec4 t3 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y + 0); // D E F - uvec4 t4 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y + 1); // G H I - uvec4 t5 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y + 2); // G5 H5 I5 - uvec4 t6 = uvec4(origxy.x - 2, origxy.y - 1, origxy.y, origxy.y + 1); // A0 D0 G0 - uvec4 t7 = uvec4(origxy.x + 2, origxy.y - 1, origxy.y, origxy.y + 1); // C4 F4 I4 - - vec2 f = fract(vec2(float(xy.x) / float(params.scale), float(xy.y) / float(params.scale))); - - //--------------------------------------- - // Input Pixel Mapping: |21|22|23| - // 19|06|07|08|09 - // 18|05|00|01|10 - // 17|04|03|02|11 - // |15|14|13| - - vec4 src[25]; - - src[21] = readColorf(t1.xw); - src[22] = readColorf(t1.yw); - src[23] = readColorf(t1.zw); - src[ 6] = readColorf(t2.xw); - src[ 7] = readColorf(t2.yw); - src[ 8] = readColorf(t2.zw); - src[ 5] = readColorf(t3.xw); - src[ 0] = readColorf(t3.yw); - src[ 1] = readColorf(t3.zw); - src[ 4] = readColorf(t4.xw); - src[ 3] = readColorf(t4.yw); - src[ 2] = readColorf(t4.zw); - src[15] = readColorf(t5.xw); - src[14] = readColorf(t5.yw); - src[13] = readColorf(t5.zw); - src[19] = readColorf(t6.xy); - src[18] = readColorf(t6.xz); - src[17] = readColorf(t6.xw); - src[ 9] = readColorf(t7.xy); - src[10] = readColorf(t7.xz); - src[11] = readColorf(t7.xw); - - float v[9]; - v[0] = reduce(src[0]); - v[1] = reduce(src[1]); - v[2] = reduce(src[2]); - v[3] = reduce(src[3]); - v[4] = reduce(src[4]); - v[5] = reduce(src[5]); - v[6] = reduce(src[6]); - v[7] = reduce(src[7]); - v[8] = reduce(src[8]); - - ivec4 blendResult = ivec4(BLEND_NONE); - - // Preprocess corners - // Pixel Tap Mapping: --|--|--|--|-- - // --|--|07|08|-- - // --|05|00|01|10 - // --|04|03|02|11 - // --|--|14|13|-- - // Corner (1, 1) - if ( ((v[0] == v[1] && v[3] == v[2]) || (v[0] == v[3] && v[1] == v[2])) == false) { - float dist_03_01 = DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + DistYCbCr(src[14], src[ 2]) + DistYCbCr(src[ 2], src[10]) + (4.0 * DistYCbCr(src[ 3], src[ 1])); - float dist_00_02 = DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[ 3], src[13]) + DistYCbCr(src[ 7], src[ 1]) + DistYCbCr(src[ 1], src[11]) + (4.0 * DistYCbCr(src[ 0], src[ 2])); - bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_03_01) < dist_00_02; - blendResult[2] = ((dist_03_01 < dist_00_02) && (v[0] != v[1]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; - } - - // Pixel Tap Mapping: --|--|--|--|-- - // --|06|07|--|-- - // 18|05|00|01|-- - // 17|04|03|02|-- - // --|15|14|--|-- - // Corner (0, 1) - if ( ((v[5] == v[0] && v[4] == v[3]) || (v[5] == v[4] && v[0] == v[3])) == false) { - float dist_04_00 = DistYCbCr(src[17], src[ 5]) + DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[15], src[ 3]) + DistYCbCr(src[ 3], src[ 1]) + (4.0 * DistYCbCr(src[ 4], src[ 0])); - float dist_05_03 = DistYCbCr(src[18], src[ 4]) + DistYCbCr(src[ 4], src[14]) + DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + (4.0 * DistYCbCr(src[ 5], src[ 3])); - bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_03) < dist_04_00; - blendResult[3] = ((dist_04_00 > dist_05_03) && (v[0] != v[5]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; - } - - // Pixel Tap Mapping: --|--|22|23|-- - // --|06|07|08|09 - // --|05|00|01|10 - // --|--|03|02|-- - // --|--|--|--|-- - // Corner (1, 0) - if ( ((v[7] == v[8] && v[0] == v[1]) || (v[7] == v[0] && v[8] == v[1])) == false) { - float dist_00_08 = DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[ 7], src[23]) + DistYCbCr(src[ 3], src[ 1]) + DistYCbCr(src[ 1], src[ 9]) + (4.0 * DistYCbCr(src[ 0], src[ 8])); - float dist_07_01 = DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + DistYCbCr(src[22], src[ 8]) + DistYCbCr(src[ 8], src[10]) + (4.0 * DistYCbCr(src[ 7], src[ 1])); - bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_07_01) < dist_00_08; - blendResult[1] = ((dist_00_08 > dist_07_01) && (v[0] != v[7]) && (v[0] != v[1])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; - } - - // Pixel Tap Mapping: --|21|22|--|-- - // 19|06|07|08|-- - // 18|05|00|01|-- - // --|04|03|--|-- - // --|--|--|--|-- - // Corner (0, 0) - if ( ((v[6] == v[7] && v[5] == v[0]) || (v[6] == v[5] && v[7] == v[0])) == false) { - float dist_05_07 = DistYCbCr(src[18], src[ 6]) + DistYCbCr(src[ 6], src[22]) + DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + (4.0 * DistYCbCr(src[ 5], src[ 7])); - float dist_06_00 = DistYCbCr(src[19], src[ 5]) + DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[21], src[ 7]) + DistYCbCr(src[ 7], src[ 1]) + (4.0 * DistYCbCr(src[ 6], src[ 0])); - bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_07) < dist_06_00; - blendResult[0] = ((dist_05_07 < dist_06_00) && (v[0] != v[5]) && (v[0] != v[7])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; - } - - vec4 dst[16]; - dst[ 0] = src[0]; - dst[ 1] = src[0]; - dst[ 2] = src[0]; - dst[ 3] = src[0]; - dst[ 4] = src[0]; - dst[ 5] = src[0]; - dst[ 6] = src[0]; - dst[ 7] = src[0]; - dst[ 8] = src[0]; - dst[ 9] = src[0]; - dst[10] = src[0]; - dst[11] = src[0]; - dst[12] = src[0]; - dst[13] = src[0]; - dst[14] = src[0]; - dst[15] = src[0]; - - // Scale pixel - if (IsBlendingNeeded(blendResult) == true) { - float dist_01_04 = DistYCbCr(src[1], src[4]); - float dist_03_08 = DistYCbCr(src[3], src[8]); - bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[4]) && (v[5] != v[4]); - bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[8]) && (v[7] != v[8]); - bool needBlend = (blendResult[2] != BLEND_NONE); - bool doLineBlend = ( blendResult[2] >= BLEND_DOMINANT || - ((blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) || - (blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) || - (IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[0], src[2]) == false) ) == false ); - - vec4 blendPix = ( DistYCbCr(src[0], src[1]) <= DistYCbCr(src[0], src[3]) ) ? src[1] : src[3]; - dst[ 2] = mix(dst[ 2], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); - dst[ 9] = mix(dst[ 9], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); - dst[10] = mix(dst[10], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); - dst[11] = mix(dst[11], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); - dst[12] = mix(dst[12], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); - dst[13] = mix(dst[13], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); - dst[14] = mix(dst[14], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); - dst[15] = mix(dst[15], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); - - dist_01_04 = DistYCbCr(src[7], src[2]); - dist_03_08 = DistYCbCr(src[1], src[6]); - haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[2]) && (v[3] != v[2]); - haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[6]) && (v[5] != v[6]); - needBlend = (blendResult[1] != BLEND_NONE); - doLineBlend = ( blendResult[1] >= BLEND_DOMINANT || - !((blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || - (blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || - (IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && !IsPixEqual(src[0], src[8])) ) ); - - blendPix = ( DistYCbCr(src[0], src[7]) <= DistYCbCr(src[0], src[1]) ) ? src[7] : src[1]; - dst[ 1] = mix(dst[ 1], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); - dst[ 6] = mix(dst[ 6], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); - dst[ 7] = mix(dst[ 7], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); - dst[ 8] = mix(dst[ 8], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); - dst[ 9] = mix(dst[ 9], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); - dst[10] = mix(dst[10], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); - dst[11] = mix(dst[11], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); - dst[12] = mix(dst[12], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); - - dist_01_04 = DistYCbCr(src[5], src[8]); - dist_03_08 = DistYCbCr(src[7], src[4]); - haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[8]) && (v[1] != v[8]); - haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[4]) && (v[3] != v[4]); - needBlend = (blendResult[0] != BLEND_NONE); - doLineBlend = ( blendResult[0] >= BLEND_DOMINANT || - !((blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) || - (blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) || - (IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && !IsPixEqual(src[0], src[6])) ) ); - - blendPix = ( DistYCbCr(src[0], src[5]) <= DistYCbCr(src[0], src[7]) ) ? src[5] : src[7]; - dst[ 0] = mix(dst[ 0], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); - dst[15] = mix(dst[15], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); - dst[ 4] = mix(dst[ 4], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); - dst[ 5] = mix(dst[ 5], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); - dst[ 6] = mix(dst[ 6], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); - dst[ 7] = mix(dst[ 7], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); - dst[ 8] = mix(dst[ 8], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); - dst[ 9] = mix(dst[ 9], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); - - dist_01_04 = DistYCbCr(src[3], src[6]); - dist_03_08 = DistYCbCr(src[5], src[2]); - haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[6]) && (v[7] != v[6]); - haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[2]) && (v[1] != v[2]); - needBlend = (blendResult[3] != BLEND_NONE); - doLineBlend = ( blendResult[3] >= BLEND_DOMINANT || - !((blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || - (blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || - (IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && !IsPixEqual(src[0], src[4])) ) ); - - blendPix = ( DistYCbCr(src[0], src[3]) <= DistYCbCr(src[0], src[5]) ) ? src[3] : src[5]; - dst[ 3] = mix(dst[ 3], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); - dst[12] = mix(dst[12], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); - dst[13] = mix(dst[13], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); - dst[14] = mix(dst[14], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); - dst[15] = mix(dst[15], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); - dst[ 4] = mix(dst[ 4], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); - dst[ 5] = mix(dst[ 5], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); - dst[ 6] = mix(dst[ 6], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); - } - - // select output pixel - vec4 res = mix(mix(mix(mix(dst[ 6], dst[ 7], step(0.25, f.x)), - mix(dst[ 8], dst[ 9], step(0.75, f.x)), - step(0.50, f.x)), - mix(mix(dst[ 5], dst[ 0], step(0.25, f.x)), - mix(dst[ 1], dst[10], step(0.75, f.x)), - step(0.50, f.x)), - step(0.25, f.y)), - mix(mix(mix(dst[ 4], dst[ 3], step(0.25, f.x)), - mix(dst[ 2], dst[11], step(0.75, f.x)), - step(0.50, f.x)), - mix(mix(dst[15], dst[14], step(0.25, f.x)), - mix(dst[13], dst[12], step(0.75, f.x)), - step(0.50, f.x)), - step(0.75, f.y)), - step(0.50, f.y)); - - return res; -} - -uint applyScalingu(uvec2 origxy, uvec2 xy) { - return packUnorm4x8(applyScalingf(origxy, xy)); -} -)"; - const char *copyShader = R"( #version 450 #extension GL_ARB_separate_shader_objects : enable @@ -645,20 +365,55 @@ void TextureCacheVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &samplerNearest_); - std::string error; - std::string fullUploadShader = StringFromFormat(uploadShader, shader4xbrz); - std::string fullCopyShader = StringFromFormat(copyShader, shader4xbrz); - - if (g_Config.bTexHardwareScaling) { - uploadCS_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_COMPUTE_BIT, fullUploadShader.c_str(), &error); - _dbg_assert_msg_(uploadCS_ != VK_NULL_HANDLE, "failed to compile upload shader"); - copyCS_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_COMPUTE_BIT, fullCopyShader.c_str(), &error); - _dbg_assert_msg_(copyCS_!= VK_NULL_HANDLE, "failed to compile copy shader"); - } + CompileScalingShader(); computeShaderManager_.DeviceRestore(vulkan); } +void TextureCacheVulkan::NotifyConfigChanged() { + TextureCacheCommon::NotifyConfigChanged(); + CompileScalingShader(); +} + +static std::string ReadShaderSrc(const std::string &filename) { + size_t sz = 0; + char *data = (char *)VFSReadFile(filename.c_str(), &sz); + if (!data) + return ""; + + std::string src(data, sz); + free(data); + return src; +} + +void TextureCacheVulkan::CompileScalingShader() { + if (!g_Config.bTexHardwareScaling || g_Config.sTextureShaderName != textureShader_) { + if (uploadCS_ != VK_NULL_HANDLE) + vulkan_->Delete().QueueDeleteShaderModule(uploadCS_); + if (copyCS_ != VK_NULL_HANDLE) + vulkan_->Delete().QueueDeleteShaderModule(copyCS_); + textureShader_.clear(); + } + if (!g_Config.bTexHardwareScaling) + return; + + const TextureShaderInfo *shaderInfo = GetTextureShaderInfo(g_Config.sTextureShaderName); + if (!shaderInfo || shaderInfo->computeShaderFile.empty()) + return; + + std::string shaderSource = ReadShaderSrc(shaderInfo->computeShaderFile); + std::string fullUploadShader = StringFromFormat(uploadShader, shaderSource.c_str()); + std::string fullCopyShader = StringFromFormat(copyShader, shaderSource.c_str()); + + std::string error; + uploadCS_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_COMPUTE_BIT, fullUploadShader.c_str(), &error); + _dbg_assert_msg_(uploadCS_ != VK_NULL_HANDLE, "failed to compile upload shader"); + copyCS_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_COMPUTE_BIT, fullCopyShader.c_str(), &error); + _dbg_assert_msg_(copyCS_ != VK_NULL_HANDLE, "failed to compile copy shader"); + + textureShader_ = g_Config.sTextureShaderName; +} + void TextureCacheVulkan::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { DEBUG_LOG(G3D, "Deleting texture %p", entry->vkTex); delete entry->vkTex; @@ -1026,17 +781,19 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { badMipSizes = false; } + bool hardwareScaling = g_Config.bTexHardwareScaling && (uploadCS_ != VK_NULL_HANDLE || copyCS_ != VK_NULL_HANDLE); + // Don't scale the PPGe texture. if (entry->addr > 0x05000000 && entry->addr < PSP_GetKernelMemoryEnd()) scaleFactor = 1; - if ((entry->status & TexCacheEntry::STATUS_CHANGE_FREQUENT) != 0 && scaleFactor != 1 && !g_Config.bTexHardwareScaling) { + if ((entry->status & TexCacheEntry::STATUS_CHANGE_FREQUENT) != 0 && scaleFactor != 1 && !hardwareScaling) { // Remember for later that we /wanted/ to scale this texture. entry->status |= TexCacheEntry::STATUS_TO_SCALE; scaleFactor = 1; } if (scaleFactor != 1) { - if (texelsScaledThisFrame_ >= TEXCACHE_MAX_TEXELS_SCALED && !g_Config.bTexHardwareScaling) { + if (texelsScaledThisFrame_ >= TEXCACHE_MAX_TEXELS_SCALED && !hardwareScaling) { entry->status |= TexCacheEntry::STATUS_TO_SCALE; scaleFactor = 1; } else { @@ -1088,7 +845,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { // If we want to use the GE debugger, we should add VK_IMAGE_USAGE_TRANSFER_SRC_BIT too... // Compute experiment - if (actualFmt == VULKAN_8888_FORMAT && scaleFactor > 1 && g_Config.bTexHardwareScaling) { + if (actualFmt == VULKAN_8888_FORMAT && scaleFactor > 1 && hardwareScaling) { // Enable the experiment you want. if (uploadCS_ != VK_NULL_HANDLE) computeUpload = true; diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index 3635d5299c..a9163f2e18 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -94,6 +94,8 @@ public: } } + void NotifyConfigChanged() override; + void GetVulkanHandles(VkImageView &imageView, VkSampler &sampler) { imageView = imageView_; sampler = curSampler_; @@ -123,6 +125,8 @@ private: void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override; void BuildTexture(TexCacheEntry *const entry) override; + void CompileScalingShader(); + VulkanContext *vulkan_ = nullptr; VulkanDeviceAllocator *allocator_ = nullptr; VulkanPushBuffer *push_ = nullptr; @@ -145,6 +149,7 @@ private: DrawEngineVulkan *drawEngine_; Vulkan2D *vulkan2D_; + std::string textureShader_; VkShaderModule uploadCS_ = VK_NULL_HANDLE; VkShaderModule copyCS_ = VK_NULL_HANDLE; diff --git a/assets/shaders/defaultshaders.ini b/assets/shaders/defaultshaders.ini index d364ad93af..78c1eb62a4 100644 --- a/assets/shaders/defaultshaders.ini +++ b/assets/shaders/defaultshaders.ini @@ -144,4 +144,8 @@ SettingDefaultValue4=1.0 SettingMaxValue4=2.0 SettingMinValue4=0.1 SettingStep4=0.05 - +[Tex4xBRZ] +Type=Texture +Name=4xBRZ +Author=Hyllian +Compute=tex_4xbrz.csh diff --git a/assets/shaders/tex_4xbrz.csh b/assets/shaders/tex_4xbrz.csh new file mode 100644 index 0000000000..2a72a7f3b5 --- /dev/null +++ b/assets/shaders/tex_4xbrz.csh @@ -0,0 +1,279 @@ +// 4xBRZ shader - Copyright (C) 2014-2016 DeSmuME team (GPL2+) +// Hyllian's xBR-vertex code and texel mapping +// Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com +#define BLEND_ALPHA 1 +#define BLEND_NONE 0 +#define BLEND_NORMAL 1 +#define BLEND_DOMINANT 2 +#define LUMINANCE_WEIGHT 1.0 +#define EQUAL_COLOR_TOLERANCE 30.0/255.0 +#define STEEP_DIRECTION_THRESHOLD 2.2 +#define DOMINANT_DIRECTION_THRESHOLD 3.6 + +float reduce(vec4 color) { + return dot(color.rgb, vec3(65536.0, 256.0, 1.0)); +} + +float DistYCbCr(vec4 pixA, vec4 pixB) { + // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion + const vec3 K = vec3(0.2627, 0.6780, 0.0593); + const mat3 MATRIX = mat3(K, + -.5 * K.r / (1.0 - K.b), -.5 * K.g / (1.0 - K.b), .5, + .5, -.5 * K.g / (1.0 - K.r), -.5 * K.b / (1.0 - K.r)); + vec4 diff = pixA - pixB; + vec3 YCbCr = diff.rgb * MATRIX; + YCbCr.x *= LUMINANCE_WEIGHT; + float d = length(YCbCr); + return sqrt(pixA.a * pixB.a * d * d + diff.a * diff.a); +} + +bool IsPixEqual(const vec4 pixA, const vec4 pixB) { + return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE); +} + +bool IsBlendingNeeded(const ivec4 blend) { + ivec4 diff = blend - ivec4(BLEND_NONE); + return diff.x != 0 || diff.y != 0 || diff.z != 0 || diff.w != 0; +} + +vec4 applyScalingf(uvec2 origxy, uvec2 xy) { + float dx = 1.0 / params.width; + float dy = 1.0 / params.height; + + // A1 B1 C1 + // A0 A B C C4 + // D0 D E F F4 + // G0 G H I I4 + // G5 H5 I5 + + uvec4 t1 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y - 2); // A1 B1 C1 + uvec4 t2 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y - 1); // A B C + uvec4 t3 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y + 0); // D E F + uvec4 t4 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y + 1); // G H I + uvec4 t5 = uvec4(origxy.x - 1, origxy.x, origxy.x + 1, origxy.y + 2); // G5 H5 I5 + uvec4 t6 = uvec4(origxy.x - 2, origxy.y - 1, origxy.y, origxy.y + 1); // A0 D0 G0 + uvec4 t7 = uvec4(origxy.x + 2, origxy.y - 1, origxy.y, origxy.y + 1); // C4 F4 I4 + + vec2 f = fract(vec2(float(xy.x) / float(params.scale), float(xy.y) / float(params.scale))); + + //--------------------------------------- + // Input Pixel Mapping: |21|22|23| + // 19|06|07|08|09 + // 18|05|00|01|10 + // 17|04|03|02|11 + // |15|14|13| + + vec4 src[25]; + + src[21] = readColorf(t1.xw); + src[22] = readColorf(t1.yw); + src[23] = readColorf(t1.zw); + src[ 6] = readColorf(t2.xw); + src[ 7] = readColorf(t2.yw); + src[ 8] = readColorf(t2.zw); + src[ 5] = readColorf(t3.xw); + src[ 0] = readColorf(t3.yw); + src[ 1] = readColorf(t3.zw); + src[ 4] = readColorf(t4.xw); + src[ 3] = readColorf(t4.yw); + src[ 2] = readColorf(t4.zw); + src[15] = readColorf(t5.xw); + src[14] = readColorf(t5.yw); + src[13] = readColorf(t5.zw); + src[19] = readColorf(t6.xy); + src[18] = readColorf(t6.xz); + src[17] = readColorf(t6.xw); + src[ 9] = readColorf(t7.xy); + src[10] = readColorf(t7.xz); + src[11] = readColorf(t7.xw); + + float v[9]; + v[0] = reduce(src[0]); + v[1] = reduce(src[1]); + v[2] = reduce(src[2]); + v[3] = reduce(src[3]); + v[4] = reduce(src[4]); + v[5] = reduce(src[5]); + v[6] = reduce(src[6]); + v[7] = reduce(src[7]); + v[8] = reduce(src[8]); + + ivec4 blendResult = ivec4(BLEND_NONE); + + // Preprocess corners + // Pixel Tap Mapping: --|--|--|--|-- + // --|--|07|08|-- + // --|05|00|01|10 + // --|04|03|02|11 + // --|--|14|13|-- + // Corner (1, 1) + if ( ((v[0] == v[1] && v[3] == v[2]) || (v[0] == v[3] && v[1] == v[2])) == false) { + float dist_03_01 = DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + DistYCbCr(src[14], src[ 2]) + DistYCbCr(src[ 2], src[10]) + (4.0 * DistYCbCr(src[ 3], src[ 1])); + float dist_00_02 = DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[ 3], src[13]) + DistYCbCr(src[ 7], src[ 1]) + DistYCbCr(src[ 1], src[11]) + (4.0 * DistYCbCr(src[ 0], src[ 2])); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_03_01) < dist_00_02; + blendResult[2] = ((dist_03_01 < dist_00_02) && (v[0] != v[1]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + // Pixel Tap Mapping: --|--|--|--|-- + // --|06|07|--|-- + // 18|05|00|01|-- + // 17|04|03|02|-- + // --|15|14|--|-- + // Corner (0, 1) + if ( ((v[5] == v[0] && v[4] == v[3]) || (v[5] == v[4] && v[0] == v[3])) == false) { + float dist_04_00 = DistYCbCr(src[17], src[ 5]) + DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[15], src[ 3]) + DistYCbCr(src[ 3], src[ 1]) + (4.0 * DistYCbCr(src[ 4], src[ 0])); + float dist_05_03 = DistYCbCr(src[18], src[ 4]) + DistYCbCr(src[ 4], src[14]) + DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + (4.0 * DistYCbCr(src[ 5], src[ 3])); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_03) < dist_04_00; + blendResult[3] = ((dist_04_00 > dist_05_03) && (v[0] != v[5]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + // Pixel Tap Mapping: --|--|22|23|-- + // --|06|07|08|09 + // --|05|00|01|10 + // --|--|03|02|-- + // --|--|--|--|-- + // Corner (1, 0) + if ( ((v[7] == v[8] && v[0] == v[1]) || (v[7] == v[0] && v[8] == v[1])) == false) { + float dist_00_08 = DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[ 7], src[23]) + DistYCbCr(src[ 3], src[ 1]) + DistYCbCr(src[ 1], src[ 9]) + (4.0 * DistYCbCr(src[ 0], src[ 8])); + float dist_07_01 = DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + DistYCbCr(src[22], src[ 8]) + DistYCbCr(src[ 8], src[10]) + (4.0 * DistYCbCr(src[ 7], src[ 1])); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_07_01) < dist_00_08; + blendResult[1] = ((dist_00_08 > dist_07_01) && (v[0] != v[7]) && (v[0] != v[1])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + // Pixel Tap Mapping: --|21|22|--|-- + // 19|06|07|08|-- + // 18|05|00|01|-- + // --|04|03|--|-- + // --|--|--|--|-- + // Corner (0, 0) + if ( ((v[6] == v[7] && v[5] == v[0]) || (v[6] == v[5] && v[7] == v[0])) == false) { + float dist_05_07 = DistYCbCr(src[18], src[ 6]) + DistYCbCr(src[ 6], src[22]) + DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + (4.0 * DistYCbCr(src[ 5], src[ 7])); + float dist_06_00 = DistYCbCr(src[19], src[ 5]) + DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[21], src[ 7]) + DistYCbCr(src[ 7], src[ 1]) + (4.0 * DistYCbCr(src[ 6], src[ 0])); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_07) < dist_06_00; + blendResult[0] = ((dist_05_07 < dist_06_00) && (v[0] != v[5]) && (v[0] != v[7])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + vec4 dst[16]; + dst[ 0] = src[0]; + dst[ 1] = src[0]; + dst[ 2] = src[0]; + dst[ 3] = src[0]; + dst[ 4] = src[0]; + dst[ 5] = src[0]; + dst[ 6] = src[0]; + dst[ 7] = src[0]; + dst[ 8] = src[0]; + dst[ 9] = src[0]; + dst[10] = src[0]; + dst[11] = src[0]; + dst[12] = src[0]; + dst[13] = src[0]; + dst[14] = src[0]; + dst[15] = src[0]; + + // Scale pixel + if (IsBlendingNeeded(blendResult) == true) { + float dist_01_04 = DistYCbCr(src[1], src[4]); + float dist_03_08 = DistYCbCr(src[3], src[8]); + bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[4]) && (v[5] != v[4]); + bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[8]) && (v[7] != v[8]); + bool needBlend = (blendResult[2] != BLEND_NONE); + bool doLineBlend = ( blendResult[2] >= BLEND_DOMINANT || + ((blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) || + (blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) || + (IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[0], src[2]) == false) ) == false ); + + vec4 blendPix = ( DistYCbCr(src[0], src[1]) <= DistYCbCr(src[0], src[3]) ) ? src[1] : src[3]; + dst[ 2] = mix(dst[ 2], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); + dst[ 9] = mix(dst[ 9], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); + dst[10] = mix(dst[10], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); + dst[11] = mix(dst[11], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[12] = mix(dst[12], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); + dst[13] = mix(dst[13], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[14] = mix(dst[14], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); + dst[15] = mix(dst[15], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); + + dist_01_04 = DistYCbCr(src[7], src[2]); + dist_03_08 = DistYCbCr(src[1], src[6]); + haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[2]) && (v[3] != v[2]); + haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[6]) && (v[5] != v[6]); + needBlend = (blendResult[1] != BLEND_NONE); + doLineBlend = ( blendResult[1] >= BLEND_DOMINANT || + !((blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || + (blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || + (IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && !IsPixEqual(src[0], src[8])) ) ); + + blendPix = ( DistYCbCr(src[0], src[7]) <= DistYCbCr(src[0], src[1]) ) ? src[7] : src[1]; + dst[ 1] = mix(dst[ 1], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); + dst[ 6] = mix(dst[ 6], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); + dst[ 7] = mix(dst[ 7], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); + dst[ 8] = mix(dst[ 8], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[ 9] = mix(dst[ 9], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); + dst[10] = mix(dst[10], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[11] = mix(dst[11], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); + dst[12] = mix(dst[12], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); + + dist_01_04 = DistYCbCr(src[5], src[8]); + dist_03_08 = DistYCbCr(src[7], src[4]); + haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[8]) && (v[1] != v[8]); + haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[4]) && (v[3] != v[4]); + needBlend = (blendResult[0] != BLEND_NONE); + doLineBlend = ( blendResult[0] >= BLEND_DOMINANT || + !((blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) || + (blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) || + (IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && !IsPixEqual(src[0], src[6])) ) ); + + blendPix = ( DistYCbCr(src[0], src[5]) <= DistYCbCr(src[0], src[7]) ) ? src[5] : src[7]; + dst[ 0] = mix(dst[ 0], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); + dst[15] = mix(dst[15], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); + dst[ 4] = mix(dst[ 4], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); + dst[ 5] = mix(dst[ 5], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[ 6] = mix(dst[ 6], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); + dst[ 7] = mix(dst[ 7], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[ 8] = mix(dst[ 8], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); + dst[ 9] = mix(dst[ 9], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); + + dist_01_04 = DistYCbCr(src[3], src[6]); + dist_03_08 = DistYCbCr(src[5], src[2]); + haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[6]) && (v[7] != v[6]); + haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[2]) && (v[1] != v[2]); + needBlend = (blendResult[3] != BLEND_NONE); + doLineBlend = ( blendResult[3] >= BLEND_DOMINANT || + !((blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || + (blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || + (IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && !IsPixEqual(src[0], src[4])) ) ); + + blendPix = ( DistYCbCr(src[0], src[3]) <= DistYCbCr(src[0], src[5]) ) ? src[3] : src[5]; + dst[ 3] = mix(dst[ 3], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); + dst[12] = mix(dst[12], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); + dst[13] = mix(dst[13], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); + dst[14] = mix(dst[14], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[15] = mix(dst[15], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); + dst[ 4] = mix(dst[ 4], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[ 5] = mix(dst[ 5], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); + dst[ 6] = mix(dst[ 6], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); + } + + // select output pixel + vec4 res = mix(mix(mix(mix(dst[ 6], dst[ 7], step(0.25, f.x)), + mix(dst[ 8], dst[ 9], step(0.75, f.x)), + step(0.50, f.x)), + mix(mix(dst[ 5], dst[ 0], step(0.25, f.x)), + mix(dst[ 1], dst[10], step(0.75, f.x)), + step(0.50, f.x)), + step(0.25, f.y)), + mix(mix(mix(dst[ 4], dst[ 3], step(0.25, f.x)), + mix(dst[ 2], dst[11], step(0.75, f.x)), + step(0.50, f.x)), + mix(mix(dst[15], dst[14], step(0.25, f.x)), + mix(dst[13], dst[12], step(0.75, f.x)), + step(0.50, f.x)), + step(0.75, f.y)), + step(0.50, f.y)); + + return res; +} + +uint applyScalingu(uvec2 origxy, uvec2 xy) { + return packUnorm4x8(applyScalingf(origxy, xy)); +} From 93a32c285bc7b9969f094e07111ed1636c5a0748 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Aug 2020 22:32:55 -0700 Subject: [PATCH 409/848] UI: Simplify on/off for hardware tex scaling. --- UI/GameSettingsScreen.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index d3846ba413..7c6637faef 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -489,14 +489,11 @@ void GameSettingsScreen::CreateViews() { return !g_Config.bSoftwareRendering && !UsingHardwareTextureScaling(); }); - CheckBox *texHardwareScaling = graphicsSettings->Add(new CheckBox(&g_Config.bTexHardwareScaling, gr->T("Hardware texture scaling"))); - texHardwareScaling->SetEnabledFunc([]() { - return GetGPUBackend() == GPUBackend::VULKAN && !g_Config.bSoftwareRendering; - }); - ChoiceWithValueDisplay *textureShaderChoice = graphicsSettings->Add(new ChoiceWithValueDisplay(&g_Config.sTextureShaderName, gr->T("Texture Shader"), &TextureTranslateName)); textureShaderChoice->OnClick.Handle(this, &GameSettingsScreen::OnTextureShader); - textureShaderChoice->SetEnabledFunc(UsingHardwareTextureScaling); + textureShaderChoice->SetEnabledFunc([]() { + return GetGPUBackend() == GPUBackend::VULKAN && !g_Config.bSoftwareRendering; + }); graphicsSettings->Add(new ItemHeader(gr->T("Texture Filtering"))); static const char *anisoLevels[] = { "Off", "2x", "4x", "8x", "16x" }; @@ -1501,6 +1498,7 @@ UI::EventReturn GameSettingsScreen::OnTextureShader(UI::EventParams &e) { UI::EventReturn GameSettingsScreen::OnTextureShaderChange(UI::EventParams &e) { NativeMessageReceived("gpu_resized", ""); RecreateViews(); // Update setting name + g_Config.bTexHardwareScaling = g_Config.sTextureShaderName != "Off"; return UI::EVENT_DONE; } From 888629143498a28fd80a108cab78712ddbfad53c Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 2 Aug 2020 12:57:27 +0700 Subject: [PATCH 410/848] Save&Restore PSP Thread IDs to prevent using the wrong Thread ID after loading from save state, also making sure DoState have default value --- Core/HLE/proAdhoc.h | 16 ++++- Core/HLE/sceNet.cpp | 8 ++- Core/HLE/sceNet.h | 9 +++ Core/HLE/sceNetAdhoc.cpp | 151 +++++++++++++++------------------------ 4 files changed, 88 insertions(+), 96 deletions(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 92fc3d8594..77afa70dd1 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -479,8 +479,8 @@ typedef struct SceNetAdhocMatchingContext { u64_le timeout; // Helper Thread (fake PSP Thread) needed to execute callback - HLEHelperThread *matchingThread; - SceUID matching_thid; + //HLEHelperThread *matchingThread; + int matching_thid; // Event Caller Thread std::thread eventThread; @@ -801,6 +801,11 @@ public: p.Do(EventID); p.Do(argsAddr); } + else { + HandlerID = -1; + EventID = -1; + argsAddr = 0; + } } void run(MipsCall& call) override; void SetData(int handlerID, int eventId, u32_le argsAddr); @@ -822,10 +827,17 @@ public: if (s >= 1) { p.Do(EventID); } + else { + EventID = -1; + } if (s >= 4) { p.Do(contextID); p.Do(bufAddr); } + else { + contextID = -1; + bufAddr = 0; + } } void run(MipsCall &call) override; void SetData(int ContextID, int eventId, u32_le BufAddr); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index d9215a9ddb..d13d805528 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -248,6 +248,12 @@ void __NetDoState(PointerWrap &p) { p.Do(actionAfterApctlMipsCall); __KernelRestoreActionType(actionAfterApctlMipsCall, AfterApctlMipsCall::Create); p.Do(apctlThreadHackAddr); + p.Do(apctlThreadID); + } + else { + actionAfterApctlMipsCall = 0; + apctlThreadHackAddr = 0; + apctlThreadID = 0; } // Let's not change "Inited" value when Loading SaveState in the middle of multiplayer to prevent memory & port leaks if (p.mode == p.MODE_READ) { @@ -256,7 +262,7 @@ void __NetDoState(PointerWrap &p) { netInited = cur_netInited; // Previously, this wasn't being saved. It needs its own space. - if (apctlThreadHackAddr && strcmp("apctlThreadHack", kernelMemory.GetBlockTag(apctlThreadHackAddr)) != 0) { + if (!apctlThreadHackAddr || (apctlThreadHackAddr && strcmp("apctlThreadHack", kernelMemory.GetBlockTag(apctlThreadHackAddr)) != 0)) { u32 blockSize = sizeof(apctlThreadCode); apctlThreadHackAddr = kernelMemory.Alloc(blockSize, false, "apctlThreadHack"); } diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index b6035e50d2..1ca82af0d5 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -208,6 +208,7 @@ public: auto s = p.Section("AfterApctlMipsCall", 1, 1); if (!s) return; + // Just in case there are "s" corruption in the future where s.ver is a negative number if (s >= 1) { p.Do(handlerID); p.Do(oldState); @@ -216,6 +217,14 @@ public: p.Do(error); p.Do(argsAddr); } + else { + handlerID = -1; + oldState = 0; + newState = 0; + event = 0; + error = 0; + argsAddr = 0; + } } void run(MipsCall& call) override; void SetData(int HandlerID, int OldState, int NewState, int Event, int Error, u32_le ArgsAddr); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index b7fafe3a18..d0fb2ac203 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -65,6 +65,7 @@ std::recursive_mutex adhocEvtMtx; std::deque> adhocctlEvents; std::deque matchingEvents; std::map adhocctlHandlers; +std::vector matchingThreads; int IsAdhocctlInCB = 0; u32 dummyThreadHackAddr = 0; @@ -110,7 +111,7 @@ void __NetAdhocShutdown() { } void __NetAdhocDoState(PointerWrap &p) { - auto s = p.Section("sceNetAdhoc", 1, 3); + auto s = p.Section("sceNetAdhoc", 1, 4); if (!s) return; @@ -129,21 +130,38 @@ void __NetAdhocDoState(PointerWrap &p) { p.Do(dummyThreadHackAddr); } + else { + actionAfterMatchingMipsCall = 0; + dummyThreadHackAddr = 0; + } if (s >= 3) { - //p.Do(IsAdhocctlInCB); // This will cause a crash if adhocEvtMtx was locked p.Do(actionAfterAdhocMipsCall); __KernelRestoreActionType(actionAfterAdhocMipsCall, AfterAdhocMipsCall::Create); p.Do(matchingThreadHackAddr); } + else { + actionAfterAdhocMipsCall = 0; + matchingThreadHackAddr = 0; + } + if (s >= 4) { + p.Do(threadAdhocID); + p.Do(matchingThreads); + } + else { + threadAdhocID = 0; + for (auto& it : matchingThreads) { + it = 0; + } + } if (p.mode == p.MODE_READ) { // Previously, this wasn't being saved. It needs its own space. - if (dummyThreadHackAddr && strcmp("dummythreadhack", kernelMemory.GetBlockTag(dummyThreadHackAddr)) != 0) { + if (!dummyThreadHackAddr || (dummyThreadHackAddr && strcmp("dummythreadhack", kernelMemory.GetBlockTag(dummyThreadHackAddr)) != 0)) { u32 blockSize = sizeof(dummyThreadCode); dummyThreadHackAddr = kernelMemory.Alloc(blockSize, false, "dummythreadhack"); } - if (matchingThreadHackAddr && strcmp("matchingThreadHack", kernelMemory.GetBlockTag(matchingThreadHackAddr)) != 0) { + if (!matchingThreadHackAddr || (matchingThreadHackAddr && strcmp("matchingThreadHack", kernelMemory.GetBlockTag(matchingThreadHackAddr)) != 0)) { u32 blockSize = sizeof(matchingThreadCode); matchingThreadHackAddr = kernelMemory.Alloc(blockSize, false, "matchingThreadHack"); } @@ -2860,16 +2878,16 @@ int NetAdhocMatching_Stop(int matchingId) { } // Stop fake PSP Thread - if (item->matching_thid > 0) { - __KernelStopThread(item->matching_thid, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocMatching stopped"); - __KernelDeleteThread(item->matching_thid, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocMatching deleted"); + if (matchingThreads[item->matching_thid] > 0) { + __KernelStopThread(matchingThreads[item->matching_thid], SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocMatching stopped"); + __KernelDeleteThread(matchingThreads[item->matching_thid], SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocMatching deleted"); /*item->matchingThread->Terminate(); if (item->matchingThread && item->matchingThread->Stopped()) { delete item->matchingThread; item->matchingThread = nullptr; }*/ } - item->matching_thid = 0; + matchingThreads[item->matching_thid] = 0; // Multithreading Lock peerlock.lock(); @@ -2999,6 +3017,7 @@ int NetAdhocMatching_Term() { context = next; } contexts = NULL; + matchingThreads.clear(); } return 0; @@ -3099,6 +3118,8 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle // Add Callback Handler context->handler.entryPoint = callbackAddr; + context->matching_thid = static_cast(matchingThreads.size()); + matchingThreads.push_back(0); // Link Context //context->connected = true; @@ -3145,84 +3166,7 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; } -// This should be similar with sceNetAdhocMatchingStart2 but using USER_PARTITION_ID (2) for PartitionId params -static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, int inthPri, int inthStack, int optLen, u32 optDataAddr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStart(%i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthStack, inthPri, inthStack, optLen, optDataAddr, currentMIPS->pc); - if (!g_Config.bEnableWlan) - return -1; - - // Multithreading Lock - peerlock.lock(); - - SceNetAdhocMatchingContext * item = findMatchingContext(matchingId); - - if (item != NULL) { - //sceNetAdhocMatchingSetHelloOpt(matchingId, optLen, optDataAddr); //SetHelloOpt only works when context is running - if ((optLen > 0) && Memory::IsValidAddress(optDataAddr)) { - // Allocate the memory and copy the content - if (item->hello != NULL) free(item->hello); - item->hello = (uint8_t *)malloc(optLen); - if (item->hello != NULL) { - Memory::Memcpy(item->hello, optDataAddr, optLen); - item->hellolen = optLen; - item->helloAddr = optDataAddr; - } - //else return ERROR_NET_ADHOC_MATCHING_NO_SPACE; //Faking success to prevent GTA:VCS from stuck unable to choose host/join menu - } - //else return ERROR_NET_ADHOC_MATCHING_INVALID_ARG; // ERROR_NET_ADHOC_MATCHING_INVALID_OPTLEN; // Returning Not Success will cause GTA:VC stuck unable to choose host/join menu - - //Add your own MAC as a member (only if it's empty?) - /*SceNetAdhocMatchingMemberInternal * peer = addMember(item, &item->mac); - switch (item->mode) { - case PSP_ADHOC_MATCHING_MODE_PARENT: - peer->state = PSP_ADHOC_MATCHING_PEER_OFFER; - break; - case PSP_ADHOC_MATCHING_MODE_CHILD: - peer->state = PSP_ADHOC_MATCHING_PEER_CHILD; - break; - case PSP_ADHOC_MATCHING_MODE_P2P: - peer->state = PSP_ADHOC_MATCHING_PEER_P2P; - }*/ - - // Create & Start the Fake PSP Thread ("matching_ev%d" and "matching_io%d") - std::string thrname = std::string("MatchingThr") + std::to_string(matchingId); - item->matching_thid = sceKernelCreateThread(thrname.c_str(), matchingThreadHackAddr, evthPri, evthStack, 0, 0); - //item->matchingThread = new HLEHelperThread(thrname.c_str(), "sceNetAdhocMatching", "__NetMatchingCallbacks", inthPri, inthStack); - if (item->matching_thid > 0) { - sceKernelStartThread(item->matching_thid, 0, 0); //sceKernelStartThread(context->event_thid, sizeof(context), &context); - //item->matchingThread->Start(matchingId, 0); - } - - //Create the threads - if (!item->eventRunning) { - item->eventRunning = true; - item->eventThread = std::thread(matchingEventThread, matchingId); - } - if (!item->inputRunning) { - item->inputRunning = true; - item->inputThread = std::thread(matchingInputThread, matchingId); - } - - item->running = 1; - netAdhocMatchingStarted++; - } - //else return ERROR_NET_ADHOC_MATCHING_INVALID_ID; //Faking success to prevent GTA:VCS from stuck unable to choose host/join menu - - // Multithreading Unlock - peerlock.unlock(); - - sleep_ms(adhocMatchingEventDelayMS); - //hleDelayResult(0, "give some time", adhocMatchingEventDelayMS * 1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? - - return 0; -} - -// With params for Partition ID for the event & input handler stack -static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartitionId, int evthStack, int inthPri, int inthPartitionId, int inthStack, int optLen, u32 optDataAddr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStart2(%i, %i, %i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthPartitionId, evthStack, inthPri, inthPartitionId, inthStack, optLen, optDataAddr, currentMIPS->pc); - if (!g_Config.bEnableWlan) - return -1; - +int NetAdhocMatching_Start(int matchingId, int evthPri, int evthPartitionId, int evthStack, int inthPri, int inthPartitionId, int inthStack, int optLen, u32 optDataAddr) { // Multithreading Lock peerlock.lock(); @@ -3256,13 +3200,13 @@ static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartit peer->state = PSP_ADHOC_MATCHING_PEER_P2P; }*/ - // Create & Start the Fake PSP Thread + // Create & Start the Fake PSP Thread ("matching_ev%d" and "matching_io%d") std::string thrname = std::string("MatchingThr") + std::to_string(matchingId); - item->matching_thid = __KernelCreateThread(thrname.c_str(), __KernelGetCurThreadModuleId(), matchingThreadHackAddr, evthPri, evthStack, PSP_THREAD_ATTR_USER, 0, false); - //item->matchingThread = new HLEHelperThread(thrname, "sceNetAdhocMatching", "AdhocMatchingFunc", inthPri, inthStack); - if (item->matching_thid > 0) { - __KernelStartThread(item->matching_thid, 0, 0); - //item->matchingThread->Start(0, 0); + matchingThreads[item->matching_thid] = sceKernelCreateThread(thrname.c_str(), matchingThreadHackAddr, evthPri, evthStack, 0, 0); + //item->matchingThread = new HLEHelperThread(thrname.c_str(), "sceNetAdhocMatching", "__NetMatchingCallbacks", inthPri, inthStack); + if (matchingThreads[item->matching_thid] > 0) { + sceKernelStartThread(matchingThreads[item->matching_thid], 0, 0); //sceKernelStartThread(context->event_thid, sizeof(context), &context); + //item->matchingThread->Start(matchingId, 0); } //Create the threads @@ -3284,11 +3228,32 @@ static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartit peerlock.unlock(); sleep_ms(adhocMatchingEventDelayMS); - //hleDelayResult(0,"give some time",adhocMatchingEventDelayMS*1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? + //hleDelayResult(0, "give some time", adhocMatchingEventDelayMS * 1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? return 0; } +#define KERNEL_PARTITION_ID 1 +#define USER_PARTITION_ID 2 +#define VSHELL_PARTITION_ID 5 +// This should be similar with sceNetAdhocMatchingStart2 but using USER_PARTITION_ID (2) for PartitionId params +static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, int inthPri, int inthStack, int optLen, u32 optDataAddr) { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStart(%i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthStack, inthPri, inthStack, optLen, optDataAddr, currentMIPS->pc); + if (!g_Config.bEnableWlan) + return -1; + + return NetAdhocMatching_Start(matchingId, evthPri, USER_PARTITION_ID, evthStack, inthPri, USER_PARTITION_ID, inthStack, optLen, optDataAddr); +} + +// With params for Partition ID for the event & input handler stack +static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartitionId, int evthStack, int inthPri, int inthPartitionId, int inthStack, int optLen, u32 optDataAddr) { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingStart2(%i, %i, %i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthPartitionId, evthStack, inthPri, inthPartitionId, inthStack, optLen, optDataAddr, currentMIPS->pc); + if (!g_Config.bEnableWlan) + return -1; + + return NetAdhocMatching_Start(matchingId, evthPri, evthPartitionId, evthStack, inthPri, inthPartitionId, inthStack, optLen, optDataAddr); +} + static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSelectTarget(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress).c_str(), optLen, optDataPtr, currentMIPS->pc); From 5de27076331cae1ddf768e8db04daba4510ff31d Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 2 Aug 2020 14:02:49 +0700 Subject: [PATCH 411/848] Fix crashes issue due to 0 is a valid index to types_, using invalid index like -1 should give a better/clearer stack trace --- Core/HLE/sceNet.cpp | 7 ++++++- Core/HLE/sceNetAdhoc.cpp | 11 +++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index d13d805528..f307275835 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -251,7 +251,7 @@ void __NetDoState(PointerWrap &p) { p.Do(apctlThreadID); } else { - actionAfterApctlMipsCall = 0; + actionAfterApctlMipsCall = -1; apctlThreadHackAddr = 0; apctlThreadID = 0; } @@ -442,6 +442,11 @@ void __NetApctlCallbacks() //if (*error == 0) *newState = netApctlState; + // Since 0 is a valid index to types_ we use -1 to detects if it was loaded from an old save state + if (actionAfterApctlMipsCall < 0) { + actionAfterApctlMipsCall = __KernelRegisterActionType(AfterApctlMipsCall::Create); + } + // Run mipscall. Should we skipped executing the mipscall if oldState == newState? for (std::map::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); ++it) { DEBUG_LOG(SCENET, "ApctlCallback [ID=%i][OldState=%d][NewState=%d][Event=%d][Error=%d][ArgsPtr=%08x]", it->first, *oldState, *newState, *event, *error, it->second.argument); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index d0fb2ac203..5f04735661 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -131,7 +131,7 @@ void __NetAdhocDoState(PointerWrap &p) { p.Do(dummyThreadHackAddr); } else { - actionAfterMatchingMipsCall = 0; + actionAfterMatchingMipsCall = -1; dummyThreadHackAddr = 0; } if (s >= 3) { @@ -141,7 +141,7 @@ void __NetAdhocDoState(PointerWrap &p) { p.Do(matchingThreadHackAddr); } else { - actionAfterAdhocMipsCall = 0; + actionAfterAdhocMipsCall = -1; matchingThreadHackAddr = 0; } if (s >= 4) { @@ -3980,6 +3980,10 @@ void __NetTriggerCallbacks() //if (/*__KernelGetCurThread() == threadAdhocID &&*/ (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && IsAdhocctlInCallback() == 0) { + // Since 0 is a valid index to types_ we use -1 to detects if it was loaded from an old save state + if (actionAfterAdhocMipsCall < 0) { + actionAfterAdhocMipsCall = __KernelRegisterActionType(AfterAdhocMipsCall::Create); + } for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { DEBUG_LOG(SCENET, "AdhocctlCallback: [ID=%i][EVENT=%i]", it->first, flags); args[2] = it->second.argument; @@ -4014,6 +4018,9 @@ void __NetMatchingCallbacks() //(int matchingId) //if (/*__KernelGetCurThread() == context->matching_thid &&*/ (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) /*&& !IsMatchingInCallback(context)*/) { + if (actionAfterMatchingMipsCall < 0) { + actionAfterMatchingMipsCall = __KernelRegisterActionType(AfterMatchingMipsCall::Create); + } DEBUG_LOG(SCENET, "AdhocMatchingCallback: [ID=%i][EVENT=%i][%s]", args[0], args[1], mac2str((SceNetEtherAddr*)Memory::GetPointer(args[2])).c_str()); AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); after->SetData(args[0], args[1], args[2]); From a47c33ac574aca460c07df1fc1f8c4d7425e5b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 15:08:30 +0200 Subject: [PATCH 412/848] Fix error in sceUsbMic savestate handling (need to accept old savestates without the section) Hopefully helps #13236. --- Core/HLE/sceUsbMic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 13a041a71e..788529e679 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -118,7 +118,7 @@ void __UsbMicShutdown() { } void __UsbMicDoState(PointerWrap &p) { - auto s = p.Section("sceUsbMic", 1, 1); + auto s = p.Section("sceUsbMic", 0, 1); if (!s) { return; } From 6aa3681f7c3c56eaab0dd7bd9797f604fe452d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 15:41:00 +0200 Subject: [PATCH 413/848] Minor logging improvements --- Core/SaveState.cpp | 2 +- GPU/Common/FramebufferCommon.cpp | 4 +-- ext/native/thin3d/VulkanRenderManager.cpp | 31 ++++++++++++----------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index d3472b5e1a..4630b0d9a3 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -744,7 +744,7 @@ namespace SaveState switch (op.type) { case SAVESTATE_LOAD: - INFO_LOG(SAVESTATE, "Loading state from %s", op.filename.c_str()); + INFO_LOG(SAVESTATE, "Loading state from '%s'", op.filename.c_str()); // Use the state's latest version as a guess for saveStateInitialGitVersion. result = CChunkFileReader::Load(op.filename, &saveStateInitialGitVersion, state, &reason); if (result == CChunkFileReader::ERROR_NONE) { diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 22fd104386..9dab512165 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -403,7 +403,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame // This happens a lot, but virtually always it's cleared. // It's possible the other might not clear, but when every game is reported it's not useful. if (params.isWritingDepth) { - WARN_LOG(SCEGE, "FBO reusing depthbuffer, %08x/%08x and %08x/%08x", params.fb_address, params.z_address, vfbs_[i]->fb_address, vfbs_[i]->z_address); + WARN_LOG(SCEGE, "FBO reusing depthbuffer, c=%08x/d=%08x and c=%08x/d=%08x", params.fb_address, params.z_address, vfbs_[i]->fb_address, vfbs_[i]->z_address); sharingReported = true; } } @@ -412,7 +412,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame // We already have it! } else if (vfb != currentRenderVfb_) { // Use it as a render target. - DEBUG_LOG(FRAMEBUF, "Switching render target to FBO for %08x: %i x %i x %i ", vfb->fb_address, vfb->width, vfb->height, vfb->format); + DEBUG_LOG(FRAMEBUF, "Switching render target to FBO for %08x: %d x %d x %d ", vfb->fb_address, vfb->width, vfb->height, vfb->format); vfb->usageFlags |= FB_USAGE_RENDERTARGET; vfb->last_frame_render = gpuStats.numFlips; frameLastFramebufUsed_ = gpuStats.numFlips; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index b2307a5a38..a595bfe29a 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -58,10 +58,10 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int vulkan->MemoryTypeFromProperties(memreq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &alloc.memoryTypeIndex); VkResult res = vkAllocateMemory(vulkan->GetDevice(), &alloc, nullptr, &img.memory); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); res = vkBindImageMemory(vulkan->GetDevice(), img.image, img.memory, 0); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); VkImageAspectFlags aspects = color ? VK_IMAGE_ASPECT_COLOR_BIT : (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); @@ -435,7 +435,7 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) { renderStepOffset_ = 0; frameData.profile.timestampDescriptions.clear(); - if (frameData_->profilingEnabled_) { + if (frameData.profilingEnabled_) { // For various reasons, we need to always use an init cmd buffer in this case to perform the vkCmdResetQueryPool, // unless we want to limit ourselves to only measure the main cmd buffer. // Reserve the first two queries for initCmd. @@ -466,7 +466,7 @@ VkCommandBuffer VulkanRenderManager::GetInitCmd() { } void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, VKRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag) { - assert(insideFrame_); + _dbg_assert_(insideFrame_); // Eliminate dupes, instantly convert to a clear if possible. if (!steps_.empty() && steps_.back()->stepType == VKRStepType::RENDER && steps_.back()->render.framebuffer == fb) { u32 clearMask = 0; @@ -581,7 +581,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR } bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { - assert(insideFrame_); + _dbg_assert_(insideFrame_); for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { steps_[i]->render.numReads++; @@ -643,7 +643,7 @@ bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int a } void VulkanRenderManager::CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { - assert(insideFrame_); + _dbg_assert_(insideFrame_); VKRStep *step = new VKRStep{ VKRStepType::READBACK_IMAGE }; step->readback_image.image = image; step->readback_image.srcRect.offset = { x, y }; @@ -679,7 +679,7 @@ bool VulkanRenderManager::InitBackbufferFramebuffers(int width, int height) { for (uint32_t i = 0; i < swapchainImageCount_; i++) { attachments[0] = swapchainImages_[i].view; res = vkCreateFramebuffer(vulkan_->GetDevice(), &fb_info, nullptr, &framebuffers_[i]); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); if (res != VK_SUCCESS) { framebuffers_.clear(); return false; @@ -714,7 +714,7 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) { VkDevice device = vulkan_->GetDevice(); res = vkCreateImage(device, &image_info, nullptr, &depth_.image); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); if (res != VK_SUCCESS) return false; @@ -736,17 +736,17 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) { pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, 0, /* No requirements */ &mem_alloc.memoryTypeIndex); - assert(pass); + _dbg_assert_(pass); if (!pass) return false; res = vkAllocateMemory(device, &mem_alloc, NULL, &depth_.mem); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); if (res != VK_SUCCESS) return false; res = vkBindImageMemory(device, depth_.image, depth_.mem, 0); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); if (res != VK_SUCCESS) return false; @@ -772,7 +772,7 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) { depth_view_info.flags = 0; res = vkCreateImageView(device, &depth_view_info, NULL, &depth_.view); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); if (res != VK_SUCCESS) return false; @@ -1076,7 +1076,6 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) { int numCmdBufs = 0; if (frameData.hasInitCommands) { cmdBufs[numCmdBufs++] = frameData.initCmd; - frameData.hasInitCommands = false; if (splitSubmit_) { // Send the init commands off separately. Used this once to confirm that the cause of a device loss was in the init cmdbuf. VkSubmitInfo submit_info{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; @@ -1120,6 +1119,8 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) { frameData.readyForFence = true; frameData.push_condVar.notify_all(); } + + frameData.hasInitCommands = false; } void VulkanRenderManager::EndSubmitFrame(int frame) { @@ -1177,7 +1178,7 @@ void VulkanRenderManager::Run(int frame) { break; default: - assert(false); + _dbg_assert_(false); } VLOG("PULL: Finished running frame %d", frame); @@ -1229,7 +1230,7 @@ void VulkanRenderManager::FlushSync() { frameData.steps = std::move(steps_); steps_.clear(); frameData.readyForRun = true; - assert(frameData.readyForFence == false); + _dbg_assert_(!frameData.readyForFence); frameData.type = VKRRunType::SYNC; frameData.pull_condVar.notify_all(); } From dee0f3f9ecfb48cfa4343832ade58f9545d5b945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 15:41:30 +0200 Subject: [PATCH 414/848] Vulkan debug log: Remove some old exclusions, add a new one (for an old issue) --- Common/Vulkan/VulkanDebug.cpp | 13 ++++++------- Common/Vulkan/VulkanMemory.cpp | 4 +++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index 3129e98938..c60898deef 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -33,13 +33,12 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( const char *pMessage = pCallbackData->pMessage; - // Apparent bugs around timestamp validation in the validation layers - if (strstr(pMessage, "vkCmdBeginQuery(): VkQueryPool")) - return false; - if (strstr(pMessage, "vkGetQueryPoolResults() on VkQueryPool")) - return false; - int messageCode = pCallbackData->messageIdNumber; + if (messageCode == 101294395) { + // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed - benign perf warning + return false; + } + const char *pLayerPrefix = ""; if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { message << "ERROR("; @@ -58,7 +57,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( } else if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) { message << "validation"; } - message << ":" << pCallbackData->messageIdNumber << ") " << pMessage << "\n"; + message << ":" << messageCode << ") " << pMessage << "\n"; std::string msg = message.str(); diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 0974bb8000..9cead85745 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -143,7 +143,9 @@ void VulkanPushBuffer::Map() { } void VulkanPushBuffer::Unmap() { - _dbg_assert_(writePtr_ != 0); + _dbg_assert_msg_(writePtr_ != nullptr, "VulkanPushBuffer::Unmap: writePtr_ null here means we have a bug (map/unmap mismatch)"); + if (!writePtr_) + return; if ((memoryPropertyMask_ & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) { VkMappedMemoryRange range{ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; From bf4db22165c2a7e2ba96dcef5e02535aa644c54c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 17:11:09 +0200 Subject: [PATCH 415/848] SaveState: On section version failure, log out the name of the bad section. Also some other minor improvements to logging and comments. --- Common/ChunkFile.cpp | 22 +++++++++++++--------- Common/ChunkFile.h | 27 +++++++++++++++++---------- Core/SaveState.cpp | 38 ++++++++++++++++++++------------------ Core/SaveState.h | 2 +- UI/EmuScreen.cpp | 23 ++++------------------- 5 files changed, 55 insertions(+), 57 deletions(-) diff --git a/Common/ChunkFile.cpp b/Common/ChunkFile.cpp index cbfec7ffe7..8954de5c45 100644 --- a/Common/ChunkFile.cpp +++ b/Common/ChunkFile.cpp @@ -30,23 +30,26 @@ PointerWrapSection PointerWrap::Section(const char *title, int minVer, int ver) char marker[16] = {0}; int foundVersion = ver; - // This is strncpy because we rely on its weird non-null-terminating truncation behaviour. + // This is strncpy because we rely on its weird non-null-terminating zero-filling truncation behaviour. // Can't replace it with the more sensible truncate_cpy because that would break savestates. strncpy(marker, title, sizeof(marker)); - if (!ExpectVoid(marker, sizeof(marker))) - { + if (!ExpectVoid(marker, sizeof(marker))) { // Might be before we added name markers for safety. - if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion))) + if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion))) { DoMarker(title); - // Wasn't found, but maybe we can still load the state. - else + } else { + // Wasn't found, but maybe we can still load the state. foundVersion = 0; - } - else + } + } else { Do(foundVersion); + } if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { - WARN_LOG(SAVESTATE, "Savestate failure: wrong version %d found for %s", foundVersion, title); + if (!firstBadSectionTitle_) { + firstBadSectionTitle_ = title; + } + WARN_LOG(SAVESTATE, "Savestate failure: wrong version %d found for section '%s'", foundVersion, title); SetError(ERROR_FAILURE); return PointerWrapSection(*this, -1, title); } @@ -58,6 +61,7 @@ void PointerWrap::SetError(Error error_) { error = error_; } if (error > ERROR_WARNING) { + // For the rest of this run, just measure. mode = PointerWrap::MODE_MEASURE; } } diff --git a/Common/ChunkFile.h b/Common/ChunkFile.h index 42d5b38675..e8a41901c5 100644 --- a/Common/ChunkFile.h +++ b/Common/ChunkFile.h @@ -76,6 +76,7 @@ private: // Wrapper class class PointerWrap { +private: // This makes it a compile error if you forget to define DoState() on non-POD. // Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... #ifdef _MSC_VER @@ -111,6 +112,8 @@ class PointerWrap } }; + const char *firstBadSectionTitle_ = nullptr; + public: enum Mode { MODE_READ = 1, // load @@ -127,11 +130,11 @@ public: u8 **ptr; Mode mode; - Error error; + Error error = ERROR_NONE; public: - PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {} - PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {} + PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_) {} + PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_) {} PointerWrapSection Section(const char *title, int ver); @@ -145,6 +148,10 @@ public: u8 **GetPPtr() {return ptr;} void SetError(Error error_); + const char *GetBadSectionTitle() const { + return firstBadSectionTitle_; + } + // Same as DoVoid, except doesn't advance pointer if it doesn't match on read. bool ExpectVoid(void *data, int size); void DoVoid(void *data, int size); @@ -586,7 +593,7 @@ public: // May fail badly if ptr doesn't point to valid data. template - static Error LoadPtr(u8 *ptr, T &_class) + static Error LoadPtr(u8 *ptr, T &_class, std::string *errorString) { PointerWrap p(&ptr, PointerWrap::MODE_READ); _class.DoState(p); @@ -594,6 +601,7 @@ public: if (p.error != p.ERROR_FAILURE) { return ERROR_NONE; } else { + *errorString = std::string("Failure at ") + p.GetBadSectionTitle(); return ERROR_BROKEN_STATE; } } @@ -630,14 +638,13 @@ public: u8 *ptr = nullptr; size_t sz; Error error = LoadFile(filename, gitVersion, ptr, sz, failureReason); - if (error == ERROR_NONE) { - error = LoadPtr(ptr, _class); - delete [] ptr; - } - - INFO_LOG(SAVESTATE, "ChunkReader: Done loading %s", filename.c_str()); if (error == ERROR_NONE) { failureReason->clear(); + error = LoadPtr(ptr, _class, failureReason); + delete [] ptr; + INFO_LOG(SAVESTATE, "ChunkReader: Done loading '%s'", filename.c_str()); + } else { + WARN_LOG(SAVESTATE, "ChunkReader: Error found during load of '%s'", filename.c_str()); } return error; } diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 4630b0d9a3..c6cd4fe469 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -91,9 +91,9 @@ namespace SaveState return CChunkFileReader::SavePtr(&data[0], state); } - CChunkFileReader::Error LoadFromRam(std::vector &data) { + CChunkFileReader::Error LoadFromRam(std::vector &data, std::string *errorString) { SaveStart state; - return CChunkFileReader::LoadPtr(&data[0], state); + return CChunkFileReader::LoadPtr(&data[0], state, errorString); } struct StateRingbuffer @@ -135,7 +135,7 @@ namespace SaveState return err; } - CChunkFileReader::Error Restore() + CChunkFileReader::Error Restore(std::string *errorString) { std::lock_guard guard(lock_); @@ -149,7 +149,7 @@ namespace SaveState static std::vector buffer; LockedDecompress(buffer, states_[n], bases_[baseMapping_[n]]); - return LoadFromRam(buffer); + return LoadFromRam(buffer, errorString); } void ScheduleCompress(std::vector *result, const std::vector *state, const std::vector *base) @@ -632,13 +632,14 @@ namespace SaveState return copy; } - bool HandleFailure() + bool HandleLoadFailure() { // Okay, first, let's give the rewind state a shot - maybe we can at least not reset entirely. // Even if this was a rewind, maybe we can still load a previous one. CChunkFileReader::Error result; do { - result = rewindStates.Restore(); + std::string errorString; + result = rewindStates.Restore(&errorString); } while (result == CChunkFileReader::ERROR_BROKEN_STATE); if (result == CChunkFileReader::ERROR_NONE) { @@ -728,7 +729,6 @@ namespace SaveState Status callbackResult; bool tempResult; std::string callbackMessage; - std::string reason; std::string title; auto sc = GetI18NCategory("Screen"); @@ -740,13 +740,14 @@ namespace SaveState i18nSaveFailure = sc->T("Failed to save state"); std::string slot_prefix = op.slot >= 0 ? StringFromFormat("(%d) ", op.slot + 1) : ""; + std::string errorString; switch (op.type) { case SAVESTATE_LOAD: INFO_LOG(SAVESTATE, "Loading state from '%s'", op.filename.c_str()); // Use the state's latest version as a guess for saveStateInitialGitVersion. - result = CChunkFileReader::Load(op.filename, &saveStateInitialGitVersion, state, &reason); + result = CChunkFileReader::Load(op.filename, &saveStateInitialGitVersion, state, &errorString); if (result == CChunkFileReader::ERROR_NONE) { callbackMessage = slot_prefix + sc->T("Loaded State"); callbackResult = Status::SUCCESS; @@ -777,12 +778,13 @@ namespace SaveState } #endif } else if (result == CChunkFileReader::ERROR_BROKEN_STATE) { - HandleFailure(); - callbackMessage = i18nLoadFailure; - ERROR_LOG(SAVESTATE, "Load state failure: %s", reason.c_str()); + HandleLoadFailure(); + callbackMessage = std::string(i18nLoadFailure) + ": " + errorString; + ERROR_LOG(SAVESTATE, "Load state failure: %s", errorString.c_str()); callbackResult = Status::FAILURE; } else { - callbackMessage = sc->T(reason.c_str(), i18nLoadFailure); + // ? + callbackMessage = sc->T(errorString.c_str(), i18nLoadFailure); callbackResult = Status::FAILURE; } break; @@ -812,9 +814,9 @@ namespace SaveState } #endif } else if (result == CChunkFileReader::ERROR_BROKEN_STATE) { - HandleFailure(); + // TODO: What else might we want to do here? This should be very unusual. callbackMessage = i18nSaveFailure; - ERROR_LOG(SAVESTATE, "Save state failure: %s", reason.c_str()); + ERROR_LOG(SAVESTATE, "Save state failure"); callbackResult = Status::FAILURE; } else { callbackMessage = i18nSaveFailure; @@ -834,24 +836,24 @@ namespace SaveState case SAVESTATE_REWIND: INFO_LOG(SAVESTATE, "Rewinding to recent savestate snapshot"); - result = rewindStates.Restore(); + result = rewindStates.Restore(&errorString); if (result == CChunkFileReader::ERROR_NONE) { callbackMessage = sc->T("Loaded State"); callbackResult = Status::SUCCESS; hasLoadedState = true; } else if (result == CChunkFileReader::ERROR_BROKEN_STATE) { // Cripes. Good news is, we might have more. Let's try those too, better than a reset. - if (HandleFailure()) { + if (HandleLoadFailure()) { // Well, we did rewind, even if too much... callbackMessage = sc->T("Loaded State"); callbackResult = Status::SUCCESS; hasLoadedState = true; } else { - callbackMessage = i18nLoadFailure; + callbackMessage = std::string(i18nLoadFailure) + ": " + errorString; callbackResult = Status::FAILURE; } } else { - callbackMessage = i18nLoadFailure; + callbackMessage = std::string(i18nLoadFailure) + ": " + errorString; callbackResult = Status::FAILURE; } break; diff --git a/Core/SaveState.h b/Core/SaveState.h index 8a205ee579..98b5d9b7d9 100644 --- a/Core/SaveState.h +++ b/Core/SaveState.h @@ -69,7 +69,7 @@ namespace SaveState void Save(const std::string &filename, int slot, Callback callback = Callback(), void *cbUserData = 0); CChunkFileReader::Error SaveToRam(std::vector &state); - CChunkFileReader::Error LoadFromRam(std::vector &state); + CChunkFileReader::Error LoadFromRam(std::vector &state, std::string *errorString); // For testing / automated tests. Runs a save state verification pass (async.) // Warning: callback will be called on a different thread. diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 31936b64dd..b517d6c206 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1439,13 +1439,15 @@ void EmuScreen::render() { return; } + // Freeze-frame functionality (loads a savestate on every frame). if (PSP_CoreParameter().freezeNext) { PSP_CoreParameter().frozen = true; PSP_CoreParameter().freezeNext = false; SaveState::SaveToRam(freezeState_); } else if (PSP_CoreParameter().frozen) { - if (CChunkFileReader::ERROR_NONE != SaveState::LoadFromRam(freezeState_)) { - ERROR_LOG(SAVESTATE, "Failed to load freeze state. Unfreezing."); + std::string errorString; + if (CChunkFileReader::ERROR_NONE != SaveState::LoadFromRam(freezeState_, &errorString)) { + ERROR_LOG(SAVESTATE, "Failed to load freeze state (%s). Unfreezing.", errorString.c_str()); PSP_CoreParameter().frozen = false; } } @@ -1503,23 +1505,6 @@ void EmuScreen::render() { screenManager()->getUIContext()->BeginFrame(); renderUI(); } - - // We have no use for backbuffer depth or stencil, so let tiled renderers discard them after tiling. - /* - if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { - GLenum attachments[2] = { GL_DEPTH, GL_STENCIL }; - glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments); - } else if (!gl_extensions.GLES3) { -#ifdef USING_GLES2 - // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? - bool hasDiscard = gl_extensions.EXT_discard_framebuffer; // TODO - if (hasDiscard) { - //const GLenum targets[3] = { GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT }; - //glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, targets); - } -#endif - } - */ } bool EmuScreen::hasVisibleUI() { From 3869ade72a5d7b3b24a345af540cc947d52729b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 17:54:03 +0200 Subject: [PATCH 416/848] libretro buildfix --- Core/SaveState.cpp | 1 - libretro/libretro.cpp | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index c6cd4fe469..4b6b944136 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -783,7 +783,6 @@ namespace SaveState ERROR_LOG(SAVESTATE, "Load state failure: %s", errorString.c_str()); callbackResult = Status::FAILURE; } else { - // ? callbackMessage = sc->T(errorString.c_str(), i18nLoadFailure); callbackResult = Status::FAILURE; } diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 4e2a6bf07d..2525541daa 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -820,7 +820,8 @@ bool retro_unserialize(const void *data, size_t size) if (useEmuThread) EmuThreadPause(); // Does nothing if already paused - retVal = CChunkFileReader::LoadPtr((u8 *)data, state) + std::string errorString; + retVal = CChunkFileReader::LoadPtr((u8 *)data, state, &errorString) == CChunkFileReader::ERROR_NONE; if (useEmuThread) From 6f02844b5be8449b5a904b166df9a6efb58c3a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 19:44:48 +0200 Subject: [PATCH 417/848] Consolidate BackgroundAudio.cpp into a class --- UI/BackgroundAudio.cpp | 32 +++++++++++--------------------- UI/BackgroundAudio.h | 25 ++++++++++++++++++++++--- UI/EmuScreen.cpp | 2 +- UI/GameScreen.cpp | 2 +- UI/MainScreen.cpp | 10 +++++----- UI/NativeApp.cpp | 4 ++-- 6 files changed, 42 insertions(+), 33 deletions(-) diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index f5bdd81da4..dc585e6a0d 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -11,12 +11,13 @@ #include "Common/FixedSizeQueue.h" #include "GameInfoCache.h" #include "Core/Config.h" +#include "UI/BackgroundAudio.h" // Really simple looping in-memory AT3 player that also takes care of reading the file format. // Turns out that AT3 files used for this are modified WAVE files so fairly easy to parse. class AT3PlusReader { public: - AT3PlusReader(const std::string &data) + explicit AT3PlusReader(const std::string &data) : file_((const uint8_t *)&data[0], (int32_t)data.size()) { // Normally 8k but let's be safe. buffer_ = new short[32 * 1024]; @@ -223,18 +224,9 @@ private: SimpleAudio *decoder_ = nullptr; }; -static std::mutex g_bgMutex; -static std::string bgGamePath; -static int playbackOffset; -static AT3PlusReader *at3Reader; -static double gameLastChanged; -static double lastPlaybackTime; -static int buffer[44100]; -static bool fadingOut = true; -static float volume; -static float delta = -0.0001f; +BackgroundAudio g_BackgroundAudio; -static void ClearBackgroundAudio(bool hard) { +void BackgroundAudio::Clear(bool hard) { if (!hard) { fadingOut = true; volume = 1.0f; @@ -248,7 +240,7 @@ static void ClearBackgroundAudio(bool hard) { playbackOffset = 0; } -void SetBackgroundAudioGame(const std::string &path) { +void BackgroundAudio::SetGame(const std::string &path) { time_update(); std::lock_guard lock(g_bgMutex); @@ -258,10 +250,10 @@ void SetBackgroundAudioGame(const std::string &path) { } if (path.size() == 0) { - ClearBackgroundAudio(false); + Clear(false); fadingOut = true; } else { - ClearBackgroundAudio(true); + Clear(true); gameLastChanged = time_now_d(); fadingOut = false; } @@ -269,14 +261,14 @@ void SetBackgroundAudioGame(const std::string &path) { bgGamePath = path; } -int PlayBackgroundAudio() { +int BackgroundAudio::Play() { time_update(); std::lock_guard lock(g_bgMutex); // Immediately stop the sound if it is turned off while playing. if (!g_Config.bEnableSound) { - ClearBackgroundAudio(true); + Clear(true); __PushExternalAudio(0, 0); return 0; } @@ -297,7 +289,7 @@ int PlayBackgroundAudio() { } __PushExternalAudio(buffer, sz); if (volume <= 0.0f) { - ClearBackgroundAudio(true); + Clear(true); fadingOut = false; gameLastChanged = 0; } @@ -313,9 +305,7 @@ int PlayBackgroundAudio() { return 0; } -// Stuff that should be on the UI thread only, like anything to do with -// g_gameInfoCache. -void UpdateBackgroundAudio() { +void BackgroundAudio::Update() { // If there's a game, and some time has passed since the selected game // last changed... (to prevent crazy amount of reads when skipping through a list) if (bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) { diff --git a/UI/BackgroundAudio.h b/UI/BackgroundAudio.h index 5d9ae1e040..04adcb8a25 100644 --- a/UI/BackgroundAudio.h +++ b/UI/BackgroundAudio.h @@ -2,6 +2,25 @@ #include -void SetBackgroundAudioGame(const std::string &path); -int PlayBackgroundAudio(); -void UpdateBackgroundAudio(); +class AT3PlusReader; + +class BackgroundAudio { +public: + void Clear(bool hard); + void SetGame(const std::string &path); + void Update(); + int Play(); +private: + std::mutex g_bgMutex; + std::string bgGamePath; + int playbackOffset = 0; + AT3PlusReader *at3Reader; + double gameLastChanged = 0.0; + double lastPlaybackTime = 0.0; + int buffer[44100]; + bool fadingOut = true; + float volume = 0.0f; + float delta = -0.0001f; +}; + +extern BackgroundAudio g_BackgroundAudio; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index b517d6c206..a2b476fa25 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -193,7 +193,7 @@ void EmuScreen::bootGame(const std::string &filename) { return; } - SetBackgroundAudioGame(""); + g_BackgroundAudio.SetGame(""); // Check permission status first, in case we came from a shortcut. if (!bootAllowStorage(filename)) diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 1c900beecd..6b4f0b05e1 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -38,7 +38,7 @@ #include "UI/BackgroundAudio.h" GameScreen::GameScreen(const std::string &gamePath) : UIDialogScreenWithGameBackground(gamePath) { - SetBackgroundAudioGame(gamePath); + g_BackgroundAudio.SetGame(gamePath); } GameScreen::~GameScreen() { diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index e9803ac0f6..c444568214 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -935,12 +935,12 @@ UI::EventReturn GameBrowser::OnHomebrewStore(UI::EventParams &e) { MainScreen::MainScreen() { System_SendMessage("event", "mainscreen"); - SetBackgroundAudioGame(""); + g_BackgroundAudio.SetGame(""); lastVertical_ = UseVerticalLayout(); } MainScreen::~MainScreen() { - SetBackgroundAudioGame(""); + g_BackgroundAudio.SetGame(""); } void MainScreen::CreateViews() { @@ -1283,7 +1283,7 @@ UI::EventReturn MainScreen::OnGameSelected(UI::EventParams &e) { // Restore focus if it was highlighted (e.g. by gamepad.) restoreFocusGamePath_ = highlightedGamePath_; - SetBackgroundAudioGame(path); + g_BackgroundAudio.SetGame(path); lockBackgroundAudio_ = true; screenManager()->push(new GameScreen(path)); return UI::EVENT_DONE; @@ -1314,7 +1314,7 @@ UI::EventReturn MainScreen::OnGameHighlight(UI::EventParams &e) { } if ((!highlightedGamePath_.empty() || e.a == FF_LOSTFOCUS) && !lockBackgroundAudio_) { - SetBackgroundAudioGame(highlightedGamePath_); + g_BackgroundAudio.SetGame(highlightedGamePath_); } lockBackgroundAudio_ = false; @@ -1401,7 +1401,7 @@ void MainScreen::dialogFinished(const Screen *dialog, DialogResult result) { restoreFocusGamePath_.clear(); } else { // Not refocusing, so we need to stop the audio. - SetBackgroundAudioGame(""); + g_BackgroundAudio.SetGame(""); } } } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 1689e333cd..1ee82a3620 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -271,7 +271,7 @@ std::string NativeQueryConfig(std::string query) { int NativeMix(short *audio, int num_samples) { if (GetUIState() != UISTATE_INGAME) { - PlayBackgroundAudio(); + g_BackgroundAudio.Play(); } int sample_rate = System_GetPropertyInt(SYSPROP_AUDIO_SAMPLE_RATE); @@ -1040,7 +1040,7 @@ void NativeRender(GraphicsContext *graphicsContext) { if (GetUIState() != UISTATE_INGAME) { // Note: We do this from NativeRender so that the graphics context is // guaranteed valid, to be safe - g_gameInfoCache messes around with textures. - UpdateBackgroundAudio(); + g_BackgroundAudio.Update(); } float xres = dp_xres; From e13b53e02cb396acc781700fd2f40a667d1e64e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 19:56:57 +0200 Subject: [PATCH 418/848] BackgroundAudio: Switch to a heap allocated buffer. --- UI/BackgroundAudio.cpp | 10 +++++++++- UI/BackgroundAudio.h | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index dc585e6a0d..defc30068a 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -226,6 +226,14 @@ private: BackgroundAudio g_BackgroundAudio; +BackgroundAudio::BackgroundAudio() { + buffer = new int[BUFSIZE](); +} + +BackgroundAudio::~BackgroundAudio() { + delete[] buffer; +} + void BackgroundAudio::Clear(bool hard) { if (!hard) { fadingOut = true; @@ -276,7 +284,7 @@ int BackgroundAudio::Play() { double now = time_now(); if (at3Reader) { int sz = lastPlaybackTime <= 0.0 ? 44100 / 60 : (int)((now - lastPlaybackTime) * 44100); - sz = std::min((int)ARRAY_SIZE(buffer) / 2, sz); + sz = std::min(BUFSIZE / 2, sz); if (sz >= 16) { if (at3Reader->Read(buffer, sz)) { if (!fadingOut) { diff --git a/UI/BackgroundAudio.h b/UI/BackgroundAudio.h index 04adcb8a25..d5d8ca7f18 100644 --- a/UI/BackgroundAudio.h +++ b/UI/BackgroundAudio.h @@ -1,23 +1,31 @@ #pragma once #include +#include class AT3PlusReader; class BackgroundAudio { public: + BackgroundAudio(); + ~BackgroundAudio(); + void Clear(bool hard); void SetGame(const std::string &path); void Update(); int Play(); private: + enum { + BUFSIZE = 44100, + }; + std::mutex g_bgMutex; std::string bgGamePath; int playbackOffset = 0; AT3PlusReader *at3Reader; double gameLastChanged = 0.0; double lastPlaybackTime = 0.0; - int buffer[44100]; + int *buffer = nullptr; bool fadingOut = true; float volume = 0.0f; float delta = -0.0001f; From a0922e7bc7c3cd2fc86accc6e80cfa2a21eab47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 22:02:38 +0200 Subject: [PATCH 419/848] Initial sound effects --- assets/sfx_back.wav | Bin 0 -> 32420 bytes assets/sfx_confirm.wav | Bin 0 -> 45268 bytes assets/sfx_select.wav | Bin 0 -> 27724 bytes assets/sfx_toggle_off.wav | Bin 0 -> 34148 bytes assets/sfx_toggle_on.wav | Bin 0 -> 38348 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/sfx_back.wav create mode 100644 assets/sfx_confirm.wav create mode 100644 assets/sfx_select.wav create mode 100644 assets/sfx_toggle_off.wav create mode 100644 assets/sfx_toggle_on.wav diff --git a/assets/sfx_back.wav b/assets/sfx_back.wav new file mode 100644 index 0000000000000000000000000000000000000000..85ae898c11a48b1770b9bff5a93d3d109bd0b3b5 GIT binary patch literal 32420 zcmYIv1z20l6K|A+ctS!TkYJ@y+zOPoK%taEONF|-ySv`H%dNXnFK(r{ySoPB?k+Ff zzW;mQe7~LDo!Qyh+4CLQvzweSYu3xN0Kl>tOXIfgIqZxB002M$2r%;p0Dwye0U!Vz zVDpB<8;)CaqJUArSYR|T(t;RE8f8hNfzvE}h9wtesfo16V}a9w5tf>n|4$Zck&Wv_ zStQZ_wf&!s>6RA%zwHc5eq0h|NoV}W$7PY0R^$E7u<+^s^*An#vh+Ld#kl@>Y223? zmVP6FaTeXF7HN!ykNY<6@wo0djobh0?|AK0i@lkay1yeC?v+>t%oJBhIKdpF+W`sp+rUid(jYn!c9#bvp|3)-!=db-4|MfQQKixQs zeB4T`#s4UamFWMhL|Do*Egp}L=5L&)S$r7xecZ-hfBwd5+_M=Ly~zK@{lBq{$M^3@ z$F;^s|F_NG`4}JL|DrPP@%S8#YmdiyT=(x>jQ2bqzrU^jdOxoDKl%S=|F6#Yb?|q5 ze`n-xX*>?&*2d#K)56DN8f)=%yk>k(WB==8Joi^RK8xe?Js$c0MKa<)z45skpOtaz zQUBM@xX0t8`)fbO61{1b_W!$b#;?S2%}5I$*ZF(BjF0wj%%@xI{VxjRwJ{d@8|866 z-urmFnHH_Zz$L)Dz}rBMg&u(JfsTL=gTFz(L7c6et-4{Iuzc%$>vCiXau_{|hT%Xs ze?kahJ~5uS-gc|)X1g_Z$&{s(07qX(6V*h`a7uSt>ax^j(6!ff)`U3|Zn|G~e>?I0 z#N!^vJkXv<&jimoo*tePJfCFVd~9JM5YfjnVvxR8w?$+?kVaq zwSzlSnm;rL)(6xxtJqb)%d*NEi`t4N6}T0Ma%H(r*$&x_8BH0QG*#M{)UTOh1i3ML&fa7Hft8^g5aEBvuvv@L;X`tF;ERh&4!Vcoz3Oj+|hdAe$qe z1DXe!moz_dzIMKD{_F*_7Q`%wT>xGHTyS{);rZX@eVcbP>1q;wE^+SE#E3*qygYt- zTx=XM1{Jd>@?hk$h(!_YliMcK14aX$c|Z2nyPMoYodcaWQZ`eHh=s%x*rV7S#BW5A zRi4!)@HKEaFc?^DE-_o15$4CHho(&ynrezL1(^a&P9|rQi-l+=iiuz%n)pVZ@u%^d zai%feSZ*jXU=4UfxIR=rSr?*%XrbCv%N$HpxvLH<4k|v#KFJy+)e?vpCB7rPC`=Zt z61?R<b*r1ag5O02H7%s*ElAc73h3 zN(sorbEWse2V&3SXI@j3TxZ zKeNRAH#?twdhFB~dx$-R@5A=#JM+aPZs615pq2z5z^q(1jcIEBJo1Hy7 zdnjWtV@7&Z`pUG`Y4p^g)HfD7YN73^TT)k~u1Z~+x+rytg%(@rOzO$hiqxvqgtWLc zLz*c~mM%`GWIANt%(|8}IVUW~HIJ5;^n3pA>_3@*))lWSo>3N6wz6_%<+qxzHM9n5 zLv?da^Og1s?VG!|cQ5Nt?oSw=GaNNGeaw~Z!XDub^G=CQi+ZH(QjS8Xc%gozhU<{J zxrPM8I@5a74!~AGCMX-UAG!zn4*nLt6158T7WWFbiL{0Eit>yy#d)gpq>1hmXZpfQ20k+ZWDFo|}9>`A%|ba(Z%2 zaz%1Oa$|Cvg}Rd4lRGVGhlP*lTP)~EZna1oE%}z@W{YN>1x=Q;I=MDED>*ayT=JP@ z&t#9}j|)>40v2i)xGeBo;5y%N{@0|hNm+Ap=S)oqNeG%1I;$n7F(x)DHmYrE>(rv~ zqVOr9VWFEsHipa$o*CQ~)DeUW#s^miR|Jbf#39Q=mxW5hL}3r6Jem?X)o1F@X=#>+ zl4&|MiW()f(Bv!06t*H{O-OY> zX+WV*sZYFTtmh%OLv9hYsk9QiLOVUdNFbwa&^9nzSOCxqxLLnLFH&-p4U$&LB!Qbi z&Q`Hw8PN>Yh;k%*FlX>i-_5>7-HW^JI>;T}EnO}DH2%{VQ5Rmvt>RRDFaJ^gu;gCJ zgTj9cJAZfoUY55t&od_}XF=ANtd5NRnfd938HThg8L!i-Gd8Eq&P+WHJ5>~xW>XxM zmQs8sZFPxT`ufs5W#rYqVg;33^d(0<)kaGtgmoTfoRmZ^Op z9m*((y<#?Gx@tVWQ>=RjYmF1T{!pHksZ}@CLs0*bC|RBEjSQ0#GG^H*n#TCy}m(ciBIf zdY(2d66&@*I>=*i2E;ohCfKhn#t@Javp<*;^KkO48Qa2~qD#WRM1GvYm^Lt_EMoPP z#o>hT>yrVYdxPSFjef*{WbaEp8$8~7Cb&JHKz7>Z+(Mb?_{dg3-a#m{If-e*HXW6M$ zqx=NBD4z`n$@K7_k^<`o;unY<(HW$Z=m4rgxCxytoQfF`T4TLL>Dc$8Ww;Qr95*Pw zhJPlpC8SG72n6|n4PW6z@>XZqa<$j(9E@3%27m)q3TbzGVx8rhi5YUAPNYrppq%wt zb3RztDw zjc$?-q*<>;D3@z~OM}&+B9-zVUX7xQ^n6+{{jCOz1@&! zMeX;WD4X*i-)P8xe6M!n6F_y_Q+h@9b8NZotA(W>-ux<_|K7R?^Xd4X>d%tjtG=Dh zulzAFui=*>=S~_bN0+`oo093A?URMcj>}HSzM7Mtt;$`T^E%%?_jCav?|ETTzNmQU z_djK|e`ZyB6wj?;mF}wtSGF{rtx0T~+92r+Z~54}sN?A1lb#Lq`hg`(6n!Pvp1DFu z@`98&ZMXe_nX{-*<|18oFMczjeAS4@ij6WlMA@Y8y-{n|Zp{l82s3|Q>m9;kQ22VZlY z9s+UMHF=-Y(a=0Xc+LsUi?_H(xzg!`U(F%Q`mlVa#U8lm4>5cnIHnWZ+fTg1%`TvwNUz+qz`U zw>!X1Rc%We;H{-~Tbk$87BzNMhc&FJs;ld$cvQQv{A*1{sj-??@}v4x(c@~?pQ`FL z1@1NM{BJc6^O9;;=Nf8P<$SI?l)b9{W0t6%oq4vwH&fD(nsKFZb;h)&bs4eE?HQL_ z>NBZr2eL68)wzqiI)2M~-WAdNvE`IuyP5~19~vWA=iANP&%JFz*6D zkRH{St4fUu-BNR)NpFq-d@}n3H<|7MyA3yiKKkjvhuQ)FR--j%t8nHuN`(=vcx%Xz zdFeMuPiwW}FX}g<3}u+`k-Uq)ReGG~BzED-1QND_r)I@)qgev>5YwJr&CF*}S!z}} zE1%uP#&P4hl{_rJOW-MV5g!-lO9`?wiay0wb(xxCd53&yP#d(S2y=wxTlENd5jYbX z2F1YLVCO6^swA`wQHbqF9VcX9JW0E8jbtie3gxxU21g~)jix7UaZ0tF;B2z};v7eo zIG-RRT~f&kXCC>Nvz?v0bF|$~r$u(_Xwi1|RFvH{hfn0M_6FNmWRmSBQY+EbCc>s4 z7lg0J^kC5F`KWBd;MQm#>uQVv z(T2N=4!0S@iAbYFncZ>w5XWn@3@5!?qT8!UhKW1DW>Kis z?6cvmiEF0pm^))i##~r<%AESi>;#wKYw>Xbg)>+9UYv2n%Q!vVgB)S)ZkT-B^?9Jw z3GKU|y2w*bx!`u*?h%b*n{Hof(@8vocf>8izDCYLFNbYH9tVH6=9ul^4Tf|pd);a1 zZ}lcfit;qLQl1BLl950UC0BuXF&pqqI2+(Bcwzp{6Pu`9tSO8=XaF%+>hF#|(kh1E zspAKqDnIpImpk>`kd}A862ES56TWVpBq(cs#4|U#apM|_*l+7@vSc;;n2FUl8TTrG zk5!cu#+apNMp?zc(W=6G^nVI`>5lpJBlmN5kFYXPBee9V!)t%J4}brDYslv-W00L< zGsyc$8kqZm-G_g_zc=w+dbjrN$Ic1wPPNy)ThYpYzqa|v$H$G^Q;hZRzogWmzwfGD z_j7X1{Zx4M-t?Brk&NdR!L`SDIShQJzq>qAH};RI{+*Ykg7k#-`Qn zj;+z%!|e(6I^o@t8=ePO5`EsUwer_(NC-^coDy_x3p)7zmMcNFTfPTQ-265`zA?rB zpAA3#RO^(!Q`aW>o?b2RdA;(RPxJCyK9Z%!eFB&4^*O(2vyW!sHlNoER{NZqzs2Y2 zyyZT^q|H9JllJ>0Cq4EFNviX4O|thTC!O#mCTV;zN%#D$lKlLu=9c*Hnj0HXHRpMN zDUlH%OMnJ8&2|hV#Wx2iXSxT($GG~3MRoc1PF?L27hdCaHzaUUYrq>1im%JWqm%L` zDBL%?eROqnJ?hlreA)4;({Fn!&4yg!Xj%1eAQIl&f5qy_LFf&(Ifzc8BYeKiJ}3kK z8gvTRVfMtrj6LWTx<{yd^(thXl7i67nD8;lTNp~5Y_(6wg-`|Sz!?4;;56PF^Ed8d zV+@z4({uJ~$~g|I+kj*tv%H{z4~;|^vcrimF2$OIi>YoK_xG`x{D5U-6)*XHSZ6p z%eSDd)Bg9lPWOCV=lr|}9S?H*+JU*cw(B{())_f@Ex4Q$&ARNMrsiyDJuX{W zw>Qhat~B#dEjUwLb33E4CLu#vb3EgEEiUt1op;t~eO>m?Mo})S`R(uPZHlt0Q;rmzdOe7=kEfmmcdBohG_D{x>>r7O5Y z5eR}QdH|iWAoEt~G2@UpUmqy~>YfTVXmq?z)mH9qC68^Vc*x?*Rx^J~S1=w*ZjJ2` zi$`NbDWegVD|w!PH+qM^aSXyIFn;n>j2ApItC6>zJ%g|3AO$%*im+91LqrybONyim zW$zSk747N;>N)xl9n_p;6o5_wURrGedms$ZZRj}o30x2&*=7g{wv9&LwA+bcQ08Op zsb(y}X(O(}`3%n2H3H}4b`AU5Z8PS&+Yc1T?K2|M^%^|XWvdm)c_ZW&Z9hoq_zf`4 z0b$;0|H^omyur{yTCJZ=e5?c5Ky=oG-`f57Z(3J;n>HRlMOTP#(mfzt*8j0tZ}27s z7~5?@rjK^-Oh+j;<~YZN=HJu<=04g@^GT;W=5D8_X1Mb+Gu8Q}IoSENd9w2xbGY+! zbCmNZ^AzW&=1Av{7Q8S=IKMMbcYbBzpUhL83oNo>^E78iK&bO3z;x#hfUk2j5a9d; z_{fO|G|=opG};6Zi0TMRa{z-TP}snucICiNwvT~D#5us11Os3*?g_w*o(cGfRG8ze z^UXNe12YZ!-TVR!0$c=r0%(CBfC3;JbR2XQasj;F${ui7eV-y%Qjds>~xoeMGr8~@{(X($-ymzDz(pTxr^OgG5SQdGX`6zv@yg1(K ziCZR}b-OdM(&??6z~Q~Kf}BQ05<4k0oW0!w)HTvOxQmSwRE4VpsxcWRZ*+tHEYeYH zu)d&r2&XF6!&;@0R=MJ(&b8y4Pe8_Wb?p~pV2r_pzG^{XioPamC8<~G`YP- z^rGco{y^hSj!pecW>QVS=s%S{!+*-c24uy_y?%uUyLSCfZ*R^;w9d`G*JPbJqd}17 zSw~Hcs=4&@W!20d!Ig8q+f{u37FoXGTYlN@Z^z2Izuhmp^qpUJ^~aU+@}CWZ3e8}GGOG=J}bXh4tGquY0Cl0E>}St zCJ>=7JqU1`_j+WP9}e3bWF(A+x{+~HH#tm+`sx%F+v|pp@A0^pc+7im(sRGU`Q*T` zg=Ilq3$F*CUbr~8Y(Z*J&HS>!(s|_pl}Wk&U32sNuybpCH_Z|Huo6Rkt|mV4UYh9O z9iEu$<(zodi;}p;3!WI`1xuXbWlZq&QYK9Fk|j{QcnNl1V+mNV;RI{1-UNhKYXZcp zA;HnBFd@W(9bQioo_Wno$n^R+`@2_B{0*<`v*vo)$LS{}$6lSJj{f3FirnCl9#P=V z4J~$S2)gWY!_UQu>h;d?r#qf9)8ztr(DJ_d(ryP~15tsUgWH9kgR(*%f}er6L9DIT z0QZ31O?3cIJ<+sXvrx}a-qO65XDMGxm9lnmvShAEA~Xw{`E5wmKIaPaKKm;34J(tmgNb4_jh$rG(V48f!&J7%pf@|SZ;Tb(lfX*toX-qycV(2f z@JF{arP7@mu8$~c4-Ye|j}3vU-VMf9&_fg2nx%1snTo3U>Fm6zuPBE4b93R&ct1cfpZ< z`R~O3&A;vXzvWl-@$xqHIplGAm*+0(Ey_vnS(szpu zK7lSVb&s6_<}){dWvtzh73|v(47&$>o7D_bGS34yGYNnZ#tYL02G$tNc&N8wkae1| z6pd_bmYOxDP;$mH6eDAI@P4}_ z1k7;+SwsV)Q7)NiwkrU$YQhkDsrx20-Tf3w;2wh9>weC9^Mp09HrG;!(pd*o({Sby z#~_1@lBo5uzo1Gd|CS%Ib(B6NeGw^%+XNZJy}SZqF^5Fj#7-w|XI;0gWWFTdVV2wF zGEtPdtZ5Dr>@|)zIWbgU9-V3{2%?3F*3tGzPSR3kS7-vo9U5MJpN7>wq&4au(c%q{ zXp4=HXjs!@+9nHLn;y{$EWFObyG;MmdQ4Af!xlblDUVn%W|57U9?+PkXO{du8pBd% zn6A)NrbRTRse?LfvZ1~)fgI*p_h~3}YMz>&8xj zwPVM?vau6jrG-n!j#%<1!Sb<#V2MSRHx>j2j@<_F>Dz!SMh48Ahv-I^f!F%my(&#p z7eO`J&X+M-?u$i@E&^En9Zph>no(G}fxf-GX>eKTlD?b8f-ZE?r*`I_i!F#h*BY-B zJyZ;mndHMfSz#ikB8;mv9UFN=FLWWj;lD<-J9-D%y)5 zS2&bbRopIPRRmOMD;Sl?%G_#V<;_~R$_@2CmF|t9mQ|-2m2+DXE3dXLtUS=Rxf0oa zt1`B|x-z&uqzcqtUe(xkuliftotl?z<+Y#MV(aN`s)mquY18j^-`0H{-`nSP?&wAd&CikbrHK97DcRc zNQ_wF;1`kTV4gDDA$Q7jhsY@o4rjv~DVM`mQDQ>N?7Ks-_TItM?TCSJ@^Qa)q?O)D zHXR;qIKCSKQ{;q1ZgLobNo~JEt`oKar(%LlXar6_!3wY04GK_#%tvKxJzGrFUJ$-e zMe%ni{JA$}p=_CCKl8n~WbC>qcr-;=Ji--h9-b?38Or7Z2dR8{|9T#z{{q*$FPXEs zm(J?w@nIhCSvR)0=NNr$&#mDXJ#PmIy&3)Ad%JtD_UXIN_Rr}0Ht?WBItXZAJbbgY zZX~EBb`;#4H70AsFyW2US+g3#+28Bg?BM!299G>m&d<7EoSSuJoPX-NI7jLREu7Ce zS0~}zs8e(9)&aOL>mb}$btrCH9gh2>&Vl=`&XK#a&V$RT_2AB~4dtG%naq7rJ)Qfg zY6kZ~S&g z41=z6?bDP4M^+%3l$I1OTCfQZ)sLX*6kaGlaa)~HI9weQs z$d#j%TUBD^8ZAV9%n+byF+b7H0b}$Wt31OG#4*!x%nHC7!ZOe#+Zf12doFaRBL$X2 zW5EtNPlJDP@rEyR&4Ar=Igi2`3wL0SQXSn!2OXc#cTp4Qf2iT~ zLF#6@j#^1KQs<5$XwWezZFme$V=u#yrDOVLtEBVctMFXYR7IGK*}Nn7$G38r=z>4O_4o`dg?X-M`lL+Ba5W zO(uAvrWtTeO*CQDd-V+}v*wQ~UnN!ju&fOB%RDu)(jcu&d|$^9g&L@$VAE6KX}}gC z0=!4q1}zXifyawZAVK0_j9je586+2N>}68Y6uE<4jKW|)NqNMfR(aIXUNz=8s(k3^ zqrBz7mox2O$ZYJ~q>i?E;)%p0Q6NDhScc2zU&j2)>q6b&#vtEvYOLGYr{VtW1lT*) z467K{MyP`M2GY$WK?<1o zYGxh<^)QctdYMN+!H=3x-aQWjb2GnvysROTz7E8`BJYLslAKo2*@4ioj$2A^ss z_Cr;u-at9Bd!uAx=NaL#_P0DuYdiZ-i!HOfdH<+QbN}#%rulHeKl%YD(-{ z&>Y&qZH{hx)N;CIYU^-QU+eM4#J0%||F(J7ziOLbm(phWd(!4to7vW1^QSGPrmF3! z1z&4=+J$?$b28eSh=)_NEp=dqUfRj_!6s z=iyF9r(<_-*Pk9>&#Jyfy*>SXePM%l2eu8J7+N>{?}-0M|EOYQDYKStV5g4O@P3RH z2x}NWBxdF<`670*s*EGnB=UCZS^N^?E1|%=Myv&fN?X80`5CBE!Lu4wIl_xHXzMq+ zZ0l`?X$Tk7b40$m8sQIQB2I&95wF1mh)xIqX>YX&c@G9g`B)F4%m_3Fiav~;jt#_r z!F$+55!aGNZJWs#?blND4tCUKv@WM(&i7q6x%#*RCOq(ncYim@b7G?R-HAJVc1;BN z=D08LEu3)1_l4Un-#xBRe1lyc`+}Vx__oj<`esr8@xAYO)%UK$G2g3{6TT_-JA6y* zw)+C?R{O@0m-~LUP4>07o#p$P6yqCBittqu1APmK6yJM9sn03mPoGW16+T;uZ107{ zgWfBNbgy{gVy^|nUz5U#{hkOS$0Nn2c%qZd3HS8`;)HYf7*`t3#yJ^tiV8*Dq^z~x zNM2+GBjUl&aj(t3Xj?;*^;OMdE0FRW___2uV4(O-!tEx&UHdig@n-u;44J!QOv9xRvCvxN=q>1LvORx-SM1f#Qi?$LMk zM2wv80S-UusULjX^LyY!Pe%Wbp31(u9$7E3cUtf9-WNT@K1xq-UsiWr|F&+yKxlX9 z5ViaBFs?hCj_w{C#dqIekh*8F?7BzTuH9$2Zrxm7KzE=Zq&reLts5eW?mjO{>Mjz+ zbhAa2ZiA?x3nljHB8U%nQpJ}$9K?6peZ||_0>$yI@nT%dGI4Ly0r98CJK_@!IpP)d z4DqZwnq*P!PRX{K5=mCIzZ6xSBYju3T(+XhPM%n0mLINyD?6&9R2Qq?t9RA}YhTnV zblCbHLv6#bsia8_khge%7qurtM>`+EF7$l04(NY|tQrhQ&mXyic{X|$o58Tb?P5*9 z6|oz!_c$#W9p?~w8kd9Iz@36P$-N7I%Yb1 zcN#7V=3Bm=7wQs32emuI<(kiuV2!P;LH%C-K)q3UULC1^p`N83vE1j9G=)Zn#traX zn*lnYn+08?SHpH0(h)a}`_NUU2%IgzKsW>}An`zl?AAb-ltL)qF~@2>Z87YS(?2j9 z=UK2F&flyKIj2KsI`4omow`BGoK%4Kv~E)q^_T%hb<{0)%vU!%oKmiJSS+VHtdlY+ zx5SkciSP^Myx=q?l0TIa&g-;a$X#Wh!jaigIIrvq+3W3&vuE0EWc%19v0d#Ju8Y=qq}Hq35_4Yc#(7|AC&X0nhYChz9z$S9tOT+9=YAMttQivkAuu8>Yn z7mbiL;(qcRX&3pAteqU7Xd{;@E6LI7U*s0eY4Qx+RPs0dur1$k%obuAATdk?(gib| zXu0tatN^R=E`TO%FaUw^2ar%&^O*G)^KIA!Gah=y@^`+}*ktAzoQ)>^K^W zR>o=TWhXR8B{k|qQK)*3pj~x}_edq;+*93S7pqRQCaFI#8`UIcfu@Yntu12A)QcE{ zh7HV86NXg}7+|5no$P(k5snmQ;9fvb`8Mbf!Fg18R3lj{YJNYM3nfy59D?T3ah!3*9!-v8j@tt6| z`0-ZH__v_{^7|n#`3aC${7Ud!{z`BPUl01k{{#BLKM(rFUkgg(CxY_$(?PlX$)GBJ z2&kPO021>3L3lwRC`#Z1x*+faHCqrYbO)^#wgYDiJ%Dln5wJ{W6*_`$MgK9pb>zm- zpW!=$w!_ecFq|N>#Q7})46QqQm0|0qqCg8y6f4fy6fp! zb@x|BZqFdIsn?%P=zq;QIN;4w4z}?h4L=vg(|3#UVj}3( zSDh=wZKf;LZH|kZTa@!8H=@%7w^8Z@x9^Trw_Of)ZqXEi8_FK*CL=@L`fVX@eI&Ij zgQ#~!5C>gDZHis55-zxQ<3nAO@f|KLxOFbuaZG0i+)C#bY@5?3>@27A*h1PaY$Rp1WGLmWWO2tl>E`Ui?kKiZPNjHftLbj zVw+5LsE7K6h{>8(7(=lR`beqHF=?aDm-NbaE#S_jkjw=$Zs6>6M}}fiJXRBifspTB&dN> zDX;IPtgd&F{AW+Q{C@XD#l@~|iZh*W6qh^d6kpmw%8oW4C9Q3p@?z^trKzP$`J#oU zTHbO%HKnCh711(9y{)BKo!2r)6WFTM^tTpi-?!b8}uP(xLS%1#RGYlE_n~oWj=81+6K%^lKZ27edooXnv`q%IX4l%And@=^3 z7MRRvZ*w^o40wRo0oK}RfQv{b&@3_*ve=#kb#ds1<~b%=0cdNi%rrNvOsDhE3C^D& zi=6j?W1Z0;qtjNvey5kFY}$K67d2hSbS&45IH*(=lqluD_J8CX?Uu@-$ga{DTSv(j zQn)ykcuV9=R14E=9tyYEBnd-os6s~@oY2|^C^q8frhR6^Jz{!E~YPY{ksrV{W{ zHoi`J5`Rb5gWE1QVV5c-m_^Dj=oPA1)B*Kx#8b@#>wK+c&zi0eYGVk71RGz2VohjZ zi1~zBYHl|!0yrCv0M_d!1D@^x7J5+OzHCr=z z(?V_>U>a`#7|(wIo-LRST_J?P=8N*+lf_90rMMn>LV`ipN*pn5k}gb%WCJ!wl8(JE zX~*7_G++-){>2`X%*O7MRACNFCR=a}eMIsebzJfbc}9|sI3r25zA4Fo-;&h8UP0WFm4funK_ z@S;Kij8rOtD3uIYpehAURVM+@s4oI8s*jl$sNGC_)nmhQRln}760B`dAk@8bin2}S zB+rzFOHWExiM_=?gmprg;E3Q2Zz?~5>%{Zt_;UT(>p5F2`#k)Z}(Lu%A z(NoGTV=`qlW3Flz^MUFBt6WvW=BUEBW>p0bt3D=hQ%@B|s!@{DYJs#uT_q3Iyi}%Y z)~n}ffm)UJqVA8bNqG+G1hOtDPf4M`EW3q0?C(~>Oo$vMKknW-WB~3;hC5e$MN!iHFq=(2Oq@&0uq?O1YBu`{E zsRNNu+JU%3Dz&l?=(0fx@=CJu%0b`Qz88AGXD*Wqj2JHyMkb|aD8&m(T!*>nn5O2={Ej}o}6 z$M9Us^MPB#pm6syowziXE4Ps4!JW^Z#2sN=zx)S$LvlbVx zrDLshPS^(B9Ly*EO!P^E4{Ec~gh({iSjU)ez(WD6Vbg$5xds!1lW+S*vEmg?_mAo{&pH{EjGHf@qVS2NRq*SHy%s#(Sls;j0UCBTeTE;2_c zj+nQ|kD71FW|&i?3{#zCqlqK#G*ZQ3#s#A9hPOhB!6^8wKP;G{hX{B&%P}L}S^fjv zD*hea9{yL|4L(oT&X3Uh3JUe_1#=9+LMvmlu-SM?lwpbzXPP0B3_z2l5qM8J2#S+Q zz%rR0a#k*Z^5jicev0d``3gt)CPg0nxFW{-vZCAisbV|glR}NiSKL5WDg?+OMGT6s zSdD@z*P=*Df7E0p9hsm!irlBuG^+9#k?-D1!dy(`GqpaH543}B_P6}Zdv3OHbz4uqPY1GJ__ z^9xgr$z*(FoMcQiAPfV#a@`i~3N2eLR_|0@u4Vu6AmBVzCmiTe2;L<4-e1!3Yb{xdO)uMjKwnase+qoIX_+9 z#V=O>^G8(A_?K1rd>0i!(574}xT|ay98hi&Zc~y(my|qFv9euE zRgFp>sX#J+^$hu_`o7|eMxnf^-J;&78`A96uheZabn7=66O75GEK{r*3UCI@25JDS zK)Jw`-~%8#2pn7rc@B<*T0uTTk3tYuBaod|OQFM7-OwelbykBgwbd#33mDNl8Qx)y zx4woLvEGRMjR--#LfWIRqo9~$Xc@+`dj-1$+lHHp%fj2>?-K^_^KGsYfJ7IYo5ZU& za$=W_4@qtlOCl3jk(`K2NHpRG5`?&%#IRXK`fRh9wA1qZaj=Od)e;D#gM?}#jrI~ClZ#!7ZRkf1VSQ=hd*YOgkK9y#F@b$>;ceD^c%o!WRB^S z^#{W;*j1e~bfZQAid3}$ycJcZ39>#zf&{BSD%zqQ5ir&3_%~Dp-XbNNlc?aaH_Gws z*RoA4qqLiORJxyumrh{jOVo^mk{-qsNdv=5(#aSRGZ;l;1oN|aD)Wi>4D*(_i+Nq_ z%epE4z`7yEv+s(ZSwP@C5~px3i37Py#bsQmcnR;3NWg=Lj`P;XKV1}w{m>@NfRjUqXz0vGtZPk8eMeDj*Ks}D#s-MBWX*kA?G-k5dMn3zb zDVPH^ALDE_H*uQH9$Z(zUG5El6;BPg#M=lY^O?Y0{!Y+V0TApbd;?Ys6Ck4^5VTob z0_~98v>K5vgXv{HaEihRpQ)^~-mZFxxTl_j{Gm}IbG4UIsX7Ddjy?$;XE=p68lItF z8-JmbOn=aPQ$6~jxfdM15<+}XN1#`b zMrZ}%Un>YA66Rwqf^CKuS+3N3)yS5zd>8xepM`jcU% zx>bK#ZKKasAJqXheC-0wKiZ!fZ!JzM(VW&+Y82XEnj^Ze8k6p`=9d18#@=vEbJws< zqc=>@EHt*NpBN9S8;v@Z+Ol$iHW`&proBp6lThJoTCX6QM&tm~X8D*=EGsqMk=-)} z%2pfsQYYh2snT#;+GaQ+tuP#y)*Eg~hYjgcj8Q0^XAG5nG(MHVOhEZL(Xny)8&n=3hN=;?N4*+cqvn8}HH#tfnpDU!4H$Y?vk01|`2nrb7@#8> z%lDxs!^&Pug@tO5!d7Wnuru13@Ne2oc)u25jnFNzUZ6W;eOq_Kx=(k~I!K>jeO(W; zR_WivR~drf{f3{gc}9EKknyP1DpLV{&aDot@yC06vQ zyp&Pui^?K(uX3Sgj!LPiP<_=dQg6|5)gJn%8mT@}n`uDlE*blEvrXxGg!z`C)_lNt z8nDO|1e|7W0a5|`KtP}z)N9!f{{=J(-VTn3I6!VeG9cZMSSTJ^2wepYwR!`6Z6$|- zU^A`O!BVVBU}%^h{4DG>+-P~0oQFTPJWD8u&(_}&35YNx57CIck6eQaLP=3Qs8i@2 zXfs-aK8)Fd8O5Yy{INrr!`NZWzu02T2kbLUDt3hhwwQEmEBY7qAM{Ub6#6SxhWd=n zKz+gOk3u zXTXit9snNfm1(yX-q;H{shGaNMl9Sk|!b$iCJ`2yiqI? zHH+7Yrb&i`za%?_UQ)C$MOrSHD7zuZkZlu$$d?Q1n_>eAIJgU1OUa$Wo?$$HKOAXeN z9z&#LiE+1tWqfIQ=j@VbOjzl8bD|Ulcp`lb7?w^1M#$3tPfb?=AJy^vSKd2K1Azp0 zhaiDKf+c7KlHl&{8azO8_W~ujI}}RM0!50o6nAUUmg0?^JlXw!-|_o@-e+#s-|o!p z%+B83E?u2bjX5&+vRRoWd5)|(d{0(3Z=2m&`Nnfyx$SAJ?(zPt&hW+BhWpRhI%@Up z&GakwSfha>(!AuzBdR$)Vyp9_^g5@Lcvl&k<~l;xx+=4St_|#rOX0U%{rG*?&-|0i zt$cCe|Ag*UN?!LPrK&qzjdPDt`?#N|Q{6Rf8{7wMhumfD=iLYF7v1$7``k|*)7>-i zuk=XQYu5+Y1lKM%cMT1i?hOA%b!LAv#c?3m<`|k|kv&h&QugCH&)FhF`q`F-_|+>R z->UaRbmfnbuFATQ)4Wv(D@fqUG04YM~m@ z3v01@6>W~*OuMTO(FzzVwc*Au+DYS!7Gjprdznf4k7jTEUo%xNBzovkB1umadG#jZ zsa9Wnr&Sd-v^?UupNLWZmu8s%cXOBTuo>^$YX0k8Z!UtZsqfus8lFAoCC^oJv*(35 z&*Ko&JQc+}Pdl;IlP0cub_nLZE)u*BxyIXAW_rJqU3`DZ3%)v}wto%T={HCrtuLLU zouePLlB}LSf-Tceva|YU_EE==;*5s8oY9vzHJ0%{#sNOpc+K}3F6EBVP?1Ke5@8-t z`kHT)&1O0Ewb@@SCHAOeMV5M2MBDPoskUMAitUQbvXvzz?9)iN{V6G9uR(+CGw5^M zHM-U2gx6Y!NwphWtqx=5)e&s3(u##DMcH6}i|%8C=?nUW1k-M$Jh>thWMSDuOcc}1 z-_0FHdGo$L+X&V(^{(0w{h;5Y74k3Dmipqg!alop-22?$&3oHl)O*eUkLO?id5>M& z>#3`ydnRe?JilqHJ-PLrp27Mq&nf++C)haUNieQ^CKz`-^NiP?g~mJ2NF&RWXfSVX z!|6S%=k<=%OL>F!8s42+vNuNS>3!gz;QiLW#arJ0v-cn0C+`8@H@*eFB;N$zG~XoO zRo`M?KK~Kl5dUZ24SyAXS#7C*p7zH7QtJqrxTvkv8|WYOi+Y^V*hn`X85u@5oNJ(& z+sv85G>gejVxK%M8jyVQ8ksIT(dY6JjUye{esYlo(`Y`1F6VdY2VR{;DNEUS0DKx@d&lF(o0>StWjSmchn|oKHFinr!AlDC)+$5w|}t>uy?Ybu^+Kla)dbM zJNh}^IZiriJ99f{I{P`#I*&WQI9;v~S8G=V*D6=I>n=cX=X8~K|L3gdKI2SsFL5?? zcX76IS97MgRcABzKaOPg?~bPK~So^jh(C*y>#e8zfT7`|}~ z$!O+tX9W9#Gj4eEW(@Tf$SB~goUzRlkx|E!m~lQkC8JgL;EcyvqccWkEzO`=do%WC z{+5xH`6+{D=F2>jk&rnpV{B%ZjANPAGXBdfpV2t0XvX5Kav7Of`1f{p>x^^RlQSYb zn=|%#?q-C0Y35#U?aWBu$jlSIy_pUCe`j9sm&{7ix@G;QZOBU0A7&lbL$fOyDcMVm zx!IY<$?SMDEBiaMxaW@9-V-KfdfJLZo`vFt=eh{;sAU50xN5k{K`zR;{&JOYm2;cUk?woW)9#f{!`;+bGw5GOm!JWTw4hh^w4iAF zsGudb@UpKX(V(>7E;YD?DBZPoNNTQR+xt$<#@7N$Q?!}OtQsBS1>`bZ^@ z{)Fe%YXO$9g8EBZP>-U8^*N-7{z4Yf8_MGP527TFJ}IhiH^cSnW@-F?I$EEI(@M%4 zaeB7iM*l_cuW!<4>Pz&^`c(ZleJ-@v61|+UP48@+)K?pS>Q4>3k>9Lj^fh}L`^}|B zmU+>rFTBPaQOUd|dYF0Sau$}`WE?0&y=A?H0f;2Cu@w~$txoVEn_CpA?9ql(>z80F+b4!A}?z$ z>aua7JzFnEu~Q8A=a?cavzJ6r`R}ojct;z*gWy;uqw;EJP;C&N8puEY67xbBIVXON$f6Tlgf0 z&7bw46}lkOH>C$YXwC^%`OtPFJ^n~ zs@X-`WDeH)nIp9-=0xqSF-O~CEYx}#tF+w4dhM0ISKFjxpHM%gCF^Ikn)-FEpngxw zslU}+x>pO*L-c}r1--J~T2Iy|>qGTJ`g;98{fb`Auo<(B`oXd3ouzG988(}x;jEG;>@QZ4 z3pSmXyD}(tfjL+5fTW z@O!fC5r8)KOnaLBvppSf#QwqlyZycWq5WU`bNgHSOZyx9D?Bd%ukFw5Pwju$@7Qvg=H^uk`Ju6oaC9#4Pm zlPACS)^i4Hj&c6?p1l5#o`=3{&orOcQ{N{%hS%o(#q0Dg@#gk+^XB!|@|N@#^p^Hg zZ=~1bspEa^iSxelGzawbzVxJeGd&BCzSkS#z3wgQ<-QniHD5dLINwC?QQvy6;=kza z;Lq?L^cVEy)LQt4YLk4Aw8Oqw{f%$GUcjHvXyKo3%<_LWj`=&9pZ#adqFPbWR+}N_ zYmdY^t%}Un(qx2wNe^CGn=`K3L~8A#xdeE>XR(vt~8AyGQ$Xx!Z;#)Mqi;B zg@tLnF?C~~NzCb{Y4k9u84HL2Q zX)=?{k=ejrGG4wX1LR}UTAm^?axEz-#}fPplYA5<$Ti`WN5l=eM(mU`#Y{O=^po90 zQ`sE<@lO!tWvr-x^H<6N*N{y_oNOz)%3flI94ofSrQ)I7BPh9wmF*{-&yqtPCbjUc zF0v$@D?8AAayGpuf22a*qs7R7G@01gU=qp}k>czSDaUT(7eCn~l7-Pa3@0nH4m5#H zrY+ez+7|oqJ=i@un0=sQnL%f>5Vnkkv2Cmv`;nDqSD*tQu?Y4bz`<*?B7i6!%@TN3 z)`1si9eEDcmHTKSzeywbkCgN2^crhR=dv=iI{QTaqQ8(dI*)|XE@TI(MCy%l+nXIl}BF>zfT^ezS@+47Yr1c*IlVhIjyeKQWewhsF@` z)`%1Di~=G9)?FGm06&@`=2A1KIoT|1_BV@~9nFen3p3n|H*1ACe=qD0Q(^+MgYz$5}9AyfsVaJJ>Y-nf(Hb@sv;FF69Ex zuP~*u5~D;bsY)$nmr_l+hI8&Rlst-EWlEU(kr!6)050+{^#>lTZsUfsntxQ%`D0}z zzo4w+hm@UsqjHkZQ?ByK${RjJvEwAXGB_hIS!st>yDDpeFDreNe{dpR9(9aTNu92= zQdcMg)Q!p%^{6sOy`rpC?S{GyU7;qbE7i8@a&;iWqtvD9RKP5C zu{vK}q%OoWTV0?oL2Q;f53yNz=BP7JYJxgZ9gbRE)b2PzEmkdr7C$I&mA%StoYU7y z$)R}oalVMR;12!~Hgy8aq@k=UT}RK5>a;kyLT1U%t;#W*gP-p8tp_^ z!!W6lZtl@z&93^tMrnP8@j**5e$%+ITf3yEYYX(5T1S0`R#6|XDG2|AeS}NeT+Y4m zsWILB-MDLJ8+k>fiIe%vy<)xT5s%C|GFVK-e7_>62}XVu3B)TVkec!|86^KDdt`C? zLMG9?WE^cp*3lW{96d|^gdcCvk~9}!QkocL5pQ$8sx6~D4y5z4PPLGixgP(MQ|H6>IHRf~hKCDe+LlxVd&_#C4qt4V4% zNK8MqhdNG8g?vm^zk_6KQrD>a)$Qs*b+7ufdRRT79#W44V2`>*-Hd0II$cduC#k*F zj%p3HsY=yS>P5U|yz)^guiQ{>@U6-SK1^})Xk|D1hu37A`F$GC2hexSNxx@1NEOzO zJi{q{Y4o%Vr&Hx^k|<}80y2hVi7a_boRs)}O>Pn`puzLYDMA-^DZWx9|!sbI4LMLMF;&IZ_UntK|xLS)PzzB6Gr!tcVsnrOcs)}WE}M9K(dmw zClg2l83K*kmQ*B7NC{G#6d+L~6k0YEDIp|+;2-g%AgPa75<JSbOy{Re&dk}9x0 z8T35PTii!)(6#he`YrxzKN#h!#%TP{TpvyyYh8!d7$SlyW8)-)(Nmb$o zU0=v|I1BTJOqaXlMEM>3lvG&{+Pai%EOX1U(hL575jOc$WQ(Wbqqr$vh#TTBaa}wV zR{?j#BS^**@fc~(VD(>!f56Z8;+^<}CsTYDS;7bT@c?ijniN8n3eMhi%TO7Dy|uzJ zTvn8|@HCfAWN$f8j>mbX>*PlHlRO}w$QM%JDNibs4x}@BzmWU_K7J$`sYol+ZnPg= zgE2p(PpKQ0H-)uj)7W%&l3ipOESr_(6?uE!8K-{E<3I2N@IS8ccla3K%r549tOdrHHLw!EALel)XB5_i;bwk# zi3RcGGmDs|%)Iz4i2S0+DP~qdUKD=G5skG)EJBU2!i+QPnTci$))tKbO|YU&GP|M8 zUU#Qkh6d?DUy$iE2i-xd z(cfrm%+g6zWvgf&_A{-C@5>rshIVH;SzlI;O=OMORM2uE8^pe6li7MUm+fX7*g>|5 zon?n1btl*ZcAmX}J^8}!GRZ!%ApVIJ=NwWI42j6kn?Oc-^Jshn*ANz_6<@%+@}+zT z-@?a2HfBRM7V(pOJ)~m`^?JZXTf29ey7c?02+xk^cyJ*?^g_kZ}(E*J=0-<4eQjwDi zJPI%xp){0Elau63znd- zxuHpO&@R*ooo>Sk*aoRXy(FAwk&^UZk{^(RJ|~ujRq0b48h;<~IDi#k3xbg!MqiOa z^c|@{Gth@D?3PfP0O&w-!D8frttdh#(s0;|>d@YGq05u#X4;(oh~1O}v@bnP#{eeL z3+UMuoW6Y-TJIX&2-peOOK+p(ZF+>>qQ~ex;M?>#y@Q&!=}*Ytf%I*tyB6}j2s!gn zVk}aI({$PuV{c7UalUs~yt^?iPAk&s?2GJ>3k9zF=G zxEFe3HOT{8nuE+FKKU*AEK|wfatL_@AMX)Xr1#*v-ImD+Hvq0p{*=|pGjQm&EJ5DN zqU62IO}@ySBwGfNEd0jFlrC_O5gSh17t%(Ygd-dTD`gLSeuFoKAeIXjIxnCwo?@gZ z`VkIm7D-a@jeiHyoD3x$VWkI?4P+WD#S+Z*-5AL^Qik5cuc)%gP>k(+ob`GFmii^A zud<1>B1@;u*eN=K-KF!GPPee!upzbBCDt4>c`SCY=CXg;59}@bmAz+A*+0y~Ucsk( z4xjE8E5om`XnvB_;D<4Pwy{XQj@9CeSS9?%w=AE;^7FAQ1oMjV!LUh#&`KZnj17Ty z?gw2l0@`CF+k>~PW0Tl&Sg!?m+YIRKDTs|{>41%F6jrLEplikfM#H;I!+JFh8fQBD z31tssEqe%B=_ppR`%&u%bp9T;3N5c=TcN3TK~rr&`g*pKErE}^5Prlo)Ja8K{qfn7 z^_u;SmR5!AP&$oXBc13P+<-8I31ygA}TTGj>T{H<4ZOv{1UeFFK3p)o6)(z{q{#f7jW7Wak z#^6LUY)lt$z6ZEE95OH*+?oIxm;~NUfecJ%d)Yj|?Emq5QNVlo1^hk*{+?%RV24&i zZr8Ijut~pRFX9Z~3Z&*7YW)fsz5wYt#SS2T6m<{b^BCmk2-|`5-N4_Y+;>Qy3dtGC zcA_V1Srf=nW%MQt^5vs5uW>ZK>Hi+b9-HFPQaUxVac>(#kO{J3vFE%R-h7e zbw${UC^{Llatd_VY#L2x;Kqi3Z59mZTS8FkOw_qysOf1F=Hv4@)rs?e?S7Q708;hM|5h)NO-y6KOpBi&*p~ z3O+_9Sjf^CVNp;d6x0cZPv)eT38g29PWEH1zKvvpb6?0(@N*t)$_&6{P2WDhxn@K59iz`j822swe+adLoMg!gz6Xw;B&>n&Zgj(0$t(94S+W{2HJ8O zb+RS!%+}HznD3$NFm@i!)7}zVJ39_TlyTi_wo4{Irs4S0H3$v zUEYRwd6oV`uhSo}lGuq=$oH_I3qXl9qzs^ku$I|^_0d{*Ws9+jno9*q1qBDg>UO{? zJB9AWyiSLoJcAUbsgRStSS2+F)tf*LYLO@KxUXUUo`)}f6!v`={P7LAb!P=&4s8BR ztN}*C{-?s`bVHg2ElC*Gc)0-iaOX!}tOW8xTNEb6;ky?iMM!QyF02q7NO6;rxYMUN z?jS(# z-e9HinY4kV4~4u8AXVrj5=*B*UKWy`@GDYbB`4GEWC_-stLYKwgHzBEXUGXy&`b0W z@*CEL_c2rMVO{tPy5a@aC9kl?d<{8!M+?KFFAY9K;@rGg@TDod{0`VH=nWVJ9;Q)A z7lM;3C}*3gN%v#t;3&cusDoXB3_gGiKA}PE4LJV=viOCDK)Q0`_mO!ZZ8;!)d6|M0sTj#{NK_~MDzgP-EDBH&`yd7BGpxYwQ3kL59l1gO0Tu4R zr?^9|W6$mn$jU`}j9jHZk@IvvsI{A%#U9Qt(8ec0(Vyv7a)53oKOww>ZX&zs7VP(J z1C_TzJ8yv<*@|7QZDbg5UzBNyaC3yCfFtM*QUs72=?;JoQkDT7@fWniGw6sL&=kKx z`p!X5oQ9ux7*^*eXqbcKHni9ita<-N_#O0zPL5z_=@|HbniN2fOVLZ%fx3Yms5_)7 zc-sbcqAPrZf%GF8Ni)er=>DnT^IYu4%!3cH48Fu-;1$$PzXM(lTd)*%Vkz)qlwSb5 zF&BQqEZC5lurJ>tJOy|H+L?%QV_-wZz=n)Md#R9{RLIS6_!6mrk&vGepz>(!{fq>R zhJLnS6y#|%Y{ghw3*}<44^Ri?8UZ&zxddpicz}hIk)DXM&5@pha0+z46>fof-U8uf zuvxJ9Nbf^iK?632f7BeiP0f*-5_sa_zr?{#)Iobu2vr7Df-Dz-pHTv-xoAyTx*F6C zpId<)GvOHt?CAW56;~E1M?a9_kd0!XU@=g#AY`OC{fp#-CsmZbhS&8Re0&bdzlK-! z3gOoXzau3O&JT-hd1eJ*i;AP2f}mzm=%GSrw-9DoK2Wa^C>aJy7QlORfh(b)WG+xN zH*hdGV|hP8(E2&x8Csvgu*f!eMQ%{mhW2D`DB!!kbIS%u9zZUV~Y<8oK#=_E`zuD9d!IMc#BI=cL_ZMJ%0pmJdFPT z0N9B&$1e0}J=O*rAwSEp9$5wXS_BzfjGoVdrkaV7%*5QE44IgOQKmt?S5Oi3;Dq4T~3s-V~&V(d)CY5$8x%^fneYAPzPlnLZ+|u~Xd*65azN90q9} z3Vo3V$xVY)PKTt*kq2(YK;qd;eBdr=Fq&{{^V*pLS!RB;3Z3)~N`Q3s0W4C%3xH^LF21hOK?t#4R z32=Kc@G_*WKpSfjUWfN>Kzs+V721o>9gw-*ki9)9wGR@p3;o@XzHf)D?}vPB#eT{z zNWf+~1g#7}tu6?+M|;fxiKvNl;-M?jAs5TA(p>_%ScX}&5OZ%nX4V48#cWVvKJ>&i zXw10*3T1;zUNQr6G6nK76Zl)eG|csHLCvX{`%|D(CjBoh4Z2|xH0oqfcpP*>8p@3c zgfq!-q>o0q!JztZ;C^VgKX4D|iLNNy9_g(B&5_;+^4SResEvL^LW4(uOJ$%jN`OO! z!IdyTDEjV#77hY8IL2aw?Gsp6QfNJsR0GsT94GBU`x1#X`2b;Y6-4dANGphb6ohsufOvjd z7dRT!stsH#0C|85BQGzYP@r5i((9rf3)caz4PMp8$m^orD1>A1&YFSrGKiNzdO7s2 zG}etq zf_h(Z4Wv~@+`^Hdc}-}gmurL1soaH%I+=!LlD&-Fo#?g;k-?txGrKzEergQsWU8G`iQC_54*1^|!7 zdqx1p0mc9(qm}WfGX(d#jw#|UtE7-V56 zpg%@92o&yx(e}ZpyMvZpK&5WL?Lftjph{~{tUbah;EP4Q6!64?Cg4dTc-k0p5f9uD z5CdM<2d|?8G7$zoS>e2BF&Ai?2U3*_e9DE^Lcqmbn7=uZ7J?RX0OthPL%`+W0JhRf zAzTQ$s3c}lLCm;fzy*K{BQFnTPC?{ZI1KNwK64-?6g6@H+-UV1)NrDoF36ArpyKT| za9%-g6pT^Dm?=PkWGj$n4w~378Woan2i+V1H%99M6>>mxe*+HY0Zns)&IKVGxq*v< zTKT}KlHghq;1b|znE)PyH}%ALhJk8*5FQ9>4nQvkL;m`M248Vya3TWn2*j(QOf~3} zNW`l{&qSlGYQQn57m0EWfuqn~W8~LEdK_>($|nG)AU_%JX$y{~K!WaKx__SoICsGHY|9vo?fv7PMW3pD6Rtx0$MMRx0L~uKzpUoeo?%k1aOf6MY@3py}`9Ez`cMiiggEnx`B&b0o?*xuK;>f z4CM==&sOf0>vW{v!F64909rbstM}{S}2FK@~B-J zR4)hFD1}zbg4$(}Rt~eH6y{k4ytOoFSsu6?Mo|v9LI7JcsU4s#>U2PFS^;-NUMrMu zhj1G}YqVwMx5h|X1==hgNNDQQbKWeQ& zyb)?yH@R9iqaNrKhq!g`X+yNy2)F_08i%^|LB+;sxe?MWI@bdvpiV5(t-4>!S3|xP zjzparfx1=?8=&V_+$s|nC~v(p5~Hetb}iqgI-n-%MgnRg90hEFH7YC38bNKON28u~ zi)u~0_v;AjBDWE8t+ZH)G;ctc2MW27|# z-{SGv2)vF9gp$#MRW2Sl1?3V@!-^*Wk^{9HAw4lrHwnFpN8473IOHdyW$RwwuQjYP z$%r>WnHG3^BEr_np&44W;w{nBR_HPI(GiY;B-TZ|Hl#BK`O%2iK|C6H(I`^~ZAAvs zl7L%)O3C0$Q{*)Rw$>L-k)DWnJb06Uu*D}!>f*rP`Y0cV8CDPZjUY3z!1WPtfc%&M zpCj;gi*J1)nvL7l9hpkyjnLRnbFyD*$Y@7Xh$l zc2(q9`PI>44YXz9NThwmb&wzXzc+e^3b6EsCBfmK&i~^m4|IE=%ZDG7Mufi2mzN+cp|wPZ=Mwdar$z%_wm0==|a zwt8Z{)fz=gpodY2e+@Uo=#ntvuOq2}wyGgq3)otvebrR05spXw7NAm-z^E+BMWQ{6 zG8T>kR136Y>4xSAC!lUK;3k1Qi}Kd!tD&4VbFF%o9*Pdswf0GxqWwhl!xGSvNFW`Xdf`*8R>FwrW^6a$B`59a$%kYTd4FX+{eg zqc?E?OZpS>c1wF%+R1verSUASW`*O?7LYMFIk~RTz+hS8(pejK?02>|FfcGQ zFfvHWH!!d-GBPkRus6ub-k<#jtcf;^GMr_YWEg80W0?5c5)9+ODA6#%a3=T}14eq* z=VyX-afXp#G|Mm^jA#7L$AWqS80!%SYVn}W0Hf&NtdHYB)A##hv0#({cA5cJME_=e zekK^lfbpL_qQOYtLqCh&*YEphzdzmL!3h$<$z%S1>-970XZkaVeu_A7_dlKWll_@3 z_V-*ff1gONMgN{A9_*F~cKhFR=~wF4>u=)E?)pv%;12rpCW2YL>9hK-F@z@BKk1*{|G#(lr+57CJ^tLIet-Q< z>RJD+;(woH7N|vmm<@K(@1vhxf5K#N<)3G)pI$$m{?7GNM1ht1)%q^~+fP4VBDgLV zoJ_w?zps8K{VDbLqL2Ql`j!8CC;xZv`kVRlF6cYzpQK*-^Ik-OQPTf()%VqRhy*qL zZRtDxdGGXH^&Rx*`SS+obAPJ!z5j3aBydFx*hBx^|IDPnKm8l0f0}>JpudZ_-?3iT zpGbe#f9BSo`p>=UGx~G=c{la%mcCLyzkbI=@D67f&Noam+;6zYFyHWlA<_tH^vEdJ zXo>McV;>V=69NPe@iPrDoo6=3Y?t{?^J^B@ElMoES+cDftvak#*8Mj9Hp8|)l3)tYGCZQf(P60!`E1l}BXvT4$I)Ogfz zV7kA%tEX$YW2j?}B3Use8I#0|;zSq$Mi9e~=0kZ7yz|_%TpzA4cbYT7(QrCBTuu|G zg(Kk9fY!)ibLu#?oCZ!k_*n;LSm0+p$ZQT1v_=qY4hLMr0(~CHOc2eW>Hl%TE&>k! ze^?0m`o2QYM4+{T+{$U=h(T2bniw<%N6L|akb$2nPCJ-w<)}fEgGvV&t2oNvu@Y1) zxmMiG+>Kl`58%Q1aQ@NeBh6tgp)IRLnId_svQ;2$lDa8u*gcsBc<^%WfA$gN1 zq$(217v($4cc$-Z-!;BFeYb+x?R&)cFW-Hj9riuyd&qY$7##)u1E8`WWWBP-_u%h% zA6UH$%pdUG?z;ob@BY1hr|&jU-2*C{L2oC>TS40b`rCc8!F`CJRg)Ot1YV>ppH)7I z-bvnLo&%msJyv;~bvx#^g1DAw=VIoPk1xVs#Gb|e!u-PALf=A915_oXJR}B&fz7v@XBTIcV5Ku1H$7=|+DJ4dn6ezR8gm(R9-P^e z*mGKQMq{pms79p|((Kk%t=omWgfM}fUsea3ytJGdis@%L0itvJP zEC+2hXnH>rh9DhqXHwDnam7s1G5Q(hC_o;{wTSl!ZF@C)*0#wbxrY@ z=ke96*elK_)@K^Dzeop3A4mnHCeV~5DM?G}Aq|syNqykw7-;~sVbUmR5VT>^5Eu=C z)(_?fK&2n7?FK7{KxjbIS7}LVQYWbk)H^{%4RSY0MN)uKH>rap2cZRH8Ms$F=?m!- zX(eb>AF@w}x7xeWi|Mt^bBAYzdzm}SmF@bP@RD%Q`JnSs{1W^%>@}>HqlaT0CJv)S z%h7}AA@pCE1DN@aDUQpr%dz)y_i)Yl7JPs+$$6v8CYO7JJA_BXN5l)R7hLDM&34m* zmgT<6{fm3CyVPCmE_ZKtuXd-nA9p|DZsTt4zQb*c+g;cHT<;LC6K50V5vrXj&N{r2 zQ!iGFeS~>}8ASD=tP!>dt^?a4%XY18fn~lW!<1_J!>G*Yn(mS=emr5kb4WXMvF~DE zbXQcDrP@M`RbrJVrN^b|t?8|=gpY(b1;+%A%}V|ZzLsao-^MfMyYM3UcAZ+4JgS?3LB-T?WFM8vHIeX^vD`xcD%NF-d0q?P-$wT(L^mT+UlQf`V! z&J7W^aVG^T?zLt)SI1Lu!@2F;)Fu^o2D_c>&eU)%>Q&sanl3K1TFG5N@8b?p&3K;F zlRSWm<`+^)%{8b7 zlbvJJ$bL(R|A?Pu>f|iD`G$#bxT!7rw&i(Tp6x>yUntQHf*A6!L_xg$0GtmEsPu6{ z+mPm?XOcFfmy`CRw~&sZcaTn@_mNJZ_mj?nI0O1;(FZ|o59u@*pGNNmwLM^dC+P1Z zokVXZ{rx+)opc;rdlJ2kbQILif&3qOGl>PV8)g&f0f-rnn@I-P9MUv)6UhOeLt5pu zk@U(rmLzv+_c0-+`53wG@@{gS>$TsFqp(SL@WqHV9mk+_!&eR}{Q+{9#erdp8xLb;k1vLhJ^CnG#*?GR!W`aR!A4#Qe*=%p-OOV)PL|Ck8#@6M^mn<6)mj zFpdWOKYAZn*A380zLDu)`^a)3+d}gE7KKnpW&O=L(+gbHiz?&oSpl?-&=Q7tf{GGmPNvag?yb?G52LQAW7!5p>hTKZjg%=JTIz5Fj? z@Awa4d;F7d?g8g;GXkFDf&xC`Oak(7Fa3|;u>MiFY`{ zqDKaB+N~1lL+pnaIV+(`+`smt7=$eYwZiHIe2=-M!&b;enCH6N~$Aj;`$4HFUf4K>vjLbI*(R;I4m_{Ti0sN}VO!*d8E7tLC?96bB`8`SsQj z*)8!5*?v)(G*Gxj`b)4vN^IT+zN=rPnH+mrQsYIL9Sbg3)&DCe*Sag}s|yqs45IRH z+I{7EYL7CXGD|g|az=%rd{a%3d8%HrR;40qR0^_K)kdyRNy#@=a`HUTA6B-L&nd-Z z17#<9l|o8>CfAUuvUW04+CeUE(~{3hy2zfb8giwmj~pV@knafw$sPPIGKn`tUdtIE z-)!t7|74Al)eZgRIrUh|SnVMSq!vZJS7S?iQjsOzj*+K^md&N5`ZZ?bEe z;+^7sY>8?q1;2(sH+j~f$MjZ-1dV$2aE+8eY8<+c z0OtRXo)RYq=Eh9{bK>CWIdQAd$#EsN<-#JE>j&$w+kS}X?d7JCox z7o)-}qEJq&BK@51ho?GKg&uQK1q+;rK{?Lb0z6$5ey)VQzVnHpq{prnK7(#1-b*}; zy{>yYc;{&$+xi2RiaeM8eC4O?o5so-{IQQZ-I1lW3M{A4*C`LIUF^B+I3KVajYS(Y=Vg1=c zX1>$(0>t0g*{Emwla4nzXQFnjV`O~z-@%N*O?{nxv%8r+YqVosH#?4YnyUh}FXXYB zlhVEFTax;YLa}3qK)9&ALvT?w!p~ExxiyNWrZM?vcC!37^Rw(+{bJd@S_fHkwV`YQ z!%k*PkCoZePRh1WIWiq3L|#w1Aups1%AZnF6%Q!S756CZirW-dkG;| z@pH;r(JRVG%Nxqyf)|tlem-Rd?+vAllTWd2dP_OPE~Z$shAEncO;l`y5AA(@D801) z9wVwDqb7y9p-#wZY%p$m!v4Vh#nCoLHD49!gxA`TZ9K(JMV8uLZP#tyE$;UkC>^;q zdUMiVmu{GE+zN@ZAX(CMRDC{0@+>%fHI#;0KxAG zuqEIb@HXfTzz%r>G=#kc-bCaB(NV8~bI}FBftc5TVeC6#PV8G?f9xCJZ0u{`4(Q*F zeF;1S`9bV+;6A85iG2m!i+uscFF}3|;w7j*18#wQH#Qfz4(9HF`nA|9;705q7$>9u ziLFFmi_OMdi=D)5jlJXuiB&o-j6q^kqP?)Akx1-@2y^VaFr8y<2ns6>T8@H);sO=y6pVjqtV6Q-IjRDb)Ks$af#c2i=Vr(%UAbQXN7y6Q?2`9rz7r( zP7dy9r#)_3{7=`fcs6kbo=K45Zn%(eLC*8B&+*=lB5VzM6ypap0vX8L$Z$9Yu5!5O zkZD(K``CKS>W2l);+?6p=}BXfakN2{fpT)?)S0o{<8H&+5k~*^pm_uXtNXvv}f{4Dp7uw%8;$6UX-n%ZkDA`H_4Kz2W4}p|H@`isj_+0 zaakhOPo6?uC!ayRBVRx*l_yd8@>Hr;KA+kJ>I!)}l_F20-Uo9_8Ex`@hXTTY#jET>{6%c$tql~gnF3aVI`MZMFKNlg;0p^EscsoQwj)Gp2%>dmIJ z)XYXM^)P!gt)7)Yzro63yk&{21K9<&A&sp17flOUkGZZ*_RZ-$Lt(36e=Au$M~0W3 zQPryYG$QTgo`AlT!Ny^;vD`_<)NP}6M%T?*rYCJxmUH2Gwj6Y=Lmz$v{0`9Zq?3FyS8nEDcHlj)p7&PKB)kk|WjvoXB;6RrGqGBRU7z5VHn&7PA4M#;gTe zV%7oTnDsy>sL4UU8)RinHqaH51t`FL2gvO)t3h9{uLfi>nIP5xZ80kWY0N5c?P}0p z4))0e{Y*dr>Mb$b0e;NCfG|b`uw!PSTVr0LU&lz$kum+~J<(irX4C_8cf*R zHIxAmgWm({fFHmGzeyl~v;|$~1;d>8Xu+&?V>xan^0D7sRJds80lcY`(#a10$vGC6 z=<)!2+{FT$?Q+&p;H<+qId8(aIhCQU@EU-E9Y$q1vXGVNBM38K07gUxLY?99_Wce> z+gEm9tP*X!ExuarF!eA$XM6&3%s^nYXv)jLX8h(<`S9fU%7IIxqdlR+cRNi76V=xJ z6Uw;W23b*eon%#)Ofx$jZ@cxex_`ank}0E-(dsVeo*^MW=uOKo1*TOnb2}TEm>wp!^n(i zBB?p;wiH4O1o>B+B`u=Of_7J8MN_w0(|}f6T9nv^Hd|y*3l-YaFfCA;s@b0QoDZXI z;9+UAxvOYtoC?~rrag30Qzir1biX>i$+fn($)J9e6Up4nt7fM*H*)T`%xc~s4iQ~y zJKyG~NLQjd_GmVC4)jQRe+?ZSqD&CRrwo7U=9$MB-?2Sm)&M_jRgE#WJM8QLeeHG- zKEvA$iS{!?0fFaGdBL@)`p|yV^Kb|d5$OPIh(Z9fq8)+4XbdnKjRjyaIKU?c3k1br zfbbYR5E+94;S2%+LLZ}nh!_9}2J?|INFV^@P>=&bJqWDv2Xp>0aKIO2Uyww=rUkrz4`r?I7Y6QH6Nwav53g6oZPun*wYs6ZqHhGWsxvgxQOJi#Y}}f|0Bfz?m<8Xa(Cn?1FJz0wWg|PY zuhZX5swR_--jB(qj}9N13K?*pXzOVkJ=Iw}?5=(@*rcrOzbdoo+akHtvqluqeO>@` z@p+`q9L`y-Z=;Pim{q4a-cX>Ku6v|;SbIgYqvnPttNN_w1mlv1ML(~ZPrsmYma&0O`4mZp43d#QL&vsJvK zU6Q}0A>|)wWwQ6Qt+FCo0LbIgVp^lLfc8fEmG+Ockd`I=PK%X(p;>_3)K*Np)%KH? z*!GRqAt|FBl9bTKTPtWgTT5wlaU~59SJ38)e$n;|DYR29RkSk#Ds5jgopzM3rak7x z(>u98=m)rG7*X6a)#+SrO#%00-A>+vh7)`zwxPg@)7)~M?;<`aq)J4RTG>ZMxJs^; zs}J?`bgdZj?ms{Aa9C=HomgXjW4g_@%QzijYyQ|#YIW6Ro}H6N02DTq;3>O?dbbv2rYIvw4Dx)aSpor)Hs zZiBhA(R|cpFn0;8JsaH!vH*1^x*l~7TyqL!ef}iKe@An`n29s&wDA0XVdPjSw-Pr{4rcVfdG@-g=u;AmUuDbz8j z5mEs?4flf?!ZKjH9A?1ScAZd1+quwL*0B!DEctec<}S8ors>unjOSar8zz|_(m9%b zoES1LAN^)nH1yB(t^Ng5OM84LP@N8AH66Ai7nE*8sj_7QPLdyej-v41KtW&kaUQ*E zuu0PSmW}Ov$h@s(*9U1+>WsDawJMESjaU;<-KaUsXwVojn3|9D8qEoMt!6X5L9>F+ z&@862Gz&p3gI=#m0ktI{(&%-+ zEr=z`O!^B&Hr-5-N#7;kK<|{Trtg=nr<=>x(cegO=&908^r^NS`m46h^vt#`bQ2Ko zB%A4rBs=Je)*bW%AV$Qy=-b3Q=#8R%bWhPP`X1qa`rDTMbhcnG-9T`ep4?2K7w~-; z5qt(i$NN@2$(yc;=D)A2;ZqxOn^V|Lf^<%Xu!0{g{w&-lv2L@G$rM8hm?pC0O;3sT z*3i|S@`=j>E=Hvzugnc5{p{u#d_w4%S~q@xZ#q-+UG9aRt>Bbs5D3xenyUsDDs3AlFA-MA1P_&r}e#AgaLq zs-rG|tk*7}Dx=P!zDJ!$T><0ds4b|kkyfY=5qpuT;dc=`LT|z61#f}L1N@-rexvpu ze9G+%z24cbb$@SDP2^gqyWp*r_$OA6v0+x(7!#{_Ky2xalv$$Tot9{*nU%4<<$(_nzQg>oMW%>MmxV?0U`o)G4e7I_K5B&|1~5 z)tc2rX%|L)nUDY;AR9 zw27S<%fwg)SwvuXh@2URh0cun76JokAu)~#HZn$=>lt^O&s48!K2x*2Sz3Fl`C0u? za}D#EU{zyo%OuhG!pw7F(9 z%dU5_0%2s>={RP>cVU{Z@K|QOjC9WKIrwY|AxZGpVMU1ah;>N!NG>uj(iEkN^g&rf zMWXOgNhpt~IVhi~6jWf;Jd|HlD#|}e#3_6cp5KL6$|%L_LU1 zM0tUD8WD%;376PY2)%-k2XBR|107*c{Bs>bePQ+wz5liy^yspVb=zfij$mQg z#62=Qgn4W#LQx?}2pFUgdd7rcZ)bALro?#Ka*uJ2d8F|#h?%jyG0P~`;GWUh zsd%HjalYZ#ktD;C!IK7seOIO*b}!VO)V56Kba+fGP;MWKk>!ufl8g;yidGEX6L9-S zdAs|LaeRAcH`@1vvQXVS8s>K?>K=C9swH;bs3B|V)t9x2)qiQn8Clu}#u{x2W2v@) zu~_?#u}u4dk*BA3 zF^CV0)!MIMuOh};?RPL=%t!C6B&&mmXaBPQaa;g8=WDL)G&f2)r{+{bqtNTnvo=~XFL+I7@a~M zBS~mnUDT3Q9oRBl-6W{5c_=Wb`$urFzCe)0G->5sL4%o{$J- zJEf=E-^q`6`l%ZG`a3p^7<7hD&Fl#=uI!&>v0-?Xo$L5&#MqR-W4&Rq^FI)-n~%j- z@AKAKe%I`Z0$rdxLh$gjVMh_2;Uwhqh#N@j$ZF)QNEI?Cau~Tc(g<}t(g1Zb(gJlR z(hPMv(j5Fgz!Hp&!PpjcD$)dX0@O}`xxYai1NCEId>GV^L_$!9!1w(y*yA7=?*nss zeHR%21!6~}A!+;nT>=VLBu| zv<)c?`3w0ZxB!6&dH@d(2!J8|9yxsRVcNNQ4chEN3iiYTS>MFZHtobhNzDYT_1(m{=-LEAbYWtt@ajZO zOVPxxmX3+pEisczTAoi{YQazSw!E3zDkSOD!h5;}qE_8Kkw%v%s?r@4Md*fvYp0+> z+$2}9Vcey8=I8|X_R##M?0!d9Zg*zgRt=F+t-M0kwS6roh?GB0^P`Icn}!MxGeZlO z)uG=R)Kt7)#c+CsqH|wZ(pb+C)aJYh%EYtPWanp>sun&iulzfAb7exVL#1i%+lrAV zQ5D)J&wq73nJ(8nNh%+Fa;U8D$*Z5!PpV4|bGu8-bFEA4awC2qa+iO1%)Ru@CHMPR z?_6y$Dc7TTZf@3>ZMly>7v^d|p`WIH`tg)rbp6@pqM|%p5%h&s5&b2msOfc9k^eh! zQD46B)9S*%za06(|9b9+VM*q%@iJE$r>dd;2xBhKl=)CHhxb&yrgi4vv})sYVz0zf zGVyO#>Z!5e~M>h z_r{y8vrTYXhfN4s=adk-j+hV(`k^35>!1nl>tG4Qb!G`T5b$-nc<8#(c%yZL@fPd4 z;zzPO;>WYw;?>!$@!D)|yfT{{U!A=v{;%xjIMG^d?D(2jG5J|0(Kf3mBTO>O!YIr4 zgdAGBCMaidNkC=BOaI)3zWzoFQ~X)!?I8CB99S3_WS#LU_*Vurbj6}$VZDo};j0#Z zk2tv4I}*AWhzweEB%*d+r1b-Y$kg99$#9G5wuxZf@}bW|gr4?Jd53|bROTsEiY_!> z;BT&JXzZ_&HLUo_ul@SR*9HpYVwRrId+OX)w~4$}r+U!(1Q1*OHlyhNSx!jXF6 z`8SHu^L><;dGjc{@>3-f zw;d0+FCYKg?(_uH_TZ$S?Y~psY$kP!Z0;L4*<3b)+I%zdwMj5LWn*G#YU^QBX?xB7 zi(L#{ZXX3CL$_nQU_xgy;-DK373ht`O!!^JHU)b)-Hd2)@r>Q*IxDf#y&>tl=eya9 zyft&T`rJyvklxSVN6JdQMIxu>ksxWWN&abhq?okNq!nofzHid*`_5jl!OtN*+uv^C z)&OkAsX(7aCxZMIZwW>&2@DY}sS7!>G(J?l^zTrwW&eZ*En5?6xokY-+0rE;x+NQe zZI}24H7>dr5SQ`FFC{&dG?04P%P(cEyXhPTVQW$YeqX|23_7M3u`^s|e=;cFD$RGd zse>oh@FQVzVk6FRBpCSGp9yR49w4eAnW-Ok zH?A#O$+IgiX<7HM%$?Djj==bOY{z&DcHIOP_iSP&u6AMtP72;k@5El*_{1Tc;pB0g)#Mov=Wwve zt2or;WgL3)9*#J93rCoIg7cYt1R@U?IQaq>Hu)A8F`17`m@LG_PkzD8oBWEKJNXlr zKKTvwcjC+@>DV0;cN`Clx1r%7$n=xRzHjxmiJJ7GFB!829r=9uXWf0+eCW}2TeC!050rCNm8)mU7B zrdiSuWXo0{(5l?=mep!}gVlZKUaKvHHmgG71FIZY8>@Y;36^%QUKTM#x|t;bF#XHf z#pEttVz>yKHO)r9nlwf+$KY_$@QD5BfZXPAUx3xgo=I~|_Xe}nt{tY*&VIXj;h-U#=$2Ehz;ut{OI8!FCo5oD$G!2@F8~aR7H#VENHRhSrvQtc6v8#-4 zu-%Q1vez0NV_!Gi#eQP2i(N3ii~UZwiJd>Shy7;qCwp`vx^eG>wvjmTt4TL5;NT~S zyn_==zR%<@LEsc1x~HpbU1m@x-ETxx@=ShqoG|;RGs$vOFUDrpAlFVivJ4tNu@SDC zszuaJXCUhgIEXQWbojWz2B?)`jQvVOtgWrlgcZ!#!19iXxA}h4eWrBtVUyif_l-~3 z?lWRK{AIWS@zMZ?Ha6(N9-98)jGSKKTCJ<_xUYNXeO71TyI)81JE#-*@6lZhIG}3@ zIH`Lvv{b~-F7g+ z?P@>Nb#q@Z@lx+I!bHzv!iSz1LN3UkdX5p4J;elEZ#`jUFNJWT_YmQ3Z?DVWz1A+X zdbv)_o+!LW&suDBcO1sFYXWs%`!C{)+68vA{ieOWQf`wdbFe~4VCGMST_$q=S;PJ& zQ=NjjXuP`ipWzSm|N6g^FL%p+UC`|Nc}=~%N?aXs_unG)cviyxISlf(hSyzl$tfxk7)(fL1);o}&8!1_3MrmxEu}x#E@w_G^ zWQtQ`I)iU!;n2df+AJp7rAr-PKa_h>Pc)fWZO>De+e33bPEG{+UNQ^~equH+^00@rqW|3IF8biHDZ|)n z_rjard($&XnG06=%}cu$;E_5Q1f9P(w0E9$1Z(b^sGK=_V@i{uapa`v_#-o<@w#|X zd{}H;{PL*r*rf2N82^xnD6>G*h#_BAsM`B#u!(0zpobgJ&z;~v65-9g);QL#Q@;Ru+B85y&V!!*~bG!Y~y|oPO-^-&Bl4)?}>1`iboh*T=;Uys^zt z$1yY5ve9R-O(PEQCByUJy@R3f`2$~J5q&i1_wFo*V(mpc-;M<~1jP@_8xoOOZp&+v zx!e@PdS>mEf6e^yXB6`Aj9&`|2qlW1t;PR!S{5BukL6!eCB5yFcf5Qe)#a5*EntAS*VsQg!f<>vo96fkPw{@_P!;sZt0L{u`SR_Luw{=PS^gA1 zN-FhxTwikk@x2oClY=ECPqvpl%w1bTeHvMkk!MsA^y0&hORr}Cha{F2i=Y}u^V$ch6h2a2fsHeL9ut?78n{G-4EVUN<-DGbCchUh4;QmqR_%7oa{Yv2>hR@eXIZ`jykk zHSR9i*^3D5bumQR`YvKhPM+(noWItgd(-P|eLVs6N^W z(ofIZOTAvIN*iBEOQ~vckN zA7hr>=A z(u(MF{>ic4L2KiWg?vdo73P%`9`P-?DRRl&jnUu_d}EfT(P9(Qm&Fwq4jZ(_zA{g6KarGp!y+Gd4=%3`%m zylIvN#V8B1V*0+J^W@l+aI|2&c3JLXgXA`;GH7(w^&v0lvpt5DRQ_M)i9Ask5Kk~ zkfuH|ex^6t05(E_;HGqzH;kUyIhfsoowmG+EV4cV&~5gjciTcRHMYw!guP~eY6fgU8%F%-E1 zcMCywaz@N1h~aG42KY)3DV*iyhCq{!BYgeF5la7K$e2I?g$eqK`Zp*GkOVoP*+FN~ z3xaN<*96W);{vV$=lpJ=7^Ia*t@kk8)ay9R*Q3W_gIkt;F|oqdjo@VS(s`eiuT#0j zE8MUd3X3(}g7G%_0icWoNbR%^es5|J{O+m4zHqe4)_eGZ^|ygE%Oiaz=KFfeAjMtl zje|SY29=sky0dE5L~2LcSaN&o@EX;d!57L`{Rrh)Z;9gHp391Vx^F6Kx_&4YcUdW| zyLK!4JEh9%&S2Hq&Lyho&TXn5?QYe-+JmY&+P$ha%|X=>%~q98y<4?joujJi*r3w3 zuTfdIuTo7b7pqznOH}vd^Ht%pd8)FuIjT@ejOw0vrfO6erb=&_r~1^qUxnots-AOA z+QT?I+NTx>U36yhRNKdy}-=xT+6iSPG(-~iDwe~{Fy)dgPDs4NzA69 zHO#aTI+Hefh2=l~ihX<{xT$W^kDH|Xj}JAN+k!U=7q2o|)}}BmlHaumZoh6V(tNag z(`^7d(!U+Kbhs65I-Y{NHg(+jqrpDnN@Imv3Z%kgrzzR&?g8wDTrysk7OjDho>C{dcI)qb_&I^B8=ZEu{CSp+rSjSz4NDSOK3he~h z4{SCAe*nyk-;zy@(HpPiNOHu^t zqMsG2$)AC|6kvwD9Z(C01{lM1eiimdeBriFd@QW)c$JtP@CY%9ayxAR5Wh{fIdev9 z@x6nuvAW*-7~8HhfSY;?GEq4nzE$c1{Ulb{!CD^JUQ-3aYY4qbr^b3CcSA^GgZ6uYYXoQhocZ+4$ADBdoYwx#G(mIq!3+^!?|M zHt}Z@$;K}Mtuu=si!;AQiu1k=h}7Tdq9rA7MBhtuMV@8%MOVuoiAH|qiRM(^5Z$fX zDWa0mA|d66kWY0NmebC*e5O|k-ZQk#KdWt;#Wg5CsxE-HqduIgZCJwj%-Y@bzVS`t z2&apEg1>;hsHKLLDPF^R)8@!>QK*@}+7--0+BRlvj~T1K--&g5crI&bEQw_|g<+LU ztC>inpG?4n#}q(3S&PhCSuf0c*^ZWno48iHxLO-Ef1f?OWhE@Sm5GGO9%ELkGe-9ov=mD~o~FT|7t*oBj3QikMk1cS z@FL!2;Rk$bdNqF4f;#-Vv}XMJR4zVkz5wr-!o&ZXE5Ikr8ODD}4se3adf;?^rkAtf zj3MV22|X@Z@lM2fam!qZu{Yhc(Pi$rQLP?skt3e}hL3y6L;Jn$LmGX&gPxLH0v7n% z`Zf5EU4<+R0X(y_@M0SpssU=rtOyLY%9mfJB`AR(w* z2KMk*6UGj;!)RMX{{pKEU2n~aYIjp36do%AL~`zud|f(Uy>BMPb=lSi}uSL z3g1f2KWf{&J|wk0C@7c27bHj!1(a69f}qxs{72&9e2923|F~#8zgswwzh7uk(A#2O zaG(WS&?j&y*er-DU^mYy2y5O{aFl<%fXsVeAm=s|OmZwgj5jU*(B8=XKxUu+c$syw za3S+&kx4_!=dwC{@xI#hZ+8_xu;4j9H?TnqR8{4yU07`Q{*(IoD$KFp@ph{(06JX)%>oMx|_Wz%%XwP#<-FH zc#9_3E&S;N5|znjMTX@ob-2A(&oU%?up0Z{cm{E)f!b>vk`<6@bv?}2etyg@`1(W< z>dmZd%-Ebx$9XA^xX9FgTv^&vJT~3KDPrL%Cy$Iur^<{9r@@T3PIVcpoaSY?IlWuR z$7|DH9#k8=kAe0@vNFB z^=gXeE&mTFrCD3(FY{*#hzhU=haU!N?%A&$%fyM4fkSQg7uyW&8msblk(r4i$Rwm~n?aiB&gAB1>gXlT_+SNVQJ+nHUDu83 zzcrDxZSDT#7mDQ-7@4q)EqPe_QvB)1b0PFQRq*3$C;wV;Fz@1*)117|{f&}O$Jv3O zNURq{V+~$KUG)uxCiN!@L+UaLFVwmhcGqAFH`PE3yQ}RBcU2<_4Xe?Grx=NaP{xVE zYxK!NJNkp7YqVpZOlg-tAEipaj8is!-A3{M-bE&s>>@AvsjGTk{-6p~nN;l(gcU7%xs;Lq;Ehiu4SW!~A7-|-8D~-h` zFm4N?YHEew>Nd9KG7m||8iy5yJWU6uWnNdB#Ihey_>8!#?@g}g4l{Z_Fm0w7CEH9+ z?S<7DwF7Quow#PpYy#cJ*_~-O=-Fo9?|t3jG-=#H>>CS(`|pSP2Rwx$0%_2yz#eFP z5CZm3&@5O%&^}mkP(JK&kOsCVC;%Q9bQP`&v_QNM{D?RecoCTs_yDygPzG!Z+=Dq4 z=!<2eW+flfn%j=Jn$8|PV*GDkuYtDvoNiWU^5i>p z*f_R*#pr9ro8kGgxFM%D<3Wd3$UwX(q5pbIejiS-u#d;b^i}edy$tU4UI_=+3*nsZ ziEXOuKGZngRl~-0IkN*gud?Q8$Cw$KQ_P)eOXlAlFB+b;XEc0Kjn}s+o9hP^wE9W8 zsJ>dJtzRRBHc%z;4V~g64IRS9hL3^(W+wk9Q_RU^Ep0@xe=(=nj`h8bw`)u|6Ld89 zE;XDNO^)N+R0cO&{AzFZE6WmGFa1k^EeR1QzB8J;zhyLMe6wq|`_{(~{N~=A|Lt+} z_3uXooF5-sZj>$-eJWeqnp)A^mPY;|uc8^XKdE`EX>It?eY^=eu%o$Zrakb@h;ySA_VuH1etF4Wi zSZ#BTc+z%?;9|FsP;Ph2Wv)Hd`KSGeleYuOX`90y{9}htxStMC9NA$PR_P#dG=na3 zTnOc0zCagaX2JyMY1js|0S^oEN^>tn~k`KLfl-p84+DBOxxgZ zO?G3BkFij@hd;p=47_(()LUS?sH@59h{np|OZ#S1du6-vP1!ZWh_;Q>@Yc;!NKxU$ zsut8ZxB2tv9sbUdtGw)CCU@V^GVZTI1UF#NhszmQ!+kNJ=KeQufmb+?%@+;KYPJ~k z75EQYw#*uAZ6OU_6$%CdMDYX9M63FTMX`Mt@lcPi_<47XII$~QEYZ#rU)5xb1Jp0X zgY7zTq3U+)S!If3xgxeLLY^UYkzJOVNqO=?NxV|n`bkwLPVRUiYE>T=p4Voz_;v*e zYP;>5m-lw@D*O1{@qQXdJwR=A z>qoGD^z&Hp0~)sV;KHWpAuBFGW;NL2z$_Yft=El+ zYpxE_7?A^Gw7|ag)MY(bN_iKYyuNdJ)eNn$a;4@)Sc^b^%aJwqn@$4!=k#R{b03Gdrx(Q z>UGU#<(b;+if45t@}Bx`*%>BLwt&4wy1MCW+bgbpn_KfCiKwN$^@n&vYiV1LxJiCc zJgn*$*=p8_?7JF-(jF(_mi{9x4+nn=Ru5YUibhhKnWH!Pj4=`K(ReU#_ryzX&}0C2 zYEs6jo%+sspey5?n1*oA7`)_`8{Xq3829lZkjDaoS-J40MR04DwWIW?U6!H^YTR)g zIjK#?R>SE9-B zgXpF4shCG`$1%ra?_g%fyv8V^USm#0e#BTuy)GcD5b31+Ww878-}?uM3* zZ>HdA!|}Js&|xNQcK=2D<=sQp8#VJRj;roLUdjdyyIMEtl7&O#O#b_k&79+d5$ub7 z9t~f+Q)@jspEAg5676MsFS$xNREbvvR+Py;mgh-#l$Euu`AKNIUHVxvQgTjmzT~20 zK}n&6R5B{@ElF$hF8SCNQG%7mm0XuDEisp^DY+m!UScM{RB~NjQUX_WmE2G)Ds55J zmyRfo{uC)zl-*OTD~Brze(jNaROZRrs*0tJl(%h$^b?Zx)k|B4YBA!%hIZjq_J@{3 zoa2JM{FLTpEna*t@fepOY2~0~^d_|8ed9yrJ2qXF$NJR%k$I_u+Tg2J*9+A_^;w$R zbt4+zx`Wz|TGP&++LxW4bva$1>lStYQ-7qVv_afEgLS#zzwzwg9u9XH%0Dm$Z8<)< zN!&0^klr*VDesv5qaL&J@4jnqH*g$*89jxGn|kH6#fas4*i7WL%(~1^Wj{N32)-hG zFTjWb92ds+V-<1s_`>*cykA14)8>RT&P55CE~u$`0a9Q^+pnBxzBTUb@9OEIo6YnT$@|d1o_(;JT1V9QGnmS9 z@+IlUUmL~2rJDs2-#q^xLsu0RRTo8P?sO+J%)l@V-64(GEh^aE-QBIIzu4W~ii)5j zNGM2mGjvXO=bfL2{oV6$-p>8j*=Mh{*KW~favBHIC)ZKFJgMIJiCo$CKCSHV+l?im zuV?+^yj)V~`TY8yeWB|Zww1s{-pcio5PG~6R)ci)}+%kys7FZ-Q8zy7<+ z%Mst(mK*f&Nx|VK|BCWn)Rs}-Wz@|4Jg@oq_p_aIbKM7P{uN8_RtIViwzQhjJzE_$ zf+Mg!axN#960@&@S^g@>$L zc}bS4Cd%h&@5`O^a``SpgM6=XoZMvemvKz5BxT08A`jzS0o(9mpiuX_m#w|r<)t3q z-k~UI87rIAxI_G}wn$J?wQX>5MNxllnYPbX>f7&Iwr*fWdEU^eO13z&=72n_;hpAY z>sb@3s~=SK58r!Y3C^M5Q+Dd=7z3uOY@SW-N&@}ds=z)s563vJyW=Pq?s&}Y1Jk%A zU_SRBSjcS$OSo)D4fn94fs2JSa!Vi`+#k?(ZZ*)$Wy1To7ZCz(II4%ML;v84uuHi* ze2yEEbeU65&Tyeoomk(gg-&Ty3585;B~U2km?07lnMuqAE)v9!C-?_;3og_80q0|R zjO#KLg>8_=!LbzJa~(TLz`~lnpDAkhX1ncXLWhl%cBekak5qR(-P8U%9x(AxG4_ zm*1+1RY2?RE8Q9{tJgMd*Y0cS*HPQ@^?v+veKvo*-lu()ZcF<#?T2={rnmi{%DH2g za%Kljaj_#yR@Sjnitofq7Iyv`m};_Cutc-GVl-p}2as6Cs7IAu3q6 z$S779bO_?A+m z`}VoED1%%t&P;Du`r}NKd)DKY_-tX@z27@KrscKbL;)BVmer#s24?|Nw5+Vxsr-+5gd)wxrh zKm1RWbjam9I??i`E}@Lj`((JgEk;Qd{#JKM{q+0Q+s*mLL*Qf34=zNk#cm*UkbCKS znGTl{&RUNXp1*vf{T>It2tz)o?FIO^C(tW%sdMyr!n=b+uwY^BzymQfxk z|B|~Ex5%lAEb>7Gjq*rwol>E|P$9}qRD$vpwNEjbdO(p*$&kM%-;_m?aMJMvS8*-2 zSkRAh8r%)X^j(Jh=!&<6v|lwIYPqc`YuF%nuJsaqspR*kmX&r%i{)*DMdzFD6ke{Q z7ILcR7EY*GRn$<*|97qUV9A*xT-njTTgo34+^A^GTUHsHtEw!|Sy;6?yR^!f#jC#b z^L91sho$;`=8>BC3|&o2`hT^DzB20KzZBJhY1`{{pTZloAMFi39|syAeQ0i4_CeS@ z_5-GM&4;ONPd_~2Ge26}e|+5DdG?d2>tfomo|?~5eYszE4y?_XB~bh@i8tgNS9BH( zXh)XBSpKVC2mRB$1k=^sOQ{n5X3y7t@>~j@588zhM{c3NO!(*)J)z$>acXAhi$tgB z=`+zI=gk~F=IIR6_`Qh%lNr+or@or1o$fhh?TqwEqh^ku_;Kdoc=61K<1n+v?W{vWkbu__aR^dpuS$-oqv!2E~&5DU<&Jx67XFZM6&Ric?IFl83Zf1S# z&YaOMZ6r7LS)yDn!} zPfdR8(8{7;!^&yCW}xPRrK?#lBmTAQE_ggb|r{Log7m%dgJ&r&}43OW)c{o zpLHNSe`ayWs2PI5l<9iE4^!zruP0CPOqrPJK7RZ}H`^GN>-$kK_Q8=s&dcLgFpk8$ zr+AKoVCM&2LO1$HBcZ;7uqMw}&{^&W9D7}N+7~%ru_EY$ z=EbDZrfJwihGzI(9oKP1Gr_!AwM1)`-;^(qnuYsCKl)b} zERtp03a@70DGbUEEiCx;T0wncN^tIUbh)la2Do?PzVYbfGrTlfyn82Onp-ui&*g&a z7#5s+juFFC&=8*2C^Nk7kgQ&=M4Y!D;h9$zUhmn8AMY7LNb&eW(D4=!_wf8kBX~42 zo)=7s<*lNo@=9sp9y6TKo^WQU*MRdKZy7tn*NyYa4|HqtzwKTSkjG02JnZ2W)ag+f zB=^`9T;X94-s`a@n1ZR;{UG$on1`p3q0 z^^ifLaOg+Lg7w|v&$=ApHr?%^g}O}x3v|AHOLYU?hjsTlFY4B|f7MNGtJQ69G3lC{ zJoV2S=jgvT?9}(vN9#%T?{waE=~`&*dQDn&fy%$CNpYs)wyd^HFD914giDHl4&)Yv z_r@09>y-UL@pB74H@D@#YGCH8YH#H|ua3$4RB6veRzUK8mu<;|l&#E{mdXn*l(7rt z<@$fDs_kXYwdbn38v^QgwJvD6+sW=+(4W|UN;Du+D!wWY>E9UIt+(x+&?vY!Y6^A} z?l@@$@g=RARK@5fRj}5Q(p?`Bzi}%G1;d=K+WQxt>i-%a9Hhs?Lhlkzg-uqFPc+Q9xP9-pgeHT*7xCJhw{j|wR zFl!3_pqYnZnOYH8<2PWkA=}ZRx7w=pdo3t~hv}mMYB+C1>u#AwXg-?vsR}F|ifU`J zyvQb&-nQSC1b|D$8$e%?FNhItvWtc|w&KArmeT`Nvul5f@oO*B;L`I)x4!GL_Cm*2 z%~k$(_0iS~s(HQHVD{jYC=_u6;wSkZ@QAhm(#04Fu4kv) z;@qBEM|k*J6MP8P@PKjFhTw-*Sh$<*VnnuWThuZ8>*zV)vY152K+GygMC={t+1Os7 zAT|kZiLF6I#jQtei-Tg`$GyaM#>L}Z;wuR=<0q1m;y04B<2uQoV_%RtF~3L=Q2|8t z2nPOU*foqjxC^;05CQ+|7Yz0FSqbjm!BFM8-ULN!Cr6&fkC5?OE=hMZ z&62KbI4u2KN0a&0cFD4;hvZwUu*#syr7B9rcQv})qzNbs)9o*vtk;x`H#{%#HeM?c z8-JBNF*%iT%wI~+nKzXEG>LO}i>T8b4KH47V!H+QpUaYHDS+GP9yw zzPth_vzFhKyeVHQo>snAWGQ`pSR9DHa?k%U1BYAvF{_!s*G+(#OX=%lT}WikiJ9qcnsI#(B# zfpgL259bBPm9vc-?~3BNx?J+GuvDI}oTqyGG9UWvaH{h?MI-nhptuB#CUFDt1b*P3 z;k)P>dR@>4BsORzd~V``eSa<)tkB*^>0XhogHO<8Q{Qg&#js|dZ|*{$b?U8DX8#xy$ww5D0Y zl7>gZ-NV8kd+k)w*_s!ko+_l+w{n|!NqL+2QfacJy!ekK@ZUITTHz1rj=yZ#wm(y3 zUkVas-UU&zqI|q8HD4<|ns1lh$Y;s;`Ez9x3Qoud3i4$y{s?4u{xamx3!~%>MG5lQ z;-zw3$!$5doT9j2*`c^vBU54y1OCRk zA58|%;5Vb6k`EJa(xLQd=O51TE}LCXaMW%&Zb#jnxOuz?uHIuDH`!|jSKvL3o9jE9 z+v}gmofwqN9SoVy%?Y2$eH%H2n-(*LdoO+pcf+WO-1ae}xuS9L+$9q{xFHj<+`AKp z+_ENqbNe~*l-t9J32sX!_H#-nM03RBr@Cg1v$IEy-Ot)G`Yf|*WG(%2>^{na$d!bE zuzK|3z!un4pC6zn@3YzB(xH^`VJ z*(Fu?b?#7{?8Hf3J1d1BI{pnpJB)pp_MJTyZGK&sT0=VawjAK6H=9}~G-tF#H=k?1 z(VWth(DJNtbnCx{6>V+xxA|RljqRni*v^MF30|XZGx<@aP>V``bIUG^+1? z@zFlozudmFg_1t{Urv8fL301w{Nw$<^Un4Y@)q?!$;I?<%e~vTJJ+r6Y3|crer{xM zP+mh%O5XLJ!Mu4rGxEcFGV+N%-Ua6F>jfR%h(CY2&;5DQ9rX8IxBhQ?x1(@D&%A$} zUSvsPUv$|(e_w@l(5vQ(&{F?Xvb$xO;!wu}4XH20$P%(_$K^3lhHeY;tK}Nb37SGi zpb$Kt&fxC1miX{OSuZxQuk2TI`?O8BY0DJsXR}wDxRyanHL&>^_UQ> zEBCA8&bV)xu+2St;#~KmlSaE6CV9Ben2d5i zJ6X!jnq0;0nEZ_kopO`QnX-?|n=+PrWAahA?UTGY-zH3PSu+mBdNcY4pE4io%1v#-AP5`p>Xc_YEdDg$Mqp}CvHowcid11$&hBW?zx}>(>H9@VI z>V%f-m8s3K6+knxJgv!8n%V>z4qnOMrp3jK=EwgoH4BS4EpbIZT2c$ww95X{+NS;e z)>iz-oj>Z&CVpkXIsTf0>wJ5DD*svj5&pFNU3^sj8h&=(O#bP-DE^o{QyV_-eOq%b zukAzb?$$%OFIv{;RyH5YMK!nOu5G%NhidwqKhT);C#-36VM9|uG0?KL?0xInD(UdQ z^}Ey3?ALp%BV_P#U%Chs{*qr%P_)ka*QVpv3E*+)H&_+&Gdc<<#2+Qn$j8V?>TgOE z?JJc`-%a~M52lZEGSmM!H9JjXh#5_cK<7=&4=f#Xm&-cmot!-9JTB;*;Nj0QdQE0k z`_5(k3E0GX7`&ggGVB(sZbTMK5GiAwiXOqPj7epiVijy={7RSbkxedR6K1_|m0mmRJ$A9*n_9qsEwZYh7^46OSpES$$>r_s< zWeR8QL)j(`QL0v#ip$h@MNia+gpbv01lQEFhi<7O2XCkc`d6rD_1RQAdStpV&?9t{HF}xFLQfI-%U4IHF&p zTW6hOVM6JUameL}5-bv%Nc=!3Bu^*XD93{#KzBOCd40LCddC`M#f{EJK~l&H^llmJH=dMW<~C2d<@4s#fPk< zB?a81#Q6Lr33vv=WzH0QI4cV)rH{oFkwvH~{3Rp;!$llGoPhZPccFC0bjKuHlP%A@ z(X!vjHEq+A4G)KnQp?mAG)5&>%~LceH_L_;rIN9V$>IjNO!!6qP;g5=cj&g9IQURr z*8fg^sqdG3bZ?m)?CzF->e9-Wcj6S#4xZvQKS43BEm_gjvQ4q8`G^ADv{CV?!AY^K z{+isQu1#jGu}Y2AfRs{g6ECO|ivCsdg^MbS1gy&JAxp)l!N!W60~ae0{nU#2y&KE7 zc3&$S+4-VW#s5@twza(2uNht3-jMpQzHY%kTpv@7G?eV3YuqGGsb6R`bu;YV^0yuhKLkXKN~QMuGCS_O5J(<0hIdBB+!%H zBk2MU5BeK#0)3yKftDQDPje5crPYR&(hvY!tG0D_kv&6mUuoTfvlnr%0lT~zt z$)C5U%Qx~73RW9T@vY^VJhHh*_N%c^I<4WGL|V5&{Js_?I$85baJV{n=yp~1Kx5_9 z{@BXO-olDyJzFYTyCN%Ab%N#1?UM2Z{N8eLE2837%hZZ3&Gi+Bo6c9(G(M<0-l(sB z-k4h(F|1Qu-F&Udwe@T3Y5ug1|AxH>;(L_?X9p#swc^o=cZzRX7oE5Hig^dv39f~; zz*WuHzQt3$S}}Be0p+ z0Sq0h!#u$xVJBe-I2TMPo{9ND2*I2q9l+#MnlTCVc~~-2hQ+fV<03h8@N3*zgo~bP zLaL91INhI0{uH=^@+eq9C4@ep`-WX%REI5b{u!3T>JGigo*mM`#s0l4uwv;=bQvX?97L+Z0r(TBb?61Kckn|FC8X23-Tu(zXUWu0Fa~Hp=p3r! zno-JEsycb7vPec&U}cH&`_gLJ8tFAzsPvXhD)}bcClSah#7=UxC`qms9+Wo=(&P_^ zD&-3Y)pEpuK>oe2TE43Htenu}FE8zSAv@byCmq?5DUtCPh%dMO6^6Fb1ZB44TgZeLn6moKRfYI{=6Y&~AhXi2ROY%Zu?(!{EH*O*#E zZ49XW+#syo($G@3p+Q{#xFMmD-dNhCY5dhPvYEuEw>Ea{;}d(fbbjsE_EZVLfduJc z5ks|D9|>1bOmaHv6-`g~4x&MPld183Zz${h$5S>3gj3uD_fzf!a;aAWJ!t6x zb{fV1IsLm&AN`+aHGQJ{Jo-A>fOWVYP^6q?UF z$c8xEXARf(+{Lqpgrbi_ zZ6cVURm2c%*_F1~J{HnsjltxMzOT458R&ep=J zPv(DbaC8WpAUz*jSN2=lS%SvySP6UJiDFQ=SZkAwGi}h!x0{R`fIIeOC}$Xmn~Dx2 zoA94#O7c>MjfQZBGCG|p%p_I;^C%1Ee1hfee3a$kyoW_~UdMtsZ)Ei{_pmCMFIXR$ z9jq(NN$dm68uk+A6_;tu1Fj*=CmbGAEtI%4hNo{5jlm)FI>s;4$>K9bsQ@t~4Fcn{{gS6LqWNiy}leR;CwE zkZ?r5Mc)KZh4+Vqg2urV!Q8=p0_fmvLG=J%kTWn=_;nylm^m;(babFiL><^A-rNsJ z&h*`o?C+&WV|$KD2fE%!k98i9g6#v6%Y0A_Ybz5yYS|#8suKCMs>`h_E2Yi-Gf%a zuOkG|dq9Xo@8H{h*gGsW*3ssv7NwD5HXFQ6V~6W)g?hYknf{jntzT|gG2s=+riRZ4aw=<6o)$(#oirH*9|I+x)AN)YMzy-pH+( z-0;5qZvCQipngjEjk>Mn)9R|rJ?nN>MApr$JX^P`idElGZK>Z|8`ik8KCS6y#KsZD2dI^LN+vo|@ie10x2v3;Tq>r0vpB6{yVD&DJHFKb!v8?KTzE4_bu);T+5g zG#}@St0n{!^u#U1FQiD)2y!Fo8hO(2B#tz)8wEyLN|{f&M!8EFu6k0$lu`lnQL>mRWDaW*rI4LKz3Y0J_QB1~ zN#qV?&hzwOwRxX+ndoQYcn2Werv;woy$oFF;TE{gBgg+6??2xl_ak0|oDTOPcD3ty z<_Bkxwuionyqqk>Z^QqG$wjY3CLwmfLV!ZZD#u(Ty3S~gl}X1yuhSZI7@kQ;{d zQw{5fed@jRKlFCpYrR(YLNC+3(<^n~^*UXd-lFT#!}V4@PR}&3^l=6c{Q|?V=a|8! zgAP01Zq@f|uj%BPt=b&5izZQZL-k#uRe-WEIa#_`N)xXT4+>@oUk&;W&F+`=n|tzm z-*;W;UemF?Gm5{w-J|tT+sNkcEk_!?nzi-ijW6pyH{7djuCJ__TtBM@UGG-oTtBMj zM16M6*oG6elNz7by>G%btZ1og+}b8-u5Dk?cCE{$<9Tm*H)1fg@4YZ^C{=0_r7A_T zw_1Vfm$6It!}`^<(=p!G0qk`&BY42bVG6;4IfT$-qmkQjt;i3!@u(c!S5zSmgU-Tj zN2lS+(T{Qdm^--JmB1$fS>QUctD{9^=g6Okw}z9&uglQSR2|^~1f=C%{APYxnT;8|Asr zx7OpEcMT8g8RC9{3wKL(nddTr>Fqp3{Y}3?97|b(l@c~1|6+dwLevJwLd0h;NjuNBKs(CzL+fed=peRKU5nMCdvD#U z-)3#qkFbt0NG#iH%clz`fc0BCmx5xE_wS!$B_?FI1e6P+K z{EHpi_`V&#`H+tIc9#xy`=O4i4t8ftC$tMY{MuX5v!Q2r982%!{saBNgJTDYf+&HP zXqjlG56CB=kbq4D=G%RrF?<6nzXf7IO=hh4~E&#0-YF$`u1b^_}P?xqW#py5;z=eoZk zr+Lhw9{0LSyXU=!-soLTclZ8HKj}G=PT?)5vD~=SO7>0i0%jVqigp@5kBq>A_*JOk zF$r)bay2jq9tME}GeEQBn=K05Wlgv3w5+rK8OG4b=2d3A`H2ZM*^PMfeq)T;Xjp7M zX}DxY8`8};^xbA}J<^h+3$`rLC0n4nq+@JYoYYD z)h>Q$^%u>sE)wKgZVmRCTl*_aQGI)iKYDcf#ocps0bNftp`FdD&X4`)y8iWV?v5Nd(9=JV)~g?+ z_Kz224s;7shVsOBggw$;@fgKMS)0mD`9|xcc|42`U(9Pvb+(UIgF_DjurNS|7>Brk z#-huyN3l1DktvT*Is9_CPJBcJi64nEq*UVY+y`P5NkyQOP7peX2K+PPa{Mx4CXPu& z+U6nkF}PEs`znULq~-J|YS2`6zzUV->-Aw}`g( z!bDBI|AdqJGK58a-NK~)Sdq5BUG#GxU3_b>Qu2JrQ&uhbE)Nx*Rpy9KsESDEIIpZSvYedgsXkex zx84A0q!&P(?@@v$xX;IJ<1}KPut%X^GqaG7=%W!&DIKsM#8-e0cLKT*vmb&%?RJRa zJ3$Aq#=ZzT%GTuww7voZEZ6Nb%$c_TOj>K7aj`Yg*k;K$EVD!!ROT=GBj#|u)$~Ib zVVbIoGq!6T`cvAAx?rtdGo*=Br)$**MQKNf`RmnZSmG^p{DI7gJ5p$iZ( zSSxZRt`6mdACEqdKZowc=b@>{+2)P&I#6fu{|BQB%I5gkrzh954H%SR?mP$rWGK?^T<$r!|rK(>gEXMT58bl_|pd(=x?gY)f){ z17|=}ARHJKD28u_c_Ej>$Dk~5J!%0W75xYS!L%b%F<2xXI}w?IJ&jz5%R{>0(I^pq z2CAO$8dXg+qPj?n(MU=GdKA?UlS+Gv>8Inc;~5vQ@0dEQ&3O-Q7P|wt*JVEbglist z5+{Vv$hk>ixIu^sZd-{{+@2DtZs&+890KvAYZSr9g@a$s`i7m&^uj=#4x$cI%MfA` z7al`+2E4;2K%LPHNFE~CaT#_Nybfi6Ee?r&DL80%wNpS}+YE4-^$yr+X#fvfAdZ<9 zCr7*`)-lyG#Svhc>*zDjb}TT@a$GZoJFXkqj`ap5$kZ2rpS1shk(vo$o(c|5R%Y0{ zQI}r}&L+P@G^}E4gW{ljK;&NPnAOO7EH=vQ5T?GJnHonN(+%6>1mB-)r8> zGu2duKy^|vP6a5tluwi|lv7n-mCkC760X@bJlrHiJyplkeAG|V@{G@Pe@xDX{g!ve zQMT!38Ys319an4_P$IYmcGRJRe}*hXzJ%^ZO$Vl;-vAwGIj|AKg-I||VMnk#V9vNp zuoB!i*mZm*Y$rhkTSo-o2S_~lee%d*1@SVtEA2S^$nafN=Trg@W@_Pwom~+>Sc!;I z_A$gSmrTTFS2be5H5}=|IfJ~^YyztUYA{*AaX|z333ILHrKDN}d59C9{F4(nhF2N`oGk`9N55j^mwNZJ(&9 zwlyi9S`RBPSg5M=<_gtE(^0j}I9+qh$kWCd$+{pTPruSQ%1~)MY20aQHq9KyieyWP z^`dp1y}@P!$AOuUw~qOM6BK}N0&XK-!)U0V@Pp|4h}W1%LvL&A7O5K#=TAwGv+BPGJukTLN2l)tcK>Q&f!+A`QFdOYlX z=G+JUk8uo=OV@)xsfqTh~3%1S`U@*V1puHRl@nrlY1NBfF23nSBPFh5& z63Zqf&5Bm6w5G}4SWie*)>V=S+kWv;+cVL3n@MQ2?Gnb?nZl#?c0sAVLf{1Q1=~QB zuo9dl^mRNHK6Ic&4#y7BVTe#JW%mciFSmyX{vsEc*_v*|tpw*#Faq4(BR& z?JyG;++eN;dn{>=owg?s6!;aI56A3M4C{S`{GfL&0 zg{ow|MBQSaLIt^OL0xs3hWhIghRSjwq29P?k;hybk+WTXAvrF0k!tpC}W-g1h8l+zA_4V1^Wd{T+!Awg%_g&Su~#$@WJq2}urA|kYRV2K(N z^sD+RWQuyRBU(KROjMt;e^r;-0yQ+7NHg2|QM=D_U3b>JU%%Tl%P_^rFd_{Z#vi&c z({k-D6GoF}`lTv29alGw+kha*N!VlPeK-a73vm)&h#W%X zpvIuCpiiOWFz+z$F>kPPOe)R^y8<7DokAFo^&u|6`jM7n{m3h@36$m7`P7Bjy|hH^ zO?ou;tCI&dlYzv3Wy&$9oa-?$tSrng))Nepor)R7-iuku-h?^KUW&QGo`ZS7o{jm) zo`?C$j>SA=>(I&Ujp*UMs3GS&$YSPn#9Brhtce~CplK%|!IV5Of@HEq5hh#XaIefs zm=MzeRI{NN@k<{9|EDVj$hz~;E82~aaoPorVC`sdtd?#6Pb;wsv@a}sbj!^So!$6c z|HUxUFiu}#&}e5EA8WoCSE((=2$i$RM;UI4Qj9RIkdHBC$R?PmvLsWQbctz#bi0Wr zy<`$fKAZX^Jtnn;VAYVZm6c2#{JE3q` z6F`8EhEoxb5GbSpDMZGiAE4G@g3-INXVA-Wh3H6pKN?CHZapB7F<*&(m_f(6>{W&vHi_{Y)8WL$csnJaN6`aOF0?^J73COw8Cea~5m!ND2!9<< zaZw-)n`t|Wo^8dWD3-4Xi|I6+X4(K-Y+MO67!skU3{jAU2Bc%9q1S$C_)Xt$*l3+; z6@{w(# z3S-Yu?YDcWHTEa!^&mkr2&QTlIjou%$6oDZ$dL9AWTnmtTBBP4ovvRC&C}0=jxw;I zIfin`c;gaCwNdC;W7^<=nswkS^I34d#UCVE#r6v8U;6{wFZ&jIi+u)20;3&UL4Sw{ z41ykWL;&89F|dBf68LNA8pJB#6p{lwi~0jQhfaj=$7I20U`=p3E*jB-TZedtzlqpN z$U%%E4k0KcB65HfjZ7miL$0S>Mmka7A|F!uNE}UtOrm+B&d|o9-qE(BifH#y?X)tK zl4e3d=wWCAeI1%be}v}I8_`^P9a=^Ej=n{kkA@HLiK4<$V<;pfg=~fw5`V$w6LtXg zI5Ko5_PZk=y#kzwV%r-KR_iIa&@u@|vbX?=W+~*aDciBsbO!V=O|#QYRGW{f-Ll#A z#r)fJ%@k!mWc+PDZkTVmtXEsob+@fjZKN$qTV;EtS#5XKblZQZXM?NMA3&aZ05qr^ zAYWw#%T+S4Sk(pAsfG=(RmC7g{S$Oo{{!c!8^OzJJy@-FakyyaICg2SIjS|SjtH$6 zWPLZZKpz4G8_oiE4V3`INPulL&VnXp@?QkcP% z4_j)!3@aRVdkeBO01qtl0iv}CdeIsHCD?94?%N!W5%yD#8avtXAD9b{cBFtb$RCchE-FZ!AdE=V0n~E*b|BnmP!HO+bN## zd6b#(36#U|5tL7G9z_i2P&^QHN)p0GUW_Oqk3uXVTi{)!vv60E95#g*1RF<41bpzx zP$_mQyu>{QlDJZnP5&^eefwQekU*KH!iWZ8qpT9 zvDid5-83#T?Kb>0?bP$kM|H2v@3jFIp(e*NL6dC#t`=A)s*l_HRSf$Z)l2&hl^?iJ z^#+`(!Z@a?Ryh`^o;WtEDje5Ua>o}Ha~S)^K|IxmA&1mCkSa9-8lqVYeWCddrD)xN zN7{1$OJ@PT=(fV*^#ia5{T%ofLpdB~j6%FL-bcin9Ees^5^|gQH4<(aLSDCcprj?+L3{vB|W zkOl-3p8@}f4}h7Z3qS+uBruV@5BN;p3|Po(ff&j%U@m1bu!b@h*g#nbY@s9%ua^Rw zC<}n)l=Z+e$_`)w)bWfZ4PSI?kkUJU6Zec}Ah_mtm9jkO5&y zG<-BoH0(7lG|V)dG|beO7&hxz#@E_&Mu^s8+^;!of@@&r&+5zOb!tD$NcB$(S-rrD zRZFZU)ma-#O|@gykL(<^GZ>)03?`^`;9~Vm$3FD~$8&Xuqe|@sL2LFwW@t(w4>kT! zljah1q1FN|)9wXE>7+n`ZaZw6UJPs3?}i^SDBx7%Zp2@s1hLw*8p$v>A+yXes5O>n zD6Ca8e0I~(Q*AfVZMF{db~_7Ww$H+x0#{>@j`f&}j`0{Agn+pO`G&YvE{=6QU5=f;fVFf}Dulg>pg8K${W17&!uu9YhGQ z{fJ_m1aSkeLd+)^5E!BX@swync#%Yi%On}1m&8Z#$Q_7@u2iJ9yB#*t4vi|p1D-}e@9mVCdJW2yIN*;&w{%{AV{!a!QCMQmjrj0Ai+#P}h_v3bVrn~?5=bNvldt~=^`_+3@)ibjFmBX z+ud$9;$E~B0~Ofdz&f@hkdk%=hS7$=b6Of`&ie$e@@j#4BJAE42i#7whbvWXca^&C z)O8j)#%bm3aPv9616Jk2eA)fr5j87nv#JoiRNaoAtGdTbP|spUsRprq)son*>RRmg zDjfTrN)^{!<%w&dileO_*Hkq?zinJ2)dTI2xNp_ixMpfbTm!WzuCZDZS5s|>tEiU8 zrBexUujTh~n`G9wZ{;7c??i*x?&8mw2RwUBW!@!vK8=ogz!HLa+4q4?_Dgq%xv0W= zfUK__vB_UTDg8ohhIh@R^QP-fk!F6QNL4R7QYCUK+#$Ryye2d-%t9TIx6}y-lj?@I zeySes{i#9t>rait$v<@rzfBwxzLOXqK9RUF{Cncb@Vdme;Wdd_BXbfPM-mbzMTRF{ zh>T23;SEge?Tt@7;Z04<=dVdz>Yqq-bvSXlF8V2~$9@`PZhU%YswVZcdy;P2uR{&k zsn7}5JY0?v!@Fp1Bo8m*E#;TIfavWH7E<333-#ABqe+m<%tM*X=2pY(0Cm%@R{7b# zY8XrF9AH%)!-hGq}wZ+M&nz=z`-5c`fzzJD3xJF(JE|%S+rptR#qvf~Jqvi7GLGn@b5E&cO zPks?IOqP!sB0Yr!cL8w{~rfd(v_yVv?El|3iNnyKQo zuEo1(L5cpKcCgh@ScTBdey>3z2l)mUdvDk&ka@e&fx09 z(xhJA#H4XvucVb;_oOXe>!d4Qo1`abUB6{g7QaQjhxI|x#$=SQO(!|j9*}~C<&UhgddCK-X0%ytquVN)bEg5%=gjA| zoXfm}6C=hu)x~0GnAqj)z}58E;;55H{^9hNE1a!zvLjSIr;*C+Y*Uw1oHI=gb}FcU z9K<(wh1~BplgRMptiTyz0tup7u$fpB%r9OA4bK#Hi&u^MgSU!Wi@Oh(@IFxqyjxT} z+8JnP@$ONpdEcll*gnPwMqT40qF(ZGQI=1MiWXC&(um1XpNU~n0ns_?39lG+n12>E zo}UPo;GKi_=viP0)d)Bg?@nUd9mO`Q(RP#6W|A0a+H$Ll(^%XmkVQW*zxgM1Pyd9U z&A;Tm^K|5}S242LTNs|_r429eR)rRO4MOX@&q9a2$4TeCQ%N7a14+^Tfuwx?;iQ`W znWVPq~f2X0kWG4Mey z3@nwe0`+8tAjvVo-Qtg6f8h6(NF8N(ZeUY7YAMEl0I+PzD@Bz-KQ}KLm6jKba(L#b zD4sehLNY2$iNQpA7<^1;gSTm0@GvC=f1z%{QB){ci(Up|C?T+)We9X-@vgD=omn=W zlg*Y>D@|Ql$kY>CbtPU-7ot;s7S`R5wL$+gbHGchhj~T(8eT^)r?)l|x<);o=KWiw1 z&KD}F3x%5La-r_JQfQX08(O7XhA!wHp*MPL=nJzx)ZAPQtuV>LFHGZbb-N|J*2YBA zvT>1k=0{>^f;WRQ_$m1oe>wkF=Msr}qnKmz$?|rkyke89!EA_f>8e^pxt+9pxHFF* zbPRCoB8s^OMNc=GoaHtIYv#x+?rHhP^`#T|Ql$tqQJ)9Kt3rXz>g&J_{7;T3r*fc_ zQz6jTDG=D;qzc@3-n;qSgKh_Rs=Ljt?7nl2Q!=p5853ya>NbT^bNK$A{hqy}+7E^FSK-p8UwDQ&8ve(mjnuIdB3tdpNCDR0Th2atd1->b zi8AWqe3L%R8=H#amN_dX+43@u9g@GWe5xo-Q(Nh|D$I*HOZiwQTI_Z@iLi4>WOid@ zUAL+1r;n(#}dl|e|9{1ix-bGeKUPc;6LXn&i;k^sz@~(s{d%MD2y^Y~n-n{T( zZ%+8BH#wZf9~Um`4-dEVhlI!Z1Hvo(Ug0Bt_wXgZTll@-A#Bmlp! zUK<{yPlxAgik#5JBZ+!!q@1}F8DWYdb6VsTvT^<*JH=NlS`TBhw8yfVLA2iZRNM~c z2d&R*u>s;w_D0mER&ooSlKFWqHI|Q5kN8*i};qGxY!hNOU-E7V%x27}P9pQ9$*E>zzJI>c`z)j(n za-TWv-R;g)9NFTQch0#H_1fK|RG^niAIPf;2kyzTfuCi)Kug&&kX5!1+!NgcTScG1 z5YaEtSo96#hB^4Zg%5eNz%gDSu$pHHOyn=zE_|C?lDBiy@F@2#Ekb#+yOi#@cH}QA3fLm%zq!r=--P}^)E(R`zIq4{3DU|{(;D8e_!OCzax@N?}!va z)>>C@h;-5$BV%9*dUIrh-V@oOk3>%CE0OE^MdY={^(Rxz%Wb-N)y+z8pn2l0HYNOr zW`>`~zV`drCi=8JrZceOW+K~U9=3zmKn~#F z%QJk5j26#iW072q7xmR~(NjGY^HgT}t12gttM>ASnkZkXmGYxHB4eG0GR`qFr;}CX zN0w6DX`?DRqf||2rK;`xfjs74Rn;MHuow|?ylpB&J=##X~|bR zRd|0V8PDUqK@|9%2CJDAty<9>nVHhbJ1kzzWlYpyUAS+r&}v(en%Gs$Gnv>%GsQMG zpIK?9nS(lq8Kn2V{Na_)Gj${tEw{x7&Z@{pFwcUip7{ z0e#3Tq4#>t^*%3N z(7$Z*0jF>MPi7R@zst{Q-}*Id8Qsy2(M#+deasd$ip?`sSlA@6cJ>xKZ3|IJHilNR zyQHWPA3!ttNqWEw@G@d3j~8e74Utl00&eYPf>6r+lm?%NMGF{Gc+)M0H2_YOS!UmmsGYTAwrLZ~j63#9ymk{HiL) z|5WMu3iXx-sS8wHtp`>K^r!4bLu56|EOXL95n|268TOPfWk2vP%ur!Ai9Xl>?X(M6 zZ<~e{wwvw0rkq`4ZkRS^h{>xShf^QA^VOqvh^5?tT$LYN{-*Hp#nr?O)LD+C?6M|36q#t6c)==*1MD83!s2-omX+sb zztcP05Lb}jvhj8lt8Fv0#sz+*f;(ZKb@ZLf1xM%HT7h_yPoFH)CvA?dV&8?FZbijD!-K3 z@3%Jx{aNO^zso%J?;Gn&n_cI%U+Y@7t?p{a>xp)=USY56LpIjjv=wn@@KBS5?KUM@ z#Pnk2?PNCDo?zGPJC=(TropTmonvb#E4`v0DL+3(19=v{o44nh|HjLSk9?dcFAj*o zA|kemg7S&zD3iL=dH(&C1+e6Kvs7s{FZ2icsLl{t7?`J66^U9?n;qDG<)#fc2`JAcdu z@Et5YAInZtZPtr2v5fS@9%j32H#Wwm0)B^VMmx|xGP!Us)nhZlEHL#!;E8{j~Zz_;<^%q_6s2ussa@ zwfd!hOuzC!Xs*+kSY6rV(LGIRJ(oi0N{U=qKBYrm_$`N^@5p;Wx!xzFsut{Sc|kif82UJ#>JNpdWc1 z`iiH3civ?yX+8U%`mkhBoYTx@qZ#I%*gBhJ``MkgjvZo?+tT)>aqM1m#{6Vfo35rW z?$fCQ6!RLbt$wJV>l6B<-l})&W%_454VoISN9#d)FxEYxuU+*N-4XlR>lM0_-lBWx z<9Igyp&p@qJzi%ti*-e_L4Ris>v86;US&S%(jnCVGf9V!Ajkwu{%|vQQY&JTg|6mYHN-SweP^HDov05V&@N zb(eGGP&pI5#d5q{AZGyK1i4hs1vay>ZvnPu;rM*8c(NRUUOzcTwv(e|Q~3j~#&?!Q zWLud+R+k1Ib4%oedPmDe;)56<&WL*W4B5nZ5#sH{5nfm<;!2AnL(zZS!jBgZ6@AaHY?40bJQfW|Cl0H*akMY9bl{Cv-Gq(>{MX4 z&3>>~Y&z!IvMdj4&+4$LY$)5q*02Zc3QI`=sz@cMFZHA~w3IHm(5pzR+00f+R^_7$GH-VW=`fv-pJbK4SgmzgOKCcknJ}#Yw#5?@;Y^;%EG& z31Wok1s(WSR1-x-4v|Jk@s!`f)x;hAXP&?Z^Y7tz#d#)t{`Yi~4$)friAGRsszs$J zJ6ZOM-DJnu3O0|8WL+^5)mToJhB20CFWL)sm)&R+u=K&$HNr@KWsBRaHofIGU|*SM zcnlgxPN?gTRqy-~dt;m5cD42GO!&?!JKi3*E9^as>dii|nOMjcX4zO1R*v;# zomc`J$9~0fo?T;jgo&l40#u$FQ)e)525koSZqOr&=CQm8FTvYjnTTZrmJ9If7szPh zM6AdqvWs$}f@mP>iZ&R}KBA}iQH&H5f#+l~N6Z307l@@|K9*%-xmbeHUxxKcu?l+^ zpj{#sqFsXX=8KtPHeNde-Y^N=9xb}yy}kubRq@_MMH7);R1pfj7d)#t%cI0^{0*PM zuL7<8{2RUipL95n=1uuiDvsD4OFxyF!!-MMYek1+%m7wzA`tBZ|)e^J}_zQW0T*$Hf8N6gUr(QvT=5j&2CrP zf_9&+X>Zw<_M`1@KV#Eve%w!4ksYz$v%9u87&o0|W{X%EwjWCIH`M-Lwu%|_($PCs zjM7shssiS9r36|;yJ;_7K$P$(hNt7@cxB#_x8f7{IKB$reV89aJiN>k`CI;(U?Q_f zCklz2q6|j1D$s0*^*2zomZH9Bg;8$>4BCk1qP1u&z88)DvzEZSHO^@)D&xE=z`q1u zS47knc|;B1R87Q*lEU!fU{zjmkLM7FcnYzF2gFbO6Ht1_Tl0&&3O~ei!lPV1g+HMo zsBymGYpD#ML@9Y!`aremES?Gdg<@#}y^e&Cme zog)L zvWOUwTVzC*lR|unh*S{$!Xgtay(l2kqD_Hg$wWTk;yejMl`TF1pQk*nxQiU=JWno; zg4;WQ)oO0|G#=)o`AgoBKj96*wUYca&&Kz1hi~SuXdb^v6Of(so#ZEM>N*meO*ox#(dwh2_X39xEz zCjjZ$;M7WJ@J{<3;%Z}i$F@O^)XGMo(#{3U%CPRX5gTHAu;F$jGRpaEfnCGa+e2(0 zGRyP!Hv7jug{~*Dl#HkZqFh~;o_=5jX$C7rds$t&#=av?{V4~HrTW0H7j2=R=`s}b zArw?{&NJ{lh$Yo{1Ktj~z;GicY|)F+azv^OL+F z?vwd{9TVi+5Y1Nbd$f=r2W~rQC|`sec@j0_{lL4HRFGGrIQ|udDI@$Z3UM!y{X&n} z1aPkt@T)~@Ssq%zT$%_C9mq}~3)sY(vdQr5f$S^R2vM*i!<-Y77_W%6VB;J6(BAzo zDxR}{*+1=GXzM;?Icx0}RQEgV&rsTR*j|9GRrYr<_7LLMMWB7vF0!xeQsA}7#)4DX zfK5@h!q#Goz_XS12e!(NM!S&xYS+T{GvrR}cYBSUvX9sm`-(lX5hyw%mqnq@NlnGz zeRWwr>dp$#7*>(iv1)XjwW6o2Gey%-#K7rL(ltPH7cGE>?xKI_7FlRfGM*MF=I0f_ z#oAEQ_Pj6e&PVZ)VB}c7h|h$!&IYCn`BvCYzL@X9-aULCQ2Gh&OumoDBfA)jSTz!; z_r?A`Xxjjj=KNP)mv7<~fn;%Hxw-gCj+ql4;PbhMUj%qgGx#mwb(}`?{qzH0O+EMm zYQx7vF9%X}-hm49Ca8BRLhp-{rqA)IlhH*A(oTBMmeId#EL}%!dxF)cgQ$~!VQFXy zR44&?+i>LG{g4N=XLDI&HkQ?5U07+>f)xa!U$7D^Ez7}@vy3c&#aO|#joA109pcm* zXx}6I);>l59`-%7gc?MEFLCUu&4Ts|v|l63ufuNHR_u=L1sjR}Y{aw`=jDGT@euK10OL#&S{tmY1rr{M4A0q@Lj3Bvzf4v2W-P)|_s# zuE@y-!E47-X&~2zRw455qa}0-vG5*{d<_ioZ~{*T^~%P-1Se|nGQ1vQPfjRvi2DBJ0SBemedGkK+Tm!geC{;%}%w z_|=o&psxHVxOJG?^G(!(uY%2`dVC7i;zOwd?(;3i+hLBO31vc6mx7nYrz?cdh`YZj z4dPxb9e{SOMRfm(Ub10y3;er`Z+i?Hx{qb0P4MVt>@E8V7~e__$Vf9!`Rs{-Mo>gY0koOe^LkqKfh?lvcx7pCk%!;A{D+DW#2>O5K)`c~Pb%6E9 zzA@0_1eOljMr!0tY1k3;&!B%7uX%>;Pw)_f3Ot(9v*h4d2FlDbQFg?(JnVDI51ti6 zRacP}p{nq_R;(_`$5B?~ zA=xlzo*tG3d1NZyo>KGg=`-FC^-M!Vgw8V0RUD-5-=5yi1Kw z9i(NLdru&bjY16UORq57av%D6A0u%VUVR>3ewfA5e$-Ao*h{va-3CW4gMo*Ec^^oVrQYUb%5Af>Ba!_wz)(v?`AK=xCmB4ms>H%&IVC50t%F#ep8U4yM2-`!! zwb85!O#p5)SZze``k19|OxwY~V~Bs}5&!;WJt@Tc(Px;S$O$VA9yS0EJJCw8auX2U zfn59maQu^w1ItTLsXKHAb;cFgIk55y>!iUdE6aXv&2Oz`cP2iS(~)xdit+J$JR zhd>rNk72iP~@VO4qn4&G#6&?TtV-x$>sP_RR& zg7>k{eqkGd?FKM&8P?0etGR3&s<8uX2GITq^H$R_k24({ zO902FvNz}_q2)9UET4*;aRxA(49sT2bEW~aX~1k2_%$8aBmlDnRtejcuw99M!Y7;# z+-3ojxX0FD#tOKH(Xd9~hgFy2r^3@B_*~=KYTj<}#@dt>X50S;*1OCrw zHug=!m`{Ypjl{8`U~fN+e{Zzia86s~xozPK%}{SQ0wxWyzdp8W;8-oRRj{uz-n#-k zqztSqyrm=}b5ZzFVfvj40k_Zbm-Ep^;I|aE05Nbf#R0$1=m*5XUYOTyOJR6yB1Yjg zM(imf3a)a}ZSe30OMwU?kfRz@74M*T&%vQbK=2yyxsEFNB;wX-9Qy;kL)fz){Q8aE z2TvaX$(KO<6HxWQSqGXHO&c&D@+-V!Bg=(;K8$xk%(oWDzS1~e65G{qtStCb4f`uY z$^YM0pu7?>Rc k-wskK>@S15rUbZF0%}kcGYwzSdg$i{*b3w>izpZU55(tI`~Uy| literal 0 HcmV?d00001 diff --git a/assets/sfx_select.wav b/assets/sfx_select.wav new file mode 100644 index 0000000000000000000000000000000000000000..3e65be69a521273baffd3e749dbe8253ef9204ef GIT binary patch literal 27724 zcmW)o1#}wO*T4rD!Q<|35NkY;)VP~g0*e=H zS`bJbGmw@=%cc#Yji3#tO{dMGounP7>8WvyevH0?v5c`3+y&-BIZ!f^h&*S$W)5O! zuzzrJIjOv4-W~o;euqP^L#UI#QpvHlX#(HDDwa!xKT<1_XymnOWv6=%lCGrY+fZSWYR<=%-UoENjtM;$n zSGBXMrn0GWXk{ifhE$HP9A3Gna)0G}YS63j${|%Ft1eZYuBxqStP)g5S8uJ}T)lx} z4;5{w-bQ%~HFi;BYxR}tzpB$@sj^M-4f3V6OKamA;u;E?CC%cF?2hBTM|v-+FR3S+ zCYsJ;=dmPk0BGPCIM-dSx_t2d=&cD<2G)f&hRuqa7PTv8Pt0k-2|>%R>+0(E)$FYqB_An2FFPkorUp$$RyS9-RLiTYs|%=6MDepam+Ib63MqB_gR10L z=TS8&H3}*IfA$x3&rIbsm%cxOA%~w>HQ+Zi+B{hCkS5?cXpCPLr zDH|ypB+rs7Yt%J!>!;QK)pWDzP1}pM8{Id%C-jf)f31I~e{FkibEkRI-ZS4bXFE=F zeCYAaW2k?o|Cf;5kfsQE#NOzG(d{u!F^>dK1)f4@;aK5B;TGXK;U3|B;c4MX;W^=1 z;dyFYq@s($E5d8SGs1_$OTw?ztdep_>}lb~*fYY)*t5dHai@fD;!X?0;&%yC;@yRv zal-_hI8*c+p)iUoaETZatqgq-sSKVUF+S+8@Z`Xe;kN=dgQ^$DAfSe#1hsx6_-_8k;P0kIG{hk*ndnyT)EzS>;{ZSYpD=!X_Z7U6v zEw6}>9j=a)eXWU*+3Le(Gn<#lENzkUoUWrapZo6A^{e(bF4T)!CtJRDHe${S9>YtU z!;+fKj$QZ)&-oA;pyDo#nB+PtHr;1LQeqICt`8e05=8}P@nZb4`GRNJ7X^mw9zn=J zzHq?6P~p&l3Bu@sDMDj*rtnV+MV43?n3X9E7H0@kMOngOnW@5?8JWV6j5HyUo+0FC zBnjtaqzkJl&(F*d=4H}^?=u$)LNbTOz!~qNcBM%ozNF-b8Iy`b<_!o7W+zq$vJ>!t z-{X%3l*jE1*bw(30FHAD+!uQ-@V(G0=(gZYP(VymP*fBd^ewzQC@17FwSFrDXZuP5 zFpn|*qg@vJPT>RI$t-UV3*))VGvbHC65BM6vvD_kRXvQR>CHh?I(*E#n^tPgH9AE_ zWkFX)X=>Z_qTib)<&UcmlZ4jx`xoX4^YIj3cZbN0w~=4_Yk$k`~{ zlCwd!EoUv|b+WBFo2dF4%9~}obJkP!4YC6{TPSam9irHivs3nns-cvx=WdrB$lE5% zm+X*D&)+2*SGZGlqIjfh7KlV4S&9p?{-&i+8K01DmF82sY7~sD<u&=x5doS&QdzTH(+6$U<(FM)Xk;8P#(ua zySH15TgMs>HHg&5CQIfXJ)PQFZ+BavyS*qoC~)rzQ^RA$L3mKmrTO3j;d$|)DftT|;e zlA5aFS(+F|cB&vMd$C|}_BO%D>_dX-*(U_!vrh_UW}gvE zq?n$4PB4M0rDUHKbY-0utjanm_$WRl(20%-97LxC!!wTxPGp=AAQ?vm_tK9FcBdZ~ z#HJ4u98WtPb2xQ+bYMzOX;B4vL$YF5GLdWJ`_~@uZZdJ8yfBJ$Ba7Y zTNGjU85+L9=TvBm_ts#6HxM|=%gZm$^RrjJdxM*k+c77r^9$}_$4$r`UOjCQ+k$?E zb*8WMPR$xZ-KVx?bdENaG~dux)FJ)xvcG%m<;OZk{_1H7Eh=gJH-ARGOmeXHUEUux zUU_BmiriiDi@D?FCvsEe>vALIn{tEXD{=$nt8zW%EB_aJQL&$Vb*`^`O>O{%pL|2E zzkDqTXVzY+bAE-jgo($YRP#q@{YW4xj_;oADJI1w-pHG z_M$NP?q74|U&~SXo9gJ=lhht6tYu&0`L4W{YyA}+amJgyEX+sE1XGMkPQCpfmsVPq zj|=Nw@Ce5zQBfX@`1O8MlD`EnOwSG1XHJaD7GI0T#j|6UW_^#jnMKBY$#M}CXT=KS z6!lr@6sdy7tV}^20W|KY5QY5Q};ygOGctT4Hyj95t{RF&W7xXWB zf~kl|(n#%DeV5FuI;QAVP44Q7T3z3;YN&fi`HJ@TlBgD-Xlr9}{-F8*>7!Z~$&H$m zdG0l7c?ELkyjyZx?oqjx>Sa&vHhE|6T6uTwW_d^M8hKalMv8S*ZJk^})w*)m%lj$! zP<2)Ac8c|KW$sSuzMCj^$~C!L<;L9IRJ=uQ&fP1w{qY=8L;A)GI7fd{H z3y1#o8^#R_6T6sWD!dE{*8@JL%m_`$_!QwKx*HWHeiHpboEigXorp=!dKoh&t2|~( zR#nXWtS*Yim<3tAF^jW0V&-Ob#w?|mtd^Jv%HPBdF{$GA zm_4HUnD?2DG0KdFn2-#43@d$Q%<0sF(O;6|qwWpZ7O^nlNSH_5&X9b;qM$#c7X{3X z+~hYf{H{-AsMd=eJjAm);EDSVKbBjs_Y@bt=W(YV*E0^YoR;&}^Kf=BYd&)|xDJ|6 zj;Dk624bCY2>M>V(PHd9XBgjcU(?uBpe(Ls_X?{2>6Ix_-6v zOYK%kRgEcca?R5`kD8--3i-OcCi&vL68XZsLisF;d3m|=nRycVTq>TM_ftMQuSmXt z%I8!0g1mhBqP${?0{Ifk|Ic!YrPO*}N%@bwa>}Lh)&I*Y3 zNMv%6v`&62Ke{Hju&(AsiAUXu^7i_vviVJ(4X0c4+ctDg>T~Y9p_`@NX`f}3GHUH% zycXJQ_dpgWV7sFt{ISPV;duW!142Vzrj|!u%WxGqig2M;G(2vOI3WIkxG+9fJTjqH z{3@YM%unnV|CXo_?@#OzUrAJn|4i%kyN|cJWj}hj?vt zt9U_Vy?AK&2XRv9Lh-2J7SYqdRMC`xHJJ)ekyfA8{6s#pZgf>ybx`@Q^0B`r|00Y2ESgq0 ztzb<-mvmG?w*)I#C0SS$Dp^&6=arQ957iL z0gCSbIa#61OQrHug_g?kybQ%)iBQogNmB&puTyvw_9>c+pDHhx_4TJ$KT$W=33aPm z_ZWM7a;#C>Zrsh*$Jk3h#SY|tb$aXO=hfxEKX7Ek{)ip1O+w$Kr~xr)38{B8o~5^C zk{LHdZ!&QaB1#c+M8At`G8c$fWv&(%Wvmo;rf(KY(^iY8r*0BIN?s#=I$)i6Ny2(@ zW9$mCgJ7*VC~Ae+JA8#WGGv8#Vc-g}-fxju;j>b_$a|i6uGctmy{Aod%=4INndgg4 zFVFOhr5-71VeU_p54x5oZg>7SPT;ss@QLRc6~rkIJHgx%+y^BGjAJzWJO_?@@(2&N zrRX82C)PqG& zjbkNot>YxY9it?-y2eTV>=`Sm>K!LJ+BaU(M-i-;B*|3#CK*q8ieidn4&^zDX_5t0 zyihSiGM|c{kt7cN&pZbR_+s(S}p(v_u1#&I^2u$nXU1cj=6I~sA5Bk}H1HxBE zJrO#^Js)s$K!0jMiZEkm+Lp|e^k~uQ^ur=ydameETCJ!oRW16Mq7zL|wu#;hu!<@Y ztfFUem}sidD3V5_qM%5VXhE1+^f}lp5(Mf*3O|#`=A#vD_ST9PdKpANJ(Z#ro+?qM zr&<*1*(Y-LtQWC8H;GgpvoZ&HTuTpe4@%wanw+%QxguWgkSd(STNbr}eLCz6awF(C z_|ESb?X%ZrBF}9R`pIdy^(HUSw2alK^M)R){|2Tg`Ixz9hUIMM1$}VaXVu51?%oCU zL7o0J2U?t}y&C3KfHg5?1FKH_vXosc@%}ZjB)=%9L|@SV>rwvCvTA8;<4ZZU zD#^HpD#^~~a><3ZACk$P`I2khIg(MmKP12PNhR%lKdALmD4DJJDOsl|knE-6gNi)K zX~i$eQ7XQmD3Y8|luOQ1@mWQss+CjoRgz2pbFJhGRXeR{l>9}_pHtLH_9(g~ zBNZZPprTXCR`?c-P?!q46^Bd0`^hpdbyjtSc3a&N!F!u%y4QZu zBhM|Ov7Wm`PM%vuxW_h8kH=O~tH%~mlgCC;wZ~>rgU4LaH;=cO(H_$?Snf$_(_EJ) zCpq&HZ##%$C0t?jTUKq@26$ai7(?azlAP-~9Q)-WvBo+KH=SmG*EK@P>IB+z#Y)Vt z=c(mRN2flpHC+9*acke&y3Wp7^6jn9szx{Ns8~>2TUJ!vTza?SXlZe2N9o=YRoTU& z8x9$!Hn;pC{nb7}y0~kIbbU{jw6`}?`nfMdnxIILu2f`6 z&nuFpcNE#u{}h?hH`MF?Rxwcek*a^Cc&`{H{izU3-zi2&a}j9z5S6DgES*$ zi}WMvMP{$oT>FP^9qFsS1bLbN<=i6_PV12@&jpUN{GGgAbj$1Im zFX2>5Ktfa6w)l}5rjfDzf-SF;Ja&=oob!*f1N~iio71!nF@?BLa z72nD|DwmdCt6E#~NY+=BSo@~XqoJ_CzuBq4zwJoAq9ZDQVz*W*=q;75?)xcqQ@oRI zQM{2pR6L_z^EXnN;<>a@@j}|BcrEQz{3q>Fyp{GUUQxW0_E0Dl@1+Wg9>qtgO7Vq? zze?4LT&Yn}EHx=gq=Z5yr70VwY-Nkors$^nYm&}XB<36Y9_K&kTTyVS?@VD=pKI|e zMc6Nw{*p3xb$HbeZCs6`5o$!NXWI^AZ9SK0WoipN-F%ljidgP^0Cw^$=I`{YavvGI z%zs*VP}rcT@@R9kUtC1Yp~S7x>B-?yQ&Z1HG^D)=`eoY$v}VV>_YPI7WYFL z8{D^LtaRU!vDAH4#(ejc8Pnb8WXyEW$Ov`clD^(8EX~z5IVINl%Yau7Me#-4!NR?) z%qSz2A3A^z1db)l-qY>HZd1*>9jEIDaF(dMpk0c`z^m>x>t9! zcU8^8&H~wn)}Pf)jZ>;`*4?arEZ-svuC~aVE0ndI^5qS?N+X(w{|akMDSSq&ix- zTy?5&gz9XervFXh(SA*#WB(Xf0QmNQ0squrV9l~!ii37Hzj z3E3<77Bnd?GO#3JqkrFk_r4dB**>3BwtCG=b@P0e+UDMqYIGx0)7+S8<*w|s8iV@^{C5W9}Z zYYdl{G%u>&-PTw+tMf>Of6t8aM}5DQeNz5WI!1NxSEQQr>#6!kiAtSV;;GRV$7?Ez z2Ws+)M{7P7PttrYo~ij#JXe!byiAizQChrFQ&hZ8Q(wGWQ&YT4(_VZ;(^Y(2(_ef_ zqbt6sF&AIf5XHAN^pZOoR>?yRujHA=rR288t7M)gw1iOqUb0_(y#!JR{CcF4|JtHz zDZQymFLzdJDgcdN^&IUZd6NEX-JeEr(-h12wo~?ou1KO+;Y?qsje*7H`RrNP5&k9m zKIa;yn|mSO&uhNxJfA^cFMKEYwfLS7^zywPqW4}Oe$6W;O6Zvv)8HN#d);kv{8?Au z#3wG>2Jl?QCY^K6Nm}4+PfBnONDg+6NOp3LO=daABoj^%$(U1Uvfjx%S?A=Q+~>qj z?r>rzw>e=+wN4faRZ^)_Z_+QPrlfqQx}+aYw~|gdl@IvtxFB(g!_4@Jyzjzy?Ej*l zA%i2b!Sf+!fky$)u-85xt;aoH8V9(1)V}1G^|RT|ebb;vU3Y-X?HCHS?zgC$A`KfF zJv93o1}eo3pLz~8?C)IJc(tv*iQe+PIYRX zH1{euYd=+VXz}tO-PH0?x`whDx*cV!btz>VbuMMQbwufYovrkk4lO-RaZU%8UDiQm zf9ssfZd3F3bpd7n>O#t%>tf5^=@Kb2%f9P|mi^F;C@a+cURJD|URJJKP*$m1RQ6c6 zsce$&Vp*d$uWYO~xI9mDyL^mhb_H8AsS;CPs2ZY)m33$WYkIVM>L%z1HHI43w#+p% zI}BEbo-TB|(vuvi-9?{mg5l@(eJnSigL?=99pAE_I$v}sa&32Uao_B5zQ?6) z;`UoWl zFNeN(#NlIH3r{C><{poE$9fW31fX#eG&`^F*s2_i9xGR5JB+e5> z6TJKwHIFOQ@qP)rc$!Z^^`?poE_iW)9Uo<^5PHiNNz76pvvTn2quU%mBt6gGR zP_xDKRleCYSiaBHBHM4eDLZOfCp%-BCp&HWU3SSdU3T3xm13^!zG*(iO4(D>3fXhh zcG+vwR@r;gVc9p+G1*tsSy`d!g6xOsHsvSOeG6o1CWY*-F-UGTERn|>O6BYHztw!y z5jEbr`r6l8ecdYUsD^D?W#b2JW%F;kfVNouqmEgI+uaSuioOTtMXHz9NF8pEHLb;` z*g)VUev2-lB|#<7MdUi`IZMHv$@%86o?GlB=WcS5a6z}L+>`Fhxhb9_xJs`?Zjnzk z_k*7=_f>#5_eYQu_g#o1_wO)-J1YX_$|6Y)7)@}Bqivkn7%gX6jFGcHriXJnrk|pP zb1|l!b3CS&b0S90*&8F{?2akqY>p}CtdIH5SrQ}Vh-1!k_C&X_g;9U9vLfyxd7+U| zbxbfxL)e}%$>@a(Dc61^mjcw$XnfV%(HvAJ+k|U z?f1~E2;;OEq_l&`<$HBC+%h6obamhTgz1>{j%D3!n z39}4o&a`+oi7ft&<1DcaV=bHNr&x;XW?078&9OAs&bQpHU2a)kyTmfRc7tV9?Rv|I z+Rc_RwcDw9uVq^80n6{TM=f(}k69Mgp0%u~J#Sf4d&#o3_L}8j?M=&HwfikEY7;E- z+WTf&oyjz~&c}4NF4btL8)evCzeMlXa7(9cP-;z$TeUIG!P-YHe%b|XqqS=~O0}Q6 zPU`0OKGqLW(u^C_&rP+u3zp5MPd0&#g`wDH;wPX57J?HP1;{C=l)VBO$7^TCJG^4; zas=3Koub%P&Y5hk>uB~Iw-IcK`&jl&&rxjBYY02fX9WAIpNPFGK+GN%l)?r=lGryx za9nH8kb{ zl?*IZs%iHWgGh6q3Ty0ZvS%wewjkwL%bNaMCMUJlpwo=j>vjKXI}C1`m!_R6zNJQK zv!p8)Q=hs$wSqlW)-7Ec;&258if>y3Ay2aU+)a+tg-{fce(dcbUYYej$ zH3ZxCGze@%8)9rx4T(0dh9sLyL%PkUA=Bp6Fvu3%FxckbFxD2{Fw7=wm|#n7m}wi; zu+TQYVVZ4k1J8E1;heRiq1FO7qUKSJX4CD)P9vkK&~U8jn?9`htxnNgua&oWYR#=@ zG-KOSHH{s?npa&DG(URsHGYZ<+PD2Tb!RkO!!`X&W3B0-In7pXy@`dQT;L);nPDf_ z!Bgl0)*^5p#}5|qMk90h9mrS*F*C^V4<_b#kg0Y$#WXvgWd^xkU@mn#$1Hb0&7A0Y zlBxDO%DmunkU8A%AXDqVlX)U=Cld+Yz?>Sgg}E?v1v5Bo4fAB!LS|mr5@t)-JZ68` zET%SW2GbBWm8lGy%v6Ow3`G!D$Uz7XJj>YZA5S~ubBdVdS%}iy z5Zf`Q*=BdX$?%CS*X>6_wR^xe^=q1^I*F`Mp%`85iau5Eu)WhnTHSR4mN$B5^FpJm z$<<66E?PSEdDg#m`)xzD&9+SVTEA3Ls-z*)!&Y;1r#YkLlj(BH2BWPd#jvdv)j70P zY9(z|nw#yt>iZpHb#3QQRd)ArRdde;)t5evs#JMZ9jd;pd7@Qnml%%gC!2Q}$Jy?g z*JGeG|qX5o9i!RhFc!;-Ms*b^vpxvc}b8YpByCL_dAm8pM(4z@C_*q{DPDPeM621 ze?+vw?-4=BM`U=&TVzVe8)O>gnIX?9zdRI63RYn3P45}lfdPMyEL6Xp6u1f;X@5GP_02>(;8n`oy>)n zF%~z=2J1cZ8e4?f%YNCk*Ir|MW$!dp*mL#G_T9REyN6a~zo$0ZLsVw_eWk@NP+<1F zUWD|}+$Mi(?pY27JWS?XIKgu2bdsWG*Gn$d=0^LK6*f?KT zYMyI2Y`bEbfWcOG@}#|y7KpC~FOn5-6Rn;pVQgj(hAwat;5hCb_#3w$j^weB>%1Vu zgCC7N;>RMx90nkeV=Pkdn1tjz#UYK(aR}xTk7T+LAAcWAd}3LMgVy)xY3poz zwoPQS*w$FD*^4X==qk%lG~TiRb+W8Q8_YY=Rpz~DvFQ-1Hy%dY4M))b^e51{y5p!- za}xbieG2tgok3qJ&!P(zXHoaQ3#hK=JlfuU5!G~EMI*Z|qH8;^qTL%f`nCNtTGsvz)wCZ%y*qr+(H(Q_`#W~oK6XsCq8))2apxD)q0V{6 zn$B*$kUFoO?~2jF-3ImX?ow5FPg8$mk5m8i-b2cN`;wG7if|>rf2nf6O0Nvol=hpn zG__X0RpV_MrdwbcY^byyGmXSrEY-wJ`#9PM>@~xM?1bWIHeWS@T; zV)k=KP~S)JUY{oDv{xZG)Z+-_k!u*e)hQRS^4F4l?oc9yH6GspU&Q(uUf5Y$Bf5>O zMIYff>Vc(Ta{GF$%yt3e+m2v+t+TK&YYJwzgkp^rZ>-GXg5_J>u)i&QY$)ZIW+$xA zkG#2_6A@@J%JdfCm37N z9fB#lLa;x(qOcKNF<5NZ5G;_&2X!@~v${s0m%5JGrCs}MobH9z;oXjwi{0-{wcTTl z(LJsDEj_z+l|A9w#9pQPR&S}wudk;6aUZ{bqGG#}qYP0hlr&{ezfcLQuPY~LCiQ>S zPEbwJUsHP+1GQF@Qb$^v4B>XOX$BTYg+)LKBaggJTTA{! z3P~MK68o^P#5i;rvDn^=Kelbc<85xZ%vy=PwZ6wLTmQk%TCZY9tXHsO)^pe%>qTs# z^#bNhaolnVD>GljdQ6wG8sk;$vEefIhyFSis=JQWYOZ5f)iv!t6C?E7+SB_I1R640|D-CK|ze01V zpQqcP8lyj={?8!SWSGY5n$2eYL+dN!5&K2+F6@AHFR{zM57>n5q0c8~fC7LA|Dqj4 z5*g2#1HqLn1=!3Q2t~5jLd)2HLKoQApnUdq2xUKj;yAaVO`L~N4(AT!#=Qp};@*Mu z+<%}Wyql0K{|;2fzYZO9xDCy7yao++dI+UBKY|imzC&WyYDny6goe0Bz^NWfVPDS= zaHD55ve)YcQtvg2`N8WyCgN4kRC&B*PIaHfT<kH zyl|P?4bM}#WeN~{Xy@n`DO6aGEBeeCYx{SODvAYv9@a_+%C2}!VK2U#7lb`)jxa1){L+$3lUZxGbO8w*|LFNA(~*a~?&-h?cUg;2E<0{?KH2>^V5gehW9*PT;+^{dl)+7v5#t zgSXkXQ2B1WnOdhR+X1|Z@-ND}ZQF4Ns{V)dAb!)b1OLx_6u)oUiJvnb!`B%0;uG{o z@f6)5JW0C+AEU{_52_2W29+N+M>QCwt3>v~es9~`{tnB#{)guF{$(adRibf@if4GP zvgzz9OglyGuYIhZtHISd>KU4$>i;xmm4`N8wMSc^GHVs8UAinaU;kYFQ9o9*-GFPx z7%Q~{O+R%b%~Jgui`MYO8f`-CN6o8HjYWs8w{0Ozb~bPr`-jFM0vJcgYhV}90Qu7i z*q2d(v@>Qg$AIscM?nSi9vH%U3l69Hxr+4zJj*HqUsG;k6@xHa0;aOd!S(D4@CmyO zw6goa(HtE7m&2#lW;}F(I|lOL?SbC$UP6=kR*3H~9?o_62w!nbL#8`bBPq^@m^SAb ztX!8&c91K|j&t3`dFLYGlse~eRy$qfymE-(eC1tdKjO5oj<9&FB}fo+9>ha7GWwwR zv~yqxFpN<^fb@H~8F-Dc024ZyT#iZzI=YCE*u#jsR39(eHTWUB0zYbR!w=XyC|W35 zsoMX$13yB=NB`$;d?{6nvG?I`Y~6Se#aycrKVa#?PnlKt0aF*g$M_B3W0;4Z)fZzQ zbTkatI-!fSgsn$YV?C$2Z<(dpW*(#&XBweNGcMM|8Lm=Sp>oX@U6i&^yG5I%E!9dj z{<=+?jk+P4U%Dhskbaovgnpw&sn63aHbiK<4Y##hjfpyM(=T0x>7@R)d7|NeVS(RWSy9eCN zc7Q&!lOZ?GDri0D5w$ig&{XaexRIL!ujY+K5PlExntzo!*I^yY%W)Dr$8i!T!O4d^ z!s#8C?Zo9RaSZ0IbTDuO`RBNYxH`^9b~vYm8OBz?0E-XZL4IQh;SaR8;2>ZggG0v9 z&3FLKA0Gp(!7hQekP`(yNCpI2@!>kCOpwmgf}{fa6_{Q4|Fhvh>8bOH8I8i zdl2DA*$*8?_)sxnA5Q$V43~)Gfb_zVa77u5<`yezP?ij>KXcdx?%cI-9CM-wnqO!>uq?b-C%g9 z{b8urIvd?|tBi|udB#_|c$2UGs_B5<%M2RsnNJzSmPn()Qe%8#y>2>cTVq~hpKe)> zPO)yo7TM0@`|V$d`)D^Q$9!pYVhlZwT*nv%8~`WMwm<{uqhJla9bU^Ag?wZjN7@*9 zh=rj>96=wZ4=85FflH}#siSs%bumJFQBVnC-@Lg+hd4P&fv^PZgA{~8}}LWEO#5ri#MD7j5m>!&Y!?N&JW<-=6~cZ<~#6v zd0zZLo|5OwUCirZzvJ#^z2@kV1MCT~3+n}V0`X^X;TN=9;9OujLriAS#}I>QJMgVQ zD^^D?!{(7Zj72t~GU6Nhns|mjCLW>JiCYx+(JPeyBJQG>h`8lClXjTYSrqgj_@toGB413Mj4VC78L%LI!&jGOQZMgx3@;fdrkMj%~`)d&Dy zL%hImNHW-tj05@1HDDO?7&wLb6kNru0538b&}(KQRKwf|q0CQE1j`Yg$l3xQWhvmF zto4YU#bJ(Re`Q`~?`E0V)7aBF+0-|XQn)ePINlU)FK-5SGv9&xoPUk;nBU3%jn84f z=Ygy|ZaZ?F^BRs~{{cN`hJbNMCH)6i^VkHqqA)tt+j*G!0 zL>#t(s&(RQOn_ITL$H15C^QgFv){1?*n;gY)^j$Fg>MTn@3oFL@vVOuFI!+^w&j9B zV;*k!X7)B*qSn$ev#a5-InnT!d8y&G`GKLqtT8xP(u|`ldyGdc1;$c~gUQ)C%{0gQ z$n?T$HnD7z%`0s0%(b>)%Ov{^ON~9sx*mONb-)(eq!`zJ7?;_{Q@?r9 zT!EYfk0JkppO8AR3}HevW;W!`+y{x7MbKR$lk zJCMuRLHh%Ypm%}a=rf@Kj9bttMm3bnV8B*JFzgLZf=7XC;YHxz@C7gzeg!JwF3=Tm zgEEnE&|KssbR21f?jiAT333kZL6``Wc>oDxdN7Ak-}zg@T*Nxg^k@Ia>}J<6KXTZt z)7*5{65b@1J73H?&PP~z{Au7k z-~8IX+kDwxYCdZZvK+Usv0Su2wftkZS@P^cYrB1w)g66g9f`JDkDy_;Jam!G5qoQ! zjbXMg*dn_({>6R@PevKkyZtdD9&;f-V^7IB_y_LuENun#Dg*&#^fq7-;{>gb zF@U}lETHFuLl_RweZ~l=hp`g!0?$C>z_-vUumZXXl28s92qNnkxXe0g< zO(tmAMPe03C!4Sh<{{ zgNWCF7GDbV;Hf|Z?gGeglB~up6gu)3^^9vM%J6d=qtLamJ>^-&#QewfGa0EW?RX^A2K_`8g40))J7}gQS^9lRoCD zpsrrd zQfuoBuCyP*eb9^eF!V0I0sVpBMtksb)SZB_al}CEIB^`SB(mc3gZg>6eEDq#5lzWqPD=Jz=7aqa0hq@d?t)H^N>V0)ESJMq;^9$Rln5(#y5LIQKnV!JPmvcU=K#2XEn)0nk@Pdn zRQh#fJ?$a<8TbM@12y0_5&`YRP{ujpCVdFC`(hF&Y2COVjp_$bfu9E2@i~A79}K`m zJheNE1pJ9GAe;!G2nM1FA3#X3DOZq*#BNeR0F;*#al{)uf#}B)2`?;($VL;0<@OZf z8ugktSVs{F)&;~P%Pu0#@{mxN>xlPeNAf<^tLNtHWTm-_UP2W_A+=Mspf3qu>;*9z zyGty^o)PD> zw5hZVdOPh3eIZ>zZ=;JDQyBXgpBY~m-e5Q550C{u0{y`zFcx%xhEctn4sM3lfG?mk zU?21d%z#V5{jdgXhrOsXp&0rX`2+G~UVzR~yHH0~2X#fkh27Y3@G`haGpcMI7!ee_AQXlHZvx$MllXBkI`QtRWupwO=G|-fq3W_ zxe^>m{>R8CxQr#lM!G9ur1j#5XrJ*I+DE(_c#l5@3h~207rqieh?!KMrUAo=iNHc) zG_aBo16v6m#Sd~1F_q#Mv4@Bu4iP)>J;Z112%$p{P*;tIh_&`3#3$P!!r69-IBLB{ zI9T5kZ>Z1ww_5Df8cZN3SeBA=EdP?nEhh4(WeDJ4y#&m+HUJ;2-ZU?pn6}ZjkXCD3 zNsG6ypq;nRqjlM{X<{^hb`sSAm8cYO$BqNPVGDs{)E?v&Mv~2#oCNXrWF-DKIT}At zZpDw2cPUrnw@C-$6FHG+BX1B8&__Lk(d0VdAMz#O3>bjzKqgHO9Hh;omC_n${`BGW zCG_v~m-JAEiGGF=$LL`!W()?;Fph!G8I|Bq1`VoYWJ8UN6_A$k5VA2^AU80C+L5k- zM}VK;<)Axq2waam1M87$Fq>%sUoj)00M-cTENdHtv93dN*f~%xy9Ih7)J*Q zINu>Pdlz(t9RP)~AAr|b!63jo!kEJBqW_JE=$-HxS}?2xmO*2Hm*5)`1XIZ+j2xnp zzKEDW_ai!K?f3zj1W%*A#Erl^Y7OS#{{U_H1pvqQQT^Ksj3fR4HW34XlLSfrOWY*i z6T#$n;u29n7;q^u94{d*VkJZiT1F(ICBzYXC1J3Y5c6#^LS=0tPFfX&*vcT?tihzo zGJ+&5J4v4PC7Ee8k(;cUz&qPV-I~f z<30U5qnqvodNbyNnT&_vTt+vzo)Hf1Wz2w%GA=+D7=_SP1_D24jDbHe&caoUcDS37 zjQn3qX8|77@wM?IcXtyAfe_qX3KW-M!GaViEiOSru;T6%NzeueP+W>T6e;ddtU(Kb z5-b#Nfuh;nd*^$}_kVa!&RpGl=Qr<}nKRq1+nVJmV!iUzvl`>S_1YZpla(g$pcNJP zz&a4nrsyDnd|8TJx=-*I|n@26mA z0hM%yQfsFi_}w)toPlP)^UAs9MB?u$+w0`81I=X2_HXzynkK&VW`{SEsp<_ir&2;q zmy}#4OG;jI^K(VB|8sq_=5sHzKS$GWB=S$p^bIAhkEx+?Y z!Iw+4sI=DaWVKF~=ekA8Ti0cX^-d028TGwYOe?u6Kzp@xi>r>_aW&I|?(ej%yNhnd zO#h{Og4XcN*BPEo`p9!ZOX4>@CI_Uo&Ic5;LIPV^jRS{RBLWv$a|5?n^N?*D7r4`E z9k>G7)gjh3Wa%aayw=PC%aFM%tpz+MWP!Vm1iH`j2v<#hY@MU_Rs>d#ZkQH2z}&*P zbAX(5LS>wDgqt}NxF~WknVhWb!H6u#xk}lc-_5cj-D>r ziMJgmz|Lld_)D1QzA)1ls~2y)^|7Yi%9QptG07?I%!ZVfW>iWK6PYsDv`Lw2+NEqX z15+-Tc`2XGk(5&OKBXs>@@}Oe-VbyT@zL#z!>Bh zCUrR}KMq>=TrOtJRL z3G0%4wjN5D>mBCKUfJMs=`)vGbGy@P4|h6U>dvW8+y%9Wr@RjG)X`m@_WH>)K+6Qg zX+P*`VZcS*AMm$c2=M8#0JpU#AiWhAz*did|Fn3(S@2%2Gd*qfYfrEqbsv%z?lyAW z^?}>CW^t00kK0+l(GzV-{q#S~`QpuTX=G}P8XsEh7GB|u=iyE*?g4%+okVKo#8Z33 z%V;MVecTu`6JwMu&J5?MLr#)2-hSthoxx1-7c)Wr>Sl$nrK#uZVV-#ho2}j-O&{+> z6YiaD@_XZq+q=R9dN;zKHu=1Xro30FgZC?n^+wVj??U?Iy-6i}*?6q42OsinCrWpEI_X$XeXZ{)q&~MJ zd)&vt?I-cMYRDYddoJQy$H%Ou+}N_gZY7P?)|5?!j>>Vv~=-psWd3T#V-XmtWH^J=n-Z5vqZ_RaYdivlkMIpX6RKpib{e6dM zmCs9$e3dzue~4kG%Calj`S16smd)Zym5 z?lEW7Z?Vo7j^5;b`hxGMk6l(qDQy*zwpLY{4vxF6PV(I9Em>WorI~AzjC0MB z-(2zX!u7M{aW9hZv2r-oy-fCE_2LoC?b#_MJikf}#KCVpXQinpK_Wbf5(dlTxgq4a zBDdYgWRrWN^mosZa_(-D?5ZxyTyCl5O5o?#Jf3AW=W=GugUBR63 z*EXa4ElnkV2lLrC-2CAiXIA;*%}n1a^Mh}v>FGOaTKg`U4!+yq`o={0j2Y<5Nin|i zv<&Qy`o>VQZ!=}|CsG}MW*+Tt%=`Sa`J?|5SG0p=to@xFwd2Kdu1XUpMCW6sljsc9 zl4cn)4!`MPb6tu4)Mk{VKhb4Pq!XH**J~?|(RirnB3D)iJy~hFFP&tY#7Hd0B^~67 zgvkfVh4G1>OY1AHr+;y@Ugy!8zzg*X@6sEbpbzykBt+Mim z6(%WGJt^R7CT(3UWxT7s>~?jP+pqw4G&0^jq&0j$ca+RPd9k~vtVDS&{6crv)O|zU zZ6(s(LaMqWB%`~$JjIIRc9-E{u18$nb%i!|r*1wR(`cKnZ{|CC^FU&5xGl$y?c$j^S_u1*?gWW``IMZc0E+FZUxcC3eHmQiX+tiI)y==Zkj1H{dnSku18|AK2;>oMoE{^bbkJ$JPX zPqAFG$qJDK@O*FOmE5j^&`DA0;rd!;xJt<;R~b2rauUj~VLn#@VRvD%UD@QLD^#Al z0_B#A*>#jFx>mEg;`oZy3+u7XxwTcCGh1%FRWi-eBh*Y6QJ@Z@ zGtz=4N;xVgnduSx%uN2F(<^0ON#HE~I>EqOpUCt=^ z=xmp|=AO(l8TGCS)1uT>htfDbPD?c%Z`P)KP#5xkDCm#|$yTi|YjmVc0k^@LAWihG zl+_URXbH>%>gf?_qbns^hszjb$0lkunXma|iKds0`U!FKCHN)tpPI0Azf4KCsE-^04OQaIZ6iTi_757!fpa{a|E zUDvpQ>lj$=;@qxP;5CgOStIy_)t(nv4SAqd6l)3Tp|`hmLvPR`-A_@vl#1&ZdL+GR zn>3{Fr7~rdd~|>_P-j+3%Wutk`o}b-hvt=eXcn0JrnF+d0w^BEqOT}~~eUcuuQ<~5)sZNFEE4s_MX)0%; zO6;b)_}#-Pi(PbglH%OVUkWODj#UjkLH{2D^Ovy{6GfeI>p1Pq5nyhKpq? zewX4$?Su?xLz$(eKtHQ2R>hp}HE)3icj+}~@ejVF$2m!l@Jl_!j_!p%_HzMi7ngvq zVeRH`tUZW#dk|lDaCca5YXkSPHo-6EPO!FM*36o~HLZbM)@sYSFqRCkO7d$(rc!O% zqfasNx=2I7tpVa>ZXJP^+KYCB+aRe)74i1ZIWPUfq12kwkf8uNj9;+q2!46+E0$+W z8k&a4S=VHxK$C^8A=A0eDFJ?!DH3^$aO5wFA&-&WX-R32Nwb_t%jc+&ZX&@|q;v4@htZ4MdJ48K1b2zI}NU7SfzZA?xoYzmOyDFuGj=!jFF z7C0?vuG5x=IDL?H=}$c{qv-04gH6U-XAE_8W@1JkhZ*7w_@Ai@d^cwa%Cq4YV%9h} zb$=g}dm#%j#951s>2`{7j#0dGnYQB_i)S5tiO|WyA*Kq~F|Bxr8O7VpN`7um@mKVe z`%tj#ps(dEwUqKaK>G7s*~#lAnU6|NxgiZOwj3^RWT||TqvDlB5o9bK3Di%L1Es>~ z^D5{gjAAZGO+6_MbdyBrGHI?qN+TU2-)n1Wtc{`8ufR7CaxNa}h!`3P{q;or?1TAW ze?81&FgF~n8+nE<0o$K>uFm778q14yHZRxl{EJS;sA&YoKqGmH_QN=~59T3}JVo2_ zByGe$XieO&EPtpK z3yVV@aVZ^gR)FtXI^b-fqs}Jm--GSlbllko{~Mja_6g@u>h>w;Ae~9IV|3LyjeB09 zm(ERk?>wOp^O?$;0B&LmL2p%gt!d5o%?J)gzT{ivO{UNd{+&Lsa)?yp@-l`S%69H0 z4|t?xmAO()R!c9zJY5dSW;u@0W0Lpd2ctR5054k4s@38m5=IqW;b`br;vtZCqPd@HaZ28z6Fj z3to-&M{cgexrq+O_5f^0a|EFUn#Df#;7DY~o;xV86h&!}ehR5%`nv=fL3tg_?v^ zOK)yaHjHLN%%AW#D6_eRd)=g5$Ul}a52&R1n;Mw6)XMm22-y8(a`0YLitm{^h?VWR zDh=j-^b@b94SbhQb1>h-FA;y@QJf9z3Q8hJNPskxQqoge%0L+;69pp?StD_BSmw(a zStxg4_hbR)3-h7O>9CpdSw_iw86iH2hElu0e+RXO!&iY7faMUsu-M{9JwIWC`MqKW zsp$7y`YWf=HEcn9=@26WbP{YLr$ubE^aplpPh8W5ZE4FNr6s?XZ}_>?<0J_~exN*` zlETO$d(h%2EU>eoSXM@6HegK{D9Z6myutWkH|7- zLms7yRF!tpRQiI$REd;%(pfg7s<9{37%c|{nP{xw{VrXh#tu+r3%MZ81#@30GaPgH zGT1IE36dMff?yu(d&d{#C0~&wzAP8{lAJ^R@8&;b8}gzn;1}>Una<~sD@~B$d{zd+ zqWPFa@&T~>O`7pGuv;TF!Kw<+K-Mk>J$8S|&5;ty-#~k1#Y@@bUrOO*`irm7engms zyp#IzCTh&{DL)wcXe8aBKD3!S(+p(WyMto`s!c_x3Z>l>NqxI$~ z{3qPwBlvv6woMz1m$n&0yTR*}aq~Ij;s+*}|23hUmhzxyF2J>@0$N)*Pot)2g1o*Ch(tlsl4Kq@`RT`cgrLJb{gCJcnNyj zW%3LB5}q%!;A41>j72Xz5PW{%Sd6A7NCzGZb_1m`)-P&tC#lNcfn7bYL-v&ONk&c& ze(#z1KHlyG|3jPj0Zqo+_5;6qe1b~h?UgrRH7lOZ&|KO`<7pZVr+x$-Q53Y-nTk_8 zte-STPuLo>hGz8Id`HhsE3j-w4@_seWqQ&bGlUY&aICe=q`%B8=yWyR#SHN}vT8}@ z1dd(Ad5LsCbv@=8uKfqw@8}-l;e9Z>YXlhq<%cGaUmFj<0WYHT7&!%Vc0`4el!>cR zA#P8Fxj&wI7S+I$*W!!Rir-KNPRE0=rZa|HfZtGF!Si`L@8Y9;h5z6eSXpKH8|ww1 zxP+u&l{`QiLOZRI(~OktP+bV3Y91LNnP6FEF#J&L>xbjRz-jK8e=ohbG1xVb z)?6L@%1H#Ct0p3S1@J1vJ}$)nVzuKIXX4X%vu)_f7qFMc@_XvWkEtQwqhfp&HF5zf z$VV}@+(##&y7jaY6c^EGaO?w$t!NT8rm={m!x2e`B8m>6La>Z95NntND3}IAmm?8d zM}zHDlxM&eP!KJK-vrx@a}L9wM=zQHOM*SZ`Tt`7f4ENyg%V>{>Edh@gb`C(%vLgS z8E`8LW_2kWH=|tKiSqIgXl@D><)u`b_dt7pfZq#hgqHao-ZYY{a9?i4BX}@R<>?&H zYk4If#+t!p=LdcBgk*=IYI&!cy$9hIHMEKhLl56rqu7LH#ufePkZ{j?>9BYh|IX&8= zi`(H%8}SD!f!3N6t69Pi(a+t$iX>Lc=`8J{BeVh>e?py)r*$+4)*Bq!W5u#9%>&1H z#L_rwL^G*6W)k&i7REGj&}SUB;}Kn#pu7}*6NTg2%5)Hs_cuh|^Hhs2;+)%51N>^y zGnC&_9r}o}L-oO~5vAeAVAh60xg(fGQw|;sX5$bmXF+c(s0bo`Q9cE3H^A>-^m`7~ z#@p5BuRtvV|G$LRSV!&019%dT=bt&2*Yi9+#;f>u-iX+Z18gUkejgUsOtpy%bXYMv$?=3ubkx^au9Y1@pv~l{L0z! z-(qE!&CvHU&M3=q?|8783!8#A6T<=M^9Pg$7&GpoSwqjhm7UP?p;Jk^tz(<2u6xu*Eu8*Qq z@Mqz#;JjNX|AlLxz`sCbeh;65`zmzh=1~;P6DcEl;OsmP{Fb3N-Uz+zL%ckLSa}1{ zBALqaJF1A5Sb;-1oQtE)R>ZqEMjf;T!#>;{W6fxu!Nb9C6mLK+{EAq50$Ufs@g_Jv zKtz3vz5k)M-tZCB=MhdpYd1K{;gg85r%*l&#;37;2-^oRf<1`seK>Cy&fksgEhujR zhqe3x_8vNai=OrkKIb1q?SFX|KgUx%<%yikQ_yyXA$pI*=l4V`=+9@d0(_D?;!bUF z$ELWtF)zXYu_K17^N(B^?@@}QU@Z_;YQZXTW-bDTnK&&Xsf#}op%+Y{WYpnx=pX@l zIEs2bi0=jLfIc=ukxS_&twz1a)3yKcyi5zhb}D$pgYQ&20mc^)VNbv=K#?aY1{#}= zV>9Ry_Faa*3V$1VzKvYlLn!!fT=$aZBVx~n{fr3kGh*ioXm10Bpf5|$2cfxRhz<#0 zcN=GHgS0L0q1*;cbdBW^~|J8}Hl<@7@7*(2H9lZbm|RU3fNB7zZ7$K?`1w zI@|><9)uQ;Bc`55ZDEAL*TC`)j@|}``>+S-VeY{v!zb}(Fy4$h--LZ@aeN)lU4!iv zoQUgh^HPk87NWce+L?p$JoK?Sy?5vbM%x0={f1#eOorP3V6g%MlwLxs6P5Z`LxjEJD=@m(o5zl1$N z?D~srF#G@lA2D`$3&s2cj<2A+r?eNg8m*@fW`7Y)bSpC+vpgM9sPP@Y)LXY{L_5KyS4c6&40Q@q1BuyDLdUCdW2;VmnGU|BAR_s)yA&I}C(pyWX;O`*()o*B`9q(k4I4l&8X zNG6c~B0v2JJ=}mUuOYf7Kpz)TP5|4pC|`nB&wv4P8rc4akUd8E6?lK~Z{S~J{}=vm zp};qE9Oqp^j6MxsU)shw_)GYVE4cS{w3%D@%p}ClN8t7n&+!`11u}To4d?=nd z50^x#DB^wvw8}4SvI>Y*!5fF8jn+T}YQWvl^Yugzm60<4zcev80p5qN#k{5+Ir;b~%^s8~GNc=UDS5Z8x-+aTz!FGxi}d!6`u z{QV9D8-ZQ}yio(ZQ5aNL7gieWH4HUS0{wd_&VV`yh877m;=$hclns4~3nAaLkQs zZ74JV_i~`v0E~E*pWriIrD{J2pBsdBl%54~UGbC|5E(OaPR@nrD+()uc2^01tKeN~ z!5W}deglrJ5IbAIA`v?~!Mfx9dxK##zDqO^90#Vh?UvveiJFZ>jduf;?x@c`P)uJa zXCQ146g3!iJp%PU6e=4Hw!@*5k=XyGJPI}x$45hP!?14@+Q3khhl0s)o|`(t9gO=8 z0_pxBIslx0z~}YB(VnnA*wYnzdf?f*;BP1V>wu@}2x={0t?{JI@buq;);AzkA8%F< zZ&?%ZvNqnoB1nZnZD0C}uTd|h5jBf(AnGFk9F+^eaw9(F2gmG~73PF4v!Y+jhI$Rf z2sJCl3F%>3QvDn7#Yi8PHkJ8%=;a@;jp?OQx}99ppF{D8lmP|px!Va#+m&=dj#rjC~OqYnt-|-g|nuhjwis!;LItA hU{m2^z;+61I|f%y#=a@oHxc_L!;i)OAEBvH{C}}CM;8D9 literal 0 HcmV?d00001 diff --git a/assets/sfx_toggle_off.wav b/assets/sfx_toggle_off.wav new file mode 100644 index 0000000000000000000000000000000000000000..bab33853f83ab2a14e424fc1e7123f6286bcb376 GIT binary patch literal 34148 zcmYhi1z1~4_dN{3B}9ne5I5Xi3Z<^Mb}P5;?(XjH?tW{urIZ$rB0-ZNfw+4h5bQhj z{@&;RJ@c$td#}A`&di>ZL9WxzAIp#WM0Byw2_~WHJraI;UEyFSGkDmqPLd)-~#n_utjC z{x3SRnp|Mq$P6QMjsoz%3Xjxeq?)-vKT`XVRgdKVx1*8k{a23>Yh>JiHTeJUcVxzq zGspw_|IR5D*w4s$jnr`jBXv#%DmB6*%E*ZSYW3fYxxna=I*tbP|F_%!&T-@nMyfw@ zjggTf{>WNJ)-|%y{68!I-+htxf4L)d`QNoh#*I{Kq}HPWI|Z;u?tqc~j_h+}){*<< zzncA5gOOd1+)e+jcI3Vr4S4^n^Zz@Ck(oz1PI8>!xE5#+93MJ5gB(D+Kzl$bPDxIK zP6JNE&cn__E(0zYH;h}Fdz$+!kC`6pJXd>e_S)*T)_b-0U*PHB7@s(wULUj1d&noq zSZE%!3|awohq=JeumD&mQ~=F_j)LYvav+u9DsZt^kyn66poh?<&BYJo2WlQ{9-P%T zqwlA+*qU$5HBz-y?H%P^Wufe=?1JQyBvc$ImUKzFK6b1<=bd2lR*1oO% zP1~zBeygC>r`4-9OOP$t#^20;!F$bH&RfKz@FI999)t(tx$_)&eJ!?@0igA?SX+8q z>_Bg8=?AQCpzi~ETZ;p)AK<<}Jd%^eOXit*Hr{l>B*DD41#Jn!I3Y*G7Ny8j&u_q^+Q>1FThl{7rzr1W-r(WdK$I(UpI)X3%EQ z+-Xjfnj2FSUJ`O?|~o0+wp7yo3NI+hS&f!Pm&vHfH*|_MJyuXiA3TULM~wdH-yW_ z=3*gXkg&l9Ut-T^L7AjF3_g&rttE3qj~wfQM@bwBb>?00XQ4* zMmgnja1Mrv=gi z0rmwHe;OLF5CBGaq`_%0pdV3uX*#Nfx`VondYl1pAjzDbl5>G(WCKeiIL9J3#b z4SR!`6`GCFgiObDhj203p;xdCp^tDU!oK12F-C$D)`j#63no)=3i2V`Dau2fg>n+- zLB-?vlpWXv$|ekv>=t&GNC}ybZwowz0r?w)Un1}OGhoLNOTce^4!H-rCpbAcUKrfi zN4J%lY^GrKLakVwsF>LPQv9r?OX%Ft+jgOLNC2%C^3Srz^RKh4JPDJ@o6UU7Gcum> zjxuiX!Wq|iwe;J(UG$4QEd3U*uIdV}pz0>?e$`dp)v8;(OI6o-r>k!BE&$res(S!m z=bfo~z`F><&I5d*>MoG;kaxN2KERK7H~!>2}qu9Y!1fENfot`syR? zbGU0er!@OX=Cz$xtQCLMu2i2er&xr&_Xpk$Z*=|PIuTkA7WuzLRAMy&SE<=y%IJ0Y zZwc9?)?_95L+TI8owQ^sEqxDlOZq+Po%90g$Mm1nU+I<9vh-3aJ)HxflvFus}a!9jL5~IrpV8s2ck@&)+k6ACE6v7 z5M2^l5tSb58?`<}5|I}?HoQ0xLap=9C#^wqaaR#fLo;Elfc@YIWUhzG=bf{w`>){} z4ma)G-WlDkMt`GS>8sfxS|`8II#qnKNhrKj7v5gV8Q&ViA_@Lw+~@1*+58=Je|`qt zksm#0)m`m3ZoTa^N^Wq>W`S*uh$N4lJ6sZ#S?=nBBs0=a75AfOLb z8F{XMY$Gs-n&&__1FQq`%sh9x35c0^-gL_!&6iH&AD}b&=NUtSovfC&iPirIN!))$ ze$C%xzHR%}L1LW&sS*lB7zV*Vv72N| zhER5<7Ez|Bc~Ti^*;JSG+0^Lt71Y%94b(~Lo2lc|w^IK~-$tDb@N|Hu0XzlZN$DE_ ze+zXikTW%XJ#|d_b|7aZH4otM^wm^L+H~sDG$v(cY8Uxk@(t3IHp-baU+Tv+KPo3Jgj$z|r*@z?icDuJbkY^L#D+8o-zMCP3HHZvcE5 znD-XnK)=cFrOWxF7>@D>lEO&2OF5eQouW!D zrBKuAD7k6Xl(}iml!bu3BCV0KJguIxF0FyG4Di?d@i~CrKv|i_p)C57Gr}CoVqo0j zG&W@cz)REaQX+seyq4-g-j-586edv#{DghD`*GEnj2L2=F7iQ0QFv@{5mgeXBYzH9 zKsw{EBW(10f**~ZgM*=9*zbrJVTr!Jp?hJu!6zWZ!13S@epR0B$X>U*aK3Z5&p}72 zr)Y4sE8PCjF{bC>K%zOuHc4M(I;0-0mCFV4N0PUqPhC~*qlGj0`Rz-ZT3g-gm4aEd z>je4L6v1ouFn>Ku&p*o)@rN1h{C^p({Ns!!{#xKOY9WKi|C`awp9$!*0Br`Ni~kp+ zg+H6o0cdSNObBQK{(OcMum!+9AmuLrV)Gbc{vw8m{|`g*hnFx^{KbI2grVcF0_LC3 z@E6=<+!Uah4_m`nQSJY-7YN1G=^}0&U3$B5P&ta9f(ti}{Wk^;?8+I;%Pe`VnBz=xrOQyzY$(;!?6nWAdN^Z(}ibv{p%I4HV zluxPqDRrqwDALr!6gA)*Q;$-*Qx8%sfNcWUmU@7q2e>+C7{i zY@ddXS_14+!{+Ys+K0wYrBw4$Mo<)rUx`Uwe+%s$>sqtgJ6n2MnT^4%`1+3m@47XD zgqo>>B2J26J3C5nfE6yNWD*5am{fr;z-k6bAY@PkwE$NG%wW(2Yz7(N2mn+86JQPi z79$eKi2`Dgf;vVtphXMn8LW8}0>Xa3XX&vNQm z$DZCfsyai=td+{7^+a`LGs3XA^@g>+^MTz>j&?L?d2U;*KYi8>oJYQP_73XwR$~|l z5fL2pin<9K81a!ri{#KQM^27f6FED!BSIQK5N=B>rfp3gOWm4sh}@O(oS2mQ6hAe! z0J|ZzC2V_YQt19vVetM`PSCN`fS|pphXaqL!UFfCz6dy$niH@qRqlT{^{oHS)Nud( zseHfPsk{7krH1-#PhErdPo0RGo-%}>CNJ@QnRo@(8GjcdkG%|j6TRIlJ#vZ13)(cd zK5~XjGBM6+Cl2lSKFl`M8C){p8Mx7o_3N`mAeVN-;1A6_pAN$YFPyH;?Xo(+IZjD( z@RuV8rb{I@i}gjCxR+8qF@PKys~phqHkLvYv3#7ZY>j)j~h>_Zr3kS z)9bp_F|`EE@9GJfBFKzybqjTsE^3-u_br#g$7r^;ilQsy$RD)N|O`Do@G`4}cj zp3n4_Ph}pG-(YS~q_K3$e71w8o%299RMTaob6;DDOW%hEbpv2Qd8YQD zd{PYnn^4}VI+QyAF90q8JX5tO*VK2YsuU~IC#4NxN&3roUE)F5_4tjDld)0Yyy$jM zL&P@sziDo+56S18-V%HruVYUQ{T*uPcMY1VjyC1|R<26LJE8vG z4AJl#Cu=Yb+cl@SXEm_8%bM>s4>Sj=?`gJk9&0YJpJ=44r<%E}XBuySJDATjRm|s_ zLgow2C+1Vlzs%Rb`Ht`#fL{T8NAm_a!!OJ*fZwXWG0m!fndzzm=4#~^X0hTc6APe3 zUdTKn|HeElFJd;z^-SPr23CP`JbSkK9_P4rS52&;t!{%^*bvjRzh$faeQVy` zOlhshGxZXP)#!$NYugfVWoUcoITsdgk~e{L7e0rQ=|`dV1|6algn5#CaUh}-sT|i! zS%zs0_YJ)rWeFn2LIYRDU+|xhxXSN+(kt|>C_j_J4jr|eR%cI1Wa$gEV#dSVgRh?IBL4(IsB*bk|}15LP9CvjE5d?yGSujVhECqav{ODlx1! z1&K9F5yo;+P+3)SBCAMFV71AovKA`-WyL60vbU>FaBvz#&3IjGo!L-d?_u$1e%aH^ ze{YZM@EZ;gH#==ml)5MB=-}~|7x1Tjlh8j4FYyD@^X8L(VUO?Z84n^ByrKsWfa@4)VkEq{CFHx(KAE1hp zAEB(tH&I?G4^aLo*HNUDyC_V`4ODo_ZNR>PBB$H}aP1Eh044%HF=ZX9Ke+}uFZl~1 zJ1N-rZ9*{YONOe4d0LXJM4K;GYCm<> zX%}_u*XFm4)@~C7X}LTf?c^3GZGF?AW?f^y#;w7w`O59n?5neB#@F^~M%VOdW>oiS z&T#A+8M|Mzl-;Xw1DM0=*L(!lq^1fm0;2Rrz8grfaov5V19@D@}AsQ|^H+(&H;KY((KI*M8!vl(?eZYOF< z!X{Kr;wIFSq|GR5@;cP=s!QP_qSA>%TiLOqXYi_(7~`L{n{XA?^ORO zJ#Ue|RvT=T*~h2Y=;e9KAa!Bt-#U)h?;1qwC-!0WW4ov8SDUWuS-L9yLUpx1OL0!W zT z(^6{5+W4AK?ZRr3_7exE4df8CAK7^ALN-ww10ax1*1EAn09Z9ctUCbwH4f|@>LFH@ zYM2EFuv+QJu2z89;}y>AM!5s~fZT(Pkq@#4WJI=AwtyWc*RtQrzi>7wq}3Od+iUHr z{oE#vLu0?rv*o(+j$p6lT?eBlRXo)`TH!x*OA7&wGrPEY_S!vogRjB+oj|ZAcZTn4 za08MDgQ264bJ6$EMD!7V9%@YBHB?aWc9di2d=wTl3pE=z5k)7AN9B;mqnfCrQHvwS zpc(eoc5()4G~kZ`{QTrB zfO7#(M~zDkLZOpaBDW`HAkq^L!H>u1LC3^C1wW5^<@qrDqT5``Cg*0tD#vi_@u8I= z%Kmc!XZyaOPTQK{_1(^p1J)d`HI@TzMdo)-$!5-QpGnc*Z1U?ZG|jUfF>#DRrVYAn z#P3q!mmkBRvzqfDJ655t(Ukm=yM(}58%UULA|7xBJJUC3& zK5dwwT~$9#o4}o@4Xc}?#n(>K=G08no~oXt6>+9%S8%3ihuKrKjXg=dhJ8=9ncb#b!=@>>un#EKvla5K?7!se*-f&Y?3uC+Y@_rN`-8Na zeMg$Z`6BJ%c*};WU&!Xyo|hB2m5SvJvsIAhQJM+-OFBzimJ!>PVJVY7>8VmB*@Fzo zq32c)&_uhFYuhl-Bh}>}aIoiU=pi3290lKqXhp;!Kcem;@qT>dDSr!68URM^4)Q_~ zLV{56FeD0(4MDBJ2cYQ0KvX^@5LHGCLM2BApiV~zqMpV2qt?X-plTBQQ9l#?P-#g4 zsN+d!)EfX5fXzulp_%|RC;6lJNr*q(o+Lp&N+KXNiBjJu32tyk922r3CJB5m@`&dK z+7CA!Y1ladzY;VlY+!hDQ2k)GpP@enF~?4Wy7r}b_uH1ZQ*ED|Pxgd6_I8&JZtVWY zUSvhsl$K^osrjezfT>CsXB<)o8P+Hx^{(=hx-N-_P9`eV`gJ|iZWo@>Hntzrj%nMg z{VCY3P3P~?mbPruPH*0$H8$?hK5E#lT~xnao5|gyjjY?F&8^+3U0t(JTVB0gi>p4U zE#z$0&gV?j;y6Z)180jy&*rG5Y?!)>JzgbbA5gZlzbZP|CV3k>Mc&0eAnRb)NITde zQW5)@#F67D$>7`-zu+toPpFyw;9nzF&KvI*`$owQDa!!&8xirayT$ZFnt^{~((i0>;Nrae| zc;D9$?+mxbIzx9xOToJ%E_#Jhb3N7(2VIY0dCu!XM4+qye@7S8sbK+(I`j$bJXqkN z>2G$i+9N?-eLsf^d$0BXWqZ~8z1z~Qw@kH+HP;zyjsNJ+8sOS%`Yu(2u3j-g*Cy-J zLZnUF`Qjq&%dYoYhtAj9xgC$SKiZyY!&;weFYw=JJ$bLSH<}ByQB9w;T@A(B=k>p| zr@0L6u{yf;ac!fvwWdy+R8yw?SiM_2z8a;qbGB)?oGSG@PLJvxCqQ+dldXKgnXP!n z*(ra=xhH$iDUcR$_>ym&UNM^!B{p)_iejs4yB=4M=}M{5cOq-)oso52olm&gUCSH# zx~@0D#01_A38nRd>`sTHa;HeG{vn&7pQH9Mrx}ua=2`F9&-X!9GAl6CNNAlddBKlq(2I_!-2a$kT`=(MJ%N*nNoOar+Sa<2NFP<2NHF zC9FbhOjv<9maqVECgC5%g@nb3eF<bfT{*khf)2}1Brc``$#q?+njEL z^@RluoZ%J|*2FW6GtSUIFjQ+Z41Z~Q^jwufKUc}sSID{gNLj7^sH9#m5H;v=T|E6B zVTZn^y;C3ArqJIPsP!nmPXD^ark~bq)B83#8q5vDdSm^t9$e4VPvUOSzpm@hQR~RM z^4h7|y|t@>=b!cJ=-Ra^QteVDu6Bk3S36#gtBsLSYl+ghTC8MtZK(KYZJLNzySi&k z-N(+Zy134tT&}RJo+-pO+J)s!XFDrf&U6I|w4$!II!V7UTz*sxQZ18D(_T}18hs66 z)*qJLy=Qy-1||>gbF@1ayG(Pv?UCTw=)Ds>7Gi}cpx0n8VC&&{xQp-K@V&mf;d0;8 z@MVaLa7W}N_-Et=_i*_r|Y;|3zF1 zze%1C=TPUsJHuzfe?(4#kBc4;KM*q-o*$bH{~S9Ou83U?cZ>T0N5<8|f5*OtOJV}x z%cIA@=0{?or8I$05qTAOG(qci1GClhW$>{3egFGzXOKCrdtpZBgW$7HA3RVXH`jFz z4?yRK_6@HYxH&M+?q|>IZL#g?v3A?7^Q<2&2;jXGX&wN+A3b0?Y^0e!8C*?Gdb6=c zr!d~uDve__DkD=RHzp`e#xrt*v02(<^p*4(XNy3l+nvKkb%&QJuieY^sTFQY5uiIw$hBJCp!#UmM`h!|Z{d|p#8>{}r9a3K5mMczkPs@*S z$I32n1ElY{S}})PBl4}U>{?dO?d+&`?>yA7OgOG_xMNzApyO&YSm@8YD>U=Zclx#2 zyY6)~iMMnm$zDqa6lBFX4M?NZ`xYse?@qp9!;2)mfC`T%Xi1Z}7$-y4M-M z?Vgtr0Ul4Gcid{c9bAJv$j%R3{6Pyr^x;Lrdk4P`Ozxj)-`qF5S75hrr`Jk27Sf?u%U*{sT*;#3-azUG}yDl=OyS+8MaPu@U+;;1qxEXX5xAnSht}5+n zmswhj^H0rTkX3!f0ivEVWKsU;zo%gJddUxV)1)esv)H0L)mfxswqs;(1QWYPwS=`@ zZjd$qTYHCF#=guk(53Vp75wterRPe}zvF(LFYfp$`59hZQvB@Kz26a~Tgs+aR933# z8<^$n`PH9mCvcxNOlVrt;?8dqoNViCKPk-Xv~{_O3dBm$J;_!vP5Mo|T`Ca&E7gm| zQkxhe>k-e8^@|_NY+_HjReVm~BaTvN#72cd+^&>~^(uv!py?8y)e6PF`c`qdp+$Vv z)GXd%sS|JQt`)DdwTjpDIY`F#Pmp*Hev+ITnk(fDlV$H6F!CtJPPxEgn!-H1SutxU zQxQ49kRR*wm9Om?Eeo=omU0X_$wTcSNuer360Hc6U}TY!o04ggH{#cldE%MU@8XNH zUy@mhb+T`&V#RyyYcc%0uu zWJ(~^Z)NaC|KgCJ{%bxbP_fm6aZZS zD)iX_+5r9vO7ymaa9;m7#e4Fdc6;n_HoJ$r9C25=WV`?Cige%P7T})cp5pH6an!xl z!|eXS^N`0GuPD#u-hG~9z>eNaeCB~mAW4uHu*Wbc;sFARcJ(_DP!*UOax4^tCF33v z77*LXgXF!mFxuk?$A}YAPa+dyJfq*m=Ee-hjg2KFVB(?^xpAnZY4P1j#qmFqyW{t# zgeGLBh9&f-x+YYnHO8Mx-yT0RqdyLtIWev)b6f14taULF+3C?Qv*nSZ?Bx-%>Sw`B%Bv!_nzQ?$ZZzvha<{E)ZgZy z>HggtY6P2BtGiSVvdt28C#T~`8(hHSWi*4DCpElkP}Eg%?KNq2YpcC$6F7b~quD#E z@38Eg5Y|_YfO(Bmz&yfv%-qAd$=t`e#oWoc%sk9F!92)GVxHs_F-~!8^otx2{W7Py z@-F8{#chsf`E$;}(x)8h?}wa>UyC>oej3>>MJeokg)>=B-{Y81zgp-^3r<&Me1TP_ ze%@QY@ROnRN9>8I1yW}ZpE znbnfMHG5vVGTSB1CC53XID1oKX!glCQr7tB)(ma9Tl#!TLCOO{RbmxpW?W71?Wk)1 z@3eB{FVY8C1@1k#CA7dJEU4F|)bAchh5Rx6+4uM$25#yf4MX$~L)rGRFyDR|>`Q+K z{PBR+w{S2VX&PFNB01baFLNyQ+X7{2(;XS|i|39+QOb(#Kh`e;lW-fs}w zC+KJOfOOAHpEVrqG__38rW_W}Rs;w?%jO7%CGVO7#Q9uemtQqlxR|MJLsT^iwv`Kc z8%w9RWR=WsX8iVOjw(6UJgM}3OGf!q{)Nhc)=b8m4g~u|7qsS}#G89mKG3jH#cs~g zPUbW9CtC-NDed3QTRPMhSK)E%a-qa}L5S>rDNO19CY;(`C|urMEZp1uQ+T8MyYNf* z523KTKnU*nD4f#sNqD*El~C66uQ0;)R(Qx(A*{7Ygkimy&h5S1J2}1P&al1w$V>YH(rp=Gu@CKH;+<`wq8};=vlAb(AQvK z4-{L@I@oP*oF5Iid#rLi2mZ$u3QzRfiyDGF4A_p?5^~kA0FxZF2_F+WleihPlvIOV zK?1&`Br0*KgfRR+xLiCMGaA1uBnW>p@HuXwUk}y^X~$fLHHP7RHiwpaDuYkEjSaf& zd?P^NDD-my0X|Dx?x4h2`eE^pXi+p+=h9LwH9G2{afM+|K;TV?^ zU!BW3#64FWa;jSw67JrFa`EU#lRT&UpYW0dfWfPJqS$$RKvikH+-}+vmocmi?$NelU=ROn` za~}vxxp#$M090}B3BLkb6`+-Hp8@fwLMHc>u#9_0Sjb&3T+a0rcGj)#K-4{IcdxzI zMz7x9I-e6G_|2-}g)!H){6p_)`c%2AvA5h-Keuc+X+E2B(ltrxwbqzJ8xkweCB*YR-3Z)rRkvstUhn(c=o^8L%H$n6rx(u;In`sM%$UsN1u-Rwhhq{FzQsI_8;S{xT^M^Ux-AwPwLPveA}#(^cyPj3T1uh=Z9~!x zYG?8`>iX2z)QI#bnn$LcHkj2HuFWwh#f;YNbOKD za`7+*RWrO8mFAFzI_A)f{O#a?eB#jJJIY}?{Lt`0==!0hKD`4z-r4=TJretVySm!= zPH(MDhdlGsL8f84eTvT7!&M)!EK-^beX_r`k0gc4l_HcZw{w?hY=^dEbK92ICV@Y1 z8Q<6#!&7o|T4=Q=n;&pOnm4knO&1u*W-R@DGo@-$%eTsZc-+b|{?@8#t6$dj246TBELjWZk=pg*mlm8(!S9Aw7teGZiiUh zI}$Cv9g{4$jujSs$979($5~5S$307aM}cK|2gh=8=p%?UsrK-5BZko^!I&9zVqx8%tSYJEu(JxgouJ6UK(~I!Ca)^jbI^-k1Y{ia zg8w7LtKgr0b1+MTj^Pi6x{x%OQu21(B?<_Cl48c$$ZK!}@)<0Yv=GB5xQ1=V?+P1HetU^6UJ0d-h|N3r+AA?IEM`1g_PoWWBW=OEdCdfoL6r{wZ z+vkw83*?ql7Q_hp3AqRw3!MZ)!^VP)uz4Uo{4U7mI}E}ik2y_8#W=q}4>-H|i(F0y zm|ZbJNcX1TWgfSI_v&=au-6Z47#M{2^zkAT`E(J|AV-MjARtmXWI0I#`AKqy4v>gY zGC2(zNzQ?S$cfN1q;5zLu?Uh!yZ|{**aa!X?}PAh=ONA5*O1Sc8pz@>8AKd10HFjM zArk{NkZk`~5DIz~#0{zRvBT&4xWKN1^B|wRKY$;5-Sb}T`OORJ;pcV7ZHXt<^_$0Y zXQ6wzlhW;*Bi(hfL#|8bP?A&D;2wv${pi6NeGYxDwmH@!>)(bkW|G=y=$1aywRaxX z^tWDAt!NP{vKyAmPu51s7IBiLMa*N84|IYASv4#cRJ4hO3NAe$+Fo)*bm{jY z(Y9a5Mdae+qSB%>q8UFmgy5I$;Iu8}Fh19R6 zj+AeH9p}GCwiABLX!H2Fvo+w?2f^YJ3%{Z)m7h_0n)i#&ZAoTfTds3fH`mpaH8s_t zn{L)$Y4m6$HZE@pYAkQw+PIQ8t7*32Tl3qtcf57N@YaXG>o!*=?3%Cgk#*`mshZ8z zdTj3mD}4}aFLFwA;CdW(g+e>L^H7n#tAqabpN7p0m6Cqo2g2V_uEsb;79`ZfOil4j zn4Nw+>2>Dll$7kC)W954>aU!(l>AXyDX&ItONQs3Pg;?CG_f>yNrHb~eEh~dLo7Y- zbqsFwg6KV?J)?x9%OfV_p9=5FpFw*wCWHEUY!;lafj2Csz?)P8m-e zJ@pk~%v3YJWQs4oc`^cbc9I6;G4XBK`0*1$*N!y>@6SITbTTh4@WCj)KQsH0A2e$z z`anh|3Y;E_{FyrFJ2s^X{%_JhFjayOB8!Xi`53d(`=6*wo|5pN?#rnr*IH7VOBUg+ z(|c?(h!EEA@G@95>>oHVw9GGIXczLq;9NLz(C+hUV71qTf!A(|{t~Ba{j6b9Kc~OQ zuC*oEDb`1Q&y7R9^K{|83)KYMGeuK(f-KqEDV}D2-W6h8F8rX2X*a4h0;KX8&s#R7 z86?&;bPJDh2ish00|gg2TU$I>rp7CDMtyi?d!4Xsc5PWncn#~HVNK)YAIDn$DcT{p`txwRsrYE;(%0Oro7Pd zU8S&$(~+!I#^u%+>u2jKn`?KBJ)?WpKwdX%aKL(R=zx_w^xd*z=(Tz2;CxeEf1SbB z2iC)TCu_&_+)$TVqf}Qd&Puv@vSOdvTk+DIqnKxLR9?5HsQ&8FsBiWnbTj&Y8jcMK z%^1+S9=PjL`()2YLrfo>(_G(THxIwH-YkNzI3#>6=2GM~e0X## z(H6ax+!UQg0Y#6dbVRyP_D1X_>uGhQf2dBRFJuhSpOiq@OGv~ka0$58*bwYsm?Eqy z^mJ%Nh*JnGWNFar;5Pv`f_Z+7U@vq=NHkIqvdQ;p=ug=8Fe>yPOo>k(_5?T*cf=ct z|K(-HCwWy6G@kc}JkLcWsb?HH#LG(F=T${<@IFa>;=P!*3QP+h=i?eN9?}{y5BeqY z1Z;WKTX=QURo}L#T*Q&6$B3%PABgu6R}iV;QHUed`@Z|h3V0fE5LSX4hC+e&$&8Sz zK8FI=fy?}+c*me-dA;-9wy2w7&kc0<#GQ#=a#+)P8!=it|<&Bc-Wn#(IQkCRjiB^*K+aj?Snql!yS3;Yi^G922=f-x&u9+QU zyUqzax;(pHinJn@7%NScmdc^>GSxICS!YuZ7$JIc_ifYHzGK}thXj3vPKSm^ zXJG7$DR zf8~Y*Ku10Fo0B~jeJ#@$)s^mu#HaZpPNe+ht4{g`U!6D>Ziw%OosFx35o15X_|XNh zIZ;<(*CU9qy|lGZ56WD~WFpij9(TsOAXMxr4Gi|EK+kvE?R(nA1;TSW?@0jpy54a3 z=?EJ>F!*8cNZ*`+@@~KW31)F$g5gK+3hf=6v-)^Xr(#35t9+hyyfn-5T8ua2MP}oZ z&R>QI;RgN3cDOFS?TqG`pibq^?@~-``6fHx^pE6CLwy&MOA^-9{@vDEeT?71{?Ke> z+8VqW8@Z#a@U;&r@YVk1huJlynXC^b>zFmaJ(&@|{h6F!|1!V)ddKSeMdr-?4X<%4 znP1mc(pk?ez0*`*wt*)sU)1VY`Bz6^)tIha;PZbjLm^ww+@M^|`lX)Cey{c8#OsSV zV+`@tJj2uKC?mG!Z(~`_7UP-PBgQjz7mS76J4RZ=DK6eO$YUZrj;hVIo3MX{IO@7S=oET++Z&=ZypesuM9HG z)S=_%h#_y_IedYsWZAs=%wjNS3%ny~tCa4l@;w!!z z-IcY*eaeZZiK;Q?_3D=viRM)ICtbCz-f+Y|(|mi-zZ>kB)LZ6!s{gt>dU%C57ZeM9 z>nibm?YR~G)rS{Q4tELphBAa54mgi<4WSbvFgHm8oPca59HdMmt)!SpjbvY-nMo8< z0V$3+gOo?m6KCRg5ij6|32oRtgcVpb9)ewjw_>Vs{g`lEB=!{c5ViuN!OFrm;^d)r z93$ik{!%cWkP}o$&;;ZWPx+S-V*27DefTktwC5qTX3zPG>NwbWhd@zeFVJH}<3 z+ijf>!o197Q&+!?>O&!*8r(h79Hx12Lw0 z`z(W?cax6Zb69iUx>!Xp;}r)DFQvs=SMd*3eCKod`1U=L$%5Rjzghx2b~g?Qs<_^~ zxwT`OvZ}w=?`E&7qq3INq%q%e>KIw<8b%On0yBq6Wu0d%WjiwXoLltEHDls;xl z>wi`K+c>>S+svs9;`>*QYn@OrwS8iFqHsc)rIQ9cmr_e);`rY#(k;Kbq}<}wvR%am zvI)gP*@og?S#7bqeD|*q`NrSj^5-Sf<>az;^3L)n^47`*xt)$uQ!EN3s>*#pDb0OE-j{otPZgJDMTOWeS9*MgWU`jg_S_dLR?^ZL9Vcs{)JF73JiS!_ksw0 zzJVRR0=$FVCVNhBTHt2po#NnWi61&*%pIWV=iB==$9j8Il|5*s zd-o*ya?3+$naNoaY1}Njua|cE>gEVfXd2oFRHNF~DhmW{@?icb*`b!_5^0lzIID3& z*WLQPLTlaK_Sv=1TfbM|=Erhww7g>-Y?{VA&;Vkb<7%ot)#@vKYDkqAIp-@@u?ZE2 zS?2O?rnS71iLX#G&sJ<=K`KYHUscZM%&7WQ?MBb8WzwCv7a7+2`AkStG;3lDi2Z=i zV>`FKRvL;+SrFM<<@4AEXb=jM2`(N$xp)*d7WW~N@{S_IvKC%(MD%ex-rwT(3sVI$Oy50GT!dx8nu1S zCb6An+S8wJy3s$%w5>nbgy?4*kJx7$%lnEAlHNYO%!b$3^+f94bVq6TTS=O6mLN6F zj8#RNW+_)1zbIM^OBJ^alNFB)cNEUX6lIAqQ^hwuRwr84YI)Y1`u9C})AwE@J|mBS{NyMwcwkMFM#j8ixma>LfKC3JBgoqzvzP^t208TZht5~(+cSd zFu0zRXVn{GJ^fS@-XXp zWh+xuNoG!~TFDr$xn@ z;f-=mlY{D7%WM^k|F5dK6{;?3->6Q@ls?C;6(tVIT z)4`-R-Bu}H&y|kThXa4ra#WV77s^ojM7c8UGHjn+xj zmAW+TR=rqv*id9(8|9|$=GoS@R;2A$Pndm0-;Tj~1OAS$hI^e8oPs@k+;)K7yar)$ zkhiGGz8eDlT zijijL$1t+LMIXryh(>0whj$Nw z(Pn5D+w1FzQpi2?m*UazysXEyqQ~YWR zlsmP~myYK@6F+b1>+)#+yK`S-d53dDdizaoS!;gXRDoNqm?y73(IVs!n|s(Djj`-o z4d+-p>LIKd+)vC^b%&S-YF9B?HAk3HHE)>Ts$E!ntN&q5uI8|&SEsZ0RDWZaR%de3 zYsxsyHFK*U*A7)*tz*}`;l8Og)PJlS-^k-OG~pXIwp?!v<%c$_1+6V#+Me*wcid=Q z*?FTqSyUlJNbFrg=`_hx`DfXDC0uD#?N+bXRB3-}K?c6g$MjR*Yo2fTVEtyu>=`l~ zwqcFud;c;f^=&df?z?L&>-*Qp>MJrn>-%P0+jqwZ?^|QM--|c;_c9H;Y;z5jJ&k(c zH<$FWtx_4ey#B|duZ00&Z+;un!Y+bZk+pCl07`hgqazda#O~XnK5Oi zEpC~aw#>|oTii0HZOTp3FlPcY$v`~hG3e9peV*@+lXG z+991SnWOwHpXJ&|z1pKxv(aa>=U)L*U!RcS0e^@04PG5pALfPO=Mcauc#l1 zL!-kQbd0tq;;2oDm!sH(l&CQY^^x!5Pen$>Pl`Me7Z*vzfygznxe?Zw7ZHnN&O{ia zcSJ0Vo)u9U)jwi#RCvViNLzSHL;Wxq#hqVj)5&9sM35g0-glq{3 z4bBN}5Y#BRRp7#)J^`-+r~9M8J$^$2zWQGG_xE-6U+=TkPv)a0dj}r*rh5NH_U`ub z4fO8f8|gj7w}JO=-$CBlzH_{r`fc>?<(J|eNOqo`^Ud>-esmVP=zV2d6rlfyfY0+OfH3et>uzAIqak*_X z{>r}dD?h8t&uN+V@BSHozE%Fp{QBi5{_^g}&@XAX9yf$^7j5ok*Ya7qYZb5-R`#k3s9I_$s~TWjTaAsbHUF5l*GSA7-752DU9p+g_pe{Czf$ke zOPG1JBN$!n1!h=XJ(FG+XK82{YdK(8W~n#qwG1^Lw7fT7u(USawtO+AS>~C|mgM?o zRzK!|wV}n|Hr4vwmT$XnU*-7a81IaAuH-*(f5ct56H1%sx(ZoG5rU^=z+?a{m(U?5EQiH1K=)9sh=5z5RBC zIDImLZhN~1F7)c^-_vuUZ$poh-tq1^o*mqLJ!WbaxLtQGa#gtg<+9PmU+wBruY9T2 zDwe2~ih=3@@>c3svS#Z3vaV{gw6FTEbhf&+w7Ytbq+E5Fj#rJLVw71hQ|q-&i!r8iT=GH$N3B8Xn&o_uKYDLoBt)xPW)Z)C-wKaKgWMB`t$2|>puY*l0U;U zzGXehIGyF6IVoQN`)m ztx8YiG$~)5OM1k4W2=tm@2dG&@KEnvq^+A>EEo$)-0DY{aZE+|FY9{ka(h4(&3>rv z=^Uq<%CY)zerw%v-fZ~A4>DEr3(N+7L47u#$h_vyGXLJKT1rH#dOE zbK?5(&g=CB?4bGqtls>_vE3Z#2s5v?e>0`o{x*f$QcO#%KBgRtmua{q%2ZDJwP%?R zrqxVu^FNGB{U63$pK9^8cv)vy!)->}c>8^a-f`La(D{vj#5ceYKY@S2$#f{)T~;b> zsr;iD*}@A?ULtqHy_V?ZpS@zZcRK| zxM#UmIyD?jgGRxxaEL)wEHMc3q{spx!ON zt6VBQBJWP8O6^ceU%~fbH=!@CbF%zC#~EjeZK6Y90&MTi4(6mW!@REUgK@F`L*2@n z@A@58wKWg5-qqUj-jyxN4pnR_(Uv)jhL^4={9No_FtzAw9#^m{_fh`3oXL4Bvs>lf z_#WoQ0c4oZ$aVDeV&*vH9&#H_czdSSZe-Fu2W}eL)p5@5={%1zk#2jswEN|7H z^!(WDV}<(c#l>%OMwPzGZCCy!&sWRl>npnyUZ}oU)I%3h@>GAP6x59^cQx`3h^GpqE^Gzjnqs^O*zs(-zA@z&uf7U-?1~bnrznJ~j{+1A1y5*3qqqWX< z*V@wVV_RxpWxHq3AuV$oyT4<>=b7n8_o4{)^iz7 z6F;9*ijDaJ*i(25e8q97CvHGr0x{A!G+16vT~fZ1#JPNt{m?+=VUIEDb>4qm=lD%` z9~0=|6&mu+=fALJ{=t!9LEWOCh6KhYgg=T~9$68;Hu`%)kJxsJx8nvR-i|L$=$Ozj zVO7GY`0WV`;zlN{juqlJ#mtZ25d9%;U6d(yVWcE>QiLtKTX=C)OxTS`d&t~~55e)_ z+k$dJI|Qx|vG_L+-sG1R818!@;FxzC|6niZx6R|VkJSB`_d?BlFYGeSbF+G+MpN*DS6*_?WuU~%C7nL19#1EzUFlz{uhd%AajL6o8RelGMb#*K zQd!DY)GK8(>Wwm%daTr;?aFCLp*#Y6E0%y(a(}Fqt`x>d?sF%p=j;o3&;9}*u-+GD zFlV{m=Iv~>ag9B+Zk07izn$q+bHlu_s@RyWO)@mE*i-wZ%uPSP^i)lklA+a+#V%D1 zidb#e!s3dp1$_C>e6RA9{E20+@@|xl%Zn&g=3OlLp4+wLLM~IhJNJ3#hMB)%xEWL->U7nef3eixaJtXrrU!n^s8|| z-9+5gkb-9!J@H~wr8wJsOYBlVN#yFi#7)dap@L~Cs4X{mXbI-anf2Twrp&pM>FAuq zoMwA63br}3($RvU96gzH_W8_c`yHmGU1e!(UvEjZ`&+Nse_0b9S8Z92EA|KMXU8+A zs}pnUxJiPGfW;5u3vd!#LMPE(`X-$zEth&Jk`yVbZK_c&jLR6!G`9w1bX)4t!F!6= z5#MLt8UFb`=D>HprNPtu4uq!p(c#}o{9ET&8KLt{jqK_BKJu`Sca*_&@VFmtR2>UHCw(jtIQ29vCoOz1%-QeZ#LDsQhh zs=1!|s;3^bI?5wLz1e-Zns-~SUgdUI4ctoAr!}rF?KQn!46gHCZoA%cS?2oKCCPP} z%S{*HQmGDC=c!y&hn1HV?h2KBlq^NMSu%uPL-j$+U_;OktHoHMf)kui*(}F-`%~Kv z>p9Ct=5+mT^HtL|<7-1!9aHOD+gSgXZbwaKwY6$M)so6gtwuYm;#Ijz`OdQErL#*{ zmCP>bUA(zCq3C&0P@%dgq+o4f$9!4g%)EOA|K-jq@W|~|uq7v`z&*#c;C{B4zc|~P zKbr9HY$1PrwtGQ(c1S_%oMr{zbNUwS$ems=HE&J9^!(!m+Y25Rd@lS}5LT=!I9wtr z^e+o9d{o}KaHMu-p{i<6;nV6jg)?cR@(EP2;wpVqQyn}M?#i{%?%kAt`9B?4-XEDXdTopqE%o@M6-Z45lQ}u5g~q_5uUzGIP^&iH+U@! z|K&-CKk%3tw#WT$=uEe)kan8lU|-klAier=;8)e5fIG^`{-+d8{LaZ`zBgsr-an*I zy_C|Eo&zO^JYLZU-J8(Y-M&(3nmLq%tje}=EkZk8?xR}uMl?n}6XmN0qUoxx2&r13 ztIDQm9D%!ojH_3Xk!lnBBg0Hoo=^DUma?ESM|N_dgZa& z=h}_>+=?~2kcx{ni^{XAE6WnA=ae0&QkVHuy(qm~xutY`Wol`7Ww%mR+oiNnJD@aI zJEt^9d%0An%_=o(6U$KL;xekTtV~lmwA`h#lwe(jva*#HYh{%dt*Nq7YpMFBRoA@G zcGq3h?$+)8K&NiA&w=HE8?a$bgc9k>6vBCMl;m)mRpL0W;JNQoA z0-+DTRGcfEz_-PGAOQ`~D!7oMsHgNLx?D0^>MjeBhsYTcMZc>;m5*FJRfjcoszvTE z)O|h49F%vU>qDPQu5J7znp6JWG+zVyY2F0-Y32vraV-vtaZL=q>@p`fz~xf#S#^GJ zjM^*Yt*URx7}drQO7%MAvC^-yDbKt0R#I*wl`}MRmHDn~l|xi^CLoq7B{T*wVPN?o}P9pHaJA7o?A`vDav;N~&*GR#hF;Dyp_ubRg&M z9M*m3yoC^wW3EdO0GrMytPxx9{CEwuVw`N*2W@-sSAVbcdz^s4JnaosSo!eLxO zb^!0M*j9h1;u-U~;$?fwxo)T^{A+@mxz82PwdN%$4cieT<*-rw>U2_l%EQ8{J&th;09j` z3t+TZ1GkD3ktjOQ5`2IHpg(;IcuD#|MxsDkX%Q-weWWtvFX(?2Ig;H;J`l ze!wjEs(?(lxIj0z)`8tL?E>eyHVi!C5*qkk4Fh#5eL#TfeZUaq&48_nRRKTb69c^E zaRIYss(`Q3@BYcs{r-0)k^ae&yMF1k#%~Ti$=8=Y?vqZXdvBvky?Rp6%ad~VtVD4h zFHl?e6KI^dfFk8Vs8aS7u90PJ?4>6ce4_1CNAdZF51Kcps7|GcKDzL~DQ z{)w)qexQDkp4AW6->)5~UtKp&Kh`i&-`hAwKhQK*KiWK0zpj3e{v6X;pKEES_pl}C zd)q_w>m6?T2P~({ahh~Su25IQr|W(R&vjeH8@f1rT(<%5)xE~+bUApbPK%ci%+^)n z`MLtUT=yNX);-7jb=U9}-FEy*Hyc;#QgE=|2lvnyi~s0via+%W#JJjK;^tb5;HZ5f z%&z-eVCq^3s|_3Vu*govgY^-%vM{1i9XjY}GWBR=8b}HuvzC z&GB3*+vfE_w$YoD4fBC=)~8lB)%Tk0vhQM9o^Ml`)DOxM{c@y({2ob{`dyTs_B$qh zO;GE1LF(dvSK8G7vviohR=Ut%Dm&yKE4%66O_t_AN%q=*h3tm^e%W0AbFx7HXR<4P zuVvwWnX)au1+q+^YFUI&y==5ME8FKKm4EV7$ZZ}T@-T1h)9g3f{W(NGWvpNl(jpkNT@a4Gx?_KK4nRL0J*t+4;H*sLkcE=!uZ0h4Od zn_Z00Ouy?c86VW%G~6en`7b)QR<7$^JF4coKD#{@8fRiA9COHTF$BW&t39{UVG&qy%x$_c_+x1dB2hUT;mbhn}>d>V^F+00j*cXBb_o14O1qdZ;HmGuh|?G%3Gr)@}9_FJ^+1`O-37K zV^K3%Ym_D}gbC6KaEatL*h6RG{Zxgx82uDF!)v^VS8#X4*3MJ`J0$#j`(x(;+e~(W zwV7j#g|-i8^w#}%X$d|>>?m}J^#d~7;v>}9@atT*2=9qs-MVLuobI^P+GaxaV>NZe8i4~##AyT(=G6{8%VGp@lWjA?kk(Tw*R z1-#BE0~?GGEHZNVFQXC9G?w91<5xV=_zd?qp2ppc+i^GJ6x_<#2e&qc;ATcqOg8=& zn;Gwjos8SW0mf$OVIp%@C}-{n8!e9nck4IdwY5~3V&jBBdytr6?<($f%ohi<*F;}uiCE+e z#Fx1)crHHzCkdmlK^TB9h{<>$_QfK$i#I@?xCp)$o1y!n8+A{tr{0RCbg@__(cog~ zAk4@vVM>93pK>8+tkQ!{>glkbiwO>NorO{~btu*?m9n_KrB1th(=9!E(Z@Z;(5_S)rQliGDCv-kKvQ~w_#!ZH$yn{%}~jFGMuw~ zGAy=!GPJX$8&vkMhGKiR;e;d8Fq17ecsQ#KZ=Lmq0UR=Z<5b2*e1LHt-^h5H>@|JH zk2L1+(~K5=GtuucW0dg3*iral94Q!#iv_vqA0g6oP3UZTFN`&n3oA{maM%f-n2xFHJ=xUn?H$r%yu!&9D`lzN8tYTyYRXCceuXZg8MR!z%^zfP+N|HrIw$d z)WU8esh(mvLih&yi07iMARP6Azn}zdgRf9aIG199FZ~!iruTsflIcJ$oe17bM}kGN zxuBzb7r^rWzz+on&L~^M8LEA-y}ATqbtm-Jt!Khf%17&F1qBKo1dZ9@~w>7conkE#T(fFf78Xxqx#vKjQcp_Jg z3cYt#qe-qVsNO|`mJrmdebGcUIh9@&g*vI4pj*mjC`8!@?NbazE{d6GuY5W3mG48h zWrt83**db*xGT~~wQ!_lB3wbg1^Xx-Z%6TXE$l3g1$~6Bco;cIeK4mIQk@QN8p}A> zIvDnvUBTwt;v9*#G4`$2b2f?9VLfb_Wo>IIw@5APEcr~BC7a1-%9)Fd%CeH_Wtqa9 zunb`&)`84g>oA70jbRSiCNd4})0l7e*<^ljArrwaV6xfe%wFd*rX#nKVYwB|6@DEv zKv>S0g!Rm3aW&cVyoyL&2BtCsp2nE) z6ebT(WYX~@<^dkZoWkRoZFnp*8;@p2;!#XXJdBAU(BP2_E2c7LaUxSF&LddK{1Nvs zKgDxQw)lc65ObJP(aF?_5f-P|!y?B^E&lkLB_5YrI^i&DKb&fvhA&!|VuN)T?rb}Q z58EDNn=Ks=w`=ixyNFvkT)}OJ3uwjG<5%owJcRV_&Cb?%FIOhE=husRK3KdYyc8yg zQ-x6ME|lS~{3URhp9%ls8=!G~4I0Itq!#jn=mR_@`OUwU1PjZhD};`+N&(3yis|wS zai3xy9-)*0AJty)O_c~&tM9`Am*(iY%MBFeDyKHM_M^VLE~Ct@hbceJBPv$&hU%^< zr3PyB)C>(xFVT3=+cZ)15lw6Qs-`o2M>CxMs2N9p(#)lEG)w3b%^JEwvyHAJ&};V7 zHqBnzpgBTYh;7syCjP@Dy_YW69H6T-|IoRbJ@i}67W%YiD?LuLfez5Drk}blrH8pL zq6=MS)8kyG(go@`z=c?Ei9WX2IjKm2~%#_$uzXiXZBeq5N!@-R@?eAGJ79p zkG(S!?dZllb)+!E*$#|>?au6Uc4UINuFSt&4-n1)_mN}%Hbu}P;k@Q1C(3mfneJ)kV^WL z2WRz6PGP-z0lrvtW_~!@nF6=#ir@g6vGxlii7quvbwz`wBI4zC*j6 z4^XjlJL=92K-V}HYWOp7JKq!n;W=0<^aie^l{zA(;+9w^{=nPBufoRq#1n#hp&LzXIzl|K+2@-Vzbu?GhzMSMxQ0>r9x z;HqjQbXPwhI+ddj>JCWZG7mLyS&G`btUzrDw{V$-Vq9jR5SI~1<1zpV>h8#@Zi7nI zEl`d+4t-TeqUY)W^hE7}E~;J8d9@TBQe(JJEy8VT3tXdi5a{6owFxd!SHWp&9h|MM zh7$=-B5dwF3F5-BGzJ7@b!opaH73$e|pH_A1Ac7wFcYhl-u3 zwc-}~DSt`E@aZT|_7t_2?Ldd5JbQbwie)otsgjL8wO6>h7%qN&e#SK?hek{x{ECbQA-N!wiC1 z6&%94!B8QtQQ8U$lQIcch}!&B%3HQo-sZf(B&2Tmr?Z z;;5gh1nQD1h8jyakffg}%T?*SvbYLLe z4fLc=;jYLmlCJ}aEx>-E6)xvHiz)nI;X1dP58*Cwm!0*_=Faxc681WKj16R`us0k% z*%U`Rw#wdvy<{KHPO$G~+t|}tjXlKaw9Ru?+KQaTwiGVc_L$4DMetd+!+fR<2-&td z!f#s!;UqD~wn5Cbr4dlL*p`3`Y~65$Z6q$WO(who>uhUqHPMuT=*wukiOsf0*lK%A z+R|UxY0JT!tr{b{0n>J#=uE)gb|vt#yMP$G7f7`GgAVo((BB>nCfOT-74{C`q`fzI zVjl}C>`Q>eu?@6wTm@4dY2bvT5`1$gAz0odb z8}!_nicHSUD3UvX25}eBdTtN8%`HT^Tyv!4>tQo~Kb*ifgZuec;1xd**!iEhfiMZr z7AnP?!V1wSc!*uZe}#SGD4|aDB_pIP{sF$u$AO*vF|ddagv39%K!SlciaTo3+z7;-3pS}^&pX;3A+$9 zB4wJgvk4}F=IjK5QJ@VwkfaBLwrmRFt|Z+aG-F$l{$2}GrvYfq#uJVK?Fc%sk)S7= z1ctB)U@F@IEMz-@-RuZ(fgJ~4u`56!xj)BV0%6XFpo{YlnC7ejdz>nG&lw5}ot>cQ z908NK6|f(-9WLaK!V}zn_<~ykOSxf?=DlDTp9y;KYr#}L46Nrr;G29Ze#P5F1AkCd z3XR2nM)wE2sKe(1UI6KTZ3)I>3ddMZw&Rk)mC$36>Fi8R|wf)=e=Fb^agEC1n?(4g~E9l1aJtq)ubS zCZfG9g!iLH|HE07s5pljC~l)@#RC+pc!ok0?~%LWGjhta(I0sRx+?#I#>j6Wr)&dS zE9;DErB2vGdJ685w1pq(EWlBtK?G&OebG|90BZ0ta9aF|Q$!k<3cbW5!XaU}KxU|g zalD-`=koaJ+%I0rW$<^MW&AWJ5E?mS1mGMel(7edPi(I6gpCyMv2(<0@4;S$Ysw0Ezw;aX>)<| zDe!WB0S%lvpog;#%y0s@)9Ft%*o0_s0F-hwVM}fYoXTA#`uhYwb2Sk0D%6ONN7MQC z=qR6pKJsmmlaD}=f(VBR@8I9UHh5lW178bOpijSsTX2ZL(T`*mC9Ola|z!KRNSS-8rKjg?R!VK9t_?sY2b`pM;or2G0N8oFs?R$j( zlO2XP2yV%a!Yc%qW#{2VQudVW9y}v^0FTQ)5d4IPWkm!G+%FRd{Lvm+6hT|GQ`R5t zl1)I{WlPXD*%q`_b{uV%T_N+FPtgY1XTq6irL2nBdNg0=K$B!z)L52{4AL9usB{gA zmUcqdBzEW_xe1rjqu^Hxg8+)Ob!afS4>4xJ1KbbH!Y6SfEXAxiRm>18g*)PC;k;<& z_ldjslVVH$idfIR6mN0m;to!VM{%ujA8s~o#GNH5!7-c$ByrtA9QPM!%pC!ZxEr7; z_W>kxZwY?~t+_PNlAtyB5p?99gI3%tkitC!ZMgfO2lo)PBjtN>w?G%}3gL?c7eIIJ z3>e6rCHbeoVD2R7#~mkpocIodA>1)yA0&Jf4C4+FJ`To^vJ<#VU@rFnEGPHaO744s z%LR8hGx))YK*#w)37-Jt`4rfLPla>&zu^IX7rf7(hvoc5DDszJ6JZzZPxcS56nevx zf+u_<6oVS!FrdX@AWl?)?&2FfUR;J(iA~5mZgt`f@`b!N;zBV;Octv}R}tVc!5hC7 z;_-E%3qCB2!MlZ}c&D%*?-l;TCxk!vt{?>;gd|WdOe9x5LazD)^b@_{-{JsxNjw9; zie(Vtwx}uIhNj~ZbPBhn{%`JD3CvVC(1%_QE|GaDk*)xPC4umqq#HCy=EHdDJ~%^q zAMTaDg7>63@T2rM{2?uaxzapXD6NKN(qdRGt$AbHb5+` zgEpxVA{k3qfT9#3UaCe`sXG#+!N?+wMmA{!#7Nr^Unf*29Zc-ONH3j1v^InADpW(D zlkP_4(gUcPyscg)y+m+}-~}p>{zvczeUsis_oc_tR_SuoUD_MjBthtiqyUCV&cX{s zpMJC#+)Vuhb!Z3Zhe-T_YTyU6$=Q@wunDinWAGGQDE7gV#4eZ-$UKSA9VZLDa5X;- zU*?zNzxdO*Gyf6?^IA;tF2KmO02SOwP{1t)`P?3mL$vdUyGA~Wc%9%O$Rj$;;a-4T zqSpeV&jRiXDCGWtV(u3x;tEOK0#M485UvE(Tm{f_I#9#a5IxnBbS*G*2B0S}b9Lli zM!*o;!kGx_fSt1dfq>_DAmbq!KfA(U-VY}7F|Y&Q8V==q!a4kSxRsv|ukt(L2mTza z`1-A;B@SgAx<_qVbl+2np5qrVWL@{f{Ja9)m1HOr=z$(T7KU_k_ z;aBl+JR8p^)-KG8XYe2KDZVOx#OuXEJXNg2y+w?ZMHdh+hJi2=Wy8d-AXFRUS61Zq3zN?!%r=v*I`XlLweo9h_Jso|QtVBN~o6uLuL6j~zPSQ8gC&?}JQSy?c-=KGr zA1F=PSpXgAul-9#w`YF6eZHB$5f$#^4grkuW z6u@*a30?rzU=8>S%mD%(0ruivAQATlU&&v0nb@B^pfb zfVc1qK*0#=`FddBF(~JGP(gH3!gHXE2T;qigjt~FouHa$KoxHVdV(sR=#6kSuP1B< zb$lJU2GJh@S=c1D3D`)_%*Go@x*G7rZzFzzFiRK{cJewv2?hWJ2FL{#xC$8f3UU}B zc*A%h0(KA@!QN!GY?3etE*7T2UBY~LMOY2r3oBuPuoxn7A`B4wlG)&RI961{O=M5e zIq?DbNK~X12Lm~d0&&=ad*V-cIzB<3+@<&&9)O?VCio}z!g}lwon+p~9b|}+;EUJ< zycN5F|H!=E8*u{RS>Us{6r_t=K(=@Yl!@noUVH>NF%8IY0a3dNBw!_Mi6h_;+!;>6 zli@nN4j#eR;lDTo{>DyNhZ`ad7>XK$184wvh86<{+7FVbr(hzL4Nj0b{_m7Gl+jIK zQ@RJ7PEUZl>DllRy^4%A)a+%oo z2|s~tB<~1+gKZ@_giFa-+DLpXv1O=(M2(Uq;i!`&3bl~5L~SH(P%EOT=8{2#Q&AJi zWRgD@HI^(StGDZje+`P4>_*K9;v^?g1IZbbAi0WS2!bW2kyLUN+35A?D?NwoeC>yp z(G5{gT7lf@3iyHg4{o6j!8mF*EFdcy%TP27Mhf^6>cD82132)W?3sN6I)Dd2k1vBm z_#WtwZv!m80iOuAi@(7bu^1$ZS|Af0r0uhSZ-SKcoWZGDEuf)goQ+pHNtY}5H><@ zaSaS7=q%2FL&dSAHEjcTlgM>jM&LeR0GnGClxb;S2B^eho`;F64+l<-iLi zf>x+47=uQDRcIc#M%uhIbP?FlGvH6N{B2GN&^77wBrdJpoT=b>t98u~&=gJsNiZBVfI8d|-Xee1mAEnN zLF_Qx99qQ&FiUIJLP}%LWwUL_9A&5NM3JZcNN26kN?@RuqUy5li#5~ zxzAv+DI6uXfT?18I7jRO=ZgJE+dL3%CwxroMtXH^;ZssSP4tGvq7#_JA`%c!xv4J=_@F!UMp0JdR)$IElA|6Zkwh zOP=1dM2}Z-7PyYfNx6FP2xIV+=t%svFG1{b4yC1}jOt zWbiEL#H%0z>!3S03jM(;7*G0Jt-w3j739HDKo4gC8Z7|_H8HBdAgEZ)yfyL(PGQsb%mqwSlyo+u<`3n?6vd zU?z1P=1~t|1@#(MQ=efSl?x425z)4h*jB<4WTaHcOnIX^DvWR(s-+qcZi{pTCaOEC zBKzD;R6oL_Ntt29KM856iAYb)LgmzaR6{K$=@rCYi;AgrD3e-_zEVrkeQGwkOpQYu zsKID1)dqDX+KeRk;SfTZNC&T=Y`6x!g@e&;7>&+AE8Gn~!gX*DTneYaS+D{5DS&bC z6Bq-Jg26+cHRi=E+HqMw)l<8JU7@x2zi6Lf*Eh>qS8`z^6w68=QeuL;r! z-jQ@VxyD^nB+5-C(QYwb4R#P+o+hfhi(3G4Vj9TD9-tmefD+h9oHXI)pd9xH6?iNt zz)L|1iLQnC3@F79KqdYJYHD|iN>#y0lo`&TI5?e>6WzF=SyTXt zX(4Df(dI0o&6!klVz)&zs15{O(NwA%@%2TMD6)5+Xl*hz3QeI#qKVXG!jsWBqSMLL zJT#J;i$)W@cB5tzElxr4M4LgR4x)OX8q^B?Kndsu3POjF63s?D?2l?;LzGYA=1=mf z?OXU6-iKG<4Y-4R<9;$c47_7c)&qKmm^4P zGm7Xk6?B1^W5<|=RjZUlGX z7I24X@fAD>UX#E0cX$b8!mFSJJ|#MR0UYof;NTzNinPENF(3i~*cfSG2NVjsqegHH z>Hx=~zHlKLNBV6u;8wJfw2>R&F|-e!MJI@UufRL#7JQ7J!uRMse22ck43q;iQ4uUc zT3CrJ1ZHR^zDOVtQ6Pd;IC7#0qOBNYNAV<`h**?F@|zKEPGVqd zlHVRVPzpgeWJO((3H3mg#4bV|$+zU&p*JWQJwOf62^5WXAU`x8xuenKo}G{##v%h$ zqf%&wSuh8Fhi~9(cmY0w`{5n9j93%lNz%$6Anp7%7!Ef=C0tC}`-QL=OoJc61b7#W zg(rwcH;|b6H__`D5*-GB5wHyyN?N87q=gy^WrRi2g4N&=umTS!J^c}+g&Pdt;8ge= z4?RnPS;Y!z=+pNtPX&2avh*C-` zisJvGzwiJ5f1TI)yw7>xbI-l^+yibCHfQpL34d-uAPYw?7{7k&9tsiyfj}X4ka6!I z5aee&hyw%(S-X1A>Zc%P6m%qXG?0Fw>T2G>A+B{Fwh^Mh(Rz0e&19w`H-dWsA01qoDC1 z!$hz`0+?mnPx4Tnv0y9-aN~w%j{v+ayKSZ6=SYCIQ;Y)g|Jk*>-7TY&pgbq3vvmL%D6|7+&92fssS@@Gfkp zv1J=x(`F6lwB@nY%a(1p`nH+FcajXy#@TSVrndaU(Y89`H8_s0A_u)<&-l^@x!*hpsW;>Uyf(b)7Tszy$;oBJnat*IyJJWEzZPggA+yA0% z{cGcFcQM?%wwU3aCID_c@N8Z7zuMbw*jB;e++&9;$AF$4jvZddR*BKj2_R~CzU_`Cg4j5KlfcOEtH*YdVHtjP z*mh>CjIFx1`NKDC+yC$@({{??4jS$XTd&$8Z8wkvMr;-MU#u;1xcI?c3)4@0B-v8rvRh9rwRJwRN6tu5AytKD52h*iKGQc>%O&sEF`E6(aU(ed!r)+m>tDvn;!}}Yqv2FF?PPF;M z=d$&VttvKuxTpWuDdT}ZeDforQ=zk=JD?k&FQMZP4sQ_E7Wt;62wx(NB4K`&s|=+gg6B`jkB9z*FB&cnA$tDccXEwahqnl=A813 zvQ$9j{$2g6`YVvs>bKP|t5bm5 zo-cqr1^Bx9RrNDqzXI}N$V&lM+K``G{l5AQu-;UEsD20Lrvgj^@&U-(>QB|*hVXOs z|KuZJ(yPA!KOL->J|thOe**aiB&#|TFyE?ks_tIMk?A|KH= zQM%}{_@TI=roQG_-SN8P4M!RzP12?hlDCqIHgVfu@}=@5^;q>j?RKrf*lqmY`?WXK znrh|QbM1Sbd!1<>z8;C_5okKz7yrvU-@BjELwQMmMgI`+AwU#V5fsQ|GRv7I%xG3L zYa@`;tP`wTtlO+dtoy8otS78jtmmw!tY@s3tQ6J@U_Al0&3epw0PrPmJaj zth<1H3g+Gc{v%-D2KW%Lw*cN_-DKSWPn&16Zn9RhRhoJ#zcbb(~& zjk?G2&@k%OKErUcpt4g~lG1O-t13I2ujQu-vnv3^^qTd6aAr~6iW zS9s%zB%&4Di+zHAhBhIL2)MhOyAGy<-Lk)Bj~VnFT-vw1@2=^ViKpdh32MChO~;## z%hG?Pnr3ZtV?%wzrn*ga4{Pq%Y!`16H;Yv>V}aQGcu^dXco7?T38G|C;*ggh8aZSqh(-V$B^oW-BibeE5Veb5i(iX# zYO-pA>zH-c`o8+WCRS5kOIFJ#X}T2F0qJdOfr+o{401>@Zz9FLFhnq;A#Jp{%Q1g z^k=juv@?`5l>Ov=8>{Mx|bi;ubnET9-$ngl#+$yI`3xhx5O7jDxQvCj#+}4=sD4|*Q3{CquYA7 zSFl&GEc-0`*Mlzxk62Dxl6zu$wE7X>}xRh&5*nUR@#uh6MYc91M*(<5j;Nt`7|US!AhTieg^M>UxwtH zC?D~7iWkT)?|qCYO+P6YBNPywHc!5x(ZQQU4ZybeTMi= z!}A(zqonp-^WOT8l3k7PHh#0P{b*~0;*M-VCscvg6{*>#ChddX5vD2D`raV>RBNd7 zQ~PP~C(au@U&D9cZg@`eUW99)RFYtfZr@LV|M~r3UiDXm#8|}63Uj`?+by^m=V9dU-c;hXHzqDVW zx7CNNW;xw*QYP-1*P3rU+HBO>HJ;Nr*Prd&Rcldgs8K2l#dDNL#SrCeu~-o+&Q`F* z9~FM$HwvowmBLs24CpHbS^QW*5x)fZ1n{qcK332G`hjsjFiry)2<)6ikq3)|f!^o{5!bgf#jtjkm?#SuQ`^GCq0(^i>eg`aA4#})og_*; zTM{YWDTx&q1AlfaTin$eA$}xfi|4k*ilMSN@jF?fctm@wSkOLF%vg7T0$W zB;u|k9eu`?g4>4B5M#ZLk<0Kus92w4bPMH=|1A2dKxn{-AW0xQs559>;IUwye_^l# zqc_;c&x6UPdNVip(wX@_bmk=QV5TpL!3-e=GXEh2G9w59Oe5Z(*@zEdmfTnp2YkK@CU%pcptzKn4iFS7M{rbfDZv<@xWgL#&0se z;&YiV@MX-E_~*u_MBr(XaTmCuMotfl`AkMzrRi=!=eJw%Oi zaicDGZl+Yg43yKbNz|jTU(^S%wX_Zx#&42yx!+Ic8}tyDB*rtB7Dk}!4F6BAAN;4f zar~8T8U8oiSNV^DmofD4cKRESAAYkDfwTd{M9LMUJ(+}BM>>yMg%_brUQV8VD2S)R zy%IIoc{OUA{a55vYd*rQ_qfL|gTehsm#foy4_n- z{urFGQg?8xNOLWapVd|j#6Pm7fz?bnbVQi0@rR=9Eg zR(No{fPF*m!EumdITJe&oW1Q>&J~#_=S>@)Qz7-@_(;7uw_7os@vT0bfK~!0p_R-z z((1=4Z=K1RDm~9BlIl3K+jess+x&UUWc|EKSwBCy-Cua8eSe{(-KjXHLtB#Ckyt)Q zZmf(}c!?J(U)SZRo;B_6bdYY;UHB34 zTk+%KcHq~<{*8YUvjguH^EaL!y$$~|dNuw+v=@F}^d;Ot)CcUAsI!=tkp!=g5xYI_ zg{LEThjn_)31!14guHf}&zj(RiRt5_3l4MM9ee;59Ng<<3`%jT3)3UX`Pd9xk>CkU3%F*r-wsf`f7j&lZeARsJcvUhtTWRGSSJrUm zDf2nwls`Dp%53Xm3C07IUpW!V@0=i@5z3#O5M>6? zOiq+Co5N6MabQ4;75SWfiY$&*UclKX|IPW>QNWS6=W`s|d7NljK4)7SpCgcRIWwgK zPIoJxQ_)(;;kFiW)UCxFlC+4kNm|Ou1xjkG;T&l*aH`ruxeVDU?k<@fFIASpYmjZ> zn`LVR9_?wu`1Tn^7ur{rz&cvW@;b^Z-^&xl?FwxDOx3z(`%ZG3ri%@J#=q-2Y}jH% zc5m*hGGB+}SjwD=tSGn)%0v?!JqgLq56OSI<@l}hI1xAkrC~Lp+r!D&ZP9l4xp8X< zm)OBXb;1JT%S06cmUMtHE~yv4GU+9LYtm-?k)(zA14(1>r;L-Awc8TgfPEd1%%0DNH#3r~%~;Qx*;#yyK-;nE`~V^brL zm=obo(4)hwDEH7QNIvUdkJrpr_shZ4-ChTExCjCtJNpJ+hn)%d=HwRO?exrF;5gnt z)v=RN?s%QSaEf7kaLS}FfyL2T&Zqs*E;nIYJIRzpWP%PrXz<+T6-aBqrjUg^-%@wC4703QgdmqHJ zHPo8XxYP2ew#Hmry`+0v1>Cr=v`1$wB5FH?$GcVvf;waPboEN!Un)6Qt$fA(sXWEK zuH3^ttz64Jr2LD!Te+OO1K=*@V(u2@I_@6jQtoEp?*Y0^xq`c0xe3Iq8p6HG_1vw> z4cr6DE!<6jU#i^5B`bGvD-|2Kixs=MLiyiZjC>b&M#pyUsrEhGY}pR(VB3D~+O|F1 z7U_QOd7$H^2f2aLeO!w41UDM^bEU_)$ANy59_6-5PjfMCN4d#ur?@NI&T;p(J>;Hl z6L1f-;d$%Z&he7ln0&9cZ~?OIypYniuxNAJ<&uWBQRNq8>#BCPJJ($4@NMXnzim0M zd@ftA?pN;U%FzDMW^^YQ><5&l4fX=F-i2%V8`)y5!XoYZy^|b^Xsevbf!o|lS<^gf z!n=@jqZ82BI1(m=y$8E7AsXkFcnY^E@jLELVlgf~u@#pGRG6s66(`DZr2xwkJ8>n6 z8sKXHDgo+oMF9DLFHThBxB!I!|0F7KJYeU8dECS<-0#G894AqQ%Sr6O<$|#s!2bqz zCa_;5w&4x~KLNzlCbZ#}B*=03YzYp=R^pQ5n{eCXl(-YIMY!!TJ8^!|T}tSk!M}Qkn>@O5Y6_BJ=l<6?yLLLT{oE5JI^%sIa0No?RBa~NM^@W>tm_Fa=m$Z z@6UQfk4KHfm{!%Qe^8FoNlOlDZWYnHz6mYru>z`kJpYjD6OX3az>_QEdDTh=@3#`i z%T^+J=}HgYcO`=NS?LVa6Zken19azo0r(Y+e^X+4KLCDG5_p+_`=G?|UMfkv?ZEa^ zQg~k#7@m)U%sVJ2@jiEudA;qvyl|jrWE5U=n;&mU8;#c~rSq;z8N5|M1EqmHUuh7} zMe5H(Ntr{6m9lsgX&4U+e5^Er*Vh`xYiW(-eQb^5Z3jqh9m~s*Z03!ZH1L{RZt@?r zd=PAGi7edTLN0#Ua=H{HSy7Q8`B441^;m75G^;U2wzsvp{c1;xoYYBH>Ge-KiM{Kz zhX+?01|9$HzVF`A%S109ctlV@N_`JFq%nG6=HSI{Z^HI^oQRr(+8>*Wz8Jp?lg~bk zU7i5NeNQuvJjKq&P@5Gll{~>&Xqb9xuej1MQe@Fyz z-oVBsz5)0KhXFn=@fFSs*jO;n6WHj)6o7AV@Wf|B=nfD8IM>7%fO~<1fpzo=&vE$) z&v3^8dL%r-{mV|lDdL~voa2w;s$vni*)dbG=b|QK?nUU)N5T$x?g(i^&Sow|tO}}u z?+-ZV{+qGPEr7n$^#d)(WfgUjiysB+VkM(p6h3oZ>b=ulgrw=NKZ(7rcL)V;Yw>s7 zJ#p*d?=jIHM6V8y^`83>r;sg(y&e!`gu4`x@3I*|f?f3(?=TUb2)*X!YQ5?5qHi~h z)f49UkDHf=kDGPbM%3nOa@;A?-{K3-#G%LUJjLICI zNtprc-vG0D-2nTPxkK2k%;zbAoulOO_9*jsP=I?CTwaNs$HU5nyd@nx-ktUmo=V2& zCCW;9@7s!bfo-L{OlcW!nY0}AVg;|fwSxD!wVJoPwURfXwT4FnwoxMHaV7P<>j0-q z8hH-De%;c~YfTbfOJg68)i{QKr$NNWH+&Kl)b|RX);}!zR-axn zSf5z_pdq$uSK~YJ^QPx1yZb!m8+`)uRL%26#Gj12)_5gny;CCl%7{aXpw*!Au!e6+pLuj+t z;x>aEYXN8D|4LX5>@@)Y!mUnN4sb1QMZ!v8ufi<@XtS3jtiY`VadW}?$$)oGSc?13 zUXF8OlX1GZ6zsOxHq71VL9gABZD?vZ-}76@Llm2N0$Ck+6tU0$k;f={JDf&a4QEl{ z@Hu3K`yFqMyPn8^uORG!i*Zu;TwV5BO+RBFkJ6pMf zKS#NZpR3r;rzv*x*U5MCKXmNjE82JR!`lz?kIHuQ#cc=pBY}RC9^@xV5Ape}NBC=6 z5At1FPx9YM4)GUBPV*fk$M|nsPVr{~RWzUEA8kI*cWge*Khku8uWdZTpU`-b|ES>t zzoz~oA69>XPpiAbpHM60@2#NA;=iJ|5Anh%wswSPpn z>!#POX_(M-x+%5QMY6A>S^7xr*@4qvRCe^t>5>f0)O$M|>t5{2>q|kp4vMjf_T}CQ zuuC+Bt1w`y$3>Pu>P+}ybZ!&{qmS{xo{jq#dp^DbOJMh5x3CeoyKF4(Bij#`!=`|r zzX3Qdn~viHU%(E;{Q4*;HWr;j+NoJm6=reE>%Xy+#80 z`~dm_&Kvg)#QhjTA7J}}^+;fhj7w$Xap_=gDw}}&%nruAVNbz5WbeiKvUlOe#*fE! z#t$d)qQ*LolnR?^oDDxKCW$k3aQ<;xI+C~vXwUGr^r8I%2l_pr#>L;j@Fa%R1bU|@TpkPXizkuHyD45tB zEcn$FC!JmSI+h@&HbyYNCQ`6L94Xi)N)#NbUM+Z3 z^-9oGNfb`5%oNHiZWeMXQj6Lv28(A^zA8mjrIZI%J6GKi2}N6K25RrtU1sMG(bFvLjm3k#GpYef?W%I3DyIQ!PzZC z=+17!x&YrD#K8c<0Po7~#M*=YbYjoK*|Xo`?AT;HjQt%iiXTZ>7XO%VGp>TLKDM0D z6#bbXkK9UlAC4pVh34Y_X3oX`6WE8l&3KG^M4Nzn>TAKKd%wk&6J}%Ga5~I1uYH)0 zsCq99!qe-vy9XNQ`Wy8Q7KluCoaIqtx5|ApWVtKEI@kHCWr7pAm+kPpn`K8gG9W3s z04rG&)&EdEqmQgSYJS*})g3P*nS`yE3@2Iw^&^{VwZ08m8cbbgS7?o_bF(PClV9~# zJ*9HA+FTA%7nZfCewGSVIVF5mS@BO5v^ZBaw&;UUK+5w4<2v#L+uFH;$Fc%J zX&X=A*2WQxk@5tWS_=gt312{!6bcTv6blNQ3k8AAC4ys3C4$n%azS8YsbEV3SgXEL zV6Lkagx6II*3?!DuGEMGAH_9-B2kS%T3sVBRy7KotEvU4N~s{Y!YWu*o+$iOc25{r zMk`d6))cmu@`|u!UB%DKW|VF!?V0Z++&+ z(#g&-o5{PQ{vkh(*h4-WHknKd>Ge4ie9Px+0N&>d{i63nY7J=@*^87+Vi4hYH$tP= zZ`^NG2==|l60cWoQ$4>sQ;-#oop5{mZ*FYJDVKi+X2a_H0vt!0UF}m%T@Z$$)B0Mg z?2qemwp6Pkdk-mg^dxtbnyhVOjUBCZ`s$W{b!|;+wXnujno0FXyHaYoo%ou7&QGGB z>Xp@N)!|hkYGNfpjjnK16U*(@!DR!g@uhvL{Urmc_r*q)eKAD6w#cNaE$mlq0qS08 zRuu}Zs@uX|)oEd;YO63;wNtoRwMICo+#+19TqFFY*eL9huN4N#HwedeY!W z>JA7MwFiZW+P%Vvnv=p+;{SwaM4yF%>P{i4dPd>HDpBFcsw+jfs`bT~s%0gKRR>Ei zR(&mlRXbL^t3FYAMC4F?2>kBpY0dGP!P<>=SL#nSEN)D1THWj~c`A7+#kDPJ|JLrJ z_*+q_@>AdHs_UAeTdPwW1cn*iBGW$ezddn%zs(OV2Yc`IKkXeo@K^8WflM>Zs_5Bc zwRR&1L%U6b=S=ZXhAGERZQSM1Vk~x?Z}ft34Qyv;!(x}|`bDlsbraowXyNWM%?Ec+ zjW>K^*Esl&&Pe!c^>6ng)eraoRM*@ms4loisE)W3RQudLR6E>ZstxY_%JuFRRVUaZ{dj#v4?RjR`tJ33Dzvotf%GQARO>YhSU zSoTo3(CPj=oPV>*5U-;O!Qc6r6yGuVfxeR?BI0M3$0O%W9=T}YlyTU_MH6Q)ZkW7d zQPq^L1wm5>=ebQSoAYSO)>*2_CDTolT&Gq|BurW}!EJo*IO%B4n9m~~jM|+zam1MT z&P4l|yKH$xVjL&b63u0Pi7XAg6s}~<3+2%u6tXa)ii`vwjp#twKP!v<=Q^nvFn*MYsB>i!7y^?n}O zt3SkRm1T|BzP=S+b9%kKv_1c#M|6MkWE(f5s&qMszOHld*D9fFb;lvte(AsVx0?*s zfZAKVV=FHjpv67v8(h7No?G9f&!`iR`?jEb^2hasBhq$rL*A^;4}G=ccfiZFIhRsu zvc{%d&m^QA$#6>9{?qc}*blpuYv0W;o~OH{{P_k=sr`ybv3x&kO6v?~f6t{QdQWDc9rtD3fo$}@F{1oe(#VK>%tWU{&eKckC>vt)# zSM4cZUQK!V=2hm)%2$V9O@7UJz4lGn+gYg}-{IdM|0Me~H9aLAk+m&LoEMURQ6LlG zEB>ySTmP{>Qg&XpO!HNf+Y9Y$w6}NI0bc{hVzV)iz^@Pb{kXJgLHh$pq1TybBmKfY z$1aMzn1GETjW`%LdGr*v$GF!C(`BO2?8_dxXn)*^1rK8K=Lw^N=SD|% z%~povXOqG|%t{UWJnLOp&n$D;KeJDUN6r}$p_$_n`D$)kRrhM2mwy*)OQhB7ilVBNg3A?m zd6@DQoEN2&3)Ym($qO$&`8%+vI47_FNNcZ7S z{zl+$`|80re%Z&@e3>b@^;IBj`erHW`QBPuoN=#mPmXI%bzWklf{T*gD%z&_Sut80 zQaimTyLpC{*sgHsQ&qX@v=0!CMh5y=PZFlz?1(Ms)nVfL4q*27rF%W?t44qBYxMln zSBEOslNL)T)MquroS*R0kZ)f8&) zY944Untbg8ZM<%yu0=Oq|6M=P@X`=(yk|@XpO^9NKHlxvv$*G158k}Q{MF1elY7nP zS-qX+alN<9U1nX+WHY2^K~JU$)6F(sF&@(A=^uj6*nH~x(j`{kQAernD8&k~+$!JN zaa+E+og*)k?NU6FT~=nws#P5_Y^PkdqpMfeuF=c3=(=T&2CeLiQ7_xkt&lOzN}0L0 zUG~$`EZaUHm5~OkWN#qNGMrtxY_WZlY^_6wEXEPip5w@DcW_$Q9_p0dKEesrG1ci< z$7CmS$1JB4^2ttKib+mC6=R*2DaSa`RB=uXsx3}EYB+3vSCsQdt%vJn!xi_qo;pOT zr5W7^o^P79#x94L@$b`gUi&{V5raFxzEhPp zr(G+_N?TF;>=AvoE|Gl~et$ zH7Dx*&R;Lz<9JUkC+h-zITLKZ*SH*|!Vt=lv;t$NRVHNl9<* zLQ#ElW>ZZ2_l^p+qwbO6Lf^VRxxE9l%smn&_xkGILE3?(nrWsJ6+iR1 zuX?)C=kB!A-jkv zOnm7hL$>6aF2DJ#M%s9y)4O4XYF1sC;&e?{`+L!swu-9Tt)_~nEtK;9rs<_u8viT4 z&>$}SQO_2#>)-P`>PGMcb*&tJ-OE3cx`PGw_3QGP^(*qG)UU{$TfhAG`1-BCNcH=2 zit8$~)9PMiXV-OSN7id{APskaPj58lxilj=6D7_3dg-EKe*2aRmBK2X+^K5hXkFVD z82ywLJ)Ih=#n;q3u%b5va=HI5bf?wDZt7q9=muGCMMBmM5FuOp zy&=afevoT@49NT5U`Umj2^r{#fv|fbAp5%$AzV`;gk%~CIboa#(HX`;wi#wX%=#&i zYx?<+1pRD?O1A>?O&11PsCzy5N}FMQqB%A&zst41PJO0tk;*Q*OQe%B3jFVLm+YP50v3$@d&uQZ~;;;!!y zZf6xFRXqu^Sv7Bvt|VI<Iv$$P^7kf)BG1&TC@>8w%S;|>j)~P-Vw%yFZrY_eY`UuTGQH59Fh10m z7>*b`3@qak{a3IXvvGtDZ<2w}r{-$E8?&@aj7?gT0jIlf*sPmj;OOuMrrxT*t5|tdrmnYxWZo(a+x_kQXDoVrYo``_DXbJ?Dc3(%!jCL z(IJt~B3Fms311d^Iy8Z`ljR=#I=CSK74)7V3HZm)G2j68j{h#-YyKB}wEka6=>dI& z!od0X=-?`BC36$zMu?BsvM`-zb+`m&iqIgBMG}ygBiAB4BRL+y5p0hiVN2k7A>r;@ znH8?Zf$LoC{c+B8zdomEN|4iHpYM)mh|e7bxB*8J=DE{h&lH#xQRU2r(_OE-?shAH zJ$A2km<{JZ!Jopc8SYtq-fr)@uR2fB$2eZ3NCYVrOi zUh`?$Iyt-(t}_{T_O|xVf}VDm=)BY|*dqv)=J^!UjuGLvB{R8!$e+HEl^o|N=Wl$G}rBZt%zfl#jpQ*6K z4C?HW9O~_{)zn`T)zte_;WW>gQMA6(Z=Ye1AtZX`TW{kgenjxTfN=uM@QVTO@LP^NQai_w<$7F?nAGsxhl)NNj zX2ON=6>*HP*yu$erQu;rpO9aH;X$tcwR8n-EM=|lR? zisMySEfnL>VbwwA_7knaeJ?D*<{7=yxTEX4a(V*w-A*3KHMX2p0MLbgVA<{-ZKAeNu(!TVL6xZ{pHj-+D^m z>FZ09zE3E@|4c2pk@=*wAZL8}#k{+f{hU;hRJf*YeA(|NdG#&nm-<}!Uy`QIpY7lD zCso?+Wttg%G5UM`WrmLfr;VipwZ?k`-A2X$)byyo&j{;>n2uTcja_|CroDY6Q(x~Y z)7@UFiQW68TWQYd`DAwO-D(!}%`j*8v&^VLAM;}<$-KeA+q@LUG%s_FF>i!VHBUh< zGpjw%nu9UrW)*g6uL>vYh2p36ZN)w5n~#Oi~ohGpjftj}!u$9$*{*5lZF z)AY8-(YU7jxPF{TubpqasJUtw*X3#$-}y~{P5n?GqE6G})e8Mcb)4am`kq0d<{6SZ zrG{IbIzvyV$*`hp(7^4I8d#cFhTEDrgG%#OKS}GNKd+sy%h!I_O0)=VhxV$bO6#e4 zqRs4@t=-xs)5_B`J2{<3bxNm)`ebLQYIf&BrFZ9ZMWxzJaajFIj!h8$wCmL8io>2nMOWCzUkfNttZ|f{YAJ!G~+~sN7y@r^_Vom1g{aqiRcj0 zU!MPYKSWI?Ymjp(E0OPMU5H4=YlJx9En;V|5s}ZjhWs9S8PyW@(o+|98$A%Z*~>Eo zj=3FtAM+r<1v{1gH&#ITh(-GpW9JbrW4B`@m>a0aUJu||p6^|7$P`D3`%CC3m&*ei z9nbczf^IS;4y@F<^v>(7G_FykYA?#JsGB9v+WhKQN*rtan&8z*^%E;T)No4= zif$IatI98ou3RbfshBTVQvRBsTjs}KR94UHE`7oKTzZYSr}PjHQ@V}!xa2RMeaQsg z{9=FJy&@I2q3|J>SQyRyOZbfQMPT~lEWrKQ#wQk(@DzD$-hrIfdw~ZP^&8#dbso12XCZ_Tib#ivIG;5ni%$>f6nUI?A^E(wiTueM>D%J% z>x=LS_nqOB$X*o%jkS+>8M!TVQrK%|9rJDAp}_wbo{X8aT&k<@ zQF0?`H0crEf?JJw>E-G<50&Ww^Vs25<{Iam0i!!UbBMBg2t6=($7<;RX?fMxZ@zC{ z(fz8s*&s5W(s>%DYS!sSb$-??Q7Jl~Dqw0CIYoJ`Jy;$m8`G|rZfMJDebRbG($liF zWnJ^cW>X`f>3)N}VQzg&J*{q5U3ZPTrdGU5{1bey=yElyYH8Js3Pk0&vYc{s$(*v% zLTSl9!J6U#UU{MHkFPKkwr4F!(tq` zXMtIJEI8}={wV8`fpONo)?-%jV43w_=<>mf_7un;M>=%2^By}pHzx-*T<)kqqMWuGyQJI8{K~kn+s{yMY}VZ{G-V%T3T%sf@1C>h@TE$oSQ$=sbRK=W* zI{Cf!RdR!@wqt~BWXIjMm+f6r`}SGVjk1E)%C=Fh)7nH5k@T44hIFCij`WbkC{;?n zwQ*V%vO($9jx5=8MN3DtdcQJObGDPG$LgxPS*G=t@4YJ_>DF{dR|hY*O)i^|zdcT4 zYS0P9EBLwOH19Xm0bh&XT-pf6HNOPLZNJ0xV%iM9RBAVM66FA;nr!d8*yplOJIU93 zKe3D$NH|Ssz^%jo!cM_G$1K8r_1cdqL8p6pp~+r5J$YzP&mU+dY5?u#dCTjV=S55+ zx)!_G>lpqg<{INpQUptjDQh-q#y=ka_~a`)4^~3e+AL}4FM17 zQH&&7Dz%CH!pDg;neYRwGQrax`2s$|ZP59I(_)7_Xy%|V=%}0Kitb3`W4)91Mwg44 ztDGwz-Jx!SwiQUQ64&PAO_v)cHXN>7QkPvLu9+^rDUJu<)L2uE6xCIwS0AW4TJ2Z0 zu{yJIMs-Xjqxx}$ph{OhwrWiIwaN=+c@^T);_{%<%Ca*hze|T&Nev{;{CepK>F##-N70UZ=oP!a74tCzkz>_EWz$eF># zF^fV7?DX(cNv5dNBWq(DMu)H`jjc`iHdd7AJGMV@@93q8w2=+$sH8h_viQnqcFgC9 zwD++!OXYK$=#OjPsTkaq5*2WrhBe$(2UVJcC~0Q>Umub z%0jiaBS=*#yR7&w9qf1`+1viC*;V$T@sm_ozpd3&J5~}^!)!Sz@@tk>QJQ8{vKoua z0~+R+`P9owV09;p8)~pc&%~dE%S1_n{;De8qsr~vpb8x4b(yfhz4S%?$>PU(*22cz zPr{|ScLYJXHT;RWhxnPf_xN}7Vg-`?ZNij4@kQ<2>m_dmd&*5kNIKqSyVkVw1lkj-|V zAQ$bPLSEXvfaKUcfm8ubX~%&$**8JL?Ry|c?Xgg)eJJ#>!+hun$IZ|rr(4i%urJVd zXFI!Fu50biy1Uqa@DSO1pmYxR(W9NlV?mE(TcJG)qiD}yBH_kOn3 zrSF>MO;1GcMUziYwqb!ON#9^V=(6?x+8W(u%?uq&W72wP+O!CbQ9DKxraP!PpyO!D zb!v@4=cH}Wp|wYJbgf()uBB*4fOp$5+K4W?me48D$W>c49A!h-c|}y$3iz-uPB} zv(XXg`quZ2)sp(gb&`N4AIYUAq{OW`S@NNoCpp*hwDpZdBlVEJkTtfIcl5U(Qr=WN z=)9~B(^)k>Cb3~dFTz|saHM~`oeLBOd*yi1&EHjlIP1}lKIyp!hr})*>hSx#JxD1& zR`9)04W3P?#QEb3uuL2u6OV26T8D}7dg}EO-Hl#>UWT5E zZuR^Jy~T479pG8*Rg98i(ol18hf&@5ohU8wJPPge6Sd0M*Yh1U(^Knr22Jq4?PVX> zf_WFT9oH2cMEK17K-|l$B#jKd?oA17@?Ob!?%hL`lLE-si3Y+q{7Fm-EKU_1lW(*7XSw)t(bPsA2M-i5s~oqGz0Y)tCO< zs5(<{s`73A_6m94((>7P6Uv%%LrSmadX}us9Vl9nt10{^cR*N?OBK$_+buBUnfcuO zKm59aMm~+ROu*re6sGZC6+#P76{i(jN`+dvK3846R?xKR^ePQk@$6(ulN*<6CnpP zjZlfXL}T26hc48Jk3#g-xVy#s24i73&!E z6`R47VlRb~a0esy;&w!9aP#9H;YkSx3D1%q5vxZSN&k&{>?0b@@=X|XoKiP>AN9p3 z1}%TYURre0X&Re7lU5j0N%e{hq=tw3Q}DrBvaA1WA3b$F$?St9P>7qchp_o*I2wy; zLhSOWaW8ipbV+uZ2@^UMIh=4fV7JU}CS*NiuJwWSazAuH)py3Szjs6*!E7?$?5+SG zb5HH|Fg!Fl=^h%zU2hCm)us9frJcU4W2SDKEKQ4)GPL}bH=2u06E*7_=b2=N2|-vJ(a9%_d0q2&-qy9~$#yZexLcGn?3_7@=8_SYdN93DWnI{tuM zcPfUoz|@e6&3HwM%bJ_Z_#SPI>ZItZ;t--b@Zeufs|i=fdYE%bsh%?_LB;~k&T>m4W3Nlw%KkWL(Gy5o0Ws$+!DdWR*%i}n$?mv(CO7w8!z z2jU0k43@YEt&g2P4m_|w(l3UPEc31RdTITR<}rP5y1$r@nGW~dHQwsB8Z4%Jh8L!z zhFhkyhEJw!!vOe-_q^_{#*5v5jK{j|Oy1p0(|Xe+({AG;(?r8I6GXq?bW?lLMAF zOP>B!OTO-A%Tw*$mb02qEz7zJTc&glwnVGxl6cij$xP*W$#F%Aq)yIkogshL>LMR4 zm3KhfyyfP$>vG@r)rw0USCr8TlA5K$b#3k3tNnjS`s#qFviI*3wb!*avLu(#n~!@7l!58D~` zBJ@>g`A{WfeMrra$dEs+_pG-p`>f%Xi`EsvB!ms#9I_*5NN9tg8DS3dBY4BnCvvIT zTx66vC%TjQMX^@q+r{gccbBYV?p?Zy*;b~qIlgQ;bLDbz=CkD*n^Ve-F(;KfYi?SO z54up+6m&55rny)dgV|LQn|c?&Y-mvQ58++pF)k!5lC5c(No$(CxCTEOHKi_XyuMg{ zEe9!M0^6k4UMfy^4e}R2=J|f%I`^miP0r4FZ|zD>BO8@wZ`P*< zCHG7n@ve7j-uo-5S3ZvTdgt@(ZxN}!?-#$N{5bj}KI2h7F3j!YnINo+%UYle$CR zQr_aAUCa^8CqpG>0UyDPVxQ3|v=Y6D6G;g)2p`vmpjzrEeUCgt%N5tFn*WHB>3u36 za@(apoTa4?wxMFLf)jyXxm;jc_5^>~%p6}{#uVR&pB7(c+GTI)@6)|YzSi{$sS(~& zU+kWVpEEt(KYjG{`1si~;X{h&@cS>Gym#L`ZQi~0TuI*GX_Q>d^W^PJ_qew^UBPd6 zI-kFpEi3-Z_UzWFM|1XmbL7_ku_0f`7+J_=F0?nydE{K0pWw-`o%S_!l^5rG zXUa)|&FWbB4?R_#4f-<%_NA(Vi<43~m!zYe^b{J*j6#jrhNue1qpp00zCw7T`wbWL z1*WTd{h-r2Yq_nvtdDe8=np**?$ra4K`6UOd32^|bJRAbC)!ke3ffX)DXLQPAlhE? z5_(_qGqRS-L$yi;<58t*;}xaKq|?L!CRNimrdeq3+bcCeP5o4R3Vd znD4cJsDG^A=6Cug2DV!lV3!V za}%UrISnK!yS-F3dw{eqYmCHa&63V%u8<~VZj-ua9+Ns`UY7c1K9ioXQjW`-E_cYx;c4y6@|1N)`x<(e`xp3Iiz#9Sxrfq9eXlLj z|HN-`A+5|z<|cEmge?MNnr4*DnrT}w8O zktH+vdL`5O@+E)ppG&0it3WE2_{t|2|H@A-p2C+a{+a&}bBOO7qjIB)*;&5mpG?&v zYe-JSK-4BoQ~O)j$c=+SMa6KI8ajCUR^a5~55?{U@1v$}uhGh zSnQmYR@+(hyVLRf>ov!o)FqB}DI*+vzBF-s{an*g^>b;*#ZP4%?Lds5syV)YZ0dOV zv4`W$$1#qykEg}zeFB(W%g+f2F{-Z9n9m$*B@ z<%Ew`-Y_q8mEnEZ2SaoOHg=1QHXezpZe*kD8P^nTV=Ncb*_c**knwQI;l_ETCmVal z&N9Z8TWKsTzuvesZjUig@qn>tIgk*VS`@>O^fu3|N* z@s&*O__`)ne4Oce{4rx>{4;}4dAcyA;xle`g*Qyua@)y-GM&)2l5TZn%td)-^bT=E zAu-sGjF<(>r%%!!>sdPdv5Qjh<0-gm(>|?Axy&@b6XaflYE{X|y;@ zZsqT!uwGVu<7%OaQ$1uKi>Fy;oVRlJMQ`ogmA)DIi~Pxj7Xv*VL~^+P zl#{%6B{9%nb4zdZ&8h)=^-xli+$JGR2;IYKB!zoN%)&pUwV@4JW+WuTbPKl+nvb6Z zx5bIpBKUWR3r!D8MsoOV^mpVDbTjHG`dVZ=x)XgA4K8{ZT`77EDMcTmxMJT>VzDeV zsTjpui<$AcVwG@mv6?u)SXUepGaOfr>4|H^IM9<~;RvQ(Y4@XBs-=pIlq*Cw5wpT1 z-{g>kp7h{;uEyp#$5}%STRDDO!Fwh&|0rSduA`y3!FtKu&1$FII?C7FOzBzPcF|DK zGmunh@%OQR^)_=J_0)GScE@{1x?H~2&c%Uxj_YDY`w^+SEmCe;I9?u809k2r zqkpXS z?)kCX`{~CeZ`q%}y`z6d`tJYi?~6%4>RXtu`m)m#VW*T!{-+rcfx5ru1up#h9jN@f zhj`-mbFoHdOX&*O&BUzQvOjB)d?9{HEZ$RNHnzx@SKj z&2V0kdbmZYw|9WN+Aqqf;!Pz{Ij81pueEKMMg1Z7Rg^zYz8HLTvAGOOEv2|#AwRf* zVa@okhx{9pbGQ)e2<95v&(U4B4!EW5msZ2JQu)(XS4y>^z&87L?@ULUd%IJ2K65p4#CZ1G zMtZ{v@A@w1Oa38w<;5DgrKRFIcBw@6M7d?wWqEeyZTZ#jD{`IRyX5n~7RwEO{V6AB z^pGcJw2-4R8q1&3Tgpl4iSmr}iE_X6EplS|Be`$7Bu`Fns%%JKq&!Z4r})xKt1U9- zs4FsFs%aTjwA#NGXsdty*1W$O>Ro>y(4YM_qq>>X(cMfx>YCLH=Vk512eL2W;W_7U zgWQ$4R$d3(INyNB72HIZ3KyZ$_C$2n@dp~<>WZp(7NX+56jUS71$UPUagy>6`Kq<1 zaX6ojr^}cm*3BH`Yq8S}HCTg5WyY9qGUtM(GS1)xriwL-_6|8i=Y)==E5hRGY}SL7QmRb(-K7WE#Lj7ru^M=sDFg%>Kd!-~tjL#l}bEV2F;K~dfk zrcgIERB&cG~@$=mNvd?IX4A=_?ia!cxN#6@c$o9gb3Ts=e zl(Icj8r$-fo;I^O&K9H2v(;8t*gC2EY=5g~Y}?d#wr8r}#%po*cG?j84(*`5P%E%^ z)SEhv>Hjz)klir_wR2{nlg_r->biudxQdYvU&nnrWi%=@^u!OysJmhW7S^)>f9WCNEJ+Lx;tR+PIK=3(Q)KeDUCZ?WIQ zFSFK&y=;Yu9c*O8ayB=7275MqGCM1LFxxzQ7#kAam(309&)y5`&F&BD!>$NRWXD0h ze^__6Q&> z$tbK26{hEJ z$?s6mAupq#QSQ0Io;ka0N3)OEE!o!{hq6+g?XxKOqVXPIW>;@c=6IhkbBdp4jSW=F zsx5ZNN){((wUzc{O_c6tO_$tRW2NZq&QhoBrqasnTGFHJ1SveHnKU?OpmZl^krbVK zNm`!kmt48c01z|<`=9`|1OllC=S!s+TLho?9KE`_Dgyn zM-`+xE}_%TmiTYicU;@OmK5>Spa$<`E5x|jsxcY}T-IgY6L_Mvi9du#E6Ezv*N zw%J?5Mm;rcNv?sme$G?2CXQJ9ANEW3;kE&eErpewKMRPfZh`7LoUge{=SO)@<|X(V z<@NG^$ej|Hm%BhLn>$nbnbS(%n&Xv63aFRRDEw=a}=3>9Bt1x;UWdo@vefmxLjdva-eV{scN&6 zv$l4$p8W!SY_~Ao9E+F&hn-pPoXpm7Nv!1B#NBhp@+UpJ_}yM7f5lfx_~vgdR1iA} zYo%5~kdh#rQcDN}^&p`lmU&Da{0}CNzr&^R8-&k%U*mP&V_M0N2&&5;4t~V#uyo<3 zT65U)A#>RCA(h!8p&yySp*xvPq5YT#p%s~|P#ZOe-KSN;*3+(G!{}dOwdlIAV0tJl zliUw`Og@AiCC;!_1clEe5#fVK+3=pEc6e*jIJ^l-46jeRgcDLdd>4Km7C=?PLQtnr zRjUzlR?V=qQ@R9SmFAnviL;H%{EY>N*UA3n`G@MRD)^i;Romn^s;sqdksjGD1xngD z|9^!Wy`u|zdJ+qJx(61nbnPf~Ic>xfdq)m5$K`l@zzHP)uNwrK}l z+1fW(Q@xaXmp;KA&|kR6q8gqT=zym^F5$h1cX$&>dEX&&!WT{J`q$FOev!5djAXt9 zo-)0~nrxc5jvXQe*i0#r8!JEN{Bk_MN;$$;QcDXj)RV$LT4O^i{h6U0>TQ(JC8Gzc z#zGQl(x}x`oGmc^!Cf@Y;zt<&6+(<2!%0IWQ%l1z^EY8_&}d;7OoG~AnZ$Ru7IL}P z_FTP?tL&JNn(VNU2TaG1DNNCj1SZ=W%3QOGbdgo1Bdvs~Wes77vdP=9G0saXv+#mfIBr!$%2Mlvc;3AufD)g9j9axYI2v9{aoYvc-ehC9o;FFBH& zH5@e@ukA+rc6%|~Tzl`r4ff=M^Y+mNioHrfqJuAZ>YxQ}olLyLSIvT|?ydzc z_k@DWo}_|B-YW%td>I85{iKi$R4M!v=v;VAoLe|eI#gIkPAx2y&9?PQqAglYvMpB~ zwwG!m*vEZ5FCZfOb5VEwtXr{3RnN>^PJZFdhuO+2^IXHPLa+dBmZ`#$3n zzA6OpB+vc7Nw+|AnibebCy1CaNh6rU(tDVTSo(Ny4~r zEJQ|(;AckM<^GFk%q2(MV82K7W-}uM_IJcf=6A$iCOu*e^DSZ;lNvFL`4BOkc^5I8 zc^ixf`*WxfijAxfyYcxfF4MxfpSmIUDhmIT7)hITDe<9FF+FER5LCG>@pu zJPO}WgTp@%HY^Qa2)TnIt*i9r!3kOo^G_w%xI%u;SCy8s&Olpw-XDQ?_^`gh%d7i5 z_2ftHHKNtc2d29&`rOWi-X!OIPYdT3m>vDer8=s+T#f@y;;iB{;8o!q@m=9u>1W|w z8QW$kHEqMyNw&t?Lt8*AZQr1;wMQVqu@bFvXeh)v5ub8?#|>SbNs8+Vnd~l4gFS2L zeorB-;qAcO@E&IV@CBHAz7A{?e-eAi|BI~}sL7oREac+EWbU$9nQtyF<})N0zgF%g zv{XI_A!?$*rRErZYO{=my4l3x8Kzp~qiHH-&9|A-&{5Ppk{3;9g@-2DFxgbf6lQ8< z-f1io6m9$+G{Z19I7N6E948>lGCtno;(A&Jax*MWcB^GNd(l#nePemb%iffj?k!z8!!1>U7+F9AV*?HHq+&ROu&DqWKpR>8=x3i5W*45uL!Zp)#(Y49L zy3cq9xu1CMyMK7fc?vzdJlJdYGTtrTAaAtK;{DGTG(Hnm7DnN@!Vmmd7)GKEIb@_^ z3cYEdjK#R08EA9(msh|0Y zF~eNV*dS<;VNTFfVM~zA?+dEPFAf^bO$$20b`7$yO@bCOWrNI&HRw8Jg8rgTb6e^% zm!rSTC25Yi2>oV`gL)16$=r&5H+QEW%|q#D^LYB!JPG<1&}Zh^^p$xWJ!o!1JDBsy z4bx=u+n9n=4MBLdPy-d=tLlHU#kI3kR^Hl*Egb-nYoaJBUhcHQ$Ya&<-#CHu~yss7H`5_pd<1sai_;$9+&Ua~`KN2|(v z=yN%nc2{aKUzFL*5cM|mQPr95S~K>cHjk~V-(=708e17P=8m9cTwVN%y9ZJE5Hg7u z=yU!ittu>HwhLWZiy@v{VTj-@MpoErM21o(zhRxpYs@fZo5Ib{%@xe2f=uQi!Ko&b zWv*$RCCKErOfhz`zA-Gdh8T`n+X*+U%lTW@SKLEu1@5kO9s9t_v)8OUn7h{c%zsuF zy=uKo&so>gf2~vLDeEwL*gB9NwGN^Ctb^%p>o~g8`WM}3ok{0fXVcEsk+jfKi;lG9 zlKsK6$*G`1yvhu_-V%n79O4EF)g zY4;V+a$sLqcfO~loAnyp^}H_EXm7IXu=k-W-+SKG*mu@-z<1sixaPIC8_(%lJiH%}4eipQ!p^djxDSJgWB-1;Y98k+3CkGa4KvM*4V))!yU2Vxs$ zpmde_CY4}E$TQhA`8C^1iQyh7gSqPJQErF&jg!=3{3xv*|43WLC+JuBeY%~GLKTFK zXt)rAj|wNSLugGJ81l$g!#3(P^k8}$gW3DWPi!4i5_bYJXOZS;VVwDuu-81raM{cn zkD1pQXPR|mym^x8s_Bubfhp9y#n{oDW0-8NV@NVD5>A-E^3Ti-_z&j8oZVcUQ_P3i z;GhIHCg>wm5x7||s2-IsBHd3wwl+I;^tap zoaqYQYOI0x7-piG!Xv#UpRE$S>>MpAWSsA zE-mzBibh{!@v!$;V6eAtpq%%s-{RfvN8X8kv$vbSq_>T~xwol*Jd``VUHxyo1N^FY zoWHhjx_^Xkk$#ycN4ey#R`*-=D_`mqS`ilp={t1C%f!BdHfx6<7 zz$Ni^$JOBlp&w(U}(k7FdX8J84#ao7|BN%@9_PNWrZZ;9N~*GStw~LZfI>9Xc%GI zW$0~sYiM9%jrqnn;|60lV~}yIah72g+_lsgEzC6z;pZApag&V-JI*)+*pV4- zOr`yeb7?mX0Jfvh*IB5{V90FU$~MU?r-;!~MX|oPCNMR?2VVHs z`xE?){C9nMzJ9)^zHr|W-)Apy$9vMZ+k4x$)|=_u;0^L`_BQh$^3L#I@t*WQ_5Skz z^cD&Dyd49WKXtjbd}qakdjKWN+dUTrtv~TR>)VsbnYDklyB!=x@$PbuN*q!rx}v@-gf@egnIY z53nEj37k>*#WfZN@r#6a{5_$wAQ&DA-3$qa{f46kr-2%q14f&TSB+nd!6u7ofT@h> zFnBV*O`@^5`I51{xrcF@`HNwVxvgQJ`LJ-vjD%z69{efu8SXH6K*!8;*u&;rX0Le~ zbI?qfB=d2)*4&FuG)K`+<}4Csen8%v4v|Hs6(qzonrt^VBZ`41Jq&m8dSNua%FE~l zHwS%Y3-$L*cl|Lvqg^G6dJ=b3ccU%JPCY~3t<{h(s;i|pic=Jn0b)xzJFs7x7|_L% zfkomozZTf%KO7kCZx|Tlm;J5%7yVuR^ZY&iz5S#8asFlgaQ}9{-FM5M;rrx&;q&|N z`62>WeKo<7b`MlZ47+${Ts;leGUZqu~@}lPaNT&B5w2F7JvG~q{@Nm(vm=) zloj|>?j(BU+u|0bwp2$wB{|ia@=@)SJYKJ%)JEqO7FShY;#2B&5~n57U7DE*(l0V| z^|tI!{WaST)#nbPRUE+|xW1U>|HX}X4fo@FkX8Iaa)fu2$9!9w&F`dGaME%@JEom* zkeMhbOp-8=eIZ-~PKI%{4P&`6hI`y8LkOP(e5`6b!;d$r{3T;s!D;+QC~x{8G&RK- zT9|qms+iUpMB{bCX=A#fi;*$DHIy`VH&is<7Frmq3vG-$`9xzdKiIg48(_p-f8%nt zwK1HHGoE2&(AG~43Y}-TM5`Lc&}Tvknkc*_$^2Z>h%ZLAaOWVS*AU0DXVD<03|dEL z>sQDZEghH91UyZxgKjCKbhC0)8zL8~*Q6F|taMcQM=Yv@i+ki_f$DOnz&nWzESHk~ zO{G)*2x+_j7d-J-;(q^C@uL5v_{D!hgjo|}eBg{YIB-E+AGj+%3A_;ffuCYU(IE~L zEz)waoODHOFMSusLi%H~R8zVx^^_daDyf`&SsE$J(n-0t9FSMZU6c&@gwj+AR<9~E z)Jp14^@`e0Ypy-kernD2`T8Zj0*XhU(O$G1N8;LKAt-~4(5 z7RDJugt~@UAy=p-tQG1B#e{~!UcRYNoUbpe=V}Q8S4^14axhB1@=KZXd=UIKXJ}0r zN$H$SR&&QmIc_w$!bXt>>{on~S%>48Kk!y+LvEPY)`3(;2k)2R znE^+@8ORT?;xFha2(%Ynf$1VEo)C+QU&WeYxYS*2BmE^Vm3D|%q+6m>$`#AVMWsG+ z2Wh#yK)NAcm-1w{R8nao_fzJ`+mzSxXQhM^r_NNStM8R}YJD|9+o|r*jG9rOq|MW_ zG{4?SpN^jDkV8U?@gbyR3tmg6VGGT~>u3`a%A6z%7=>ueK-!x>vg9^7VT zCHIv%&qcGZxdH4iZX4_5KCnD*;;cOEfWS}X68Pg>EB*^NkmvYGe0BaGz8`;*pT|Gv zkHLv44|$8=Ky!@qXnrC>G`3Pla9A;wVFz#Hlq(uEF&qe2fu zU!jjd|39Q#7)tR~3`aTEP=Wg)9Agg(@$4w!3{ygA$h_uX(wY2V8qJI3KW-;!!__D6 z*i_t`U4TC@F}MqJ7hR)0VLrEAUr%6lIu6nMs;#~2q zm;`c3d@rT~f-3Zvm1MD-WR+$}Rir~wTj{0rm*kT+N@e70Qd>D&nk`%9BXU>yle|C< zRi4Ui6kge^bW@U*!%8L9sVr2xsNdBiYAcP^E^A}8a{43fkRGp>Kn_%`_)x1{xDOK zf6g@J6{a&^iXF_iWhe9F*#-Ps;O8awDF2Fm%sbgnyoK}gRXK~$gG&&maGiv0+(h9P zw?X*Eoe>ECRw&Qs34idMVFX{qFo%yYY~aHU2Y9Ejn}04G;@1o7`BuU#-o^Lj*Tb}k zO1#3|;O=wnxrJN`+lU*&=CgKYA3K|A#j=cz*+4fkC1^F~1bI%Y!|Kf2*iV|`1>_Yf zLRzEk_>CTiJLnhCJFO1ttUc5}s$KM6>JKeLnW>Faf;FO?S9i&M)y6WTI;4BbK53RR zQfi}Ak|GpVa>(i8TRB<0D&G_Tm7j?F&Y#LedgZUrC0 z?cyW21AI7l0`NY_6K*q~4=WKqu^ssHY&5@|P3HQtE4WxTp8L(bWlu6A*};s;#4u}_ z_cVrCMvv2mv_8!u_sA~Nn=~gsumexUTQP;R$F`!Mr~+Du?&z^7QNN?xwc+|IP1P!D z$6#-fX4-hwrbes(sE?H<>U71U)KE?;`SMuhl3ZO`Aj@*1{9djkpOr)8B-sbEtn;NA z@=s}+oG#6k^Q2X>N7^O_$yel9`K8=S_R1rGP3z?5%75}G<(Ir!u__OhKa>JxqEcKv zqI6KdDAQDvdP;4fzEkI@X6>q4U-PO{wYu6VZ8q#Qa969KTl8`IK>fUaT9?Y9j^a|{%q|!f_x`5nN<_U9xVcBm? zLzZVJur=5{Y&Z5XI|D}jI#%G0vvJ%Fwhs4(ZOeUQdvOJ9AI`-N<5)N`iRb?2qPQ7c zabQY3w~9;Pws6h4Bfy-0xjx)2ZXox98_j*<#&EgZIL^)u=M=6V$Mfwufv?H2d=%&5 z+-y4clD*9BV%KwjvYojE*35~_9riXef}O)~Y$N6X{H=9hzVKr@mG*{n;L=DY`J3z} zUfdNdJ0(VZ5htOcxID7r%lc*1Ss#QlH4ZJ+&gijPPyLOmYtz&tTAbPwILK++l`HBX zus~&%>Z)DVlt=PyWskfUaGaVe7e=1AW4ayPqk@8G+D1~ag8mbLc>uLMc zk=hq^y;e%QuMO24+G(x2?$<`>t@UI2c0E_m)+?i?Xa?Gd?gENtK(RNVcn}xhTwIUT z2Nb81ujC;qLlrWCHU<=DP(M9En=;?&G{(SOWvVgxOiw13oy2ryH!_RaBg}F37QCZ< z#yHqC#=_+=6*v!5kJFj1oB%k6u|v6{z|(Rd@$3?=HoJ;z%x>mdvIn^~>~XF=dkxCF zAaA&O>}Re9n*sLK&T$~QjLgCJaz~h7+#Kc$*N6F+E6M!BX|y+Yo0i~q(=Xs-t!8V| z1QyZv%nLG!*+F<_G)baWNi0?IS#lfKC+qPYI9;#<4#OYNOEeg*MK-++TCB4uM!&0H z)@JL2wFWxYyug8L+Gus2Rvy-g<|v`s1?4xa$hoQZQnsn_$|5yH84Y+2RDa98)R%Hk z^^rV8y(*7UugiY9qa#+Fu{7PS+2q+w@QBH9bcAruWt;I-td)Y^@*Y%r$6S;?Gcb}-MF{a|fQF&6e5Q;xmBv<4m9kNuAs53&UM*0E=p-Rx237|02B z8*`D}1+oITvy{2bPG%mnqnPJxSI~uxK`+NLUs!=jW3%ZG_BqXA_d~gmX0lyrG8<1{ zu!NptKax%CzhpeS7`)3w!m!oJ9R`z`%y(RdIfq}<)p#`Rk4>~5-bpB~L%yL0_$V5H zXQ3R_0xd-r6oFFpEBb!DC+H>>#`h^r)&^(~v?AJiEkzxy?N_U6f2%}m0X};Sc&dcD;mlS?{mC)YocG{hek+L3%CJ zOYe>L=nGMnehJkD-M<(W$DdJGTn4Yjlkj7F3v+}e%}58bkgOqB$t&U|7-obwqJ!xe zx`}S1x9A<3OEam7;emH$nT|{|W)#z(nZ->8#i=)LBET?@81cpMD?_X4_Y4QXRGoK|5SB!+!KSoSE%VV02F%s{f0X+j1t5u_9oz+dSb zh=0!G`gA$YAVcs{(g>F%W_%C-M&0p6* zeT6lG@0I>qn)0`ns;mdhPH36HHJ|cB1J$Wn)DXR>T1~I5Hq~3Jee_Z4SbdQ?M?VgE zpBL&rJ)oY`D}W!>54e}4c>qHT3el^fK6)bBtJIt&0 z(&oU*9*n^J#e@K=A3J-tKkT}iL@%)hgJrhsC=C0r-9fUF*>XsYoBHmeu>H_4EO1Zzw0~{nRyjU-c-ouj?b!6u>J}pQviE9wrE_ zQe)6TH6C4toWU#g59CohBa1c=HPuGJD&DzhueJvK;=RbC-vK-Q0d3Y5^ihw-Wnj(g zDD*ds#DB1c9>V#sHoOLxAdhi7VkWalW3q?LC9lb0Qb@j#Fe;K-v<&SCR&X>O0IN?X z(G7GN-9>lPQ(zI#((CjZeFpL#SeglC0pKgs|3KTGq+!fKT7vn9#xbkFub4?2G9zh6 zrU&iDG^Tx+vUE5TOh+;*7@ww<@N8_Q^})cvNOVDes;|{o>woL*_3pY=Ptd< z2*jABv|6Z)))Ljwx}b*I0Mtbrj)rLy&^&Dx+NLc!1dBGU|=*pk)~2L%2Qu0$MbHUqkE=OuCYeWG1lh0J%c$f)&gsR*J#?Ris^M zEjo_&qD$ydIIVOFL=}s{DlP}?HqnRlAHZ)LeF<0IL;WM*n*!H=f_$fwX%-y@xb~;{ zv>A2MdelKYlxa?tx;R88)^goNKaU))CagWO8Xm4)ux~o+Dx=hTa2!0tI&7AP}7d0c!*8= z>#xyj{Tq6&%SeYkoTU%RO_+s!mF_1G=vwj!uzE^Ik=L{L53~~bNW-AyNeZ>&5A+v) zPv7EXdJn&(7a*5#3_qaT@g=$npP~!#UOEYHq$BWL@KZ(tc3o*BT#d%#P#S~t2#+5T zAKFHKqS53ftgb(Y5ZMDh%zU&K{{6bF7R%i5(9k)+%3|jUHsSaLi zLwb?arw2(Rx`#BQt4LEikNiQ$lh(8!NJr9v)`Kxnfpn!&AeeNg0o;pz!-@1W?oDsu ze)I~o58^&_2lTDMJ?MPEW;$*MShb|XfMcC;0_}*)(I&VkO~3|P0S8D7_$tBpInmKM z;z1k1-<(1|ppLMTw>&wGRJ<9z#f#B?{3n`<`yn`499eKJl!jtJkA|RmNYgtaFK{tW z_v;z@d;O<=K~L2;KsiJIrS}0pr;YB=>*xrTh20a2>(R&xF_=ZKk68GmQSXZw{Vycw zGZAQAWYV`mxf=!RXOI~O4NAhv0{LSq%R>E{fXV)@V4Mi>BcVXbX5`CvZu?uN(e}S78}ngDAcL zS0&NlkG6yr-DAl}vKFl2X|e=ZxQToxNnjOsf`5952y`cjpnFMingp_$l&336S-Kd? z86aawIXVp5-Jom%(MUazihy?!5=n!A%PNiljzt59NtgL;N_6_n+3ewloWdKd5~`l6QlIMhU+g6imtQC)ols-^FM=YI^!(;zpX z?>1a}f*R`2Py@iKA>_N70ZvWzFYwtfs5$Vfy`BQ~pMX~y>ICHgJsXYGbI?TH1#zht zd=`w)0r#GQ?aR}v;b736bx=1v7%*H97~VpgaUnX0OG9Ma5hvq?I3J(F3jTzxM8h$p z97!N;NgXnrv?Gh4wjFHbagqquu{(JJ^-o|ie?b3l@&_q^dkaAvq$F^(ByoX74G@mF zi68rj4SPu@;P4sSVTZT?d59h48g`OP*hP-u0&)o2NjQgW0^PS9|0c_TPqXk(G97=0 zT_5XSI`x_A0^@KXf9rb5@7__2Y)6EJUK5KiQb~Vfa4&v9`!(zP=C}L4M24u!jDDc z5CdMSSD%M|fV>8r?gF>Y!K$1S`hRFI#AMq5qs{tDv_}63ndCIIT+cu&0f*(lp~b+Z z6}k^C(w)F12`vLmmVhs^7;M=x-T!~(a%e9D-*Pov2hRucnhf3!a##<798oyFqZh^B z^-6$W0=A;2I1cr|ozM_G1vJSvv;=$5Eq_D^T8f2M+?wO@NNEw=5~no_n^w?I4Xre z528DuX>Y?Gw4YIq{t6Krz`^(=Zip}A9^lU`29I;n53M(nr@$p`CL zfZLEf+?S-|QRFxNn|#F6K^Bl_AP?a=U&qUUSE~W9wd5$Y_W=gm0fWuZw*jvqtAHKGgsABT>WR;R6*-OK z@nIAVIT;2YfE?m+l!6YS2k0a^jn1K6kR4uzZlEd9GZMW39FtKih@0y`{-YYo1*@44 z(Z3G`0ej(q7z7R;R&@emgjJ0kmVi4>5E*c>>sBa(u@Bllz~_H`q8H7r$2S4hoA@qp^Ammuk>WLs$Riv~E(4a=aTRg_a#N>qOW;*I z;8h2*3-<>-*aLEn!^m2A?o07#z-b_v2jxt_VkTtirogqycm&`zj7)&OG5=TZLx$o( zQ11yjlmAH<;9YybuNCQvn*;yqfzGTA9E>9kaCri`2T~1itAcsJPsPQs2mbmjEa0!; zk-fq`bQinPe>fZP`wjS|!29XXU@_jHQQ)=pz)w+Yz_dDy-dOw$^7tV}+~il!nRc*%kNF+e041kW=Bw*gPKH9YUy@Z1}tqVTMv zaZQlwkmss|ir{LfB(4D0tDqRjn-{}Xp{xjHCAc>p?umnI|GTF$^w$Kb4w%(}c0*L* z|D-*Pw6>7%><1d-fBRMag<65e=z`b4NZbz?UV&fq98JL)Xa)w23{PP-t^iSCE4&>i z;!SuKJ^*%c3!r)kpN4lZkMMq2&%O!&hPn;1-V*HF!jU!DNalj~vltg8Q*lY~Im(f7 zz>le*(?;X!WIT99Lx3}50fV7{`*6^ALvTD9j1xfO$v|9<41jVF;FAc_55`A#_?|>u zjC25wb;K6Z3dT)S;8_!p+Q79M*p4d$W~D$!l*aFIC}@8R;5T#d+s*I^Gu#n||6dFDALDZ!#{vBNTCG?sNn#dFiM!*z-}~wAh-Qq1b5|n2 zGiB7uOk3(yDy>`8OeCEA=#E9T7Lv{})5MI~Rh+U>!|F^-w9=9upYQtP^?m(#|M+}9 z&*%H~dVhZG?mYPgFD>|LhW&ng?Zm@Z?9DK)$HiJWuV636*%JCqQpC|?v9xddMf&3uL>`d<5||ssA1QNFU8Y3Uk^X_ z26ZdhYs|iwAU7x2IVY-PW9^>)+LN4>$rrLRIxfW+UsJ2&viRkA1TWP%PhwU4F*vFu z5Bn-I!d{lhaC{Ap(<(ws3?TjENR;8N1aG~gG5W;L=%F@rcP?F>QkvEuJS&;AT31bXM;0&ANR&7@eauIz^sw_nYHRSKc{tuz4?Lb5-ITS=rnA&X1p9 zdYnFz%BaHmv76qPN_#>{+g&qqBJICPrR}T*cGfhG^W|(2=`Cjpage4nBtPq~GT%Df ztj6PN{XP^=`qZ-C*K`{8l>;Th7Js+50KR%Lal z?l>Id*>I9880-2Tcb(%PJH_wBm=@z>7MV*H;AN3M??YuRX@LC}oNS?+aI(v&{rvr& zP!7_EVwAh10DQmC@6Ydc*_x>Pw0v zKkhS6FLQQ`G**jbase(&<2wBQN|m_RE0LRp?v6_0G&#XO2Iuc_)||yQ6Nlx>UhxCs zyT!kj>51Njt6kcf*t@kg>azz|jqE+ySg~;h>{7Xv?;TmGISSSBVsn<_tAzB8A8~hv z{uz%KQv>V{gH)7ZaTT9!UDZvbGc50dZ%^3f&?T<8A54eQBk6JCljx`MGh6#yW8T17 ztvp$(ZJD<^$(_(z{wLZu^FP;js~Ns9!#4g-?b~EQ!tGfju|NHCd4gA&4 zr-5Dt-4EESK^6MUaXVxw}{J)uKnMSC*j|O_ z6u|5t6T`m|$>7T?i>UM=OX}ZjO8B&_9 M0ax|;*PMy`2j36Z6#xJL literal 0 HcmV?d00001 From b30be913c0f567df0546e9b3b651468610b19d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 21:55:46 +0200 Subject: [PATCH 420/848] Read in WAV files for UI sounds --- Core/WaveFile.cpp | 3 +- Core/WaveFile.h | 4 - UI/BackgroundAudio.cpp | 348 ++++++++++++++++++++--------------- UI/BackgroundAudio.h | 32 ++++ UI/NativeApp.cpp | 3 + ext/native/file/zip_read.cpp | 1 + ext/native/file/zip_read.h | 4 +- 7 files changed, 238 insertions(+), 157 deletions(-) diff --git a/Core/WaveFile.cpp b/Core/WaveFile.cpp index f789a7807e..038c66e80f 100644 --- a/Core/WaveFile.cpp +++ b/Core/WaveFile.cpp @@ -1,7 +1,7 @@ // Copyright 2008 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. -#ifndef MOBILE_DEVICE + #include #include "Core/WaveFile.h" @@ -105,4 +105,3 @@ void WaveFileWriter::AddStereoSamples(const short* sample_data, u32 count) file.WriteBytes(sample_data, count * 4); audio_size += count * 4; } -#endif diff --git a/Core/WaveFile.h b/Core/WaveFile.h index 39bcf483a4..c2ba17d802 100644 --- a/Core/WaveFile.h +++ b/Core/WaveFile.h @@ -11,7 +11,6 @@ // --------------------------------------------------------------------------------- #pragma once -#ifndef MOBILE_DEVICE #include #include @@ -40,6 +39,3 @@ private: void Write(u32 value); void Write4(const char* ptr); }; - -#endif - diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index defc30068a..89e173c510 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -4,6 +4,7 @@ #include "base/logging.h" #include "base/timeutil.h" #include "file/chunk_file.h" +#include "file/vfs.h" #include "Common/CommonTypes.h" #include "Core/HW/SimpleAudioDec.h" @@ -13,6 +14,152 @@ #include "Core/Config.h" #include "UI/BackgroundAudio.h" +struct WavData { + int num_channels = -1, sample_rate = -1, numFrames = -1, samplesPerSec = -1, avgBytesPerSec = -1, Nothing = -1; + int raw_offset_loop_start_ = 0; + int raw_offset_loop_end_ = 0; + int loop_start_offset_ = 0; + int loop_end_offset_ = 0; + int codec = 0; + int raw_bytes_per_frame_ = 0; + uint8_t *raw_data_ = nullptr; + int raw_data_size_ = 0; + u8 at3_extradata[16]; + + void Read(RIFFReader &riff); + + ~WavData() { + free(raw_data_); + raw_data_ = nullptr; + } +}; + +void WavData::Read(RIFFReader &file_) { + // If we have no loop start info, we'll just loop the entire audio. + raw_offset_loop_start_ = 0; + raw_offset_loop_end_ = 0; + + if (file_.Descend('RIFF')) { + file_.ReadInt(); //get past 'WAVE' + if (file_.Descend('fmt ')) { //enter the format chunk + int temp = file_.ReadInt(); + int format = temp & 0xFFFF; + switch (format) { + case 0xFFFE: + codec = PSP_CODEC_AT3PLUS; + break; + case 0x270: + codec = PSP_CODEC_AT3; + break; + case 1: + // Raw wave data, no codec + codec = 0; + break; + default: + ERROR_LOG(SCEAUDIO, "Unexpected wave format %04x", format); + return; + } + + num_channels = temp >> 16; + + samplesPerSec = file_.ReadInt(); + avgBytesPerSec = file_.ReadInt(); + + temp = file_.ReadInt(); + raw_bytes_per_frame_ = temp & 0xFFFF; + Nothing = temp >> 16; + + // Not currently used, but part of the format. + (void)avgBytesPerSec; + (void)Nothing; + + if (codec == PSP_CODEC_AT3) { + // The first two bytes are actually not a useful part of the extradata. + // We already read 16 bytes, so make sure there's enough left. + if (file_.GetCurrentChunkSize() >= 32) { + file_.ReadData(at3_extradata, 16); + } else { + memset(at3_extradata, 0, sizeof(at3_extradata)); + } + } + file_.Ascend(); + // ILOG("got fmt data: %i", samplesPerSec); + } else { + ELOG("Error - no format chunk in wav"); + file_.Ascend(); + return; + } + + if (file_.Descend('smpl')) { + std::vector smplData; + smplData.resize(file_.GetCurrentChunkSize()); + file_.ReadData(&smplData[0], (int)smplData.size()); + + int numLoops = *(int *)&smplData[28]; + struct AtracLoopInfo { + int cuePointID; + int type; + int startSample; + int endSample; + int fraction; + int playCount; + }; + + if (numLoops > 0 && smplData.size() >= 36 + sizeof(AtracLoopInfo) * numLoops) { + AtracLoopInfo *loops = (AtracLoopInfo *)&smplData[36]; + int samplesPerFrame = codec == PSP_CODEC_AT3PLUS ? 2048 : 1024; + + for (int i = 0; i < numLoops; ++i) { + // Only seen forward loops, so let's ignore others. + if (loops[i].type != 0) + continue; + + // We ignore loop interpolation (fraction) and play count for now. + raw_offset_loop_start_ = (loops[i].startSample / samplesPerFrame) * raw_bytes_per_frame_; + loop_start_offset_ = loops[i].startSample % samplesPerFrame; + raw_offset_loop_end_ = (loops[i].endSample / samplesPerFrame) * raw_bytes_per_frame_; + loop_end_offset_ = loops[i].endSample % samplesPerFrame; + + if (loops[i].playCount == 0) { + // This was an infinite loop, so ignore the rest. + // In practice, there's usually only one and it's usually infinite. + break; + } + } + } + + file_.Ascend(); + } + + // enter the data chunk + if (file_.Descend('data')) { + int numBytes = file_.GetCurrentChunkSize(); + numFrames = numBytes / raw_bytes_per_frame_; // numFrames + + raw_data_ = (uint8_t *)malloc(numBytes); + raw_data_size_ = numBytes; + if (num_channels == 1 || num_channels == 2) { + file_.ReadData(raw_data_, numBytes); + } else { + ELOG("Error - bad blockalign or channels"); + free(raw_data_); + raw_data_ = nullptr; + return; + } + file_.Ascend(); + } else { + ELOG("Error - no data chunk in wav"); + file_.Ascend(); + return; + } + file_.Ascend(); + } else { + ELOG("Could not descend into RIFF file."); + return; + } + sample_rate = samplesPerSec; +} + // Really simple looping in-memory AT3 player that also takes care of reading the file format. // Turns out that AT3 files used for this are modified WAVE files so fairly easy to parse. class AT3PlusReader { @@ -22,163 +169,39 @@ public: // Normally 8k but let's be safe. buffer_ = new short[32 * 1024]; - int codec = PSP_CODEC_AT3PLUS; - u8 at3_extradata[16]; + skip_next_samples_ = 0; - int num_channels, sample_rate, numFrames, samplesPerSec, avgBytesPerSec, Nothing; - if (file_.Descend('RIFF')) { - file_.ReadInt(); //get past 'WAVE' - if (file_.Descend('fmt ')) { //enter the format chunk - int temp = file_.ReadInt(); - int format = temp & 0xFFFF; - switch (format) { - case 0xFFFE: - codec = PSP_CODEC_AT3PLUS; - break; - case 0x270: - codec = PSP_CODEC_AT3; - break; - default: - ERROR_LOG(SCEAUDIO, "Unexpected SND0.AT3 format %04x", format); - return; - } + wave_.Read(file_); - num_channels = temp >> 16; - - samplesPerSec = file_.ReadInt(); - avgBytesPerSec = file_.ReadInt(); - - temp = file_.ReadInt(); - raw_bytes_per_frame_ = temp & 0xFFFF; - Nothing = temp >> 16; - - // Not currently used, but part of the format. - (void)avgBytesPerSec; - (void)Nothing; - - if (codec == PSP_CODEC_AT3) { - // The first two bytes are actually not a useful part of the extradata. - // We already read 16 bytes, so make sure there's enough left. - if (file_.GetCurrentChunkSize() >= 32) { - file_.ReadData(at3_extradata, 16); - } else { - memset(at3_extradata, 0, sizeof(at3_extradata)); - } - } - file_.Ascend(); - // ILOG("got fmt data: %i", samplesPerSec); - } else { - ELOG("Error - no format chunk in wav"); - file_.Ascend(); - return; - } - - // If we have no loop info, we'll just loop the entire audio. - raw_offset_loop_start_ = 0; - raw_offset_loop_end_ = 0; - skip_next_samples_ = 0; - - if (file_.Descend('smpl')) { - std::vector smplData; - smplData.resize(file_.GetCurrentChunkSize()); - file_.ReadData(&smplData[0], (int)smplData.size()); - - int numLoops = *(int *)&smplData[28]; - struct AtracLoopInfo { - int cuePointID; - int type; - int startSample; - int endSample; - int fraction; - int playCount; - }; - - if (numLoops > 0 && smplData.size() >= 36 + sizeof(AtracLoopInfo) * numLoops) { - AtracLoopInfo *loops = (AtracLoopInfo *)&smplData[36]; - int samplesPerFrame = codec == PSP_CODEC_AT3PLUS ? 2048 : 1024; - - for (int i = 0; i < numLoops; ++i) { - // Only seen forward loops, so let's ignore others. - if (loops[i].type != 0) - continue; - - // We ignore loop interpolation (fraction) and play count for now. - raw_offset_loop_start_ = (loops[i].startSample / samplesPerFrame) * raw_bytes_per_frame_; - loop_start_offset_ = loops[i].startSample % samplesPerFrame; - raw_offset_loop_end_ = (loops[i].endSample / samplesPerFrame) * raw_bytes_per_frame_; - loop_end_offset_ = loops[i].endSample % samplesPerFrame; - - if (loops[i].playCount == 0) { - // This was an infinite loop, so ignore the rest. - // In practice, there's usually only one and it's usually infinite. - break; - } - } - } - - file_.Ascend(); - } - - if (file_.Descend('data')) { //enter the data chunk - int numBytes = file_.GetCurrentChunkSize(); - numFrames = numBytes / raw_bytes_per_frame_; // numFrames - - raw_data_ = (uint8_t *)malloc(numBytes); - raw_data_size_ = numBytes; - if (num_channels == 1 || num_channels == 2) { - file_.ReadData(raw_data_, numBytes); - } else { - ELOG("Error - bad blockalign or channels"); - free(raw_data_); - raw_data_ = nullptr; - return; - } - file_.Ascend(); - } else { - ELOG("Error - no data chunk in wav"); - file_.Ascend(); - return; - } - file_.Ascend(); - } else { - ELOG("Could not descend into RIFF file. Data size=%d", (int32_t)data.size()); - return; + decoder_ = new SimpleAudio(wave_.codec, wave_.sample_rate, wave_.num_channels); + if (wave_.codec == PSP_CODEC_AT3) { + decoder_->SetExtraData(&wave_.at3_extradata[2], 14, wave_.raw_bytes_per_frame_); } - sample_rate = samplesPerSec; - decoder_ = new SimpleAudio(codec, sample_rate, num_channels); - if (codec == PSP_CODEC_AT3) { - decoder_->SetExtraData(&at3_extradata[2], 14, raw_bytes_per_frame_); - } - ILOG("read ATRAC, frames: %i, rate %i", numFrames, sample_rate); + ILOG("read ATRAC, frames: %d, rate %d", wave_.numFrames, wave_.sample_rate); } ~AT3PlusReader() { - } - - void Shutdown() { - free(raw_data_); - raw_data_ = nullptr; delete[] buffer_; buffer_ = nullptr; delete decoder_; decoder_ = nullptr; } - bool IsOK() { return raw_data_ != nullptr; } + bool IsOK() { return wave_.raw_data_ != nullptr; } bool Read(int *buffer, int len) { - if (!raw_data_) + if (!wave_.raw_data_) return false; while (bgQueue.size() < (size_t)(len * 2)) { int outBytes = 0; - decoder_->Decode(raw_data_ + raw_offset_, raw_bytes_per_frame_, (uint8_t *)buffer_, &outBytes); + decoder_->Decode(wave_.raw_data_ + raw_offset_, wave_.raw_bytes_per_frame_, (uint8_t *)buffer_, &outBytes); if (!outBytes) return false; - if (raw_offset_loop_end_ != 0 && raw_offset_ == raw_offset_loop_end_) { + if (wave_.raw_offset_loop_end_ != 0 && raw_offset_ == wave_.raw_offset_loop_end_) { // Only take the remaining bytes, but convert to stereo s16. - outBytes = std::min(outBytes, loop_end_offset_ * 4); + outBytes = std::min(outBytes, wave_.loop_end_offset_ * 4); } int start = skip_next_samples_; @@ -188,16 +211,16 @@ public: bgQueue.push(buffer_[i]); } - if (raw_offset_loop_end_ != 0 && raw_offset_ == raw_offset_loop_end_) { + if (wave_.raw_offset_loop_end_ != 0 && raw_offset_ == wave_.raw_offset_loop_end_) { // Time to loop. Account for the addition below. - raw_offset_ = raw_offset_loop_start_ - raw_bytes_per_frame_; + raw_offset_ = wave_.raw_offset_loop_start_ - wave_.raw_bytes_per_frame_; // This time we're counting each stereo sample. - skip_next_samples_ = loop_start_offset_ * 2; + skip_next_samples_ = wave_.loop_start_offset_ * 2; } // Handle loops when there's no loop info. - raw_offset_ += raw_bytes_per_frame_; - if (raw_offset_ >= raw_data_size_) { + raw_offset_ += wave_.raw_bytes_per_frame_; + if (raw_offset_ >= wave_.raw_data_size_) { raw_offset_ = 0; } } @@ -210,14 +233,10 @@ public: private: RIFFReader file_; - uint8_t *raw_data_ = nullptr; - int raw_data_size_ = 0; + + WavData wave_; + int raw_offset_ = 0; - int raw_bytes_per_frame_; - int raw_offset_loop_start_ = 0; - int raw_offset_loop_end_ = 0; - int loop_start_offset_ = 0; - int loop_end_offset_ = 0; int skip_next_samples_ = 0; FixedSizeQueue bgQueue; short *buffer_ = nullptr; @@ -234,6 +253,38 @@ BackgroundAudio::~BackgroundAudio() { delete[] buffer; } +BackgroundAudio::Sample *BackgroundAudio::LoadSample(const std::string &path) { + size_t bytes; + uint8_t *data = VFSReadFile(path.c_str(), &bytes); + if (!data) { + return nullptr; + } + + WavData wave; + wave.Read(RIFFReader(data, (int)bytes)); + + if (wave.num_channels != 2) { + ELOG("Wave format not supported for mixer playback. Must be 16-bit raw stereo. '%s'", path.c_str()); + return nullptr; + } + + int16_t *samples = new int16_t[2 * wave.numFrames]; + memcpy(samples, wave.raw_data_, wave.numFrames * wave.raw_bytes_per_frame_); + + return new BackgroundAudio::Sample(samples, wave.numFrames); +} + +void BackgroundAudio::LoadSamples() { + samples_.resize((size_t)MenuSFX::COUNT); + samples_[(size_t)MenuSFX::BACK] = std::unique_ptr(LoadSample("sfx_back.wav")); + samples_[(size_t)MenuSFX::SELECT] = std::unique_ptr(LoadSample("sfx_select.wav")); + samples_[(size_t)MenuSFX::CONFIRM] = std::unique_ptr(LoadSample("sfx_confirm.wav")); +} + +void BackgroundAudio::PlaySFX(MenuSFX sfx) { + plays_.push_back(PlayInstance{ sfx, 0 }); +} + void BackgroundAudio::Clear(bool hard) { if (!hard) { fadingOut = true; @@ -241,7 +292,6 @@ void BackgroundAudio::Clear(bool hard) { return; } if (at3Reader) { - at3Reader->Shutdown(); delete at3Reader; at3Reader = nullptr; } @@ -281,7 +331,7 @@ int BackgroundAudio::Play() { return 0; } - double now = time_now(); + double now = time_now_d(); if (at3Reader) { int sz = lastPlaybackTime <= 0.0 ? 44100 / 60 : (int)((now - lastPlaybackTime) * 44100); sz = std::min(BUFSIZE / 2, sz); diff --git a/UI/BackgroundAudio.h b/UI/BackgroundAudio.h index d5d8ca7f18..00afb4bab6 100644 --- a/UI/BackgroundAudio.h +++ b/UI/BackgroundAudio.h @@ -2,9 +2,17 @@ #include #include +#include class AT3PlusReader; +enum class MenuSFX { + SELECT = 0, + BACK = 1, + CONFIRM = 2, + COUNT, +}; + class BackgroundAudio { public: BackgroundAudio(); @@ -14,6 +22,10 @@ public: void SetGame(const std::string &path); void Update(); int Play(); + + void LoadSamples(); + void PlaySFX(MenuSFX sfx); + private: enum { BUFSIZE = 44100, @@ -29,6 +41,26 @@ private: bool fadingOut = true; float volume = 0.0f; float delta = -0.0001f; + + struct PlayInstance { + MenuSFX sound; + int offset; + }; + + struct Sample { + // data must be new-ed. + Sample(int16_t *data, int length) : data_(data), length_(length) {} + ~Sample() { + delete[] data_; + } + int16_t *data_; + int length_; // stereo samples. + }; + + static Sample *LoadSample(const std::string &path); + + std::vector plays_; + std::vector> samples_; }; extern BackgroundAudio g_BackgroundAudio; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 1ee82a3620..9e113e8369 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -446,6 +446,9 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch g_Discord.SetPresenceMenu(); + // TODO: Load these in the background instead of synchronously. + g_BackgroundAudio.LoadSamples(); + // Make sure UI state is MENU. ResetUIState(); diff --git a/ext/native/file/zip_read.cpp b/ext/native/file/zip_read.cpp index 5069cfc223..8c12860246 100644 --- a/ext/native/file/zip_read.cpp +++ b/ext/native/file/zip_read.cpp @@ -285,6 +285,7 @@ static bool IsLocalPath(const char *path) { return isUnixLocal || isWindowsLocal; } +// The returned data should be free'd with delete[]. uint8_t *VFSReadFile(const char *filename, size_t *size) { if (IsLocalPath(filename)) { // Local path, not VFS. diff --git a/ext/native/file/zip_read.h b/ext/native/file/zip_read.h index 3607ddb926..750a71a154 100644 --- a/ext/native/file/zip_read.h +++ b/ext/native/file/zip_read.h @@ -48,7 +48,7 @@ private: class DirectoryAssetReader : public AssetReader { public: - DirectoryAssetReader(const char *path) { + explicit DirectoryAssetReader(const char *path) { strncpy(path_, path, ARRAY_SIZE(path_)); path_[ARRAY_SIZE(path_) - 1] = '\0'; } @@ -61,6 +61,6 @@ public: } private: - char path_[512]; + char path_[512]{}; }; From 5423f76e25b73255bae6ba94e7addfb6dc9d2afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 23:02:30 +0200 Subject: [PATCH 421/848] Hook up the first UI sound, make it play. --- Core/HLE/sceMpeg.cpp | 4 +-- UI/BackgroundAudio.cpp | 77 ++++++++++++++++++++++++++++++++---------- UI/BackgroundAudio.h | 2 ++ ext/native/ui/root.cpp | 15 ++++++++ ext/native/ui/root.h | 11 ++++++ 5 files changed, 89 insertions(+), 20 deletions(-) diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 70bfb5f509..37a3ae9ede 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1882,11 +1882,11 @@ static u32 sceMpegAvcCopyYCbCr(u32 mpeg, u32 sourceAddr, u32 YCbCrAddr) MpegContext *ctx = getMpegCtx(mpeg); if (!ctx) { - WARN_LOG(ME, "UNIMPL sceMpegAvcCopyYCbCr(%08x, %08x, %08x): bad mpeg handle", mpeg, sourceAddr, YCbCrAddr); + ERROR_LOG(ME, "UNIMPL sceMpegAvcCopyYCbCr(%08x, %08x, %08x): bad mpeg handle", mpeg, sourceAddr, YCbCrAddr); return -1; } - ERROR_LOG(ME, "UNIMPL sceMpegAvcCopyYCbCr(%08x, %08x, %08x)", mpeg, sourceAddr, YCbCrAddr); + WARN_LOG(ME, "UNIMPL sceMpegAvcCopyYCbCr(%08x, %08x, %08x)", mpeg, sourceAddr, YCbCrAddr); return 0; } diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 89e173c510..794992adc9 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -5,6 +5,7 @@ #include "base/timeutil.h" #include "file/chunk_file.h" #include "file/vfs.h" +#include "ui/root.h" #include "Common/CommonTypes.h" #include "Core/HW/SimpleAudioDec.h" @@ -260,10 +261,12 @@ BackgroundAudio::Sample *BackgroundAudio::LoadSample(const std::string &path) { return nullptr; } - WavData wave; - wave.Read(RIFFReader(data, (int)bytes)); + RIFFReader reader(data, (int)bytes); - if (wave.num_channels != 2) { + WavData wave; + wave.Read(reader); + + if (wave.num_channels != 2 || wave.sample_rate != 44100 || wave.raw_bytes_per_frame_ != 4) { ELOG("Wave format not supported for mixer playback. Must be 16-bit raw stereo. '%s'", path.c_str()); return nullptr; } @@ -279,10 +282,23 @@ void BackgroundAudio::LoadSamples() { samples_[(size_t)MenuSFX::BACK] = std::unique_ptr(LoadSample("sfx_back.wav")); samples_[(size_t)MenuSFX::SELECT] = std::unique_ptr(LoadSample("sfx_select.wav")); samples_[(size_t)MenuSFX::CONFIRM] = std::unique_ptr(LoadSample("sfx_confirm.wav")); + + UI::SetSoundCallback([](UI::UISound sound) { + MenuSFX sfx; + switch (sound) { + case UI::UISound::BACK: sfx = MenuSFX::BACK; break; + case UI::UISound::CONFIRM: sfx = MenuSFX::CONFIRM; break; + case UI::UISound::SELECT: sfx = MenuSFX::SELECT; break; + default: return; + } + + g_BackgroundAudio.PlaySFX(sfx); + }); } void BackgroundAudio::PlaySFX(MenuSFX sfx) { - plays_.push_back(PlayInstance{ sfx, 0 }); + std::lock_guard lock(g_bgMutex); + plays_.push_back(PlayInstance{ sfx, 0, 64, false }); } void BackgroundAudio::Clear(bool hard) { @@ -332,34 +348,59 @@ int BackgroundAudio::Play() { } double now = time_now_d(); + int sz = lastPlaybackTime <= 0.0 ? 44100 / 60 : (int)((now - lastPlaybackTime) * 44100); + sz = std::min(BUFSIZE / 2, sz); if (at3Reader) { - int sz = lastPlaybackTime <= 0.0 ? 44100 / 60 : (int)((now - lastPlaybackTime) * 44100); - sz = std::min(BUFSIZE / 2, sz); if (sz >= 16) { if (at3Reader->Read(buffer, sz)) { - if (!fadingOut) { - __PushExternalAudio(buffer, sz); - } else { + if (fadingOut) { for (int i = 0; i < sz*2; i += 2) { buffer[i] *= volume; buffer[i + 1] *= volume; volume += delta; } - __PushExternalAudio(buffer, sz); - if (volume <= 0.0f) { - Clear(true); - fadingOut = false; - gameLastChanged = 0; - } } } - lastPlaybackTime = now; } } else { - __PushExternalAudio(0, 0); - lastPlaybackTime = now; + for (int i = 0; i < sz * 2; i += 2) { + buffer[i] = 0; + buffer[i + 1] = 0; + } } + // Mix in menu sound effects + if (!plays_.empty()) { + for (int i = 0; i < sz * 2; i += 2) { + std::vector::iterator iter = plays_.begin(); + while (iter != plays_.end()) { + PlayInstance inst = *iter; + auto sample = samples_[(int)inst.sound].get(); + if (iter->offset >= sample->length_) { + iter->done = true; + iter = plays_.erase(iter); + } else { + if (!iter->done) { + buffer[i] += sample->data_[inst.offset * 2] * inst.volume >> 8; + buffer[i + 1] += sample->data_[inst.offset * 2 + 1] * inst.volume >> 8; + } + iter->offset++; + iter++; + } + } + } + } + + __PushExternalAudio(buffer, sz); + + if (at3Reader && fadingOut && volume <= 0.0f) { + Clear(true); + fadingOut = false; + gameLastChanged = 0; + } + + lastPlaybackTime = now; + return 0; } diff --git a/UI/BackgroundAudio.h b/UI/BackgroundAudio.h index 00afb4bab6..fff043e465 100644 --- a/UI/BackgroundAudio.h +++ b/UI/BackgroundAudio.h @@ -45,6 +45,8 @@ private: struct PlayInstance { MenuSFX sound; int offset; + int volume; // 0..255 + bool done; }; struct Sample { diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index ef44036747..d65bfc0d33 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -17,6 +17,9 @@ static bool focusMovementEnabled; bool focusForced; static std::mutex eventMutex_; +static std::function soundCallback; + + struct DispatchQueueItem { Event *e; EventParams params; @@ -133,6 +136,18 @@ void MoveFocus(ViewGroup *root, FocusDirection direction) { if (neigh.view) { neigh.view->SetFocus(); root->SubviewFocused(neigh.view); + + PlayUISound(UISound::SELECT); + } +} + +void SetSoundCallback(std::function func) { + soundCallback = func; +} + +void PlayUISound(UISound sound) { + if (soundCallback) { + soundCallback(UISound::SELECT); } } diff --git a/ext/native/ui/root.h b/ext/native/ui/root.h index 8cfca36f29..5d13c51e2d 100644 --- a/ext/native/ui/root.h +++ b/ext/native/ui/root.h @@ -1,5 +1,6 @@ #pragma once +#include #include "ui/ui_context.h" #include "input/input_state.h" @@ -26,4 +27,14 @@ bool KeyEvent(const KeyInput &key, ViewGroup *root); bool TouchEvent(const TouchInput &touch, ViewGroup *root); bool AxisEvent(const AxisInput &axis, ViewGroup *root); +enum class UISound { + SELECT, + BACK, + CONFIRM, +}; + +void SetSoundCallback(std::function func); + +void PlayUISound(UISound sound); + } // namespace UI From 55eb2844fd83f974b6f8b82a60fba31db768ff67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 2 Aug 2020 23:09:04 +0200 Subject: [PATCH 422/848] Hook up a couple more sounds. Unfortunately clickable back buttons now play both back and confirm sounds... --- UI/BackgroundAudio.cpp | 2 +- ext/native/ui/root.cpp | 2 +- ext/native/ui/root.h | 1 + ext/native/ui/ui_screen.cpp | 4 ++++ ext/native/ui/view.cpp | 1 + 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 794992adc9..82cb981a9c 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -369,7 +369,7 @@ int BackgroundAudio::Play() { } } - // Mix in menu sound effects + // Mix in menu sound effects. Terribly slow mixer but meh. if (!plays_.empty()) { for (int i = 0; i < sz * 2; i += 2) { std::vector::iterator iter = plays_.begin(); diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index d65bfc0d33..5533359c7c 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -147,7 +147,7 @@ void SetSoundCallback(std::function func) { void PlayUISound(UISound sound) { if (soundCallback) { - soundCallback(UISound::SELECT); + soundCallback(sound); } } diff --git a/ext/native/ui/root.h b/ext/native/ui/root.h index 5d13c51e2d..97923f93e0 100644 --- a/ext/native/ui/root.h +++ b/ext/native/ui/root.h @@ -1,6 +1,7 @@ #pragma once #include + #include "ui/ui_context.h" #include "input/input_state.h" diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 0a2a665e34..74e31c8601 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -157,6 +157,10 @@ bool UIScreen::key(const KeyInput &key) { } void UIScreen::TriggerFinish(DialogResult result) { + switch (result) { + case DialogResult::DR_BACK: UI::PlayUISound(UI::UISound::BACK); break; + case DialogResult::DR_OK: UI::PlayUISound(UI::UISound::CONFIRM); break; + } screenManager()->finishDialog(this, result); } diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index d452b6a8a3..1aea855070 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -217,6 +217,7 @@ void Clickable::Click() { UI::EventParams e{}; e.v = this; OnClick.Trigger(e); + UI::PlayUISound(UI::UISound::CONFIRM); }; void Clickable::FocusChanged(int focusFlags) { From 434b717ba0a9aaa17feaadb5f1879dbda1c9072f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 11:29:54 +0200 Subject: [PATCH 423/848] Add a couple of more sounds. Rename some vars. --- UI/BackgroundAudio.cpp | 171 ++++++++++++++++++++--------------------- UI/BackgroundAudio.h | 31 ++++---- ext/native/ui/root.h | 5 +- 3 files changed, 99 insertions(+), 108 deletions(-) diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 82cb981a9c..b8a08fcaa9 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -16,29 +16,33 @@ #include "UI/BackgroundAudio.h" struct WavData { - int num_channels = -1, sample_rate = -1, numFrames = -1, samplesPerSec = -1, avgBytesPerSec = -1, Nothing = -1; - int raw_offset_loop_start_ = 0; - int raw_offset_loop_end_ = 0; - int loop_start_offset_ = 0; - int loop_end_offset_ = 0; + int num_channels = -1; + int sample_rate = -1; + int numFrames = -1; + int samplesPerSec = -1; + int avgBytesPerSec = -1; + int raw_offset_loop_start = 0; + int raw_offset_loop_end = 0; + int loop_start_offset = 0; + int loop_end_offset = 0; int codec = 0; - int raw_bytes_per_frame_ = 0; - uint8_t *raw_data_ = nullptr; - int raw_data_size_ = 0; + int raw_bytes_per_frame = 0; + uint8_t *raw_data = nullptr; + int raw_data_size = 0; u8 at3_extradata[16]; void Read(RIFFReader &riff); ~WavData() { - free(raw_data_); - raw_data_ = nullptr; + free(raw_data); + raw_data = nullptr; } }; void WavData::Read(RIFFReader &file_) { // If we have no loop start info, we'll just loop the entire audio. - raw_offset_loop_start_ = 0; - raw_offset_loop_end_ = 0; + raw_offset_loop_start = 0; + raw_offset_loop_end = 0; if (file_.Descend('RIFF')) { file_.ReadInt(); //get past 'WAVE' @@ -64,15 +68,10 @@ void WavData::Read(RIFFReader &file_) { num_channels = temp >> 16; samplesPerSec = file_.ReadInt(); - avgBytesPerSec = file_.ReadInt(); + /*avgBytesPerSec =*/ file_.ReadInt(); temp = file_.ReadInt(); - raw_bytes_per_frame_ = temp & 0xFFFF; - Nothing = temp >> 16; - - // Not currently used, but part of the format. - (void)avgBytesPerSec; - (void)Nothing; + raw_bytes_per_frame = temp & 0xFFFF; if (codec == PSP_CODEC_AT3) { // The first two bytes are actually not a useful part of the extradata. @@ -116,10 +115,10 @@ void WavData::Read(RIFFReader &file_) { continue; // We ignore loop interpolation (fraction) and play count for now. - raw_offset_loop_start_ = (loops[i].startSample / samplesPerFrame) * raw_bytes_per_frame_; - loop_start_offset_ = loops[i].startSample % samplesPerFrame; - raw_offset_loop_end_ = (loops[i].endSample / samplesPerFrame) * raw_bytes_per_frame_; - loop_end_offset_ = loops[i].endSample % samplesPerFrame; + raw_offset_loop_start = (loops[i].startSample / samplesPerFrame) * raw_bytes_per_frame; + loop_start_offset = loops[i].startSample % samplesPerFrame; + raw_offset_loop_end = (loops[i].endSample / samplesPerFrame) * raw_bytes_per_frame; + loop_end_offset = loops[i].endSample % samplesPerFrame; if (loops[i].playCount == 0) { // This was an infinite loop, so ignore the rest. @@ -135,16 +134,16 @@ void WavData::Read(RIFFReader &file_) { // enter the data chunk if (file_.Descend('data')) { int numBytes = file_.GetCurrentChunkSize(); - numFrames = numBytes / raw_bytes_per_frame_; // numFrames + numFrames = numBytes / raw_bytes_per_frame; // numFrames - raw_data_ = (uint8_t *)malloc(numBytes); - raw_data_size_ = numBytes; + raw_data = (uint8_t *)malloc(numBytes); + raw_data_size = numBytes; if (num_channels == 1 || num_channels == 2) { - file_.ReadData(raw_data_, numBytes); + file_.ReadData(raw_data, numBytes); } else { ELOG("Error - bad blockalign or channels"); - free(raw_data_); - raw_data_ = nullptr; + free(raw_data); + raw_data = nullptr; return; } file_.Ascend(); @@ -176,7 +175,7 @@ public: decoder_ = new SimpleAudio(wave_.codec, wave_.sample_rate, wave_.num_channels); if (wave_.codec == PSP_CODEC_AT3) { - decoder_->SetExtraData(&wave_.at3_extradata[2], 14, wave_.raw_bytes_per_frame_); + decoder_->SetExtraData(&wave_.at3_extradata[2], 14, wave_.raw_bytes_per_frame); } ILOG("read ATRAC, frames: %d, rate %d", wave_.numFrames, wave_.sample_rate); } @@ -188,21 +187,21 @@ public: decoder_ = nullptr; } - bool IsOK() { return wave_.raw_data_ != nullptr; } + bool IsOK() { return wave_.raw_data != nullptr; } bool Read(int *buffer, int len) { - if (!wave_.raw_data_) + if (!wave_.raw_data) return false; while (bgQueue.size() < (size_t)(len * 2)) { int outBytes = 0; - decoder_->Decode(wave_.raw_data_ + raw_offset_, wave_.raw_bytes_per_frame_, (uint8_t *)buffer_, &outBytes); + decoder_->Decode(wave_.raw_data + raw_offset_, wave_.raw_bytes_per_frame, (uint8_t *)buffer_, &outBytes); if (!outBytes) return false; - if (wave_.raw_offset_loop_end_ != 0 && raw_offset_ == wave_.raw_offset_loop_end_) { + if (wave_.raw_offset_loop_end != 0 && raw_offset_ == wave_.raw_offset_loop_end) { // Only take the remaining bytes, but convert to stereo s16. - outBytes = std::min(outBytes, wave_.loop_end_offset_ * 4); + outBytes = std::min(outBytes, wave_.loop_end_offset * 4); } int start = skip_next_samples_; @@ -212,16 +211,16 @@ public: bgQueue.push(buffer_[i]); } - if (wave_.raw_offset_loop_end_ != 0 && raw_offset_ == wave_.raw_offset_loop_end_) { + if (wave_.raw_offset_loop_end != 0 && raw_offset_ == wave_.raw_offset_loop_end) { // Time to loop. Account for the addition below. - raw_offset_ = wave_.raw_offset_loop_start_ - wave_.raw_bytes_per_frame_; + raw_offset_ = wave_.raw_offset_loop_start - wave_.raw_bytes_per_frame; // This time we're counting each stereo sample. - skip_next_samples_ = wave_.loop_start_offset_ * 2; + skip_next_samples_ = wave_.loop_start_offset * 2; } // Handle loops when there's no loop info. - raw_offset_ += wave_.raw_bytes_per_frame_; - if (raw_offset_ >= wave_.raw_data_size_) { + raw_offset_ += wave_.raw_bytes_per_frame; + if (raw_offset_ >= wave_.raw_data_size) { raw_offset_ = 0; } } @@ -266,79 +265,73 @@ BackgroundAudio::Sample *BackgroundAudio::LoadSample(const std::string &path) { WavData wave; wave.Read(reader); - if (wave.num_channels != 2 || wave.sample_rate != 44100 || wave.raw_bytes_per_frame_ != 4) { + if (wave.num_channels != 2 || wave.sample_rate != 44100 || wave.raw_bytes_per_frame != 4) { ELOG("Wave format not supported for mixer playback. Must be 16-bit raw stereo. '%s'", path.c_str()); return nullptr; } int16_t *samples = new int16_t[2 * wave.numFrames]; - memcpy(samples, wave.raw_data_, wave.numFrames * wave.raw_bytes_per_frame_); + memcpy(samples, wave.raw_data, wave.numFrames * wave.raw_bytes_per_frame); return new BackgroundAudio::Sample(samples, wave.numFrames); } void BackgroundAudio::LoadSamples() { - samples_.resize((size_t)MenuSFX::COUNT); - samples_[(size_t)MenuSFX::BACK] = std::unique_ptr(LoadSample("sfx_back.wav")); - samples_[(size_t)MenuSFX::SELECT] = std::unique_ptr(LoadSample("sfx_select.wav")); - samples_[(size_t)MenuSFX::CONFIRM] = std::unique_ptr(LoadSample("sfx_confirm.wav")); + samples_.resize((size_t)UI::UISound::COUNT); + samples_[(size_t)UI::UISound::BACK] = std::unique_ptr(LoadSample("sfx_back.wav")); + samples_[(size_t)UI::UISound::SELECT] = std::unique_ptr(LoadSample("sfx_select.wav")); + samples_[(size_t)UI::UISound::CONFIRM] = std::unique_ptr(LoadSample("sfx_confirm.wav")); + samples_[(size_t)UI::UISound::TOGGLE_ON] = std::unique_ptr(LoadSample("sfx_toggle_on.wav")); + samples_[(size_t)UI::UISound::TOGGLE_OFF] = std::unique_ptr(LoadSample("sfx_toggle_off.wav")); UI::SetSoundCallback([](UI::UISound sound) { - MenuSFX sfx; - switch (sound) { - case UI::UISound::BACK: sfx = MenuSFX::BACK; break; - case UI::UISound::CONFIRM: sfx = MenuSFX::CONFIRM; break; - case UI::UISound::SELECT: sfx = MenuSFX::SELECT; break; - default: return; - } - - g_BackgroundAudio.PlaySFX(sfx); + g_BackgroundAudio.PlaySFX(sound); }); } -void BackgroundAudio::PlaySFX(MenuSFX sfx) { - std::lock_guard lock(g_bgMutex); +void BackgroundAudio::PlaySFX(UI::UISound sfx) { + std::lock_guard lock(mutex_); plays_.push_back(PlayInstance{ sfx, 0, 64, false }); } void BackgroundAudio::Clear(bool hard) { if (!hard) { - fadingOut = true; - volume = 1.0f; + fadingOut_ = true; + volume_ = 1.0f; return; } - if (at3Reader) { - delete at3Reader; - at3Reader = nullptr; + if (at3Reader_) { + delete at3Reader_; + at3Reader_ = nullptr; } - playbackOffset = 0; + playbackOffset_ = 0; } void BackgroundAudio::SetGame(const std::string &path) { time_update(); - std::lock_guard lock(g_bgMutex); - if (path == bgGamePath) { + std::lock_guard lock(mutex_); + if (path == bgGamePath_) { // Do nothing return; } if (path.size() == 0) { Clear(false); - fadingOut = true; + fadingOut_ = true; } else { Clear(true); - gameLastChanged = time_now_d(); - fadingOut = false; + gameLastChanged_ = time_now_d(); + fadingOut_ = false; } - volume = 1.0f; - bgGamePath = path; + volume_ = 1.0f; + bgGamePath_ = path; } int BackgroundAudio::Play() { time_update(); - std::lock_guard lock(g_bgMutex); + std::lock_guard lock(mutex_); // Immediately stop the sound if it is turned off while playing. if (!g_Config.bEnableSound) { @@ -348,16 +341,16 @@ int BackgroundAudio::Play() { } double now = time_now_d(); - int sz = lastPlaybackTime <= 0.0 ? 44100 / 60 : (int)((now - lastPlaybackTime) * 44100); + int sz = lastPlaybackTime_ <= 0.0 ? 44100 / 60 : (int)((now - lastPlaybackTime_) * 44100); sz = std::min(BUFSIZE / 2, sz); - if (at3Reader) { + if (at3Reader_) { if (sz >= 16) { - if (at3Reader->Read(buffer, sz)) { - if (fadingOut) { + if (at3Reader_->Read(buffer, sz)) { + if (fadingOut_) { for (int i = 0; i < sz*2; i += 2) { - buffer[i] *= volume; - buffer[i + 1] *= volume; - volume += delta; + buffer[i] *= volume_; + buffer[i + 1] *= volume_; + volume_ += delta_; } } } @@ -376,7 +369,7 @@ int BackgroundAudio::Play() { while (iter != plays_.end()) { PlayInstance inst = *iter; auto sample = samples_[(int)inst.sound].get(); - if (iter->offset >= sample->length_) { + if (!sample || iter->offset >= sample->length_) { iter->done = true; iter = plays_.erase(iter); } else { @@ -393,13 +386,13 @@ int BackgroundAudio::Play() { __PushExternalAudio(buffer, sz); - if (at3Reader && fadingOut && volume <= 0.0f) { + if (at3Reader_ && fadingOut_ && volume_ <= 0.0f) { Clear(true); - fadingOut = false; - gameLastChanged = 0; + fadingOut_ = false; + gameLastChanged_ = 0; } - lastPlaybackTime = now; + lastPlaybackTime_ = now; return 0; } @@ -407,14 +400,14 @@ int BackgroundAudio::Play() { void BackgroundAudio::Update() { // If there's a game, and some time has passed since the selected game // last changed... (to prevent crazy amount of reads when skipping through a list) - if (bgGamePath.size() && (time_now_d() - gameLastChanged > 0.5)) { - std::lock_guard lock(g_bgMutex); - if (!at3Reader) { + if (bgGamePath_.size() && (time_now_d() - gameLastChanged_ > 0.5)) { + std::lock_guard lock(mutex_); + if (!at3Reader_) { // Grab some audio from the current game and play it. if (!g_gameInfoCache) return; - std::shared_ptr gameInfo = g_gameInfoCache->GetInfo(NULL, bgGamePath, GAMEINFO_WANTSND); + std::shared_ptr gameInfo = g_gameInfoCache->GetInfo(NULL, bgGamePath_, GAMEINFO_WANTSND); if (!gameInfo) return; @@ -425,8 +418,8 @@ void BackgroundAudio::Update() { if (gameInfo->sndFileData.size()) { const std::string &data = gameInfo->sndFileData; - at3Reader = new AT3PlusReader(data); - lastPlaybackTime = 0.0; + at3Reader_ = new AT3PlusReader(data); + lastPlaybackTime_ = 0.0; } } } diff --git a/UI/BackgroundAudio.h b/UI/BackgroundAudio.h index fff043e465..a0c154411e 100644 --- a/UI/BackgroundAudio.h +++ b/UI/BackgroundAudio.h @@ -4,14 +4,9 @@ #include #include -class AT3PlusReader; +#include "ui/root.h" -enum class MenuSFX { - SELECT = 0, - BACK = 1, - CONFIRM = 2, - COUNT, -}; +class AT3PlusReader; class BackgroundAudio { public: @@ -24,26 +19,26 @@ public: int Play(); void LoadSamples(); - void PlaySFX(MenuSFX sfx); + void PlaySFX(UI::UISound sfx); private: enum { BUFSIZE = 44100, }; - std::mutex g_bgMutex; - std::string bgGamePath; - int playbackOffset = 0; - AT3PlusReader *at3Reader; - double gameLastChanged = 0.0; - double lastPlaybackTime = 0.0; + std::mutex mutex_; + std::string bgGamePath_; + int playbackOffset_ = 0; + AT3PlusReader *at3Reader_; + double gameLastChanged_ = 0.0; + double lastPlaybackTime_ = 0.0; int *buffer = nullptr; - bool fadingOut = true; - float volume = 0.0f; - float delta = -0.0001f; + bool fadingOut_ = true; + float volume_ = 0.0f; + float delta_ = -0.0001f; struct PlayInstance { - MenuSFX sound; + UI::UISound sound; int offset; int volume; // 0..255 bool done; diff --git a/ext/native/ui/root.h b/ext/native/ui/root.h index 97923f93e0..3f7850b2dc 100644 --- a/ext/native/ui/root.h +++ b/ext/native/ui/root.h @@ -29,9 +29,12 @@ bool TouchEvent(const TouchInput &touch, ViewGroup *root); bool AxisEvent(const AxisInput &axis, ViewGroup *root); enum class UISound { - SELECT, + SELECT = 0, BACK, CONFIRM, + TOGGLE_ON, + TOGGLE_OFF, + COUNT, }; void SetSoundCallback(std::function func); From 3fd8f3d86d764f83b9ef6582365462808c27ca93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 11:58:55 +0200 Subject: [PATCH 424/848] Add a setting. Various tweaks to sound triggering. --- Core/Config.cpp | 1 + Core/Config.h | 1 + UI/GameSettingsScreen.cpp | 2 +- UI/NativeApp.cpp | 2 ++ ext/native/ui/root.cpp | 8 +++++++- ext/native/ui/root.h | 1 + ext/native/ui/ui_screen.cpp | 5 +---- ext/native/ui/view.cpp | 24 +++++++++++++++++++++--- ext/native/ui/view.h | 2 ++ ext/native/ui/viewgroup.cpp | 15 +++++++++++---- 10 files changed, 48 insertions(+), 13 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 2a696abaf4..a5c217248c 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -433,6 +433,7 @@ static ConfigSetting generalSettings[] = { ConfigSetting("Language", &g_Config.sLanguageIni, &DefaultLangRegion), 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... + ConfigSetting("UISound", &g_Config.bUISound, true, true, false), ReportedConfigSetting("NumWorkerThreads", &g_Config.iNumWorkerThreads, &DefaultNumWorkers, true, true), ConfigSetting("AutoLoadSaveState", &g_Config.iAutoLoadSaveState, 0, true, true), diff --git a/Core/Config.h b/Core/Config.h index d288f62305..71fa93e357 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -196,6 +196,7 @@ public: int iMaxRecent; int iCurrentStateSlot; int iRewindFlipFrequency; + bool bUISound; bool bEnableStateUndo; int iAutoLoadSaveState; // 0 = off, 1 = oldest, 2 = newest, >2 = slot number + 3 bool bEnableCheats; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 7c6637faef..cb312c0145 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -859,7 +859,7 @@ void GameSettingsScreen::CreateViews() { } } #endif - + systemSettings->Add(new CheckBox(&g_Config.bUISound, dev->T("UI Sound"))); systemSettings->Add(new CheckBox(&g_Config.bCheckForNewVersion, sy->T("VersionCheck", "Check for new versions of PPSSPP"))); const std::string bgPng = GetSysDirectory(DIRECTORY_SYSTEM) + "background.png"; const std::string bgJpg = GetSysDirectory(DIRECTORY_SYSTEM) + "background.jpg"; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 9e113e8369..4c222078fa 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1208,6 +1208,8 @@ void NativeUpdate() { screenManager->update(); g_Discord.Update(); + + UI::SetSoundEnabled(g_Config.bUISound); } bool NativeIsAtTopLevel() { diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index 5533359c7c..b71641895e 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -2,6 +2,7 @@ #include #include "ppsspp_config.h" + #include "base/timeutil.h" #include "ui/root.h" #include "ui/viewgroup.h" @@ -18,6 +19,7 @@ bool focusForced; static std::mutex eventMutex_; static std::function soundCallback; +static bool soundEnabled = true; struct DispatchQueueItem { @@ -141,12 +143,16 @@ void MoveFocus(ViewGroup *root, FocusDirection direction) { } } +void SetSoundEnabled(bool enabled) { + soundEnabled = enabled; +} + void SetSoundCallback(std::function func) { soundCallback = func; } void PlayUISound(UISound sound) { - if (soundCallback) { + if (soundEnabled && soundCallback) { soundCallback(sound); } } diff --git a/ext/native/ui/root.h b/ext/native/ui/root.h index 3f7850b2dc..0944373e27 100644 --- a/ext/native/ui/root.h +++ b/ext/native/ui/root.h @@ -37,6 +37,7 @@ enum class UISound { COUNT, }; +void SetSoundEnabled(bool enabled); void SetSoundCallback(std::function func); void PlayUISound(UISound sound); diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 74e31c8601..e2dba2cf60 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -157,10 +157,6 @@ bool UIScreen::key(const KeyInput &key) { } void UIScreen::TriggerFinish(DialogResult result) { - switch (result) { - case DialogResult::DR_BACK: UI::PlayUISound(UI::UISound::BACK); break; - case DialogResult::DR_OK: UI::PlayUISound(UI::UISound::CONFIRM); break; - } screenManager()->finishDialog(this, result); } @@ -172,6 +168,7 @@ bool UIDialogScreen::key(const KeyInput &key) { } else { finished_ = true; TriggerFinish(DR_BACK); + UI::PlayUISound(UI::UISound::BACK); } return true; } diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 1aea855070..577fd91e1c 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -217,7 +217,6 @@ void Clickable::Click() { UI::EventParams e{}; e.v = this; OnClick.Trigger(e); - UI::PlayUISound(UI::UISound::CONFIRM); }; void Clickable::FocusChanged(int focusFlags) { @@ -377,6 +376,7 @@ bool StickyChoice::Key(const KeyInput &key) { if (key.flags & KEY_DOWN) { if (IsAcceptKey(key)) { down_ = true; + UI::PlayUISound(UI::UISound::TOGGLE_ON); Click(); return true; } @@ -425,6 +425,11 @@ void ClickableItem::Draw(UIContext &dc) { DrawBG(dc, style); } +void Choice::Click() { + ClickableItem::Click(); + UI::PlayUISound(UI::UISound::CONFIRM); +} + void Choice::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const { if (atlasImage_.isValid()) { dc.Draw()->GetAtlas()->measureImage(atlasImage_, &w, &h); @@ -597,8 +602,10 @@ void PopupHeader::Draw(UIContext &dc) { } void CheckBox::Toggle() { - if (toggle_) + if (toggle_) { *toggle_ = !(*toggle_); + UI::PlayUISound(*toggle_ ? UI::UISound::TOGGLE_ON : UI::UISound::TOGGLE_OFF); + } } bool CheckBox::Toggled() const { @@ -669,8 +676,14 @@ void CheckBox::GetContentDimensions(const UIContext &dc, float &w, float &h) con } void BitCheckBox::Toggle() { - if (bitfield_) + if (bitfield_) { *bitfield_ = *bitfield_ ^ bit_; + if (*bitfield_ & bit_) { + UI::PlayUISound(UI::UISound::TOGGLE_ON); + } else { + UI::PlayUISound(UI::UISound::TOGGLE_OFF); + } + } } bool BitCheckBox::Toggled() const { @@ -690,6 +703,11 @@ void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const h += paddingH_; } +void Button::Click() { + Clickable::Click(); + UI::PlayUISound(UI::UISound::CONFIRM); +} + void Button::Draw(UIContext &dc) { Style style = dc.theme->buttonStyle; diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index 5cf1ad275c..335ce822e8 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -519,6 +519,7 @@ public: Button(const std::string &text, ImageID imageID, LayoutParams *layoutParams = 0) : Clickable(layoutParams), text_(text), imageID_(imageID) {} + void Click() override; void Draw(UIContext &dc) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; const std::string &GetText() const { return text_; } @@ -647,6 +648,7 @@ public: Choice(ImageID image, LayoutParams *layoutParams = nullptr) : ClickableItem(layoutParams), atlasImage_(image), iconImage_(ImageID::invalid()), centered_(false), highlighted_(false), selected_(false) {} + virtual void Click(); virtual void HighlightChanged(bool highlighted); void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override; void Draw(UIContext &dc) override; diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index 7d188743f0..e9f2f88176 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -9,6 +9,7 @@ #include "math/curves.h" #include "ui/ui_context.h" #include "ui/ui_tween.h" +#include "ui/root.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "gfx_es2/draw_buffer.h" @@ -1321,11 +1322,17 @@ void ChoiceStrip::HighlightChoice(unsigned int choice){ bool ChoiceStrip::Key(const KeyInput &input) { bool ret = false; if (input.flags & KEY_DOWN) { - if (IsTabLeftKey(input) && selected_ > 0) { - SetSelection(selected_ - 1); + if (IsTabLeftKey(input)) { + if (selected_ > 0) { + SetSelection(selected_ - 1); + UI::PlayUISound(UI::UISound::TOGGLE_OFF); // Maybe make specific sounds for this at some point? + } ret = true; - } else if (IsTabRightKey(input) && selected_ < (int)views_.size() - 1) { - SetSelection(selected_ + 1); + } else if (IsTabRightKey(input)) { + if (selected_ < (int)views_.size() - 1) { + SetSelection(selected_ + 1); + UI::PlayUISound(UI::UISound::TOGGLE_ON); + } ret = true; } } From b77d954bc1e307d9e57eb37c634c305039e69d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 12:14:38 +0200 Subject: [PATCH 425/848] Off by default --- Core/Config.cpp | 2 +- UI/GameSettingsScreen.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index a5c217248c..d700dcd4fe 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -433,7 +433,7 @@ static ConfigSetting generalSettings[] = { ConfigSetting("Language", &g_Config.sLanguageIni, &DefaultLangRegion), 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... - ConfigSetting("UISound", &g_Config.bUISound, true, true, false), + ConfigSetting("UISound", &g_Config.bUISound, false, true, false), ReportedConfigSetting("NumWorkerThreads", &g_Config.iNumWorkerThreads, &DefaultNumWorkers, true, true), ConfigSetting("AutoLoadSaveState", &g_Config.iAutoLoadSaveState, 0, true, true), diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index cb312c0145..e0c8d2750f 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -816,8 +816,9 @@ void GameSettingsScreen::CreateViews() { systemSettingsScroll->Add(systemSettings); tabHolder->AddTab(ms->T("System"), systemSettingsScroll); - systemSettings->Add(new ItemHeader(sy->T("UI Language"))); + systemSettings->Add(new ItemHeader(sy->T("UI Language"))); // Should be renamed "UI"? systemSettings->Add(new Choice(dev->T("Language", "Language")))->OnClick.Handle(this, &GameSettingsScreen::OnLanguage); + systemSettings->Add(new CheckBox(&g_Config.bUISound, dev->T("UI Sound"))); systemSettings->Add(new ItemHeader(sy->T("Help the PPSSPP team"))); enableReports_ = Reporting::IsEnabled(); @@ -859,7 +860,6 @@ void GameSettingsScreen::CreateViews() { } } #endif - systemSettings->Add(new CheckBox(&g_Config.bUISound, dev->T("UI Sound"))); systemSettings->Add(new CheckBox(&g_Config.bCheckForNewVersion, sy->T("VersionCheck", "Check for new versions of PPSSPP"))); const std::string bgPng = GetSysDirectory(DIRECTORY_SYSTEM) + "background.png"; const std::string bgJpg = GetSysDirectory(DIRECTORY_SYSTEM) + "background.jpg"; From ce2fc7d986439d8d4fda816a7e2576bf53b9b80e Mon Sep 17 00:00:00 2001 From: iota97 Date: Mon, 3 Aug 2020 15:52:52 +0200 Subject: [PATCH 426/848] Fix texture upscaling and per game setting fix/cleanup --- Core/Config.cpp | 18 +++++++++--------- GPU/Vulkan/TextureCacheVulkan.cpp | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 2a696abaf4..e8657bd4be 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -450,19 +450,19 @@ static ConfigSetting generalSettings[] = { ConfigSetting("EnableStateUndo", &g_Config.bEnableStateUndo, &DefaultEnableStateUndo, true, true), ConfigSetting("RewindFlipFrequency", &g_Config.iRewindFlipFrequency, 0, true, true), - ConfigSetting("ShowRegionOnGameIcon", &g_Config.bShowRegionOnGameIcon, false, true, true), - ConfigSetting("ShowIDOnGameIcon", &g_Config.bShowIDOnGameIcon, false, true, true), - ConfigSetting("GameGridScale", &g_Config.fGameGridScale, 1.0, true, true), + ConfigSetting("ShowRegionOnGameIcon", &g_Config.bShowRegionOnGameIcon, false), + ConfigSetting("ShowIDOnGameIcon", &g_Config.bShowIDOnGameIcon, false), + ConfigSetting("GameGridScale", &g_Config.fGameGridScale, 1.0), ConfigSetting("GridView1", &g_Config.bGridView1, true), ConfigSetting("GridView2", &g_Config.bGridView2, true), ConfigSetting("GridView3", &g_Config.bGridView3, false), ConfigSetting("ComboMode", &g_Config.iComboMode, 0), - ConfigSetting("RightAnalogUp", &g_Config.iRightAnalogUp, 0), - ConfigSetting("RightAnalogDown", &g_Config.iRightAnalogDown, 0), - ConfigSetting("RightAnalogLeft", &g_Config.iRightAnalogLeft, 0), - ConfigSetting("RightAnalogRight", &g_Config.iRightAnalogRight, 0), - ConfigSetting("RightAnalogPress", &g_Config.iRightAnalogPress, 0), - ConfigSetting("RightAnalogCustom", &g_Config.bRightAnalogCustom, false), + ConfigSetting("RightAnalogUp", &g_Config.iRightAnalogUp, 0, true, true), + ConfigSetting("RightAnalogDown", &g_Config.iRightAnalogDown, 0, true, true), + ConfigSetting("RightAnalogLeft", &g_Config.iRightAnalogLeft, 0, true, true), + ConfigSetting("RightAnalogRight", &g_Config.iRightAnalogRight, 0, true, true), + ConfigSetting("RightAnalogPress", &g_Config.iRightAnalogPress, 0, true, true), + ConfigSetting("RightAnalogCustom", &g_Config.bRightAnalogCustom, false, true, true), // "default" means let emulator decide, "" means disable. ConfigSetting("ReportingHost", &g_Config.sReportHost, "default"), diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index b46ca05710..28bef1d9a6 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -397,6 +397,7 @@ void TextureCacheVulkan::CompileScalingShader() { if (!g_Config.bTexHardwareScaling) return; + ReloadAllPostShaderInfo(); const TextureShaderInfo *shaderInfo = GetTextureShaderInfo(g_Config.sTextureShaderName); if (!shaderInfo || shaderInfo->computeShaderFile.empty()) return; From 9f7839c96a1961313cd490f0d0ff8b0816a527ab Mon Sep 17 00:00:00 2001 From: Filippo Scognamiglio Date: Mon, 3 Aug 2020 12:24:43 +0200 Subject: [PATCH 427/848] Fix Android Libretro build issues. --- libretro/Makefile.common | 8 ++------ libretro/jni/Android.mk | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 624d3f837c..7d44b4402f 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -486,7 +486,6 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/Util/PPGeDraw.cpp \ $(COREDIR)/Util/AudioFormat.cpp \ $(COREDIR)/Util/PortManager.cpp \ - $(EXTDIR)/disarm.cpp \ $(CORE_DIR)/UI/TextureUtil.cpp \ $(CORE_DIR)/UI/GameInfoCache.cpp @@ -509,6 +508,7 @@ ifeq ($(WITH_DYNAREC),1) $(COREDIR)/MIPS/ARM/ArmJit.cpp \ $(COREDIR)/MIPS/ARM/ArmRegCache.cpp \ $(COREDIR)/MIPS/ARM/ArmRegCacheFPU.cpp \ + $(EXTDIR)/disarm.cpp \ $(GPUCOMMONDIR)/VertexDecoderArm.cpp ifeq ($(HAVE_NEON),1) @@ -545,6 +545,7 @@ ifeq ($(WITH_DYNAREC),1) SOURCES_CXX += \ $(COREDIR)/MIPS/ARM/ArmCompVFPUNEON.cpp \ $(COREDIR)/MIPS/ARM/ArmCompVFPUNEONUtil.cpp \ + $(COREDIR)/Util/AudioFormatNEON.cpp \ $(COMMONDIR)/ColorConvNEON.cpp \ $(GPUDIR)/Common/TextureDecoderNEON.cpp @@ -591,11 +592,6 @@ endif SOURCES_C += $(NATIVEDIR)/math/fast/fast_matrix_sse.c endif endif -SOURCES_CXX += \ - $(COMMONDIR)/ArmEmitter.cpp \ - $(COMMONDIR)/Arm64Emitter.cpp \ - $(COREDIR)/Util/DisArm64.cpp - #UDIS86 # Compiled and linked even on ARM for now diff --git a/libretro/jni/Android.mk b/libretro/jni/Android.mk index e1b48c2f7a..f5703ba4c4 100644 --- a/libretro/jni/Android.mk +++ b/libretro/jni/Android.mk @@ -9,6 +9,7 @@ COREFLAGS := CORE_DIR := ../.. FFMPEGDIR := $(CORE_DIR)/ffmpeg FFMPEGLIBS += libavformat libavcodec libavutil libswresample libswscale +WITH_DYNAREC := 1 ifeq ($(TARGET_ARCH),arm64) COREFLAGS += -DARM64 -D_ARCH_64 From cbdb9cc5dc00d398eaae416e1105bdff30ced3cb Mon Sep 17 00:00:00 2001 From: Filippo Scognamiglio Date: Mon, 3 Aug 2020 19:04:40 +0200 Subject: [PATCH 428/848] Expose SYSPROP_SYSTEMVERSION to Libretro Android core. This fixes crashes with targetSdk 29. --- libretro/libretro.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 2525541daa..2a962377a3 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "base/timeutil.h" #include "Common/ChunkFile.h" @@ -32,6 +33,10 @@ #include "libretro/libretro.h" #include "libretro/LibretroGraphicsContext.h" +#if PPSSPP_PLATFORM(ANDROID) +#include +#endif + #define DIR_SEP "/" #ifdef _WIN32 #define DIR_SEP_CHRS "/\\" @@ -857,6 +862,15 @@ int System_GetPropertyInt(SystemProperty prop) { case SYSPROP_AUDIO_SAMPLE_RATE: return SAMPLERATE; +#if PPSSPP_PLATFORM(ANDROID) + case SYSPROP_SYSTEMVERSION: { + char sdk[PROP_VALUE_MAX] = {0}; + if (__system_property_get("ro.build.version.sdk", sdk) != 0) { + return atoi(sdk); + } + return -1; + } +#endif default: break; } From de178d617b0e3c4c7d985a51bba30d38d4cf9dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 23:14:27 +0200 Subject: [PATCH 429/848] Move a line to a better place --- GPU/Vulkan/TextureCacheVulkan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 28bef1d9a6..f4edb36944 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -712,7 +712,6 @@ VkFormat ToVulkanFormat(ReplacedTextureFormat fmt) { void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { entry->status &= ~TexCacheEntry::STATUS_ALPHA_MASK; - VkCommandBuffer cmdInit = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER); // For the estimate, we assume cluts always point to 8888 for simplicity. cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); @@ -816,6 +815,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { bool computeUpload = false; bool computeCopy = false; + VkCommandBuffer cmdInit = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER); { delete entry->vkTex; From d57edfbdaca42c1ac3838683a569859b3842c4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 23:17:22 +0200 Subject: [PATCH 430/848] Rename FramebufferCommon.cpp/h to FramebufferManagerCommon.cpp/h for consistency --- CMakeLists.txt | 4 ++-- Core/Config.cpp | 2 +- Core/HLE/sceDisplay.cpp | 2 +- ...bufferCommon.cpp => FramebufferManagerCommon.cpp} | 2 +- ...ramebufferCommon.h => FramebufferManagerCommon.h} | 0 GPU/Common/GPUStateUtils.cpp | 2 +- GPU/Common/ShaderUniforms.cpp | 2 +- GPU/Common/SoftwareTransformCommon.cpp | 2 +- GPU/Common/TextureCacheCommon.cpp | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 2 +- GPU/D3D11/FramebufferManagerD3D11.h | 2 +- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/D3D11/StateMappingD3D11.cpp | 2 +- GPU/D3D11/TextureCacheD3D11.cpp | 2 +- GPU/Directx9/FramebufferDX9.cpp | 2 +- GPU/Directx9/FramebufferDX9.h | 2 +- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GLES/FramebufferManagerGLES.cpp | 2 +- GPU/GLES/FramebufferManagerGLES.h | 2 +- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GPU.vcxproj | 4 ++-- GPU/GPU.vcxproj.filters | 12 ++++++------ GPU/GPUCommon.cpp | 2 +- GPU/Vulkan/FramebufferVulkan.cpp | 2 +- GPU/Vulkan/FramebufferVulkan.h | 2 +- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- UI/DisplayLayoutScreen.cpp | 2 +- UI/EmuScreen.cpp | 2 +- UI/GameSettingsScreen.cpp | 2 +- UWP/GPU_UWP/GPU_UWP.vcxproj | 6 +++--- UWP/GPU_UWP/GPU_UWP.vcxproj.filters | 6 +++--- Windows/MainWindowMenu.cpp | 2 +- android/jni/Android.mk | 2 +- headless/Headless.cpp | 2 +- libretro/Makefile.common | 2 +- libretro/libretro.cpp | 2 +- 37 files changed, 47 insertions(+), 47 deletions(-) rename GPU/Common/{FramebufferCommon.cpp => FramebufferManagerCommon.cpp} (99%) rename GPU/Common/{FramebufferCommon.h => FramebufferManagerCommon.h} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b07111e86..e06deae2cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1352,8 +1352,8 @@ set(GPU_SOURCES ${GPU_NEON} GPU/Common/DepalettizeShaderCommon.cpp GPU/Common/DepalettizeShaderCommon.h - GPU/Common/FramebufferCommon.cpp - GPU/Common/FramebufferCommon.h + GPU/Common/FramebufferManagerCommon.cpp + GPU/Common/FramebufferManagerCommon.h GPU/Common/GPUDebugInterface.cpp GPU/Common/GPUDebugInterface.h GPU/Common/GPUStateUtils.cpp diff --git a/Core/Config.cpp b/Core/Config.cpp index db67ba515b..d28e9c2494 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -43,7 +43,7 @@ #include "Core/Loaders.h" #include "Core/HLE/sceUtility.h" #include "Core/Instance.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" // TODO: Find a better place for this. http::Downloader g_DownloadManager; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 12c069ab0e..305339d86c 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -55,7 +55,7 @@ #include "GPU/GPU.h" #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PostShader.h" #include "GPU/Debugger/Record.h" diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp similarity index 99% rename from GPU/Common/FramebufferCommon.cpp rename to GPU/Common/FramebufferManagerCommon.cpp index 9dab512165..c93f838e18 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -33,7 +33,7 @@ #include "Core/Host.h" #include "Core/Reporting.h" #include "GPU/Common/DrawEngineCommon.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PostShader.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/TextureCacheCommon.h" diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferManagerCommon.h similarity index 100% rename from GPU/Common/FramebufferCommon.h rename to GPU/Common/FramebufferManagerCommon.h diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 5406f9d360..bf95736774 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -28,7 +28,7 @@ #include "GPU/ge_constants.h" #include "GPU/GPUState.h" #include "GPU/Math3D.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/ShaderId.h" #include "GPU/Common/VertexDecoderCommon.h" diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index be3391cc90..c80ae842ef 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -8,7 +8,7 @@ #include "math/math_util.h" #include "math/lin/vec3.h" #include "GPU/GPUState.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/GPUStateUtils.h" #include "GPU/Math3D.h" diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 2c14865a6b..c7e18fff21 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -23,7 +23,7 @@ #include "Core/Config.h" #include "GPU/GPUState.h" #include "GPU/Math3D.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/GPUStateUtils.h" #include "GPU/Common/SoftwareTransformCommon.h" #include "GPU/Common/TransformCommon.h" diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 8680f33f1b..462e72fc63 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -23,7 +23,7 @@ #include "Core/Config.h" #include "Core/Reporting.h" #include "Core/System.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureCacheCommon.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/Common/ShaderId.h" diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 1ec5128cdb..74ded8bc75 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -35,7 +35,7 @@ #include "GPU/GPUState.h" #include "GPU/Debugger/Stepping.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/ShaderTranslation.h" #include "GPU/Common/TextureDecoder.h" diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index 1f91af61ae..a1683c299c 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -24,7 +24,7 @@ // pixel data. #include "GPU/GPUCommon.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "ext/native/thin3d/thin3d.h" class TextureCacheD3D11; diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 6e497064c7..13cbb442fc 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -53,7 +53,7 @@ #include "GPU/ge_constants.h" #include "GPU/GeDisasm.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Debugger/Debugger.h" #include "GPU/D3D11/ShaderManagerD3D11.h" #include "GPU/D3D11/GPU_D3D11.h" diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 51674571c8..cb10fd96f2 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -28,7 +28,7 @@ #include "Core/Config.h" #include "Core/Reporting.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/D3D11/DrawEngineD3D11.h" #include "GPU/D3D11/StateMappingD3D11.h" #include "GPU/D3D11/FramebufferManagerD3D11.h" diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 4b342eb296..70fee76b59 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -32,7 +32,7 @@ #include "GPU/D3D11/ShaderManagerD3D11.h" #include "GPU/D3D11/DepalettizeShaderD3D11.h" #include "GPU/D3D11/D3D11Util.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureDecoder.h" #include "Core/Config.h" #include "Core/Host.h" diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index c3cb5ff1dd..53123b8255 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -29,7 +29,7 @@ #include "GPU/Debugger/Stepping.h" #include "gfx/d3d9_state.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/ShaderTranslation.h" #include "GPU/Common/TextureDecoder.h" diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index d311c8aa78..b164a9b0e7 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -26,7 +26,7 @@ // pixel data. #include "GPU/GPUCommon.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" namespace DX9 { diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index a51db99ca4..502f20205b 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -38,7 +38,7 @@ #include "GPU/ge_constants.h" #include "GPU/GeDisasm.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Debugger/Debugger.h" #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/GPU_DX9.h" diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index e10aff8cc2..2cbfaa978e 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -30,7 +30,7 @@ #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/DepalettizeShaderDX9.h" #include "gfx/d3d9_state.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureDecoder.h" #include "Core/Config.h" #include "Core/Host.h" diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index d3ae9616c7..3d28e9bc98 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -31,7 +31,7 @@ #include "Core/Reporting.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/Debugger/Stepping.h" diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index f86fb1218f..12a3eb85c5 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -23,7 +23,7 @@ // pixel data. #include "GPU/GPUCommon.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "thin3d/GLRenderManager.h" struct GLSLProgram; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 64f872d3a0..0d4e0035e3 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -34,7 +34,7 @@ #include "GPU/GPUState.h" #include "GPU/ge_constants.h" #include "GPU/GeDisasm.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Debugger/Debugger.h" #include "GPU/GLES/ShaderManagerGLES.h" #include "GPU/GLES/GPU_GLES.h" diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index e427e500bf..e9c82cba8d 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -340,7 +340,7 @@ - + @@ -493,7 +493,7 @@ - + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index e5e6f1a0e7..3935a822bc 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -129,9 +129,6 @@ Common - - Common - Common @@ -288,6 +285,9 @@ Common + + Common + @@ -383,9 +383,6 @@ Common - - Common - Common @@ -572,5 +569,8 @@ Common + + Common + \ No newline at end of file diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 190a4fd2db..73278fb103 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -26,7 +26,7 @@ #include "Core/Debugger/Breakpoints.h" #include "Core/MemMapHelpers.h" #include "GPU/Common/DrawEngineCommon.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/SplineCommon.h" #include "GPU/Common/TextureCacheCommon.h" #include "GPU/Debugger/Debugger.h" diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 7fb74a2f96..430b37987a 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -41,7 +41,7 @@ #include "GPU/GPUState.h" #include "GPU/Common/TextureDecoder.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Debugger/Stepping.h" #include "GPU/Vulkan/FramebufferVulkan.h" #include "GPU/Vulkan/DrawEngineVulkan.h" diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index 622ad28164..b66eeb6033 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -19,7 +19,7 @@ #include "Common/Vulkan/VulkanLoader.h" #include "GPU/GPUInterface.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/GPUDebugInterface.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Vulkan/VulkanUtil.h" diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index b0e4ebf641..17a7e89563 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -35,7 +35,7 @@ #include "GPU/GPUState.h" #include "GPU/ge_constants.h" #include "GPU/GeDisasm.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Debugger/Debugger.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Vulkan/GPU_Vulkan.h" diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 7b210c2c85..7dba4e28ed 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -31,7 +31,7 @@ #include "Core/ConfigValues.h" #include "Core/System.h" #include "DisplayLayoutEditor.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" static const int leftColumnWidth = 200; static const float orgRatio = 1.764706f; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index a2b476fa25..08476fbad0 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -52,7 +52,7 @@ #include "Core/System.h" #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #if !PPSSPP_PLATFORM(UWP) #include "GPU/Vulkan/DebugVisVulkan.h" #endif diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index e0c8d2750f..5594e2e035 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -64,7 +64,7 @@ #include "GPU/Common/PostShader.h" #include "android/jni/TestRunner.h" #include "GPU/GPUInterface.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #if defined(_WIN32) && !PPSSPP_PLATFORM(UWP) #pragma warning(disable:4091) // workaround bug in VS2015 headers diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index 356e226e26..0a0e4ee197 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -381,7 +381,7 @@ - + @@ -440,7 +440,7 @@ - + @@ -526,4 +526,4 @@ - \ No newline at end of file + diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index c72d9173e4..3c47339764 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -3,7 +3,7 @@ - + @@ -62,7 +62,7 @@ - + @@ -118,4 +118,4 @@ - \ No newline at end of file + diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index e95816204a..6a3447cdc3 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -23,7 +23,7 @@ #endif #include "UI/OnScreenDisplay.h" #include "GPU/Common/PostShader.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureCacheCommon.h" #include "GPU/Common/TextureScalerCommon.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 3df8536529..b1eb79d940 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -227,7 +227,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/GPUState.cpp \ $(SRC)/GPU/GeDisasm.cpp \ $(SRC)/GPU/Common/DepalettizeShaderCommon.cpp \ - $(SRC)/GPU/Common/FramebufferCommon.cpp \ + $(SRC)/GPU/Common/FramebufferManagerCommon.cpp \ $(SRC)/GPU/Common/PresentationCommon.cpp \ $(SRC)/GPU/Common/GPUDebugInterface.cpp \ $(SRC)/GPU/Common/IndexGenerator.cpp.arm \ diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 8246a7df43..77af343446 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -21,7 +21,7 @@ #include "Core/HLE/sceUtility.h" #include "Core/Host.h" #include "Core/SaveState.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "Log.h" #include "LogManager.h" #include "base/NativeApp.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 7d44b4402f..fd5293aa7a 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -162,7 +162,7 @@ SOURCES_CXX += \ $(GPUCOMMONDIR)/GPUStateUtils.cpp \ $(GPUCOMMONDIR)/DrawEngineCommon.cpp \ $(GPUCOMMONDIR)/SplineCommon.cpp \ - $(GPUCOMMONDIR)/FramebufferCommon.cpp \ + $(GPUCOMMONDIR)/FramebufferManagerCommon.cpp \ $(GPUCOMMONDIR)/PresentationCommon.cpp \ $(GPUCOMMONDIR)/ShaderId.cpp \ $(GPUCOMMONDIR)/ShaderCommon.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 2a962377a3..2c782a4b3c 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -24,7 +24,7 @@ #include "file/zip_read.h" #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" -#include "GPU/Common/FramebufferCommon.h" +#include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureScalerCommon.h" #include "input/input_state.h" #include "base/NativeApp.h" From 882cc6295e1dabe8d501c03d18416ade7802d18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 23:22:11 +0200 Subject: [PATCH 431/848] Rename FramebufferVulkan.cpp/h to FramebufferManagerVulkan.cpp/h --- CMakeLists.txt | 4 ++-- GPU/GPU.vcxproj | 6 +++--- GPU/GPU.vcxproj.filters | 6 +++--- GPU/Vulkan/DrawEngineVulkan.cpp | 2 +- GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp | 2 +- .../{FramebufferVulkan.cpp => FramebufferManagerVulkan.cpp} | 2 +- .../{FramebufferVulkan.h => FramebufferManagerVulkan.h} | 0 GPU/Vulkan/GPU_Vulkan.cpp | 2 +- GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/StateMappingVulkan.cpp | 2 +- GPU/Vulkan/StencilBufferVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 2 +- android/jni/Android.mk | 2 +- libretro/Makefile.common | 2 +- 14 files changed, 18 insertions(+), 18 deletions(-) rename GPU/Vulkan/{FramebufferVulkan.cpp => FramebufferManagerVulkan.cpp} (99%) rename GPU/Vulkan/{FramebufferVulkan.h => FramebufferManagerVulkan.h} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e06deae2cf..91ec9ce4d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1267,8 +1267,8 @@ set(GPU_VULKAN GPU/Vulkan/DrawEngineVulkan.h GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp GPU/Vulkan/FragmentShaderGeneratorVulkan.h - GPU/Vulkan/FramebufferVulkan.cpp - GPU/Vulkan/FramebufferVulkan.h + GPU/Vulkan/FramebufferManagerVulkan.cpp + GPU/Vulkan/FramebufferManagerVulkan.h GPU/Vulkan/GPU_Vulkan.cpp GPU/Vulkan/GPU_Vulkan.h GPU/Vulkan/PipelineManagerVulkan.cpp diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index e9c82cba8d..d00e1b8e60 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -479,7 +479,7 @@ - + @@ -671,7 +671,7 @@ - + @@ -693,4 +693,4 @@ - \ No newline at end of file + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 3935a822bc..a74f43458a 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -165,7 +165,7 @@ Vulkan - + Vulkan @@ -533,7 +533,7 @@ Common - + Vulkan @@ -573,4 +573,4 @@ Common - \ No newline at end of file + diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 506716dd00..cad3b34225 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -48,7 +48,7 @@ #include "GPU/Vulkan/TextureCacheVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Vulkan/PipelineManagerVulkan.h" -#include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/GPU_Vulkan.h" diff --git a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp index 361d38813c..87e07857c0 100644 --- a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp @@ -26,7 +26,7 @@ #include "GPU/Common/GPUStateUtils.h" #include "GPU/Common/ShaderId.h" #include "GPU/Vulkan/FragmentShaderGeneratorVulkan.h" -#include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Vulkan/PipelineManagerVulkan.h" diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp similarity index 99% rename from GPU/Vulkan/FramebufferVulkan.cpp rename to GPU/Vulkan/FramebufferManagerVulkan.cpp index 430b37987a..5c4d0f0b51 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -43,7 +43,7 @@ #include "GPU/Common/TextureDecoder.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Debugger/Stepping.h" -#include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/DrawEngineVulkan.h" #include "GPU/Vulkan/TextureCacheVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferManagerVulkan.h similarity index 100% rename from GPU/Vulkan/FramebufferVulkan.h rename to GPU/Vulkan/FramebufferManagerVulkan.h diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 17a7e89563..99002e68f4 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -39,7 +39,7 @@ #include "GPU/Debugger/Debugger.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Vulkan/GPU_Vulkan.h" -#include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/DrawEngineVulkan.h" #include "GPU/Vulkan/TextureCacheVulkan.h" #include "thin3d/VulkanRenderManager.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 6e6cff086a..515adb158d 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -38,7 +38,7 @@ #include "GPU/ge_constants.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Vulkan/DrawEngineVulkan.h" -#include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/FragmentShaderGeneratorVulkan.h" #include "GPU/Vulkan/VertexShaderGeneratorVulkan.h" diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index d2a3e8591c..68f4bffefd 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -29,7 +29,7 @@ #include "GPU/Vulkan/GPU_Vulkan.h" #include "GPU/Vulkan/PipelineManagerVulkan.h" #include "GPU/Vulkan/TextureCacheVulkan.h" -#include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Vulkan/DrawEngineVulkan.h" diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 1384d957c1..c952a57b37 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -21,7 +21,7 @@ #include "ext/native/thin3d/VulkanRenderManager.h" #include "Core/Reporting.h" #include "GPU/Common/StencilCommon.h" -#include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/FragmentShaderGeneratorVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Vulkan/TextureCacheVulkan.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index f4edb36944..5476af392a 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -43,7 +43,7 @@ #include "GPU/Common/TextureCacheCommon.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/Vulkan/TextureCacheVulkan.h" -#include "GPU/Vulkan/FramebufferVulkan.h" +#include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/FragmentShaderGeneratorVulkan.h" #include "GPU/Vulkan/DepalettizeShaderVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index b1eb79d940..252572d1ba 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -134,7 +134,7 @@ VULKAN_FILES := \ $(SRC)/Common/Vulkan/VulkanMemory.cpp \ $(SRC)/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp \ $(SRC)/GPU/Vulkan/DrawEngineVulkan.cpp \ - $(SRC)/GPU/Vulkan/FramebufferVulkan.cpp \ + $(SRC)/GPU/Vulkan/FramebufferManagerVulkan.cpp \ $(SRC)/GPU/Vulkan/GPU_Vulkan.cpp \ $(SRC)/GPU/Vulkan/PipelineManagerVulkan.cpp \ $(SRC)/GPU/Vulkan/ShaderManagerVulkan.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index fd5293aa7a..b4abe5a65d 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -630,7 +630,7 @@ SOURCES_CXX += \ $(GPUDIR)/Vulkan/DepalettizeShaderVulkan.cpp \ $(GPUDIR)/Vulkan/DrawEngineVulkan.cpp \ $(GPUDIR)/Vulkan/FragmentShaderGeneratorVulkan.cpp \ - $(GPUDIR)/Vulkan/FramebufferVulkan.cpp \ + $(GPUDIR)/Vulkan/FramebufferManagerVulkan.cpp \ $(GPUDIR)/Vulkan/GPU_Vulkan.cpp \ $(GPUDIR)/Vulkan/PipelineManagerVulkan.cpp \ $(GPUDIR)/Vulkan/ShaderManagerVulkan.cpp \ From cb568b8f5e2b14188bfae22e60cbac6fade441ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 23:24:50 +0200 Subject: [PATCH 432/848] Rename FramebufferDX9.cpp/h to FramebufferManagerDX9.cpp/h --- CMakeLists.txt | 4 ++-- ...ramebufferDX9.cpp => FramebufferManagerDX9.cpp} | 2 +- .../{FramebufferDX9.h => FramebufferManagerDX9.h} | 0 GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/Directx9/GPU_DX9.h | 2 +- GPU/Directx9/ShaderManagerDX9.cpp | 2 +- GPU/Directx9/StateMappingDX9.cpp | 2 +- GPU/Directx9/StencilBufferDX9.cpp | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GPU.vcxproj | 6 +++--- GPU/GPU.vcxproj.filters | 14 +++++++------- libretro/Makefile.common | 2 +- 12 files changed, 20 insertions(+), 20 deletions(-) rename GPU/Directx9/{FramebufferDX9.cpp => FramebufferManagerDX9.cpp} (99%) rename GPU/Directx9/{FramebufferDX9.h => FramebufferManagerDX9.h} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91ec9ce4d6..a6d488f2df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1295,8 +1295,8 @@ set(GPU_D3D9 GPU/Directx9/DrawEngineDX9.h GPU/Directx9/PixelShaderGeneratorDX9.cpp GPU/Directx9/PixelShaderGeneratorDX9.h - GPU/Directx9/FramebufferDX9.cpp - GPU/Directx9/FramebufferDX9.h + GPU/Directx9/FramebufferManagerDX9.cpp + GPU/Directx9/FramebufferManagerDX9.h GPU/Directx9/GPU_DX9.cpp GPU/Directx9/GPU_DX9.h GPU/Directx9/ShaderManagerDX9.cpp diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp similarity index 99% rename from GPU/Directx9/FramebufferDX9.cpp rename to GPU/Directx9/FramebufferManagerDX9.cpp index 53123b8255..5e70c0b350 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -33,7 +33,7 @@ #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/ShaderTranslation.h" #include "GPU/Common/TextureDecoder.h" -#include "GPU/Directx9/FramebufferDX9.h" +#include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/TextureCacheDX9.h" #include "GPU/Directx9/DrawEngineDX9.h" diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferManagerDX9.h similarity index 100% rename from GPU/Directx9/FramebufferDX9.h rename to GPU/Directx9/FramebufferManagerDX9.h diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 502f20205b..9c490edfa9 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -42,7 +42,7 @@ #include "GPU/Debugger/Debugger.h" #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/GPU_DX9.h" -#include "GPU/Directx9/FramebufferDX9.h" +#include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/DrawEngineDX9.h" #include "GPU/Directx9/TextureCacheDX9.h" diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h index 95980c5c35..aab20eabe1 100644 --- a/GPU/Directx9/GPU_DX9.h +++ b/GPU/Directx9/GPU_DX9.h @@ -21,7 +21,7 @@ #include #include "GPU/GPUCommon.h" -#include "GPU/Directx9/FramebufferDX9.h" +#include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/DrawEngineDX9.h" #include "GPU/Directx9/TextureCacheDX9.h" #include "GPU/Directx9/DepalettizeShaderDX9.h" diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 4c3c79701b..856150bbb3 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -40,7 +40,7 @@ #include "GPU/Common/ShaderUniforms.h" #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/DrawEngineDX9.h" -#include "GPU/Directx9/FramebufferDX9.h" +#include "GPU/Directx9/FramebufferManagerDX9.h" using namespace Lin; diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 9f8a251451..f1c5309853 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -29,7 +29,7 @@ #include "GPU/Directx9/GPU_DX9.h" #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/TextureCacheDX9.h" -#include "GPU/Directx9/FramebufferDX9.h" +#include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/PixelShaderGeneratorDX9.h" namespace DX9 { diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 707f63b9d6..5c0459c6e8 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -23,7 +23,7 @@ #include "ext/native/thin3d/thin3d.h" #include "Core/Reporting.h" #include "GPU/Common/StencilCommon.h" -#include "GPU/Directx9/FramebufferDX9.h" +#include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/PixelShaderGeneratorDX9.h" #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/TextureCacheDX9.h" diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 2cbfaa978e..b6c2dcf17c 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -26,7 +26,7 @@ #include "GPU/GPUState.h" #include "GPU/Directx9/PixelShaderGeneratorDX9.h" #include "GPU/Directx9/TextureCacheDX9.h" -#include "GPU/Directx9/FramebufferDX9.h" +#include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/DepalettizeShaderDX9.h" #include "gfx/d3d9_state.h" diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index d00e1b8e60..9ea555f538 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -385,9 +385,9 @@ + - @@ -564,9 +564,9 @@ + - @@ -693,4 +693,4 @@ - + \ No newline at end of file diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index a74f43458a..8dcbf8229d 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -84,9 +84,6 @@ DirectX9 - - DirectX9 - DirectX9 @@ -288,6 +285,9 @@ Common + + DirectX9 + @@ -341,9 +341,6 @@ DirectX9 - - DirectX9 - DirectX9 @@ -572,5 +569,8 @@ Common + + DirectX9 + - + \ No newline at end of file diff --git a/libretro/Makefile.common b/libretro/Makefile.common index b4abe5a65d..7cbf1ce527 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -654,7 +654,7 @@ SOURCES_CXX += \ $(GPUDIR)/Directx9/DepalettizeShaderDX9.cpp \ $(GPUDIR)/Directx9/DrawEngineDX9.cpp \ $(GPUDIR)/Directx9/PixelShaderGeneratorDX9.cpp \ - $(GPUDIR)/Directx9/FramebufferDX9.cpp \ + $(GPUDIR)/Directx9/FramebufferManagerDX9.cpp \ $(GPUDIR)/Directx9/GPU_DX9.cpp \ $(GPUDIR)/Directx9/ShaderManagerDX9.cpp \ $(GPUDIR)/Directx9/StateMappingDX9.cpp \ From ca04d9b516c1fe094a5ba60e6341a1ec99f3827b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 4 Aug 2020 11:13:17 +0200 Subject: [PATCH 433/848] Improve logging of unknown syscall imports. Also stop reporting these, just not that interesting anymore. --- Core/HLE/sceKernelModule.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index d53aea8e03..ad63d32f45 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -152,7 +152,7 @@ void ImportVarSymbol(const VarSymbolImport &var); void ExportVarSymbol(const VarSymbolExport &var); void UnexportVarSymbol(const VarSymbolExport &var); -void ImportFuncSymbol(const FuncSymbolImport &func, bool reimporting); +void ImportFuncSymbol(const FuncSymbolImport &func, bool reimporting, const char *importingModule); void ExportFuncSymbol(const FuncSymbolExport &func); void UnexportFuncSymbol(const FuncSymbolExport &func); @@ -351,7 +351,7 @@ public: // Keep track and actually hook it up if possible. importedFuncs.push_back(func); impExpModuleNames.insert(func.moduleName); - ImportFuncSymbol(func, reimporting); + ImportFuncSymbol(func, reimporting, GetName()); } void ImportVar(const VarSymbolImport &var) { @@ -711,7 +711,7 @@ void UnexportVarSymbol(const VarSymbolExport &var) { } } -void ImportFuncSymbol(const FuncSymbolImport &func, bool reimporting) { +void ImportFuncSymbol(const FuncSymbolImport &func, bool reimporting, const char *importingModule) { // Prioritize HLE implementations. // TODO: Or not? if (FuncImportIsSyscall(func.moduleName, func.nid)) { @@ -748,9 +748,10 @@ void ImportFuncSymbol(const FuncSymbolImport &func, bool reimporting) { // It hasn't been exported yet, but hopefully it will later. bool isKnownModule = GetModuleIndex(func.moduleName) != -1; if (isKnownModule) { - WARN_LOG_REPORT(LOADER, "Unknown syscall in known module '%s': 0x%08x", func.moduleName, func.nid); + // We used to report this, but I don't think it's very interesting anymore. + WARN_LOG(LOADER, "Unknown syscall from known module '%s': 0x%08x (import for '%s')", func.moduleName, func.nid, importingModule); } else { - INFO_LOG(LOADER, "Function (%s,%08x) unresolved, storing for later resolving", func.moduleName, func.nid); + INFO_LOG(LOADER, "Function (%s,%08x) unresolved in '%s', storing for later resolving", func.moduleName, func.nid, importingModule); } if (isKnownModule || !reimporting) { WriteFuncMissingStub(func.stubAddr, func.nid); From 49efaaef59665330e70a6f9d7ac3bda3cce49440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 3 Aug 2020 23:35:40 +0200 Subject: [PATCH 434/848] Clarify, but don't yet remove, a perf hack for ES devices. Remove a unused sync parameter from readbacks. --- GPU/Common/FramebufferManagerCommon.cpp | 30 +++++++++++++------------ GPU/Common/FramebufferManagerCommon.h | 5 +++-- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index c93f838e18..1ca924df16 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -45,6 +45,10 @@ FramebufferManagerCommon::FramebufferManagerCommon(Draw::DrawContext *draw) : draw_(draw), displayFormat_(GE_FORMAT_565) { presentation_ = new PresentationCommon(draw); + + // See comment from where it's used below. + // As for the use of IsGLES, just the way it was. Scary to change it. + clearFramebufferOnFirstUseHack_ = gl_extensions.IsGLES; } FramebufferManagerCommon::~FramebufferManagerCommon() { @@ -500,7 +504,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) { if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) { - ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height); + ReadFramebufferToMemory(vfb, 0, 0, vfb->width, vfb->height); vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; vfb->firstFrameSaved = true; } else { @@ -527,13 +531,12 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe if (useBufferedRendering_) { if (vfb->fbo) { shaderManager_->DirtyLastShader(); - if (gl_extensions.IsGLES) { - // Some tiled mobile GPUs benefit IMMENSELY from clearing an FBO before rendering - // to it. This broke stuff before, so now it only clears on the first use of an - // FBO in a frame. This means that some games won't be able to avoid the on-some-GPUs - // performance-crushing framebuffer reloads from RAM, but we'll have to live with that. - - // Wait, can we even do this? Seems highly unsafe.. TODO: Remove + if (clearFramebufferOnFirstUseHack_) { + // HACK: Some tiled mobile GPUs benefit IMMENSELY from clearing an FBO before rendering + // to it (or in Vulkan, clear during framebuffer load). This is a hack to force this + // the first time a framebuffer is bound for rendering in a frame. + // + // Quite unsafe as it might kill some feedback effects. if (vfb->last_frame_render != gpuStats.numFlips) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "FramebufferSwitch"); } else { @@ -809,7 +812,7 @@ void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *v // To support this, we save the first frame to memory when we have a safe w/h. // Saving each frame would be slow. if (!g_Config.bDisableSlowFramebufEffects) { - ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight); + ReadFramebufferToMemory(vfb, 0, 0, vfb->safeWidth, vfb->safeHeight); vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; vfb->firstFrameSaved = true; vfb->safeWidth = 0; @@ -975,8 +978,7 @@ void FramebufferManagerCommon::DecimateFBOs() { int age = frameLastFramebufUsed_ - std::max(vfb->last_frame_render, vfb->last_frame_used); if (ShouldDownloadFramebuffer(vfb) && age == 0 && !vfb->memoryUpdated) { - bool sync = gl_extensions.IsGLES; - ReadFramebufferToMemory(vfb, sync, 0, 0, vfb->width, vfb->height); + ReadFramebufferToMemory(vfb, 0, 0, vfb->width, vfb->height); vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; vfb->firstFrameSaved = true; } @@ -1187,7 +1189,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, if (srcH == 0 || srcY + srcH > srcBuffer->bufferHeight) { WARN_LOG_REPORT_ONCE(btdcpyheight, G3D, "Memcpy fbo download %08x -> %08x skipped, %d+%d is taller than %d", src, dst, srcY, srcH, srcBuffer->bufferHeight); } else if (g_Config.bBlockTransferGPU && !srcBuffer->memoryUpdated && !PSP_CoreParameter().compat.flags().DisableReadbacks) { - ReadFramebufferToMemory(srcBuffer, true, 0, srcY, srcBuffer->width, srcH); + ReadFramebufferToMemory(srcBuffer, 0, srcY, srcBuffer->width, srcH); srcBuffer->usageFlags = (srcBuffer->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; } return false; @@ -1587,7 +1589,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst } else { if (tooTall) WARN_LOG_ONCE(btdheight, G3D, "Block transfer download %08x -> %08x dangerous, %d+%d is taller than %d", srcBasePtr, dstBasePtr, srcY, srcHeight, srcBuffer->bufferHeight); - ReadFramebufferToMemory(srcBuffer, true, static_cast(srcX * srcXFactor), srcY, static_cast(srcWidth * srcXFactor), srcHeight); + ReadFramebufferToMemory(srcBuffer, static_cast(srcX * srcXFactor), srcY, static_cast(srcWidth * srcXFactor), srcHeight); srcBuffer->usageFlags = (srcBuffer->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; } } @@ -1971,7 +1973,7 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int gpuStats.numReadbacks++; } -void FramebufferManagerCommon::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) { +void FramebufferManagerCommon::ReadFramebufferToMemory(VirtualFramebuffer *vfb, int x, int y, int w, int h) { // Clamp to bufferWidth. Sometimes block transfers can cause this to hit. if (x + w >= vfb->bufferWidth) { w = vfb->bufferWidth - x; diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 07ee628d1e..e1fbd2958c 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -187,7 +187,7 @@ class TextureCacheCommon; class FramebufferManagerCommon { public: - FramebufferManagerCommon(Draw::DrawContext *draw); + explicit FramebufferManagerCommon(Draw::DrawContext *draw); virtual ~FramebufferManagerCommon(); virtual void Init(); @@ -231,7 +231,7 @@ public: bool NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason); void NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason); - void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h); + void ReadFramebufferToMemory(VirtualFramebuffer *vfb, int x, int y, int w, int h); void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes); void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride); @@ -394,6 +394,7 @@ protected: std::vector bvfbs_; // blitting framebuffers (for download) bool gameUsesSequentialCopies_ = false; + bool clearFramebufferOnFirstUseHack_ = false; // Sampled in BeginFrame for safety. float renderWidth_ = 0.0f; From 58ef0c8e8096d4408cd44f72a60890bd25bf7dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 4 Aug 2020 14:45:14 +0200 Subject: [PATCH 435/848] Texture from framebuffer: Logging improvements --- CMakeLists.txt | 2 ++ GPU/Common/FramebufferManagerCommon.cpp | 2 +- GPU/Common/FramebufferManagerCommon.h | 4 ++- GPU/Common/TextureCacheCommon.cpp | 34 +++++++++++++++---------- GPU/Common/TextureCacheCommon.h | 3 ++- GPU/Directx9/TextureCacheDX9.cpp | 1 - GPU/GLES/TextureCacheGLES.cpp | 1 - GPU/GPU.vcxproj | 1 + GPU/GPU.vcxproj.filters | 9 ++++--- GPU/GeConstants.cpp | 28 ++++++++++++++++++++ GPU/Vulkan/TextureCacheVulkan.cpp | 1 - GPU/ge_constants.h | 10 ++++++++ UWP/GPU_UWP/GPU_UWP.vcxproj | 1 + UWP/GPU_UWP/GPU_UWP.vcxproj.filters | 1 + android/jni/Android.mk | 1 + libretro/Makefile.common | 1 + 16 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 GPU/GeConstants.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a6d488f2df..a1edc34f9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1402,6 +1402,8 @@ set(GPU_SOURCES GPU/Debugger/RecordFormat.h GPU/Debugger/Stepping.cpp GPU/Debugger/Stepping.h + GPU/ge_constants.h + GPU/GeConstants.cpp GPU/GPUInterface.h GPU/GeDisasm.cpp GPU/GeDisasm.h diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 1ca924df16..5be05dfded 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1304,7 +1304,7 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd float renderWidthFactor = renderWidth_ / 480.0f; float renderHeightFactor = renderHeight_ / 272.0f; - DEBUG_LOG(G3D, "Creating RAM framebuffer at %08x (%dx%d, stride %d, format %d)", fbAddress, width, height, stride, format); + INFO_LOG(G3D, "Creating RAM framebuffer at %08x (%dx%d, stride %d, format %d)", fbAddress, width, height, stride, format); // A target for the destination is missing - so just create one! // Make sure this one would be found by the algorithm above so we wouldn't diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index e1fbd2958c..66954c511c 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -68,13 +68,15 @@ struct VirtualFramebuffer { // There's also a top left of the drawing region, but meh... - // width/height: The detected size of the current framebuffer. + // width/height: The detected size of the current framebuffer, in original PSP pixels. u16 width; u16 height; + // renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions. // The physical buffer may be larger than renderWidth/renderHeight. u16 renderWidth; u16 renderHeight; + // bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than width/height. // Actual physical buffer is this size times the render resolution multiplier. // The buffer may be used to render a width or height from 0 to these values without being recreated. diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 462e72fc63..e6e6666adb 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -772,13 +772,13 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // If they match exactly, it's non-CLUT and from the top left. if (exactMatch) { - DEBUG_LOG(G3D, "Render to texture detected at %08x!", address); if (framebuffer->fb_stride != entry->bufw) { - WARN_LOG_REPORT_ONCE(diffStrides1, G3D, "Render to texture with different strides %d != %d", entry->bufw, framebuffer->fb_stride); + WARN_LOG_REPORT_ONCE(diffStrides1, G3D, "Texturing from framebuffer with different strides %d != %d", entry->bufw, framebuffer->fb_stride); } + // NOTE: This check is okay because the first texture formats are the same as the buffer formats. if (entry->format != (GETextureFormat)framebuffer->format) { - WARN_LOG_REPORT_ONCE(diffFormat1, G3D, "Render to texture with different formats %d != %d", entry->format, framebuffer->format); - // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. + WARN_LOG_REPORT_ONCE(diffFormat1, G3D, "Texturing from framebuffer with different formats %d != %d", entry->format, framebuffer->format); + // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. // However, some games use a different format to clear the buffer. if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) { DetachFramebuffer(entry, address, framebuffer); @@ -792,10 +792,12 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi if (!framebufferManager_->UseBufferedRendering()) return false; - const bool clutFormat = + const bool matchingClutFormat = (framebuffer->format == GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT32) || (framebuffer->format != GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT16); + const bool clutFormat = IsClutFormat((GETextureFormat)(entry->format)); + const u32 bitOffset = (texaddr - addr) * 8; const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry->format]); fbInfo.yOffset = entry->bufw == 0 ? 0 : pixelOffset / entry->bufw; @@ -803,7 +805,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi if (framebuffer->fb_stride != entry->bufw) { if (noOffset) { - WARN_LOG_REPORT_ONCE(diffStrides2, G3D, "Render to texture using CLUT with different strides %d != %d", entry->bufw, framebuffer->fb_stride); + // Not actually sure why we even try here. There's no way it'll go well if the strides are different. + WARN_LOG_ONCE(diffStrides2, G3D, "Texturing from framebuffer (matching_clut=%s) different strides %d != %d", matchingClutFormat ? "yes" : "no", entry->bufw, framebuffer->fb_stride); } else { // Assume any render-to-tex with different bufw + offset is a render from ram. DetachFramebuffer(entry, address, framebuffer); @@ -823,32 +826,34 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi DetachFramebuffer(entry, address, framebuffer); return false; } + // Trying to play it safe. Below 0x04110000 is almost always framebuffers. // TODO: Maybe we can reduce this check and find a better way above 0x04110000? if (fbInfo.yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 0x04110000) { - WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible render to texture at %08x +%dx%d / %dx%d", address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); + WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); DetachFramebuffer(entry, address, framebuffer); return false; } // Check for CLUT. The framebuffer is always RGB, but it can be interpreted as a CLUT texture. // 3rd Birthday (and a bunch of other games) render to a 16 bit clut texture. - if (clutFormat) { + if (matchingClutFormat) { if (!noOffset) { - WARN_LOG_REPORT_ONCE(subareaClut, G3D, "Render to texture using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); + WARN_LOG_REPORT_ONCE(subareaClut, G3D, "Texturing from framebuffer using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); } AttachFramebufferValid(entry, framebuffer, fbInfo); entry->status |= TexCacheEntry::STATUS_DEPALETTIZE; // We'll validate it compiles later. return true; - } else if (entry->format == GE_TFMT_CLUT8 || entry->format == GE_TFMT_CLUT4) { - ERROR_LOG_REPORT_ONCE(fourEightBit, G3D, "4 and 8-bit CLUT format not supported for framebuffers"); + } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) { + WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffers", GeTextureFormatToString((GETextureFormat)entry->format)); } // This is either normal or we failed to generate a shader to depalettize - if (framebuffer->format == entry->format || clutFormat) { + if (framebuffer->format == entry->format || matchingClutFormat) { if (framebuffer->format != entry->format) { - WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Render to texture with different formats %d != %d at %08x", entry->format, framebuffer->format, address); + WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", + GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); AttachFramebufferValid(entry, framebuffer, fbInfo); return true; } else { @@ -858,7 +863,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi return true; } } else { - WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Render to texture with incompatible formats %d != %d at %08x", entry->format, framebuffer->format, address); + WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", + GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); } } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 166f378b26..d0f7085969 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -123,11 +123,12 @@ struct TexCacheEntry { // Status, but int so we can zero initialize. int status; + u32 addr; u32 hash; VirtualFramebuffer *framebuffer; // if null, not sourced from an FBO. TODO: Collapse into texturePtr u32 sizeInRAM; // Could be computed - u8 format; + u8 format; // GeTextureFormat u8 maxLevel; u16 dim; u16 bufw; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index b6c2dcf17c..fcafb02685 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -87,7 +87,6 @@ void TextureCacheDX9::SetFramebufferManager(FramebufferManagerDX9 *fbManager) { } void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { - DEBUG_LOG(G3D, "Deleting texture %p", entry->texturePtr); LPDIRECT3DTEXTURE9 &texture = DxTex(entry); if (texture) { texture->Release(); diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 48c4a3eda8..9428cdf5d7 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -73,7 +73,6 @@ void TextureCacheGLES::SetFramebufferManager(FramebufferManagerGLES *fbManager) } void TextureCacheGLES::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { - DEBUG_LOG(G3D, "Deleting texture %08x", entry->addr); if (delete_them) { if (entry->textureName) { render_->DeleteTexture(entry->textureName); diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 9ea555f538..d77221d6a4 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -575,6 +575,7 @@ + true true diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index 8dcbf8229d..04ac5cae2d 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -27,9 +27,6 @@ - - Common - Common @@ -288,6 +285,9 @@ DirectX9 + + Common + @@ -572,5 +572,8 @@ DirectX9 + + Common + \ No newline at end of file diff --git a/GPU/GeConstants.cpp b/GPU/GeConstants.cpp new file mode 100644 index 0000000000..a8a27685cb --- /dev/null +++ b/GPU/GeConstants.cpp @@ -0,0 +1,28 @@ +#include "GPU/ge_constants.h" + +const char *GeBufferFormatToString(GEBufferFormat fmt) { + switch (fmt) { + case GE_FORMAT_4444: return "4444"; + case GE_FORMAT_5551: return "5551"; + case GE_FORMAT_565: return "565"; + case GE_FORMAT_8888: return "8888"; + default: return "N/A"; + } +} + +const char *GeTextureFormatToString(GETextureFormat fmt) { + switch (fmt) { + case GE_TFMT_5650: return "565"; + case GE_TFMT_5551: return "5551"; + case GE_TFMT_4444: return "4444"; + case GE_TFMT_8888: return "8888"; + case GE_TFMT_CLUT4: return "CLUT4"; + case GE_TFMT_CLUT8: return "CLUT8"; + case GE_TFMT_CLUT16: return "CLUT16"; + case GE_TFMT_CLUT32: return "CLUT32"; + case GE_TFMT_DXT1: return "DXT1"; + case GE_TFMT_DXT3: return "DXT3"; + case GE_TFMT_DXT5: return "DXT5"; + default: return "N/A"; + } +} diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 5476af392a..8631e4cdea 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -416,7 +416,6 @@ void TextureCacheVulkan::CompileScalingShader() { } void TextureCacheVulkan::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { - DEBUG_LOG(G3D, "Deleting texture %p", entry->vkTex); delete entry->vkTex; entry->vkTex = nullptr; } diff --git a/GPU/ge_constants.h b/GPU/ge_constants.h index e9509767f0..fc7c2ca982 100644 --- a/GPU/ge_constants.h +++ b/GPU/ge_constants.h @@ -285,6 +285,8 @@ enum GEBufferFormat GE_FORMAT_INVALID = 0xFF, }; +const char *GeBufferFormatToString(GEBufferFormat fmt); + #define GE_VTYPE_TRANSFORM (0<<23) #define GE_VTYPE_THROUGH (1<<23) #define GE_VTYPE_THROUGH_MASK (1<<23) @@ -413,6 +415,14 @@ enum GETextureFormat GE_TFMT_DXT5 = 10, }; +const char *GeTextureFormatToString(GETextureFormat fmt); +inline bool IsClutFormat(GETextureFormat fmt) { + return fmt == GE_TFMT_CLUT4 || fmt == GE_TFMT_CLUT8 || fmt == GE_TFMT_CLUT16 || fmt == GE_TFMT_CLUT32; +} +inline bool IsDXTFormat(GETextureFormat fmt) { + return fmt == GE_TFMT_DXT1 || fmt == GE_TFMT_DXT3 || fmt == GE_TFMT_DXT5; +} + enum GETexLevelMode { GE_TEXLEVEL_MODE_AUTO = 0, GE_TEXLEVEL_MODE_CONST = 1, diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index 0a0e4ee197..248d1c6a2b 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -482,6 +482,7 @@ + diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters index 3c47339764..261335da46 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj.filters +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj.filters @@ -45,6 +45,7 @@ + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 252572d1ba..ac68cf1815 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -225,6 +225,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/GPU.cpp \ $(SRC)/GPU/GPUCommon.cpp \ $(SRC)/GPU/GPUState.cpp \ + $(SRC)/GPU/GeConstants.cpp \ $(SRC)/GPU/GeDisasm.cpp \ $(SRC)/GPU/Common/DepalettizeShaderCommon.cpp \ $(SRC)/GPU/Common/FramebufferManagerCommon.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 7cbf1ce527..ff7b524875 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -187,6 +187,7 @@ SOURCES_CXX += \ $(GPUDIR)/Software/TransformUnit.cpp \ $(GPUDIR)/Software/SoftGpu.cpp \ $(GPUDIR)/Software/Sampler.cpp \ + $(GPUDIR)/GeConstants.cpp \ $(GPUDIR)/GeDisasm.cpp \ $(GPUDIR)/GPUCommon.cpp \ $(GPUDIR)/GPU.cpp \ From 09e300e646b81337341b4a508a3ac00838a667fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 4 Aug 2020 14:48:28 +0200 Subject: [PATCH 436/848] Be a little more aggressive discarding non matching framebuffers when texturing. Enable create framebuffer from copy, fixing #12345 --- GPU/Common/TextureCacheCommon.cpp | 4 ++++ assets/compat.ini | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index e6e6666adb..1b87c4afb5 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -847,6 +847,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi return true; } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) { WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffers", GeTextureFormatToString((GETextureFormat)entry->format)); + DetachFramebuffer(entry, address, framebuffer); + return false; } // This is either normal or we failed to generate a shader to depalettize @@ -865,6 +867,8 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi } else { WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); + DetachFramebuffer(entry, address, framebuffer); + return false; } } diff --git a/assets/compat.ini b/assets/compat.ini index 03ec98bbb0..068d3b9f05 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -523,6 +523,15 @@ NPEH00065 = true # Ys Seven NPJH50350 = true # Ys Seven ULJM08041 = true # Ys Seven +# Burnout Legends +ULES00125 = true +ULUS10025 = true +ULJM05228 = true +NPJH50305 = true +ULJM05049 = true +ULKS46027 = true +ULAS42019 = true + # Note! This whole flag is disabled temporarily by appending "Disabled" to its name). See 7914 [YugiohSaveFixDisabled] # The cause of Yu-gi-oh series 's bad save (cannot save) are load "save status" and use cwcheat, From c392d95c63e68dbf181e076bf20559d6421c9259 Mon Sep 17 00:00:00 2001 From: iota97 Date: Tue, 4 Aug 2020 23:36:35 +0200 Subject: [PATCH 437/848] UI sound fix --- CMakeLists.txt | 5 +++++ UI/NativeApp.cpp | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a1edc34f9e..a2a6987e01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2037,6 +2037,11 @@ set(NativeAssets assets/rargray.png assets/unknown.png assets/zip.png + assets/sfx_back.wav + assets/sfx_confirm.wav + assets/sfx_select.wav + assets/sfx_toggle_off.wav + assets/sfx_toggle_on.wav source_assets/image/logo.png source_assets/image/icon_regular_72.png ) diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 4c222078fa..cc855aa1fe 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -446,9 +446,6 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch g_Discord.SetPresenceMenu(); - // TODO: Load these in the background instead of synchronously. - g_BackgroundAudio.LoadSamples(); - // Make sure UI state is MENU. ResetUIState(); @@ -710,6 +707,9 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch } #endif + // TODO: Load these in the background instead of synchronously. + g_BackgroundAudio.LoadSamples(); + if (!boot_filename.empty() && stateToLoad != NULL) { SaveState::Load(stateToLoad, -1, [](SaveState::Status status, const std::string &message, void *) { if (!message.empty() && (!g_Config.bDumpFrames || !g_Config.bDumpVideoOutput)) { From acc952d839d88a9904b259f10e5fa4c047119786 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Wed, 5 Aug 2020 18:43:45 +0800 Subject: [PATCH 438/848] Correct the alignment size when allocate memory at a position. --- Core/Util/BlockAllocator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index 02496432b1..34bf5ee618 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -163,7 +163,7 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag) alignedPosition &= ~(grain_ - 1); // Since the position was decreased, size must increase. - alignedSize += alignedPosition - position; + alignedSize += position - alignedPosition; } // Upalign size to grain. From 77da51c41820f5836209c380bfac687abbce2fcf Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Wed, 5 Aug 2020 19:01:00 +0800 Subject: [PATCH 439/848] Also correct the allocated size. --- Core/Util/BlockAllocator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index 34bf5ee618..1b67b82a9a 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -169,7 +169,7 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag) // Upalign size to grain. alignedSize = (alignedSize + grain_ - 1) & ~(grain_ - 1); // Tell the caller the allocated size from their requested starting position. - size = alignedSize - (alignedPosition - position); + size = alignedSize - (position - alignedPosition); Block *bp = GetBlockFromAddress(alignedPosition); if (bp != NULL) From eadd3c57850ec8b6a9e55f75fa9b546bf99ae130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Aug 2020 10:54:07 +0200 Subject: [PATCH 440/848] Remove the LARGE_VIEWPORTS separate path. The fewer paths the better, all need to work anyway. Required fixing a bug in ShaderUniforms.cpp (used by D3D11 and Vulkan, the two backends that previously exposed LARGE_VIEWPORTS). --- GPU/Common/GPUStateUtils.cpp | 26 ++++++++++++++------------ GPU/Common/ShaderUniforms.cpp | 4 ++-- GPU/D3D11/GPU_D3D11.cpp | 1 - GPU/GPUState.h | 2 +- GPU/Vulkan/GPU_Vulkan.cpp | 1 - 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index bf95736774..c2f6931d85 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -648,27 +648,29 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo float hScale = 1.0f; float yOffset = 0.0f; - if (!gstate_c.Supports(GPU_SUPPORTS_LARGE_VIEWPORTS)) { - // If we're within the bounds, we want clipping the viewport way. So leave it be. - if (left < 0.0f || right > renderWidth) { - float overageLeft = std::max(-left, 0.0f); - float overageRight = std::max(right - renderWidth, 0.0f); - // Our center drifted by the difference in overages. - float drift = overageRight - overageLeft; + // If we're within the bounds, we want clipping the viewport way. So leave it be. + { + float overageLeft = std::max(-left, 0.0f); + float overageRight = std::max(right - renderWidth, 0.0f); + // Our center drifted by the difference in overages. + float drift = overageRight - overageLeft; + if (overageLeft != 0.0f || overageRight != 0.0f) { left += overageLeft; right -= overageRight; wScale = vpWidth / (right - left); xOffset = drift / (right - left); } + } - if (top < 0.0f || bottom > renderHeight) { - float overageTop = std::max(-top, 0.0f); - float overageBottom = std::max(bottom - renderHeight, 0.0f); - // Our center drifted by the difference in overages. - float drift = overageBottom - overageTop; + { + float overageTop = std::max(-top, 0.0f); + float overageBottom = std::max(bottom - renderHeight, 0.0f); + // Our center drifted by the difference in overages. + float drift = overageBottom - overageTop; + if (overageTop != 0.0f || overageBottom != 0.0f) { top += overageTop; bottom -= overageBottom; diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index c80ae842ef..5cc61f32e3 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -15,13 +15,13 @@ using namespace Lin; static void ConvertProjMatrixToVulkan(Matrix4x4 &in) { - const Vec3 trans(0, 0, gstate_c.vpZOffset * 0.5f + 0.5f); + const Vec3 trans(gstate_c.vpXOffset, gstate_c.vpYOffset, gstate_c.vpZOffset * 0.5f + 0.5f); const Vec3 scale(gstate_c.vpWidthScale, gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f); in.translateAndScale(trans, scale); } static void ConvertProjMatrixToD3D11(Matrix4x4 &in) { - const Vec3 trans(0, 0, gstate_c.vpZOffset * 0.5f + 0.5f); + const Vec3 trans(gstate_c.vpXOffset, gstate_c.vpYOffset, gstate_c.vpZOffset * 0.5f + 0.5f); const Vec3 scale(gstate_c.vpWidthScale, -gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f); in.translateAndScale(trans, scale); } diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 13cbb442fc..8535d1fb5e 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -143,7 +143,6 @@ void GPU_D3D11::CheckGPUFeatures() { #endif features |= GPU_SUPPORTS_OES_TEXTURE_NPOT; - features |= GPU_SUPPORTS_LARGE_VIEWPORTS; if (draw_->GetDeviceCaps().dualSourceBlend) features |= GPU_SUPPORTS_DUALSOURCE_BLEND; if (draw_->GetDeviceCaps().depthClampSupported) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 2f33c3fb91..4aac1e9907 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -482,7 +482,7 @@ enum { GPU_SUPPORTS_16BIT_FORMATS = FLAG_BIT(13), GPU_SUPPORTS_DEPTH_CLAMP = FLAG_BIT(14), GPU_SUPPORTS_32BIT_INT_FSHADER = FLAG_BIT(15), - GPU_SUPPORTS_LARGE_VIEWPORTS = FLAG_BIT(16), + // Free bit: 16 GPU_SUPPORTS_ACCURATE_DEPTH = FLAG_BIT(17), GPU_SUPPORTS_VAO = FLAG_BIT(18), GPU_SUPPORTS_ANY_COPY_IMAGE = FLAG_BIT(19), diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 99002e68f4..a912f4b781 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -227,7 +227,6 @@ void GPU_Vulkan::CheckGPUFeatures() { features |= GPU_SUPPORTS_BLEND_MINMAX; features |= GPU_SUPPORTS_ANY_COPY_IMAGE; features |= GPU_SUPPORTS_OES_TEXTURE_NPOT; - features |= GPU_SUPPORTS_LARGE_VIEWPORTS; features |= GPU_SUPPORTS_INSTANCE_RENDERING; features |= GPU_SUPPORTS_VERTEX_TEXTURE_FETCH; features |= GPU_SUPPORTS_TEXTURE_FLOAT; From 1b2d4dd75dfced5be687e94a20ecac2766d8bf44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Aug 2020 19:03:51 +0200 Subject: [PATCH 441/848] Viewport state conversion: Move the pixel scaling to after the overage clipping. --- GPU/Common/GPUStateUtils.cpp | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index c2f6931d85..46f0b56bc5 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -568,7 +568,7 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo renderHeightFactor = renderHeight / 272.0f; } - renderX += gstate_c.curRTOffsetX * renderWidthFactor; + renderX = gstate_c.curRTOffsetX; // Scissor int scissorX1 = gstate.getScissorX1(); @@ -576,8 +576,6 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; - // This is a bit of a hack as the render buffer isn't always that size - // We always scissor on non-buffered so that clears don't spill outside the frame. out.scissorEnable = true; if (scissorX2 < scissorX1 || scissorY2 < scissorY1) { out.scissorX = 0; @@ -585,8 +583,8 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo out.scissorW = 0; out.scissorH = 0; } else { - out.scissorX = renderX + displayOffsetX + scissorX1 * renderWidthFactor; - out.scissorY = renderY + displayOffsetY + scissorY1 * renderHeightFactor; + out.scissorX = (renderX * renderWidthFactor) + displayOffsetX + scissorX1 * renderWidthFactor; + out.scissorY = (renderY * renderHeightFactor) + displayOffsetY + scissorY1 * renderHeightFactor; out.scissorW = (scissorX2 - scissorX1) * renderWidthFactor; out.scissorH = (scissorY2 - scissorY1) * renderHeightFactor; } @@ -598,8 +596,8 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo float offsetY = gstate.getOffsetY(); if (throughmode) { - out.viewportX = renderX + displayOffsetX; - out.viewportY = renderY + displayOffsetY; + out.viewportX = renderX * renderWidthFactor + displayOffsetX; + out.viewportY = renderY * renderHeightFactor + displayOffsetY; out.viewportW = curRTWidth * renderWidthFactor; out.viewportH = curRTHeight * renderHeightFactor; out.depthRangeMin = ToScaledDepthFromIntegerScale(0); @@ -629,12 +627,6 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo float vpWidth = fabsf(gstate_c.vpWidth); float vpHeight = fabsf(gstate_c.vpHeight); - // This multiplication should probably be done after viewport clipping. Would let us very slightly simplify the clipping logic? - vpX0 *= renderWidthFactor; - vpY0 *= renderHeightFactor; - vpWidth *= renderWidthFactor; - vpHeight *= renderHeightFactor; - // We used to apply the viewport here via glstate, but there are limits which vary by driver. // This may mean some games won't work, or at least won't work at higher render resolutions. // So we apply it in the shader instead. @@ -651,7 +643,8 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo // If we're within the bounds, we want clipping the viewport way. So leave it be. { float overageLeft = std::max(-left, 0.0f); - float overageRight = std::max(right - renderWidth, 0.0f); + float overageRight = std::max(right - bufferWidth, 0.0f); + // Our center drifted by the difference in overages. float drift = overageRight - overageLeft; @@ -666,7 +659,7 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo { float overageTop = std::max(-top, 0.0f); - float overageBottom = std::max(bottom - renderHeight, 0.0f); + float overageBottom = std::max(bottom - bufferHeight, 0.0f); // Our center drifted by the difference in overages. float drift = overageBottom - overageTop; @@ -679,10 +672,10 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo } } - out.viewportX = left + displayOffsetX; - out.viewportY = top + displayOffsetY; - out.viewportW = right - left; - out.viewportH = bottom - top; + out.viewportX = left * renderWidthFactor + displayOffsetX; + out.viewportY = top * renderHeightFactor + displayOffsetY; + out.viewportW = (right - left) * renderWidthFactor; + out.viewportH = (bottom - top) * renderHeightFactor; // The depth viewport parameters are the same, but we handle it a bit differently. // When clipping is enabled, depth is clamped to [0, 65535]. And minz/maxz discard. From fd3a9d420278ddbc0c5ec3472c3d105ac339e740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Aug 2020 19:19:30 +0200 Subject: [PATCH 442/848] Expand the viewport to cover the scissor region, if it doesn't. Fixes #4845 (bloom in Dante's Inferno). --- GPU/Common/GPUStateUtils.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 46f0b56bc5..1fd166cf45 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -645,6 +645,14 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo float overageLeft = std::max(-left, 0.0f); float overageRight = std::max(right - bufferWidth, 0.0f); + // Expand viewport to cover scissor region. The viewport doesn't clip on the PSP. + if (right < scissorX2) { + overageRight -= scissorX2 - right; + } + if (left > scissorX1) { + overageLeft += scissorX1 - left; + } + // Our center drifted by the difference in overages. float drift = overageRight - overageLeft; @@ -660,6 +668,14 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo { float overageTop = std::max(-top, 0.0f); float overageBottom = std::max(bottom - bufferHeight, 0.0f); + + // Expand viewport to cover scissor region. The viewport doesn't clip on the PSP. + if (bottom < scissorY2) { + overageBottom -= scissorY2 - bottom; + } + if (top > scissorY1) { + overageTop += scissorY1 - top; + } // Our center drifted by the difference in overages. float drift = overageBottom - overageTop; From ff248ff94f9cee841c2b99ae2006f3c3ccc832b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 6 Aug 2020 09:35:26 +0200 Subject: [PATCH 443/848] Fix #13251 for D3D11. The remaining issue in #7124 should be fixed. --- GPU/Common/ShaderUniforms.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 5cc61f32e3..352ae43ddc 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -21,7 +21,7 @@ static void ConvertProjMatrixToVulkan(Matrix4x4 &in) { } static void ConvertProjMatrixToD3D11(Matrix4x4 &in) { - const Vec3 trans(gstate_c.vpXOffset, gstate_c.vpYOffset, gstate_c.vpZOffset * 0.5f + 0.5f); + const Vec3 trans(gstate_c.vpXOffset, -gstate_c.vpYOffset, gstate_c.vpZOffset * 0.5f + 0.5f); const Vec3 scale(gstate_c.vpWidthScale, -gstate_c.vpHeightScale, gstate_c.vpDepthScale * 0.5f); in.translateAndScale(trans, scale); } From f9a1a0eee5018d67db5c501fcff4dbb71b7548ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 6 Aug 2020 10:19:58 +0200 Subject: [PATCH 444/848] Fix issue where after a backend change restart, the new instance was considered secondary. --- Core/Instance.cpp | 4 ++-- UI/GameSettingsScreen.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Core/Instance.cpp b/Core/Instance.cpp index 70976427de..ed6222b185 100644 --- a/Core/Instance.cpp +++ b/Core/Instance.cpp @@ -136,9 +136,9 @@ void InitInstanceCounter() { void ShutdownInstanceCounter() { #if PPSSPP_PLATFORM(WINDOWS) - if (hIDMapFile != NULL) { + if (hIDMapFile) { CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted. - hIDMapFile = NULL; + hIDMapFile = nullptr; } #elif PPSSPP_PLATFORM(ANDROID) // Do nothing diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 5594e2e035..9945d98127 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -55,6 +55,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Host.h" +#include "Core/Instance.h" #include "Core/System.h" #include "Core/Reporting.h" #include "Core/TextureReplacer.h" @@ -229,6 +230,11 @@ void GameSettingsScreen::CreateViews() { renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D11); if (!g_Config.IsBackendEnabled(GPUBackend::VULKAN)) renderingBackendChoice->HideChoice((int)GPUBackend::VULKAN); + + if (!IsFirstInstance()) { + // If we're not the first instance, can't save the setting, and it requires a restart, so... + renderingBackendChoice->SetEnabled(false); + } #endif Draw::DrawContext *draw = screenManager()->getDrawContext(); @@ -1273,6 +1279,8 @@ void GameSettingsScreen::TriggerRestart(const char *why) { } else if (!gamePath_.empty()) { param += " \"" + ReplaceAll(ReplaceAll(gamePath_, "\\", "\\\\"), "\"", "\\\"") + "\""; } + // Make sure the new instance is considered the first. + ShutdownInstanceCounter(); System_SendMessage("graphics_restart", param.c_str()); } From 8e1caadb486995564b575db1d4374ff07e0ac325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 6 Aug 2020 10:20:27 +0200 Subject: [PATCH 445/848] Remove some unnecessary reporting. --- Core/HLE/sceKernelModule.cpp | 4 ++-- GPU/Common/TextureCacheCommon.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index ad63d32f45..576c65c245 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -761,8 +761,8 @@ void ImportFuncSymbol(const FuncSymbolImport &func, bool reimporting, const char void ExportFuncSymbol(const FuncSymbolExport &func) { if (FuncImportIsSyscall(func.moduleName, func.nid)) { - // Oops, HLE covers this. - WARN_LOG_REPORT(LOADER, "Ignoring func export %s/%08x, already implemented in HLE.", func.moduleName, func.nid); + // HLE covers this already - let's ignore the function. + WARN_LOG(LOADER, "Ignoring func export %s/%08x, already implemented in HLE.", func.moduleName, func.nid); return; } diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 1b87c4afb5..51ea073fda 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -859,7 +859,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi AttachFramebufferValid(entry, framebuffer, fbInfo); return true; } else { - WARN_LOG_REPORT_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); + WARN_LOG_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); // If "AttachFramebufferValid" , God of War Ghost of Sparta/Chains of Olympus will be missing special effect. AttachFramebufferInvalid(entry, framebuffer, fbInfo); return true; From c24dad2ac4815f0e69f1b0b1f094157376645b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 6 Aug 2020 14:33:29 +0200 Subject: [PATCH 446/848] Logging improvement --- GPU/Common/TextureCacheCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 51ea073fda..2587761719 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -846,7 +846,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // We'll validate it compiles later. return true; } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) { - WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffers", GeTextureFormatToString((GETextureFormat)entry->format)); + WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffer of format %s", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format)); DetachFramebuffer(entry, address, framebuffer); return false; } From ad0ef74afe7a67c5bd7f57dce9574f5302ad9192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 6 Aug 2020 15:21:46 +0200 Subject: [PATCH 447/848] Enable pixel depth rounding for Nayuta no Kiseki. See issue #8744. --- assets/compat.ini | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 068d3b9f05..7826197a67 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -121,6 +121,12 @@ NPJH90062 = true # Phantasy Star Portable Infinity Demo NPJH90157 = true # Infinity demo +# Nayuta no Kiseki might improve with pixel depth rounding. See issue #8744. +ULJM06113 = true +NPJH50625 = true +ULJM08069 = true +NPJH50625 = true + [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 From d2a9bc6bccf8375196a45809ff057af64a22ecd4 Mon Sep 17 00:00:00 2001 From: iota97 Date: Fri, 7 Aug 2020 10:16:43 +0200 Subject: [PATCH 448/848] Remove double disable function on frame duplication --- UI/GameSettingsScreen.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 9945d98127..4734b179a6 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -381,15 +381,12 @@ void GameSettingsScreen::CreateViews() { #endif CheckBox *frameDuplication = graphicsSettings->Add(new CheckBox(&g_Config.bRenderDuplicateFrames, gr->T("Render duplicate frames to 60hz"))); - frameDuplication->SetEnabledFunc([] { - return g_Config.iRenderingMode != FB_NON_BUFFERED_MODE || (g_Config.bSoftwareRendering && g_Config.iFrameSkip != 0); - }); frameDuplication->OnClick.Add([=](EventParams &e) { settingInfo_->Show(gr->T("RenderDuplicateFrames Tip", "Can make framerate smoother in games that run at lower framerates"), e.v); return UI::EVENT_CONTINUE; }); - frameDuplication->SetEnabledFunc([]() -> bool { - return g_Config.iFrameSkip == 0; + frameDuplication->SetEnabledFunc([] { + return g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && g_Config.iFrameSkip == 0; }); if (GetGPUBackend() == GPUBackend::VULKAN || GetGPUBackend() == GPUBackend::OPENGL) { From 9e44523426bc4c6e54e2e49ff832a749790b6be0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 7 Aug 2020 22:53:45 +0200 Subject: [PATCH 449/848] (Libretro) Buildfix for Windows --- Core/MIPS/JitCommon/JitCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index 697733ec1d..6ef4a534a7 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -77,7 +77,7 @@ namespace MIPSComp { } } -#if PPSSPP_PLATFORM(WINDOWS) +#if PPSSPP_PLATFORM(WINDOWS) && !defined(__LIBRETRO__) #define DISASM_ALL 1 #endif From 11f9df33ba753c0ca50657da99165f72a9ea4089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 8 Aug 2020 21:29:29 +0200 Subject: [PATCH 450/848] Vulkan: Start adding object names for easier validation debugging --- Common/Vulkan/VulkanContext.cpp | 8 ++++++++ Common/Vulkan/VulkanContext.h | 10 ++++++++++ ext/native/thin3d/VulkanRenderManager.h | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index abf4072a23..2d6978f2fa 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -694,6 +694,14 @@ VkResult VulkanContext::InitDebugUtilsCallback() { return res; } +void VulkanContext::SetDebugNameImpl(uint64_t handle, VkObjectType type, const char *name) { + VkDebugUtilsObjectNameInfoEXT info{ VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT }; + info.pObjectName = name; + info.objectHandle = handle; + info.objectType = type; + vkSetDebugUtilsObjectNameEXT(device_, &info); +} + VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) { winsys_ = winsys; winsysData1_ = data1; diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index db61f2e5b1..553580334d 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -167,6 +167,16 @@ public: void BeginFrame(); void EndFrame(); + void SetDebugNameImpl(uint64_t handle, VkObjectType type, const char *name); + + // Simple workaround for the casting warning. + template + void SetDebugName(T handle, VkObjectType type, const char *name) { + if (extensionsLookup_.EXT_debug_utils) { + SetDebugNameImpl((uint64_t)handle, type, name); + } + } + bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); VkPhysicalDevice GetPhysicalDevice(int n) const { diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 3bc5a344e7..9f3c08a7d3 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -37,6 +37,12 @@ public: CreateImage(vulkan_, initCmd, color, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); CreateImage(vulkan_, initCmd, depth, width, height, vulkan_->GetDeviceInfo().preferredDepthStencilFormat, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false); + vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, "fb_color"); + vk->SetDebugName(color.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, "fb_color_view"); + + vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, "fb_depth"); + vk->SetDebugName(depth.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, "fb_depth_view"); + VkFramebufferCreateInfo fbci{ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; VkImageView views[2]{}; From 2f5de1987ea29b2896f3e0d425a0bbbdf25cee74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 8 Aug 2020 23:18:17 +0200 Subject: [PATCH 451/848] Allow passing in an object name tag when creating framebuffers --- Common/Vulkan/VulkanContext.cpp | 2 +- Common/Vulkan/VulkanContext.h | 19 +++++++++++++++---- Common/Vulkan/VulkanLoader.cpp | 4 ++-- Common/Vulkan/VulkanLoader.h | 6 +++--- UI/TextureUtil.cpp | 8 ++++---- UI/TextureUtil.h | 2 +- ext/native/thin3d/VulkanQueueRunner.cpp | 2 +- ext/native/thin3d/VulkanRenderManager.h | 14 +++++++------- ext/native/thin3d/thin3d.h | 3 ++- ext/native/thin3d/thin3d_vulkan.cpp | 2 +- 10 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 2d6978f2fa..7d483f11ad 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -1391,7 +1391,7 @@ void VulkanDeleteList::PerformDeletes(VkDevice device) { } void VulkanContext::GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation) { - if (DeviceExtensions().KHR_dedicated_allocation) { + if (Extensions().KHR_dedicated_allocation) { VkImageMemoryRequirementsInfo2KHR memReqInfo2{VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR}; memReqInfo2.image = image; diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 553580334d..a10692b88f 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -167,8 +167,6 @@ public: void BeginFrame(); void EndFrame(); - void SetDebugNameImpl(uint64_t handle, VkObjectType type, const char *name); - // Simple workaround for the casting warning. template void SetDebugName(T handle, VkObjectType type, const char *name) { @@ -177,6 +175,17 @@ public: } } + // Shorthand for the above, the most common types we want to tag. + void SetDebugName(VkImage image, const char *name) { + SetDebugName(image, VK_OBJECT_TYPE_IMAGE, name); + } + void SetDebugName(VkFramebuffer framebuf, const char *name) { + SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, name); + } + void SetDebugName(VkSampler sampler, const char *name) { + SetDebugName(sampler, VK_OBJECT_TYPE_SAMPLER, name); + } + bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); VkPhysicalDevice GetPhysicalDevice(int n) const { @@ -277,13 +286,15 @@ public: MAX_INFLIGHT_FRAMES = 3, }; - const VulkanDeviceExtensions &DeviceExtensions() { return extensionsLookup_; } + const VulkanExtensions &Extensions() { return extensionsLookup_; } void GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation); private: bool ChooseQueue(); + void SetDebugNameImpl(uint64_t handle, VkObjectType type, const char *name); + VkResult InitDebugUtilsCallback(); // A layer can expose extensions, keep track of those extensions here. @@ -317,7 +328,7 @@ private: std::vector device_extensions_enabled_; std::vector device_extension_properties_; - VulkanDeviceExtensions extensionsLookup_{}; + VulkanExtensions extensionsLookup_{}; std::vector physical_devices_; diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index 43298ec9c4..59b3fb5bd3 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -489,7 +489,7 @@ bool VulkanLoad() { } } -void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions) { +void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions) { // OK, let's use the above functions to get the rest. LOAD_INSTANCE_FUNC(instance, vkDestroyInstance); LOAD_INSTANCE_FUNC(instance, vkEnumeratePhysicalDevices); @@ -554,7 +554,7 @@ void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensio // On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may // increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very // good for multi-device - not likely we'll ever try that anyway though. -void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions) { +void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions) { WLOG("Vulkan device functions loaded."); LOAD_DEVICE_FUNC(device, vkQueueSubmit); diff --git a/Common/Vulkan/VulkanLoader.h b/Common/Vulkan/VulkanLoader.h index e9c7f96156..c91ad6296c 100644 --- a/Common/Vulkan/VulkanLoader.h +++ b/Common/Vulkan/VulkanLoader.h @@ -215,7 +215,7 @@ extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; // For fast extension-enabled checks. -struct VulkanDeviceExtensions { +struct VulkanExtensions { bool EXT_debug_utils; bool KHR_maintenance1; // required for KHR_create_renderpass2 bool KHR_maintenance2; @@ -236,6 +236,6 @@ bool VulkanMayBeAvailable(); void VulkanSetAvailable(bool available); bool VulkanLoad(); -void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanDeviceExtensions &enabledExtensions); -void VulkanLoadDeviceFunctions(VkDevice device, const VulkanDeviceExtensions &enabledExtensions); +void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &enabledExtensions); +void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions); void VulkanFree(); diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index b79459f769..b9f9b8966a 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -92,7 +92,7 @@ static bool LoadTextureLevels(const uint8_t *data, size_t size, ImageFileType ty return *num_levels > 0; } -bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips) { +bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips, const char *name) { generateMips_ = generateMips; using namespace Draw; @@ -131,7 +131,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag desc.depth = 1; desc.mipLevels = generateMips ? potentialLevels : num_levels; desc.generateMips = generateMips && potentialLevels > num_levels; - desc.tag = "LoadedFileData"; + desc.tag = name; for (int i = 0; i < num_levels; i++) { desc.initData.push_back(image[i]); } @@ -152,7 +152,7 @@ bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType typ ELOG("Failed to read file '%s'", filename.c_str()); return false; } - bool retval = LoadFromFileData(buffer, fileSize, type, generateMips); + bool retval = LoadFromFileData(buffer, fileSize, type, generateMips, filename.c_str()); if (retval) { filename_ = filename; } else { @@ -206,7 +206,7 @@ std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *dra if (!draw) return std::unique_ptr(); ManagedTexture *mtex = new ManagedTexture(draw); - if (mtex->LoadFromFileData(data, size, type, generateMips)) { + if (mtex->LoadFromFileData(data, size, type, generateMips, nullptr)) { return std::unique_ptr(mtex); } else { // Best to return a null pointer if we fail! diff --git a/UI/TextureUtil.h b/UI/TextureUtil.h index 6a93f4809b..61abbfc2c8 100644 --- a/UI/TextureUtil.h +++ b/UI/TextureUtil.h @@ -23,7 +23,7 @@ public: } bool LoadFromFile(const std::string &filename, ImageFileType type = ImageFileType::DETECT, bool generateMips = false); - bool LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type = ImageFileType::DETECT, bool generateMips = false); + bool LoadFromFileData(const uint8_t *data, size_t dataSize, ImageFileType type, bool generateMips, const char *name); Draw::Texture *GetTexture(); // For immediate use, don't store. int Width() const { return texture_->Width(); } int Height() const { return texture_->Height(); } diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 088af77b01..c1e2d34f00 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -447,7 +447,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &st } } - bool emitLabels = vulkan_->DeviceExtensions().EXT_debug_utils; + bool emitLabels = vulkan_->Extensions().EXT_debug_utils; for (size_t i = 0; i < steps.size(); i++) { const VKRStep &step = *steps[i]; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 9f3c08a7d3..0122dc488e 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -11,6 +11,7 @@ #include #include "base/display.h" +#include "base/stringutil.h" #include "Common/Vulkan/VulkanContext.h" #include "math/dataconv.h" #include "math/math_util.h" @@ -30,19 +31,13 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int class VKRFramebuffer { public: - VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height) : vulkan_(vk) { + VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height, const char *tag) : vulkan_(vk) { width = _width; height = _height; CreateImage(vulkan_, initCmd, color, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); CreateImage(vulkan_, initCmd, depth, width, height, vulkan_->GetDeviceInfo().preferredDepthStencilFormat, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false); - vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, "fb_color"); - vk->SetDebugName(color.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, "fb_color_view"); - - vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, "fb_depth"); - vk->SetDebugName(depth.imageView, VK_OBJECT_TYPE_IMAGE_VIEW, "fb_depth_view"); - VkFramebufferCreateInfo fbci{ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; VkImageView views[2]{}; @@ -56,6 +51,11 @@ public: fbci.layers = 1; vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf); + if (vk->Extensions().EXT_debug_utils) { + vk->SetDebugName(color.image, StringFromFormat("fb_color_%s", tag).c_str()); + vk->SetDebugName(depth.image, StringFromFormat("fb_depth_%s", tag).c_str()); + vk->SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, StringFromFormat("fb_%s", tag).c_str()); + } } ~VKRFramebuffer() { diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 2ead85c2e4..d3ae7c20d4 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -311,6 +311,7 @@ struct FramebufferDesc { int numColorAttachments; bool z_stencil; FBColorDepth colorDepth; + const char *tag; // For graphics debuggers }; // Binary compatible with D3D11 viewport. @@ -536,7 +537,7 @@ struct TextureDesc { int depth; int mipLevels; bool generateMips; - // Optional, for tracking memory usage. + // Optional, for tracking memory usage and graphcis debuggers. std::string tag; // Does not take ownership over pointed-to data. std::vector initData; diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index a0b3a5f1d4..3c90511893 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1462,7 +1462,7 @@ private: Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) { VkCommandBuffer cmd = renderManager_.GetInitCmd(); - VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetFramebufferRenderPass(), desc.width, desc.height); + VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetFramebufferRenderPass(), desc.width, desc.height, desc.tag); return new VKFramebuffer(vkrfb); } From fbf6008a03800e3fe7d12a09eec0bf3abf340407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 9 Aug 2020 09:35:56 +0200 Subject: [PATCH 452/848] Set debug names for more framebuffers and textures --- Common/Vulkan/VulkanImage.cpp | 4 ++++ GPU/Common/FramebufferManagerCommon.cpp | 15 +++++++++++---- GPU/Common/PresentationCommon.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 2 +- UI/GameInfoCache.cpp | 2 +- UI/Store.cpp | 2 +- UI/TextureUtil.cpp | 4 ++-- UI/TextureUtil.h | 4 ++-- ext/native/thin3d/VulkanRenderManager.cpp | 2 ++ ext/native/thin3d/thin3d.h | 2 +- ext/native/thin3d/thin3d_vulkan.cpp | 4 +++- 11 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index d6f3f53877..1d9b8d7ffe 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -71,6 +71,9 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all return false; } + // Apply the tag + vulkan_->SetDebugName(image_, tag_.c_str()); + VkMemoryRequirements mem_reqs{}; bool dedicatedAllocation = false; vulkan_->GetImageMemoryRequirements(image_, &mem_reqs, &dedicatedAllocation); @@ -161,6 +164,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all return true; } +// TODO: Batch these. void VulkanTexture::UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mipHeight, VkBuffer buffer, uint32_t offset, size_t rowLength) { VkBufferImageCopy copy_region{}; copy_region.bufferOffset = offset; diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 5be05dfded..556e2519ee 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1060,7 +1060,9 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } shaderManager_->DirtyLastShader(); - vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth }); + char name[256]; + snprintf(name, sizeof(name), "%08x_%08x", vfb->fb_address, vfb->z_address); + vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, name }); if (old.fbo) { INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %d x %d x %d", vfb->fb_address, w, h, vfb->format); if (vfb->fbo) { @@ -1329,7 +1331,9 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd vfb->usageFlags = FB_USAGE_RENDERTARGET; SetColorUpdated(vfb, 0); textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED); - vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth }); + char name[64]; + snprintf(name, sizeof(name), "%08x_color_RAM", vfb->fb_address); + vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, name }); vfbs_.push_back(vfb); u32 byteSize = ColorBufferByteSize(vfb); @@ -1417,7 +1421,9 @@ bool FramebufferManagerCommon::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb } } - nvfb->fbo = draw_->CreateFramebuffer({ nvfb->bufferWidth, nvfb->bufferHeight, 1, 1, false, (Draw::FBColorDepth)nvfb->colorDepth }); + char name[64]; + snprintf(name, sizeof(name), "download_temp"); + nvfb->fbo = draw_->CreateFramebuffer({ nvfb->bufferWidth, nvfb->bufferHeight, 1, 1, false, (Draw::FBColorDepth)nvfb->colorDepth, name }); if (!nvfb->fbo) { ERROR_LOG(FRAMEBUF, "Error creating GL FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight); return false; @@ -1744,7 +1750,8 @@ Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u textureCache_->ForgetLastTexture(); bool z_stencil = reason == TempFBO::STENCIL; - Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, z_stencil, depth }); + const char *name = "temp_fbo"; + Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, z_stencil, depth, name }); if (!fbo) return fbo; diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 09bf2c2009..9ef488ffda 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -317,7 +317,7 @@ bool PresentationCommon::AllocateFramebuffer(int w, int h) { } // No depth/stencil for post processing - Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888 }); + Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888, "presentation" }); if (!fbo) { return false; } diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 8631e4cdea..d15f68988a 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -859,7 +859,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { } char texName[128]{}; - snprintf(texName, sizeof(texName), "Texture%08x", entry->addr); + snprintf(texName, sizeof(texName), "texture_%08x_%s", entry->addr, GeTextureFormatToString((GETextureFormat)entry->format)); image->SetTag(texName); bool allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, imageLayout, usage, mapping); diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 32c9684db0..e1c2db94f0 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -789,7 +789,7 @@ void GameInfoCache::SetupTexture(std::shared_ptr &info, Draw::DrawCont using namespace Draw; if (tex.data.size()) { if (!tex.texture) { - tex.texture = CreateTextureFromFileData(thin3d, (const uint8_t *)tex.data.data(), (int)tex.data.size(), ImageFileType::DETECT); + tex.texture = CreateTextureFromFileData(thin3d, (const uint8_t *)tex.data.data(), (int)tex.data.size(), ImageFileType::DETECT, false, info->GetTitle().c_str()); if (tex.texture) { tex.timeLoaded = time_now_d(); } else { diff --git a/UI/Store.cpp b/UI/Store.cpp index 780a7f4c99..f52a1ae916 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -139,7 +139,7 @@ void HttpImageFileView::Draw(UIContext &dc) { } if (!textureData_.empty()) { - texture_ = CreateTextureFromFileData(dc.GetDrawContext(), (const uint8_t *)(textureData_.data()), (int)textureData_.size(), DETECT); + texture_ = CreateTextureFromFileData(dc.GetDrawContext(), (const uint8_t *)(textureData_.data()), (int)textureData_.size(), DETECT, false, "store_icon"); if (!texture_) textureFailed_ = true; textureData_.clear(); diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index b9f9b8966a..0d05bbc448 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -202,11 +202,11 @@ Draw::Texture *ManagedTexture::GetTexture() { } // TODO: Remove the code duplication between this and LoadFromFileData -std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType type, bool generateMips) { +std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType type, bool generateMips, const char *name) { if (!draw) return std::unique_ptr(); ManagedTexture *mtex = new ManagedTexture(draw); - if (mtex->LoadFromFileData(data, size, type, generateMips, nullptr)) { + if (mtex->LoadFromFileData(data, size, type, generateMips, name)) { return std::unique_ptr(mtex); } else { // Best to return a null pointer if we fail! diff --git a/UI/TextureUtil.h b/UI/TextureUtil.h index 61abbfc2c8..d5ebca8a5c 100644 --- a/UI/TextureUtil.h +++ b/UI/TextureUtil.h @@ -39,8 +39,8 @@ private: bool loadPending_ = false; }; -std::unique_ptr CreateTextureFromFile(Draw::DrawContext *draw, const char *filename, ImageFileType fileType, bool generateMips = false); -std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType fileType, bool generateMips = false); +std::unique_ptr CreateTextureFromFile(Draw::DrawContext *draw, const char *filename, ImageFileType fileType, bool generateMips); +std::unique_ptr CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType fileType, bool generateMips, const char *name); class GameIconView : public UI::InertView { public: diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index a595bfe29a..01e692de59 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -718,6 +718,8 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) { if (res != VK_SUCCESS) return false; + vulkan_->SetDebugName(depth_.image, "BackbufferDepth"); + bool dedicatedAllocation = false; VkMemoryRequirements mem_reqs; vulkan_->GetImageMemoryRequirements(depth_.image, &mem_reqs, &dedicatedAllocation); diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index d3ae7c20d4..ced1d8df67 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -538,7 +538,7 @@ struct TextureDesc { int mipLevels; bool generateMips; // Optional, for tracking memory usage and graphcis debuggers. - std::string tag; + const char *tag; // Does not take ownership over pointed-to data. std::vector initData; TextureCallback initDataCallback; diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 3c90511893..7c033aeed3 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -714,7 +714,9 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur height_ = desc.height; depth_ = desc.depth; vkTex_ = new VulkanTexture(vulkan_); - vkTex_->SetTag(desc.tag); + if (desc.tag) { + vkTex_->SetTag(desc.tag); + } VkFormat vulkanFormat = DataFormatToVulkan(format_); int bpp = GetBpp(vulkanFormat); int bytesPerPixel = bpp / 8; From fd41c9cd5708b392e5e4b89d013b908a30a6c1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 9 Aug 2020 10:28:37 +0200 Subject: [PATCH 453/848] These convenience overloads don't work in 32-bit builds, remove them. --- Common/Vulkan/VulkanContext.h | 11 ----------- Common/Vulkan/VulkanImage.cpp | 2 +- ext/native/thin3d/VulkanRenderManager.cpp | 2 +- ext/native/thin3d/VulkanRenderManager.h | 4 ++-- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index a10692b88f..7c9174f38f 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -175,17 +175,6 @@ public: } } - // Shorthand for the above, the most common types we want to tag. - void SetDebugName(VkImage image, const char *name) { - SetDebugName(image, VK_OBJECT_TYPE_IMAGE, name); - } - void SetDebugName(VkFramebuffer framebuf, const char *name) { - SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, name); - } - void SetDebugName(VkSampler sampler, const char *name) { - SetDebugName(sampler, VK_OBJECT_TYPE_SAMPLER, name); - } - bool MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex); VkPhysicalDevice GetPhysicalDevice(int n) const { diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 1d9b8d7ffe..247df10ff9 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -72,7 +72,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all } // Apply the tag - vulkan_->SetDebugName(image_, tag_.c_str()); + vulkan_ ->SetDebugName(image_, VK_OBJECT_TYPE_IMAGE, tag_.c_str()); VkMemoryRequirements mem_reqs{}; bool dedicatedAllocation = false; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 01e692de59..a56a357cc7 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -718,7 +718,7 @@ bool VulkanRenderManager::InitDepthStencilBuffer(VkCommandBuffer cmd) { if (res != VK_SUCCESS) return false; - vulkan_->SetDebugName(depth_.image, "BackbufferDepth"); + vulkan_->SetDebugName(depth_.image, VK_OBJECT_TYPE_IMAGE, "BackbufferDepth"); bool dedicatedAllocation = false; VkMemoryRequirements mem_reqs; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 0122dc488e..6113132980 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -52,8 +52,8 @@ public: vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf); if (vk->Extensions().EXT_debug_utils) { - vk->SetDebugName(color.image, StringFromFormat("fb_color_%s", tag).c_str()); - vk->SetDebugName(depth.image, StringFromFormat("fb_depth_%s", tag).c_str()); + vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_color_%s", tag).c_str()); + vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_depth_%s", tag).c_str()); vk->SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, StringFromFormat("fb_%s", tag).c_str()); } } From e6dfb55d3db6910bfd2e5e35713709514303fc5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 7 Aug 2020 11:19:48 +0200 Subject: [PATCH 454/848] Optimize value conversion in (unused) depth readback. This also exposes factors we can feed into shaders to do the conversion on the GPU. --- GPU/Common/GPUStateUtils.cpp | 12 +++++++++--- GPU/Common/GPUStateUtils.h | 13 ++++++++++++- GPU/Directx9/FramebufferManagerDX9.cpp | 3 ++- GPU/GLES/DepthBufferGLES.cpp | 5 ++++- Windows/GEDebugger/GEDebugger.cpp | 18 +++++++++++++++--- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 1fd166cf45..8d8ebba59b 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -531,14 +531,20 @@ float ToScaledDepthFromIntegerScale(float z) { } } -float FromScaledDepth(float z) { +// See struct DepthScaleFactors for how to apply. +DepthScaleFactors GetDepthScaleFactors() { + DepthScaleFactors factors; if (!gstate_c.Supports(GPU_SUPPORTS_ACCURATE_DEPTH)) { - return z * 65535.0f; + factors.offset = 0; + factors.scale = 65535.0f; + return factors; } const float depthSliceFactor = DepthSliceFactor(); const float offset = 0.5f * (depthSliceFactor - 1.0f) * (1.0f / depthSliceFactor); - return (z - offset) * depthSliceFactor * 65535.0f; + factors.scale = depthSliceFactor * 65535.0f; + factors.offset = offset; + return factors; } void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, float renderHeight, int bufferWidth, int bufferHeight, ViewportAndScissor &out) { diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h index c4a26058f7..d58d38f6d4 100644 --- a/GPU/Common/GPUStateUtils.h +++ b/GPU/Common/GPUStateUtils.h @@ -72,7 +72,18 @@ struct ViewportAndScissor { }; void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, float renderHeight, int bufferWidth, int bufferHeight, ViewportAndScissor &out); float ToScaledDepthFromIntegerScale(float z); -float FromScaledDepth(float z); + +// Use like this: (z - offset) * scale +struct DepthScaleFactors { + float offset; + float scale; + + float Apply(float z) const { + return (z - offset) * scale; + } +}; +DepthScaleFactors GetDepthScaleFactors(); + float DepthSliceFactor(); // These are common to all modern APIs and can be easily converted with a lookup table. diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 5e70c0b350..012846f25c 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -538,12 +538,13 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { const u32 *packed = (const u32 *)locked.pBits; u16 *depth = (u16 *)Memory::GetPointer(z_address); + DepthScaleFactors depthScale = GetDepthScaleFactors(); // TODO: Optimize. for (int yp = 0; yp < h; ++yp) { for (int xp = 0; xp < w; ++xp) { const int offset = (yp + y) * vfb->z_stride + x + xp; - float scaled = FromScaledDepth((packed[offset] & 0x00FFFFFF) * (1.0f / 16777215.0f)); + float scaled = depthScale.Apply((packed[offset] & 0x00FFFFFF) * (1.0f / 16777215.0f)); if (scaled <= 0.0f) { depth[offset] = 0; } else if (scaled >= 65535.0f) { diff --git a/GPU/GLES/DepthBufferGLES.cpp b/GPU/GLES/DepthBufferGLES.cpp index 2a7238e8ea..145963cd7b 100644 --- a/GPU/GLES/DepthBufferGLES.cpp +++ b/GPU/GLES/DepthBufferGLES.cpp @@ -169,6 +169,7 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int int totalPixels = h == 1 ? packWidth : vfb->z_stride * h; if (format16Bit) { + // TODO: We have to apply GetDepthScaleFactors here too, right? for (int yp = 0; yp < h; ++yp) { int row_offset = vfb->z_stride * yp; for (int xp = 0; xp < packWidth; ++xp) { @@ -177,11 +178,13 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int } } } else { + // TODO: Apply this in the shader. + DepthScaleFactors depthScale = GetDepthScaleFactors(); for (int yp = 0; yp < h; ++yp) { int row_offset = vfb->z_stride * yp; for (int xp = 0; xp < packWidth; ++xp) { const int i = row_offset + xp; - float scaled = FromScaledDepth(packedf[i]); + float scaled = depthScale.Apply(packedf[i]); if (scaled <= 0.0f) { depth[i] = 0; } else if (scaled >= 65535.0f) { diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 6b41ca425b..aa0de48d05 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -546,9 +546,12 @@ void CGEDebugger::DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, break; case GPU_DBG_FORMAT_24BIT_8X: + { + DepthScaleFactors depthScale = GetDepthScaleFactors(); // These are only ever going to be depth values, so let's also show scaled to 16 bit. - _snwprintf(desc, 256, L"%d,%d: %d / %f / %f", x, y, pix & 0x00FFFFFF, (pix & 0x00FFFFFF) * (1.0f / 16777215.0f), FromScaledDepth((pix & 0x00FFFFFF) * (1.0f / 16777215.0f))); + _snwprintf(desc, 256, L"%d,%d: %d / %f / %f", x, y, pix & 0x00FFFFFF, (pix & 0x00FFFFFF) * (1.0f / 16777215.0f), depthScale.Apply((pix & 0x00FFFFFF) * (1.0f / 16777215.0f))); break; + } case GPU_DBG_FORMAT_24BIT_8X_DIV_256: { @@ -563,15 +566,24 @@ void CGEDebugger::DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, _snwprintf(desc, 256, L"%d,%d: %d / %f", x, y, (pix >> 24) & 0xFF, ((pix >> 24) & 0xFF) * (1.0f / 255.0f)); break; - case GPU_DBG_FORMAT_FLOAT: - _snwprintf(desc, 256, L"%d,%d: %f / %f", x, y, *(float *)&pix, FromScaledDepth(*(float *)&pix)); + case GPU_DBG_FORMAT_FLOAT: { + float pixf = *(float *)&pix; + DepthScaleFactors depthScale = GetDepthScaleFactors(); + _snwprintf(desc, 256, L"%d,%d: %f / %f", x, y, pixf, depthScale.Apply(pixf)); break; + } case GPU_DBG_FORMAT_FLOAT_DIV_256: { double z = *(float *)&pix; int z24 = (int)(z * 16777215.0); + + DepthScaleFactors factors = GetDepthScaleFactors(); + // TODO: Use GetDepthScaleFactors here too, verify it's the same. int z16 = z24 - 0x800000 + 0x8000; + + int z16_2 = factors.Apply(z); + _snwprintf(desc, 256, L"%d,%d: %d / %f", x, y, z16, (z - 0.5 + (1.0 / 512.0)) * 256.0); } break; From cf122e933335d59fe60ed386720ecefd2d7c460f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Nov 2017 12:24:05 +0100 Subject: [PATCH 455/848] Vulkan/generic: Initial prep for depth texturing --- GPU/Common/TextureCacheCommon.h | 2 + ext/native/thin3d/VulkanQueueRunner.cpp | 47 +++++++++++++++++++++-- ext/native/thin3d/VulkanQueueRunner.h | 2 + ext/native/thin3d/VulkanRenderManager.cpp | 31 +++++++++++---- ext/native/thin3d/VulkanRenderManager.h | 8 ++-- 5 files changed, 74 insertions(+), 16 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index d0f7085969..eca1e13836 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -119,6 +119,8 @@ struct TexCacheEntry { STATUS_FREE_CHANGE = 0x200, // Allow one change before marking "frequent". STATUS_BAD_MIPS = 0x400, // Has bad or unusable mipmap levels. + + STATUS_DEPTH = 0x800, }; // Status, but int so we can zero initialize. diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index c1e2d34f00..f7825947db 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -949,9 +949,8 @@ void VulkanQueueRunner::LogReadbackImage(const VKRStep &step) { void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer cmd) { // TODO: If there are multiple, we can transition them together. for (const auto &iter : step.preTransitions) { - if (iter.fb->color.layout != iter.targetLayout) { - VkImageMemoryBarrier barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + if (iter.aspect == VK_IMAGE_ASPECT_COLOR_BIT && iter.fb->color.layout != iter.targetLayout) { + VkImageMemoryBarrier barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; barrier.oldLayout = iter.fb->color.layout; barrier.subresourceRange.layerCount = 1; barrier.subresourceRange.levelCount = 1; @@ -992,9 +991,49 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - vkCmdPipelineBarrier(cmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); iter.fb->color.layout = barrier.newLayout; + } else if (iter.aspect == VK_IMAGE_ASPECT_DEPTH_BIT && iter.fb->depth.layout != iter.targetLayout) { + VkImageMemoryBarrier barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; + barrier.oldLayout = iter.fb->depth.layout; + barrier.subresourceRange.layerCount = 1; + barrier.subresourceRange.levelCount = 1; + barrier.image = iter.fb->depth.image; + barrier.srcAccessMask = 0; + VkPipelineStageFlags srcStage; + VkPipelineStageFlags dstStage; + switch (barrier.oldLayout) { + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + srcStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + default: + Crash(); + break; + } + barrier.newLayout = iter.targetLayout; + switch (barrier.newLayout) { + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + break; + default: + Crash(); + break; + } + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + vkCmdPipelineBarrier(cmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); + iter.fb->depth.layout = barrier.newLayout; } } diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index e7851c3554..90210bf40d 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -107,6 +107,7 @@ enum class VKRRenderPassAction : uint8_t { }; struct TransitionRequest { + VkImageAspectFlags aspect; // COLOR or DEPTH VKRFramebuffer *fb; VkImageLayout targetLayout; }; @@ -141,6 +142,7 @@ struct VKRStep { // Downloads and textures from this pass. int numReads; VkImageLayout finalColorLayout; + VkImageLayout finalDepthStencilLayout; } render; struct { VKRFramebuffer *src; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index a56a357cc7..ee8740fe3c 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -580,7 +580,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR } } -bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { +bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, VkImageAspectFlags aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag) { _dbg_assert_(insideFrame_); for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { @@ -869,7 +869,7 @@ void VulkanRenderManager::Clear(uint32_t clearColor, float clearZ, int clearSten } } -void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, int aspectMask, const char *tag) { +void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, VkImageAspectFlags aspectMask, const char *tag) { _dbg_assert_msg_(srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); _dbg_assert_msg_(srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); _dbg_assert_msg_(srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); @@ -919,7 +919,7 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, curRenderStep_ = nullptr; } -void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter, const char *tag) { +void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, VkImageAspectFlags aspectMask, VkFilter filter, const char *tag) { _dbg_assert_msg_(srcRect.offset.x >= 0, "srcrect offset x (%d) < 0", srcRect.offset.x); _dbg_assert_msg_(srcRect.offset.y >= 0, "srcrect offset y (%d) < 0", srcRect.offset.y); _dbg_assert_msg_(srcRect.offset.x + srcRect.extent.width <= (uint32_t)src->width, "srcrect offset x (%d) + extent (%d) > width (%d)", srcRect.offset.x, srcRect.extent.width, (uint32_t)src->width); @@ -962,15 +962,30 @@ void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, curRenderStep_ = nullptr; } -VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, int aspectBit, int attachment) { +VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, VkImageAspectFlags aspectBit, int attachment) { _dbg_assert_(curRenderStep_ != nullptr); // Mark the dependency, check for required transitions, and return the image. for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == fb) { - // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. - if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { - steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + if (aspectBit == VK_IMAGE_ASPECT_COLOR_BIT) { + // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. + if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + break; + } else if (steps_[i]->render.finalColorLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + _assert_msg_(false, "Unexpected color layout %d", (int)steps_[i]->render.finalColorLayout); + // May need to shadow the framebuffer if we re-order passes later. + } + } else { + // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. + if (steps_[i]->render.finalDepthStencilLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps_[i]->render.finalDepthStencilLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + break; + } else if (steps_[i]->render.finalDepthStencilLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + _assert_msg_(false, "Unexpected depth layout %d", (int)steps_[i]->render.finalDepthStencilLayout); + // May need to shadow the framebuffer if we re-order passes later. + } } steps_[i]->render.numReads++; break; @@ -986,7 +1001,7 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in // We're done. return fb->color.imageView; } else { - curRenderStep_->preTransitions.push_back({ fb, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }); + curRenderStep_->preTransitions.push_back({ aspectBit, fb, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }); return fb->color.imageView; } } diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 6113132980..c1607354f4 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -130,13 +130,13 @@ public: // Returns an ImageView corresponding to a framebuffer. Is called BindFramebufferAsTexture to maintain a similar interface // as the other backends, even though there's no actual binding happening here. - VkImageView BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, int aspectBit, int attachment); + VkImageView BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, VkImageAspectFlags aspectBits, int attachment); - bool CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); + bool CopyFramebufferToMemorySync(VKRFramebuffer *src, VkImageAspectFlags aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); void CopyImageToMemorySync(VkImage image, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride, const char *tag); - void CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, int aspectMask, const char *tag); - void BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, int aspectMask, VkFilter filter, const char *tag); + void CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkOffset2D dstPos, VkImageAspectFlags aspectMask, const char *tag); + void BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, VKRFramebuffer *dst, VkRect2D dstRect, VkImageAspectFlags aspectMask, VkFilter filter, const char *tag); void BindPipeline(VkPipeline pipeline) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); From 375da0a2fe4d81d83f13f58f4f47e1d5942b377e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 9 Aug 2020 19:40:46 +0200 Subject: [PATCH 456/848] Some fixes --- ext/native/thin3d/VulkanRenderManager.cpp | 29 ++++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index ee8740fe3c..dcc5f6ccf7 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -885,8 +885,15 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { - if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { - steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { + if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + } + } + if (aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + if (steps_[i]->render.finalDepthStencilLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps_[i]->render.finalDepthStencilLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + } } steps_[i]->render.numReads++; break; @@ -894,8 +901,15 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, } for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == dst) { - if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { - steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + if (aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { + if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + } + } + if (aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + if (steps_[i]->render.finalDepthStencilLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps_[i]->render.finalDepthStencilLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + } } break; } @@ -936,6 +950,8 @@ void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect, _dbg_assert_msg_(dstRect.extent.width > 0, "blit dstwidth == 0"); _dbg_assert_msg_(dstRect.extent.height > 0, "blit dstheight == 0"); + // TODO: Seem to be missing final layouts here like in Copy... + for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) { steps_[i]->render.numReads++; @@ -968,7 +984,7 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == fb) { - if (aspectBit == VK_IMAGE_ASPECT_COLOR_BIT) { + if (aspectBit & VK_IMAGE_ASPECT_COLOR_BIT) { // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -977,7 +993,8 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in _assert_msg_(false, "Unexpected color layout %d", (int)steps_[i]->render.finalColorLayout); // May need to shadow the framebuffer if we re-order passes later. } - } else { + } + if (aspectBit & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. if (steps_[i]->render.finalDepthStencilLayout == VK_IMAGE_LAYOUT_UNDEFINED) { steps_[i]->render.finalDepthStencilLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; From ba0d04a14275a1deb2e613974569a497591a8e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 22 Nov 2017 12:24:05 +0100 Subject: [PATCH 457/848] Vulkan: Implement depth texturing through depal. --- GPU/Common/DepalettizeShaderCommon.cpp | 23 ++++++++- GPU/Common/FramebufferManagerCommon.cpp | 26 +++++++---- GPU/Common/GPUStateUtils.cpp | 3 -- GPU/Common/TextureCacheCommon.cpp | 57 +++++++++++++---------- GPU/Common/TextureCacheCommon.h | 15 ++++-- GPU/GeDisasm.cpp | 2 +- GPU/Vulkan/DepalettizeShaderVulkan.cpp | 2 + GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 19 ++++++-- GPU/ge_constants.h | 1 + ext/native/thin3d/VulkanQueueRunner.cpp | 27 +++++++---- ext/native/thin3d/VulkanQueueRunner.h | 6 +-- ext/native/thin3d/VulkanRenderManager.cpp | 9 ++-- 13 files changed, 128 insertions(+), 64 deletions(-) diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index a29f4f49e9..871fea767c 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -45,6 +45,14 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang WRITE(p, "layout(set = 0, binding = 1) uniform sampler2D pal;\n"); WRITE(p, "layout(location = 0) in vec2 v_texcoord0;\n"); WRITE(p, "layout(location = 0) out vec4 fragColor0;\n"); + + // Support for depth. + if (pixelFormat == GE_FORMAT_DEPTH16) { + WRITE(p, "layout (push_constant) uniform params {\n"); + WRITE(p, " float z_scale; float z_offset;\n"); + WRITE(p, "};\n"); + } + } else { if (gl_extensions.IsGLES) { WRITE(p, "#version 300 es\n"); @@ -63,9 +71,12 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang WRITE(p, "float4 main(in float2 v_texcoord0 : TEXCOORD0) : SV_Target {\n"); WRITE(p, " float4 color = tex.Sample(texSamp, v_texcoord0);\n"); } else { - // TODO: Add support for integer textures. Though it hardly matters. WRITE(p, "void main() {\n"); - WRITE(p, " vec4 color = texture(tex, v_texcoord0);\n"); + if (pixelFormat == GE_FORMAT_DEPTH16) { + WRITE(p, " float color = texture(tex, v_texcoord0).r;\n"); + } else { + WRITE(p, " vec4 color = texture(tex, v_texcoord0);\n"); + } } int mask = gstate.getClutIndexMask(); @@ -105,6 +116,11 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang if (shiftedMask & 0x8000) WRITE(p, " int a = int(color.a);\n"); else WRITE(p, " int a = 0;\n"); WRITE(p, " int index = (a << 15) | (b << 10) | (g << 5) | (r);\n"); break; + case GE_FORMAT_DEPTH16: + // Remap depth buffer. + WRITE(p, " float depth = (color - z_offset) * z_scale;\n"); + WRITE(p, " int index = int(clamp(depth, 0.0, 65535.0));\n"); + break; default: break; } @@ -225,6 +241,9 @@ void GenerateDepalShaderFloat(char *buffer, GEBufferFormat pixelFormat, ShaderLa formatOK = false; } break; + case GE_FORMAT_DEPTH16: + sprintf(lookupMethod, "index.r * (1.0 / 256.0)"); + break; default: break; } diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 556e2519ee..06d6b08328 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -374,7 +374,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame ResizeFramebufFBO(vfb, drawing_width, drawing_height, true); NotifyRenderFramebufferCreated(vfb); - INFO_LOG(FRAMEBUF, "Creating FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format); + INFO_LOG(FRAMEBUF, "Creating FBO for %08x (z: %08x) : %i x %i x %i", vfb->fb_address, vfb->z_address, vfb->width, vfb->height, vfb->format); vfb->last_frame_render = gpuStats.numFlips; frameLastFramebufUsed_ = gpuStats.numFlips; @@ -445,7 +445,9 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame } void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { - textureCache_->NotifyFramebuffer(v->fb_address, v, NOTIFY_FB_DESTROYED); + // Notify the texture cache of both the color and depth buffers. + textureCache_->NotifyFramebuffer(v->fb_address, v, NOTIFY_FB_DESTROYED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(v->z_address, v, NOTIFY_FB_DESTROYED, NOTIFY_FB_DEPTH); if (v->fbo) { v->fbo->Release(); v->fbo = nullptr; @@ -472,7 +474,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer DownloadFramebufferOnSwitch(currentRenderVfb_); } - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb->z_address, vfb, NOTIFY_FB_CREATED, NOTIFY_FB_DEPTH); // Ugly... if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { @@ -486,7 +489,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged) { if (vfbFormatChanged) { - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); if (vfb->drawnFormat != vfb->format) { ReformatFramebufferFrom(vfb, vfb->drawnFormat); } @@ -552,7 +556,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe } else { if (vfb->fbo) { // This should only happen very briefly when toggling useBufferedRendering_. - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_DESTROYED); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_DESTROYED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb->z_address, vfb, NOTIFY_FB_DESTROYED, NOTIFY_FB_DEPTH); vfb->fbo->Release(); vfb->fbo = nullptr; } @@ -564,7 +569,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB; } } - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb->z_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); // ugly... is all this needed? if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { @@ -1164,9 +1170,9 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, if (dstBuffer && srcBuffer && !isMemset) { if (srcBuffer == dstBuffer) { - WARN_LOG_REPORT_ONCE(dstsrccpy, G3D, "Intra-buffer memcpy (not supported) %08x -> %08x", src, dst); + WARN_LOG_REPORT_ONCE(dstsrccpy, G3D, "Intra-buffer memcpy (not supported) %08x -> %08x (size: %x)", src, dst, size); } else { - WARN_LOG_REPORT_ONCE(dstnotsrccpy, G3D, "Inter-buffer memcpy %08x -> %08x", src, dst); + WARN_LOG_REPORT_ONCE(dstnotsrccpy, G3D, "Inter-buffer memcpy %08x -> %08x (size: %x)", src, dst, size); // Just do the blit! BlitFramebuffer(dstBuffer, 0, dstY, srcBuffer, 0, srcY, srcBuffer->width, srcH, 0); SetColorUpdated(dstBuffer, skipDrawReason); @@ -1177,7 +1183,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, if (isMemset) { gpuStats.numClears++; } - WARN_LOG_ONCE(btucpy, G3D, "Memcpy fbo upload %08x -> %08x", src, dst); + WARN_LOG_ONCE(btucpy, G3D, "Memcpy fbo upload %08x -> %08x (size: %x)", src, dst, size); FlushBeforeCopy(); const u8 *srcBase = Memory::GetPointerUnchecked(src); DrawPixels(dstBuffer, 0, dstY, srcBase, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstH); @@ -1330,9 +1336,9 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd vfb->drawnFormat = GE_FORMAT_8888; vfb->usageFlags = FB_USAGE_RENDERTARGET; SetColorUpdated(vfb, 0); - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED); char name[64]; snprintf(name, sizeof(name), "%08x_color_RAM", vfb->fb_address); + textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED, NOTIFY_FB_COLOR); vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, name }); vfbs_.push_back(vfb); diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 8d8ebba59b..2f629b1b89 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -633,9 +633,6 @@ void ConvertViewportAndScissor(bool useBufferedRendering, float renderWidth, flo float vpWidth = fabsf(gstate_c.vpWidth); float vpHeight = fabsf(gstate_c.vpHeight); - // We used to apply the viewport here via glstate, but there are limits which vary by driver. - // This may mean some games won't work, or at least won't work at higher render resolutions. - // So we apply it in the shader instead. float left = renderX + vpX0; float top = renderY + vpY0; float right = left + vpWidth; diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 2587761719..2789d1ff29 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -389,7 +389,7 @@ void TextureCacheCommon::SetTexture(bool force) { return; } else { // Make sure we re-evaluate framebuffers. - DetachFramebuffer(entry, texaddr, entry->framebuffer); + DetachFramebuffer(entry, texaddr, entry->framebuffer, (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR); reason = "detached framebuf"; match = false; } @@ -530,7 +530,7 @@ void TextureCacheCommon::SetTexture(bool force) { entry->framebuffer = nullptr; for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { auto framebuffer = fbCache_[i]; - AttachFramebuffer(entry, framebuffer->fb_address, framebuffer); + AttachFramebuffer(entry, framebuffer->fb_address, framebuffer, 0, (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR); } // If we ended up with a framebuffer, attach it - no texture decoding needed. @@ -640,12 +640,12 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c entry->numFrames = 0; } -void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg) { +void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel) { // Mask to ignore the Z memory mirrors if the address is in VRAM. // These checks are mainly to reduce scanning all textures. const u32 mirrorMask = 0x00600000; const u32 addr = Memory::IsVRAMAddress(address) ? (address & ~mirrorMask) : address; - const u32 bpp = framebuffer->format == GE_FORMAT_8888 ? 4 : 2; + const u32 bpp = (framebuffer->format == GE_FORMAT_8888 && channel == NOTIFY_FB_COLOR) ? 4 : 2; const u64 cacheKey = (u64)addr << 32; // If it has a clut, those are the low 32 bits, so it'll be inside this range. // Also, if it's a subsample of the buffer, it'll also be within the FBO. @@ -663,14 +663,14 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram fbCache_.push_back(framebuffer); } for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { - AttachFramebuffer(it->second.get(), addr, framebuffer); + AttachFramebuffer(it->second.get(), addr, framebuffer, 0, channel); } // Let's assume anything in mirrors is fair game to check. for (auto it = cache_.lower_bound(mirrorCacheKey), end = cache_.upper_bound(mirrorCacheKeyEnd); it != end; ++it) { const u64 mirrorlessKey = it->first & ~0x0060000000000000ULL; // Let's still make sure it's in the cache range. if (mirrorlessKey >= cacheKey && mirrorlessKey <= cacheKeyEnd) { - AttachFramebuffer(it->second.get(), addr, framebuffer); + AttachFramebuffer(it->second.get(), addr, framebuffer, 0, channel); } } break; @@ -685,12 +685,13 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram // We might erase, so move to the next one already (which won't become invalid.) ++it; - DetachFramebuffer(cache_[cachekey].get(), addr, framebuffer); + DetachFramebuffer(cache_[cachekey].get(), addr, framebuffer, channel); } break; } } -void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) { + +void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo, FramebufferNotificationChannel channel) { const u64 cachekey = entry->CacheKey(); const bool hasInvalidFramebuffer = entry->framebuffer == nullptr || entry->invalidHint == -1; const bool hasOlderFramebuffer = entry->framebuffer != nullptr && entry->framebuffer->last_frame_render < framebuffer->last_frame_render; @@ -713,6 +714,9 @@ void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFra entry->invalidHint = 0; entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; entry->maxLevel = 0; + if (channel == NOTIFY_FB_DEPTH) { + entry->status |= TexCacheEntry::STATUS_DEPTH; + } fbTexInfo_[cachekey] = fbInfo; framebuffer->last_frame_attached = gpuStats.numFlips; GPUDebug::NotifyTextureAttachment(entry->addr); @@ -721,7 +725,7 @@ void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFra } } -void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) { +void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo, FramebufferNotificationChannel channel) { const u64 cachekey = entry->CacheKey(); if (entry->framebuffer == nullptr || entry->framebuffer == framebuffer) { @@ -733,12 +737,14 @@ void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualF entry->invalidHint = -1; entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; entry->maxLevel = 0; + if (channel == NOTIFY_FB_DEPTH) + entry->status |= TexCacheEntry::STATUS_DEPTH; fbTexInfo_[cachekey] = fbInfo; GPUDebug::NotifyTextureAttachment(entry->addr); } } -void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) { +void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel) { if (entry->framebuffer == framebuffer) { const u64 cachekey = entry->CacheKey(); cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); @@ -751,20 +757,20 @@ void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, Vi } } -bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset) { +bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) { static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32; AttachedFramebufferInfo fbInfo = { 0 }; const u32 mirrorMask = 0x00600000; u32 addr = address & 0x3FFFFFFF; - u32 texaddr = entry->addr + texaddrOffset; + u32 texaddr = (entry->addr + texaddrOffset) & ~mirrorMask; if (entry->addr & 0x04000000) { addr &= ~mirrorMask; texaddr &= ~mirrorMask; } const bool noOffset = texaddr == addr; - const bool exactMatch = noOffset && entry->format < 4; + const bool exactMatch = noOffset && entry->format < 4 && channel == NOTIFY_FB_COLOR; const u32 w = 1 << ((entry->dim >> 0) & 0xf); const u32 h = 1 << ((entry->dim >> 8) & 0xf); // 512 on a 272 framebuffer is sane, so let's be lenient. @@ -781,10 +787,10 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. // However, some games use a different format to clear the buffer. if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) { - DetachFramebuffer(entry, address, framebuffer); + DetachFramebuffer(entry, address, framebuffer, channel); } } else { - AttachFramebufferValid(entry, framebuffer, fbInfo); + AttachFramebufferValid(entry, framebuffer, fbInfo, channel); return true; } } else { @@ -792,6 +798,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi if (!framebufferManager_->UseBufferedRendering()) return false; + // Check works for D16 too (???) const bool matchingClutFormat = (framebuffer->format == GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT32) || (framebuffer->format != GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT16); @@ -809,7 +816,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi WARN_LOG_ONCE(diffStrides2, G3D, "Texturing from framebuffer (matching_clut=%s) different strides %d != %d", matchingClutFormat ? "yes" : "no", entry->bufw, framebuffer->fb_stride); } else { // Assume any render-to-tex with different bufw + offset is a render from ram. - DetachFramebuffer(entry, address, framebuffer); + DetachFramebuffer(entry, address, framebuffer, channel); return false; } } @@ -817,13 +824,13 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // Check if it's in bufferWidth (which might be higher than width and may indicate the framebuffer includes the data.) if (fbInfo.xOffset >= framebuffer->bufferWidth && fbInfo.xOffset + w <= (u32)framebuffer->fb_stride) { // This happens in Brave Story, see #10045 - the texture is in the space between strides, with matching stride. - DetachFramebuffer(entry, address, framebuffer); + DetachFramebuffer(entry, address, framebuffer, channel); return false; } if (fbInfo.yOffset + minSubareaHeight >= framebuffer->height) { // Can't be inside the framebuffer then, ram. Detach to be safe. - DetachFramebuffer(entry, address, framebuffer); + DetachFramebuffer(entry, address, framebuffer, channel); return false; } @@ -831,7 +838,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // TODO: Maybe we can reduce this check and find a better way above 0x04110000? if (fbInfo.yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 0x04110000) { WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); - DetachFramebuffer(entry, address, framebuffer); + DetachFramebuffer(entry, address, framebuffer, channel); return false; } @@ -841,13 +848,13 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi if (!noOffset) { WARN_LOG_REPORT_ONCE(subareaClut, G3D, "Texturing from framebuffer using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); } - AttachFramebufferValid(entry, framebuffer, fbInfo); + AttachFramebufferValid(entry, framebuffer, fbInfo, channel); entry->status |= TexCacheEntry::STATUS_DEPALETTIZE; // We'll validate it compiles later. return true; } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) { WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffer of format %s", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format)); - DetachFramebuffer(entry, address, framebuffer); + DetachFramebuffer(entry, address, framebuffer, channel); return false; } @@ -856,18 +863,18 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi if (framebuffer->format != entry->format) { WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); - AttachFramebufferValid(entry, framebuffer, fbInfo); + AttachFramebufferValid(entry, framebuffer, fbInfo, channel); return true; } else { WARN_LOG_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); // If "AttachFramebufferValid" , God of War Ghost of Sparta/Chains of Olympus will be missing special effect. - AttachFramebufferInvalid(entry, framebuffer, fbInfo); + AttachFramebufferInvalid(entry, framebuffer, fbInfo, channel); return true; } } else { WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); - DetachFramebuffer(entry, address, framebuffer); + DetachFramebuffer(entry, address, framebuffer, channel); return false; } } @@ -944,7 +951,7 @@ bool TextureCacheCommon::SetOffsetTexture(u32 yOffset) { bool success = false; for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { auto framebuffer = fbCache_[i]; - if (AttachFramebuffer(entry, framebuffer->fb_address, framebuffer, texaddrOffset)) { + if (AttachFramebuffer(entry, framebuffer->fb_address, framebuffer, texaddrOffset, (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR)) { success = true; } } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index eca1e13836..4962856342 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -41,6 +41,11 @@ enum FramebufferNotification { NOTIFY_FB_DESTROYED, }; +enum FramebufferNotificationChannel { + NOTIFY_FB_COLOR = 0, + NOTIFY_FB_DEPTH = 1, +}; + // Changes more frequent than this will be considered "frequent" and prevent texture scaling. #define TEXCACHE_FRAME_CHANGE_FREQUENT 6 // Note: only used when hash backoff is disabled. @@ -200,7 +205,7 @@ public: virtual void Clear(bool delete_them); // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to. - void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg); + void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel); virtual void NotifyConfigChanged(); void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt); @@ -251,10 +256,10 @@ protected: void UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key); // Used by D3D11 and Vulkan. void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode); - bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0); - void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo); - void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo); - void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer); + bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel); + void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo, FramebufferNotificationChannel channel); + void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo, FramebufferNotificationChannel channel); + void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel); void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer); diff --git a/GPU/GeDisasm.cpp b/GPU/GeDisasm.cpp index 4faaca6a43..fda2d77890 100644 --- a/GPU/GeDisasm.cpp +++ b/GPU/GeDisasm.cpp @@ -429,7 +429,7 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer, int bufsize) { case GE_CMD_LOADCLUT: // This could be used to "dirty" textures with clut. if (data) - snprintf(buffer, bufsize, "Clut load: %06x", data); + snprintf(buffer, bufsize, "Clut load: %08x, %d bytes, %06x", gstate.getClutAddress(), (data & 0x3F) << 5, data & 0xFFFFC0); else snprintf(buffer, bufsize, "Clut load"); break; diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.cpp b/GPU/Vulkan/DepalettizeShaderVulkan.cpp index 31041b010b..e1cc53fd09 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.cpp +++ b/GPU/Vulkan/DepalettizeShaderVulkan.cpp @@ -103,6 +103,7 @@ DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMod std::string error; VkShaderModule fshader = CompileShaderModule(vulkan_, VK_SHADER_STAGE_FRAGMENT_BIT, buffer, &error); if (fshader == VK_NULL_HANDLE) { + INFO_LOG(G3D, "Source:\n%s\n\n", buffer); Crash(); delete[] buffer; return nullptr; @@ -111,6 +112,7 @@ DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMod VkPipeline pipeline = vulkan2D_->GetPipeline(rp, vshader_, fshader); // Can delete the shader module now that the pipeline has been created. // Maybe don't even need to queue it.. + // "true" keeps the pipeline itself alive, forgetting the fshader. vulkan2D_->PurgeFragmentShader(fshader, true); vulkan_->Delete().QueueDeleteShaderModule(fshader); diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 515adb158d..4cd2c98363 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 17 +#define CACHE_VERSION 18 struct VulkanCacheHeader { uint32_t magic; uint32_t version; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index d15f68988a..1dc8630082 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -558,8 +558,9 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr DepalShaderVulkan *depalShader = nullptr; uint32_t clutMode = gstate.clutformat & 0xFFFFFF; - bool useShaderDepal = framebufferManager_->GetCurrentRenderVFB() != framebuffer; bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS); + bool depth = (entry->status & TexCacheEntry::STATUS_DEPTH) != 0; + bool useShaderDepal = framebufferManager_->GetCurrentRenderVFB() != framebuffer && !depth; if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { if (useShaderDepal) { @@ -584,7 +585,7 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr imageView_ = framebufferManagerVulkan_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); return; } else { - depalShader = depalShaderCache_->GetDepalettizeShader(clutMode, framebuffer->drawnFormat); + depalShader = depalShaderCache_->GetDepalettizeShader(clutMode, depth ? GE_FORMAT_DEPTH16 : framebuffer->drawnFormat); drawEngine_->SetDepalTexture(VK_NULL_HANDLE); gstate_c.SetUseShaderDepal(false); } @@ -652,12 +653,24 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr VkBuffer pushed; uint32_t offset = push_->PushAligned(verts, sizeof(verts), 4, &pushed); - draw_->BindFramebufferAsTexture(framebuffer->fbo, 0, Draw::FB_COLOR_BIT, 0); + draw_->BindFramebufferAsTexture(framebuffer->fbo, 0, depth ? Draw::FB_DEPTH_BIT : Draw::FB_COLOR_BIT, 0); VkImageView fbo = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW); VkDescriptorSet descSet = vulkan2D_->GetDescriptorSet(fbo, samplerNearest_, clutTexture->GetImageView(), samplerNearest_); VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); renderManager->BindPipeline(depalShader->pipeline); + + if (depth) { + DepthScaleFactors scaleFactors = GetDepthScaleFactors(); + struct DepthPushConstants { + float z_scale; + float z_offset; + }; + DepthPushConstants push; + push.z_scale = scaleFactors.scale; + push.z_offset = scaleFactors.offset; + renderManager->PushConstants(vulkan2D_->GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(DepthPushConstants), &push); + } renderManager->SetScissor(VkRect2D{ {0, 0}, { framebuffer->renderWidth, framebuffer->renderHeight} }); renderManager->SetViewport(VkViewport{ 0.f, 0.f, (float)framebuffer->renderWidth, (float)framebuffer->renderHeight, 0.f, 1.f }); renderManager->Draw(vulkan2D_->GetPipelineLayout(), descSet, 0, nullptr, pushed, offset, 4); diff --git a/GPU/ge_constants.h b/GPU/ge_constants.h index fc7c2ca982..5facb4ad05 100644 --- a/GPU/ge_constants.h +++ b/GPU/ge_constants.h @@ -282,6 +282,7 @@ enum GEBufferFormat GE_FORMAT_5551 = 1, GE_FORMAT_4444 = 2, GE_FORMAT_8888 = 3, + GE_FORMAT_DEPTH16 = 4, // Virtual format, just used to pass into Depal GE_FORMAT_INVALID = 0xFF, }; diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index f7825947db..0ede7acccc 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -2,6 +2,7 @@ #include "base/timeutil.h" #include "DataFormat.h" +#include "Common/Log.h" #include "VulkanQueueRunner.h" #include "VulkanRenderManager.h" @@ -12,7 +13,7 @@ void VulkanQueueRunner::CreateDeviceObjects() { InitBackbufferRenderPass(); framebufferRenderPass_ = GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); #if 0 // Just to check whether it makes sense to split some of these. drawidx is way bigger than the others... @@ -238,7 +239,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { attachments[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; #else attachments[1].initialLayout = key.prevDepthLayout; - attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + attachments[1].finalLayout = key.finalDepthStencilLayout; #endif attachments[1].flags = 0; @@ -387,10 +388,13 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &st for (int j = 0; j < (int)steps.size(); j++) { if (steps[j]->stepType == VKRStepType::RENDER && - steps[j]->render.framebuffer && - steps[j]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { - // Just leave it at color_optimal. - steps[j]->render.finalColorLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + steps[j]->render.framebuffer) { + if (steps[j]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps[j]->render.finalColorLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } + if (steps[j]->render.finalDepthStencilLayout == VK_IMAGE_LAYOUT_UNDEFINED) { + steps[j]->render.finalDepthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + } } } @@ -1043,6 +1047,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c return; } + // Write-after-write hazards. Fixed flicker in God of War on ARM (before we added another fix). + // TODO: depth too if (step.render.framebuffer && step.render.framebuffer->color.layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -1213,6 +1219,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c // The renderpass handles the layout transition. if (fb) { fb->color.layout = step.render.finalColorLayout; + fb->depth.layout = step.render.finalDepthStencilLayout; } } @@ -1225,6 +1232,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step int h; if (step.render.framebuffer) { _dbg_assert_(step.render.finalColorLayout != VK_IMAGE_LAYOUT_UNDEFINED); + _dbg_assert_(step.render.finalDepthStencilLayout != VK_IMAGE_LAYOUT_UNDEFINED); VKRFramebuffer *fb = step.render.framebuffer; framebuf = fb->framebuf; @@ -1249,7 +1257,9 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step renderPass = GetRenderPass( step.render.color, step.render.depth, step.render.stencil, - fb->color.layout, fb->depth.layout, step.render.finalColorLayout); + fb->color.layout, fb->depth.layout, + step.render.finalColorLayout, + step.render.finalDepthStencilLayout); // We now do any layout pretransitions as part of the render pass. fb->color.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; @@ -1685,6 +1695,7 @@ void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataForm } else if (srcFormat == Draw::DataFormat::B8G8R8A8_UNORM) { ConvertFromBGRA8888(pixels, (const uint8_t *)mappedData, pixelStride, width, width, height, destFormat); } else if (srcFormat == destFormat) { + // Can just memcpy when it matches no matter the format! uint8_t *dst = pixels; const uint8_t *src = (const uint8_t *)mappedData; for (int y = 0; y < height; ++y) { @@ -1697,7 +1708,7 @@ void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataForm } else { // TODO: Maybe a depth conversion or something? ELOG("CopyReadbackBuffer: Unknown format"); - assert(false); + _assert_msg_(false, "CopyReadbackBuffer: Unknown src format %d", (int)srcFormat); } vkUnmapMemory(vulkan_->GetDevice(), readbackMemory_); } diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index 90210bf40d..a89951af3b 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -212,14 +212,14 @@ public: VkImageLayout prevColorLayout; VkImageLayout prevDepthLayout; VkImageLayout finalColorLayout; - // TODO: Also pre-transition depth, for copies etc. + VkImageLayout finalDepthStencilLayout; }; // Only call this from the render thread! Also ok during initialization (LoadCache). VkRenderPass GetRenderPass( VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction, - VkImageLayout prevColorLayout, VkImageLayout prevDepthLayout, VkImageLayout finalColorLayout) { - RPKey key{ colorLoadAction, depthLoadAction, stencilLoadAction, prevColorLayout, prevDepthLayout, finalColorLayout }; + VkImageLayout prevColorLayout, VkImageLayout prevDepthLayout, VkImageLayout finalColorLayout, VkImageLayout finalDepthStencilLayout) { + RPKey key{ colorLoadAction, depthLoadAction, stencilLoadAction, prevColorLayout, prevDepthLayout, finalColorLayout, finalDepthStencilLayout }; return GetRenderPass(key); } diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index dcc5f6ccf7..0a48e277aa 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -63,6 +63,8 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int res = vkBindImageMemory(vulkan->GetDevice(), img.image, img.memory, 0); _dbg_assert_(res == VK_SUCCESS); + // Note that we don't view or at + VkImageAspectFlags viewAspects = color ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; VkImageAspectFlags aspects = color ? VK_IMAGE_ASPECT_COLOR_BIT : (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); VkImageViewCreateInfo ivci{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; @@ -70,7 +72,7 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int ivci.format = ici.format; ivci.image = img.image; ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; - ivci.subresourceRange.aspectMask = aspects; + ivci.subresourceRange.aspectMask = viewAspects; ivci.subresourceRange.layerCount = 1; ivci.subresourceRange.levelCount = 1; res = vkCreateImageView(vulkan->GetDevice(), &ivci, nullptr, &img.imageView); @@ -548,6 +550,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR step->render.numDraws = 0; step->render.numReads = 0; step->render.finalColorLayout = !fb ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED; + step->render.finalDepthStencilLayout = !fb ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED; step->tag = tag; steps_.push_back(step); @@ -1016,10 +1019,10 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in curRenderStep_->preTransitions.back().fb == fb && curRenderStep_->preTransitions.back().targetLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { // We're done. - return fb->color.imageView; + return aspectBit == VK_IMAGE_ASPECT_COLOR_BIT ? fb->color.imageView : fb->depth.imageView; } else { curRenderStep_->preTransitions.push_back({ aspectBit, fb, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }); - return fb->color.imageView; + return aspectBit == VK_IMAGE_ASPECT_COLOR_BIT ? fb->color.imageView : fb->depth.imageView; } } From 86355779d7b578d138afe40620f2c42713480d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 9 Aug 2020 20:49:08 +0200 Subject: [PATCH 458/848] Remove partial comment --- ext/native/thin3d/VulkanRenderManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 0a48e277aa..385d8a580e 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -63,7 +63,6 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int res = vkBindImageMemory(vulkan->GetDevice(), img.image, img.memory, 0); _dbg_assert_(res == VK_SUCCESS); - // Note that we don't view or at VkImageAspectFlags viewAspects = color ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; VkImageAspectFlags aspects = color ? VK_IMAGE_ASPECT_COLOR_BIT : (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); From dd79d33f147410a91e47bc2c0e4a876ef79c3589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 9 Aug 2020 21:44:58 +0200 Subject: [PATCH 459/848] Minor: Initialize a struct. Decrease logging in sceMt19937. --- Core/HLE/sceMt19937.cpp | 3 +-- ext/native/thin3d/VulkanQueueRunner.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceMt19937.cpp b/Core/HLE/sceMt19937.cpp index a402bb5757..ba7aa28166 100644 --- a/Core/HLE/sceMt19937.cpp +++ b/Core/HLE/sceMt19937.cpp @@ -28,7 +28,7 @@ static u32 sceMt19937Init(u32 mt19937Addr, u32 seed) { - WARN_LOG(HLE, "sceMt19937Init(%08x, %08x)", mt19937Addr, seed); + INFO_LOG(HLE, "sceMt19937Init(%08x, %08x)", mt19937Addr, seed); if (!Memory::IsValidAddress(mt19937Addr)) return -1; void *ptr = Memory::GetPointer(mt19937Addr); @@ -40,7 +40,6 @@ static u32 sceMt19937Init(u32 mt19937Addr, u32 seed) static u32 sceMt19937UInt(u32 mt19937Addr) { - WARN_LOG(HLE, "sceMt19937UInt(%08x)", mt19937Addr); if (!Memory::IsValidAddress(mt19937Addr)) return -1; MersenneTwister *mt = (MersenneTwister *)Memory::GetPointer(mt19937Addr); diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index f7825947db..dbd2e02d0e 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -1179,7 +1179,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c rc.layerCount = 1; rc.rect.extent.width = (uint32_t)curWidth; rc.rect.extent.height = (uint32_t)curHeight; - VkClearAttachment attachments[2]; + VkClearAttachment attachments[2]{}; if (c.clear.clearMask & VK_IMAGE_ASPECT_COLOR_BIT) { VkClearAttachment &attachment = attachments[numAttachments++]; attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; From 0aa2ceb372f01883d0a4eb82dc3476453935d994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 10 Aug 2020 09:16:28 +0200 Subject: [PATCH 460/848] Address feedback --- GPU/Common/DepalettizeShaderCommon.cpp | 11 ++++- GPU/Common/FramebufferManagerCommon.cpp | 6 +-- GPU/Common/TextureCacheCommon.cpp | 7 ++-- ext/native/thin3d/VulkanQueueRunner.cpp | 54 +++++++++++++++++-------- 4 files changed, 55 insertions(+), 23 deletions(-) diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index 871fea767c..3e9cd383ab 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -21,6 +21,7 @@ #include "GPU/Common/ShaderId.h" #include "GPU/Common/ShaderCommon.h" +#include "Common/StringUtils.h" #include "Common/Log.h" #include "Core/Reporting.h" #include "GPU/GPUState.h" @@ -242,8 +243,16 @@ void GenerateDepalShaderFloat(char *buffer, GEBufferFormat pixelFormat, ShaderLa } break; case GE_FORMAT_DEPTH16: - sprintf(lookupMethod, "index.r * (1.0 / 256.0)"); + { + // TODO: I think we can handle most scenarios here, but texturing from depth buffers requires an extension on ES 2.0 anyway. + if ((mask & (mask + 1)) == 0 && shift < 16) { + index_multiplier = 1.0f / (float)(1 << shift); + truncate_cpy(lookupMethod, "index.r"); + } else { + formatOK = false; + } break; + } default: break; } diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 06d6b08328..3a8e443ba5 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1170,9 +1170,9 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, if (dstBuffer && srcBuffer && !isMemset) { if (srcBuffer == dstBuffer) { - WARN_LOG_REPORT_ONCE(dstsrccpy, G3D, "Intra-buffer memcpy (not supported) %08x -> %08x (size: %x)", src, dst, size); + WARN_LOG_ONCE(dstsrccpy, G3D, "Intra-buffer memcpy (not supported) %08x -> %08x (size: %x)", src, dst, size); } else { - WARN_LOG_REPORT_ONCE(dstnotsrccpy, G3D, "Inter-buffer memcpy %08x -> %08x (size: %x)", src, dst, size); + WARN_LOG_ONCE(dstnotsrccpy, G3D, "Inter-buffer memcpy %08x -> %08x (size: %x)", src, dst, size); // Just do the blit! BlitFramebuffer(dstBuffer, 0, dstY, srcBuffer, 0, srcY, srcBuffer->width, srcH, 0); SetColorUpdated(dstBuffer, skipDrawReason); @@ -1195,7 +1195,7 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, WARN_LOG_ONCE(btdcpy, G3D, "Memcpy fbo download %08x -> %08x", src, dst); FlushBeforeCopy(); if (srcH == 0 || srcY + srcH > srcBuffer->bufferHeight) { - WARN_LOG_REPORT_ONCE(btdcpyheight, G3D, "Memcpy fbo download %08x -> %08x skipped, %d+%d is taller than %d", src, dst, srcY, srcH, srcBuffer->bufferHeight); + WARN_LOG_ONCE(btdcpyheight, G3D, "Memcpy fbo download %08x -> %08x skipped, %d+%d is taller than %d", src, dst, srcY, srcH, srcBuffer->bufferHeight); } else if (g_Config.bBlockTransferGPU && !srcBuffer->memoryUpdated && !PSP_CoreParameter().compat.flags().DisableReadbacks) { ReadFramebufferToMemory(srcBuffer, 0, srcY, srcBuffer->width, srcH); srcBuffer->usageFlags = (srcBuffer->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 2789d1ff29..14f49ffa90 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -764,7 +764,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi const u32 mirrorMask = 0x00600000; u32 addr = address & 0x3FFFFFFF; - u32 texaddr = (entry->addr + texaddrOffset) & ~mirrorMask; + u32 texaddr = entry->addr + texaddrOffset; if (entry->addr & 0x04000000) { addr &= ~mirrorMask; texaddr &= ~mirrorMask; @@ -800,8 +800,9 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // Check works for D16 too (???) const bool matchingClutFormat = - (framebuffer->format == GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT32) || - (framebuffer->format != GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT16); + (channel != NOTIFY_FB_COLOR && entry->format == GE_TFMT_CLUT16) || + (channel == NOTIFY_FB_COLOR && framebuffer->format == GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT32) || + (channel == NOTIFY_FB_COLOR && framebuffer->format != GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT16); const bool clutFormat = IsClutFormat((GETextureFormat)(entry->format)); diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 0ede7acccc..0130f901db 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -1047,22 +1047,44 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c return; } - // Write-after-write hazards. Fixed flicker in God of War on ARM (before we added another fix). - // TODO: depth too - if (step.render.framebuffer && step.render.framebuffer->color.layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - VkImageMemoryBarrier barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - barrier.subresourceRange.layerCount = 1; - barrier.subresourceRange.levelCount = 1; - barrier.image = step.render.framebuffer->color.image; - barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier); + // Write-after-write hazards. Fixed flicker in God of War on ARM (before we added another fix that removed these). + if (step.render.framebuffer) { + int n = 0; + int stage = 0; + VkImageMemoryBarrier barriers[2]{}; + if (step.render.framebuffer->color.layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { + barriers[n].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barriers[n].oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barriers[n].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barriers[n].subresourceRange.layerCount = 1; + barriers[n].subresourceRange.levelCount = 1; + barriers[n].image = step.render.framebuffer->color.image; + barriers[n].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + barriers[n].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + barriers[n].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barriers[n].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barriers[n].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + stage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + n++; + } + if (step.render.framebuffer->depth.layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) { + barriers[n].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barriers[n].oldLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + barriers[n].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barriers[n].subresourceRange.layerCount = 1; + barriers[n].subresourceRange.levelCount = 1; + barriers[n].image = step.render.framebuffer->depth.image; + barriers[n].srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + barriers[n].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + barriers[n].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barriers[n].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barriers[n].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + stage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + n++; + } + if (stage) { + vkCmdPipelineBarrier(cmd, stage, stage, 0, 0, nullptr, 0, nullptr, n, barriers); + } } // This is supposed to bind a vulkan render pass to the command buffer. From 4b4e3432cde2493d6d9bdd8cd3da559ae57e6a16 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 9 Aug 2020 21:20:42 -0700 Subject: [PATCH 461/848] SaveState: Split Do() into a separate header. --- CMakeLists.txt | 2 + Common/ChunkFile.cpp | 63 +-- Common/ChunkFile.h | 464 +-------------------- Common/ChunkFileDo.h | 415 ++++++++++++++++++ Common/Common.vcxproj | 3 +- Common/Common.vcxproj.filters | 3 +- Common/FixedSizeQueue.h | 10 +- Common/ThreadSafeList.h | 2 +- Core/Core.vcxproj | 1 + Core/Core.vcxproj.filters | 7 +- Core/CoreTiming.cpp | 33 +- Core/CwCheat.cpp | 3 +- Core/Dialog/PSPDialog.cpp | 27 +- Core/Dialog/PSPGamedataInstallDialog.cpp | 23 +- Core/Dialog/PSPMsgDialog.cpp | 15 +- Core/Dialog/PSPNetconfDialog.cpp | 9 +- Core/Dialog/PSPOskDialog.cpp | 15 +- Core/Dialog/PSPSaveDialog.cpp | 16 +- Core/Dialog/PSPScreenshotDialog.cpp | 5 +- Core/Dialog/SavedataParam.cpp | 33 +- Core/FileSystems/DirectoryFileSystem.cpp | 25 +- Core/FileSystems/FileSystem.cpp | 25 +- Core/FileSystems/ISOFileSystem.cpp | 37 +- Core/FileSystems/MetaFileSystem.cpp | 7 +- Core/FileSystems/VirtualDiscFileSystem.cpp | 39 +- Core/Font/PGF.cpp | 39 +- Core/HLE/HLE.cpp | 12 +- Core/HLE/HLEHelperThread.cpp | 5 +- Core/HLE/ThreadQueueList.h | 8 +- Core/HLE/__sceAudio.cpp | 11 +- Core/HLE/proAdhoc.cpp | 34 ++ Core/HLE/proAdhoc.h | 36 +- Core/HLE/sceAtrac.cpp | 71 ++-- Core/HLE/sceAudio.cpp | 19 +- Core/HLE/sceAudiocodec.cpp | 13 +- Core/HLE/sceCcc.cpp | 11 +- Core/HLE/sceCtrl.cpp | 29 +- Core/HLE/sceDisplay.cpp | 57 +-- Core/HLE/sceDmac.cpp | 3 +- Core/HLE/sceFont.cpp | 77 ++-- Core/HLE/sceGe.cpp | 19 +- Core/HLE/sceHeap.cpp | 11 +- Core/HLE/sceImpose.cpp | 11 +- Core/HLE/sceIo.cpp | 65 +-- Core/HLE/sceJpeg.cpp | 8 +- Core/HLE/sceKernel.cpp | 17 +- Core/HLE/sceKernelAlarm.cpp | 9 +- Core/HLE/sceKernelEventFlag.cpp | 11 +- Core/HLE/sceKernelHeap.cpp | 15 +- Core/HLE/sceKernelInterrupt.cpp | 23 +- Core/HLE/sceKernelMbx.cpp | 9 +- Core/HLE/sceKernelMemory.cpp | 55 +-- Core/HLE/sceKernelModule.cpp | 37 +- Core/HLE/sceKernelMsgPipe.cpp | 17 +- Core/HLE/sceKernelMutex.cpp | 19 +- Core/HLE/sceKernelSemaphore.cpp | 11 +- Core/HLE/sceKernelThread.cpp | 135 +++--- Core/HLE/sceKernelTime.cpp | 5 +- Core/HLE/sceKernelVTimer.cpp | 13 +- Core/HLE/sceMp3.cpp | 43 +- Core/HLE/sceMp4.cpp | 3 +- Core/HLE/sceMpeg.cpp | 81 ++-- Core/HLE/sceNet.cpp | 53 ++- Core/HLE/sceNet.h | 23 +- Core/HLE/sceNetAdhoc.cpp | 21 +- Core/HLE/scePower.cpp | 11 +- Core/HLE/scePsmf.cpp | 133 +++--- Core/HLE/sceRtc.cpp | 3 +- Core/HLE/sceSas.cpp | 5 +- Core/HLE/sceSsl.cpp | 12 +- Core/HLE/sceUmd.cpp | 23 +- Core/HLE/sceUsb.cpp | 9 +- Core/HLE/sceUsbCam.cpp | 3 +- Core/HLE/sceUsbGps.cpp | 3 +- Core/HLE/sceUsbMic.cpp | 13 +- Core/HLE/sceUtility.cpp | 9 +- Core/HLE/sceVaudio.cpp | 3 +- Core/HW/AsyncIOManager.cpp | 7 +- Core/HW/AsyncIOManager.h | 6 +- Core/HW/BufferQueue.cpp | 34 ++ Core/HW/BufferQueue.h | 15 +- Core/HW/MediaEngine.cpp | 31 +- Core/HW/MemoryStick.cpp | 11 +- Core/HW/MpegDemux.cpp | 15 +- Core/HW/SasAudio.cpp | 123 +++--- Core/HW/SimpleAudioDec.cpp | 37 +- Core/MIPS/ARM/ArmJit.cpp | 7 +- Core/MIPS/ARM64/Arm64Jit.cpp | 7 +- Core/MIPS/IR/IRFrontend.cpp | 5 +- Core/MIPS/JitCommon/JitCommon.cpp | 5 +- Core/MIPS/MIPS.cpp | 37 +- Core/MIPS/MIPS/MipsJit.cpp | 4 +- Core/MIPS/x86/Jit.cpp | 5 +- Core/MemMap.cpp | 13 +- Core/Reporting.cpp | 3 +- Core/SaveState.cpp | 5 +- Core/Util/BlockAllocator.cpp | 19 +- Core/Util/PPGeDraw.cpp | 55 +-- GPU/Common/PostShader.h | 2 +- GPU/GPUCommon.cpp | 25 +- GPU/GPUState.cpp | 61 +-- UWP/CoreUWP/CoreUWP.vcxproj | 1 + UWP/CoreUWP/CoreUWP.vcxproj.filters | 3 + android/jni/Android.mk | 1 + libretro/Makefile.common | 1 + 105 files changed, 1630 insertions(+), 1556 deletions(-) create mode 100644 Common/ChunkFileDo.h create mode 100644 Core/HW/BufferQueue.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a2a6987e01..d616ca6ebf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1687,6 +1687,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/HW/SimpleAudioDec.h Core/HW/AsyncIOManager.cpp Core/HW/AsyncIOManager.h + Core/HW/BufferQueue.cpp + Core/HW/BufferQueue.h Core/HW/Camera.cpp Core/HW/Camera.h Core/HW/MediaEngine.cpp diff --git a/Common/ChunkFile.cpp b/Common/ChunkFile.cpp index 8954de5c45..229c96aaff 100644 --- a/Common/ChunkFile.cpp +++ b/Common/ChunkFile.cpp @@ -20,6 +20,7 @@ #include #include "ChunkFile.h" +#include "ChunkFileDo.h" #include "StringUtils.h" PointerWrapSection PointerWrap::Section(const char *title, int ver) { @@ -42,7 +43,7 @@ PointerWrapSection PointerWrap::Section(const char *title, int minVer, int ver) foundVersion = 0; } } else { - Do(foundVersion); + Do(*this, foundVersion); } if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { @@ -95,43 +96,43 @@ void PointerWrap::DoVoid(void *data, int size) { (*ptr) += size; } -void PointerWrap::Do(std::string &x) { +void Do(PointerWrap &p, std::string &x) { int stringLen = (int)x.length() + 1; - Do(stringLen); + Do(p, stringLen); - switch (mode) { - case MODE_READ: x = (char*)*ptr; break; - case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; - case MODE_MEASURE: break; - case MODE_VERIFY: _dbg_assert_msg_(!strcmp(x.c_str(), (char*)*ptr), "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (char*)*ptr, ptr); break; + switch (p.mode) { + case PointerWrap::MODE_READ: x = (char*)*p.ptr; break; + case PointerWrap::MODE_WRITE: memcpy(*p.ptr, x.c_str(), stringLen); break; + case PointerWrap::MODE_MEASURE: break; + case PointerWrap::MODE_VERIFY: _dbg_assert_msg_(!strcmp(x.c_str(), (char*)*p.ptr), "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (char *)*p.ptr, p.ptr); break; } - (*ptr) += stringLen; + (*p.ptr) += stringLen; } -void PointerWrap::Do(std::wstring &x) { +void Do(PointerWrap &p, std::wstring &x) { int stringLen = sizeof(wchar_t)*((int)x.length() + 1); - Do(stringLen); + Do(p, stringLen); - switch (mode) { - case MODE_READ: x = (wchar_t*)*ptr; break; - case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; - case MODE_MEASURE: break; - case MODE_VERIFY: _dbg_assert_msg_(x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; + switch (p.mode) { + case PointerWrap::MODE_READ: x = (wchar_t*)*p.ptr; break; + case PointerWrap::MODE_WRITE: memcpy(*p.ptr, x.c_str(), stringLen); break; + case PointerWrap::MODE_MEASURE: break; + case PointerWrap::MODE_VERIFY: _dbg_assert_msg_(x == (wchar_t*)*p.ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*p.ptr, p.ptr); break; } - (*ptr) += stringLen; + (*p.ptr) += stringLen; } -void PointerWrap::Do(std::u16string &x) { +void Do(PointerWrap &p, std::u16string &x) { int stringLen = sizeof(char16_t) * ((int)x.length() + 1); - Do(stringLen); + Do(p, stringLen); - switch (mode) { - case MODE_READ: x = (char16_t*)*ptr; break; - case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; - case MODE_MEASURE: break; - case MODE_VERIFY: _dbg_assert_msg_(x == (char16_t*)*ptr, "Savestate verification failure: (at %p).\n", x.c_str()); break; + switch (p.mode) { + case PointerWrap::MODE_READ: x = (char16_t*)*p.ptr; break; + case PointerWrap::MODE_WRITE: memcpy(*p.ptr, x.c_str(), stringLen); break; + case PointerWrap::MODE_MEASURE: break; + case PointerWrap::MODE_VERIFY: _dbg_assert_msg_(x == (char16_t*)*p.ptr, "Savestate verification failure: (at %p).\n", x.c_str()); break; } - (*ptr) += stringLen; + (*p.ptr) += stringLen; } struct standard_tm { @@ -146,31 +147,31 @@ struct standard_tm { int tm_isdst; }; -void PointerWrap::Do(tm &t) { +void Do(PointerWrap &p, tm &t) { // We savestate this separately because some platforms use extra data at the end. // However, old files may have the native tm in them. // Since the first value in the struct is 0-59, we save a funny value and check for it. // If our funny value ('tm' 0x1337) exists, it's a new version savestate. int funnyValue = 0x13376D74; - if (ExpectVoid(&funnyValue, sizeof(funnyValue))) { + if (p.ExpectVoid(&funnyValue, sizeof(funnyValue))) { standard_tm stm; - if (mode == MODE_READ) { + if (p.mode == PointerWrap::MODE_READ) { // Null out the extra members, e.g. tm_gmtoff or tm_zone. memset(&t, 0, sizeof(t)); } else { memcpy(&stm, &t, sizeof(stm)); } - DoVoid((void *)&stm, sizeof(stm)); + p.DoVoid((void *)&stm, sizeof(stm)); memcpy(&t, &stm, sizeof(stm)); } else { - DoVoid((void *)&t, sizeof(t)); + p.DoVoid((void *)&t, sizeof(t)); } } void PointerWrap::DoMarker(const char *prevName, u32 arbitraryNumber) { u32 cookie = arbitraryNumber; - Do(cookie); + Do(*this, cookie); if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) { _assert_msg_(false, "Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); SetError(ERROR_FAILURE); diff --git a/Common/ChunkFile.h b/Common/ChunkFile.h index e8a41901c5..67ef6f0e21 100644 --- a/Common/ChunkFile.h +++ b/Common/ChunkFile.h @@ -76,44 +76,6 @@ private: // Wrapper class class PointerWrap { -private: - // This makes it a compile error if you forget to define DoState() on non-POD. - // Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... -#ifdef _MSC_VER - template::value, bool isPointer = std::is_pointer::value> -#else - template::value> -#endif - struct DoHelper - { - static void DoArray(PointerWrap *p, T *x, int count) - { - for (int i = 0; i < count; ++i) - p->Do(x[i]); - } - - static void Do(PointerWrap *p, T &x) - { - p->DoClass(x); - } - }; - - template - struct DoHelper - { - static void DoArray(PointerWrap *p, T *x, int count) - { - p->DoVoid((void *)x, sizeof(T) * count); - } - - static void Do(PointerWrap *p, T &x) - { - p->DoVoid((void *)&x, sizeof(x)); - } - }; - - const char *firstBadSectionTitle_ = nullptr; - public: enum Mode { MODE_READ = 1, // load @@ -132,7 +94,6 @@ public: Mode mode; Error error = ERROR_NONE; -public: PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_) {} PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_) {} @@ -155,430 +116,11 @@ public: // Same as DoVoid, except doesn't advance pointer if it doesn't match on read. bool ExpectVoid(void *data, int size); void DoVoid(void *data, int size); - - template - void Do(std::map &x) - { - if (mode == MODE_READ) - { - for (auto it = x.begin(), end = x.end(); it != end; ++it) - { - if (it->second != NULL) - delete it->second; - } - } - T *dv = NULL; - DoMap(x, dv); - } - - template - void Do(std::map &x) - { - T dv = T(); - DoMap(x, dv); - } - - template - void Do(std::unordered_map &x) - { - if (mode == MODE_READ) - { - for (auto it = x.begin(), end = x.end(); it != end; ++it) - { - if (it->second != NULL) - delete it->second; - } - } - T *dv = NULL; - DoMap(x, dv); - } - - template - void Do(std::unordered_map &x) - { - T dv = T(); - DoMap(x, dv); - } - - template - void DoMap(M &x, typename M::mapped_type &default_val) - { - unsigned int number = (unsigned int)x.size(); - Do(number); - switch (mode) { - case MODE_READ: - { - x.clear(); - while (number > 0) - { - typename M::key_type first = typename M::key_type(); - Do(first); - typename M::mapped_type second = default_val; - Do(second); - x[first] = second; - --number; - } - } - break; - case MODE_WRITE: - case MODE_MEASURE: - case MODE_VERIFY: - { - typename M::iterator itr = x.begin(); - while (number > 0) - { - typename M::key_type first = itr->first; - Do(first); - Do(itr->second); - --number; - ++itr; - } - } - break; - } - } - - template - void Do(std::multimap &x) - { - if (mode == MODE_READ) - { - for (auto it = x.begin(), end = x.end(); it != end; ++it) - { - if (it->second != NULL) - delete it->second; - } - } - T *dv = NULL; - DoMultimap(x, dv); - } - - template - void Do(std::multimap &x) - { - T dv = T(); - DoMultimap(x, dv); - } - - template - void Do(std::unordered_multimap &x) - { - if (mode == MODE_READ) - { - for (auto it = x.begin(), end = x.end(); it != end; ++it) - { - if (it->second != NULL) - delete it->second; - } - } - T *dv = NULL; - DoMultimap(x, dv); - } - - template - void Do(std::unordered_multimap &x) - { - T dv = T(); - DoMultimap(x, dv); - } - - template - void DoMultimap(M &x, typename M::mapped_type &default_val) - { - unsigned int number = (unsigned int)x.size(); - Do(number); - switch (mode) { - case MODE_READ: - { - x.clear(); - while (number > 0) - { - typename M::key_type first = typename M::key_type(); - Do(first); - typename M::mapped_type second = default_val; - Do(second); - x.insert(std::make_pair(first, second)); - --number; - } - } - break; - case MODE_WRITE: - case MODE_MEASURE: - case MODE_VERIFY: - { - typename M::iterator itr = x.begin(); - while (number > 0) - { - Do(itr->first); - Do(itr->second); - --number; - ++itr; - } - } - break; - } - } - - // Store vectors. - template - void Do(std::vector &x) - { - T *dv = NULL; - DoVector(x, dv); - } - - template - void Do(std::vector &x) - { - T dv = T(); - DoVector(x, dv); - } - - template - void Do(std::vector &x, T &default_val) - { - DoVector(x, default_val); - } - - template - void DoVector(std::vector &x, T &default_val) - { - u32 vec_size = (u32)x.size(); - Do(vec_size); - x.resize(vec_size, default_val); - if (vec_size > 0) - DoArray(&x[0], vec_size); - } - - // Store deques. - template - void Do(std::deque &x) - { - T *dv = NULL; - DoDeque(x, dv); - } - - template - void Do(std::deque &x) - { - T dv = T(); - DoDeque(x, dv); - } - - template - void DoDeque(std::deque &x, T &default_val) - { - u32 deq_size = (u32)x.size(); - Do(deq_size); - x.resize(deq_size, default_val); - u32 i; - for(i = 0; i < deq_size; i++) - Do(x[i]); - } - - // Store STL lists. - template - void Do(std::list &x) - { - T *dv = NULL; - Do(x, dv); - } - - template - void Do(std::list &x) - { - T dv = T(); - DoList(x, dv); - } - - template - void Do(std::list &x, T &default_val) - { - DoList(x, default_val); - } - - template - void DoList(std::list &x, T &default_val) - { - u32 list_size = (u32)x.size(); - Do(list_size); - x.resize(list_size, default_val); - - typename std::list::iterator itr, end; - for (itr = x.begin(), end = x.end(); itr != end; ++itr) - Do(*itr); - } - - // Store STL sets. - template - void Do(std::set &x) - { - if (mode == MODE_READ) - { - for (auto it = x.begin(), end = x.end(); it != end; ++it) - { - if (*it != NULL) - delete *it; - } - } - DoSet(x); - } - - template - void Do(std::set &x) - { - DoSet(x); - } - - template - void DoSet(std::set &x) - { - unsigned int number = (unsigned int)x.size(); - Do(number); - - switch (mode) - { - case MODE_READ: - { - x.clear(); - while (number-- > 0) - { - T it = T(); - Do(it); - x.insert(it); - } - } - break; - case MODE_WRITE: - case MODE_MEASURE: - case MODE_VERIFY: - { - typename std::set::iterator itr = x.begin(); - while (number-- > 0) - Do(*itr++); - } - break; - - default: - ERROR_LOG(SAVESTATE, "Savestate error: invalid mode %d.", mode); - } - } - - // Store strings. - void Do(std::string &x); - void Do(std::wstring &x); // DEPRECATED, do not save wstrings - void Do(std::u16string &x); - - void Do(tm &t); - - template - void Do(swap_struct_t &x) { - T v = x.swap(); - Do(v); - x = v; - } - - template - void DoClass(T &x) { - x.DoState(*this); - } - - template - void DoClass(T *&x) { - if (mode == MODE_READ) - { - if (x != NULL) - delete x; - x = new T(); - } - x->DoState(*this); - } - - template - void DoArray(T *x, int count) { - DoHelper::DoArray(this, x, count); - } - - template - void Do(T &x) { - DoHelper::Do(this, x); - } - - template - void DoPointer(T* &x, T*const base) { - // pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range - s32 offset = x - base; - Do(offset); - if (mode == MODE_READ) - x = base + offset; - } - - template* (*TNew)(), void (*TFree)(LinkedListItem*), void (*TDo)(PointerWrap&, T*)> - void DoLinkedList(LinkedListItem*& list_start, LinkedListItem** list_end=0) - { - LinkedListItem* list_cur = list_start; - LinkedListItem* prev = 0; - - while (true) - { - u8 shouldExist = (list_cur ? 1 : 0); - Do(shouldExist); - if (shouldExist == 1) - { - LinkedListItem* cur = list_cur ? list_cur : TNew(); - TDo(*this, (T*)cur); - if (!list_cur) - { - if (mode == MODE_READ) - { - cur->next = 0; - list_cur = cur; - if (prev) - prev->next = cur; - else - list_start = cur; - } - else - { - TFree(cur); - continue; - } - } - } - else - { - if (shouldExist != 0) - { - WARN_LOG(SAVESTATE, "Savestate failure: incorrect item marker %d", shouldExist); - SetError(ERROR_FAILURE); - } - if (mode == MODE_READ) - { - if (prev) - prev->next = 0; - if (list_end) - *list_end = prev; - if (list_cur) - { - if (list_start == list_cur) - list_start = 0; - do - { - LinkedListItem* next = list_cur->next; - TFree(list_cur); - list_cur = next; - } - while (list_cur); - } - } - break; - } - prev = list_cur; - list_cur = list_cur->next; - } - } void DoMarker(const char *prevName, u32 arbitraryNumber = 0x42); + +private: + const char *firstBadSectionTitle_ = nullptr; }; class CChunkFileReader diff --git a/Common/ChunkFileDo.h b/Common/ChunkFileDo.h new file mode 100644 index 0000000000..3849248295 --- /dev/null +++ b/Common/ChunkFileDo.h @@ -0,0 +1,415 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +// Templates for save state serialization. See ChunkFile.h. +#include "Common/ChunkFile.h" + +void Do(PointerWrap &p, std::string &x); +void Do(PointerWrap &p, std::wstring &x); // DEPRECATED, do not save wstrings +void Do(PointerWrap &p, std::u16string &x); + +void Do(PointerWrap &p, tm &t); + +// Don't use DoHelper_ directly. Just use Do(). + +// This makes it a compile error if you forget to define DoState() on non-POD. +// Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... +#ifdef _MSC_VER +template::value, bool isPointer = std::is_pointer::value> +#else +template::value> +#endif +struct DoHelper_ { + static void DoArray(PointerWrap &p, T *x, int count) { + for (int i = 0; i < count; ++i) + Do(p, x[i]); + } + + static void DoThing(PointerWrap &p, T &x) { + DoClass(p, x); + } +}; + +template +struct DoHelper_ { + static void DoArray(PointerWrap &p, T *x, int count) { + p.DoVoid((void *)x, sizeof(T) * count); + } + + static void DoThing(PointerWrap &p, T &x) { + p.DoVoid((void *)&x, sizeof(x)); + } +}; + +template +void DoClass(PointerWrap &p, T &x) { + x.DoState(p); +} + +template +void DoClass(PointerWrap &p, T *&x) { + if (p.mode == PointerWrap::MODE_READ) { + if (x != nullptr) + delete x; + x = new T(); + } + x->DoState(p); +} + +template +void DoArray(PointerWrap &p, T *x, int count) { + DoHelper_::DoArray(p, x, count); +} + +template +void Do(PointerWrap &p, T &x) { + DoHelper_::DoThing(p, x); +} + +template +void DoMap(PointerWrap &p, M &x, typename M::mapped_type &default_val) { + unsigned int number = (unsigned int)x.size(); + Do(p, number); + switch (p.mode) { + case PointerWrap::MODE_READ: + { + x.clear(); + while (number > 0) { + typename M::key_type first = typename M::key_type(); + Do(p, first); + typename M::mapped_type second = default_val; + Do(p, second); + x[first] = second; + --number; + } + } + break; + case PointerWrap::MODE_WRITE: + case PointerWrap::MODE_MEASURE: + case PointerWrap::MODE_VERIFY: + { + typename M::iterator itr = x.begin(); + while (number > 0) { + typename M::key_type first = itr->first; + Do(p, first); + Do(p, itr->second); + --number; + ++itr; + } + } + break; + } +} + +template +void Do(PointerWrap &p, std::map &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (it->second != nullptr) + delete it->second; + } + } + T *dv = nullptr; + DoMap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::map &x) { + T dv = T(); + DoMap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::unordered_map &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (it->second != nullptr) + delete it->second; + } + } + T *dv = nullptr; + DoMap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::unordered_map &x) { + T dv = T(); + DoMap(p, x, dv); +} + +template +void DoMultimap(PointerWrap &p, M &x, typename M::mapped_type &default_val) { + unsigned int number = (unsigned int)x.size(); + Do(p, number); + switch (p.mode) { + case PointerWrap::MODE_READ: + { + x.clear(); + while (number > 0) { + typename M::key_type first = typename M::key_type(); + Do(p, first); + typename M::mapped_type second = default_val; + Do(p, second); + x.insert(std::make_pair(first, second)); + --number; + } + } + break; + case PointerWrap::MODE_WRITE: + case PointerWrap::MODE_MEASURE: + case PointerWrap::MODE_VERIFY: + { + typename M::iterator itr = x.begin(); + while (number > 0) { + Do(p, itr->first); + Do(p, itr->second); + --number; + ++itr; + } + } + break; + } +} + +template +void Do(PointerWrap &p, std::multimap &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (it->second != nullptr) + delete it->second; + } + } + T *dv = nullptr; + DoMultimap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::multimap &x) { + T dv = T(); + DoMultimap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::unordered_multimap &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (it->second != nullptr) + delete it->second; + } + } + T *dv = nullptr; + DoMultimap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::unordered_multimap &x) { + T dv = T(); + DoMultimap(p, x, dv); +} + +template +void DoVector(PointerWrap &p, std::vector &x, T &default_val) { + u32 vec_size = (u32)x.size(); + Do(p, vec_size); + x.resize(vec_size, default_val); + if (vec_size > 0) + DoArray(p, &x[0], vec_size); +} + +template +void Do(PointerWrap &p, std::vector &x) { + T *dv = nullptr; + DoVector(p, x, dv); +} + +template +void Do(PointerWrap &p, std::vector &x) { + T dv = T(); + DoVector(p, x, dv); +} + +template +void Do(PointerWrap &p, std::vector &x, T &default_val) { + DoVector(p, x, default_val); +} + +template +void DoDeque(PointerWrap &p, std::deque &x, T &default_val) { + u32 deq_size = (u32)x.size(); + Do(p, deq_size); + x.resize(deq_size, default_val); + u32 i; + for (i = 0; i < deq_size; i++) + Do(p, x[i]); +} + +template +void Do(PointerWrap &p, std::deque &x) { + T *dv = nullptr; + DoDeque(p, x, dv); +} + +template +void Do(PointerWrap &p, std::deque &x) { + T dv = T(); + DoDeque(p, x, dv); +} + +template +void DoList(PointerWrap &p, std::list &x, T &default_val) { + u32 list_size = (u32)x.size(); + Do(p, list_size); + x.resize(list_size, default_val); + + typename std::list::iterator itr, end; + for (itr = x.begin(), end = x.end(); itr != end; ++itr) + Do(p, *itr); +} + +template +void Do(PointerWrap &p, std::list &x) { + T *dv = nullptr; + Do(p, x, dv); +} + +template +void Do(PointerWrap &p, std::list &x) { + T dv = T(); + DoList(p, x, dv); +} + +template +void Do(PointerWrap &p, std::list &x, T &default_val) { + DoList(p, x, default_val); +} + +template +void DoSet(PointerWrap &p, std::set &x) { + unsigned int number = (unsigned int)x.size(); + Do(p, number); + + switch (p.mode) { + case PointerWrap::MODE_READ: + { + x.clear(); + while (number-- > 0) { + T it = T(); + Do(p, it); + x.insert(it); + } + } + break; + case PointerWrap::MODE_WRITE: + case PointerWrap::MODE_MEASURE: + case PointerWrap::MODE_VERIFY: + { + typename std::set::iterator itr = x.begin(); + while (number-- > 0) + Do(p, *itr++); + } + break; + + default: + ERROR_LOG(SAVESTATE, "Savestate error: invalid mode %d.", p.mode); + } +} + +// Store STL sets. +template +void Do(PointerWrap &p, std::set &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (*it != nullptr) + delete *it; + } + } + DoSet(p, x); +} + +template +void Do(PointerWrap &p, std::set &x) { + DoSet(p, x); +} + +template +void Do(PointerWrap &p, swap_struct_t &x) { + T v = x.swap(); + Do(p, v); + x = v; +} + +template +void DoPointer(PointerWrap &p, T *&x, T *const base) { + // pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range + s32 offset = x - base; + Do(p, offset); + if (p.mode == PointerWrap::MODE_READ) + x = base + offset; +} + +template *(*TNew)(), void (*TFree)(LinkedListItem *), void (*TDo)(PointerWrap &, T *)> +void DoLinkedList(PointerWrap &p, LinkedListItem *&list_start, LinkedListItem **list_end = nullptr) { + LinkedListItem *list_cur = list_start; + LinkedListItem *prev = nullptr; + + while (true) { + u8 shouldExist = (list_cur ? 1 : 0); + Do(p, shouldExist); + if (shouldExist == 1) { + LinkedListItem *cur = list_cur ? list_cur : TNew(); + TDo(p, (T *)cur); + if (!list_cur) { + if (p.mode == PointerWrap::MODE_READ) { + cur->next = 0; + list_cur = cur; + if (prev) + prev->next = cur; + else + list_start = cur; + } else { + TFree(cur); + continue; + } + } + } else { + if (shouldExist != 0) { + WARN_LOG(SAVESTATE, "Savestate failure: incorrect item marker %d", shouldExist); + p.SetError(p.ERROR_FAILURE); + } + if (p.mode == PointerWrap::MODE_READ) { + if (prev) + prev->next = nullptr; + if (list_end) + *list_end = prev; + if (list_cur) { + if (list_start == list_cur) + list_start = nullptr; + do { + LinkedListItem *next = list_cur->next; + TFree(list_cur); + list_cur = next; + } while (list_cur); + } + } + break; + } + prev = list_cur; + list_cur = list_cur->next; + } +} diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 6486c530e7..c54bc30238 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -354,6 +354,7 @@ + @@ -524,4 +525,4 @@ - + \ No newline at end of file diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index c49d67d6af..a19ee2e281 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -76,6 +76,7 @@ + @@ -155,4 +156,4 @@ {c14d66ef-5f7c-4565-975a-72774e7ccfb9} - + \ No newline at end of file diff --git a/Common/FixedSizeQueue.h b/Common/FixedSizeQueue.h index d59555f7d8..03ebf5c41f 100644 --- a/Common/FixedSizeQueue.h +++ b/Common/FixedSizeQueue.h @@ -147,16 +147,16 @@ public: void DoState(PointerWrap &p) { int size = N; - p.Do(size); + Do(p, size); if (size != N) { ERROR_LOG(COMMON, "Savestate failure: Incompatible queue size."); return; } - p.DoArray(storage_, N); - p.Do(head_); - p.Do(tail_); - p.Do(count_); + DoArray(p, storage_, N); + Do(p, head_); + Do(p, tail_); + Do(p, count_); p.DoMarker("FixedSizeQueue"); } diff --git a/Common/ThreadSafeList.h b/Common/ThreadSafeList.h index 37389286ba..9697438bb9 100644 --- a/Common/ThreadSafeList.h +++ b/Common/ThreadSafeList.h @@ -75,7 +75,7 @@ public: void DoState(PointerWrap &p) { std::lock_guard guard(lock); - p.Do(list); + Do(p, list); } private: diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index baf1d89505..d690042fb9 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -388,6 +388,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index a5460b6d4f..1a63c8b4a2 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -748,13 +748,16 @@ Core - + Util Core + + HW + @@ -1396,7 +1399,7 @@ Core - + Util diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index a269455161..8c49a4c15c 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -23,6 +23,8 @@ #include "base/logging.h" #include "profiler/profiler.h" +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/MsgHandler.h" #include "Core/CoreTiming.h" #include "Core/Core.h" @@ -31,7 +33,6 @@ #include "Core/HLE/sceDisplay.h" #include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" -#include "Common/ChunkFile.h" static const int initialHz = 222000000; int CPU_HZ = 222000000; @@ -671,14 +672,14 @@ std::string GetScheduledEventsSummary() { void Event_DoState(PointerWrap &p, BaseEvent *ev) { // There may be padding, so do each one individually. - p.Do(ev->time); - p.Do(ev->userdata); - p.Do(ev->type); + Do(p, ev->time); + Do(p, ev->userdata); + Do(p, ev->type); } void Event_DoStateOld(PointerWrap &p, BaseEvent *ev) { - p.Do(*ev); + Do(p, *ev); } void DoState(PointerWrap &p) @@ -690,26 +691,26 @@ void DoState(PointerWrap &p) return; int n = (int) event_types.size(); - p.Do(n); + Do(p, n); // These (should) be filled in later by the modules. event_types.resize(n, EventType(AntiCrashCallback, "INVALID EVENT")); if (s >= 3) { - p.DoLinkedList(first, (Event **) NULL); - p.DoLinkedList(tsFirst, &tsLast); + DoLinkedList(p, first, (Event **) NULL); + DoLinkedList(p, tsFirst, &tsLast); } else { - p.DoLinkedList(first, (Event **) NULL); - p.DoLinkedList(tsFirst, &tsLast); + DoLinkedList(p, first, (Event **) NULL); + DoLinkedList(p, tsFirst, &tsLast); } - p.Do(CPU_HZ); - p.Do(slicelength); - p.Do(globalTimer); - p.Do(idledCycles); + Do(p, CPU_HZ); + Do(p, slicelength); + Do(p, globalTimer); + Do(p, idledCycles); if (s >= 2) { - p.Do(lastGlobalTimeTicks); - p.Do(lastGlobalTimeUs); + Do(p, lastGlobalTimeTicks); + Do(p, lastGlobalTimeUs); } else { lastGlobalTimeTicks = 0; lastGlobalTimeUs = 0; diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 3b8e643097..1fb4a4623e 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -5,6 +5,7 @@ #include "i18n/i18n.h" #include "Common/StringUtils.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/FileUtil.h" #include "Core/CoreTiming.h" #include "Core/CoreParameter.h" @@ -304,7 +305,7 @@ void __CheatDoState(PointerWrap &p) { return; } - p.Do(CheatEvent); + Do(p, CheatEvent); CoreTiming::RestoreRegisterEvent(CheatEvent, "CheatEvent", &hleCheat); if (s < 2) { diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp index f77682848c..4d7eda334a 100644 --- a/Core/Dialog/PSPDialog.cpp +++ b/Core/Dialog/PSPDialog.cpp @@ -18,6 +18,7 @@ #include "i18n/i18n.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/StringUtils.h" #include "Core/CoreTiming.h" #include "Core/HLE/sceCtrl.h" @@ -137,26 +138,26 @@ void PSPDialog::DoState(PointerWrap &p) if (!s) return; - p.Do(status); - p.Do(lastButtons); - p.Do(buttons); - p.Do(fadeTimer); - p.Do(isFading); - p.Do(fadeIn); - p.Do(fadeValue); + Do(p, status); + Do(p, lastButtons); + Do(p, buttons); + Do(p, fadeTimer); + Do(p, isFading); + Do(p, fadeIn); + Do(p, fadeValue); // I don't think we should save these two... Let's just ignore them for now for compat. int okButtonImg = 0; - p.Do(okButtonImg); + Do(p, okButtonImg); int cancelButtonImg = 0; - p.Do(cancelButtonImg); + Do(p, cancelButtonImg); - p.Do(okButtonFlag); - p.Do(cancelButtonFlag); + Do(p, okButtonFlag); + Do(p, cancelButtonFlag); if (s >= 2) { - p.Do(pendingStatus); - p.Do(pendingStatusTicks); + Do(p, pendingStatus); + Do(p, pendingStatusTicks); } else { pendingStatusTicks = 0; } diff --git a/Core/Dialog/PSPGamedataInstallDialog.cpp b/Core/Dialog/PSPGamedataInstallDialog.cpp index 5210914309..e8b239982d 100644 --- a/Core/Dialog/PSPGamedataInstallDialog.cpp +++ b/Core/Dialog/PSPGamedataInstallDialog.cpp @@ -18,6 +18,7 @@ #include #include "Common/Common.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/ELF/ParamSFO.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" @@ -260,25 +261,25 @@ void PSPGamedataInstallDialog::DoState(PointerWrap &p) { // This was included in version 1 and higher. PSPDialog::DoState(p); - p.Do(request); + Do(p, request); // This was included in version 2 and higher, but for BC reasons we use 3+. if (s >= 3) { - p.Do(param.ptr); - p.Do(inFileNames); - p.Do(numFiles); - p.Do(readFiles); - p.Do(allFilesSize); - p.Do(allReadSize); - p.Do(progressValue); + Do(p, param.ptr); + Do(p, inFileNames); + Do(p, numFiles); + Do(p, readFiles); + Do(p, allFilesSize); + Do(p, allReadSize); + Do(p, progressValue); } else { param.ptr = 0; } if (s >= 4) { - p.Do(currentInputFile); - p.Do(currentInputBytesLeft); - p.Do(currentOutputFile); + Do(p, currentInputFile); + Do(p, currentInputBytesLeft); + Do(p, currentOutputFile); } else { currentInputFile = 0; currentInputBytesLeft = 0; diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index 7ddd1f8a73..b655dd6300 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -16,14 +16,15 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" +#include "Common/StringUtils.h" #include "Core/Dialog/PSPMsgDialog.h" #include "Core/Dialog/PSPSaveDialog.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" -#include "Common/ChunkFile.h" -#include "Common/StringUtils.h" #include "i18n/i18n.h" #include "util/text/utf8.h" @@ -378,11 +379,11 @@ void PSPMsgDialog::DoState(PointerWrap &p) if (!s) return; - p.Do(flag); - p.Do(messageDialog); - p.Do(messageDialogAddr); - p.DoArray(msgText, sizeof(msgText)); - p.Do(yesnoChoice); + Do(p, flag); + Do(p, messageDialog); + Do(p, messageDialogAddr); + DoArray(p, msgText, sizeof(msgText)); + Do(p, yesnoChoice); // We don't save state this, you'll just have to scroll down again. if (p.mode == p.MODE_READ) { diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 998f5745cf..4a77d37a8c 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -15,15 +15,16 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "PSPNetconfDialog.h" -#include "ChunkFile.h" +#include "i18n/i18n.h" +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Config.h" +#include "Core/Dialog/PSPNetconfDialog.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/sceNetAdhoc.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" #include "Core/HLE/sceUtility.h" -#include "i18n/i18n.h" #define NETCONF_CONNECT_APNET 0 #define NETCONF_STATUS_APNET 1 @@ -140,5 +141,5 @@ void PSPNetconfDialog::DoState(PointerWrap &p) { if (!s) return; - p.Do(request); + Do(p, request); } diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 3041cae300..4cec09e0c2 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -21,6 +21,7 @@ #include "math/math_util.h" #include "util/text/utf8.h" +#include "Common/ChunkFileDo.h" #include "Core/Dialog/PSPOskDialog.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" @@ -1135,17 +1136,17 @@ void PSPOskDialog::DoState(PointerWrap &p) if (!s) return; - p.Do(oskParams); - p.Do(oskDesc); - p.Do(oskIntext); - p.Do(oskOuttext); - p.Do(selectedChar); + Do(p, oskParams); + Do(p, oskDesc); + Do(p, oskIntext); + Do(p, oskOuttext); + Do(p, selectedChar); if (s >= 2) { - p.Do(inputChars); + Do(p, inputChars); } else { // Discard the wstring. std::wstring wstr; - p.Do(wstr); + Do(p, wstr); } // Don't need to save state native status or value. } diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 3c99d75203..190e6c41cd 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -25,7 +25,7 @@ #include "thread/threadutil.h" #include "Common/ChunkFile.h" - +#include "Common/ChunkFileDo.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" @@ -1140,20 +1140,20 @@ void PSPSaveDialog::DoState(PointerWrap &p) { return; } - p.Do(display); + Do(p, display); param.DoState(p); - p.Do(request); + Do(p, request); // Just reset it. bool hasParam = param.GetPspParam() != NULL; - p.Do(hasParam); + Do(p, hasParam); if (hasParam) { param.SetPspParam(&request); } - p.Do(requestAddr); - p.Do(currentSelectedSave); - p.Do(yesnoChoice); + Do(p, requestAddr); + Do(p, currentSelectedSave); + Do(p, yesnoChoice); if (s > 2) { - p.Do(ioThreadStatus); + Do(p, ioThreadStatus); } else { ioThreadStatus = SAVEIO_NONE; } diff --git a/Core/Dialog/PSPScreenshotDialog.cpp b/Core/Dialog/PSPScreenshotDialog.cpp index cb3abf9a71..2d5c847828 100644 --- a/Core/Dialog/PSPScreenshotDialog.cpp +++ b/Core/Dialog/PSPScreenshotDialog.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Dialog/PSPDialog.h" #include "Core/Dialog/PSPScreenshotDialog.h" #include "Core/HLE/sceKernel.h" @@ -123,8 +124,8 @@ void PSPScreenshotDialog::DoState(PointerWrap &p) { if (!s) return; - p.Do(mode); + Do(p, mode); if (s >= 2) { - p.Do(params_); + Do(p, params_); } } diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 484bb6e910..32374e98cf 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -18,6 +18,7 @@ #include "i18n/i18n.h" #include "base/logging.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Host.h" @@ -153,23 +154,23 @@ void SaveFileInfo::DoState(PointerWrap &p) if (!s) return; - p.Do(size); - p.Do(saveName); - p.Do(idx); + Do(p, size); + Do(p, saveName); + Do(p, idx); - p.DoArray(title, sizeof(title)); - p.DoArray(saveTitle, sizeof(saveTitle)); - p.DoArray(saveDetail, sizeof(saveDetail)); + DoArray(p, title, sizeof(title)); + DoArray(p, saveTitle, sizeof(saveTitle)); + DoArray(p, saveDetail, sizeof(saveDetail)); - p.Do(modif_time); + Do(p, modif_time); if (s <= 1) { u32 textureData; int textureWidth; int textureHeight; - p.Do(textureData); - p.Do(textureWidth); - p.Do(textureHeight); + Do(p, textureData); + Do(p, textureWidth); + Do(p, textureHeight); if (textureData != 0) { // Must be MODE_READ. @@ -178,7 +179,7 @@ void SaveFileInfo::DoState(PointerWrap &p) } } else { bool hasTexture = texture != NULL; - p.Do(hasTexture); + Do(p, hasTexture); if (hasTexture) { if (p.mode == p.MODE_READ) { delete texture; @@ -1725,9 +1726,9 @@ void SavedataParam::DoState(PointerWrap &p) return; // pspParam is handled in PSPSaveDialog. - p.Do(selectedSave); - p.Do(saveDataListCount); - p.Do(saveNameListDataCount); + Do(p, selectedSave); + Do(p, saveDataListCount); + Do(p, saveNameListDataCount); if (p.mode == p.MODE_READ) { if (saveDataList != NULL) @@ -1735,13 +1736,13 @@ void SavedataParam::DoState(PointerWrap &p) if (saveDataListCount != 0) { saveDataList = new SaveFileInfo[saveDataListCount]; - p.DoArray(saveDataList, saveDataListCount); + DoArray(p, saveDataList, saveDataListCount); } else saveDataList = NULL; } else - p.DoArray(saveDataList, saveDataListCount); + DoArray(p, saveDataList, saveDataListCount); } int SavedataParam::GetSaveCryptMode(SceUtilitySavedataParam* param, const std::string &saveDirName) diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 1e38103ff2..b32f8cc1af 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -24,6 +24,7 @@ #include "i18n/i18n.h" #include "util/text/utf8.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/FileUtil.h" #include "Core/FileSystems/DirectoryFileSystem.h" #include "Core/FileSystems/ISOFileSystem.h" @@ -976,41 +977,41 @@ void DirectoryFileSystem::DoState(PointerWrap &p) { // s64 current truncate position (v2+ only) u32 num = (u32) entries.size(); - p.Do(num); + Do(p, num); if (p.mode == p.MODE_READ) { CloseAll(); u32 key; OpenFileEntry entry; for (u32 i = 0; i < num; i++) { - p.Do(key); - p.Do(entry.guestFilename); - p.Do(entry.access); + Do(p, key); + Do(p, entry.guestFilename); + Do(p, entry.access); u32 err; if (!entry.hFile.Open(basePath,entry.guestFilename,entry.access, err)) { ERROR_LOG(FILESYS, "Failed to reopen file while loading state: %s", entry.guestFilename.c_str()); continue; } u32 position; - p.Do(position); + Do(p, position); if (position != entry.hFile.Seek(position, FILEMOVE_BEGIN)) { ERROR_LOG(FILESYS, "Failed to restore seek position while loading state: %s", entry.guestFilename.c_str()); continue; } if (s >= 2) { - p.Do(entry.hFile.needsTrunc_); + Do(p, entry.hFile.needsTrunc_); } entries[key] = entry; } } else { for (auto iter = entries.begin(); iter != entries.end(); ++iter) { u32 key = iter->first; - p.Do(key); - p.Do(iter->second.guestFilename); - p.Do(iter->second.access); + Do(p, key); + Do(p, iter->second.guestFilename); + Do(p, iter->second.access); u32 position = (u32)iter->second.hFile.Seek(0, FILEMOVE_CURRENT); - p.Do(position); - p.Do(iter->second.hFile.needsTrunc_); + Do(p, position); + Do(p, iter->second.hFile.needsTrunc_); } } } @@ -1186,7 +1187,7 @@ void VFSFileSystem::DoState(PointerWrap &p) { return; u32 num = (u32) entries.size(); - p.Do(num); + Do(p, num); if (num != 0) { p.SetError(p.ERROR_WARNING); diff --git a/Core/FileSystems/FileSystem.cpp b/Core/FileSystems/FileSystem.cpp index b2130e2eda..7fae8183e7 100644 --- a/Core/FileSystems/FileSystem.cpp +++ b/Core/FileSystems/FileSystem.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/FileSystems/FileSystem.h" void PSPFileInfo::DoState(PointerWrap &p) { @@ -23,17 +24,17 @@ void PSPFileInfo::DoState(PointerWrap &p) { if (!s) return; - p.Do(name); - p.Do(size); - p.Do(access); - p.Do(exists); - p.Do(type); - p.Do(atime); - p.Do(ctime); - p.Do(mtime); - p.Do(isOnSectorSystem); - p.Do(startSector); - p.Do(numSectors); - p.Do(sectorSize); + Do(p, name); + Do(p, size); + Do(p, access); + Do(p, exists); + Do(p, type); + Do(p, atime); + Do(p, ctime); + Do(p, mtime); + Do(p, isOnSectorSystem); + Do(p, startSector); + Do(p, numSectors); + Do(p, sectorSize); } diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index b0461ba014..7ead5c5e4d 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -23,6 +23,7 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/HLE/sceKernel.h" #include "Core/MemMap.h" @@ -710,7 +711,7 @@ void ISOFileSystem::DoState(PointerWrap &p) { return; int n = (int) entries.size(); - p.Do(n); + Do(p, n); if (p.mode == p.MODE_READ) { entries.clear(); @@ -718,18 +719,18 @@ void ISOFileSystem::DoState(PointerWrap &p) { u32 fd = 0; OpenFileEntry of; - p.Do(fd); - p.Do(of.seekPos); - p.Do(of.isRawSector); - p.Do(of.isBlockSectorMode); - p.Do(of.sectorStart); - p.Do(of.openSize); + Do(p, fd); + Do(p, of.seekPos); + Do(p, of.isRawSector); + Do(p, of.isBlockSectorMode); + Do(p, of.sectorStart); + Do(p, of.openSize); bool hasFile = false; - p.Do(hasFile); + Do(p, hasFile); if (hasFile) { std::string path; - p.Do(path); + Do(p, path); of.file = GetFromPath(path); } else { of.file = NULL; @@ -740,24 +741,24 @@ void ISOFileSystem::DoState(PointerWrap &p) { } else { for (EntryMap::iterator it = entries.begin(), end = entries.end(); it != end; ++it) { OpenFileEntry &of = it->second; - p.Do(it->first); - p.Do(of.seekPos); - p.Do(of.isRawSector); - p.Do(of.isBlockSectorMode); - p.Do(of.sectorStart); - p.Do(of.openSize); + Do(p, it->first); + Do(p, of.seekPos); + Do(p, of.isRawSector); + Do(p, of.isBlockSectorMode); + Do(p, of.sectorStart); + Do(p, of.openSize); bool hasFile = of.file != NULL; - p.Do(hasFile); + Do(p, hasFile); if (hasFile) { std::string path = EntryFullPath(of.file); - p.Do(path); + Do(p, path); } } } if (s >= 2) { - p.Do(lastReadBlock_); + Do(p, lastReadBlock_); } else { lastReadBlock_ = 0; } diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 3b6d487e9f..b40a336243 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -19,6 +19,7 @@ #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/StringUtils.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/HLE/sceKernelThread.h" @@ -641,13 +642,13 @@ void MetaFileSystem::DoState(PointerWrap &p) if (!s) return; - p.Do(current); + Do(p, current); // Save/load per-thread current directory map - p.Do(currentDir); + Do(p, currentDir); u32 n = (u32) fileSystems.size(); - p.Do(n); + Do(p, n); bool skipPfat0 = false; if (n != (u32) fileSystems.size()) { diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 81ecbeef57..974823415d 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -20,6 +20,7 @@ #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/FileSystems/VirtualDiscFileSystem.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/HLE/sceKernel.h" @@ -167,18 +168,18 @@ void VirtualDiscFileSystem::DoState(PointerWrap &p) int fileListSize = (int)fileList.size(); int entryCount = (int)entries.size(); - p.Do(fileListSize); - p.Do(entryCount); - p.Do(currentBlockIndex); + Do(p, fileListSize); + Do(p, entryCount); + Do(p, currentBlockIndex); FileListEntry dummy = {""}; fileList.resize(fileListSize, dummy); for (int i = 0; i < fileListSize; i++) { - p.Do(fileList[i].fileName); - p.Do(fileList[i].firstBlock); - p.Do(fileList[i].totalSize); + Do(p, fileList[i].fileName); + Do(p, fileList[i].firstBlock); + Do(p, fileList[i].totalSize); } if (p.mode == p.MODE_READ) @@ -190,12 +191,12 @@ void VirtualDiscFileSystem::DoState(PointerWrap &p) u32 fd = 0; OpenFileEntry of; - p.Do(fd); - p.Do(of.fileIndex); - p.Do(of.type); - p.Do(of.curOffset); - p.Do(of.startOffset); - p.Do(of.size); + Do(p, fd); + Do(p, of.fileIndex); + Do(p, of.type); + Do(p, of.curOffset); + Do(p, of.startOffset); + Do(p, of.size); // open file if (of.type != VFILETYPE_ISO) { @@ -222,17 +223,17 @@ void VirtualDiscFileSystem::DoState(PointerWrap &p) { OpenFileEntry &of = it->second; - p.Do(it->first); - p.Do(of.fileIndex); - p.Do(of.type); - p.Do(of.curOffset); - p.Do(of.startOffset); - p.Do(of.size); + Do(p, it->first); + Do(p, of.fileIndex); + Do(p, of.type); + Do(p, of.curOffset); + Do(p, of.startOffset); + Do(p, of.size); } } if (s >= 2) { - p.Do(lastReadBlock_); + Do(p, lastReadBlock_); } else { lastReadBlock_ = 0; } diff --git a/Core/Font/PGF.cpp b/Core/Font/PGF.cpp index 2383736a94..074688676f 100644 --- a/Core/Font/PGF.cpp +++ b/Core/Font/PGF.cpp @@ -22,6 +22,7 @@ #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MemMap.h" #include "Core/Reporting.h" #include "Core/Font/PGF.h" @@ -128,12 +129,12 @@ void PGF::DoState(PointerWrap &p) { if (!s) return; - p.Do(header); - p.Do(rev3extra); + Do(p, header); + Do(p, rev3extra); // Don't savestate size_t directly, 32-bit and 64-bit are different. u32 fontDataSizeTemp = (u32)fontDataSize; - p.Do(fontDataSizeTemp); + Do(p, fontDataSizeTemp); fontDataSize = (size_t)fontDataSizeTemp; if (p.mode == p.MODE_READ) { if (fontData) { @@ -141,39 +142,39 @@ void PGF::DoState(PointerWrap &p) { } if (fontDataSize) { fontData = new u8[fontDataSize]; - p.DoArray(fontData, (int)fontDataSize); + DoArray(p, fontData, (int)fontDataSize); } } else if (fontDataSize) { - p.DoArray(fontData, (int)fontDataSize); + DoArray(p, fontData, (int)fontDataSize); } - p.Do(fileName); + Do(p, fileName); - p.DoArray(dimensionTable, ARRAY_SIZE(dimensionTable)); - p.DoArray(xAdjustTable, ARRAY_SIZE(xAdjustTable)); - p.DoArray(yAdjustTable, ARRAY_SIZE(yAdjustTable)); - p.DoArray(advanceTable, ARRAY_SIZE(advanceTable)); - p.DoArray(charmapCompressionTable1, ARRAY_SIZE(charmapCompressionTable1)); - p.DoArray(charmapCompressionTable2, ARRAY_SIZE(charmapCompressionTable2)); + DoArray(p, dimensionTable, ARRAY_SIZE(dimensionTable)); + DoArray(p, xAdjustTable, ARRAY_SIZE(xAdjustTable)); + DoArray(p, yAdjustTable, ARRAY_SIZE(yAdjustTable)); + DoArray(p, advanceTable, ARRAY_SIZE(advanceTable)); + DoArray(p, charmapCompressionTable1, ARRAY_SIZE(charmapCompressionTable1)); + DoArray(p, charmapCompressionTable2, ARRAY_SIZE(charmapCompressionTable2)); - p.Do(charmap_compr); - p.Do(charmap); + Do(p, charmap_compr); + Do(p, charmap); if (s == 1) { std::vector oldGlyphs; - p.Do(oldGlyphs); + Do(p, oldGlyphs); glyphs.resize(oldGlyphs.size()); for (size_t i = 0; i < oldGlyphs.size(); ++i) { glyphs[i] = oldGlyphs[i]; } - p.Do(oldGlyphs); + Do(p, oldGlyphs); shadowGlyphs.resize(oldGlyphs.size()); for (size_t i = 0; i < oldGlyphs.size(); ++i) { shadowGlyphs[i] = oldGlyphs[i]; } } else { - p.Do(glyphs); - p.Do(shadowGlyphs); + Do(p, glyphs); + Do(p, shadowGlyphs); } - p.Do(firstGlyph); + Do(p, firstGlyph); } bool PGF::ReadPtr(const u8 *ptr, size_t dataSize) { diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index d12ba73955..6a731ef340 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -24,13 +24,13 @@ #include "base/timeutil.h" #include "profiler/profiler.h" +#include "Common/ChunkFileDo.h" #include "Core/Config.h" +#include "Core/Core.h" #include "Core/CoreTiming.h" +#include "Core/Host.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" - -#include "Core/Core.h" -#include "Core/Host.h" #include "Core/System.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSCodeUtils.h" @@ -128,19 +128,19 @@ void HLEDoState(PointerWrap &p) { // Can't be inside a syscall, reset this so errors aren't misleading. latestSyscall = nullptr; - p.Do(delayedResultEvent); + Do(p, delayedResultEvent); CoreTiming::RestoreRegisterEvent(delayedResultEvent, "HLEDelayedResult", hleDelayResultFinish); if (s >= 2) { int actions = (int)mipsCallActions.size(); - p.Do(actions); + Do(p, actions); if (actions != (int)mipsCallActions.size()) { mipsCallActions.resize(actions); } for (auto &action : mipsCallActions) { int actionTypeID = action != nullptr ? action->actionTypeID : -1; - p.Do(actionTypeID); + Do(p, actionTypeID); if (actionTypeID != -1) { if (p.mode == p.MODE_READ) action = __KernelCreateAction(actionTypeID); diff --git a/Core/HLE/HLEHelperThread.cpp b/Core/HLE/HLEHelperThread.cpp index 36f9166813..c84be0feca 100644 --- a/Core/HLE/HLEHelperThread.cpp +++ b/Core/HLE/HLEHelperThread.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/HLE.h" @@ -73,8 +74,8 @@ void HLEHelperThread::DoState(PointerWrap &p) { return; } - p.Do(id_); - p.Do(entry_); + Do(p, id_); + Do(p, entry_); } void HLEHelperThread::Start(u32 a0, u32 a1) { diff --git a/Core/HLE/ThreadQueueList.h b/Core/HLE/ThreadQueueList.h index dbb46d1818..e08b9c07a5 100644 --- a/Core/HLE/ThreadQueueList.h +++ b/Core/HLE/ThreadQueueList.h @@ -184,7 +184,7 @@ struct ThreadQueueList { return; int numQueues = NUM_QUEUES; - p.Do(numQueues); + Do(p, numQueues); if (numQueues != NUM_QUEUES) { p.SetError(p.ERROR_FAILURE); ERROR_LOG(SCEKERNEL, "Savestate loading error: invalid data"); @@ -197,9 +197,9 @@ struct ThreadQueueList { for (int i = 0; i < NUM_QUEUES; ++i) { Queue *cur = &queues[i]; int size = cur->size(); - p.Do(size); + Do(p, size); int capacity = cur->capacity; - p.Do(capacity); + Do(p, capacity); if (capacity == 0) continue; @@ -211,7 +211,7 @@ struct ThreadQueueList { } if (size != 0) - p.DoArray(&cur->data[cur->first], size); + DoArray(p, &cur->data[cur->first], size); } } diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index e462a94efd..c938c09929 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -20,6 +20,7 @@ #include "Common/CommonTypes.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/FixedSizeQueue.h" #ifdef _M_SSE @@ -130,14 +131,14 @@ void __AudioDoState(PointerWrap &p) { if (!s) return; - p.Do(eventAudioUpdate); + Do(p, eventAudioUpdate); CoreTiming::RestoreRegisterEvent(eventAudioUpdate, "AudioUpdate", &hleAudioUpdate); - p.Do(eventHostAudioUpdate); + Do(p, eventHostAudioUpdate); CoreTiming::RestoreRegisterEvent(eventHostAudioUpdate, "AudioUpdateHost", &hleHostAudioUpdate); - p.Do(mixFrequency); + Do(p, mixFrequency); if (s >= 2) { - p.Do(srcFrequency); + Do(p, srcFrequency); } else { // Assume that it was actually the SRC channel frequency. srcFrequency = mixFrequency; @@ -156,7 +157,7 @@ void __AudioDoState(PointerWrap &p) { } int chanCount = ARRAY_SIZE(chans); - p.Do(chanCount); + Do(p, chanCount); if (chanCount != ARRAY_SIZE(chans)) { ERROR_LOG(SCEAUDIO, "Savestate failure: different number of audio channels."); diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 32cfdc15d2..6e22b3801f 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -33,6 +33,7 @@ #include #include "util/text/parsers.h" #include "thread/threadutil.h" +#include "Common/ChunkFileDo.h" #include "Core/Core.h" #include "Core/Host.h" #include "Core/HLE/sceKernelInterrupt.h" @@ -980,6 +981,24 @@ void clearPeerList(SceNetAdhocMatchingContext * context) peerlock.unlock(); } +void AfterMatchingMipsCall::DoState(PointerWrap & p) { + auto s = p.Section("AfterMatchingMipsCall", 1, 4); + if (!s) + return; + if (s >= 1) { + Do(p, EventID); + } else { + EventID = -1; + } + if (s >= 4) { + Do(p, contextID); + Do(p, bufAddr); + } else { + contextID = -1; + bufAddr = 0; + } +} + // It seems After Actions being called in reverse order of Mipscall order (ie. MipsCall order of ACCEPT(6)->ESTABLISH(7) getting AfterAction order of ESTABLISH(7)->ACCEPT(6) void AfterMatchingMipsCall::run(MipsCall &call) { if (context == NULL) { @@ -1021,6 +1040,21 @@ bool IsMatchingInCallback(SceNetAdhocMatchingContext* context) { return inCB; } +void AfterAdhocMipsCall::DoState(PointerWrap & p) { + auto s = p.Section("AfterAdhocMipsCall", 1, 4); + if (!s) + return; + if (s >= 3) { + Do(p, HandlerID); + Do(p, EventID); + Do(p, argsAddr); + } else { + HandlerID = -1; + EventID = -1; + argsAddr = 0; + } +} + void AfterAdhocMipsCall::run(MipsCall& call) { u32 v0 = currentMIPS->r[MIPS_REG_V0]; if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterAdhocMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", HandlerID, EventID); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index c7d32c5010..b84a13de6d 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -792,21 +792,7 @@ class AfterAdhocMipsCall : public PSPAction { public: AfterAdhocMipsCall() {} static PSPAction* Create() { return new AfterAdhocMipsCall(); } - void DoState(PointerWrap& p) override { - auto s = p.Section("AfterAdhocMipsCall", 1, 4); - if (!s) - return; - if (s >= 3) { - p.Do(HandlerID); - p.Do(EventID); - p.Do(argsAddr); - } - else { - HandlerID = -1; - EventID = -1; - argsAddr = 0; - } - } + void DoState(PointerWrap& p) override; void run(MipsCall& call) override; void SetData(int handlerID, int eventId, u32_le argsAddr); @@ -820,25 +806,7 @@ class AfterMatchingMipsCall : public PSPAction { public: AfterMatchingMipsCall() {} static PSPAction *Create() { return new AfterMatchingMipsCall(); } - void DoState(PointerWrap &p) override { - auto s = p.Section("AfterMatchingMipsCall", 1, 4); - if (!s) - return; - if (s >= 1) { - p.Do(EventID); - } - else { - EventID = -1; - } - if (s >= 4) { - p.Do(contextID); - p.Do(bufAddr); - } - else { - contextID = -1; - bufAddr = 0; - } - } + void DoState(PointerWrap &p) override; void run(MipsCall &call) override; void SetData(int ContextID, int eventId, u32_le BufAddr); diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index bef952a7e8..fb54546fdb 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -17,6 +17,8 @@ #include +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" @@ -27,7 +29,6 @@ #include "Core/Debugger/Breakpoints.h" #include "Core/HW/MediaEngine.h" #include "Core/HW/BufferQueue.h" -#include "Common/ChunkFile.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceUtility.h" @@ -236,65 +237,65 @@ struct Atrac { if (!s) return; - p.Do(channels_); - p.Do(outputChannels_); + Do(p, channels_); + Do(p, outputChannels_); if (s >= 5) { - p.Do(jointStereo_); + Do(p, jointStereo_); } - p.Do(atracID_); - p.Do(first_); - p.Do(bufferMaxSize_); - p.Do(codecType_); + Do(p, atracID_); + Do(p, first_); + Do(p, bufferMaxSize_); + Do(p, codecType_); - p.Do(currentSample_); - p.Do(endSample_); - p.Do(firstSampleOffset_); + Do(p, currentSample_); + Do(p, endSample_); + Do(p, firstSampleOffset_); if (s >= 3) { - p.Do(dataOff_); + Do(p, dataOff_); } else { dataOff_ = firstSampleOffset_; } u32 hasDataBuf = dataBuf_ != nullptr; - p.Do(hasDataBuf); + Do(p, hasDataBuf); if (hasDataBuf) { if (p.mode == p.MODE_READ) { if (dataBuf_) delete [] dataBuf_; dataBuf_ = new u8[first_.filesize]; } - p.DoArray(dataBuf_, first_.filesize); + DoArray(p, dataBuf_, first_.filesize); } - p.Do(second_); + Do(p, second_); - p.Do(decodePos_); + Do(p, decodePos_); if (s < 9) { u32 oldDecodeEnd = 0; - p.Do(oldDecodeEnd); + Do(p, oldDecodeEnd); } if (s >= 4) { - p.Do(bufferPos_); + Do(p, bufferPos_); } else { bufferPos_ = decodePos_; } - p.Do(bitrate_); - p.Do(bytesPerFrame_); + Do(p, bitrate_); + Do(p, bytesPerFrame_); - p.Do(loopinfo_); + Do(p, loopinfo_); if (s < 9) { int oldLoopInfoNum = 42; - p.Do(oldLoopInfoNum); + Do(p, oldLoopInfoNum); } - p.Do(loopStartSample_); - p.Do(loopEndSample_); - p.Do(loopNum_); + Do(p, loopStartSample_); + Do(p, loopEndSample_); + Do(p, loopNum_); - p.Do(context_); + Do(p, context_); if (s >= 6) { - p.Do(bufferState_); + Do(p, bufferState_); } else { if (dataBuf_ == nullptr) { bufferState_ = ATRAC_STATUS_NO_DATA; @@ -304,14 +305,14 @@ struct Atrac { } if (s >= 7) { - p.Do(ignoreDataBuf_); + Do(p, ignoreDataBuf_); } else { ignoreDataBuf_ = false; } if (s >= 9) { - p.Do(bufferValidBytes_); - p.Do(bufferHeaderSize_); + Do(p, bufferValidBytes_); + Do(p, bufferHeaderSize_); } else { bufferHeaderSize_ = dataOff_; bufferValidBytes_ = std::min(first_.size - dataOff_, StreamBufferEnd() - dataOff_); @@ -333,7 +334,7 @@ struct Atrac { if (s >= 2 && s < 9) { bool oldResetBuffer = false; - p.Do(oldResetBuffer); + Do(p, oldResetBuffer); } } @@ -645,18 +646,18 @@ void __AtracDoState(PointerWrap &p) { if (!s) return; - p.Do(atracInited); + Do(p, atracInited); for (int i = 0; i < PSP_NUM_ATRAC_IDS; ++i) { bool valid = atracIDs[i] != NULL; - p.Do(valid); + Do(p, valid); if (valid) { - p.Do(atracIDs[i]); + Do(p, atracIDs[i]); } else { delete atracIDs[i]; atracIDs[i] = NULL; } } - p.DoArray(atracIDTypes, PSP_NUM_ATRAC_IDS); + DoArray(p, atracIDTypes, PSP_NUM_ATRAC_IDS); } void __AtracShutdown() { diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index f75b66604c..ba7ca82b62 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MIPS/MIPS.h" #include "Core/Host.h" #include "Core/CoreTiming.h" @@ -40,16 +41,16 @@ void AudioChannel::DoState(PointerWrap &p) if (!s) return; - p.Do(reserved); - p.Do(sampleAddress); - p.Do(sampleCount); - p.Do(leftVolume); - p.Do(rightVolume); - p.Do(format); - p.Do(waitingThreads); + Do(p, reserved); + Do(p, sampleAddress); + Do(p, sampleCount); + Do(p, leftVolume); + Do(p, rightVolume); + Do(p, format); + Do(p, waitingThreads); if (s >= 2) { - p.Do(defaultRoutingMode); - p.Do(defaultRoutingVolMode); + Do(p, defaultRoutingMode); + Do(p, defaultRoutingVolMode); } sampleQueue.DoState(p); } diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index 83d70dc343..509d35c50f 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -15,13 +15,14 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceAudiocodec.h" #include "Core/MemMap.h" #include "Core/Reporting.h" #include "Core/HW/SimpleAudioDec.h" -#include "Common/ChunkFile.h" // Following kaien_fr's sample code https://github.com/hrydgard/ppsspp/issues/5620#issuecomment-37086024 // Should probably store the EDRAM get/release status somewhere within here, etc. @@ -171,7 +172,7 @@ void __sceAudiocodecDoState(PointerWrap &p){ } int count = (int)audioList.size(); - p.Do(count); + Do(p, count); if (count > 0) { if (p.mode == PointerWrap::MODE_READ) { @@ -182,8 +183,8 @@ void __sceAudiocodecDoState(PointerWrap &p){ auto ctxPtr_ = new u32[count]; // These sizeof(pointers) are wrong, but kept to avoid breaking on old saves. // They're not used in new savestates. - p.DoArray(codec_, s >= 2 ? count : (int)ARRAY_SIZE(codec_)); - p.DoArray(ctxPtr_, s >= 2 ? count : (int)ARRAY_SIZE(ctxPtr_)); + DoArray(p, codec_, s >= 2 ? count : (int)ARRAY_SIZE(codec_)); + DoArray(p, ctxPtr_, s >= 2 ? count : (int)ARRAY_SIZE(ctxPtr_)); for (int i = 0; i < count; i++) { auto decoder = new SimpleAudio(codec_[i]); decoder->SetCtxPtr(ctxPtr_[i]); @@ -205,8 +206,8 @@ void __sceAudiocodecDoState(PointerWrap &p){ ctxPtr_[i] = decoder->GetCtxPtr(); i++; } - p.DoArray(codec_, count); - p.DoArray(ctxPtr_, count); + DoArray(p, codec_, count); + DoArray(p, ctxPtr_, count); delete[] codec_; delete[] ctxPtr_; } diff --git a/Core/HLE/sceCcc.cpp b/Core/HLE/sceCcc.cpp index 71cbfa6e40..7040a5f329 100644 --- a/Core/HLE/sceCcc.cpp +++ b/Core/HLE/sceCcc.cpp @@ -20,6 +20,7 @@ #include "util/text/shiftjis.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Debugger/Breakpoints.h" #include "Core/MemMap.h" #include "Core/HLE/HLE.h" @@ -55,11 +56,11 @@ void __CccDoState(PointerWrap &p) if (!s) return; - p.Do(errorUTF8); - p.Do(errorUTF16); - p.Do(errorSJIS); - p.Do(ucs2jisTable); - p.Do(jis2ucsTable); + Do(p, errorUTF8); + Do(p, errorUTF16); + Do(p, errorSJIS); + Do(p, ucs2jisTable); + Do(p, jis2ucsTable); } static u32 __CccUCStoJIS(u32 c, u32 alt) diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index 8bad0e193a..28957509b2 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -18,13 +18,14 @@ #include #include +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/Replay.h" -#include "Common/ChunkFile.h" #include "Core/Util/AudioFormat.h" // for clamp_u8 #include "Core/HLE/sceCtrl.h" #include "Core/HLE/sceDisplay.h" @@ -350,33 +351,33 @@ void __CtrlDoState(PointerWrap &p) if (!s) return; - p.Do(analogEnabled); - p.Do(ctrlLatchBufs); - p.Do(ctrlOldButtons); + Do(p, analogEnabled); + Do(p, ctrlLatchBufs); + Do(p, ctrlOldButtons); p.DoVoid(ctrlBufs, sizeof(ctrlBufs)); if (s <= 2) { CtrlData dummy = {0}; - p.Do(dummy); + Do(p, dummy); } - p.Do(ctrlBuf); - p.Do(ctrlBufRead); - p.Do(latch); + Do(p, ctrlBuf); + Do(p, ctrlBufRead); + Do(p, latch); if (s == 1) { dialogBtnMake = 0; } else { - p.Do(dialogBtnMake); + Do(p, dialogBtnMake); } - p.Do(ctrlIdleReset); - p.Do(ctrlIdleBack); + Do(p, ctrlIdleReset); + Do(p, ctrlIdleBack); - p.Do(ctrlCycle); + Do(p, ctrlCycle); SceUID dv = 0; - p.Do(waitingThreads, dv); + Do(p, waitingThreads, dv); - p.Do(ctrlTimer); + Do(p, ctrlTimer); CoreTiming::RestoreRegisterEvent(ctrlTimer, "CtrlSampleTimer", __CtrlTimerUpdate); } diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 305339d86c..1e30c5112a 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -37,6 +37,7 @@ #include "gfx_es2/gpu_features.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Config.h" #include "Core/CoreTiming.h" #include "Core/CoreParameter.h" @@ -77,8 +78,8 @@ struct WaitVBlankInfo { if (!s) return; - p.Do(threadID); - p.Do(vcountUnblock); + Do(p, threadID); + Do(p, vcountUnblock); } }; @@ -261,42 +262,42 @@ void __DisplayDoState(PointerWrap &p) { if (!s) return; - p.Do(framebuf); - p.Do(latchedFramebuf); - p.Do(framebufIsLatched); - p.Do(frameStartTicks); - p.Do(vCount); + Do(p, framebuf); + Do(p, latchedFramebuf); + Do(p, framebufIsLatched); + Do(p, frameStartTicks); + Do(p, vCount); if (s <= 2) { double oldHCountBase; - p.Do(oldHCountBase); + Do(p, oldHCountBase); hCountBase = (int) oldHCountBase; } else { - p.Do(hCountBase); + Do(p, hCountBase); } - p.Do(isVblank); - p.Do(hasSetMode); - p.Do(mode); - p.Do(resumeMode); - p.Do(holdMode); + Do(p, isVblank); + Do(p, hasSetMode); + Do(p, mode); + Do(p, resumeMode); + Do(p, holdMode); if (s >= 4) { - p.Do(brightnessLevel); + Do(p, brightnessLevel); } - p.Do(width); - p.Do(height); + Do(p, width); + Do(p, height); WaitVBlankInfo wvi(0); - p.Do(vblankWaitingThreads, wvi); - p.Do(vblankPausedWaits); + Do(p, vblankWaitingThreads, wvi); + Do(p, vblankPausedWaits); - p.Do(enterVblankEvent); + Do(p, enterVblankEvent); CoreTiming::RestoreRegisterEvent(enterVblankEvent, "EnterVBlank", &hleEnterVblank); - p.Do(leaveVblankEvent); + Do(p, leaveVblankEvent); CoreTiming::RestoreRegisterEvent(leaveVblankEvent, "LeaveVBlank", &hleLeaveVblank); - p.Do(afterFlipEvent); + Do(p, afterFlipEvent); CoreTiming::RestoreRegisterEvent(afterFlipEvent, "AfterFlip", &hleAfterFlip); if (s >= 5) { - p.Do(lagSyncEvent); - p.Do(lagSyncScheduled); + Do(p, lagSyncEvent); + Do(p, lagSyncScheduled); CoreTiming::RestoreRegisterEvent(lagSyncEvent, "LagSync", &hleLagSync); lastLagSync = real_time_now(); if (lagSyncScheduled != g_Config.bForceLagSync) { @@ -307,7 +308,7 @@ void __DisplayDoState(PointerWrap &p) { ScheduleLagSync(); } - p.Do(gstate); + Do(p, gstate); // TODO: GPU stuff is really not the responsibility of sceDisplay. // Display just displays the buffers the GPU has drawn, they are really completely distinct. @@ -321,7 +322,7 @@ void __DisplayDoState(PointerWrap &p) { } if (s < 6) { GPUStatistics_v0 oldStats; - p.Do(oldStats); + Do(p, oldStats); } if (s < 7) { @@ -329,8 +330,8 @@ void __DisplayDoState(PointerWrap &p) { lastFlipCycles = now; nextFlipCycles = now; } else { - p.Do(lastFlipCycles); - p.Do(nextFlipCycles); + Do(p, lastFlipCycles); + Do(p, nextFlipCycles); } gpu->DoState(p); diff --git a/Core/HLE/sceDmac.cpp b/Core/HLE/sceDmac.cpp index da48432e8b..9290cc4d76 100644 --- a/Core/HLE/sceDmac.cpp +++ b/Core/HLE/sceDmac.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" @@ -40,7 +41,7 @@ void __DmacDoState(PointerWrap &p) { return; } - p.Do(dmacMemcpyDeadline); + Do(p, dmacMemcpyDeadline); } static int __DmacMemcpy(u32 dst, u32 src, u32 size) { diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index c742134ecd..605beda7da 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -8,6 +8,7 @@ #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceFont.h" @@ -221,12 +222,12 @@ public: if (!s) return; - p.Do(pgf_); - p.Do(style_); + Do(p, pgf_); + Do(p, style_); if (s < 2) { valid_ = true; } else { - p.Do(valid_); + Do(p, valid_); } } @@ -317,29 +318,29 @@ public: return; int numInternalFonts = (int)internalFonts.size(); - p.Do(numInternalFonts); + Do(p, numInternalFonts); if (numInternalFonts != (int)internalFonts.size()) { ERROR_LOG(SCEFONT, "Unable to load state: different internal font count."); p.SetError(p.ERROR_FAILURE); return; } - p.Do(fontLibID_); + Do(p, fontLibID_); int internalFont = GetInternalFontIndex(font_); - p.Do(internalFont); + Do(p, internalFont); if (internalFont == -1) { - p.Do(font_); + Do(p, font_); } else if (p.mode == p.MODE_READ) { font_ = internalFonts[internalFont]; } - p.Do(handle_); + Do(p, handle_); if (s >= 2) { - p.Do(open_); + Do(p, open_); } else { open_ = fontLibID_ != (u32)-1; } if (s >= 3) { - p.Do(mode_); + Do(p, mode_); } else { mode_ = FONT_OPEN_INTERNAL_FULL; } @@ -363,9 +364,9 @@ public: if (!s) return; - p.Do(fontLibID_); + Do(p, fontLibID_); if (s >= 2) { - p.Do(errorCodePtr_); + Do(p, errorCodePtr_); } else { errorCodePtr_ = 0; } @@ -387,7 +388,7 @@ public: if (!s) return; - p.Do(fontLibID_); + Do(p, fontLibID_); } void run(MipsCall &call) override; void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } @@ -405,9 +406,9 @@ public: if (!s) return; - p.Do(fontLibID_); - p.Do(fontHandle_); - p.Do(fontIndex_); + Do(p, fontLibID_); + Do(p, fontHandle_); + Do(p, fontIndex_); } void run(MipsCall &call) override; void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } @@ -428,7 +429,7 @@ public: if (!s) return; - p.Do(fontLibID_); + Do(p, fontLibID_); } void run(MipsCall &call) override; void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } @@ -446,8 +447,8 @@ public: if (!s) return; - p.Do(fontLibID_); - p.Do(charInfo_); + Do(p, fontLibID_); + Do(p, charInfo_); } void run(MipsCall &call) override; void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } @@ -662,23 +663,23 @@ public: if (!s) return; - p.Do(fonts_); - p.Do(isfontopen_); - p.Do(params_); - p.Do(fontHRes_); - p.Do(fontVRes_); - p.Do(fileFontHandle_); - p.Do(handle_); - p.Do(altCharCode_); + Do(p, fonts_); + Do(p, isfontopen_); + Do(p, params_); + Do(p, fontHRes_); + Do(p, fontVRes_); + Do(p, fileFontHandle_); + Do(p, handle_); + Do(p, altCharCode_); if (s >= 2) { - p.Do(nfl_); + Do(p, nfl_); } else { nfl_ = 0; } if (s >= 3) { - p.Do(openAllocatedAddresses_); - p.Do(charInfoBitmapAddress_); + Do(p, openAllocatedAddresses_); + Do(p, charInfoBitmapAddress_); } else { openAllocatedAddresses_.resize(params_.numFonts); charInfoBitmapAddress_ = 0; @@ -917,20 +918,20 @@ void __FontDoState(PointerWrap &p) { __LoadInternalFonts(); - p.Do(fontLibList); - p.Do(fontLibMap); - p.Do(fontMap); + Do(p, fontLibList); + Do(p, fontLibMap); + Do(p, fontMap); - p.Do(actionPostAllocCallback); + Do(p, actionPostAllocCallback); __KernelRestoreActionType(actionPostAllocCallback, PostAllocCallback::Create); - p.Do(actionPostOpenCallback); + Do(p, actionPostOpenCallback); __KernelRestoreActionType(actionPostOpenCallback, PostOpenCallback::Create); if (s >= 2) { - p.Do(actionPostOpenAllocCallback); + Do(p, actionPostOpenAllocCallback); __KernelRestoreActionType(actionPostOpenAllocCallback, PostOpenAllocCallback::Create); - p.Do(actionPostCharInfoAllocCallback); + Do(p, actionPostCharInfoAllocCallback); __KernelRestoreActionType(actionPostCharInfoAllocCallback, PostCharInfoAllocCallback::Create); - p.Do(actionPostCharInfoFreeCallback); + Do(p, actionPostCharInfoFreeCallback); __KernelRestoreActionType(actionPostCharInfoFreeCallback, PostCharInfoFreeCallback::Create); } else { useAllocCallbacks = false; diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 1af22c00de..625fa1b3d0 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -20,6 +20,7 @@ #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/ThreadSafeList.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" @@ -219,14 +220,14 @@ void __GeDoState(PointerWrap &p) { if (!s) return; - p.DoArray(ge_callback_data, ARRAY_SIZE(ge_callback_data)); - p.DoArray(ge_used_callbacks, ARRAY_SIZE(ge_used_callbacks)); + DoArray(p, ge_callback_data, ARRAY_SIZE(ge_callback_data)); + DoArray(p, ge_used_callbacks, ARRAY_SIZE(ge_used_callbacks)); if (s >= 2) { - p.Do(ge_pending_cb); + Do(p, ge_pending_cb); } else { std::list old; - p.Do(old); + Do(p, old); ge_pending_cb.clear(); for (auto it = old.begin(), end = old.end(); it != end; ++it) { GeInterruptData intrdata = {it->listid, it->pc}; @@ -235,15 +236,15 @@ void __GeDoState(PointerWrap &p) { } } - p.Do(geSyncEvent); + Do(p, geSyncEvent); CoreTiming::RestoreRegisterEvent(geSyncEvent, "GeSyncEvent", &__GeExecuteSync); - p.Do(geInterruptEvent); + Do(p, geInterruptEvent); CoreTiming::RestoreRegisterEvent(geInterruptEvent, "GeInterruptEvent", &__GeExecuteInterrupt); - p.Do(geCycleEvent); + Do(p, geCycleEvent); CoreTiming::RestoreRegisterEvent(geCycleEvent, "GeCycleEvent", &__GeCheckCycles); - p.Do(listWaitingThreads); - p.Do(drawWaitingThreads); + Do(p, listWaitingThreads); + Do(p, drawWaitingThreads); // Everything else is done in sceDisplay. } diff --git a/Core/HLE/sceHeap.cpp b/Core/HLE/sceHeap.cpp index 72873edbbd..61bf921012 100644 --- a/Core/HLE/sceHeap.cpp +++ b/Core/HLE/sceHeap.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MemMap.h" #include "Core/Reporting.h" #include "Core/HLE/HLE.h" @@ -34,10 +35,10 @@ struct Heap { BlockAllocator alloc; void DoState (PointerWrap &p) { - p.Do(size); - p.Do(address); - p.Do(fromtop); - p.Do(alloc); + Do(p, size); + Do(p, address); + Do(p, fromtop); + Do(p, alloc); } }; @@ -57,7 +58,7 @@ void __HeapDoState(PointerWrap &p) { return; if (s >= 2) { - p.Do(heapList); + Do(p, heapList); } } diff --git a/Core/HLE/sceImpose.cpp b/Core/HLE/sceImpose.cpp index 9ef9af254a..8a3b60fec0 100644 --- a/Core/HLE/sceImpose.cpp +++ b/Core/HLE/sceImpose.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceImpose.h" @@ -22,7 +24,6 @@ #include "Core/MIPS/MIPS.h" #include "Core/Config.h" #include "Core/MemMap.h" -#include "Common/ChunkFile.h" const int PSP_UMD_POPUP_DISABLE = 0; const int PSP_UMD_POPUP_ENABLE = 1; @@ -50,10 +51,10 @@ void __ImposeDoState(PointerWrap &p) if (!s) return; - p.Do(language); - p.Do(buttonValue); - p.Do(umdPopup); - p.Do(backlightOffTime); + Do(p, language); + Do(p, buttonValue); + Do(p, umdPopup); + Do(p, backlightOffTime); } static u32 sceImposeGetBatteryIconStatus(u32 chargingPtr, u32 iconStatusPtr) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 49d14f0c36..93d9adb3ec 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -22,6 +22,7 @@ #include "thread/threadutil.h" #include "profiler/profiler.h" +#include "Common/ChunkFileDo.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/ConfigValues.h" @@ -227,22 +228,22 @@ public: if (!s) return; - p.Do(fullpath); - p.Do(handle); - p.Do(callbackID); - p.Do(callbackArg); - p.Do(asyncResult); - p.Do(hasAsyncResult); - p.Do(pendingAsyncResult); - p.Do(sectorBlockMode); - p.Do(closePending); - p.Do(info); - p.Do(openMode); + Do(p, fullpath); + Do(p, handle); + Do(p, callbackID); + Do(p, callbackArg); + Do(p, asyncResult); + Do(p, hasAsyncResult); + Do(p, pendingAsyncResult); + Do(p, sectorBlockMode); + Do(p, closePending); + Do(p, info); + Do(p, openMode); - p.Do(npdrm); - p.Do(pgd_offset); + Do(p, npdrm); + Do(p, pgd_offset); bool hasPGD = pgdInfo != NULL; - p.Do(hasPGD); + Do(p, hasPGD); if (hasPGD) { if (p.mode == p.MODE_READ) { pgdInfo = (PGD_DESC*) malloc(sizeof(PGD_DESC)); @@ -253,11 +254,11 @@ public: } } - p.Do(waitingThreads); + Do(p, waitingThreads); if (s >= 2) { - p.Do(waitingSyncThreads); + Do(p, waitingSyncThreads); } - p.Do(pausedWaits); + Do(p, pausedWaits); } std::string fullpath; @@ -670,10 +671,10 @@ void __IoDoState(PointerWrap &p) { return; ioManager.DoState(p); - p.DoArray(fds, ARRAY_SIZE(fds)); - p.Do(asyncNotifyEvent); + DoArray(p, fds, ARRAY_SIZE(fds)); + Do(p, asyncNotifyEvent); CoreTiming::RestoreRegisterEvent(asyncNotifyEvent, "IoAsyncNotify", __IoAsyncNotify); - p.Do(syncNotifyEvent); + Do(p, syncNotifyEvent); CoreTiming::RestoreRegisterEvent(syncNotifyEvent, "IoSyncNotify", __IoSyncNotify); if (s < 2) { std::set legacy; @@ -681,22 +682,22 @@ void __IoDoState(PointerWrap &p) { memStickFatCallbacks.clear(); // Convert from set to vector. - p.Do(legacy); + Do(p, legacy); for (SceUID id : legacy) { memStickCallbacks.push_back(id); } - p.Do(legacy); + Do(p, legacy); for (SceUID id : legacy) { memStickFatCallbacks.push_back(id); } } else { - p.Do(memStickCallbacks); - p.Do(memStickFatCallbacks); + Do(p, memStickCallbacks); + Do(p, memStickFatCallbacks); } if (s >= 3) { - p.Do(lastMemStickState); - p.Do(lastMemStickFatState); + Do(p, lastMemStickState); + Do(p, lastMemStickFatState); } for (int i = 0; i < PSP_COUNT_FDS; ++i) { @@ -710,11 +711,11 @@ void __IoDoState(PointerWrap &p) { if (s >= 4) { p.DoVoid(&asyncParams[i], (int)sizeof(IoAsyncParams)); bool hasThread = asyncThreads[i] != nullptr; - p.Do(hasThread); + Do(p, hasThread); if (hasThread) { if (p.GetMode() == p.MODE_READ) clearThread(); - p.DoClass(asyncThreads[i]); + DoClass(p, asyncThreads[i]); } else if (!hasThread) { clearThread(); } @@ -726,7 +727,7 @@ void __IoDoState(PointerWrap &p) { } if (s >= 5) { - p.Do(asyncDefaultPriority); + Do(p, asyncDefaultPriority); } else { asyncDefaultPriority = -1; } @@ -2244,12 +2245,12 @@ public: if (!s) return; - p.Do(name); - p.Do(index); + Do(p, name); + Do(p, index); // TODO: Is this the right way for it to wake up? int count = (int) listing.size(); - p.Do(count); + Do(p, count); listing.resize(count); for (int i = 0; i < count; ++i) { listing[i].DoState(p); diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index f532233203..feb0c0ea58 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -15,10 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "ext/jpge/jpgd.h" #include "Common/Common.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceJpeg.h" @@ -33,8 +35,6 @@ #include "ext/xxhash.h" #endif -#include - static int mjpegWidth, mjpegHeight; void __JpegInit() { @@ -47,8 +47,8 @@ void __JpegDoState(PointerWrap &p) { if (!s) return; - p.Do(mjpegWidth); - p.Do(mjpegHeight); + Do(p, mjpegWidth); + Do(p, mjpegHeight); } static int getWidthHeight(int width, int height) { diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index f03eb5f8c3..30fe5dc999 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/ChunkFileDo.h" +#include "Common/LogManager.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/CwCheat.h" @@ -26,7 +28,6 @@ #include "Core/MIPS/MIPSInt.h" #include "Core/MIPS/JitCommon/JitCommon.h" -#include "Common/LogManager.h" #include "Core/FileSystems/FileSystem.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/PSPLoaders.h" @@ -217,11 +218,11 @@ void __KernelDoState(PointerWrap &p) if (!s) return; - p.Do(kernelRunning); + Do(p, kernelRunning); kernelObjects.DoState(p); if (s >= 2) - p.Do(registeredExitCbId); + Do(p, registeredExitCbId); } { @@ -542,7 +543,7 @@ void KernelObjectPool::DoState(PointerWrap &p) { return; int _maxCount = maxCount; - p.Do(_maxCount); + Do(p, _maxCount); if (_maxCount != maxCount) { p.SetError(p.ERROR_FAILURE); @@ -555,15 +556,15 @@ void KernelObjectPool::DoState(PointerWrap &p) { kernelObjects.Clear(); } - p.Do(nextID); - p.DoArray(occupied, maxCount); + Do(p, nextID); + DoArray(p, occupied, maxCount); for (int i = 0; i < maxCount; ++i) { if (!occupied[i]) continue; int type; if (p.mode == p.MODE_READ) { - p.Do(type); + Do(p, type); pool[i] = CreateByIDType(type); // Already logged an error. @@ -573,7 +574,7 @@ void KernelObjectPool::DoState(PointerWrap &p) { pool[i]->uid = i + handleOffset; } else { type = pool[i]->GetIDType(); - p.Do(type); + Do(p, type); } pool[i]->DoState(p); if (p.error >= p.ERROR_FAILURE) diff --git a/Core/HLE/sceKernelAlarm.cpp b/Core/HLE/sceKernelAlarm.cpp index edce430446..94cd258f96 100644 --- a/Core/HLE/sceKernelAlarm.cpp +++ b/Core/HLE/sceKernelAlarm.cpp @@ -15,13 +15,14 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelAlarm.h" #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/HLE.h" #include "Core/CoreTiming.h" #include "Core/MemMap.h" -#include "Common/ChunkFile.h" #include const int NATIVEALARM_SIZE = 20; @@ -50,7 +51,7 @@ struct PSPAlarm : public KernelObject { if (!s) return; - p.Do(alm); + Do(p, alm); } NativeAlarm alm; @@ -136,8 +137,8 @@ void __KernelAlarmDoState(PointerWrap &p) if (!s) return; - p.Do(alarmTimer); - p.Do(triggeredAlarm); + Do(p, alarmTimer); + Do(p, triggeredAlarm); CoreTiming::RestoreRegisterEvent(alarmTimer, "Alarm", __KernelTriggerAlarm); } diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index 0dde6fb966..db79bd4f62 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -15,12 +15,13 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" -#include "Common/ChunkFile.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelThread.h" @@ -73,10 +74,10 @@ public: if (!s) return; - p.Do(nef); + Do(p, nef); EventFlagTh eft = { 0 }; - p.Do(waitingThreads, eft); - p.Do(pausedWaits); + Do(p, waitingThreads, eft); + Do(p, pausedWaits); } NativeEventFlag nef; @@ -121,7 +122,7 @@ void __KernelEventFlagDoState(PointerWrap &p) { if (!s) return; - p.Do(eventFlagWaitTimer); + Do(p, eventFlagWaitTimer); CoreTiming::RestoreRegisterEvent(eventFlagWaitTimer, "EventFlagTimeout", __KernelEventFlagTimeout); } diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index 36581f1e15..e73f9f60c6 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -1,6 +1,7 @@ #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernel.h" @@ -27,13 +28,13 @@ struct Heap : public KernelObject { static const char *GetStaticTypeName() { return "Heap"; } void DoState(PointerWrap &p) override { - p.Do(uid); - p.Do(partitionId); - p.Do(size); - p.Do(flags); - p.Do(address); - p.Do(name); - p.Do(alloc); + Do(p, uid); + Do(p, partitionId); + Do(p, size); + Do(p, flags); + Do(p, address); + Do(p, name); + Do(p, alloc); } }; diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 7e3fab221d..d065fcce14 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -19,12 +19,13 @@ #include #include +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" -#include "Common/ChunkFile.h" #include "Core/Debugger/Breakpoints.h" #include "Core/HLE/sceKernel.h" @@ -59,7 +60,7 @@ public: if (!s) return; - p.Do(savedCpu); + Do(p, savedCpu); } PSPThreadContext savedCpu; @@ -213,8 +214,8 @@ void IntrHandler::DoState(PointerWrap &p) if (!s) return; - p.Do(intrNumber); - p.Do(subIntrHandlers); + Do(p, intrNumber); + Do(p, subIntrHandlers); } void PendingInterrupt::DoState(PointerWrap &p) @@ -223,8 +224,8 @@ void PendingInterrupt::DoState(PointerWrap &p) if (!s) return; - p.Do(intr); - p.Do(subintr); + Do(p, intr); + Do(p, subintr); } void __InterruptsInit() @@ -244,7 +245,7 @@ void __InterruptsDoState(PointerWrap &p) return; int numInterrupts = PSP_NUMBER_INTERRUPTS; - p.Do(numInterrupts); + Do(p, numInterrupts); if (numInterrupts != PSP_NUMBER_INTERRUPTS) { p.SetError(p.ERROR_FAILURE); @@ -254,10 +255,10 @@ void __InterruptsDoState(PointerWrap &p) intState.DoState(p); PendingInterrupt pi(0, 0); - p.Do(pendingInterrupts, pi); - p.Do(interruptsEnabled); - p.Do(inInterrupt); - p.Do(threadBeforeInterrupt); + Do(p, pendingInterrupts, pi); + Do(p, interruptsEnabled); + Do(p, inInterrupt); + Do(p, threadBeforeInterrupt); } void __InterruptsDoStateLate(PointerWrap &p) diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index 38dd9687f0..e881363b7b 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -18,6 +18,7 @@ #include #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelMbx.h" @@ -166,10 +167,10 @@ struct Mbx : public KernelObject if (!s) return; - p.Do(nmb); + Do(p, nmb); MbxWaitingThread mwt = {0}; - p.Do(waitingThreads, mwt); - p.Do(pausedWaits); + Do(p, waitingThreads, mwt); + Do(p, pausedWaits); } NativeMbx nmb; @@ -194,7 +195,7 @@ void __KernelMbxDoState(PointerWrap &p) if (!s) return; - p.Do(mbxWaitTimer); + Do(p, mbxWaitTimer); CoreTiming::RestoreRegisterEvent(mbxWaitTimer, "MbxTimeout", __KernelMbxTimeout); } diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 50792c39ff..73e53538df 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -21,6 +21,7 @@ #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/System.h" @@ -130,16 +131,16 @@ struct FPL : public KernelObject if (!s) return; - p.Do(nf); + Do(p, nf); if (p.mode == p.MODE_READ) blocks = new bool[nf.numBlocks]; - p.DoArray(blocks, nf.numBlocks); - p.Do(address); - p.Do(alignedSize); - p.Do(nextBlock); + DoArray(p, blocks, nf.numBlocks); + Do(p, address); + Do(p, alignedSize); + Do(p, nextBlock); FplWaitingThread dv = {0}; - p.Do(waitingThreads, dv); - p.Do(pausedWaits); + Do(p, waitingThreads, dv); + Do(p, pausedWaits); } NativeFPL nf; @@ -392,15 +393,15 @@ struct VPL : public KernelObject return; } - p.Do(nv); - p.Do(address); + Do(p, nv); + Do(p, address); VplWaitingThread dv = {0}; - p.Do(waitingThreads, dv); + Do(p, waitingThreads, dv); alloc.DoState(p); - p.Do(pausedWaits); + Do(p, pausedWaits); if (s >= 2) { - p.Do(header); + Do(p, header); } } @@ -456,16 +457,16 @@ void __KernelMemoryDoState(PointerWrap &p) kernelMemory.DoState(p); userMemory.DoState(p); - p.Do(vplWaitTimer); + Do(p, vplWaitTimer); CoreTiming::RestoreRegisterEvent(vplWaitTimer, "VplTimeout", __KernelVplTimeout); - p.Do(fplWaitTimer); + Do(p, fplWaitTimer); CoreTiming::RestoreRegisterEvent(fplWaitTimer, "FplTimeout", __KernelFplTimeout); - p.Do(flags_); - p.Do(sdkVersion_); - p.Do(compilerVersion_); - p.DoArray(tlsplUsedIndexes, ARRAY_SIZE(tlsplUsedIndexes)); + Do(p, flags_); + Do(p, sdkVersion_); + Do(p, compilerVersion_); + DoArray(p, tlsplUsedIndexes, ARRAY_SIZE(tlsplUsedIndexes)); if (s >= 2) { - p.Do(tlsplThreadEndChecks); + Do(p, tlsplThreadEndChecks); } } @@ -949,8 +950,8 @@ public: if (!s) return; - p.Do(address); - p.DoArray(name, sizeof(name)); + Do(p, address); + DoArray(p, name, sizeof(name)); } u32 address; @@ -1886,15 +1887,15 @@ struct TLSPL : public KernelObject if (!s) return; - p.Do(ntls); - p.Do(address); + Do(p, ntls); + Do(p, address); if (s >= 2) - p.Do(alignment); + Do(p, alignment); else alignment = 4; - p.Do(waitingThreads); - p.Do(next); - p.Do(usage); + Do(p, waitingThreads); + Do(p, next); + Do(p, usage); } NativeTlspl ntls; diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 576c65c245..fe51c77699 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -23,6 +23,7 @@ #include "base/stringutil.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Config.h" @@ -265,14 +266,14 @@ public: if (!s) return; - p.Do(nm); - p.Do(memoryBlockAddr); - p.Do(memoryBlockSize); - p.Do(isFake); + Do(p, nm); + Do(p, memoryBlockAddr); + Do(p, memoryBlockSize); + Do(p, isFake); if (s < 2) { bool isStarted = false; - p.Do(isStarted); + Do(p, isStarted); if (isStarted) nm.status = MODULE_STATUS_STARTED; else @@ -280,24 +281,24 @@ public: } if (s >= 3) { - p.Do(textStart); - p.Do(textEnd); + Do(p, textStart); + Do(p, textEnd); } if (s >= 4) { - p.Do(libstub); - p.Do(libstubend); + Do(p, libstub); + Do(p, libstubend); } ModuleWaitingThread mwt = {0}; - p.Do(waitingThreads, mwt); + Do(p, waitingThreads, mwt); FuncSymbolExport fsx = {{0}}; - p.Do(exportedFuncs, fsx); + Do(p, exportedFuncs, fsx); FuncSymbolImport fsi = {{0}}; - p.Do(importedFuncs, fsi); + Do(p, importedFuncs, fsi); VarSymbolExport vsx = {{0}}; - p.Do(exportedVars, vsx); + Do(p, exportedVars, vsx); VarSymbolImport vsi = {{0}}; - p.Do(importedVars, vsi); + Do(p, importedVars, vsi); if (p.mode == p.MODE_READ) { // On load state, we re-examine in case our syscall ids changed. @@ -437,8 +438,8 @@ public: if (!s) return; - p.Do(moduleID_); - p.Do(retValAddr); + Do(p, moduleID_); + Do(p, retValAddr); } static PSPAction *Create() { return new AfterModuleEntryCall; @@ -498,11 +499,11 @@ void __KernelModuleDoState(PointerWrap &p) if (!s) return; - p.Do(actionAfterModule); + Do(p, actionAfterModule); __KernelRestoreActionType(actionAfterModule, AfterModuleEntryCall::Create); if (s >= 2) { - p.Do(loadedModules); + Do(p, loadedModules); } if (p.mode == p.MODE_READ) { diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 543afbb3fe..67d0c58e86 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -17,6 +17,8 @@ #include +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Reporting.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" @@ -27,7 +29,6 @@ #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/KernelWaitHelpers.h" -#include "Common/ChunkFile.h" #define SCE_KERNEL_MPA_THFIFO_S 0x0000 #define SCE_KERNEL_MPA_THPRI_S 0x0100 @@ -278,13 +279,13 @@ struct MsgPipe : public KernelObject if (!s) return; - p.Do(nmp); + Do(p, nmp); MsgPipeWaitingThread mpwt1 = {0}, mpwt2 = {0}; - p.Do(sendWaitingThreads, mpwt1); - p.Do(receiveWaitingThreads, mpwt2); - p.Do(pausedSendWaits); - p.Do(pausedReceiveWaits); - p.Do(buffer); + Do(p, sendWaitingThreads, mpwt1); + Do(p, receiveWaitingThreads, mpwt2); + Do(p, pausedSendWaits); + Do(p, pausedReceiveWaits); + Do(p, buffer); } NativeMsgPipe nmp; @@ -662,7 +663,7 @@ void __KernelMsgPipeDoState(PointerWrap &p) if (!s) return; - p.Do(waitTimer); + Do(p, waitTimer); CoreTiming::RestoreRegisterEvent(waitTimer, "MsgPipeTimeout", __KernelMsgPipeTimeout); } diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index fe958ade6d..cafc38d289 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -19,6 +19,7 @@ #include #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" @@ -77,10 +78,10 @@ struct PSPMutex : public KernelObject if (!s) return; - p.Do(nm); + Do(p, nm); SceUID dv = 0; - p.Do(waitingThreads, dv); - p.Do(pausedWaits); + Do(p, waitingThreads, dv); + Do(p, pausedWaits); } NativeMutex nm; @@ -143,10 +144,10 @@ struct LwMutex : public KernelObject if (!s) return; - p.Do(nm); + Do(p, nm); SceUID dv = 0; - p.Do(waitingThreads, dv); - p.Do(pausedWaits); + Do(p, waitingThreads, dv); + Do(p, pausedWaits); } NativeLwMutex nm; @@ -182,11 +183,11 @@ void __KernelMutexDoState(PointerWrap &p) if (!s) return; - p.Do(mutexWaitTimer); + Do(p, mutexWaitTimer); CoreTiming::RestoreRegisterEvent(mutexWaitTimer, "MutexTimeout", __KernelMutexTimeout); - p.Do(lwMutexWaitTimer); + Do(p, lwMutexWaitTimer); CoreTiming::RestoreRegisterEvent(lwMutexWaitTimer, "LwMutexTimeout", __KernelLwMutexTimeout); - p.Do(mutexHeldLocks); + Do(p, mutexHeldLocks); } KernelObject *__KernelMutexObject() diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index fe2f3c6c96..0f81cc43c4 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -16,12 +16,13 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" -#include "Common/ChunkFile.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelSemaphore.h" @@ -69,10 +70,10 @@ struct PSPSemaphore : public KernelObject { if (!s) return; - p.Do(ns); + Do(p, ns); SceUID dv = 0; - p.Do(waitingThreads, dv); - p.Do(pausedWaits); + Do(p, waitingThreads, dv); + Do(p, pausedWaits); } NativeSemaphore ns; @@ -98,7 +99,7 @@ void __KernelSemaDoState(PointerWrap &p) if (!s) return; - p.Do(semaWaitTimer); + Do(p, semaWaitTimer); CoreTiming::RestoreRegisterEvent(semaWaitTimer, "SemaphoreTimeout", __KernelSemaTimeout); } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 29c256b3db..9ff2fcb8d3 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -24,6 +24,8 @@ #include "base/logging.h" #include "Common/LogManager.h" +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/CommonTypes.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" @@ -36,7 +38,6 @@ #include "Core/MemMapHelpers.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/Reporting.h" -#include "Common/ChunkFile.h" #include "Core/HLE/sceAudio.h" #include "Core/HLE/sceKernel.h" @@ -162,14 +163,14 @@ public: if (!s) return; - p.Do(nc); + Do(p, nc); // Saved values were moved to mips call, ignoring here. u32 legacySaved = 0; - p.Do(legacySaved); - p.Do(legacySaved); - p.Do(legacySaved); - p.Do(legacySaved); - p.Do(legacySaved); + Do(p, legacySaved); + Do(p, legacySaved); + Do(p, legacySaved); + Do(p, legacySaved); + Do(p, legacySaved); } NativeCallback nc; @@ -281,8 +282,8 @@ public: if (!s) return; - p.Do(calls_); - p.Do(idGen_); + Do(p, calls_); + Do(p, idGen_); } private: @@ -312,18 +313,18 @@ public: if (!s) return; - p.Do(threadID); - p.Do(status); - p.Do(waitType); - p.Do(waitID); - p.Do(waitInfo); - p.Do(isProcessingCallbacks); - p.Do(currentCallbackId); + Do(p, threadID); + Do(p, status); + Do(p, waitType); + Do(p, waitID); + Do(p, waitInfo); + Do(p, isProcessingCallbacks); + Do(p, currentCallbackId); int chainedActionType = 0; if (chainedAction != NULL) chainedActionType = chainedAction->actionTypeID; - p.Do(chainedActionType); + Do(p, chainedActionType); if (chainedActionType != 0) { @@ -367,7 +368,7 @@ public: if (!s) return; - p.Do(cbId); + Do(p, cbId); } SceUID cbId; @@ -532,15 +533,15 @@ public: if (!s) return; - p.Do(nt); - p.Do(waitInfo); - p.Do(moduleId); - p.Do(isProcessingCallbacks); - p.Do(currentMipscallId); - p.Do(currentCallbackId); + Do(p, nt); + Do(p, waitInfo); + Do(p, moduleId); + Do(p, isProcessingCallbacks); + Do(p, currentMipscallId); + Do(p, currentCallbackId); // TODO: If we want to "version" a DoState method here, we can just use minVer = 0. - p.Do(context); + Do(p, context); if (s <= 3) { @@ -561,16 +562,16 @@ public: if (s <= 4) std::swap(context.hi, context.lo); - p.Do(callbacks); + Do(p, callbacks); - p.Do(pendingMipsCalls); - p.Do(pushedStacks); - p.Do(currentStack); + Do(p, pendingMipsCalls); + Do(p, pushedStacks); + Do(p, currentStack); if (s >= 2) { - p.Do(waitingThreads); - p.Do(pausedWaits); + Do(p, waitingThreads); + Do(p, pausedWaits); } } @@ -695,26 +696,26 @@ void MipsCall::DoState(PointerWrap &p) if (!s) return; - p.Do(entryPoint); - p.Do(cbId); - p.DoArray(args, ARRAY_SIZE(args)); - p.Do(numArgs); + Do(p, entryPoint); + Do(p, cbId); + DoArray(p, args, ARRAY_SIZE(args)); + Do(p, numArgs); // No longer used. u32 legacySavedIdRegister = 0; - p.Do(legacySavedIdRegister); + Do(p, legacySavedIdRegister); u32 legacySavedRa = 0; - p.Do(legacySavedRa); - p.Do(savedPc); - p.Do(savedV0); - p.Do(savedV1); - p.Do(tag); - p.Do(savedId); - p.Do(reschedAfter); + Do(p, legacySavedRa); + Do(p, savedPc); + Do(p, savedV0); + Do(p, savedV1); + Do(p, tag); + Do(p, savedId); + Do(p, reschedAfter); int actionTypeID = 0; if (doAfter != NULL) actionTypeID = doAfter->actionTypeID; - p.Do(actionTypeID); + Do(p, actionTypeID); if (actionTypeID != 0) { if (p.mode == p.MODE_READ) @@ -970,48 +971,48 @@ void __KernelThreadingDoState(PointerWrap &p) if (!s) return; - p.Do(g_inCbCount); - p.Do(currentCallbackThreadID); - p.Do(readyCallbacksCount); - p.Do(idleThreadHackAddr); - p.Do(threadReturnHackAddr); - p.Do(cbReturnHackAddr); - p.Do(intReturnHackAddr); - p.Do(extendReturnHackAddr); - p.Do(moduleReturnHackAddr); + Do(p, g_inCbCount); + Do(p, currentCallbackThreadID); + Do(p, readyCallbacksCount); + Do(p, idleThreadHackAddr); + Do(p, threadReturnHackAddr); + Do(p, cbReturnHackAddr); + Do(p, intReturnHackAddr); + Do(p, extendReturnHackAddr); + Do(p, moduleReturnHackAddr); if (s >= 4) { - p.Do(hleReturnHackAddr); + Do(p, hleReturnHackAddr); } else { hleReturnHackAddr = 0; } - p.Do(currentThread); + Do(p, currentThread); SceUID dv = 0; - p.Do(threadqueue, dv); - p.DoArray(threadIdleID, ARRAY_SIZE(threadIdleID)); - p.Do(dispatchEnabled); + Do(p, threadqueue, dv); + DoArray(p, threadIdleID, ARRAY_SIZE(threadIdleID)); + Do(p, dispatchEnabled); - p.Do(threadReadyQueue); + Do(p, threadReadyQueue); - p.Do(eventScheduledWakeup); + Do(p, eventScheduledWakeup); CoreTiming::RestoreRegisterEvent(eventScheduledWakeup, "ScheduledWakeup", &hleScheduledWakeup); - p.Do(eventThreadEndTimeout); + Do(p, eventThreadEndTimeout); CoreTiming::RestoreRegisterEvent(eventThreadEndTimeout, "ThreadEndTimeout", &hleThreadEndTimeout); - p.Do(actionAfterMipsCall); + Do(p, actionAfterMipsCall); __KernelRestoreActionType(actionAfterMipsCall, ActionAfterMipsCall::Create); - p.Do(actionAfterCallback); + Do(p, actionAfterCallback); __KernelRestoreActionType(actionAfterCallback, ActionAfterCallback::Create); - p.Do(pausedDelays); + Do(p, pausedDelays); __SetCurrentThread(kernelObjects.GetFast(currentThread), currentThread, __KernelGetThreadName(currentThread)); lastSwitchCycles = CoreTiming::GetTicks(); if (s >= 2) - p.Do(threadEventHandlers); + Do(p, threadEventHandlers); if (s >= 3) - p.Do(pendingDeleteThreads); + Do(p, pendingDeleteThreads); } void __KernelThreadingDoStateLate(PointerWrap &p) @@ -3672,7 +3673,7 @@ struct ThreadEventHandler : public KernelObject { if (!s) return; - p.Do(nteh); + Do(p, nteh); } NativeThreadEventHandler nteh; diff --git a/Core/HLE/sceKernelTime.cpp b/Core/HLE/sceKernelTime.cpp index 2e16ba9237..64b454f7e4 100644 --- a/Core/HLE/sceKernelTime.cpp +++ b/Core/HLE/sceKernelTime.cpp @@ -24,6 +24,7 @@ #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/CoreTiming.h" #include "Core/HLE/HLE.h" #include "Core/HLE/sceKernel.h" @@ -48,10 +49,10 @@ void __KernelTimeDoState(PointerWrap &p) return; if (s < 2) { - p.Do(start_time); + Do(p, start_time); } else { u64 t = start_time; - p.Do(t); + Do(p, t); start_time = (time_t)t; } } diff --git a/Core/HLE/sceKernelVTimer.cpp b/Core/HLE/sceKernelVTimer.cpp index 7b5a272358..3a3d4e2be0 100644 --- a/Core/HLE/sceKernelVTimer.cpp +++ b/Core/HLE/sceKernelVTimer.cpp @@ -16,6 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" @@ -24,7 +26,6 @@ #include "Core/HLE/sceKernelMemory.h" #include "Core/HLE/sceKernelVTimer.h" #include "Core/HLE/HLE.h" -#include "Common/ChunkFile.h" static int vtimerTimer = -1; static SceUID runningVTimer = 0; @@ -54,10 +55,10 @@ struct VTimer : public KernelObject { if (!s) return; - p.Do(nvt); + Do(p, nvt); if (s < 2) { u32 memoryPtr; - p.Do(memoryPtr); + Do(p, memoryPtr); } } @@ -192,12 +193,12 @@ void __KernelVTimerDoState(PointerWrap &p) { if (!s) return; - p.Do(vtimerTimer); - p.Do(vtimers); + Do(p, vtimerTimer); + Do(p, vtimers); CoreTiming::RestoreRegisterEvent(vtimerTimer, "VTimer", __KernelTriggerVTimer); if (s >= 2) - p.Do(runningVTimer); + Do(p, runningVTimer); else runningVTimer = 0; } diff --git a/Core/HLE/sceMp3.cpp b/Core/HLE/sceMp3.cpp index 3dab28d418..b94b06dcb2 100644 --- a/Core/HLE/sceMp3.cpp +++ b/Core/HLE/sceMp3.cpp @@ -18,6 +18,7 @@ #include #include +#include "Common/ChunkFileDo.h" #include "Core/Config.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" @@ -70,24 +71,24 @@ public: if (!s) return; - p.Do(mp3StreamStart); - p.Do(mp3StreamEnd); - p.Do(mp3Buf); - p.Do(mp3BufSize); - p.Do(mp3PcmBuf); - p.Do(mp3PcmBufSize); - p.Do(readPosition); - p.Do(bufferRead); - p.Do(bufferWrite); - p.Do(bufferAvailable); - p.Do(mp3DecodedBytes); - p.Do(mp3LoopNum); - p.Do(mp3MaxSamples); - p.Do(mp3SumDecodedSamples); - p.Do(mp3Channels); - p.Do(mp3Bitrate); - p.Do(mp3SamplingRate); - p.Do(mp3Version); + Do(p, mp3StreamStart); + Do(p, mp3StreamEnd); + Do(p, mp3Buf); + Do(p, mp3BufSize); + Do(p, mp3PcmBuf); + Do(p, mp3PcmBufSize); + Do(p, readPosition); + Do(p, bufferRead); + Do(p, bufferWrite); + Do(p, bufferAvailable); + Do(p, mp3DecodedBytes); + Do(p, mp3LoopNum); + Do(p, mp3MaxSamples); + Do(p, mp3SumDecodedSamples); + Do(p, mp3Channels); + Do(p, mp3Bitrate); + Do(p, mp3SamplingRate); + Do(p, mp3Version); }; }; @@ -114,10 +115,10 @@ void __Mp3DoState(PointerWrap &p) { return; if (s >= 2) { - p.Do(mp3Map); + Do(p, mp3Map); } else { std::map mp3Map_old; - p.Do(mp3Map_old); // read old map + Do(p, mp3Map_old); // read old map for (auto it = mp3Map_old.begin(), end = mp3Map_old.end(); it != end; ++it) { auto mp3 = new AuCtx; u32 id = it->first; @@ -147,7 +148,7 @@ void __Mp3DoState(PointerWrap &p) { } if (s >= 3) { - p.Do(resourceInited); + Do(p, resourceInited); } else { // Previous behavior acted as if it was already inited. resourceInited = true; diff --git a/Core/HLE/sceMp4.cpp b/Core/HLE/sceMp4.cpp index ca2c3d3e11..0bbf4edaa8 100644 --- a/Core/HLE/sceMp4.cpp +++ b/Core/HLE/sceMp4.cpp @@ -17,6 +17,7 @@ #include +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/Reporting.h" @@ -43,7 +44,7 @@ void __AACDoState(PointerWrap &p) { if (!s) return; - p.Do(aacMap); + Do(p, aacMap); } static u32 sceMp4Init() diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 37a3ae9ede..8a79a786f2 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -20,6 +20,7 @@ #include #include +#include "Common/ChunkFileDo.h" #include "Common/Swap.h" #include "Core/HLE/sceMpeg.h" #include "Core/HLE/sceKernelModule.h" @@ -176,35 +177,35 @@ struct MpegContext { if (!s) return; - p.DoArray(mpegheader, 2048); - p.Do(defaultFrameWidth); - p.Do(videoFrameCount); - p.Do(audioFrameCount); - p.Do(endOfAudioReached); - p.Do(endOfVideoReached); - p.Do(videoPixelMode); - p.Do(mpegMagic); - p.Do(mpegVersion); - p.Do(mpegRawVersion); - p.Do(mpegOffset); - p.Do(mpegStreamSize); - p.Do(mpegFirstTimestamp); - p.Do(mpegLastTimestamp); - p.Do(mpegFirstDate); - p.Do(mpegLastDate); - p.Do(mpegRingbufferAddr); - p.DoArray(esBuffers, MPEG_DATA_ES_BUFFERS); - p.Do(avc); - p.Do(avcRegistered); - p.Do(atracRegistered); - p.Do(pcmRegistered); - p.Do(dataRegistered); - p.Do(ignoreAtrac); - p.Do(ignorePcm); - p.Do(ignoreAvc); - p.Do(isAnalyzed); - p.Do(streamMap); - p.DoClass(mediaengine); + DoArray(p, mpegheader, 2048); + Do(p, defaultFrameWidth); + Do(p, videoFrameCount); + Do(p, audioFrameCount); + Do(p, endOfAudioReached); + Do(p, endOfVideoReached); + Do(p, videoPixelMode); + Do(p, mpegMagic); + Do(p, mpegVersion); + Do(p, mpegRawVersion); + Do(p, mpegOffset); + Do(p, mpegStreamSize); + Do(p, mpegFirstTimestamp); + Do(p, mpegLastTimestamp); + Do(p, mpegFirstDate); + Do(p, mpegLastDate); + Do(p, mpegRingbufferAddr); + DoArray(p, esBuffers, MPEG_DATA_ES_BUFFERS); + Do(p, avc); + Do(p, avcRegistered); + Do(p, atracRegistered); + Do(p, pcmRegistered); + Do(p, dataRegistered); + Do(p, ignoreAtrac); + Do(p, ignorePcm); + Do(p, ignoreAvc); + Do(p, isAnalyzed); + Do(p, streamMap); + DoClass(p, mediaengine); ringbufferNeedsReverse = s < 2; } @@ -365,7 +366,7 @@ public: if (!s) return; - p.Do(ringAddr_); + Do(p, ringAddr_); } void run(MipsCall &call) override; private: @@ -392,20 +393,20 @@ void __MpegDoState(PointerWrap &p) { if (s < 2) { int oldLastMpeg = -1; bool oldIsMpegAnalyzed = false; - p.Do(oldLastMpeg); - p.Do(streamIdGen); - p.Do(oldIsMpegAnalyzed); + Do(p, oldLastMpeg); + Do(p, streamIdGen); + Do(p, oldIsMpegAnalyzed); // Let's assume the oldest version. mpegLibVersion = 0x0101; } else { - p.Do(streamIdGen); - p.Do(mpegLibVersion); + Do(p, streamIdGen); + Do(p, mpegLibVersion); } - p.Do(isMpegInit); - p.Do(actionPostPut); + Do(p, isMpegInit); + Do(p, actionPostPut); __KernelRestoreActionType(actionPostPut, PostPutAction::Create); - p.Do(mpegMap); + Do(p, mpegMap); } void __MpegShutdown() { @@ -1054,8 +1055,8 @@ void __VideoPmpDoState(PointerWrap &p){ return; } - p.Do(pmp_videoSource); - p.Do(pmp_nBlocks); + Do(p, pmp_videoSource); + Do(p, pmp_nBlocks); if (p.mode == PointerWrap::MODE_READ){ // for loadstate, we will reinitialize the pmp codec __VideoPmpShutdown(); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index f307275835..e3936c4841 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -26,6 +26,7 @@ #include "util/text/parsers.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernelMemory.h" @@ -73,6 +74,28 @@ u32 Net_Term(); int NetApctl_Term(); void NetApctl_InitInfo(); +void AfterApctlMipsCall::DoState(PointerWrap & p) { + auto s = p.Section("AfterApctlMipsCall", 1, 1); + if (!s) + return; + // Just in case there are "s" corruption in the future where s.ver is a negative number + if (s >= 1) { + Do(p, handlerID); + Do(p, oldState); + Do(p, newState); + Do(p, event); + Do(p, error); + Do(p, argsAddr); + } else { + handlerID = -1; + oldState = 0; + newState = 0; + event = 0; + error = 0; + argsAddr = 0; + } +} + void AfterApctlMipsCall::run(MipsCall& call) { u32 v0 = currentMIPS->r[MIPS_REG_V0]; DEBUG_LOG(SCENET, "AfterApctlMipsCall::run [ID=%i][OldState=%d][NewState=%d][Event=%d][Error=%d][ArgsPtr=%08x] [cbId: %u][retV0: %08x]", handlerID, oldState, newState, event, error, argsAddr, call.cbId, v0); @@ -221,34 +244,34 @@ void __NetDoState(PointerWrap &p) { auto cur_netInetInited = netInetInited; auto cur_netApctlInited = netApctlInited; - p.Do(netInited); - p.Do(netInetInited); - p.Do(netApctlInited); - p.Do(apctlHandlers); - p.Do(netMallocStat); + Do(p, netInited); + Do(p, netInetInited); + Do(p, netApctlInited); + Do(p, apctlHandlers); + Do(p, netMallocStat); if (s < 2) { netDropRate = 0; netDropDuration = 0; } else { - p.Do(netDropRate); - p.Do(netDropDuration); + Do(p, netDropRate); + Do(p, netDropDuration); } if (s < 3) { netPoolAddr = 0; netThread1Addr = 0; netThread2Addr = 0; } else { - p.Do(netPoolAddr); - p.Do(netThread1Addr); - p.Do(netThread2Addr); + Do(p, netPoolAddr); + Do(p, netThread1Addr); + Do(p, netThread2Addr); } if (s >= 4) { - p.Do(netApctlState); - p.Do(netApctlInfo); - p.Do(actionAfterApctlMipsCall); + Do(p, netApctlState); + Do(p, netApctlInfo); + Do(p, actionAfterApctlMipsCall); __KernelRestoreActionType(actionAfterApctlMipsCall, AfterApctlMipsCall::Create); - p.Do(apctlThreadHackAddr); - p.Do(apctlThreadID); + Do(p, apctlThreadHackAddr); + Do(p, apctlThreadID); } else { actionAfterApctlMipsCall = -1; diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index 1ca82af0d5..73f4566eb9 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -204,28 +204,7 @@ class AfterApctlMipsCall : public PSPAction { public: AfterApctlMipsCall() {} static PSPAction* Create() { return new AfterApctlMipsCall(); } - void DoState(PointerWrap& p) override { - auto s = p.Section("AfterApctlMipsCall", 1, 1); - if (!s) - return; - // Just in case there are "s" corruption in the future where s.ver is a negative number - if (s >= 1) { - p.Do(handlerID); - p.Do(oldState); - p.Do(newState); - p.Do(event); - p.Do(error); - p.Do(argsAddr); - } - else { - handlerID = -1; - oldState = 0; - newState = 0; - event = 0; - error = 0; - argsAddr = 0; - } - } + void DoState(PointerWrap& p) override; void run(MipsCall& call) override; void SetData(int HandlerID, int OldState, int NewState, int Event, int Error, u32_le ArgsAddr); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 87f7075025..54562f0dd2 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -29,6 +29,7 @@ #include "Core/Host.h" #include "Core/MemMapHelpers.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/Util/PortManager.h" @@ -119,34 +120,34 @@ void __NetAdhocDoState(PointerWrap &p) { auto cur_netAdhocctlInited = netAdhocctlInited; auto cur_netAdhocMatchingInited = netAdhocMatchingInited; - p.Do(netAdhocInited); - p.Do(netAdhocctlInited); - p.Do(netAdhocMatchingInited); - p.Do(adhocctlHandlers); + Do(p, netAdhocInited); + Do(p, netAdhocctlInited); + Do(p, netAdhocMatchingInited); + Do(p, adhocctlHandlers); if (s >= 2) { - p.Do(actionAfterMatchingMipsCall); + Do(p, actionAfterMatchingMipsCall); __KernelRestoreActionType(actionAfterMatchingMipsCall, AfterMatchingMipsCall::Create); - p.Do(dummyThreadHackAddr); + Do(p, dummyThreadHackAddr); } else { actionAfterMatchingMipsCall = -1; dummyThreadHackAddr = 0; } if (s >= 3) { - p.Do(actionAfterAdhocMipsCall); + Do(p, actionAfterAdhocMipsCall); __KernelRestoreActionType(actionAfterAdhocMipsCall, AfterAdhocMipsCall::Create); - p.Do(matchingThreadHackAddr); + Do(p, matchingThreadHackAddr); } else { actionAfterAdhocMipsCall = -1; matchingThreadHackAddr = 0; } if (s >= 4) { - p.Do(threadAdhocID); - p.Do(matchingThreads); + Do(p, threadAdhocID); + Do(p, matchingThreads); } else { threadAdhocID = 0; diff --git a/Core/HLE/scePower.cpp b/Core/HLE/scePower.cpp index b4fe3b0925..610e21234f 100644 --- a/Core/HLE/scePower.cpp +++ b/Core/HLE/scePower.cpp @@ -17,6 +17,7 @@ #include #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/CoreTiming.h" @@ -132,8 +133,8 @@ void __PowerDoState(PointerWrap &p) { return; if (s >= 2) { - p.Do(RealpllFreq); - p.Do(RealbusFreq); + Do(p, RealpllFreq); + Do(p, RealbusFreq); if (RealpllFreq < 1000000) RealpllFreq = PowerPllMhzToHz(RealpllFreq); @@ -151,9 +152,9 @@ void __PowerDoState(PointerWrap &p) { pllFreq = RealpllFreq; busFreq = RealbusFreq; } - p.DoArray(powerCbSlots, ARRAY_SIZE(powerCbSlots)); - p.Do(volatileMemLocked); - p.Do(volatileWaitingThreads); + DoArray(p, powerCbSlots, ARRAY_SIZE(powerCbSlots)); + Do(p, volatileMemLocked); + Do(p, volatileWaitingThreads); } static int scePowerGetBatteryLifePercent() { diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index f89fa524dd..74c4f7242a 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" #include "Core/System.h" @@ -334,13 +335,13 @@ public: if (!s) return; - p.Do(type_); - p.Do(channel_); + Do(p, type_); + Do(p, channel_); if (s >= 2) { - p.Do(videoWidth_); - p.Do(videoHeight_); - p.Do(audioChannels_); - p.Do(audioFrequency_); + Do(p, videoWidth_); + Do(p, videoHeight_); + Do(p, audioChannels_); + Do(p, audioFrequency_); } } @@ -440,38 +441,38 @@ void Psmf::DoState(PointerWrap &p) { if (!s) return; - p.Do(magic); - p.Do(version); - p.Do(streamOffset); - p.Do(streamSize); - p.Do(headerOffset); - p.Do(streamDataTotalSize); - p.Do(presentationStartTime); - p.Do(presentationEndTime); - p.Do(streamDataNextBlockSize); - p.Do(streamDataNextInnerBlockSize); - p.Do(numStreams); + Do(p, magic); + Do(p, version); + Do(p, streamOffset); + Do(p, streamSize); + Do(p, headerOffset); + Do(p, streamDataTotalSize); + Do(p, presentationStartTime); + Do(p, presentationEndTime); + Do(p, streamDataNextBlockSize); + Do(p, streamDataNextInnerBlockSize); + Do(p, numStreams); - p.Do(currentStreamNum); + Do(p, currentStreamNum); int legacyStreamNums = 0; - p.Do(legacyStreamNums); - p.Do(legacyStreamNums); + Do(p, legacyStreamNums); + Do(p, legacyStreamNums); - p.Do(EPMapOffset); - p.Do(EPMapEntriesNum); - p.Do(videoWidth); - p.Do(videoHeight); - p.Do(audioChannels); - p.Do(audioFrequency); + Do(p, EPMapOffset); + Do(p, EPMapEntriesNum); + Do(p, videoWidth); + Do(p, videoHeight); + Do(p, audioChannels); + Do(p, audioFrequency); if (s >= 2) { - p.Do(EPMap); + Do(p, EPMap); } - p.Do(streamMap); + Do(p, streamMap); if (s >= 3) { - p.Do(currentStreamType); - p.Do(currentStreamChannel); + Do(p, currentStreamType); + Do(p, currentStreamChannel); } else { currentStreamType = -1; currentStreamChannel = -1; @@ -488,65 +489,65 @@ void PsmfPlayer::DoState(PointerWrap &p) { if (!s) return; - p.Do(videoCodec); - p.Do(videoStreamNum); - p.Do(audioCodec); - p.Do(audioStreamNum); - p.Do(playMode); - p.Do(playSpeed); + Do(p, videoCodec); + Do(p, videoStreamNum); + Do(p, audioCodec); + Do(p, audioStreamNum); + Do(p, playMode); + Do(p, playSpeed); - p.Do(displayBuffer); - p.Do(displayBufferSize); - p.Do(playbackThreadPriority); + Do(p, displayBuffer); + Do(p, displayBufferSize); + Do(p, playbackThreadPriority); int oldMaxAheadTimestamp = 0; - p.Do(oldMaxAheadTimestamp); + Do(p, oldMaxAheadTimestamp); if (s >= 4) { - p.Do(totalDurationTimestamp); + Do(p, totalDurationTimestamp); } else { long oldTimestamp; - p.Do(oldTimestamp); + Do(p, oldTimestamp); totalDurationTimestamp = oldTimestamp; } if (s >= 2) { - p.Do(totalVideoStreams); - p.Do(totalAudioStreams); - p.Do(playerVersion); + Do(p, totalVideoStreams); + Do(p, totalAudioStreams); + Do(p, playerVersion); } else { totalVideoStreams = 1; totalAudioStreams = 1; playerVersion = PSMF_PLAYER_VERSION_FULL; } if (s >= 3) { - p.Do(videoStep); + Do(p, videoStep); } else { videoStep = 0; } if (s >= 4) { - p.Do(warmUp); + Do(p, warmUp); } else { warmUp = 10000; } if (s >= 5) { - p.Do(seekDestTimeStamp); + Do(p, seekDestTimeStamp); } else { seekDestTimeStamp = 0; } - p.DoClass(mediaengine); - p.Do(filehandle); - p.Do(fileoffset); - p.Do(readSize); - p.Do(streamSize); + DoClass(p, mediaengine); + Do(p, filehandle); + Do(p, fileoffset); + Do(p, readSize); + Do(p, streamSize); - p.Do(status); + Do(p, status); if (s >= 4) { - p.Do(psmfPlayerAtracAu); + Do(p, psmfPlayerAtracAu); } - p.Do(psmfPlayerAvcAu); + Do(p, psmfPlayerAvcAu); if (s >= 7) { bool hasFinishThread = finishThread != nullptr; - p.Do(hasFinishThread); + Do(p, hasFinishThread); if (hasFinishThread) { - p.Do(finishThread); + Do(p, finishThread); } else { if (finishThread) finishThread->Forget(); @@ -554,7 +555,7 @@ void PsmfPlayer::DoState(PointerWrap &p) { finishThread = nullptr; } } else if (s >= 6) { - p.Do(finishThread); + Do(p, finishThread); } else { if (finishThread) finishThread->Forget(); @@ -563,8 +564,8 @@ void PsmfPlayer::DoState(PointerWrap &p) { } if (s >= 8) { - p.Do(videoWidth); - p.Do(videoHeight); + Do(p, videoWidth); + Do(p, videoHeight); } } @@ -679,7 +680,7 @@ void __PsmfDoState(PointerWrap &p) { if (!s) return; - p.Do(psmfMap); + Do(p, psmfMap); } void __PsmfPlayerDoState(PointerWrap &p) { @@ -687,11 +688,11 @@ void __PsmfPlayerDoState(PointerWrap &p) { if (!s) return; - p.Do(psmfPlayerMap); - p.Do(videoPixelMode); - p.Do(videoLoopStatus); + Do(p, psmfPlayerMap); + Do(p, videoPixelMode); + Do(p, videoLoopStatus); if (s >= 2) { - p.Do(psmfPlayerLibVersion); + Do(p, psmfPlayerLibVersion); } else { // Assume the latest, which is what we were emulating before. psmfPlayerLibVersion = 0x06060010; diff --git a/Core/HLE/sceRtc.cpp b/Core/HLE/sceRtc.cpp index 75e9e3ef3b..eb19ce95b2 100644 --- a/Core/HLE/sceRtc.cpp +++ b/Core/HLE/sceRtc.cpp @@ -27,6 +27,7 @@ #include "base/timeutil.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" @@ -167,7 +168,7 @@ void __RtcDoState(PointerWrap &p) if (!s) return; - p.Do(rtcBaseTime); + Do(p, rtcBaseTime); // Update the precalc, pointless to savestate this as it's just based on the other value. RtcUpdateBaseTicks(); } diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index 778708e65d..0e5f95f65e 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -35,6 +35,7 @@ #include "base/basictypes.h" #include "profiler/profiler.h" #include "thread/threadutil.h" +#include "Common/ChunkFileDo.h" #include "Common/Log.h" #include "Core/Config.h" #include "Core/CoreTiming.h" @@ -204,10 +205,10 @@ void __SasDoState(PointerWrap &p) { __SasDrain(); } - p.DoClass(sas); + DoClass(p, sas); if (s >= 2) { - p.Do(sasMixEvent); + Do(p, sasMixEvent); } else { sasMixEvent = -1; __SasDisableThread(); diff --git a/Core/HLE/sceSsl.cpp b/Core/HLE/sceSsl.cpp index 2fa138cb78..65efc6cde4 100644 --- a/Core/HLE/sceSsl.cpp +++ b/Core/HLE/sceSsl.cpp @@ -15,11 +15,11 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MemMap.h" -#include "Common/ChunkFile.h" - #include "Core/HLE/sceSsl.h" #define ERROR_SSL_NOT_INIT 0x80435001; @@ -44,9 +44,9 @@ void __SslDoState(PointerWrap &p) if (!s) return; - p.Do(isSslInit); - p.Do(maxMemSize); - p.Do(currentMemSize); + Do(p, isSslInit); + Do(p, maxMemSize); + Do(p, currentMemSize); } static int sceSslInit(int heapSize) @@ -127,4 +127,4 @@ const HLEFunction sceSsl[] = void Register_sceSsl() { RegisterModule("sceSsl", ARRAY_SIZE(sceSsl), sceSsl); -} \ No newline at end of file +} diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index a93fa7f977..12c8a53a1b 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -20,6 +20,7 @@ #include "file/file_util.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Loaders.h" #include "Core/MemMap.h" #include "Core/System.h" @@ -87,26 +88,26 @@ void __UmdDoState(PointerWrap &p) if (!s) return; - p.Do(umdActivated); - p.Do(umdStatus); - p.Do(umdErrorStat); - p.Do(driveCBId); - p.Do(umdStatTimeoutEvent); + Do(p, umdActivated); + Do(p, umdStatus); + Do(p, umdErrorStat); + Do(p, driveCBId); + Do(p, umdStatTimeoutEvent); CoreTiming::RestoreRegisterEvent(umdStatTimeoutEvent, "UmdTimeout", __UmdStatTimeout); - p.Do(umdStatChangeEvent); + Do(p, umdStatChangeEvent); CoreTiming::RestoreRegisterEvent(umdStatChangeEvent, "UmdChange", __UmdStatChange); - p.Do(umdWaitingThreads); - p.Do(umdPausedWaits); + Do(p, umdWaitingThreads); + Do(p, umdPausedWaits); if (s > 1) { - p.Do(UMDReplacePermit); + Do(p, UMDReplacePermit); if (UMDReplacePermit) host->UpdateUI(); } if (s > 2) { - p.Do(umdInsertChangeEvent); + Do(p, umdInsertChangeEvent); CoreTiming::RestoreRegisterEvent(umdInsertChangeEvent, "UmdInsertChange", __UmdInsertChange); - p.Do(UMDInserted); + Do(p, UMDInserted); } else UMDInserted = true; diff --git a/Core/HLE/sceUsb.cpp b/Core/HLE/sceUsb.cpp index c29ef6e6b2..6300be0118 100644 --- a/Core/HLE/sceUsb.cpp +++ b/Core/HLE/sceUsb.cpp @@ -16,11 +16,12 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "base/NativeApp.h" +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" -#include "Common/ChunkFile.h" #include "Core/HLE/sceUsb.h" // TODO: Map by driver name @@ -53,13 +54,13 @@ void __UsbDoState(PointerWrap &p) return; if (s >= 2) { - p.Do(usbStarted); - p.Do(usbConnected); + Do(p, usbStarted); + Do(p, usbConnected); } else { usbStarted = false; usbConnected = true; } - p.Do(usbActivated); + Do(p, usbActivated); } static int sceUsbStart(const char* driverName, u32 argsSize, u32 argsPtr) { diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index a5c4653335..751952dbb9 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -21,6 +21,7 @@ #include "base/NativeApp.h" #include "ppsspp_config.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/sceUsbCam.h" #include "Core/HLE/sceUsbMic.h" @@ -62,7 +63,7 @@ void __UsbCamDoState(PointerWrap &p) { return; } - p.Do(*config); + Do(p, *config); if (config->mode == Camera::Mode::Video) { // stillImage? TBD Camera::stopCapture(); Camera::startCapture(); diff --git a/Core/HLE/sceUsbGps.cpp b/Core/HLE/sceUsbGps.cpp index 05b16e5b3d..b7e1be9902 100644 --- a/Core/HLE/sceUsbGps.cpp +++ b/Core/HLE/sceUsbGps.cpp @@ -17,6 +17,7 @@ #include "base/NativeApp.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceUsbGps.h" @@ -40,7 +41,7 @@ void __UsbGpsDoState(PointerWrap &p) { if (!s) return; - p.Do(gpsStatus); + Do(p, gpsStatus); } void __UsbGpsShutdown() { diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 788529e679..9f165ed064 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -19,6 +19,7 @@ #include "base/NativeApp.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernelThread.h" @@ -122,12 +123,12 @@ void __UsbMicDoState(PointerWrap &p) { if (!s) { return; } - p.Do(numNeedSamples); - p.Do(waitingThreads); - p.Do(isNeedInput); - p.Do(curSampleRate); - p.Do(curChannels); - p.Do(micState); + Do(p, numNeedSamples); + Do(p, waitingThreads); + Do(p, isNeedInput); + Do(p, curSampleRate); + Do(p, curChannels); + Do(p, micState); // Maybe also need to save the state of audioBuf. if (waitingThreads.size() != 0 && p.mode == PointerWrap::MODE_READ) { u64 waitTimeus = (waitingThreads[0].needSize - Microphone::availableAudioBufSize()) * 1000000 / 2 / waitingThreads[0].sampleRate; diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 4838013dc4..d1a13e1fc2 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -21,6 +21,7 @@ #include "file/ini_file.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" @@ -153,8 +154,8 @@ void __UtilityDoState(PointerWrap &p) { return; } - p.Do(currentDialogType); - p.Do(currentDialogActive); + Do(p, currentDialogType); + Do(p, currentDialogActive); saveDialog.DoState(p); msgDialog.DoState(p); oskDialog.DoState(p); @@ -163,10 +164,10 @@ void __UtilityDoState(PointerWrap &p) { gamedataInstallDialog.DoState(p); if (s >= 2) { - p.Do(currentlyLoadedModules); + Do(p, currentlyLoadedModules); } else { std::set oldModules; - p.Do(oldModules); + Do(p, oldModules); for (auto it = oldModules.begin(), end = oldModules.end(); it != end; ++it) { currentlyLoadedModules[*it] = 0; } diff --git a/Core/HLE/sceVaudio.cpp b/Core/HLE/sceVaudio.cpp index e3749d0680..de617a78b4 100644 --- a/Core/HLE/sceVaudio.cpp +++ b/Core/HLE/sceVaudio.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Reporting.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" @@ -36,7 +37,7 @@ void __VaudioDoState(PointerWrap &p) { if (!s) return; - p.Do(vaudioReserved); + Do(p, vaudioReserved); } static u32 sceVaudioChReserve(int sampleCount, int freq, int format) { diff --git a/Core/HW/AsyncIOManager.cpp b/Core/HW/AsyncIOManager.cpp index b2a99805e4..98a15f5c48 100644 --- a/Core/HW/AsyncIOManager.cpp +++ b/Core/HW/AsyncIOManager.cpp @@ -19,6 +19,7 @@ #include #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "Core/System.h" @@ -153,12 +154,12 @@ void AsyncIOManager::DoState(PointerWrap &p) { SyncThread(); std::lock_guard guard(resultsLock_); - p.Do(resultsPending_); + Do(p, resultsPending_); if (s >= 2) { - p.Do(results_); + Do(p, results_); } else { std::map oldResults; - p.Do(oldResults); + Do(p, oldResults); for (auto it = oldResults.begin(), end = oldResults.end(); it != end; ++it) { results_[it->first] = AsyncIOResult(it->second); } diff --git a/Core/HW/AsyncIOManager.h b/Core/HW/AsyncIOManager.h index 6bb9be5039..4b1e0b5276 100644 --- a/Core/HW/AsyncIOManager.h +++ b/Core/HW/AsyncIOManager.h @@ -61,10 +61,10 @@ struct AsyncIOResult { if (!s) return; - p.Do(result); - p.Do(finishTicks); + Do(p, result); + Do(p, finishTicks); if (s >= 2) { - p.Do(invalidateAddr); + Do(p, invalidateAddr); } else { invalidateAddr = 0; } diff --git a/Core/HW/BufferQueue.cpp b/Core/HW/BufferQueue.cpp new file mode 100644 index 0000000000..14ece774e1 --- /dev/null +++ b/Core/HW/BufferQueue.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2013- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "Common/ChunkFileDo.h" +#include "Core/HW/BufferQueue.h" + +void BufferQueue::DoState(PointerWrap &p) { + auto s = p.Section("BufferQueue", 0, 1); + + Do(p, bufQueueSize); + Do(p, start); + Do(p, end); + if (bufQueue) { + DoArray(p, bufQueue, bufQueueSize); + } + + if (s >= 1) { + Do(p, ptsMarks); + } +} diff --git a/Core/HW/BufferQueue.h b/Core/HW/BufferQueue.h index 79e7072f19..b69782e985 100644 --- a/Core/HW/BufferQueue.h +++ b/Core/HW/BufferQueue.h @@ -124,20 +124,7 @@ struct BufferQueue { return bytesgot; } - void DoState(PointerWrap &p) { - auto s = p.Section("BufferQueue", 0, 1); - - p.Do(bufQueueSize); - p.Do(start); - p.Do(end); - if (bufQueue) { - p.DoArray(bufQueue, bufQueueSize); - } - - if (s >= 1) { - p.Do(ptsMarks); - } - } + void DoState(PointerWrap &p); private: void savePts(u64 pts) { diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 1f8113f011..83735a02ce 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/ChunkFileDo.h" #include "Core/Config.h" #include "Core/Debugger/Breakpoints.h" #include "Core/HW/MediaEngine.h" @@ -172,25 +173,25 @@ void MediaEngine::DoState(PointerWrap &p) { if (!s) return; - p.Do(m_videoStream); - p.Do(m_audioStream); + Do(p, m_videoStream); + Do(p, m_audioStream); - p.DoArray(m_mpegheader, sizeof(m_mpegheader)); + DoArray(p, m_mpegheader, sizeof(m_mpegheader)); if (s >= 4) { - p.Do(m_mpegheaderSize); + Do(p, m_mpegheaderSize); } else { m_mpegheaderSize = sizeof(m_mpegheader); } if (s >= 5) { - p.Do(m_mpegheaderReadPos); + Do(p, m_mpegheaderReadPos); } else { m_mpegheaderReadPos = m_mpegheaderSize; } - p.Do(m_ringbuffersize); + Do(p, m_ringbuffersize); u32 hasloadStream = m_pdata != NULL; - p.Do(hasloadStream); + Do(p, hasloadStream); if (hasloadStream && p.mode == p.MODE_READ) reloadStream(); #ifdef USE_FFMPEG @@ -198,29 +199,29 @@ void MediaEngine::DoState(PointerWrap &p) { #else u32 hasopencontext = false; #endif - p.Do(hasopencontext); + Do(p, hasopencontext); if (m_pdata) m_pdata->DoState(p); if (m_demux) m_demux->DoState(p); - p.Do(m_videopts); - p.Do(m_audiopts); + Do(p, m_videopts); + Do(p, m_audiopts); if (s >= 2) { - p.Do(m_firstTimeStamp); - p.Do(m_lastTimeStamp); + Do(p, m_firstTimeStamp); + Do(p, m_lastTimeStamp); } if (hasopencontext && p.mode == p.MODE_READ) { openContext(true); } - p.Do(m_isVideoEnd); + Do(p, m_isVideoEnd); bool noAudioDataRemoved; - p.Do(noAudioDataRemoved); + Do(p, noAudioDataRemoved); if (s >= 3) { - p.Do(m_audioType); + Do(p, m_audioType); } else { m_audioType = PSP_CODEC_AT3PLUS; } diff --git a/Core/HW/MemoryStick.cpp b/Core/HW/MemoryStick.cpp index 42bc625bdb..d04f116508 100644 --- a/Core/HW/MemoryStick.cpp +++ b/Core/HW/MemoryStick.cpp @@ -1,4 +1,5 @@ #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/CoreTiming.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/HW/MemoryStick.h" @@ -16,15 +17,15 @@ void MemoryStick_DoState(PointerWrap &p) { if (!s) return; - p.Do(memStickState); - p.Do(memStickFatState); + Do(p, memStickState); + Do(p, memStickFatState); if (s >= 2) - p.Do(memStickSize); + Do(p, memStickSize); else memStickSize = 1ULL * 1024 * 1024 * 1024; if (s >= 3) { - p.Do(memStickNeedsAssign); - p.Do(memStickInsertedAt); + Do(p, memStickNeedsAssign); + Do(p, memStickInsertedAt); } } diff --git a/Core/HW/MpegDemux.cpp b/Core/HW/MpegDemux.cpp index 7b51c6b68a..d65db8d4cf 100644 --- a/Core/HW/MpegDemux.cpp +++ b/Core/HW/MpegDemux.cpp @@ -1,4 +1,5 @@ -#include "MpegDemux.h" +#include "Common/ChunkFileDo.h" +#include "Core/HW/MpegDemux.h" #include "Core/Reporting.h" const int PACKET_START_CODE_MASK = 0xffffff00; @@ -37,13 +38,13 @@ void MpegDemux::DoState(PointerWrap &p) { if (!s) return; - p.Do(m_index); - p.Do(m_len); - p.Do(m_audioChannel); - p.Do(m_readSize); + Do(p, m_index); + Do(p, m_len); + Do(p, m_audioChannel); + Do(p, m_readSize); if (m_buf) - p.DoArray(m_buf, m_len); - p.DoClass(m_audioStream); + DoArray(p, m_buf, m_len); + DoClass(p, m_audioStream); } bool MpegDemux::addStreamData(const u8 *buf, int addSize) { diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index e36bdd1c1b..7cb6db52d0 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -20,6 +20,7 @@ #include "base/basictypes.h" #include "profiler/profiler.h" +#include "Common/ChunkFileDo.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/sceAtrac.h" #include "Core/Config.h" @@ -159,28 +160,28 @@ void VagDecoder::DoState(PointerWrap &p) { return; if (s >= 2) { - p.DoArray(samples, ARRAY_SIZE(samples)); + DoArray(p, samples, ARRAY_SIZE(samples)); } else { int samplesOld[ARRAY_SIZE(samples)]; - p.DoArray(samplesOld, ARRAY_SIZE(samples)); + DoArray(p, samplesOld, ARRAY_SIZE(samples)); for (size_t i = 0; i < ARRAY_SIZE(samples); ++i) { samples[i] = samplesOld[i]; } } - p.Do(curSample); + Do(p, curSample); - p.Do(data_); - p.Do(read_); - p.Do(curBlock_); - p.Do(loopStartBlock_); - p.Do(numBlocks_); + Do(p, data_); + Do(p, read_); + Do(p, curBlock_); + Do(p, loopStartBlock_); + Do(p, numBlocks_); - p.Do(s_1); - p.Do(s_2); + Do(p, s_1); + Do(p, s_2); - p.Do(loopEnabled_); - p.Do(loopAtNextBlock_); - p.Do(end_); + Do(p, loopEnabled_); + Do(p, loopAtNextBlock_); + Do(p, end_); } int SasAtrac3::setContext(u32 context) { @@ -226,13 +227,13 @@ void SasAtrac3::DoState(PointerWrap &p) { if (!s) return; - p.Do(contextAddr_); - p.Do(atracID_); + Do(p, contextAddr_); + Do(p, atracID_); if (p.mode == p.MODE_READ && atracID_ >= 0 && !sampleQueue_) { sampleQueue_ = new BufferQueue(); } if (s >= 2) { - p.Do(end_); + Do(p, end_); } } @@ -692,7 +693,7 @@ void SasInstance::DoState(PointerWrap &p) { if (!s) return; - p.Do(grainSize); + Do(p, grainSize); if (p.mode == p.MODE_READ) { if (grainSize > 0) { SetGrainSize(grainSize); @@ -701,32 +702,32 @@ void SasInstance::DoState(PointerWrap &p) { } } - p.Do(maxVoices); - p.Do(sampleRate); - p.Do(outputMode); + Do(p, maxVoices); + Do(p, sampleRate); + Do(p, outputMode); // SetGrainSize() / ClearGrainSize() should've made our buffers match. if (mixBuffer != NULL && grainSize > 0) { - p.DoArray(mixBuffer, grainSize * 2); + DoArray(p, mixBuffer, grainSize * 2); } if (sendBuffer != NULL && grainSize > 0) { - p.DoArray(sendBuffer, grainSize * 2); + DoArray(p, sendBuffer, grainSize * 2); } if (sendBuffer != NULL && grainSize > 0) { // Backwards compat int16_t *resampleBuf = new int16_t[grainSize * 4 + 3](); - p.DoArray(resampleBuf, grainSize * 4 + 3); + DoArray(p, resampleBuf, grainSize * 4 + 3); delete[] resampleBuf; } int n = PSP_SAS_VOICES_MAX; - p.Do(n); + Do(p, n); if (n != PSP_SAS_VOICES_MAX) { ERROR_LOG(SAVESTATE, "Wrong number of SAS voices"); return; } - p.DoArray(voices, ARRAY_SIZE(voices)); - p.Do(waveformEffect); + DoArray(p, voices, ARRAY_SIZE(voices)); + Do(p, waveformEffect); if (p.mode == p.MODE_READ) { reverb_.SetPreset(waveformEffect.type); } @@ -776,45 +777,45 @@ void SasVoice::DoState(PointerWrap &p) { if (!s) return; - p.Do(playing); - p.Do(paused); - p.Do(on); + Do(p, playing); + Do(p, paused); + Do(p, on); - p.Do(type); + Do(p, type); - p.Do(vagAddr); - p.Do(vagSize); - p.Do(pcmAddr); - p.Do(pcmSize); - p.Do(pcmIndex); + Do(p, vagAddr); + Do(p, vagSize); + Do(p, pcmAddr); + Do(p, pcmSize); + Do(p, pcmIndex); if (s >= 2) { - p.Do(pcmLoopPos); + Do(p, pcmLoopPos); } else { pcmLoopPos = 0; } - p.Do(sampleRate); + Do(p, sampleRate); - p.Do(sampleFrac); - p.Do(pitch); - p.Do(loop); + Do(p, sampleFrac); + Do(p, pitch); + Do(p, loop); if (s < 2 && type == VOICETYPE_PCM) { // We set loop incorrectly before, and always looped. // Let's keep always looping, since it's usually right. loop = true; } - p.Do(noiseFreq); + Do(p, noiseFreq); - p.Do(volumeLeft); - p.Do(volumeRight); + Do(p, volumeLeft); + Do(p, volumeRight); if (s < 3) { // There were extra variables here that were for the same purpose. - p.Do(effectLeft); - p.Do(effectRight); + Do(p, effectLeft); + Do(p, effectRight); } - p.Do(effectLeft); - p.Do(effectRight); - p.DoArray(resampleHist, ARRAY_SIZE(resampleHist)); + Do(p, effectLeft); + Do(p, effectRight); + DoArray(p, resampleHist, ARRAY_SIZE(resampleHist)); envelope.DoState(p); vag.DoState(p); @@ -948,24 +949,24 @@ void ADSREnvelope::DoState(PointerWrap &p) { return; } - p.Do(attackRate); - p.Do(decayRate); - p.Do(sustainRate); - p.Do(releaseRate); - p.Do(attackType); - p.Do(decayType); - p.Do(sustainType); - p.Do(sustainLevel); - p.Do(releaseType); + Do(p, attackRate); + Do(p, decayRate); + Do(p, sustainRate); + Do(p, releaseRate); + Do(p, attackType); + Do(p, decayType); + Do(p, sustainType); + Do(p, sustainLevel); + Do(p, releaseType); if (s < 2) { - p.Do(state_); + Do(p, state_); if (state_ == 4) { state_ = STATE_OFF; } int stepsLegacy; - p.Do(stepsLegacy); + Do(p, stepsLegacy); } else { - p.Do(state_); + Do(p, state_); } - p.Do(height_); + Do(p, height_); } diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index be35d16b20..3730b299eb 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -17,6 +17,7 @@ #include +#include "Common/ChunkFileDo.h" #include "Core/Config.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HW/SimpleAudioDec.h" @@ -500,25 +501,25 @@ void AuCtx::DoState(PointerWrap &p) { if (!s) return; - p.Do(startPos); - p.Do(endPos); - p.Do(AuBuf); - p.Do(AuBufSize); - p.Do(PCMBuf); - p.Do(PCMBufSize); - p.Do(freq); - p.Do(SumDecodedSamples); - p.Do(LoopNum); - p.Do(Channels); - p.Do(MaxOutputSample); - p.Do(readPos); - p.Do(audioType); - p.Do(BitRate); - p.Do(SamplingRate); - p.Do(askedReadSize); + Do(p, startPos); + Do(p, endPos); + Do(p, AuBuf); + Do(p, AuBufSize); + Do(p, PCMBuf); + Do(p, PCMBufSize); + Do(p, freq); + Do(p, SumDecodedSamples); + Do(p, LoopNum); + Do(p, Channels); + Do(p, MaxOutputSample); + Do(p, readPos); + Do(p, audioType); + Do(p, BitRate); + Do(p, SamplingRate); + Do(p, askedReadSize); int dummy = 0; - p.Do(dummy); - p.Do(FrameNum); + Do(p, dummy); + Do(p, FrameNum); if (p.mode == p.MODE_READ) { decoder = new SimpleAudio(audioType); diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 5cf32aa86d..1ff3c29ee8 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -20,7 +20,8 @@ #include "base/logging.h" #include "profiler/profiler.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Reporting.h" #include "Core/Config.h" @@ -129,9 +130,9 @@ void ArmJit::DoState(PointerWrap &p) if (!s) return; - p.Do(js.startDefaultPrefix); + Do(p, js.startDefaultPrefix); if (s >= 2) { - p.Do(js.hasSetRounding); + Do(p, js.hasSetRounding); js.lastSetRounding = 0; } else { js.hasSetRounding = 1; diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index 3c39b7bf5a..c1d2bac89f 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -20,7 +20,8 @@ #include "base/logging.h" #include "profiler/profiler.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/CPUDetect.h" #include "Common/StringUtils.h" @@ -122,9 +123,9 @@ void Arm64Jit::DoState(PointerWrap &p) { if (!s) return; - p.Do(js.startDefaultPrefix); + Do(p, js.startDefaultPrefix); if (s >= 2) { - p.Do(js.hasSetRounding); + Do(p, js.hasSetRounding); js.lastSetRounding = 0; } else { js.hasSetRounding = 1; diff --git a/Core/MIPS/IR/IRFrontend.cpp b/Core/MIPS/IR/IRFrontend.cpp index b86ff2890e..d1ccfec8bf 100644 --- a/Core/MIPS/IR/IRFrontend.cpp +++ b/Core/MIPS/IR/IRFrontend.cpp @@ -18,6 +18,7 @@ #include "base/logging.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/SymbolMap.h" #include "Core/Reporting.h" @@ -46,9 +47,9 @@ void IRFrontend::DoState(PointerWrap &p) { if (!s) return; - p.Do(js.startDefaultPrefix); + Do(p, js.startDefaultPrefix); if (s >= 2) { - p.Do(js.hasSetRounding); + Do(p, js.hasSetRounding); js.lastSetRounding = 0; } else { js.hasSetRounding = 1; diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index 6ef4a534a7..232c099ec9 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -22,6 +22,7 @@ #include "Common/StringUtils.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Util/DisArm64.h" #include "Core/Config.h" @@ -55,10 +56,10 @@ namespace MIPSComp { return; bool dummy = false; - p.Do(dummy); + Do(p, dummy); if (s >= 2) { dummy = true; - p.Do(dummy); + Do(p, dummy); } } diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index a04e8f2387..6415d5c57e 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -22,6 +22,7 @@ #include "Common.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/ConfigValues.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSInt.h" @@ -265,35 +266,35 @@ void MIPSState::DoState(PointerWrap &p) { else MIPSComp::DoDummyJitState(p); - p.DoArray(r, sizeof(r) / sizeof(r[0])); - p.DoArray(f, sizeof(f) / sizeof(f[0])); + DoArray(p, r, sizeof(r) / sizeof(r[0])); + DoArray(p, f, sizeof(f) / sizeof(f[0])); if (s <= 2) { float vtemp[128]; - p.DoArray(vtemp, sizeof(v) / sizeof(v[0])); + DoArray(p, vtemp, sizeof(v) / sizeof(v[0])); for (int i = 0; i < 128; i++) { v[voffset[i]] = vtemp[i]; } } else { - p.DoArray(v, sizeof(v) / sizeof(v[0])); + DoArray(p, v, sizeof(v) / sizeof(v[0])); } - p.DoArray(vfpuCtrl, sizeof(vfpuCtrl) / sizeof(vfpuCtrl[0])); - p.Do(pc); - p.Do(nextPC); - p.Do(downcount); + DoArray(p, vfpuCtrl, sizeof(vfpuCtrl) / sizeof(vfpuCtrl[0])); + Do(p, pc); + Do(p, nextPC); + Do(p, downcount); // Reversed, but we can just leave it that way. - p.Do(hi); - p.Do(lo); - p.Do(fpcond); + Do(p, hi); + Do(p, lo); + Do(p, fpcond); if (s <= 1) { u32 fcr0_unused = 0; - p.Do(fcr0_unused); + Do(p, fcr0_unused); } - p.Do(fcr31); - p.Do(rng.m_w); - p.Do(rng.m_z); - p.Do(inDelaySlot); - p.Do(llBit); - p.Do(debugCount); + Do(p, fcr31); + Do(p, rng.m_w); + Do(p, rng.m_z); + Do(p, inDelaySlot); + Do(p, llBit); + Do(p, debugCount); if (p.mode == p.MODE_READ && MIPSComp::jit) { // Now that we've loaded fcr31, update any jit state associated. diff --git a/Core/MIPS/MIPS/MipsJit.cpp b/Core/MIPS/MIPS/MipsJit.cpp index bf3b88ee20..e7419bf305 100644 --- a/Core/MIPS/MIPS/MipsJit.cpp +++ b/Core/MIPS/MIPS/MipsJit.cpp @@ -57,9 +57,9 @@ void MipsJit::DoState(PointerWrap &p) if (!s) return; - p.Do(js.startDefaultPrefix); + Do(p, js.startDefaultPrefix); if (s >= 2) { - p.Do(js.hasSetRounding); + Do(p, js.hasSetRounding); js.lastSetRounding = 0; } else { js.hasSetRounding = 1; diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index a062c6fc51..f68993d3d8 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -25,6 +25,7 @@ #include "profiler/profiler.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/Core.h" #include "Core/MemMap.h" #include "Core/System.h" @@ -129,9 +130,9 @@ void Jit::DoState(PointerWrap &p) { if (!s) return; - p.Do(js.startDefaultPrefix); + Do(p, js.startDefaultPrefix); if (s >= 2) { - p.Do(js.hasSetRounding); + Do(p, js.hasSetRounding); js.lastSetRounding = 0; } else { js.hasSetRounding = 1; diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 334bb66491..d4d6bc9ed9 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -28,6 +28,7 @@ #include "Common/MemoryUtil.h" #include "Common/MemArena.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/MemMap.h" #include "Core/MemFault.h" @@ -326,7 +327,7 @@ void DoState(PointerWrap &p) { } else if (s == 2) { // In version 2, we determine memory size based on PSP model. u32 oldMemorySize = g_MemorySize; - p.Do(g_PSPModel); + Do(p, g_PSPModel); p.DoMarker("PSPModel"); if (!g_RemasterMode) { g_MemorySize = g_PSPModel == PSP_MODEL_FAT ? RAM_NORMAL_SIZE : RAM_DOUBLE_SIZE; @@ -338,20 +339,20 @@ void DoState(PointerWrap &p) { // In version 3, we started just saving the memory size directly. // It's no longer based strictly on the PSP model. u32 oldMemorySize = g_MemorySize; - p.Do(g_PSPModel); + Do(p, g_PSPModel); p.DoMarker("PSPModel"); - p.Do(g_MemorySize); + Do(p, g_MemorySize); if (oldMemorySize != g_MemorySize) { Reinit(); } } - p.DoArray(GetPointer(PSP_GetKernelMemoryBase()), g_MemorySize); + DoArray(p, GetPointer(PSP_GetKernelMemoryBase()), g_MemorySize); p.DoMarker("RAM"); - p.DoArray(m_pPhysicalVRAM1, VRAM_SIZE); + DoArray(p, m_pPhysicalVRAM1, VRAM_SIZE); p.DoMarker("VRAM"); - p.DoArray(m_pPhysicalScratchPad, SCRATCHPAD_SIZE); + DoArray(p, m_pPhysicalScratchPad, SCRATCHPAD_SIZE); p.DoMarker("ScratchPad"); } diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 388086ad76..ea680cb957 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -22,6 +22,7 @@ #include "Core/Reporting.h" +#include "Common/ChunkFileDo.h" #include "Common/CPUDetect.h" #include "Core/Core.h" #include "Core/CoreTiming.h" @@ -335,7 +336,7 @@ namespace Reporting return; } - p.Do(everUnsupported); + Do(p, everUnsupported); } void UpdateConfig() diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 4b6b944136..46d661b2ce 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -27,6 +27,7 @@ #include "Common/FileUtil.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/SaveState.h" #include "Core/Config.h" @@ -274,11 +275,11 @@ namespace SaveState if (s >= 2) { // This only increments on save, of course. ++saveStateGeneration; - p.Do(saveStateGeneration); + Do(p, saveStateGeneration); // This saves the first git version to create this save state (or generation of save states.) if (saveStateInitialGitVersion.empty()) saveStateInitialGitVersion = PPSSPP_GIT_VERSION; - p.Do(saveStateInitialGitVersion); + Do(p, saveStateInitialGitVersion); } else { saveStateGeneration = 1; } diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index 1b67b82a9a..10d3d7e627 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -19,6 +19,7 @@ #include "Common/Log.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Common/StringUtils.h" #include "Core/Util/BlockAllocator.h" #include "Core/Reporting.h" @@ -442,7 +443,7 @@ void BlockAllocator::DoState(PointerWrap &p) if (p.mode == p.MODE_READ) { Shutdown(); - p.Do(count); + Do(p, count); bottom_ = new Block(0, 0, false, NULL, NULL); bottom_->DoState(p); @@ -460,7 +461,7 @@ void BlockAllocator::DoState(PointerWrap &p) { for (const Block *bp = bottom_; bp != NULL; bp = bp->next) ++count; - p.Do(count); + Do(p, count); bottom_->DoState(p); --count; @@ -473,9 +474,9 @@ void BlockAllocator::DoState(PointerWrap &p) } } - p.Do(rangeStart_); - p.Do(rangeSize_); - p.Do(grain_); + Do(p, rangeStart_); + Do(p, rangeSize_); + Do(p, grain_); } BlockAllocator::Block::Block(u32 _start, u32 _size, bool _taken, Block *_prev, Block *_next) @@ -498,13 +499,13 @@ void BlockAllocator::Block::DoState(PointerWrap &p) if (!s) return; - p.Do(start); - p.Do(size); - p.Do(taken); + Do(p, start); + Do(p, size); + Do(p, taken); // Since we use truncate_cpy, the empty space is not zeroed. Zero it now. // This avoids saving uninitialized memory. size_t tagLen = strlen(tag); if (tagLen != sizeof(tag)) memset(tag + tagLen, 0, sizeof(tag) - tagLen); - p.DoArray(tag, sizeof(tag)); + DoArray(p, tag, sizeof(tag)); } diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index b679581a0e..9b5cb865f4 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -27,6 +27,7 @@ #include "util/text/utf8.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/HDRemaster.h" #include "Core/Host.h" #include "GPU/ge_constants.h" @@ -282,23 +283,23 @@ void __PPGeDoState(PointerWrap &p) if (!s) return; - p.Do(atlasPtr); - p.Do(atlasWidth); - p.Do(atlasHeight); - p.Do(palette); + Do(p, atlasPtr); + Do(p, atlasWidth); + Do(p, atlasHeight); + Do(p, palette); - p.Do(savedContextPtr); - p.Do(savedContextSize); + Do(p, savedContextPtr); + Do(p, savedContextSize); if (s == 1) { listArgs = 0; } else { - p.Do(listArgs); + Do(p, listArgs); } if (s >= 3) { uint32_t sz = (uint32_t)textDrawerImages.size(); - p.Do(sz); + Do(p, sz); switch (p.mode) { case PointerWrap::MODE_READ: @@ -307,12 +308,12 @@ void __PPGeDoState(PointerWrap &p) // We only care about the pointers, so we can free them. We'll decimate right away. PPGeTextDrawerCacheKey key{ StringFromFormat("__savestate__%d", i), -1, -1 }; textDrawerImages[key] = PPGeTextDrawerImage{}; - p.Do(textDrawerImages[key].ptr); + Do(p, textDrawerImages[key].ptr); } break; default: for (const auto &im : textDrawerImages) { - p.Do(im.second.ptr); + Do(p, im.second.ptr); } break; } @@ -320,19 +321,19 @@ void __PPGeDoState(PointerWrap &p) textDrawerImages.clear(); } - p.Do(dlPtr); - p.Do(dlWritePtr); - p.Do(dlSize); + Do(p, dlPtr); + Do(p, dlWritePtr); + Do(p, dlSize); - p.Do(dataPtr); - p.Do(dataWritePtr); - p.Do(dataSize); + Do(p, dataPtr); + Do(p, dataWritePtr); + Do(p, dataSize); - p.Do(vertexStart); - p.Do(vertexCount); + Do(p, vertexStart); + Do(p, vertexCount); - p.Do(char_lines); - p.Do(char_lines_metrics); + Do(p, char_lines); + Do(p, char_lines_metrics); } void __PPGeShutdown() @@ -1245,13 +1246,13 @@ void PPGeImage::DoState(PointerWrap &p) { if (!s) return; - p.Do(filename_); - p.Do(png_); - p.Do(size_); - p.Do(texture_); - p.Do(width_); - p.Do(height_); - p.Do(lastFrame_); + Do(p, filename_); + Do(p, png_); + Do(p, size_); + Do(p, texture_); + Do(p, width_); + Do(p, height_); + Do(p, lastFrame_); } void PPGeImage::CompatLoad(u32 texture, int width, int height) { diff --git a/GPU/Common/PostShader.h b/GPU/Common/PostShader.h index 4f01d728f9..6febf0ee2d 100644 --- a/GPU/Common/PostShader.h +++ b/GPU/Common/PostShader.h @@ -54,7 +54,7 @@ struct ShaderInfo { Setting settings[4]; // TODO: Add support for all kinds of fun options like mapping the depth buffer, - // SRGB texture reads, etc. + // SRGB texture reads, etc. prev shader? bool operator == (const std::string &other) { return name == other; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 73278fb103..c5f75b5255 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -5,6 +5,7 @@ #include "base/timeutil.h" #include "profiler/profiler.h" +#include "Common/ChunkFileDo.h" #include "Common/ColorConv.h" #include "Common/GraphicsContext.h" #include "Core/Reporting.h" @@ -2409,9 +2410,9 @@ void GPUCommon::DoState(PointerWrap &p) { if (!s) return; - p.Do(dlQueue); + Do(p, dlQueue); if (s >= 4) { - p.DoArray(dls, ARRAY_SIZE(dls)); + DoArray(p, dls, ARRAY_SIZE(dls)); } else if (s >= 3) { // This may have been saved with or without padding, depending on platform. // We need to upconvert it to our consistently-padded struct. @@ -2429,7 +2430,7 @@ void GPUCommon::DoState(PointerWrap &p) { const bool hasPadding = savedPtr32[1] == 1; if (hasPadding) { u32 padding; - p.Do(padding); + Do(p, padding); } for (size_t i = 1; i < ARRAY_SIZE(dls); ++i) { @@ -2437,13 +2438,13 @@ void GPUCommon::DoState(PointerWrap &p) { dls[i].padding = 0; if (hasPadding) { u32 padding; - p.Do(padding); + Do(p, padding); } } } else if (s >= 2) { for (size_t i = 0; i < ARRAY_SIZE(dls); ++i) { DisplayList_v2 oldDL; - p.Do(oldDL); + Do(p, oldDL); // Copy over everything except the last, new member (stackAddr.) memcpy(&dls[i], &oldDL, sizeof(DisplayList_v2)); dls[i].stackAddr = 0; @@ -2452,7 +2453,7 @@ void GPUCommon::DoState(PointerWrap &p) { // Can only be in read mode here. for (size_t i = 0; i < ARRAY_SIZE(dls); ++i) { DisplayList_v1 oldDL; - p.Do(oldDL); + Do(p, oldDL); // On 32-bit, they're the same, on 64-bit oldDL is bigger. memcpy(&dls[i], &oldDL, sizeof(DisplayList_v1)); // Fix the other fields. Let's hope context wasn't important, it was a pointer. @@ -2466,17 +2467,17 @@ void GPUCommon::DoState(PointerWrap &p) { if (currentList != nullptr) { currentID = (int)(currentList - &dls[0]); } - p.Do(currentID); + Do(p, currentID); if (currentID == 0) { currentList = nullptr; } else { currentList = &dls[currentID]; } - p.Do(interruptRunning); - p.Do(gpuState); - p.Do(isbreak); - p.Do(drawCompleteTicks); - p.Do(busyTicks); + Do(p, interruptRunning); + Do(p, gpuState); + Do(p, isbreak); + Do(p, drawCompleteTicks); + Do(p, busyTicks); } void GPUCommon::InterruptStart(int listid) { diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index 44c9419cb9..c64e57d49f 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -19,6 +19,7 @@ #include "GPU/GPUState.h" #include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" #include "Core/CoreParameter.h" #include "Core/Config.h" #include "Core/System.h" @@ -277,7 +278,7 @@ void GPUStateCache::DoState(PointerWrap &p) { if (!s) { // Old state, this was not versioned. GPUStateCache_v0 old; - p.Do(old); + Do(p, old); vertexAddr = old.vertexAddr; indexAddr = old.indexAddr; @@ -290,67 +291,67 @@ void GPUStateCache::DoState(PointerWrap &p) { savedContextVersion = 0; } else { - p.Do(vertexAddr); - p.Do(indexAddr); - p.Do(offsetAddr); + Do(p, vertexAddr); + Do(p, indexAddr); + Do(p, offsetAddr); uint8_t textureChanged = 0; - p.Do(textureChanged); // legacy + Do(p, textureChanged); // legacy gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); - p.Do(textureFullAlpha); - p.Do(vertexFullAlpha); + Do(p, textureFullAlpha); + Do(p, vertexFullAlpha); bool framebufChanged = false; // legacy - p.Do(framebufChanged); + Do(p, framebufChanged); - p.Do(skipDrawReason); + Do(p, skipDrawReason); - p.Do(uv); + Do(p, uv); bool oldFlipTexture = false; - p.Do(oldFlipTexture); // legacy + Do(p, oldFlipTexture); // legacy } // needShaderTexClamp and bgraTexture don't need to be saved. if (s >= 3) { bool oldTextureSimpleAlpha = false; - p.Do(oldTextureSimpleAlpha); + Do(p, oldTextureSimpleAlpha); } if (s < 2) { float l12[12]; float l4[4]; - p.Do(l12); // lightpos - p.Do(l12); // lightdir - p.Do(l12); // lightattr - p.Do(l12); // lightcol0 - p.Do(l12); // lightcol1 - p.Do(l12); // lightcol2 - p.Do(l4); // lightangle - p.Do(l4); // lightspot + Do(p, l12); // lightpos + Do(p, l12); // lightdir + Do(p, l12); // lightattr + Do(p, l12); // lightcol0 + Do(p, l12); // lightcol1 + Do(p, l12); // lightcol2 + Do(p, l4); // lightangle + Do(p, l4); // lightspot } - p.Do(morphWeights); + Do(p, morphWeights); - p.Do(curTextureWidth); - p.Do(curTextureHeight); - p.Do(actualTextureHeight); + Do(p, curTextureWidth); + Do(p, curTextureHeight); + Do(p, actualTextureHeight); // curTextureXOffset and curTextureYOffset don't need to be saved. Well, the above don't either... - p.Do(vpWidth); - p.Do(vpHeight); + Do(p, vpWidth); + Do(p, vpHeight); if (s == 4) { float oldDepth = 1.0f; - p.Do(oldDepth); + Do(p, oldDepth); } - p.Do(curRTWidth); - p.Do(curRTHeight); + Do(p, curRTWidth); + Do(p, curRTHeight); // curRTBufferWidth, curRTBufferHeight, and cutRTOffsetX don't need to be saved. if (s < 5) { savedContextVersion = 0; } else { - p.Do(savedContextVersion); + Do(p, savedContextVersion); } } diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 4f9545c490..31f2327547 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -727,6 +727,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 781833645f..6538bd1df1 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -708,6 +708,9 @@ MIPS\ARM64 + + HW + HW diff --git a/android/jni/Android.mk b/android/jni/Android.mk index ac68cf1815..9b2d62b92a 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -279,6 +279,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/ELF/ParamSFO.cpp \ $(SRC)/Core/HW/SimpleAudioDec.cpp \ $(SRC)/Core/HW/AsyncIOManager.cpp \ + $(SRC)/Core/HW/BufferQueue.cpp \ $(SRC)/Core/HW/Camera.cpp \ $(SRC)/Core/HW/MemoryStick.cpp \ $(SRC)/Core/HW/MpegDemux.cpp.arm \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index ff7b524875..cf38aae92b 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -438,6 +438,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/HLE/sceNp.cpp \ $(COREDIR)/HLE/scePauth.cpp \ $(COREDIR)/HLE/sceUsbGps.cpp \ + $(COREDIR)/HW/BufferQueue.cpp \ $(COREDIR)/HW/Camera.cpp \ $(COREDIR)/HW/SimpleAudioDec.cpp \ $(COREDIR)/HW/AsyncIOManager.cpp \ From 1af3009e80e115e496cfa6da50eada1f5abe3ca1 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 02:19:02 +0000 Subject: [PATCH 462/848] HLE: Fix some missing error logging. --- Core/HLE/sceMt19937.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceMt19937.cpp b/Core/HLE/sceMt19937.cpp index ba7aa28166..cc56df502b 100644 --- a/Core/HLE/sceMt19937.cpp +++ b/Core/HLE/sceMt19937.cpp @@ -28,22 +28,21 @@ static u32 sceMt19937Init(u32 mt19937Addr, u32 seed) { - INFO_LOG(HLE, "sceMt19937Init(%08x, %08x)", mt19937Addr, seed); if (!Memory::IsValidAddress(mt19937Addr)) - return -1; + return hleLogError(HLE, -1); void *ptr = Memory::GetPointer(mt19937Addr); // This is made to match the memory layout of a PSP MT structure exactly. // Let's just construct it in place with placement new. Elite C++ hackery FTW. new (ptr) MersenneTwister(seed); - return 0; + return hleLogSuccessInfoI(HLE, 0); } static u32 sceMt19937UInt(u32 mt19937Addr) { if (!Memory::IsValidAddress(mt19937Addr)) - return -1; + return hleLogError(HLE, -1); MersenneTwister *mt = (MersenneTwister *)Memory::GetPointer(mt19937Addr); - return mt->R32(); + return hleLogSuccessVerboseX(HLE, mt->R32()); } const HLEFunction sceMt19937[] = From 667a8522ccad57f7ef7ae3d860f3f73663044c2e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 02:20:07 +0000 Subject: [PATCH 463/848] Global: Cut down on file/string includes. --- Common/ConsoleListener.cpp | 1 + Common/FileUtil.cpp | 1 + Common/FileUtil.h | 10 ---------- Common/LogManager.h | 4 ++-- Common/StringUtils.cpp | 1 + Core/Compatibility.cpp | 1 + Core/Util/DisArm64.cpp | 3 ++- Core/Util/PortManager.cpp | 15 ++++++++------- ext/native/base/stringutil.h | 24 ------------------------ ext/native/file/path.cpp | 1 + ext/native/i18n/i18n.h | 1 - 11 files changed, 17 insertions(+), 45 deletions(-) diff --git a/Common/ConsoleListener.cpp b/Common/ConsoleListener.cpp index 39b1073ad3..5b7217827a 100644 --- a/Common/ConsoleListener.cpp +++ b/Common/ConsoleListener.cpp @@ -17,6 +17,7 @@ #include #include // min +#include #include // System: To be able to add strings with "+" #include #ifdef _WIN32 diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index d1ad8a5b72..d18ccecad4 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -24,6 +24,7 @@ #include "ppsspp_config.h" +#include #include #include "FileUtil.h" #include "StringUtils.h" diff --git a/Common/FileUtil.h b/Common/FileUtil.h index e088ceda4c..f9f86433a7 100644 --- a/Common/FileUtil.h +++ b/Common/FileUtil.h @@ -35,16 +35,6 @@ inline struct tm* localtime_r(const time_t *clock, struct tm *result) { namespace File { -// FileSystem tree node/ -struct FSTEntry -{ - bool isDirectory; - u64 size; // file length or number of entries from children - std::string physicalName; // name on disk - std::string virtualName; // name in FST names table - std::vector children; -}; - struct FileDetails { bool isDirectory; u64 size; diff --git a/Common/LogManager.h b/Common/LogManager.h index 1e8e39547d..e05711a19c 100644 --- a/Common/LogManager.h +++ b/Common/LogManager.h @@ -19,13 +19,13 @@ #include "ppsspp_config.h" -#include +#include #include +#include #include "file/ini_file.h" #include "Log.h" #include "StringUtils.h" -#include "FileUtil.h" #define MAX_MESSAGES 8000 diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index c1289720b0..0bd5da6962 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include #include "Common.h" #include "StringUtils.h" diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 1d8c9d513a..547ebb5925 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "file/ini_file.h" #include "Core/Compatibility.h" #include "Core/System.h" diff --git a/Core/Util/DisArm64.cpp b/Core/Util/DisArm64.cpp index e6c983be55..651ffe35c9 100644 --- a/Core/Util/DisArm64.cpp +++ b/Core/Util/DisArm64.cpp @@ -21,7 +21,8 @@ // Does enough to understand what's going on without having to resort to an // external disassembler all the time... -#include +#include +#include #include "Common/Arm64Emitter.h" #include "Common/StringUtils.h" diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index d91e4fb428..f1ed937836 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -25,18 +25,19 @@ // All credit goes to him and the official miniupnp project! http://miniupnp.free.fr/ -#include #include -#include -#include -#include -#include "Core/Util/PortManager.h" -#include +#include +#include #include +#include "base/timeutil.h" #include "i18n/i18n.h" #include "net/resolve.h" #include "thread/threadutil.h" -#include "base/timeutil.h" +#include "Common/Log.h" +#include "Core/System.h" +#include "Core/Host.h" +#include "Core/ELF/ParamSFO.h" +#include "Core/Util/PortManager.h" PortManager g_PortManager; diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h index 6a06a739db..c16602946f 100644 --- a/ext/native/base/stringutil.h +++ b/ext/native/base/stringutil.h @@ -1,11 +1,7 @@ #pragma once -#include -#include -#include #include #include -#include #include #include "base/basictypes.h" @@ -67,26 +63,6 @@ inline void StringToHexString(const std::string &data, std::string *output) { // highly unsafe and not recommended. unsigned int parseHex(const char* _szValue); - -// Suitable for inserting into maps, unlike char*, and cheaper than std::string. -// Strings must be constant and preferably be stored in the read-only part -// of the binary. -class ConstString { -public: - ConstString(const char *ptr) { - ptr_ = ptr; - } - bool operator <(const ConstString &other) const { - return strcmp(ptr_, other.ptr_) < 0; - } - bool operator ==(const ConstString &other) const { - return ptr_ == other.ptr_ || !strcmp(ptr_, other.ptr_); - } - const char *get() const { return ptr_; } -private: - const char *ptr_; -}; - std::string StringFromFormat(const char* format, ...); std::string StringFromInt(int value); std::string StringFromBool(bool value); diff --git a/ext/native/file/path.cpp b/ext/native/file/path.cpp index ec62c179b5..6aa562dbbc 100644 --- a/ext/native/file/path.cpp +++ b/ext/native/file/path.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "base/stringutil.h" #include "base/timeutil.h" diff --git a/ext/native/i18n/i18n.h b/ext/native/i18n/i18n.h index bc4e3ca4bf..75d8ddd776 100644 --- a/ext/native/i18n/i18n.h +++ b/ext/native/i18n/i18n.h @@ -14,7 +14,6 @@ #include #include -#include "base/stringutil.h" #include "file/ini_file.h" // Reasonably thread safe. From 481181714b3412af2994509b70555cb968385f0c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 02:20:28 +0000 Subject: [PATCH 464/848] Audiocodec: Silence a known warning. --- Core/HLE/sceAudiocodec.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index 509d35c50f..2e29668cdd 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -183,6 +183,10 @@ void __sceAudiocodecDoState(PointerWrap &p){ auto ctxPtr_ = new u32[count]; // These sizeof(pointers) are wrong, but kept to avoid breaking on old saves. // They're not used in new savestates. +#ifdef __clang__ +#pragma diagnostic push +#pragma clang diagnostic ignored "-Wsizeof-pointer-div" +#endif DoArray(p, codec_, s >= 2 ? count : (int)ARRAY_SIZE(codec_)); DoArray(p, ctxPtr_, s >= 2 ? count : (int)ARRAY_SIZE(ctxPtr_)); for (int i = 0; i < count; i++) { @@ -190,6 +194,9 @@ void __sceAudiocodecDoState(PointerWrap &p){ decoder->SetCtxPtr(ctxPtr_[i]); audioList[ctxPtr_[i]] = decoder; } +#ifdef __clang__ +#pragma diagnostic pop +#endif delete[] codec_; delete[] ctxPtr_; } From 1bcafafdbb52e62ab93f81eb7c0488456564c94a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 02:20:47 +0000 Subject: [PATCH 465/848] UI: Fix an override warning. --- ext/native/ui/view.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index 335ce822e8..e8baa55702 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -648,7 +648,7 @@ public: Choice(ImageID image, LayoutParams *layoutParams = nullptr) : ClickableItem(layoutParams), atlasImage_(image), iconImage_(ImageID::invalid()), centered_(false), highlighted_(false), selected_(false) {} - virtual void Click(); + void Click() override; virtual void HighlightChanged(bool highlighted); void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override; void Draw(UIContext &dc) override; From 34f6d085a5b7ece43f75415f3d2930df7793ac6e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 02:40:30 +0000 Subject: [PATCH 466/848] Global: Remove unnecessary includes. --- Common/LogManager.h | 3 +-- UI/GPUDriverTestScreen.h | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Common/LogManager.h b/Common/LogManager.h index e05711a19c..81a23d518d 100644 --- a/Common/LogManager.h +++ b/Common/LogManager.h @@ -24,8 +24,7 @@ #include #include "file/ini_file.h" -#include "Log.h" -#include "StringUtils.h" +#include "Common/Log.h" #define MAX_MESSAGES 8000 diff --git a/UI/GPUDriverTestScreen.h b/UI/GPUDriverTestScreen.h index bf5c56a02c..a241e81bae 100644 --- a/UI/GPUDriverTestScreen.h +++ b/UI/GPUDriverTestScreen.h @@ -1,7 +1,5 @@ #pragma once -#include - #include "base/display.h" #include "ui/ui_context.h" #include "ui/view.h" From 2da977bed25297a01c6589fd640fd65def3eb60b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 04:22:28 +0000 Subject: [PATCH 467/848] SaveState: Add header to other makefiles. --- CMakeLists.txt | 1 + UWP/CommonUWP/CommonUWP.vcxproj | 1 + UWP/CommonUWP/CommonUWP.vcxproj.filters | 1 + 3 files changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d616ca6ebf..09ca275110 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -418,6 +418,7 @@ add_library(Common STATIC Common/ColorConv.h Common/ChunkFile.cpp Common/ChunkFile.h + Common/ChunkFileDo.h Common/ConsoleListener.cpp Common/ConsoleListener.h Common/Crypto/md5.cpp diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 88559e8c82..747a2a83f0 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -385,6 +385,7 @@ + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 100c103e66..ec50d08b2a 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -56,6 +56,7 @@ + From 4c46867230c548730550d6d52378cc7c267d577c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 9 Aug 2020 22:03:49 -0700 Subject: [PATCH 468/848] Audio: Avoid exposing fixed size queue in header. --- Core/HLE/__sceAudio.cpp | 38 ++++++++++++++++++++++++-------------- Core/HLE/sceAudio.cpp | 17 ++++++++++------- Core/HLE/sceAudio.h | 12 ++---------- UI/BackgroundAudio.cpp | 3 ++- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index c938c09929..d8472edc47 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -52,6 +52,10 @@ StereoResampler resampler; // atomic locks are used on the lock. TODO: make this lock-free std::atomic_flag atomicLock_; +// We copy samples as they are written into this simple ring buffer. +// Might try something more efficient later. +FixedSizeQueue chanSampleQueues[PSP_AUDIO_CHANNEL_MAX + 1]; + int eventAudioUpdate = -1; int eventHostAudioUpdate = -1; int mixFrequency = 44100; @@ -115,8 +119,10 @@ void __AudioInit() { CoreTiming::ScheduleEvent(audioIntervalCycles, eventAudioUpdate, 0); CoreTiming::ScheduleEvent(audioHostIntervalCycles, eventHostAudioUpdate, 0); - for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) + for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) { + chans[i].index = i; chans[i].clear(); + } mixBuffer = new s32[hwBlockSize * 2]; clampedMixBuffer = new s16[hwBlockSize * 2]; @@ -164,8 +170,10 @@ void __AudioDoState(PointerWrap &p) { p.SetError(p.ERROR_FAILURE); return; } - for (int i = 0; i < chanCount; ++i) + for (int i = 0; i < chanCount; ++i) { + chans[i].index = i; chans[i].DoState(p); + } __AudioCPUMHzChange(); } @@ -175,8 +183,10 @@ void __AudioShutdown() { delete [] clampedMixBuffer; mixBuffer = 0; - for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) + for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) { + chans[i].index = i; chans[i].clear(); + } #ifndef MOBILE_DEVICE if (g_Config.bDumpAudio) { @@ -196,11 +206,11 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) { } // If there's anything on the queue at all, it should be busy, but we try to be a bit lax. - //if (chan.sampleQueue.size() > chan.sampleCount * 2 * chanQueueMaxSizeFactor || chan.sampleAddress == 0) { - if (chan.sampleQueue.size() > 0) { + //if (chanSampleQueues[chanNum].size() > chan.sampleCount * 2 * chanQueueMaxSizeFactor || chan.sampleAddress == 0) { + if (chanSampleQueues[chanNum].size() > 0) { if (blocking) { // TODO: Regular multichannel audio seems to block for 64 samples less? Or enqueue the first 64 sync? - int blockSamples = (int)chan.sampleQueue.size() / 2 / chanQueueMinSizeFactor; + int blockSamples = (int)chanSampleQueues[chanNum].size() / 2 / chanQueueMinSizeFactor; if (__KernelIsDispatchEnabled()) { AudioChannelWaitInfo waitInfo = {__KernelGetCurThread(), blockSamples}; @@ -235,7 +245,7 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) { const u32 totalSamples = chan.sampleCount * (chan.format == PSP_AUDIO_FORMAT_STEREO ? 2 : 1); s16 *buf1 = 0, *buf2 = 0; size_t sz1, sz2; - chan.sampleQueue.pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2); + chanSampleQueues[chanNum].pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2); if (Memory::IsValidAddress(chan.sampleAddress + (totalSamples - 1) * sizeof(s16_le))) { Memory::Memcpy(buf1, chan.sampleAddress, (u32)sz1 * sizeof(s16)); @@ -257,7 +267,7 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) { if (Memory::IsValidAddress(chan.sampleAddress + (totalSamples - 1) * sizeof(s16_le))) { s16 *buf1 = 0, *buf2 = 0; size_t sz1, sz2; - chan.sampleQueue.pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2); + chanSampleQueues[chanNum].pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2); AdjustVolumeBlock(buf1, sampleData, sz1, leftVol, rightVol); if (buf2) { AdjustVolumeBlock(buf2, sampleData + sz1, sz2, leftVol, rightVol); @@ -267,8 +277,8 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) { // Rare, so unoptimized. Expands to stereo. for (u32 i = 0; i < chan.sampleCount; i++) { s16 sample = (s16)Memory::Read_U16(chan.sampleAddress + 2 * i); - chan.sampleQueue.push(ApplySampleVolume(sample, leftVol)); - chan.sampleQueue.push(ApplySampleVolume(sample, rightVol)); + chanSampleQueues[chanNum].push(ApplySampleVolume(sample, leftVol)); + chanSampleQueues[chanNum].push(ApplySampleVolume(sample, rightVol)); } } } @@ -335,20 +345,20 @@ void __AudioUpdate(bool resetRecording) { __AudioWakeThreads(chans[i], 0, hwBlockSize); - if (!chans[i].sampleQueue.size()) { + if (!chanSampleQueues[i].size()) { continue; } bool needsResample = i == PSP_AUDIO_CHANNEL_SRC && srcFrequency != 0 && srcFrequency != mixFrequency; size_t sz = needsResample ? (hwBlockSize * 2 * srcFrequency) / mixFrequency : hwBlockSize * 2; - if (sz > chans[i].sampleQueue.size()) { - ERROR_LOG(SCEAUDIO, "Channel %i buffer underrun at %i of %i", i, (int)chans[i].sampleQueue.size() / 2, (int)sz / 2); + if (sz > chanSampleQueues[i].size()) { + ERROR_LOG(SCEAUDIO, "Channel %i buffer underrun at %i of %i", i, (int)chanSampleQueues[i].size() / 2, (int)sz / 2); } const s16 *buf1 = 0, *buf2 = 0; size_t sz1, sz2; - chans[i].sampleQueue.popPointers(sz, &buf1, &sz1, &buf2, &sz2); + chanSampleQueues[i].popPointers(sz, &buf1, &sz1, &buf2, &sz2); if (needsResample) { auto read = [&](size_t i) { diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index ba7ca82b62..c5d2d54a0a 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -17,6 +17,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/FixedSizeQueue.h" #include "Core/MIPS/MIPS.h" #include "Core/Host.h" #include "Core/CoreTiming.h" @@ -35,6 +36,8 @@ const int AUDIO_ROUTING_SPEAKER_ON = 1; int defaultRoutingMode = AUDIO_ROUTING_SPEAKER_ON; int defaultRoutingVolMode = AUDIO_ROUTING_SPEAKER_ON; +extern FixedSizeQueue chanSampleQueues[PSP_AUDIO_CHANNEL_MAX + 1]; + void AudioChannel::DoState(PointerWrap &p) { auto s = p.Section("AudioChannel", 1, 2); @@ -52,7 +55,7 @@ void AudioChannel::DoState(PointerWrap &p) Do(p, defaultRoutingMode); Do(p, defaultRoutingVolMode); } - sampleQueue.DoState(p); + chanSampleQueues[index].DoState(p); } void AudioChannel::reset() @@ -69,7 +72,7 @@ void AudioChannel::clear() format = 0; sampleAddress = 0; sampleCount = 0; - sampleQueue.clear(); + chanSampleQueues[index].clear(); waitingThreads.clear(); } @@ -183,7 +186,7 @@ static int sceAudioGetChannelRestLen(u32 chan) { ERROR_LOG(SCEAUDIO, "sceAudioGetChannelRestLen(%08x) - bad channel", chan); return SCE_ERROR_AUDIO_INVALID_CHANNEL; } - int remainingSamples = (int)chans[chan].sampleQueue.size() / 2; + int remainingSamples = (int)chanSampleQueues[chan].size() / 2; VERBOSE_LOG(SCEAUDIO, "%d=sceAudioGetChannelRestLen(%08x)", remainingSamples, chan); return remainingSamples; } @@ -193,7 +196,7 @@ static int sceAudioGetChannelRestLength(u32 chan) { ERROR_LOG(SCEAUDIO, "sceAudioGetChannelRestLength(%08x) - bad channel", chan); return SCE_ERROR_AUDIO_INVALID_CHANNEL; } - int remainingSamples = (int)chans[chan].sampleQueue.size() / 2; + int remainingSamples = (int)chanSampleQueues[chan].size() / 2; VERBOSE_LOG(SCEAUDIO, "%d=sceAudioGetChannelRestLength(%08x)", remainingSamples, chan); return remainingSamples; } @@ -371,7 +374,7 @@ static u32 sceAudioOutput2GetRestSample() { if (!chan.reserved) { return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED, "channel not reserved"); } - u32 size = (u32)chan.sampleQueue.size() / 2; + u32 size = (u32)chanSampleQueues[PSP_AUDIO_CHANNEL_OUTPUT2].size() / 2; if (size > chan.sampleCount) { // If ChangeLength reduces the size, it still gets output but this return is clamped. size = chan.sampleCount; @@ -383,7 +386,7 @@ static u32 sceAudioOutput2Release() { auto &chan = chans[PSP_AUDIO_CHANNEL_OUTPUT2]; if (!chan.reserved) return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED, "channel not reserved"); - if (!chan.sampleQueue.empty()) + if (!chanSampleQueues[PSP_AUDIO_CHANNEL_OUTPUT2].empty()) return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED, "output busy"); chan.reset(); @@ -444,7 +447,7 @@ static u32 sceAudioSRCChRelease() { auto &chan = chans[PSP_AUDIO_CHANNEL_SRC]; if (!chan.reserved) return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED, "channel not reserved"); - if (!chan.sampleQueue.empty()) + if (!chanSampleQueues[PSP_AUDIO_CHANNEL_SRC].empty()) return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED, "output busy"); chan.reset(); diff --git a/Core/HLE/sceAudio.h b/Core/HLE/sceAudio.h index bf8af1e62b..2c21192710 100644 --- a/Core/HLE/sceAudio.h +++ b/Core/HLE/sceAudio.h @@ -21,7 +21,6 @@ #include "CommonTypes.h" #include "sceKernel.h" -#include "FixedSizeQueue.h" class PointerWrap; @@ -60,9 +59,8 @@ struct AudioChannel clear(); } - // PSP side - - bool reserved; + int index = 0; + bool reserved = false; // last sample address u32 sampleAddress; @@ -73,12 +71,6 @@ struct AudioChannel std::vector waitingThreads; - // PC side - should probably split out - - // We copy samples as they are written into this simple ring buffer. - // Might try something more efficient later. - FixedSizeQueue sampleQueue; - void DoState(PointerWrap &p); void reset(); diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index b8a08fcaa9..7a25c34afa 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -7,10 +7,11 @@ #include "file/vfs.h" #include "ui/root.h" +#include "Common/ChunkFileDo.h" #include "Common/CommonTypes.h" +#include "Common/FixedSizeQueue.h" #include "Core/HW/SimpleAudioDec.h" #include "Core/HLE/__sceAudio.h" -#include "Common/FixedSizeQueue.h" #include "GameInfoCache.h" #include "Core/Config.h" #include "UI/BackgroundAudio.h" From 1dc5ee424bd3843ae9279c4615660795ce9f42f2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 06:38:45 +0000 Subject: [PATCH 469/848] SaveState: Split out Do types to reduce headers. --- Common/ChunkFile.cpp | 7 +- Common/ChunkFile.h | 17 +- Common/ChunkFileDo.h | 293 +--------------------------- Common/ChunkFileDoDeque.h | 44 +++++ Common/ChunkFileDoList.h | 101 ++++++++++ Common/ChunkFileDoMap.h | 164 ++++++++++++++++ Common/ChunkFileDoSet.h | 69 +++++++ Core/CoreTiming.cpp | 2 +- Core/Dialog/PSPSaveDialog.cpp | 1 + Core/FileSystems/MetaFileSystem.cpp | 1 + Core/HLE/sceDisplay.cpp | 1 + Core/HLE/sceFont.cpp | 1 + Core/HLE/sceGe.cpp | 2 + Core/HLE/sceHeap.cpp | 1 + Core/HLE/sceIo.cpp | 3 + Core/HLE/sceKernelAlarm.cpp | 3 +- Core/HLE/sceKernelEventFlag.cpp | 1 + Core/HLE/sceKernelInterrupt.cpp | 2 + Core/HLE/sceKernelMbx.cpp | 1 + Core/HLE/sceKernelMemory.cpp | 1 + Core/HLE/sceKernelModule.cpp | 1 + Core/HLE/sceKernelMsgPipe.cpp | 1 + Core/HLE/sceKernelMutex.cpp | 1 + Core/HLE/sceKernelSemaphore.cpp | 1 + Core/HLE/sceKernelThread.cpp | 4 +- Core/HLE/sceKernelVTimer.cpp | 2 + Core/HLE/sceMp3.cpp | 1 + Core/HLE/sceMp4.cpp | 1 + Core/HLE/sceMpeg.cpp | 1 + Core/HLE/sceNet.cpp | 1 + Core/HLE/sceNetAdhoc.cpp | 1 + Core/HLE/scePsmf.cpp | 1 + Core/HLE/sceUmd.cpp | 1 + Core/HLE/sceUsbGps.cpp | 1 + Core/HLE/sceUtility.cpp | 2 + Core/HW/AsyncIOManager.cpp | 2 + Core/HW/BufferQueue.cpp | 1 + Core/MIPS/IR/IRJit.cpp | 1 + Core/Reporting.cpp | 1 + Core/System.cpp | 1 + GPU/GLES/GPU_GLES.cpp | 1 + GPU/GPUCommon.cpp | 1 + GPU/Vulkan/GPU_Vulkan.cpp | 1 + Windows/MainWindowMenu.cpp | 1 + Windows/main.cpp | 1 + 45 files changed, 440 insertions(+), 306 deletions(-) create mode 100644 Common/ChunkFileDoDeque.h create mode 100644 Common/ChunkFileDoList.h create mode 100644 Common/ChunkFileDoMap.h create mode 100644 Common/ChunkFileDoSet.h diff --git a/Common/ChunkFile.cpp b/Common/ChunkFile.cpp index 229c96aaff..7252d46d68 100644 --- a/Common/ChunkFile.cpp +++ b/Common/ChunkFile.cpp @@ -19,9 +19,10 @@ #include #include -#include "ChunkFile.h" -#include "ChunkFileDo.h" -#include "StringUtils.h" +#include "Common/ChunkFile.h" +#include "Common/ChunkFileDo.h" +#include "Common/FileUtil.h" +#include "Common/StringUtils.h" PointerWrapSection PointerWrap::Section(const char *title, int ver) { return Section(title, ver, ver); diff --git a/Common/ChunkFile.h b/Common/ChunkFile.h index 67ef6f0e21..99d7a5c343 100644 --- a/Common/ChunkFile.h +++ b/Common/ChunkFile.h @@ -29,17 +29,14 @@ // + Sections can be versioned for backwards/forwards compatibility // - Serialization code for anything complex has to be manually written. -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include "Common/CommonTypes.h" +#include "Common/Log.h" -#include "Common.h" -#include "Swap.h" -#include "FileUtil.h" +namespace File { +class IOFile; +}; template struct LinkedListItem : public T diff --git a/Common/ChunkFileDo.h b/Common/ChunkFileDo.h index 3849248295..e43f229e8a 100644 --- a/Common/ChunkFileDo.h +++ b/Common/ChunkFileDo.h @@ -18,7 +18,10 @@ #pragma once // Templates for save state serialization. See ChunkFile.h. +#include +#include #include "Common/ChunkFile.h" +#include "Common/Swap.h" void Do(PointerWrap &p, std::string &x); void Do(PointerWrap &p, std::wstring &x); // DEPRECATED, do not save wstrings @@ -82,147 +85,6 @@ void Do(PointerWrap &p, T &x) { DoHelper_::DoThing(p, x); } -template -void DoMap(PointerWrap &p, M &x, typename M::mapped_type &default_val) { - unsigned int number = (unsigned int)x.size(); - Do(p, number); - switch (p.mode) { - case PointerWrap::MODE_READ: - { - x.clear(); - while (number > 0) { - typename M::key_type first = typename M::key_type(); - Do(p, first); - typename M::mapped_type second = default_val; - Do(p, second); - x[first] = second; - --number; - } - } - break; - case PointerWrap::MODE_WRITE: - case PointerWrap::MODE_MEASURE: - case PointerWrap::MODE_VERIFY: - { - typename M::iterator itr = x.begin(); - while (number > 0) { - typename M::key_type first = itr->first; - Do(p, first); - Do(p, itr->second); - --number; - ++itr; - } - } - break; - } -} - -template -void Do(PointerWrap &p, std::map &x) { - if (p.mode == PointerWrap::MODE_READ) { - for (auto it = x.begin(), end = x.end(); it != end; ++it) { - if (it->second != nullptr) - delete it->second; - } - } - T *dv = nullptr; - DoMap(p, x, dv); -} - -template -void Do(PointerWrap &p, std::map &x) { - T dv = T(); - DoMap(p, x, dv); -} - -template -void Do(PointerWrap &p, std::unordered_map &x) { - if (p.mode == PointerWrap::MODE_READ) { - for (auto it = x.begin(), end = x.end(); it != end; ++it) { - if (it->second != nullptr) - delete it->second; - } - } - T *dv = nullptr; - DoMap(p, x, dv); -} - -template -void Do(PointerWrap &p, std::unordered_map &x) { - T dv = T(); - DoMap(p, x, dv); -} - -template -void DoMultimap(PointerWrap &p, M &x, typename M::mapped_type &default_val) { - unsigned int number = (unsigned int)x.size(); - Do(p, number); - switch (p.mode) { - case PointerWrap::MODE_READ: - { - x.clear(); - while (number > 0) { - typename M::key_type first = typename M::key_type(); - Do(p, first); - typename M::mapped_type second = default_val; - Do(p, second); - x.insert(std::make_pair(first, second)); - --number; - } - } - break; - case PointerWrap::MODE_WRITE: - case PointerWrap::MODE_MEASURE: - case PointerWrap::MODE_VERIFY: - { - typename M::iterator itr = x.begin(); - while (number > 0) { - Do(p, itr->first); - Do(p, itr->second); - --number; - ++itr; - } - } - break; - } -} - -template -void Do(PointerWrap &p, std::multimap &x) { - if (p.mode == PointerWrap::MODE_READ) { - for (auto it = x.begin(), end = x.end(); it != end; ++it) { - if (it->second != nullptr) - delete it->second; - } - } - T *dv = nullptr; - DoMultimap(p, x, dv); -} - -template -void Do(PointerWrap &p, std::multimap &x) { - T dv = T(); - DoMultimap(p, x, dv); -} - -template -void Do(PointerWrap &p, std::unordered_multimap &x) { - if (p.mode == PointerWrap::MODE_READ) { - for (auto it = x.begin(), end = x.end(); it != end; ++it) { - if (it->second != nullptr) - delete it->second; - } - } - T *dv = nullptr; - DoMultimap(p, x, dv); -} - -template -void Do(PointerWrap &p, std::unordered_multimap &x) { - T dv = T(); - DoMultimap(p, x, dv); -} - template void DoVector(PointerWrap &p, std::vector &x, T &default_val) { u32 vec_size = (u32)x.size(); @@ -249,104 +111,6 @@ void Do(PointerWrap &p, std::vector &x, T &default_val) { DoVector(p, x, default_val); } -template -void DoDeque(PointerWrap &p, std::deque &x, T &default_val) { - u32 deq_size = (u32)x.size(); - Do(p, deq_size); - x.resize(deq_size, default_val); - u32 i; - for (i = 0; i < deq_size; i++) - Do(p, x[i]); -} - -template -void Do(PointerWrap &p, std::deque &x) { - T *dv = nullptr; - DoDeque(p, x, dv); -} - -template -void Do(PointerWrap &p, std::deque &x) { - T dv = T(); - DoDeque(p, x, dv); -} - -template -void DoList(PointerWrap &p, std::list &x, T &default_val) { - u32 list_size = (u32)x.size(); - Do(p, list_size); - x.resize(list_size, default_val); - - typename std::list::iterator itr, end; - for (itr = x.begin(), end = x.end(); itr != end; ++itr) - Do(p, *itr); -} - -template -void Do(PointerWrap &p, std::list &x) { - T *dv = nullptr; - Do(p, x, dv); -} - -template -void Do(PointerWrap &p, std::list &x) { - T dv = T(); - DoList(p, x, dv); -} - -template -void Do(PointerWrap &p, std::list &x, T &default_val) { - DoList(p, x, default_val); -} - -template -void DoSet(PointerWrap &p, std::set &x) { - unsigned int number = (unsigned int)x.size(); - Do(p, number); - - switch (p.mode) { - case PointerWrap::MODE_READ: - { - x.clear(); - while (number-- > 0) { - T it = T(); - Do(p, it); - x.insert(it); - } - } - break; - case PointerWrap::MODE_WRITE: - case PointerWrap::MODE_MEASURE: - case PointerWrap::MODE_VERIFY: - { - typename std::set::iterator itr = x.begin(); - while (number-- > 0) - Do(p, *itr++); - } - break; - - default: - ERROR_LOG(SAVESTATE, "Savestate error: invalid mode %d.", p.mode); - } -} - -// Store STL sets. -template -void Do(PointerWrap &p, std::set &x) { - if (p.mode == PointerWrap::MODE_READ) { - for (auto it = x.begin(), end = x.end(); it != end; ++it) { - if (*it != nullptr) - delete *it; - } - } - DoSet(p, x); -} - -template -void Do(PointerWrap &p, std::set &x) { - DoSet(p, x); -} - template void Do(PointerWrap &p, swap_struct_t &x) { T v = x.swap(); @@ -362,54 +126,3 @@ void DoPointer(PointerWrap &p, T *&x, T *const base) { if (p.mode == PointerWrap::MODE_READ) x = base + offset; } - -template *(*TNew)(), void (*TFree)(LinkedListItem *), void (*TDo)(PointerWrap &, T *)> -void DoLinkedList(PointerWrap &p, LinkedListItem *&list_start, LinkedListItem **list_end = nullptr) { - LinkedListItem *list_cur = list_start; - LinkedListItem *prev = nullptr; - - while (true) { - u8 shouldExist = (list_cur ? 1 : 0); - Do(p, shouldExist); - if (shouldExist == 1) { - LinkedListItem *cur = list_cur ? list_cur : TNew(); - TDo(p, (T *)cur); - if (!list_cur) { - if (p.mode == PointerWrap::MODE_READ) { - cur->next = 0; - list_cur = cur; - if (prev) - prev->next = cur; - else - list_start = cur; - } else { - TFree(cur); - continue; - } - } - } else { - if (shouldExist != 0) { - WARN_LOG(SAVESTATE, "Savestate failure: incorrect item marker %d", shouldExist); - p.SetError(p.ERROR_FAILURE); - } - if (p.mode == PointerWrap::MODE_READ) { - if (prev) - prev->next = nullptr; - if (list_end) - *list_end = prev; - if (list_cur) { - if (list_start == list_cur) - list_start = nullptr; - do { - LinkedListItem *next = list_cur->next; - TFree(list_cur); - list_cur = next; - } while (list_cur); - } - } - break; - } - prev = list_cur; - list_cur = list_cur->next; - } -} diff --git a/Common/ChunkFileDoDeque.h b/Common/ChunkFileDoDeque.h new file mode 100644 index 0000000000..1c2aa9339e --- /dev/null +++ b/Common/ChunkFileDoDeque.h @@ -0,0 +1,44 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +// Templates for save state serialization. See ChunkFile.h. +#include +#include "Common/ChunkFileDo.h" + +template +void DoDeque(PointerWrap &p, std::deque &x, T &default_val) { + u32 deq_size = (u32)x.size(); + Do(p, deq_size); + x.resize(deq_size, default_val); + u32 i; + for (i = 0; i < deq_size; i++) + Do(p, x[i]); +} + +template +void Do(PointerWrap &p, std::deque &x) { + T *dv = nullptr; + DoDeque(p, x, dv); +} + +template +void Do(PointerWrap &p, std::deque &x) { + T dv = T(); + DoDeque(p, x, dv); +} diff --git a/Common/ChunkFileDoList.h b/Common/ChunkFileDoList.h new file mode 100644 index 0000000000..1ae1a2a12d --- /dev/null +++ b/Common/ChunkFileDoList.h @@ -0,0 +1,101 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +// Templates for save state serialization. See ChunkFile.h. +#include +#include "Common/ChunkFileDo.h" + +template +void DoList(PointerWrap &p, std::list &x, T &default_val) { + u32 list_size = (u32)x.size(); + Do(p, list_size); + x.resize(list_size, default_val); + + typename std::list::iterator itr, end; + for (itr = x.begin(), end = x.end(); itr != end; ++itr) + Do(p, *itr); +} + +template +void Do(PointerWrap &p, std::list &x) { + T *dv = nullptr; + Do(p, x, dv); +} + +template +void Do(PointerWrap &p, std::list &x) { + T dv = T(); + DoList(p, x, dv); +} + +template +void Do(PointerWrap &p, std::list &x, T &default_val) { + DoList(p, x, default_val); +} + +template *(*TNew)(), void (*TFree)(LinkedListItem *), void (*TDo)(PointerWrap &, T *)> +void DoLinkedList(PointerWrap &p, LinkedListItem *&list_start, LinkedListItem **list_end = nullptr) { + LinkedListItem *list_cur = list_start; + LinkedListItem *prev = nullptr; + + while (true) { + u8 shouldExist = (list_cur ? 1 : 0); + Do(p, shouldExist); + if (shouldExist == 1) { + LinkedListItem *cur = list_cur ? list_cur : TNew(); + TDo(p, (T *)cur); + if (!list_cur) { + if (p.mode == PointerWrap::MODE_READ) { + cur->next = 0; + list_cur = cur; + if (prev) + prev->next = cur; + else + list_start = cur; + } else { + TFree(cur); + continue; + } + } + } else { + if (shouldExist != 0) { + WARN_LOG(SAVESTATE, "Savestate failure: incorrect item marker %d", shouldExist); + p.SetError(p.ERROR_FAILURE); + } + if (p.mode == PointerWrap::MODE_READ) { + if (prev) + prev->next = nullptr; + if (list_end) + *list_end = prev; + if (list_cur) { + if (list_start == list_cur) + list_start = nullptr; + do { + LinkedListItem *next = list_cur->next; + TFree(list_cur); + list_cur = next; + } while (list_cur); + } + } + break; + } + prev = list_cur; + list_cur = list_cur->next; + } +} diff --git a/Common/ChunkFileDoMap.h b/Common/ChunkFileDoMap.h new file mode 100644 index 0000000000..5c01a244c8 --- /dev/null +++ b/Common/ChunkFileDoMap.h @@ -0,0 +1,164 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +// Templates for save state serialization. See ChunkFile.h. +#include +#include +#include "Common/ChunkFileDo.h" + +template +void DoMap(PointerWrap &p, M &x, typename M::mapped_type &default_val) { + unsigned int number = (unsigned int)x.size(); + Do(p, number); + switch (p.mode) { + case PointerWrap::MODE_READ: + { + x.clear(); + while (number > 0) { + typename M::key_type first = typename M::key_type(); + Do(p, first); + typename M::mapped_type second = default_val; + Do(p, second); + x[first] = second; + --number; + } + } + break; + case PointerWrap::MODE_WRITE: + case PointerWrap::MODE_MEASURE: + case PointerWrap::MODE_VERIFY: + { + typename M::iterator itr = x.begin(); + while (number > 0) { + typename M::key_type first = itr->first; + Do(p, first); + Do(p, itr->second); + --number; + ++itr; + } + } + break; + } +} + +template +void Do(PointerWrap &p, std::map &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (it->second != nullptr) + delete it->second; + } + } + T *dv = nullptr; + DoMap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::map &x) { + T dv = T(); + DoMap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::unordered_map &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (it->second != nullptr) + delete it->second; + } + } + T *dv = nullptr; + DoMap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::unordered_map &x) { + T dv = T(); + DoMap(p, x, dv); +} + +template +void DoMultimap(PointerWrap &p, M &x, typename M::mapped_type &default_val) { + unsigned int number = (unsigned int)x.size(); + Do(p, number); + switch (p.mode) { + case PointerWrap::MODE_READ: + { + x.clear(); + while (number > 0) { + typename M::key_type first = typename M::key_type(); + Do(p, first); + typename M::mapped_type second = default_val; + Do(p, second); + x.insert(std::make_pair(first, second)); + --number; + } + } + break; + case PointerWrap::MODE_WRITE: + case PointerWrap::MODE_MEASURE: + case PointerWrap::MODE_VERIFY: + { + typename M::iterator itr = x.begin(); + while (number > 0) { + Do(p, itr->first); + Do(p, itr->second); + --number; + ++itr; + } + } + break; + } +} + +template +void Do(PointerWrap &p, std::multimap &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (it->second != nullptr) + delete it->second; + } + } + T *dv = nullptr; + DoMultimap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::multimap &x) { + T dv = T(); + DoMultimap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::unordered_multimap &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (it->second != nullptr) + delete it->second; + } + } + T *dv = nullptr; + DoMultimap(p, x, dv); +} + +template +void Do(PointerWrap &p, std::unordered_multimap &x) { + T dv = T(); + DoMultimap(p, x, dv); +} diff --git a/Common/ChunkFileDoSet.h b/Common/ChunkFileDoSet.h new file mode 100644 index 0000000000..ff2186b9f2 --- /dev/null +++ b/Common/ChunkFileDoSet.h @@ -0,0 +1,69 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +// Templates for save state serialization. See ChunkFile.h. +#include +#include "Common/ChunkFileDo.h" + +template +void DoSet(PointerWrap &p, std::set &x) { + unsigned int number = (unsigned int)x.size(); + Do(p, number); + + switch (p.mode) { + case PointerWrap::MODE_READ: + { + x.clear(); + while (number-- > 0) { + T it = T(); + Do(p, it); + x.insert(it); + } + } + break; + case PointerWrap::MODE_WRITE: + case PointerWrap::MODE_MEASURE: + case PointerWrap::MODE_VERIFY: + { + typename std::set::iterator itr = x.begin(); + while (number-- > 0) + Do(p, *itr++); + } + break; + + default: + ERROR_LOG(SAVESTATE, "Savestate error: invalid mode %d.", p.mode); + } +} + +template +void Do(PointerWrap &p, std::set &x) { + if (p.mode == PointerWrap::MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { + if (*it != nullptr) + delete *it; + } + } + DoSet(p, x); +} + +template +void Do(PointerWrap &p, std::set &x) { + DoSet(p, x); +} diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 8c49a4c15c..7819370885 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -24,7 +24,7 @@ #include "profiler/profiler.h" #include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoList.h" #include "Common/MsgHandler.h" #include "Core/CoreTiming.h" #include "Core/Core.h" diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 190e6c41cd..f663c61518 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -24,6 +24,7 @@ #include "i18n/i18n.h" #include "thread/threadutil.h" +#include "Common/FileUtil.h" #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" #include "Core/FileSystems/MetaFileSystem.h" diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index b40a336243..b4d545a25d 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -20,6 +20,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Common/StringUtils.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/HLE/sceKernelThread.h" diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 1e30c5112a..1781bc4aec 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -38,6 +38,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/Config.h" #include "Core/CoreTiming.h" #include "Core/CoreParameter.h" diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 605beda7da..786d7b0ed4 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -9,6 +9,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceFont.h" diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 625fa1b3d0..7e90b9e8a4 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -21,6 +21,8 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoList.h" +#include "Common/ChunkFileDoMap.h" #include "Common/ThreadSafeList.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" diff --git a/Core/HLE/sceHeap.cpp b/Core/HLE/sceHeap.cpp index 61bf921012..edf8b82698 100644 --- a/Core/HLE/sceHeap.cpp +++ b/Core/HLE/sceHeap.cpp @@ -17,6 +17,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/MemMap.h" #include "Core/Reporting.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 93d9adb3ec..9f1a167f66 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -23,6 +23,9 @@ #include "profiler/profiler.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" +#include "Common/ChunkFileDoSet.h" +#include "Common/FileUtil.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/Core/HLE/sceKernelAlarm.cpp b/Core/HLE/sceKernelAlarm.cpp index 94cd258f96..ce78663ded 100644 --- a/Core/HLE/sceKernelAlarm.cpp +++ b/Core/HLE/sceKernelAlarm.cpp @@ -15,15 +15,16 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoList.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelAlarm.h" #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/HLE.h" #include "Core/CoreTiming.h" #include "Core/MemMap.h" -#include const int NATIVEALARM_SIZE = 20; diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index db79bd4f62..fac0cc1164 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -17,6 +17,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index d065fcce14..fe7b00a9e1 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -21,6 +21,8 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoList.h" +#include "Common/ChunkFileDoMap.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index e881363b7b..d18fe88b5a 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -19,6 +19,7 @@ #include #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelMbx.h" diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 73e53538df..3965469280 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -22,6 +22,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/System.h" diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index fe51c77699..8d4d0f85c0 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -24,6 +24,7 @@ #include "base/stringutil.h" #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoSet.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 67d0c58e86..632e9815b6 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -19,6 +19,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/Reporting.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index cafc38d289..527a4ffc7a 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -20,6 +20,7 @@ #include #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 0f81cc43c4..3d74bffa3d 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -18,6 +18,7 @@ #include #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 9ff2fcb8d3..d6c64f87e1 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -16,16 +16,18 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include #include #include #include -#include #include "base/logging.h" #include "Common/LogManager.h" #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoList.h" +#include "Common/ChunkFileDoMap.h" #include "Common/CommonTypes.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" diff --git a/Core/HLE/sceKernelVTimer.cpp b/Core/HLE/sceKernelVTimer.cpp index 3a3d4e2be0..643ca3a5ab 100644 --- a/Core/HLE/sceKernelVTimer.cpp +++ b/Core/HLE/sceKernelVTimer.cpp @@ -16,8 +16,10 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoList.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" diff --git a/Core/HLE/sceMp3.cpp b/Core/HLE/sceMp3.cpp index b94b06dcb2..048d4df1ef 100644 --- a/Core/HLE/sceMp3.cpp +++ b/Core/HLE/sceMp3.cpp @@ -19,6 +19,7 @@ #include #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/Config.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" diff --git a/Core/HLE/sceMp4.cpp b/Core/HLE/sceMp4.cpp index 0bbf4edaa8..646ef63e9e 100644 --- a/Core/HLE/sceMp4.cpp +++ b/Core/HLE/sceMp4.cpp @@ -18,6 +18,7 @@ #include #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/Reporting.h" diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 8a79a786f2..d9f264cfa0 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -21,6 +21,7 @@ #include #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Common/Swap.h" #include "Core/HLE/sceMpeg.h" #include "Core/HLE/sceKernelModule.h" diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index e3936c4841..f7acd4e851 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -27,6 +27,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernelMemory.h" diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 54562f0dd2..174e9ed930 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -30,6 +30,7 @@ #include "Core/MemMapHelpers.h" #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/Util/PortManager.h" diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 74c4f7242a..e02da6b4f1 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -17,6 +17,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" #include "Core/System.h" diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 12c8a53a1b..e609a14592 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -21,6 +21,7 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/Loaders.h" #include "Core/MemMap.h" #include "Core/System.h" diff --git a/Core/HLE/sceUsbGps.cpp b/Core/HLE/sceUsbGps.cpp index b7e1be9902..dce4fe5fb3 100644 --- a/Core/HLE/sceUsbGps.cpp +++ b/Core/HLE/sceUsbGps.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "base/NativeApp.h" #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index d1a13e1fc2..29e745a7f4 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -22,6 +22,8 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" +#include "Common/ChunkFileDoSet.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HW/AsyncIOManager.cpp b/Core/HW/AsyncIOManager.cpp index 98a15f5c48..78f636b809 100644 --- a/Core/HW/AsyncIOManager.cpp +++ b/Core/HW/AsyncIOManager.cpp @@ -20,6 +20,8 @@ #include "Common/ChunkFile.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" +#include "Common/ChunkFileDoSet.h" #include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "Core/System.h" diff --git a/Core/HW/BufferQueue.cpp b/Core/HW/BufferQueue.cpp index 14ece774e1..8051720d6c 100644 --- a/Core/HW/BufferQueue.cpp +++ b/Core/HW/BufferQueue.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoMap.h" #include "Core/HW/BufferQueue.h" void BufferQueue::DoState(PointerWrap &p) { diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 5063911293..9c07d83280 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "base/logging.h" #include "ext/xxhash.h" #include "profiler/profiler.h" diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index ea680cb957..a993b98947 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -24,6 +24,7 @@ #include "Common/ChunkFileDo.h" #include "Common/CPUDetect.h" +#include "Common/FileUtil.h" #include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/Config.h" diff --git a/Core/System.cpp b/Core/System.cpp index 2d0ced0c6b..f64754e22d 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -38,6 +38,7 @@ #include "thread/threadutil.h" #include "util/text/utf8.h" +#include "Common/FileUtil.h" #include "Common/GraphicsContext.h" #include "Core/MemFault.h" #include "Core/HDRemaster.h" diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 0d4e0035e3..3c3f881aae 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -20,6 +20,7 @@ #include "i18n/i18n.h" #include "Common/ChunkFile.h" +#include "Common/FileUtil.h" #include "Common/GraphicsContext.h" #include "Core/Config.h" diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index c5f75b5255..48d0a332e9 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -6,6 +6,7 @@ #include "profiler/profiler.h" #include "Common/ChunkFileDo.h" +#include "Common/ChunkFileDoList.h" #include "Common/ColorConv.h" #include "Common/GraphicsContext.h" #include "Core/Reporting.h" diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index a912f4b781..7000084dcb 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -23,6 +23,7 @@ #include "profiler/profiler.h" #include "Common/ChunkFile.h" +#include "Common/FileUtil.h" #include "Common/GraphicsContext.h" #include "Core/Config.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 6a3447cdc3..03296a8f28 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -11,6 +11,7 @@ #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" +#include "Common/FileUtil.h" #include "Common/Log.h" #include "Common/LogManager.h" #include "Common/ConsoleListener.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index 4039264bd0..9a2bcce356 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -21,6 +21,7 @@ #include #include "Common/CommonWindows.h" +#include "Common/FileUtil.h" #include "Common/OSVersion.h" #include "Common/Vulkan/VulkanLoader.h" #include "ppsspp_config.h" From d0f3cfeb9bd4154b27d09bf0a560cb0f7fbb4b72 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 06:39:13 +0000 Subject: [PATCH 470/848] Global: Remove some unused header code. --- Common/Common.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/Common/Common.h b/Common/Common.h index afd4176a10..9fffa42922 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -33,8 +33,6 @@ #define LOGGING 1 #endif -#define STACKALIGN - #include "Log.h" #include "CommonTypes.h" #include "CommonFuncs.h" @@ -45,17 +43,7 @@ void operator =(const t &other) = delete; #endif -#ifdef __APPLE__ -// The Darwin ABI requires that stack frames be aligned to 16-byte boundaries. -// This is only needed on i386 gcc - x86_64 already aligns to 16 bytes. -#if defined __i386__ && defined __GNUC__ -#undef STACKALIGN -#define STACKALIGN __attribute__((__force_align_arg_pointer__)) -#endif - -#define CHECK_HEAP_INTEGRITY() - -#elif defined(_WIN32) +#if defined(_WIN32) // Memory leak checks #define CHECK_HEAP_INTEGRITY() From b8342fb8ec52e071edcccecc6ffd2410a4c1641b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 00:12:51 -0700 Subject: [PATCH 471/848] SaveState: Rename ChunkFile files to Serialize. Makes more sense and less weird than ChunkFileDoMap, etc. --- CMakeLists.txt | 10 ++++--- Common/Common.vcxproj | 10 ++++--- Common/Common.vcxproj.filters | 27 ++++++++++++++++--- Common/FixedSizeQueue.h | 4 +-- .../SerializeDeque.h} | 4 +-- .../SerializeFuncs.h} | 4 +-- .../SerializeList.h} | 4 +-- .../SerializeMap.h} | 4 +-- .../SerializeSet.h} | 4 +-- .../Serializer.cpp} | 4 +-- .../{ChunkFile.h => Serialize/Serializer.h} | 0 Core/CoreTiming.cpp | 4 +-- Core/CwCheat.cpp | 4 +-- Core/Dialog/PSPDialog.cpp | 4 +-- Core/Dialog/PSPGamedataInstallDialog.cpp | 4 +-- Core/Dialog/PSPMsgDialog.cpp | 4 +-- Core/Dialog/PSPNetconfDialog.cpp | 4 +-- Core/Dialog/PSPOskDialog.cpp | 4 +-- Core/Dialog/PSPSaveDialog.cpp | 4 +-- Core/Dialog/PSPScreenshotDialog.cpp | 4 +-- Core/Dialog/SavedataParam.cpp | 4 +-- Core/FileSystems/DirectoryFileSystem.cpp | 4 +-- Core/FileSystems/FileSystem.cpp | 4 +-- Core/FileSystems/ISOFileSystem.cpp | 4 +-- Core/FileSystems/MetaFileSystem.cpp | 6 ++--- Core/FileSystems/VirtualDiscFileSystem.cpp | 4 +-- Core/Font/PGF.cpp | 4 +-- Core/HLE/HLE.cpp | 2 +- Core/HLE/HLEHelperThread.cpp | 4 +-- Core/HLE/ThreadQueueList.h | 2 +- Core/HLE/__sceAudio.cpp | 4 +-- Core/HLE/proAdhoc.cpp | 2 +- Core/HLE/proAdhoc.h | 2 +- Core/HLE/sceAtrac.cpp | 4 +-- Core/HLE/sceAudio.cpp | 4 +-- Core/HLE/sceAudiocodec.cpp | 4 +-- Core/HLE/sceCcc.cpp | 4 +-- Core/HLE/sceCtrl.cpp | 4 +-- Core/HLE/sceDisplay.cpp | 6 ++--- Core/HLE/sceDmac.cpp | 4 +-- Core/HLE/sceFont.cpp | 6 ++--- Core/HLE/sceGe.cpp | 8 +++--- Core/HLE/sceHeap.cpp | 6 ++--- Core/HLE/sceImpose.cpp | 4 +-- Core/HLE/sceIo.cpp | 6 ++--- Core/HLE/sceJpeg.cpp | 4 +-- Core/HLE/sceKernel.cpp | 2 +- Core/HLE/sceKernelAlarm.cpp | 6 ++--- Core/HLE/sceKernelEventFlag.cpp | 6 ++--- Core/HLE/sceKernelHeap.cpp | 4 +-- Core/HLE/sceKernelInterrupt.cpp | 8 +++--- Core/HLE/sceKernelMbx.cpp | 6 ++--- Core/HLE/sceKernelMemory.cpp | 6 ++--- Core/HLE/sceKernelModule.cpp | 6 ++--- Core/HLE/sceKernelMsgPipe.cpp | 6 ++--- Core/HLE/sceKernelMutex.cpp | 6 ++--- Core/HLE/sceKernelSemaphore.cpp | 6 ++--- Core/HLE/sceKernelThread.cpp | 10 +++---- Core/HLE/sceKernelTime.cpp | 4 +-- Core/HLE/sceKernelVTimer.cpp | 6 ++--- Core/HLE/sceMp3.cpp | 4 +-- Core/HLE/sceMp4.cpp | 4 +-- Core/HLE/sceMpeg.cpp | 4 +-- Core/HLE/sceNet.cpp | 6 ++--- Core/HLE/sceNetAdhoc.cpp | 6 ++--- Core/HLE/scePower.cpp | 4 +-- Core/HLE/scePsmf.cpp | 6 ++--- Core/HLE/sceRtc.cpp | 4 +-- Core/HLE/sceSas.cpp | 2 +- Core/HLE/sceSsl.cpp | 4 +-- Core/HLE/sceUmd.cpp | 6 ++--- Core/HLE/sceUsb.cpp | 4 +-- Core/HLE/sceUsbCam.cpp | 4 +-- Core/HLE/sceUsbGps.cpp | 4 +-- Core/HLE/sceUsbMic.cpp | 4 +-- Core/HLE/sceUtility.cpp | 8 +++--- Core/HLE/sceVaudio.cpp | 4 +-- Core/HW/AsyncIOManager.cpp | 8 +++--- Core/HW/BufferQueue.cpp | 4 +-- Core/HW/BufferQueue.h | 2 +- Core/HW/MediaEngine.cpp | 2 +- Core/HW/MemoryStick.cpp | 4 +-- Core/HW/MpegDemux.cpp | 2 +- Core/HW/SasAudio.cpp | 2 +- Core/HW/SimpleAudioDec.cpp | 2 +- Core/HW/StereoResampler.cpp | 2 +- Core/HW/StereoResampler.h | 2 +- Core/MIPS/IR/IRFrontend.cpp | 4 +-- Core/MIPS/IR/IRJit.cpp | 2 +- Core/MIPS/JitCommon/JitCommon.cpp | 4 +-- Core/MIPS/MIPS.cpp | 4 +-- Core/MIPS/MIPS/MipsJit.cpp | 2 +- Core/MIPS/fake/FakeJit.cpp | 2 +- Core/MIPS/x86/Jit.cpp | 4 +-- Core/MemMap.cpp | 4 +-- Core/Reporting.cpp | 2 +- Core/SaveState.cpp | 4 +-- Core/SaveState.h | 2 +- Core/Util/BlockAllocator.cpp | 4 +-- Core/Util/PPGeDraw.cpp | 4 +-- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GPUCommon.cpp | 6 ++--- GPU/GPUState.cpp | 4 +-- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- UI/BackgroundAudio.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 10 ++++--- UWP/CommonUWP/CommonUWP.vcxproj.filters | 10 ++++--- android/jni/Android.mk | 2 +- libretro/Makefile.common | 2 +- libretro/libretro.cpp | 2 +- 112 files changed, 268 insertions(+), 231 deletions(-) rename Common/{ChunkFileDoDeque.h => Serialize/SerializeDeque.h} (91%) rename Common/{ChunkFileDo.h => Serialize/SerializeFuncs.h} (96%) rename Common/{ChunkFileDoList.h => Serialize/SerializeList.h} (96%) rename Common/{ChunkFileDoMap.h => Serialize/SerializeMap.h} (97%) rename Common/{ChunkFileDoSet.h => Serialize/SerializeSet.h} (93%) rename Common/{ChunkFile.cpp => Serialize/Serializer.cpp} (99%) rename Common/{ChunkFile.h => Serialize/Serializer.h} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09ca275110..0137d06d5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -416,9 +416,13 @@ add_library(Common STATIC ${CommonVulkan} Common/ColorConv.cpp Common/ColorConv.h - Common/ChunkFile.cpp - Common/ChunkFile.h - Common/ChunkFileDo.h + Common/Serialize/Serializer.cpp + Common/Serialize/Serializer.h + Common/Serialize/SerializeDeque.h + Common/Serialize/SerializeFuncs.h + Common/Serialize/SerializeList.h + Common/Serialize/SerializeMap.h + Common/Serialize/SerializeSet.h Common/ConsoleListener.cpp Common/ConsoleListener.h Common/Crypto/md5.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index c54bc30238..40a9f61a06 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -354,9 +354,12 @@ - + + - + + + @@ -406,6 +409,7 @@ + @@ -445,7 +449,7 @@ false false - + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index a19ee2e281..92551a3e85 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -3,7 +3,6 @@ - @@ -76,7 +75,24 @@ - + + Serialize + + + Serialize + + + Serialize + + + Serialize + + + Serialize + + + Serialize + @@ -106,7 +122,6 @@ Crypto - @@ -141,6 +156,9 @@ Vulkan + + Serialize + @@ -155,5 +173,8 @@ {c14d66ef-5f7c-4565-975a-72774e7ccfb9} + + {7be79ad5-3520-46a1-a370-dce2a943978c} + \ No newline at end of file diff --git a/Common/FixedSizeQueue.h b/Common/FixedSizeQueue.h index 03ebf5c41f..ed7eb14a75 100644 --- a/Common/FixedSizeQueue.h +++ b/Common/FixedSizeQueue.h @@ -18,8 +18,8 @@ #pragma once #include -#include "ChunkFile.h" -#include "MemoryUtil.h" +#include "Common/MemoryUtil.h" +#include "Common/Serialize/Serializer.h" // STL-look-a-like interface, but name is mixed case to distinguish it clearly from the // real STL classes. diff --git a/Common/ChunkFileDoDeque.h b/Common/Serialize/SerializeDeque.h similarity index 91% rename from Common/ChunkFileDoDeque.h rename to Common/Serialize/SerializeDeque.h index 1c2aa9339e..d0dc8adbb0 100644 --- a/Common/ChunkFileDoDeque.h +++ b/Common/Serialize/SerializeDeque.h @@ -17,9 +17,9 @@ #pragma once -// Templates for save state serialization. See ChunkFile.h. +// Templates for save state serialization. See Serializer.h. #include -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" template void DoDeque(PointerWrap &p, std::deque &x, T &default_val) { diff --git a/Common/ChunkFileDo.h b/Common/Serialize/SerializeFuncs.h similarity index 96% rename from Common/ChunkFileDo.h rename to Common/Serialize/SerializeFuncs.h index e43f229e8a..3080749fa3 100644 --- a/Common/ChunkFileDo.h +++ b/Common/Serialize/SerializeFuncs.h @@ -17,10 +17,10 @@ #pragma once -// Templates for save state serialization. See ChunkFile.h. +// Templates for save state serialization. See Serializer.h. #include #include -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Common/Swap.h" void Do(PointerWrap &p, std::string &x); diff --git a/Common/ChunkFileDoList.h b/Common/Serialize/SerializeList.h similarity index 96% rename from Common/ChunkFileDoList.h rename to Common/Serialize/SerializeList.h index 1ae1a2a12d..ff4ed57a9a 100644 --- a/Common/ChunkFileDoList.h +++ b/Common/Serialize/SerializeList.h @@ -17,9 +17,9 @@ #pragma once -// Templates for save state serialization. See ChunkFile.h. +// Templates for save state serialization. See Serializer.h. #include -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" template void DoList(PointerWrap &p, std::list &x, T &default_val) { diff --git a/Common/ChunkFileDoMap.h b/Common/Serialize/SerializeMap.h similarity index 97% rename from Common/ChunkFileDoMap.h rename to Common/Serialize/SerializeMap.h index 5c01a244c8..9190f5067e 100644 --- a/Common/ChunkFileDoMap.h +++ b/Common/Serialize/SerializeMap.h @@ -17,10 +17,10 @@ #pragma once -// Templates for save state serialization. See ChunkFile.h. +// Templates for save state serialization. See Serializer.h. #include #include -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" template void DoMap(PointerWrap &p, M &x, typename M::mapped_type &default_val) { diff --git a/Common/ChunkFileDoSet.h b/Common/Serialize/SerializeSet.h similarity index 93% rename from Common/ChunkFileDoSet.h rename to Common/Serialize/SerializeSet.h index ff2186b9f2..7e22f21e56 100644 --- a/Common/ChunkFileDoSet.h +++ b/Common/Serialize/SerializeSet.h @@ -17,9 +17,9 @@ #pragma once -// Templates for save state serialization. See ChunkFile.h. +// Templates for save state serialization. See Serializer.h. #include -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" template void DoSet(PointerWrap &p, std::set &x) { diff --git a/Common/ChunkFile.cpp b/Common/Serialize/Serializer.cpp similarity index 99% rename from Common/ChunkFile.cpp rename to Common/Serialize/Serializer.cpp index 7252d46d68..c2eca8731e 100644 --- a/Common/ChunkFile.cpp +++ b/Common/Serialize/Serializer.cpp @@ -19,8 +19,8 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" diff --git a/Common/ChunkFile.h b/Common/Serialize/Serializer.h similarity index 100% rename from Common/ChunkFile.h rename to Common/Serialize/Serializer.h diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 7819370885..b87ee057ed 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -23,9 +23,9 @@ #include "base/logging.h" #include "profiler/profiler.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDoList.h" #include "Common/MsgHandler.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeList.h" #include "Core/CoreTiming.h" #include "Core/Core.h" #include "Core/Config.h" diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 1fb4a4623e..131c739ce1 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -4,8 +4,8 @@ #include #include "i18n/i18n.h" #include "Common/StringUtils.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/FileUtil.h" #include "Core/CoreTiming.h" #include "Core/CoreParameter.h" diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp index 4d7eda334a..fd01a96d4f 100644 --- a/Core/Dialog/PSPDialog.cpp +++ b/Core/Dialog/PSPDialog.cpp @@ -17,8 +17,8 @@ #include "i18n/i18n.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" #include "Core/CoreTiming.h" #include "Core/HLE/sceCtrl.h" diff --git a/Core/Dialog/PSPGamedataInstallDialog.cpp b/Core/Dialog/PSPGamedataInstallDialog.cpp index e8b239982d..319314fd20 100644 --- a/Core/Dialog/PSPGamedataInstallDialog.cpp +++ b/Core/Dialog/PSPGamedataInstallDialog.cpp @@ -17,8 +17,8 @@ #include #include "Common/Common.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/ELF/ParamSFO.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index b655dd6300..292c213558 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -16,8 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" #include "Core/Dialog/PSPMsgDialog.h" #include "Core/Dialog/PSPSaveDialog.h" diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 4a77d37a8c..1898cbcd94 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -16,8 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "i18n/i18n.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" #include "Core/Dialog/PSPNetconfDialog.h" #include "Core/MemMapHelpers.h" diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 4cec09e0c2..60bcb6d6f5 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -21,7 +21,7 @@ #include "math/math_util.h" #include "util/text/utf8.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Dialog/PSPOskDialog.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" @@ -29,7 +29,7 @@ #include "Core/HLE/sceUtility.h" #include "Core/Config.h" #include "Core/Reporting.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "GPU/GPUState.h" #ifndef _WIN32 diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index f663c61518..80b4f7c6e1 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -25,8 +25,8 @@ #include "thread/threadutil.h" #include "Common/FileUtil.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" diff --git a/Core/Dialog/PSPScreenshotDialog.cpp b/Core/Dialog/PSPScreenshotDialog.cpp index 2d5c847828..acec8d08d4 100644 --- a/Core/Dialog/PSPScreenshotDialog.cpp +++ b/Core/Dialog/PSPScreenshotDialog.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Dialog/PSPDialog.h" #include "Core/Dialog/PSPScreenshotDialog.h" #include "Core/HLE/sceKernel.h" diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 32374e98cf..1e021d94fc 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -17,8 +17,8 @@ #include "i18n/i18n.h" #include "base/logging.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Host.h" diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index b32f8cc1af..7edb316eef 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -23,8 +23,8 @@ #include "file/zip_read.h" #include "i18n/i18n.h" #include "util/text/utf8.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/FileUtil.h" #include "Core/FileSystems/DirectoryFileSystem.h" #include "Core/FileSystems/ISOFileSystem.h" diff --git a/Core/FileSystems/FileSystem.cpp b/Core/FileSystems/FileSystem.cpp index 7fae8183e7..40b527f562 100644 --- a/Core/FileSystems/FileSystem.cpp +++ b/Core/FileSystems/FileSystem.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/FileSystems/FileSystem.h" void PSPFileInfo::DoState(PointerWrap &p) { diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 7ead5c5e4d..04c52f14c6 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -22,8 +22,8 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/HLE/sceKernel.h" #include "Core/MemMap.h" diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index b4d545a25d..31f7bf5689 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -18,9 +18,9 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Common/StringUtils.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/HLE/sceKernelThread.h" diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 974823415d..df3375fffb 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -19,8 +19,8 @@ #include "Common/FileUtil.h" #include "Common/StringUtils.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/FileSystems/VirtualDiscFileSystem.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/HLE/sceKernel.h" diff --git a/Core/Font/PGF.cpp b/Core/Font/PGF.cpp index 074688676f..ae3afa57b8 100644 --- a/Core/Font/PGF.cpp +++ b/Core/Font/PGF.cpp @@ -21,8 +21,8 @@ // Some parts, especially in this file, were simply copied, so I guess this really makes this file GPL3. #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/MemMap.h" #include "Core/Reporting.h" #include "Core/Font/PGF.h" diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 6a731ef340..06cdf4f390 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -24,7 +24,7 @@ #include "base/timeutil.h" #include "profiler/profiler.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" #include "Core/Core.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/HLEHelperThread.cpp b/Core/HLE/HLEHelperThread.cpp index c84be0feca..a142820b92 100644 --- a/Core/HLE/HLEHelperThread.cpp +++ b/Core/HLE/HLEHelperThread.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/ThreadQueueList.h b/Core/HLE/ThreadQueueList.h index e08b9c07a5..72282e2a3f 100644 --- a/Core/HLE/ThreadQueueList.h +++ b/Core/HLE/ThreadQueueList.h @@ -18,7 +18,7 @@ #pragma once #include "Core/HLE/sceKernel.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" struct ThreadQueueList { // Number of queues (number of priority levels starting at 0.) diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index d8472edc47..57ef29281d 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -19,8 +19,8 @@ #include #include "Common/CommonTypes.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/FixedSizeQueue.h" #ifdef _M_SSE diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 6e22b3801f..681e11e493 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -33,7 +33,7 @@ #include #include "util/text/parsers.h" #include "thread/threadutil.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Core.h" #include "Core/Host.h" #include "Core/HLE/sceKernelInterrupt.h" diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index b84a13de6d..e5d39745ee 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -43,7 +43,7 @@ #include "base/timeutil.h" #include "net/resolve.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Core/Config.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index fb54546fdb..bdaeea8b98 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -17,8 +17,8 @@ #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index c5d2d54a0a..41eb487167 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/FixedSizeQueue.h" #include "Core/MIPS/MIPS.h" #include "Core/Host.h" diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index 2e29668cdd..d21be884b8 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceAudiocodec.h" diff --git a/Core/HLE/sceCcc.cpp b/Core/HLE/sceCcc.cpp index 7040a5f329..2dba0143cd 100644 --- a/Core/HLE/sceCcc.cpp +++ b/Core/HLE/sceCcc.cpp @@ -19,8 +19,8 @@ #include "util/text/utf16.h" #include "util/text/shiftjis.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Debugger/Breakpoints.h" #include "Core/MemMap.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index 28957509b2..a87cba554f 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -18,8 +18,8 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 1781bc4aec..5551513e7f 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -36,9 +36,9 @@ #include "gfx_es2/gpu_features.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/Config.h" #include "Core/CoreTiming.h" #include "Core/CoreParameter.h" diff --git a/Core/HLE/sceDmac.cpp b/Core/HLE/sceDmac.cpp index 9290cc4d76..4f186facfe 100644 --- a/Core/HLE/sceDmac.cpp +++ b/Core/HLE/sceDmac.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 786d7b0ed4..4577aa5d83 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -7,9 +7,9 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceFont.h" diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 7e90b9e8a4..0cdae03b8a 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -19,10 +19,10 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoList.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeList.h" +#include "Common/Serialize/SerializeMap.h" #include "Common/ThreadSafeList.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" diff --git a/Core/HLE/sceHeap.cpp b/Core/HLE/sceHeap.cpp index edf8b82698..0de98e1443 100644 --- a/Core/HLE/sceHeap.cpp +++ b/Core/HLE/sceHeap.cpp @@ -15,9 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/MemMap.h" #include "Core/Reporting.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceImpose.cpp b/Core/HLE/sceImpose.cpp index 8a3b60fec0..086cc83c17 100644 --- a/Core/HLE/sceImpose.cpp +++ b/Core/HLE/sceImpose.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceImpose.h" diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 9f1a167f66..16206298f2 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -22,10 +22,10 @@ #include "thread/threadutil.h" #include "profiler/profiler.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" -#include "Common/ChunkFileDoSet.h" #include "Common/FileUtil.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" +#include "Common/Serialize/SerializeSet.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index feb0c0ea58..aa6d554ded 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -19,8 +19,8 @@ #include "ext/jpge/jpgd.h" #include "Common/Common.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceJpeg.h" diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 30fe5dc999..6521f3e79c 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/LogManager.h" #include "Core/Core.h" #include "Core/Config.h" diff --git a/Core/HLE/sceKernelAlarm.cpp b/Core/HLE/sceKernelAlarm.cpp index ce78663ded..d6b12703df 100644 --- a/Core/HLE/sceKernelAlarm.cpp +++ b/Core/HLE/sceKernelAlarm.cpp @@ -16,9 +16,9 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoList.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeList.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelAlarm.h" #include "Core/HLE/sceKernelInterrupt.h" diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index fac0cc1164..b4c28732b6 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -15,9 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index e73f9f60c6..0399f3a0a6 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -1,7 +1,7 @@ #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernel.h" diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index fe7b00a9e1..8d8e4124db 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -19,10 +19,10 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoList.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeList.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index d18fe88b5a..29ff672e2a 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -17,9 +17,9 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelMbx.h" diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 3965469280..7da8bc4ef2 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -20,9 +20,9 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/System.h" diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 8d4d0f85c0..c049729246 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -22,9 +22,9 @@ #include "zlib.h" #include "base/stringutil.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoSet.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeSet.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 632e9815b6..2df1f2d105 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -17,9 +17,9 @@ #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/Reporting.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index 527a4ffc7a..1b6b314764 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -18,9 +18,9 @@ #include #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 3d74bffa3d..0b90a3067c 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -16,9 +16,9 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HLE/HLE.h" #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index d6c64f87e1..5e4ebe84d1 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -23,12 +23,12 @@ #include "base/logging.h" -#include "Common/LogManager.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoList.h" -#include "Common/ChunkFileDoMap.h" #include "Common/CommonTypes.h" +#include "Common/LogManager.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeList.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" #include "Core/MIPS/MIPSAnalyst.h" diff --git a/Core/HLE/sceKernelTime.cpp b/Core/HLE/sceKernelTime.cpp index 64b454f7e4..8bfa812e30 100644 --- a/Core/HLE/sceKernelTime.cpp +++ b/Core/HLE/sceKernelTime.cpp @@ -23,8 +23,8 @@ #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/CoreTiming.h" #include "Core/HLE/HLE.h" #include "Core/HLE/sceKernel.h" diff --git a/Core/HLE/sceKernelVTimer.cpp b/Core/HLE/sceKernelVTimer.cpp index 643ca3a5ab..245db8a395 100644 --- a/Core/HLE/sceKernelVTimer.cpp +++ b/Core/HLE/sceKernelVTimer.cpp @@ -17,9 +17,9 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoList.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeList.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" diff --git a/Core/HLE/sceMp3.cpp b/Core/HLE/sceMp3.cpp index 048d4df1ef..b3bdcb9b18 100644 --- a/Core/HLE/sceMp3.cpp +++ b/Core/HLE/sceMp3.cpp @@ -18,8 +18,8 @@ #include #include -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/Config.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" diff --git a/Core/HLE/sceMp4.cpp b/Core/HLE/sceMp4.cpp index 646ef63e9e..376c4adeaf 100644 --- a/Core/HLE/sceMp4.cpp +++ b/Core/HLE/sceMp4.cpp @@ -17,8 +17,8 @@ #include -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/Reporting.h" diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index d9f264cfa0..6a10183fab 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -20,8 +20,8 @@ #include #include -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Common/Swap.h" #include "Core/HLE/sceMpeg.h" #include "Core/HLE/sceKernelModule.h" diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index f7acd4e851..a631ee09c9 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -25,9 +25,9 @@ #include "net/resolve.h" #include "util/text/parsers.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernelMemory.h" diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 174e9ed930..1260fcaead 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -28,9 +28,9 @@ #include "Core/Core.h" #include "Core/Host.h" #include "Core/MemMapHelpers.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/Util/PortManager.h" diff --git a/Core/HLE/scePower.cpp b/Core/HLE/scePower.cpp index 610e21234f..caa8e1d8fe 100644 --- a/Core/HLE/scePower.cpp +++ b/Core/HLE/scePower.cpp @@ -16,8 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index e02da6b4f1..0a601db8d4 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -15,9 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" #include "Core/System.h" diff --git a/Core/HLE/sceRtc.cpp b/Core/HLE/sceRtc.cpp index eb19ce95b2..f9ad48aa7e 100644 --- a/Core/HLE/sceRtc.cpp +++ b/Core/HLE/sceRtc.cpp @@ -26,8 +26,8 @@ #include #include "base/timeutil.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index 0e5f95f65e..a79e511ae7 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -35,7 +35,7 @@ #include "base/basictypes.h" #include "profiler/profiler.h" #include "thread/threadutil.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/Log.h" #include "Core/Config.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/sceSsl.cpp b/Core/HLE/sceSsl.cpp index 65efc6cde4..7361962d1d 100644 --- a/Core/HLE/sceSsl.cpp +++ b/Core/HLE/sceSsl.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MemMap.h" diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index e609a14592..9ff737f1b5 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -19,9 +19,9 @@ #include "file/file_util.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/Loaders.h" #include "Core/MemMap.h" #include "Core/System.h" diff --git a/Core/HLE/sceUsb.cpp b/Core/HLE/sceUsb.cpp index 6300be0118..60622c9cf0 100644 --- a/Core/HLE/sceUsb.cpp +++ b/Core/HLE/sceUsb.cpp @@ -16,8 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "base/NativeApp.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index 751952dbb9..4b3ec1a4ef 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -20,8 +20,8 @@ #include "base/NativeApp.h" #include "ppsspp_config.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/sceUsbCam.h" #include "Core/HLE/sceUsbMic.h" diff --git a/Core/HLE/sceUsbGps.cpp b/Core/HLE/sceUsbGps.cpp index dce4fe5fb3..3d014318ac 100644 --- a/Core/HLE/sceUsbGps.cpp +++ b/Core/HLE/sceUsbGps.cpp @@ -17,8 +17,8 @@ #include #include "base/NativeApp.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceUsbGps.h" diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 9f165ed064..30035f1584 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -18,8 +18,8 @@ #include #include "base/NativeApp.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernelThread.h" diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 29e745a7f4..0421c6bb67 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -20,10 +20,10 @@ #include "file/ini_file.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" -#include "Common/ChunkFileDoSet.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" +#include "Common/Serialize/SerializeSet.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HLE/sceVaudio.cpp b/Core/HLE/sceVaudio.cpp index de617a78b4..7d5819114f 100644 --- a/Core/HLE/sceVaudio.cpp +++ b/Core/HLE/sceVaudio.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Reporting.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" diff --git a/Core/HW/AsyncIOManager.cpp b/Core/HW/AsyncIOManager.cpp index 78f636b809..1d4ce89b0a 100644 --- a/Core/HW/AsyncIOManager.cpp +++ b/Core/HW/AsyncIOManager.cpp @@ -18,10 +18,10 @@ #include #include -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" -#include "Common/ChunkFileDoSet.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" +#include "Common/Serialize/SerializeSet.h" #include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "Core/System.h" diff --git a/Core/HW/BufferQueue.cpp b/Core/HW/BufferQueue.cpp index 8051720d6c..9fbffe0c65 100644 --- a/Core/HW/BufferQueue.cpp +++ b/Core/HW/BufferQueue.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoMap.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeMap.h" #include "Core/HW/BufferQueue.h" void BufferQueue::DoState(PointerWrap &p) { diff --git a/Core/HW/BufferQueue.h b/Core/HW/BufferQueue.h index b69782e985..b587b29498 100644 --- a/Core/HW/BufferQueue.h +++ b/Core/HW/BufferQueue.h @@ -19,7 +19,7 @@ #include #include -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" struct BufferQueue { BufferQueue(int size = 0x20000) { diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 83735a02ce..6b1d646bd1 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" #include "Core/Debugger/Breakpoints.h" #include "Core/HW/MediaEngine.h" diff --git a/Core/HW/MemoryStick.cpp b/Core/HW/MemoryStick.cpp index d04f116508..f2acf2991b 100644 --- a/Core/HW/MemoryStick.cpp +++ b/Core/HW/MemoryStick.cpp @@ -1,5 +1,5 @@ -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/CoreTiming.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/HW/MemoryStick.h" diff --git a/Core/HW/MpegDemux.cpp b/Core/HW/MpegDemux.cpp index d65db8d4cf..da121f72e0 100644 --- a/Core/HW/MpegDemux.cpp +++ b/Core/HW/MpegDemux.cpp @@ -1,4 +1,4 @@ -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HW/MpegDemux.h" #include "Core/Reporting.h" diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 7cb6db52d0..913c6948cf 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -20,7 +20,7 @@ #include "base/basictypes.h" #include "profiler/profiler.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/sceAtrac.h" #include "Core/Config.h" diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index 3730b299eb..b6a51438c9 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -17,7 +17,7 @@ #include -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HW/SimpleAudioDec.h" diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index 27617e3ba7..29ecf60b76 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -38,7 +38,7 @@ #include "base/logging.h" #include "base/timeutil.h" #include "base/NativeApp.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Common/MathUtil.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/Core/HW/StereoResampler.h b/Core/HW/StereoResampler.h index 451b598d66..4b10d032c0 100644 --- a/Core/HW/StereoResampler.h +++ b/Core/HW/StereoResampler.h @@ -22,7 +22,7 @@ #include #include -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Common/CommonTypes.h" struct AudioDebugStats; diff --git a/Core/MIPS/IR/IRFrontend.cpp b/Core/MIPS/IR/IRFrontend.cpp index d1ccfec8bf..86f6b0e198 100644 --- a/Core/MIPS/IR/IRFrontend.cpp +++ b/Core/MIPS/IR/IRFrontend.cpp @@ -17,8 +17,8 @@ #include "base/logging.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/SymbolMap.h" #include "Core/Reporting.h" diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 9c07d83280..12af157044 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -19,7 +19,7 @@ #include "base/logging.h" #include "ext/xxhash.h" #include "profiler/profiler.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Common/StringUtils.h" #include "Core/Core.h" diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index 232c099ec9..397cc85ad9 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -21,8 +21,8 @@ #include "ext/udis86/udis86.h" #include "Common/StringUtils.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Util/DisArm64.h" #include "Core/Config.h" diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 6415d5c57e..a85e5a9999 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -21,8 +21,8 @@ #include "math/math_util.h" #include "Common.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/ConfigValues.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSInt.h" diff --git a/Core/MIPS/MIPS/MipsJit.cpp b/Core/MIPS/MIPS/MipsJit.cpp index e7419bf305..345ff74018 100644 --- a/Core/MIPS/MIPS/MipsJit.cpp +++ b/Core/MIPS/MIPS/MipsJit.cpp @@ -20,7 +20,7 @@ #include "base/logging.h" #include "profiler/profiler.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Core/Reporting.h" #include "Core/Config.h" #include "Core/Core.h" diff --git a/Core/MIPS/fake/FakeJit.cpp b/Core/MIPS/fake/FakeJit.cpp index 1a521ee68b..25e085c0ed 100644 --- a/Core/MIPS/fake/FakeJit.cpp +++ b/Core/MIPS/fake/FakeJit.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "base/logging.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Core/Reporting.h" #include "Core/Config.h" #include "Core/Core.h" diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index f68993d3d8..fb4ec02292 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -24,8 +24,8 @@ #include "math/math_util.h" #include "profiler/profiler.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Core.h" #include "Core/MemMap.h" #include "Core/System.h" diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index d4d6bc9ed9..1a60d42b9c 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -27,8 +27,8 @@ #include "Common/Common.h" #include "Common/MemoryUtil.h" #include "Common/MemArena.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/MemMap.h" #include "Core/MemFault.h" diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index a993b98947..0447d6adb9 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -22,9 +22,9 @@ #include "Core/Reporting.h" -#include "Common/ChunkFileDo.h" #include "Common/CPUDetect.h" #include "Common/FileUtil.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/Config.h" diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 46d661b2ce..19a78cc6ac 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -26,8 +26,8 @@ #include "util/text/parsers.h" #include "Common/FileUtil.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/SaveState.h" #include "Core/Config.h" diff --git a/Core/SaveState.h b/Core/SaveState.h index 98b5d9b7d9..f2c1a3a426 100644 --- a/Core/SaveState.h +++ b/Core/SaveState.h @@ -19,7 +19,7 @@ #include #include -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" namespace SaveState { diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index 10d3d7e627..c302d8e91b 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -18,8 +18,8 @@ #include #include "Common/Log.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" #include "Core/Util/BlockAllocator.h" #include "Core/Reporting.h" diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 9b5cb865f4..356bd4ef90 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -26,8 +26,8 @@ #include "image/png_load.h" #include "util/text/utf8.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/HDRemaster.h" #include "Core/Host.h" #include "GPU/ge_constants.h" diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 8535d1fb5e..31a2faa449 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -36,7 +36,7 @@ #include -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Common/GraphicsContext.h" #include "base/NativeApp.h" #include "base/logging.h" diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 9c490edfa9..73049a864b 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -17,7 +17,7 @@ #include -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Common/GraphicsContext.h" #include "base/NativeApp.h" #include "base/logging.h" diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 3c3f881aae..1597ae0218 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -19,7 +19,7 @@ #include "profiler/profiler.h" #include "i18n/i18n.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 48d0a332e9..4b8d995983 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -5,16 +5,16 @@ #include "base/timeutil.h" #include "profiler/profiler.h" -#include "Common/ChunkFileDo.h" -#include "Common/ChunkFileDoList.h" #include "Common/ColorConv.h" #include "Common/GraphicsContext.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Common/Serialize/SerializeList.h" #include "Core/Reporting.h" #include "GPU/GeDisasm.h" #include "GPU/GPU.h" #include "GPU/GPUCommon.h" #include "GPU/GPUState.h" -#include "ChunkFile.h" #include "Core/Config.h" #include "Core/CoreTiming.h" #include "Core/MemMap.h" diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index c64e57d49f..bc62a3661b 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -18,8 +18,8 @@ #include "GPU/ge_constants.h" #include "GPU/GPUState.h" -#include "Common/ChunkFile.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/Serializer.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Core/CoreParameter.h" #include "Core/Config.h" #include "Core/System.h" diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 7000084dcb..eb31fbc95e 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -22,7 +22,7 @@ #include "base/timeutil.h" #include "profiler/profiler.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 7a25c34afa..16c8e5cea1 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -7,7 +7,7 @@ #include "file/vfs.h" #include "ui/root.h" -#include "Common/ChunkFileDo.h" +#include "Common/Serialize/SerializeFuncs.h" #include "Common/CommonTypes.h" #include "Common/FixedSizeQueue.h" #include "Core/HW/SimpleAudioDec.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 747a2a83f0..d07e29c0a5 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -384,8 +384,12 @@ - - + + + + + + @@ -429,7 +433,7 @@ - + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index ec50d08b2a..5a670fd890 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -11,7 +11,7 @@ - + @@ -55,8 +55,12 @@ - - + + + + + + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 9b2d62b92a..4f7d7c2899 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -205,7 +205,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Crypto/md5.cpp \ $(SRC)/Common/Crypto/sha1.cpp \ $(SRC)/Common/Crypto/sha256.cpp \ - $(SRC)/Common/ChunkFile.cpp \ + $(SRC)/Common/Serialize/Serializer.cpp \ $(SRC)/Common/ColorConv.cpp \ $(SRC)/Common/ExceptionHandlerSetup.cpp \ $(SRC)/Common/KeyMap.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index cf38aae92b..1a347a8acb 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -141,7 +141,7 @@ SOURCES_CXX += \ $(COMMONDIR)/Crypto/sha256.cpp SOURCES_CXX += \ - $(COMMONDIR)/ChunkFile.cpp \ + $(COMMONDIR)/Serialize/Serializer.cpp \ $(COMMONDIR)/ConsoleListener.cpp \ $(COMMONDIR)/ExceptionHandlerSetup.cpp \ $(COMMONDIR)/FileUtil.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 2c782a4b3c..6058b27670 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -6,7 +6,7 @@ #include #include "base/timeutil.h" -#include "Common/ChunkFile.h" +#include "Common/Serialize/Serializer.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Core.h" From df969a6c31283bce4278b25f07e36715f8cdde0b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 08:04:53 +0000 Subject: [PATCH 472/848] libretro: Buildfix. --- libretro/libretro.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 6058b27670..497cbae28d 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -6,6 +6,7 @@ #include #include "base/timeutil.h" +#include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" #include "Core/Config.h" #include "Core/ConfigValues.h" From 62a8329c33656e14e264067dcd7f340c1ffa2d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 10 Aug 2020 14:31:31 +0200 Subject: [PATCH 473/848] Remove sstream from stringutil.h. See #13267 --- Core/Config.cpp | 1 + Core/Util/GameManager.cpp | 1 + GPU/Vulkan/PipelineManagerVulkan.cpp | 1 + Windows/MainWindowMenu.cpp | 1 + ext/native/base/stringutil.cpp | 29 ++++++++++++++++++++++++-- ext/native/base/stringutil.h | 31 +++++----------------------- ext/native/file/ini_file.cpp | 5 +++-- ext/native/file/ini_file.h | 8 +++++++ ext/native/i18n/i18n.h | 1 - ext/native/ui/ui_screen.cpp | 2 ++ 10 files changed, 49 insertions(+), 31 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index d28e9c2494..52d5e3a847 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "base/display.h" #include "base/NativeApp.h" diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index da0617dd43..462aa02dbf 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "file/file_util.h" #ifdef SHARED_LIBZIP diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index e8898c144b..9986f1a523 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "profiler/profiler.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 03296a8f28..1533e21d5d 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "CommonWindows.h" #include diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp index 2861f844d3..3b42400c88 100644 --- a/ext/native/base/stringutil.cpp +++ b/ext/native/base/stringutil.cpp @@ -8,8 +8,8 @@ #define _GNU_SOURCE #include #endif -#include -#include +#include +#include #include #include #include @@ -240,6 +240,7 @@ bool TryParse(const std::string &str, uint32_t *const output) if (errno == ERANGE) return false; + // Range check if (ULONG_MAX > UINT_MAX) { #ifdef _MSC_VER #pragma warning (disable:4309) @@ -266,6 +267,30 @@ bool TryParse(const std::string &str, bool *const output) return true; } +template +bool TryParseImpl(const std::string &str, N *const output) { + std::istringstream iss(str); + N tmp = 0; + if (iss >> tmp) { + *output = tmp; + return true; + } else { + return false; + } +} + +bool TryParse(const std::string &str, int32_t *const output) { + return TryParseImpl(str, output); +} + +bool TryParse(const std::string &str, float *const output) { + return TryParseImpl(str, output); +} + +bool TryParse(const std::string &str, double *const output) { + return TryParseImpl(str, output); +} + void SplitString(const std::string& str, const char delim, std::vector& output) { size_t next = 0; diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h index c16602946f..255b588322 100644 --- a/ext/native/base/stringutil.h +++ b/ext/native/base/stringutil.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include "base/basictypes.h" @@ -37,7 +36,7 @@ inline bool startsWith(const std::string &str, const std::string &what) { inline bool endsWith(const std::string &str, const std::string &what) { if (str.size() < what.size()) return false; - return str.substr(str.size() - what.size()) == what; + return str.substr(str.size() - what.size()) == what; } // Only use on strings where you're only concerned about ASCII. @@ -56,10 +55,9 @@ inline bool endsWithNoCase(const std::string &str, const std::string &what) { void DataToHexString(const uint8_t *data, size_t size, std::string *output); inline void StringToHexString(const std::string &data, std::string *output) { - DataToHexString((uint8_t *)(&data[0]), data.size(), output); + DataToHexString((uint8_t *)(&data[0]), data.size(), output); } - // highly unsafe and not recommended. unsigned int parseHex(const char* _szValue); @@ -74,21 +72,10 @@ std::string StripQuotes(const std::string &s); bool TryParse(const std::string &str, bool *const output); bool TryParse(const std::string &str, uint32_t *const output); +bool TryParse(const std::string &str, int32_t *const output); +bool TryParse(const std::string &str, float *const output); +bool TryParse(const std::string &str, double *const output); -template -static bool TryParse(const std::string &str, N *const output) -{ - std::istringstream iss(str); - - N tmp = 0; - if (iss >> tmp) - { - *output = tmp; - return true; - } - else - return false; -} void SplitString(const std::string& str, const char delim, std::vector& output); void GetQuotedStrings(const std::string& str, std::vector& output); @@ -98,14 +85,6 @@ std::string ReplaceAll(std::string input, const std::string& src, const std::str // Compare two strings, ignore the difference between the ignorestr1 and the ignorestr2 in str1 and str2. int strcmpIgnore(std::string str1, std::string str2, std::string ignorestr1, std::string ignorestr2); -template -static std::string ValueToString(const N value) -{ - std::stringstream string; - string << value; - return string.str(); -} - void StringTrimEndNonAlphaNum(char *str); void SkipSpace(const char **ptr); void StringUpper(char *str); diff --git a/ext/native/file/ini_file.cpp b/ext/native/file/ini_file.cpp index 99bdcd163a..79a9f3ff8f 100644 --- a/ext/native/file/ini_file.cpp +++ b/ext/native/file/ini_file.cpp @@ -2,8 +2,8 @@ // Taken from Dolphin but relicensed by me, Henrik Rydgard, under the MIT // license as I wrote the whole thing originally and it has barely changed. -#include -#include +#include +#include #ifndef _MSC_VER #include @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "base/logging.h" diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h index ba63ab1ab5..1c8d1e3976 100644 --- a/ext/native/file/ini_file.h +++ b/ext/native/file/ini_file.h @@ -10,6 +10,14 @@ #include "base/stringutil.h" +template +inline std::string ValueToString(const N value) +{ + std::stringstream string; + string << value; + return string.str(); +} + class IniFile { public: diff --git a/ext/native/i18n/i18n.h b/ext/native/i18n/i18n.h index 75d8ddd776..cdffed3a29 100644 --- a/ext/native/i18n/i18n.h +++ b/ext/native/i18n/i18n.h @@ -9,7 +9,6 @@ // As usual, everything is UTF-8. Nothing else allowed. #include -#include #include #include #include diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index e2dba2cf60..3bfa8dcfe1 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -1,5 +1,7 @@ #include #include +#include + #include "base/display.h" #include "input/input_state.h" #include "input/keycodes.h" From d70dcaf53ab3af80cb651a0be2d421b08c907904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 10 Aug 2020 15:29:10 +0200 Subject: [PATCH 474/848] Buildfix --- ext/native/file/ini_file.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h index 1c8d1e3976..62029c00e2 100644 --- a/ext/native/file/ini_file.h +++ b/ext/native/file/ini_file.h @@ -104,14 +104,14 @@ public: for(size_t i = 0; i < temp.size(); i++) { std::vector key_val; - SplitString(temp[i],'_',key_val); - if(key_val.size() < 2) + SplitString(temp[i], '_', key_val); + if (key_val.size() < 2) continue; U mapKey; V mapValue; - if(!TryParse(key_val[0],&mapKey)) + if (!TryParse(key_val[0], &mapKey)) continue; - if(!TryParse(key_val[1],&mapValue)) + if (!TryParse(key_val[1], &mapValue)) continue; values[mapKey] = mapValue; } From 72d5b29434f55d63617c62558ccc5ff3e86deb19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 10 Aug 2020 15:46:21 +0200 Subject: [PATCH 475/848] Can't avoid sstream in ini_file.h, it seems. --- ext/native/file/ini_file.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h index 62029c00e2..98afb66248 100644 --- a/ext/native/file/ini_file.h +++ b/ext/native/file/ini_file.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "base/stringutil.h" From 5ec2da0f2dfe1b30de89221420546772d07be92a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 10 Aug 2020 15:53:52 +0200 Subject: [PATCH 476/848] Move Section out of IniFile so it can be forward declared. Unlocked further improvements to build speed. --- Common/ArmCPUDetect.cpp | 3 + Common/KeyMap.cpp | 4 +- Common/LogManager.cpp | 4 +- Common/LogManager.h | 4 +- Core/Config.cpp | 42 ++--- Core/Dialog/PSPSaveDialog.cpp | 1 + Core/FileSystems/DirectoryFileSystem.cpp | 2 + Core/SaveState.cpp | 1 + Core/Util/GameManager.cpp | 1 + GPU/Common/PostShader.cpp | 2 +- UI/CwCheatScreen.cpp | 1 + UI/PauseScreen.cpp | 2 + UI/RemoteISOScreen.cpp | 1 + UI/ReportScreen.cpp | 2 + UI/SavedataScreen.cpp | 1 + ext/native/file/ini_file.cpp | 44 ++--- ext/native/file/ini_file.h | 222 +++++++++++------------ ext/native/i18n/i18n.cpp | 8 +- ext/native/i18n/i18n.h | 10 +- ext/native/ui/ui_screen.cpp | 1 + 20 files changed, 186 insertions(+), 170 deletions(-) diff --git a/Common/ArmCPUDetect.cpp b/Common/ArmCPUDetect.cpp index da8d45f2f9..90aeaf8433 100644 --- a/Common/ArmCPUDetect.cpp +++ b/Common/ArmCPUDetect.cpp @@ -16,6 +16,9 @@ // http://code.google.com/p/dolphin-emu/ #include "ppsspp_config.h" + +#include + #if PPSSPP_ARCH(ARM) || PPSSPP_ARCH(ARM64) #include diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index b7091b537a..d67c06c056 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -916,7 +916,7 @@ void LoadFromIni(IniFile &file) { return; } - IniFile::Section *controls = file.GetOrCreateSection("ControlMapping"); + Section *controls = file.GetOrCreateSection("ControlMapping"); for (size_t i = 0; i < ARRAY_SIZE(psp_button_names); i++) { std::string value; controls->Get(psp_button_names[i].name, &value, ""); @@ -943,7 +943,7 @@ void LoadFromIni(IniFile &file) { } void SaveToIni(IniFile &file) { - IniFile::Section *controls = file.GetOrCreateSection("ControlMapping"); + Section *controls = file.GetOrCreateSection("ControlMapping"); for (size_t i = 0; i < ARRAY_SIZE(psp_button_names); i++) { std::vector keys; diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 485a7b47da..c13a3d712f 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -185,14 +185,14 @@ void LogManager::ChangeFileLog(const char *filename) { } } -void LogManager::SaveConfig(IniFile::Section *section) { +void LogManager::SaveConfig(Section *section) { for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) { section->Set((std::string(log_[i].m_shortName) + "Enabled").c_str(), log_[i].enabled); section->Set((std::string(log_[i].m_shortName) + "Level").c_str(), (int)log_[i].level); } } -void LogManager::LoadConfig(IniFile::Section *section, bool debugDefaults) { +void LogManager::LoadConfig(Section *section, bool debugDefaults) { for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) { bool enabled = false; int level = 0; diff --git a/Common/LogManager.h b/Common/LogManager.h index 81a23d518d..a9d5a568e9 100644 --- a/Common/LogManager.h +++ b/Common/LogManager.h @@ -180,6 +180,6 @@ public: void ChangeFileLog(const char *filename); - void SaveConfig(IniFile::Section *section); - void LoadConfig(IniFile::Section *section, bool debugDefaults); + void SaveConfig(Section *section); + void LoadConfig(Section *section, bool debugDefaults); }; diff --git a/Core/Config.cpp b/Core/Config.cpp index 52d5e3a847..f7fd8e9af9 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -203,7 +203,7 @@ struct ConfigSetting { return type_ != TYPE_TERMINATOR; } - bool Get(IniFile::Section *section) { + bool Get(Section *section) { switch (type_) { case TYPE_BOOL: if (cb_.b) { @@ -256,7 +256,7 @@ struct ConfigSetting { } } - void Set(IniFile::Section *section) { + void Set(Section *section) { if (!save_) return; @@ -1108,9 +1108,9 @@ static ConfigSectionSettings sections[] = { {"Theme", themeSettings}, }; -static void IterateSettings(IniFile &iniFile, std::function func) { +static void IterateSettings(IniFile &iniFile, std::function func) { for (size_t i = 0; i < ARRAY_SIZE(sections); ++i) { - IniFile::Section *section = iniFile.GetOrCreateSection(sections[i].section); + Section *section = iniFile.GetOrCreateSection(sections[i].section); for (auto setting = sections[i].settings; setting->HasMore(); ++setting) { func(section, setting); } @@ -1147,8 +1147,8 @@ std::map> GetLangValuesMapping() { langCodeMapping["CHINESE_TRADITIONAL"] = PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL; langCodeMapping["CHINESE_SIMPLIFIED"] = PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED; - IniFile::Section *langRegionNames = mapping.GetOrCreateSection("LangRegionNames"); - IniFile::Section *systemLanguage = mapping.GetOrCreateSection("SystemLanguage"); + Section *langRegionNames = mapping.GetOrCreateSection("LangRegionNames"); + Section *systemLanguage = mapping.GetOrCreateSection("SystemLanguage"); for (size_t i = 0; i < keys.size(); i++) { std::string langName; @@ -1187,7 +1187,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { // Continue anyway to initialize the config. } - IterateSettings(iniFile, [](IniFile::Section *section, ConfigSetting *setting) { + IterateSettings(iniFile, [](Section *section, ConfigSetting *setting) { setting->Get(section); }); @@ -1195,7 +1195,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { if (!File::Exists(currentDirectory)) currentDirectory = ""; - IniFile::Section *log = iniFile.GetOrCreateSection(logSectionName); + Section *log = iniFile.GetOrCreateSection(logSectionName); bool debugDefaults = false; #ifdef _DEBUG @@ -1203,7 +1203,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { #endif LogManager::GetInstance()->LoadConfig(log, debugDefaults); - IniFile::Section *recent = iniFile.GetOrCreateSection("Recent"); + Section *recent = iniFile.GetOrCreateSection("Recent"); recent->Get("MaxRecent", &iMaxRecent, 30); // Fix issue from switching from uint (hex in .ini) to int (dec) @@ -1249,7 +1249,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { } // Check for an old dpad setting - IniFile::Section *control = iniFile.GetOrCreateSection("Control"); + Section *control = iniFile.GetOrCreateSection("Control"); float f; control->Get("DPadRadius", &f, 0.0f); if (f > 0.0f) { @@ -1338,13 +1338,13 @@ void Config::Save(const char *saveReason) { // Need to do this somewhere... bFirstRun = false; - IterateSettings(iniFile, [&](IniFile::Section *section, ConfigSetting *setting) { + IterateSettings(iniFile, [&](Section *section, ConfigSetting *setting) { if (!bGameSpecific || !setting->perGame_) { setting->Set(section); } }); - IniFile::Section *recent = iniFile.GetOrCreateSection("Recent"); + Section *recent = iniFile.GetOrCreateSection("Recent"); recent->Set("MaxRecent", iMaxRecent); for (int i = 0; i < iMaxRecent; i++) { @@ -1357,7 +1357,7 @@ void Config::Save(const char *saveReason) { } } - IniFile::Section *pinnedPaths = iniFile.GetOrCreateSection("PinnedPaths"); + Section *pinnedPaths = iniFile.GetOrCreateSection("PinnedPaths"); pinnedPaths->Clear(); for (size_t i = 0; i < vPinnedPaths.size(); ++i) { char keyName[64]; @@ -1366,17 +1366,17 @@ void Config::Save(const char *saveReason) { } if (!bGameSpecific) { - IniFile::Section *postShaderSetting = iniFile.GetOrCreateSection("PostShaderSetting"); + Section *postShaderSetting = iniFile.GetOrCreateSection("PostShaderSetting"); postShaderSetting->Clear(); for (auto it = mPostShaderSetting.begin(), end = mPostShaderSetting.end(); it != end; ++it) { postShaderSetting->Set(it->first.c_str(), it->second); } } - IniFile::Section *control = iniFile.GetOrCreateSection("Control"); + Section *control = iniFile.GetOrCreateSection("Control"); control->Delete("DPadRadius"); - IniFile::Section *log = iniFile.GetOrCreateSection(logSectionName); + Section *log = iniFile.GetOrCreateSection(logSectionName); if (LogManager::GetInstance()) LogManager::GetInstance()->SaveConfig(log); @@ -1614,16 +1614,16 @@ bool Config::saveGameConfig(const std::string &pGameId, const std::string &title IniFile iniFile; - IniFile::Section *top = iniFile.GetOrCreateSection(""); + Section *top = iniFile.GetOrCreateSection(""); top->AddComment(StringFromFormat("Game config for %s - %s", pGameId.c_str(), title.c_str())); - IterateSettings(iniFile, [](IniFile::Section *section, ConfigSetting *setting) { + IterateSettings(iniFile, [](Section *section, ConfigSetting *setting) { if (setting->perGame_) { setting->Set(section); } }); - IniFile::Section *postShaderSetting = iniFile.GetOrCreateSection("PostShaderSetting"); + Section *postShaderSetting = iniFile.GetOrCreateSection("PostShaderSetting"); postShaderSetting->Clear(); for (auto it = mPostShaderSetting.begin(), end = mPostShaderSetting.end(); it != end; ++it) { postShaderSetting->Set(it->first.c_str(), it->second); @@ -1653,7 +1653,7 @@ bool Config::loadGameConfig(const std::string &pGameId, const std::string &title mPostShaderSetting[it.first] = std::stof(it.second); } - IterateSettings(iniFile, [](IniFile::Section *section, ConfigSetting *setting) { + IterateSettings(iniFile, [](Section *section, ConfigSetting *setting) { if (setting->perGame_) { setting->Get(section); } @@ -1671,7 +1671,7 @@ void Config::unloadGameConfig() { iniFile.Load(iniFilename_); // Reload game specific settings back to standard. - IterateSettings(iniFile, [](IniFile::Section *section, ConfigSetting *setting) { + IterateSettings(iniFile, [](Section *section, ConfigSetting *setting) { if (setting->perGame_) { setting->Get(section); } diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 80b4f7c6e1..1e58737c2a 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -21,6 +21,7 @@ #include +#include "base/stringutil.h" #include "i18n/i18n.h" #include "thread/threadutil.h" diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 7edb316eef..ece079445e 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -19,6 +19,8 @@ #include #include + +#include "base/stringutil.h" #include "file/free.h" #include "file/zip_read.h" #include "i18n/i18n.h" diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 19a78cc6ac..42ec9b289b 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -21,6 +21,7 @@ #include #include "base/timeutil.h" +#include "base/stringutil.h" #include "i18n/i18n.h" #include "thread/threadutil.h" #include "util/text/parsers.h" diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 462aa02dbf..448a63f177 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -30,6 +30,7 @@ #include "ext/libzip/zip.h" #endif #include "util/text/utf8.h" +#include "file/ini_file.h" #include "Common/Log.h" #include "Common/FileUtil.h" diff --git a/GPU/Common/PostShader.cpp b/GPU/Common/PostShader.cpp index 5c24d48ee3..57eaf1f50d 100644 --- a/GPU/Common/PostShader.cpp +++ b/GPU/Common/PostShader.cpp @@ -103,7 +103,7 @@ void LoadPostShaderInfo(const std::vector &directories) { // Alright, let's loop through the sections and see if any is a shader. for (size_t i = 0; i < ini.Sections().size(); i++) { - IniFile::Section §ion = ini.Sections()[i]; + Section §ion = ini.Sections()[i]; std::string shaderType; section.Get("Type", &shaderType, "render"); diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index c36056b273..dad1ac5861 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "base/stringutil.h" #include "ext/cityhash/city.h" #include "i18n/i18n.h" #include "ui/ui.h" diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 59769a01c7..4e388dd2a2 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -17,6 +17,8 @@ #include #include + +#include "base/stringutil.h" #include "i18n/i18n.h" #include "gfx_es2/draw_buffer.h" #include "ui/view.h" diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 9f0930f77d..8029c39671 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -25,6 +25,7 @@ #include #endif +#include "base/stringutil.h" #include "base/timeutil.h" #include "file/path.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index 96ba662c6f..f214ba9dfd 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -16,7 +16,9 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + #include "base/display.h" +#include "base/stringutil.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 5ec73aa9ca..3771796629 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -20,6 +20,7 @@ #include "base/colorutil.h" #include "base/timeutil.h" +#include "base/stringutil.h" #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" #include "math/curves.h" diff --git a/ext/native/file/ini_file.cpp b/ext/native/file/ini_file.cpp index 79a9f3ff8f..048116aeba 100644 --- a/ext/native/file/ini_file.cpp +++ b/ext/native/file/ini_file.cpp @@ -149,11 +149,11 @@ static std::string EscapeComments(const std::string &value) { return result; } -void IniFile::Section::Clear() { +void Section::Clear() { lines.clear(); } -std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut, std::string* commentOut) +std::string* Section::GetLine(const char* key, std::string* valueOut, std::string* commentOut) { for (std::vector::iterator iter = lines.begin(); iter != lines.end(); ++iter) { @@ -166,7 +166,7 @@ std::string* IniFile::Section::GetLine(const char* key, std::string* valueOut, s return 0; } -void IniFile::Section::Set(const char* key, const char* newValue) +void Section::Set(const char* key, const char* newValue) { std::string value, commented; std::string* line = GetLine(key, &value, &commented); @@ -182,7 +182,7 @@ void IniFile::Section::Set(const char* key, const char* newValue) } } -void IniFile::Section::Set(const char* key, const std::string& newValue, const std::string& defaultValue) +void Section::Set(const char* key, const std::string& newValue, const std::string& defaultValue) { if (newValue != defaultValue) Set(key, newValue); @@ -190,7 +190,7 @@ void IniFile::Section::Set(const char* key, const std::string& newValue, const s Delete(key); } -bool IniFile::Section::Get(const char* key, std::string* value, const char* defaultValue) +bool Section::Get(const char* key, std::string* value, const char* defaultValue) { const std::string* line = GetLine(key, value, 0); if (!line) @@ -204,7 +204,7 @@ bool IniFile::Section::Get(const char* key, std::string* value, const char* defa return true; } -void IniFile::Section::Set(const char* key, const float newValue, const float defaultValue) +void Section::Set(const char* key, const float newValue, const float defaultValue) { if (newValue != defaultValue) Set(key, newValue); @@ -212,7 +212,7 @@ void IniFile::Section::Set(const char* key, const float newValue, const float de Delete(key); } -void IniFile::Section::Set(const char* key, int newValue, int defaultValue) +void Section::Set(const char* key, int newValue, int defaultValue) { if (newValue != defaultValue) Set(key, newValue); @@ -220,7 +220,7 @@ void IniFile::Section::Set(const char* key, int newValue, int defaultValue) Delete(key); } -void IniFile::Section::Set(const char* key, bool newValue, bool defaultValue) +void Section::Set(const char* key, bool newValue, bool defaultValue) { if (newValue != defaultValue) Set(key, newValue); @@ -228,7 +228,7 @@ void IniFile::Section::Set(const char* key, bool newValue, bool defaultValue) Delete(key); } -void IniFile::Section::Set(const char* key, const std::vector& newValues) +void Section::Set(const char* key, const std::vector& newValues) { std::string temp; // Join the strings with , @@ -243,11 +243,11 @@ void IniFile::Section::Set(const char* key, const std::vector& newV Set(key, temp.c_str()); } -void IniFile::Section::AddComment(const std::string &comment) { +void Section::AddComment(const std::string &comment) { lines.push_back("# " + comment); } -bool IniFile::Section::Get(const char* key, std::vector& values) +bool Section::Get(const char* key, std::vector& values) { std::string temp; bool retval = Get(key, &temp, 0); @@ -275,7 +275,7 @@ bool IniFile::Section::Get(const char* key, std::vector& values) return true; } -bool IniFile::Section::Get(const char* key, int* value, int defaultValue) +bool Section::Get(const char* key, int* value, int defaultValue) { std::string temp; bool retval = Get(key, &temp, 0); @@ -285,7 +285,7 @@ bool IniFile::Section::Get(const char* key, int* value, int defaultValue) return false; } -bool IniFile::Section::Get(const char* key, uint32_t* value, uint32_t defaultValue) +bool Section::Get(const char* key, uint32_t* value, uint32_t defaultValue) { std::string temp; bool retval = Get(key, &temp, 0); @@ -295,7 +295,7 @@ bool IniFile::Section::Get(const char* key, uint32_t* value, uint32_t defaultVal return false; } -bool IniFile::Section::Get(const char* key, bool* value, bool defaultValue) +bool Section::Get(const char* key, bool* value, bool defaultValue) { std::string temp; bool retval = Get(key, &temp, 0); @@ -305,7 +305,7 @@ bool IniFile::Section::Get(const char* key, bool* value, bool defaultValue) return false; } -bool IniFile::Section::Get(const char* key, float* value, float defaultValue) +bool Section::Get(const char* key, float* value, float defaultValue) { std::string temp; bool retval = Get(key, &temp, 0); @@ -315,7 +315,7 @@ bool IniFile::Section::Get(const char* key, float* value, float defaultValue) return false; } -bool IniFile::Section::Get(const char* key, double* value, double defaultValue) +bool Section::Get(const char* key, double* value, double defaultValue) { std::string temp; bool retval = Get(key, &temp, 0); @@ -325,7 +325,7 @@ bool IniFile::Section::Get(const char* key, double* value, double defaultValue) return false; } -bool IniFile::Section::Exists(const char *key) const +bool Section::Exists(const char *key) const { for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) { @@ -337,7 +337,7 @@ bool IniFile::Section::Exists(const char *key) const return false; } -std::map IniFile::Section::ToMap() const +std::map Section::ToMap() const { std::map outMap; for (std::vector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter) @@ -351,7 +351,7 @@ std::map IniFile::Section::ToMap() const } -bool IniFile::Section::Delete(const char *key) +bool Section::Delete(const char *key) { std::string* line = GetLine(key, 0, 0); for (std::vector::iterator liter = lines.begin(); liter != lines.end(); ++liter) @@ -367,7 +367,7 @@ bool IniFile::Section::Delete(const char *key) // IniFile -const IniFile::Section* IniFile::GetSection(const char* sectionName) const +const Section* IniFile::GetSection(const char* sectionName) const { for (std::vector
::const_iterator iter = sections.begin(); iter != sections.end(); ++iter) if (!strcasecmp(iter->name().c_str(), sectionName)) @@ -375,7 +375,7 @@ const IniFile::Section* IniFile::GetSection(const char* sectionName) const return 0; } -IniFile::Section* IniFile::GetSection(const char* sectionName) +Section* IniFile::GetSection(const char* sectionName) { for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) if (!strcasecmp(iter->name().c_str(), sectionName)) @@ -383,7 +383,7 @@ IniFile::Section* IniFile::GetSection(const char* sectionName) return 0; } -IniFile::Section* IniFile::GetOrCreateSection(const char* sectionName) +Section* IniFile::GetOrCreateSection(const char* sectionName) { Section* section = GetSection(sectionName); if (!section) diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h index 98afb66248..83e02d4144 100644 --- a/ext/native/file/ini_file.h +++ b/ext/native/file/ini_file.h @@ -19,120 +19,120 @@ inline std::string ValueToString(const N value) return string.str(); } +class Section +{ + friend class IniFile; + +public: + Section() {} + Section(const std::string& name) : name_(name) {} + + bool Exists(const char *key) const; + bool Delete(const char *key); + + void Clear(); + + std::map ToMap() const; + + std::string* GetLine(const char* key, std::string* valueOut, std::string* commentOut); + void Set(const char* key, const char* newValue); + void Set(const char* key, const std::string& newValue, const std::string& defaultValue); + + void Set(const std::string &key, const std::string &value) { + Set(key.c_str(), value.c_str()); + } + bool Get(const char* key, std::string* value, const char* defaultValue); + + void Set(const char* key, uint32_t newValue) { + Set(key, StringFromFormat("0x%08x", newValue).c_str()); + } + void Set(const char* key, float newValue) { + Set(key, StringFromFormat("%f", newValue).c_str()); + } + void Set(const char* key, const float newValue, const float defaultValue); + void Set(const char* key, double newValue) { + Set(key, StringFromFormat("%f", newValue).c_str()); + } + + void Set(const char* key, int newValue, int defaultValue); + void Set(const char* key, int newValue) { + Set(key, StringFromInt(newValue).c_str()); + } + + void Set(const char* key, bool newValue, bool defaultValue); + void Set(const char* key, bool newValue) { + Set(key, StringFromBool(newValue).c_str()); + } + void Set(const char* key, const std::vector& newValues); + + template + void Set(const char* key, const std::map& newValues) + { + std::vector temp; + for (typename std::map::const_iterator it = newValues.begin(); it != newValues.end(); it++) + { + temp.push_back(ValueToString(it->first) + "_" + ValueToString(it->second)); + } + Set(key, temp); + } + + // Declare without a body to make it fail to compile. This is to prevent accidentally + // setting a pointer as a bool. The failure is in the linker unfortunately, but that's better + // than accidentally succeeding in a bad way. + template + void Set(const char *key, T *ptr); + + void AddComment(const std::string &comment); + + bool Get(const char* key, int* value, int defaultValue = 0); + bool Get(const char* key, uint32_t* value, uint32_t defaultValue = 0); + bool Get(const char* key, bool* value, bool defaultValue = false); + bool Get(const char* key, float* value, float defaultValue = false); + bool Get(const char* key, double* value, double defaultValue = false); + bool Get(const char* key, std::vector& values); + template + bool Get(const char* key, std::map& values) + { + std::vector temp; + if (!Get(key, temp)) + { + return false; + } + values.clear(); + for (size_t i = 0; i < temp.size(); i++) + { + std::vector key_val; + SplitString(temp[i], '_', key_val); + if (key_val.size() < 2) + continue; + U mapKey; + V mapValue; + if (!TryParse(key_val[0], &mapKey)) + continue; + if (!TryParse(key_val[1], &mapValue)) + continue; + values[mapKey] = mapValue; + } + return true; + } + + bool operator < (const Section& other) const { + return name_ < other.name_; + } + + const std::string &name() const { + return name_; + } + +protected: + std::vector lines; + std::string name_; + std::string comment; +}; + class IniFile { public: - class Section - { - friend class IniFile; - - public: - Section() {} - Section(const std::string& name) : name_(name) {} - - bool Exists(const char *key) const; - bool Delete(const char *key); - - void Clear(); - - std::map ToMap() const; - - std::string* GetLine(const char* key, std::string* valueOut, std::string* commentOut); - void Set(const char* key, const char* newValue); - void Set(const char* key, const std::string& newValue, const std::string& defaultValue); - - void Set(const std::string &key, const std::string &value) { - Set(key.c_str(), value.c_str()); - } - bool Get(const char* key, std::string* value, const char* defaultValue); - - void Set(const char* key, uint32_t newValue) { - Set(key, StringFromFormat("0x%08x", newValue).c_str()); - } - void Set(const char* key, float newValue) { - Set(key, StringFromFormat("%f", newValue).c_str()); - } - void Set(const char* key, const float newValue, const float defaultValue); - void Set(const char* key, double newValue) { - Set(key, StringFromFormat("%f", newValue).c_str()); - } - - void Set(const char* key, int newValue, int defaultValue); - void Set(const char* key, int newValue) { - Set(key, StringFromInt(newValue).c_str()); - } - - void Set(const char* key, bool newValue, bool defaultValue); - void Set(const char* key, bool newValue) { - Set(key, StringFromBool(newValue).c_str()); - } - void Set(const char* key, const std::vector& newValues); - - template - void Set(const char* key, const std::map& newValues) - { - std::vector temp; - for(typename std::map::const_iterator it = newValues.begin(); it != newValues.end(); it++) - { - temp.push_back(ValueToString(it->first)+"_"+ValueToString(it->second)); - } - Set(key,temp); - } - - // Declare without a body to make it fail to compile. This is to prevent accidentally - // setting a pointer as a bool. The failure is in the linker unfortunately, but that's better - // than accidentally succeeding in a bad way. - template - void Set(const char *key, T *ptr); - - void AddComment(const std::string &comment); - - bool Get(const char* key, int* value, int defaultValue = 0); - bool Get(const char* key, uint32_t* value, uint32_t defaultValue = 0); - bool Get(const char* key, bool* value, bool defaultValue = false); - bool Get(const char* key, float* value, float defaultValue = false); - bool Get(const char* key, double* value, double defaultValue = false); - bool Get(const char* key, std::vector& values); - template - bool Get(const char* key, std::map& values) - { - std::vector temp; - if(!Get(key,temp)) - { - return false; - } - values.clear(); - for(size_t i = 0; i < temp.size(); i++) - { - std::vector key_val; - SplitString(temp[i], '_', key_val); - if (key_val.size() < 2) - continue; - U mapKey; - V mapValue; - if (!TryParse(key_val[0], &mapKey)) - continue; - if (!TryParse(key_val[1], &mapValue)) - continue; - values[mapKey] = mapValue; - } - return true; - } - - bool operator < (const Section& other) const { - return name_ < other.name_; - } - - const std::string &name() const { - return name_; - } - - protected: - std::vector lines; - std::string name_; - std::string comment; - }; - bool Load(const char* filename); bool Load(const std::string &filename) { return Load(filename.c_str()); } bool Load(std::istream &istream); diff --git a/ext/native/i18n/i18n.cpp b/ext/native/i18n/i18n.cpp index eb823dc2b9..a77111361d 100644 --- a/ext/native/i18n/i18n.cpp +++ b/ext/native/i18n/i18n.cpp @@ -95,7 +95,7 @@ bool I18NRepo::LoadIni(const std::string &languageID, const std::string &overrid Clear(); - const std::vector §ions = ini.Sections(); + const std::vector
§ions = ini.Sections(); std::lock_guard guard(catsLock_); for (auto iter = sections.begin(); iter != sections.end(); ++iter) { @@ -108,7 +108,7 @@ bool I18NRepo::LoadIni(const std::string &languageID, const std::string &overrid return true; } -I18NCategory *I18NRepo::LoadSection(const IniFile::Section *section, const char *name) { +I18NCategory *I18NRepo::LoadSection(const Section *section, const char *name) { I18NCategory *cat = new I18NCategory(this, name); std::map sectionMap = section->ToMap(); cat->SetMap(sectionMap); @@ -123,13 +123,13 @@ void I18NRepo::SaveIni(const std::string &languageID) { std::lock_guard guard(catsLock_); for (auto iter = cats_.begin(); iter != cats_.end(); ++iter) { std::string categoryName = iter->first; - IniFile::Section *section = ini.GetOrCreateSection(categoryName.c_str()); + Section *section = ini.GetOrCreateSection(categoryName.c_str()); SaveSection(ini, section, iter->second); } ini.Save(GetIniPath(languageID)); } -void I18NRepo::SaveSection(IniFile &ini, IniFile::Section *section, std::shared_ptr cat) { +void I18NRepo::SaveSection(IniFile &ini, Section *section, std::shared_ptr cat) { const std::map &missed = cat->Missed(); for (auto iter = missed.begin(); iter != missed.end(); ++iter) { diff --git a/ext/native/i18n/i18n.h b/ext/native/i18n/i18n.h index cdffed3a29..fcf281b3b7 100644 --- a/ext/native/i18n/i18n.h +++ b/ext/native/i18n/i18n.h @@ -13,11 +13,13 @@ #include #include -#include "file/ini_file.h" +#include "Common/Common.h" // Reasonably thread safe. class I18NRepo; +class IniFile; +class Section; struct I18NEntry { I18NEntry(const std::string &t) : text(t), readFlag(false) {} @@ -63,8 +65,6 @@ private: // Noone else can create these. friend class I18NRepo; - - DISALLOW_COPY_AND_ASSIGN(I18NCategory); }; class I18NRepo { @@ -88,8 +88,8 @@ public: private: std::string GetIniPath(const std::string &languageID) const; void Clear(); - I18NCategory *LoadSection(const IniFile::Section *section, const char *name); - void SaveSection(IniFile &ini, IniFile::Section *section, std::shared_ptr cat); + I18NCategory *LoadSection(const Section *section, const char *name); + void SaveSection(IniFile &ini, Section *section, std::shared_ptr cat); mutable std::mutex catsLock_; std::map> cats_; diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 3bfa8dcfe1..9d36ee627b 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -3,6 +3,7 @@ #include #include "base/display.h" +#include "base/stringutil.h" #include "input/input_state.h" #include "input/keycodes.h" #include "math/curves.h" From e59951382ae02271eaf7a994685e7bead96899a6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 01:30:58 -0700 Subject: [PATCH 477/848] Global: Make stringutil includes more explicit. --- Common/KeyMap.cpp | 1 + Core/FileSystems/DirectoryFileSystem.cpp | 1 + Core/SaveState.cpp | 1 + Core/TextureReplacer.cpp | 1 + GPU/Directx9/ShaderManagerDX9.cpp | 1 + UI/DevScreens.cpp | 1 + UI/NativeApp.cpp | 3 ++- UI/PauseScreen.cpp | 1 + UI/RemoteISOScreen.cpp | 1 + UI/ReportScreen.cpp | 1 + UI/SavedataScreen.cpp | 1 + Windows/MainWindow.cpp | 1 + Windows/MainWindowMenu.cpp | 2 ++ Windows/main.cpp | 3 ++- ext/native/i18n/i18n.cpp | 1 + ext/native/i18n/i18n.h | 1 + ext/native/ui/ui_screen.cpp | 2 ++ 17 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index b7091b537a..8683ba8346 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -25,6 +25,7 @@ #endif #include "base/logging.h" +#include "base/stringutil.h" #include "base/NativeApp.h" #include "file/ini_file.h" #include "input/input_state.h" diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 7edb316eef..45dc902f04 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -19,6 +19,7 @@ #include #include +#include "base/stringutil.h" #include "file/free.h" #include "file/zip_read.h" #include "i18n/i18n.h" diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 19a78cc6ac..649b644a88 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -20,6 +20,7 @@ #include #include +#include "base/stringutil.h" #include "base/timeutil.h" #include "i18n/i18n.h" #include "thread/threadutil.h" diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 41edb29ce0..05dd6c44f9 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -22,6 +22,7 @@ #endif #include +#include "base/stringutil.h" #include "i18n/i18n.h" #include "ext/xxhash.h" #include "file/ini_file.h" diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 856150bbb3..e3157371e8 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -23,6 +23,7 @@ #include #include "gfx/d3d9_shader.h" #include "base/logging.h" +#include "base/stringutil.h" #include "i18n/i18n.h" #include "math/lin/matrix4x4.h" #include "math/math_util.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index f146d099e9..9c0d6cdf99 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -18,6 +18,7 @@ #include #include "base/display.h" +#include "base/stringutil.h" #include "gfx_es2/gpu_features.h" #include "i18n/i18n.h" #include "ui/ui_context.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index cc855aa1fe..3db216d802 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -44,8 +44,9 @@ #endif #include "base/display.h" -#include "base/timeutil.h" #include "base/logging.h" +#include "base/stringutil.h" +#include "base/timeutil.h" #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 59769a01c7..df694192f4 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -17,6 +17,7 @@ #include #include +#include "base/stringutil.h" #include "i18n/i18n.h" #include "gfx_es2/draw_buffer.h" #include "ui/view.h" diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 9f0930f77d..8029c39671 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -25,6 +25,7 @@ #include #endif +#include "base/stringutil.h" #include "base/timeutil.h" #include "file/path.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index 96ba662c6f..e2cf904b2c 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -17,6 +17,7 @@ #include #include "base/display.h" +#include "base/stringutil.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 5ec73aa9ca..0f3ce2a45f 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -19,6 +19,7 @@ #include #include "base/colorutil.h" +#include "base/stringutil.h" #include "base/timeutil.h" #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index a735878ba0..59f6820aa5 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -34,6 +34,7 @@ #include "base/display.h" #include "base/NativeApp.h" +#include "base/stringutil.h" #include "base/timeutil.h" #include "i18n/i18n.h" #include "input/input_state.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 03296a8f28..fcc1b2528d 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -1,11 +1,13 @@ #include #include +#include #include "CommonWindows.h" #include #include "resource.h" +#include "base/stringutil.h" #include "i18n/i18n.h" #include "util/text/utf8.h" #include "base/NativeApp.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index 9a2bcce356..50cd28534b 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -31,8 +31,9 @@ #include #include -#include "base/NativeApp.h" #include "base/display.h" +#include "base/stringutil.h" +#include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" #include "i18n/i18n.h" diff --git a/ext/native/i18n/i18n.cpp b/ext/native/i18n/i18n.cpp index eb823dc2b9..cba62a2e4b 100644 --- a/ext/native/i18n/i18n.cpp +++ b/ext/native/i18n/i18n.cpp @@ -1,4 +1,5 @@ #include "base/logging.h" +#include "base/stringutil.h" #include "i18n/i18n.h" #include "file/ini_file.h" #include "file/vfs.h" diff --git a/ext/native/i18n/i18n.h b/ext/native/i18n/i18n.h index 75d8ddd776..b184dd7975 100644 --- a/ext/native/i18n/i18n.h +++ b/ext/native/i18n/i18n.h @@ -14,6 +14,7 @@ #include #include +#include "base/basictypes.h" #include "file/ini_file.h" // Reasonably thread safe. diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index e2dba2cf60..180e271aae 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -1,6 +1,8 @@ #include #include +#include #include "base/display.h" +#include "base/stringutil.h" #include "input/input_state.h" #include "input/keycodes.h" #include "math/curves.h" From 3d9c4733ab299108bfc7d82a25ad4f99311cae88 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 01:31:47 -0700 Subject: [PATCH 478/848] Global: Reduce ini_file header complexity. We're not using the old std::map support anymore. Avoid pulling in headers if possible. --- ext/native/file/ini_file.h | 45 +++++--------------------------------- 1 file changed, 5 insertions(+), 40 deletions(-) diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h index ba63ab1ab5..467f4b870f 100644 --- a/ext/native/file/ini_file.h +++ b/ext/native/file/ini_file.h @@ -4,11 +4,14 @@ #pragma once +#include +#include #include #include -#include -#include "base/stringutil.h" +std::string StringFromFormat(const char* format, ...); +std::string StringFromInt(int value); +std::string StringFromBool(bool value); class IniFile { @@ -59,17 +62,6 @@ public: } void Set(const char* key, const std::vector& newValues); - template - void Set(const char* key, const std::map& newValues) - { - std::vector temp; - for(typename std::map::const_iterator it = newValues.begin(); it != newValues.end(); it++) - { - temp.push_back(ValueToString(it->first)+"_"+ValueToString(it->second)); - } - Set(key,temp); - } - // Declare without a body to make it fail to compile. This is to prevent accidentally // setting a pointer as a bool. The failure is in the linker unfortunately, but that's better // than accidentally succeeding in a bad way. @@ -84,31 +76,6 @@ public: bool Get(const char* key, float* value, float defaultValue = false); bool Get(const char* key, double* value, double defaultValue = false); bool Get(const char* key, std::vector& values); - template - bool Get(const char* key, std::map& values) - { - std::vector temp; - if(!Get(key,temp)) - { - return false; - } - values.clear(); - for(size_t i = 0; i < temp.size(); i++) - { - std::vector key_val; - SplitString(temp[i],'_',key_val); - if(key_val.size() < 2) - continue; - U mapKey; - V mapValue; - if(!TryParse(key_val[0],&mapKey)) - continue; - if(!TryParse(key_val[1],&mapValue)) - continue; - values[mapKey] = mapValue; - } - return true; - } bool operator < (const Section& other) const { return name_ < other.name_; @@ -189,6 +156,4 @@ private: const Section* GetSection(const char* section) const; Section* GetSection(const char* section); - std::string* GetLine(const char* section, const char* key); - void CreateSection(const char* section); }; From a0f8e788f3dff63daeeb7eb0d6d22140bc758b03 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 01:43:40 -0700 Subject: [PATCH 479/848] Global: Move string number parse to text/parsers. It's not used as much as the other string utils. --- Core/Debugger/WebSocket/WebSocketUtils.cpp | 1 + Core/TextureReplacer.cpp | 1 + Windows/GEDebugger/GEDebugger.cpp | 1 + ext/native/base/stringutil.cpp | 85 ---------------------- ext/native/base/stringutil.h | 30 +------- ext/native/file/file_util.cpp | 4 +- ext/native/file/ini_file.cpp | 3 +- ext/native/net/websocket_server.cpp | 5 -- ext/native/util/text/parsers.cpp | 44 ++++++++++- ext/native/util/text/parsers.h | 18 ++++- 10 files changed, 66 insertions(+), 126 deletions(-) diff --git a/Core/Debugger/WebSocket/WebSocketUtils.cpp b/Core/Debugger/WebSocket/WebSocketUtils.cpp index 3a3536684c..013121ff80 100644 --- a/Core/Debugger/WebSocket/WebSocketUtils.cpp +++ b/Core/Debugger/WebSocket/WebSocketUtils.cpp @@ -17,6 +17,7 @@ #include #include +#include "util/text/parsers.h" #include "Common/StringUtils.h" #include "Core/Debugger/WebSocket/WebSocketUtils.h" diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 05dd6c44f9..f403deba44 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -26,6 +26,7 @@ #include "i18n/i18n.h" #include "ext/xxhash.h" #include "file/ini_file.h" +#include "util/text/parsers.h" #include "Common/ColorConv.h" #include "Common/FileUtil.h" #include "Core/Config.h" diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index aa0de48d05..5fb0fcb72b 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -21,6 +21,7 @@ #include #include "base/stringutil.h" +#include "util/text/parsers.h" #include "Common/ColorConv.h" #include "Core/Config.h" #include "Core/Screenshot.h" diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp index 2861f844d3..d0ff0a71d7 100644 --- a/ext/native/base/stringutil.cpp +++ b/ext/native/base/stringutil.cpp @@ -22,8 +22,6 @@ #include "base/stringutil.h" #ifdef _WIN32 -// Function Cross-Compatibility -#define strcasecmp _stricmp void OutputDebugStringUTF8(const char *p) { wchar_t temp[4096]; @@ -84,46 +82,6 @@ void StringUpper(char *str, int len) { } } - -unsigned int parseHex(const char *_szValue) -{ - int Value = 0; - size_t Finish = strlen(_szValue); - if (Finish > 8 ) { Finish = 8; } - - for (size_t Count = 0; Count < Finish; Count++) { - Value = (Value << 4); - switch( _szValue[Count] ) { - case '0': break; - case '1': Value += 1; break; - case '2': Value += 2; break; - case '3': Value += 3; break; - case '4': Value += 4; break; - case '5': Value += 5; break; - case '6': Value += 6; break; - case '7': Value += 7; break; - case '8': Value += 8; break; - case '9': Value += 9; break; - case 'A': Value += 10; break; - case 'a': Value += 10; break; - case 'B': Value += 11; break; - case 'b': Value += 11; break; - case 'C': Value += 12; break; - case 'c': Value += 12; break; - case 'D': Value += 13; break; - case 'd': Value += 13; break; - case 'E': Value += 14; break; - case 'e': Value += 14; break; - case 'F': Value += 15; break; - case 'f': Value += 15; break; - default: - Value = (Value >> 4); - Count = Finish; - } - } - return Value; -} - void DataToHexString(const uint8_t *data, size_t size, std::string *output) { Buffer buffer; for (size_t i = 0; i < size; i++) { @@ -223,49 +181,6 @@ std::string ArrayToString(const uint8_t *data, uint32_t size, int line_len, bool return oss.str(); } -bool TryParse(const std::string &str, uint32_t *const output) -{ - char *endptr = NULL; - - // Holy crap this is ugly. - - // Reset errno to a value other than ERANGE - errno = 0; - - unsigned long value = strtoul(str.c_str(), &endptr, 0); - - if (!endptr || *endptr) - return false; - - if (errno == ERANGE) - return false; - - if (ULONG_MAX > UINT_MAX) { -#ifdef _MSC_VER -#pragma warning (disable:4309) -#endif - // Note: The typecasts avoid GCC warnings when long is 32 bits wide. - if (value >= static_cast(0x100000000ull) - && value <= static_cast(0xFFFFFFFF00000000ull)) - return false; - } - - *output = static_cast(value); - return true; -} - -bool TryParse(const std::string &str, bool *const output) -{ - if ("1" == str || !strcasecmp("true", str.c_str())) - *output = true; - else if ("0" == str || !strcasecmp("false", str.c_str())) - *output = false; - else - return false; - - return true; -} - void SplitString(const std::string& str, const char delim, std::vector& output) { size_t next = 0; diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h index c16602946f..744a725088 100644 --- a/ext/native/base/stringutil.h +++ b/ext/native/base/stringutil.h @@ -9,6 +9,7 @@ #ifdef _MSC_VER #pragma warning (disable:4996) #define strncasecmp _strnicmp +#define strcasecmp _stricmp #else #include #endif @@ -59,10 +60,6 @@ inline void StringToHexString(const std::string &data, std::string *output) { DataToHexString((uint8_t *)(&data[0]), data.size(), output); } - -// highly unsafe and not recommended. -unsigned int parseHex(const char* _szValue); - std::string StringFromFormat(const char* format, ...); std::string StringFromInt(int value); std::string StringFromBool(bool value); @@ -72,23 +69,6 @@ std::string ArrayToString(const uint8_t *data, uint32_t size, int line_len = 20, std::string StripSpaces(const std::string &s); std::string StripQuotes(const std::string &s); -bool TryParse(const std::string &str, bool *const output); -bool TryParse(const std::string &str, uint32_t *const output); - -template -static bool TryParse(const std::string &str, N *const output) -{ - std::istringstream iss(str); - - N tmp = 0; - if (iss >> tmp) - { - *output = tmp; - return true; - } - else - return false; -} void SplitString(const std::string& str, const char delim, std::vector& output); void GetQuotedStrings(const std::string& str, std::vector& output); @@ -98,14 +78,6 @@ std::string ReplaceAll(std::string input, const std::string& src, const std::str // Compare two strings, ignore the difference between the ignorestr1 and the ignorestr2 in str1 and str2. int strcmpIgnore(std::string str1, std::string str2, std::string ignorestr1, std::string ignorestr2); -template -static std::string ValueToString(const N value) -{ - std::stringstream string; - string << value; - return string.str(); -} - void StringTrimEndNonAlphaNum(char *str); void SkipSpace(const char **ptr); void StringUpper(char *str); diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index 5b1087b425..d95dcef311 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -4,9 +4,6 @@ #define WIN32_LEAN_AND_MEAN #include #include -#ifndef strcasecmp -#define strcasecmp _stricmp -#endif #else #include #include @@ -23,6 +20,7 @@ #include "base/logging.h" #include "base/basictypes.h" +#include "base/stringutil.h" #include "file/file_util.h" #include "util/text/utf8.h" diff --git a/ext/native/file/ini_file.cpp b/ext/native/file/ini_file.cpp index 99bdcd163a..f8a96025a2 100644 --- a/ext/native/file/ini_file.cpp +++ b/ext/native/file/ini_file.cpp @@ -19,11 +19,10 @@ #include "base/stringutil.h" #include "file/ini_file.h" #include "file/vfs.h" +#include "util/text/parsers.h" #ifdef _WIN32 #include "../util/text/utf8.h" - // Function Cross-Compatibility -#define strcasecmp _stricmp #endif static bool ParseLineKey(const std::string &line, size_t &pos, std::string *keyOut) { diff --git a/ext/native/net/websocket_server.cpp b/ext/native/net/websocket_server.cpp index 42efb36647..dc9b361884 100644 --- a/ext/native/net/websocket_server.cpp +++ b/ext/native/net/websocket_server.cpp @@ -23,11 +23,6 @@ // TODO: Not a great cross dependency. #include "Common/Crypto/sha1.h" -#ifdef _WIN32 -// Function Cross-Compatibility -#define strcasecmp _stricmp -#endif - static const char *const WEBSOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; namespace net { diff --git a/ext/native/util/text/parsers.cpp b/ext/native/util/text/parsers.cpp index 8024324b08..8a381c0286 100644 --- a/ext/native/util/text/parsers.cpp +++ b/ext/native/util/text/parsers.cpp @@ -1,6 +1,7 @@ +#include #include -#include +#include "base/stringutil.h" #include "util/text/parsers.h" bool Version::ParseVersionString(std::string str) { @@ -37,3 +38,44 @@ bool ParseMacAddress(std::string str, uint8_t macAddr[6]) { } return true; } + +bool TryParse(const std::string &str, uint32_t *const output) { + char *endptr = NULL; + + // Holy crap this is ugly. + + // Reset errno to a value other than ERANGE + errno = 0; + + unsigned long value = strtoul(str.c_str(), &endptr, 0); + + if (!endptr || *endptr) + return false; + + if (errno == ERANGE) + return false; + + if (ULONG_MAX > UINT_MAX) { +#ifdef _MSC_VER +#pragma warning (disable:4309) +#endif + // Note: The typecasts avoid GCC warnings when long is 32 bits wide. + if (value >= static_cast(0x100000000ull) + && value <= static_cast(0xFFFFFFFF00000000ull)) + return false; + } + + *output = static_cast(value); + return true; +} + +bool TryParse(const std::string &str, bool *const output) { + if ("1" == str || !strcasecmp("true", str.c_str())) + *output = true; + else if ("0" == str || !strcasecmp("false", str.c_str())) + *output = false; + else + return false; + + return true; +} diff --git a/ext/native/util/text/parsers.h b/ext/native/util/text/parsers.h index fbf2c36d99..a2bf62dfd4 100644 --- a/ext/native/util/text/parsers.h +++ b/ext/native/util/text/parsers.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "base/basictypes.h" @@ -53,4 +54,19 @@ private: bool ParseVersionString(std::string str); }; -bool ParseMacAddress(std::string str, uint8_t macAddr[6]); \ No newline at end of file +bool ParseMacAddress(std::string str, uint8_t macAddr[6]); + +bool TryParse(const std::string &str, bool *const output); +bool TryParse(const std::string &str, uint32_t *const output); + +template +static bool TryParse(const std::string &str, N *const output) { + std::istringstream iss(str); + + N tmp = 0; + if (iss >> tmp) { + *output = tmp; + return true; + } else + return false; +} From cf4a5b1b9c049aca1f0a1e368bab820a2381bb09 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 10 Aug 2020 14:43:13 +0000 Subject: [PATCH 480/848] Global: Buildfix for parsers. --- ext/native/util/text/parsers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/native/util/text/parsers.cpp b/ext/native/util/text/parsers.cpp index 8a381c0286..e762ec4232 100644 --- a/ext/native/util/text/parsers.cpp +++ b/ext/native/util/text/parsers.cpp @@ -1,3 +1,4 @@ +#include #include #include From 48ba304a4a883b80190eabde61df36dea9bbe535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 10 Aug 2020 20:17:01 +0200 Subject: [PATCH 481/848] Minor logging improvements --- GPU/Common/FramebufferManagerCommon.cpp | 6 +++--- GPU/Common/TextureCacheCommon.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 3a8e443ba5..8e291942db 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1566,7 +1566,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst if (dstBuffer && srcBuffer) { if (srcBuffer == dstBuffer) { if (srcX != dstX || srcY != dstY) { - WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); + WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x -> %08x (%dx%d %dbpp)", srcBasePtr, dstBasePtr, width, height, bpp); FlushBeforeCopy(); BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); RebindFramebuffer("rebind after intra block transfer"); @@ -1577,7 +1577,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst return true; } } else { - WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); + WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x -> %08x (%dx%d %dbpp)", srcBasePtr, dstBasePtr, width, height, bpp); // Just do the blit! FlushBeforeCopy(); BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); @@ -1590,7 +1590,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst // Here we should just draw the pixels into the buffer. Copy first. return false; } else if (srcBuffer) { - WARN_LOG_ONCE(btd, G3D, "Block transfer download %08x -> %08x", srcBasePtr, dstBasePtr); + WARN_LOG_ONCE(btd, G3D, "Block transfer download %08x -> %08x (%dx%d %dbpp)", srcBasePtr, dstBasePtr, width, height, bpp); FlushBeforeCopy(); if (g_Config.bBlockTransferGPU && !srcBuffer->memoryUpdated) { const int srcBpp = srcBuffer->format == GE_FORMAT_8888 ? 4 : 2; diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 14f49ffa90..cd7a725349 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -776,14 +776,14 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // 512 on a 272 framebuffer is sane, so let's be lenient. const u32 minSubareaHeight = h / 4; - // If they match exactly, it's non-CLUT and from the top left. + // If they match "exactly", it's non-CLUT and from the top left. if (exactMatch) { if (framebuffer->fb_stride != entry->bufw) { - WARN_LOG_REPORT_ONCE(diffStrides1, G3D, "Texturing from framebuffer with different strides %d != %d", entry->bufw, framebuffer->fb_stride); + WARN_LOG_ONCE(diffStrides1, G3D, "Texturing from framebuffer with different strides %d != %d", entry->bufw, framebuffer->fb_stride); } // NOTE: This check is okay because the first texture formats are the same as the buffer formats. if (entry->format != (GETextureFormat)framebuffer->format) { - WARN_LOG_REPORT_ONCE(diffFormat1, G3D, "Texturing from framebuffer with different formats %d != %d", entry->format, framebuffer->format); + WARN_LOG_ONCE(diffFormat1, G3D, "Texturing from framebuffer with different formats %s != %s", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format)); // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. // However, some games use a different format to clear the buffer. if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) { @@ -862,7 +862,7 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // This is either normal or we failed to generate a shader to depalettize if (framebuffer->format == entry->format || matchingClutFormat) { if (framebuffer->format != entry->format) { - WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", + WARN_LOG_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); AttachFramebufferValid(entry, framebuffer, fbInfo, channel); return true; From b2d6eef65d7a4c2215b1dad48f736ad80635a649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 10 Aug 2020 21:54:49 +0200 Subject: [PATCH 482/848] UninstallExceptionHandler: Zero-initialize some structs. I've seen some weird crashes on the free() on Android. --- Common/ExceptionHandlerSetup.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index b73bcbdc44..f886a5b6da 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -287,7 +287,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { INFO_LOG(SYSTEM, "Installed exception handler"); g_badAccessHandler = badAccessHandler; - stack_t signal_stack; + stack_t signal_stack{}; #ifdef __FreeBSD__ signal_stack.ss_sp = (char*)malloc(SIGSTKSZ); #else @@ -298,7 +298,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { if (sigaltstack(&signal_stack, nullptr)) { _assert_msg_(false, "sigaltstack failed"); } - struct sigaction sa; + struct sigaction sa{}; sa.sa_handler = nullptr; sa.sa_sigaction = &sigsegv_handler; sa.sa_flags = SA_SIGINFO; @@ -313,9 +313,10 @@ void UninstallExceptionHandler() { if (!g_badAccessHandler) { return; } - stack_t signal_stack, old_stack; + stack_t signal_stack{}; + stack_t old_stack{}; signal_stack.ss_flags = SS_DISABLE; - if (!sigaltstack(&signal_stack, &old_stack) && !(old_stack.ss_flags & SS_DISABLE)) { + if (0 == sigaltstack(&signal_stack, &old_stack) && !(old_stack.ss_flags & SS_DISABLE)) { free(old_stack.ss_sp); } sigaction(SIGSEGV, &old_sa_segv, nullptr); From 14532847c7e045e687f69f9e66bbcb361c943e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 11 Aug 2020 22:28:36 +0200 Subject: [PATCH 483/848] Fix some minor issues found by address-sanitizer on Linux --- Core/HLE/sceUsbCam.cpp | 4 ++-- SDL/SDLMain.cpp | 3 ++- UI/BackgroundAudio.cpp | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index 4b3ec1a4ef..7f0a20a68e 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -51,7 +51,7 @@ enum { }; void __UsbCamInit() { - config = new Camera::Config; + config = new Camera::Config(); config->mode = Camera::Mode::Unused; config->type = Camera::ConfigType::CfNone; videoBuffer = new uint8_t[VIDEO_BUFFER_SIZE]; @@ -76,7 +76,7 @@ void __UsbCamShutdown() { } delete[] videoBuffer; videoBuffer = nullptr; - delete[] config; + delete config; config = nullptr; } diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index ece0b81c96..9bacb7de9f 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -1156,6 +1156,7 @@ int main(int argc, char *argv[]) { // Destroys Draw, which is used in NativeShutdown to shutdown. graphicsContext->ShutdownFromRenderThread(); + graphicsContext->Shutdown(); delete graphicsContext; if (audioDev > 0) { @@ -1168,7 +1169,7 @@ int main(int argc, char *argv[]) { #endif glslang::FinalizeProcess(); - ILOG("Leaving main"); + printf("Leaving main"); #ifdef HAVE_LIBNX socketExit(); #endif diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 16c8e5cea1..d8db2bea6f 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -266,6 +266,8 @@ BackgroundAudio::Sample *BackgroundAudio::LoadSample(const std::string &path) { WavData wave; wave.Read(reader); + delete [] data; + if (wave.num_channels != 2 || wave.sample_rate != 44100 || wave.raw_bytes_per_frame != 4) { ELOG("Wave format not supported for mixer playback. Must be 16-bit raw stereo. '%s'", path.c_str()); return nullptr; From f617bfce291e328cb4d27487da344323553ab39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 11 Aug 2020 22:32:41 +0200 Subject: [PATCH 484/848] Disable the instance counter in libretro builds. Dunno if it might help #13271... --- Core/Instance.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Instance.cpp b/Core/Instance.cpp index ed6222b185..8d8554629a 100644 --- a/Core/Instance.cpp +++ b/Core/Instance.cpp @@ -92,7 +92,7 @@ void InitInstanceCounter() { //hIDMapFile = NULL; PPSSPP_ID = id; -#elif PPSSPP_PLATFORM(ANDROID) +#elif PPSSPP_PLATFORM(ANDROID) || defined(__LIBRETRO__) // TODO : replace shm_open & shm_unlink with ashmem or android-shmem PPSSPP_ID = 1; #else @@ -140,7 +140,7 @@ void ShutdownInstanceCounter() { CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted. hIDMapFile = nullptr; } -#elif PPSSPP_PLATFORM(ANDROID) +#elif PPSSPP_PLATFORM(ANDROID) || defined(__LIBRETRO__) // Do nothing #else // TODO : This unlink should be called when program exits instead of everytime the game reset. From 27c059bf9ed350772022a6571ba10ce5d89c01a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 12 Aug 2020 00:22:11 +0200 Subject: [PATCH 485/848] Really no need to call clear() in the constructor for AudioChannel. However if this helps #13271, something is very wrong... --- Core/HLE/sceAudio.cpp | 14 +++++--------- Core/HLE/sceAudio.h | 20 +++++++------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index 41eb487167..76f97e9a20 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -38,6 +38,9 @@ int defaultRoutingVolMode = AUDIO_ROUTING_SPEAKER_ON; extern FixedSizeQueue chanSampleQueues[PSP_AUDIO_CHANNEL_MAX + 1]; +// The extra channel is for SRC/Output2/Vaudio. +AudioChannel chans[PSP_AUDIO_CHANNEL_MAX + 1]; + void AudioChannel::DoState(PointerWrap &p) { auto s = p.Section("AudioChannel", 1, 2); @@ -76,18 +79,11 @@ void AudioChannel::clear() waitingThreads.clear(); } -// There's a second Audio api called Audio2 that only has one channel, I guess the 8 channel api was overkill. -// We simply map it to an extra channel after the 8 channels, since they can be used concurrently. - -// The extra channel is for SRC/Output2/Vaudio. -AudioChannel chans[PSP_AUDIO_CHANNEL_MAX + 1]; - -// Enqueues the buffer pointer on the channel. If channel buffer queue is full (2 items?) will block until it isn't. -// For solid audio output we'll need a queue length of 2 buffers at least, we'll try that first. +// Enqueues the buffer pointed to on the channel. If channel buffer queue is full (2 items?) will block until it isn't. +// For solid audio output we'll need a queue length of 2 buffers at least. // Not sure about the range of volume, I often see 0x800 so that might be either // max or 50%? - static u32 sceAudioOutputBlocking(u32 chan, int vol, u32 samplePtr) { if (vol > 0xFFFF) { ERROR_LOG(SCEAUDIO, "sceAudioOutputBlocking() - invalid volume"); diff --git a/Core/HLE/sceAudio.h b/Core/HLE/sceAudio.h index 2c21192710..def23ebb02 100644 --- a/Core/HLE/sceAudio.h +++ b/Core/HLE/sceAudio.h @@ -47,27 +47,21 @@ const int PSP_AUDIO_CHANNEL_SRC = 8; const int PSP_AUDIO_CHANNEL_OUTPUT2 = 8; const int PSP_AUDIO_CHANNEL_VAUDIO = 8; -struct AudioChannelWaitInfo -{ +struct AudioChannelWaitInfo { SceUID threadID; int numSamples; }; -struct AudioChannel -{ - AudioChannel() { - clear(); - } - +struct AudioChannel { int index = 0; bool reserved = false; // last sample address - u32 sampleAddress; - u32 sampleCount; // Number of samples written in each OutputBlocking - u32 leftVolume; - u32 rightVolume; - u32 format; + u32 sampleAddress = 0; + u32 sampleCount = 0; // Number of samples written in each OutputBlocking + u32 leftVolume = 0; + u32 rightVolume = 0; + u32 format = 0; std::vector waitingThreads; From 92db25e486a7466960595d61bd696c956f5c4a61 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 12 Aug 2020 20:27:03 +0700 Subject: [PATCH 486/848] Renaming sceNp* NIDs functions to their proper function names. --- Core/HLE/sceNp.cpp | 129 ++++++++++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 36 deletions(-) diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index a8a926c72d..70dc77d9c7 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -23,23 +23,29 @@ #include "Core/HLE/sceNp.h" -static int sceNp_857B47D3() +static int sceNpInit(u32 poolsize, u32 poolptr) { - // No parameters - ERROR_LOG(HLE, "UNIMPL sceNp_857B47D3()"); + ERROR_LOG(HLE, "UNIMPL %s(%08x, %08x) at %08x", __FUNCTION__, poolsize, poolptr, currentMIPS->pc); return 0; } -static int sceNp_37E1E274() +static int sceNpTerm() { // No parameters - ERROR_LOG(HLE, "UNIMPL sceNp_37E1E274()"); + ERROR_LOG(HLE, "UNIMPL %s()", __FUNCTION__); + return 0; +} + +static int sceNpGetContentRatingFlag() +{ + ERROR_LOG(HLE, "UNIMPL %s()", __FUNCTION__); return 0; } const HLEFunction sceNp[] = { - {0X857B47D3, &WrapI_V, "sceNp_857B47D3", 'i', "" }, - {0X37E1E274, &WrapI_V, "sceNp_37E1E274", 'i', "" }, + {0X857B47D3, &WrapI_UU, "sceNpInit", 'i', "xx" }, + {0X37E1E274, &WrapI_V, "sceNpTerm", 'i', "" }, + {0XBB069A87, &WrapI_V, "sceNpGetContentRatingFlag", 'i', "" }, }; void Register_sceNp() @@ -47,22 +53,73 @@ void Register_sceNp() RegisterModule("sceNp", ARRAY_SIZE(sceNp), sceNp); } -static int sceNpAuth_4EC1F667() +static int sceNpAuthTerm() { // No parameters - ERROR_LOG(HLE, "UNIMPL sceNpAuth_4EC1F667()"); + ERROR_LOG(HLE, "UNIMPL %s()", __FUNCTION__); return 0; } -static int sceNpAuth_A1DE86F8(u32 poolSize, u32 stackSize, u32 threadPrio) +static int sceNpAuthInit(u32 poolSize, u32 stackSize, u32 threadPrio) { - ERROR_LOG(HLE, "UNIMPL sceNpAuth_A1DE86F8(%08x, %08x, %08x)",poolSize, stackSize, threadPrio); + ERROR_LOG(HLE, "UNIMPL %s(%08x, %08x, %08x)", __FUNCTION__, poolSize, stackSize, threadPrio); + return 0; +} + +/* +"Authenticating matching server usage license" on Patapon 3. Could be waiting for a state change for eternity? probably need to trigger a callback handler? +unknownPtr seems to be a struct where offset: + +00: 32-bit is the size of the struct (ie. 36 bytes), + +04: 32-bit is also a small number (ie. 3) a mode/event/flag enum may be?, + +08: 32-bit is a pointer to a productId? (ie. "EP9000-UCES01421_00"), + +0C: 4x 32-bit reserved? all zero + +1C: 32-bit random data or callback handler? optional handler? seems to be a valid pointer and pointing to a starting point of a function (have a label on the disassembly) + +20: 32-bit a pointer to a random data (4 to 8-bytes data max? both 2x 32-bit seems to be a valid pointer). optional handler args? +return value >= 0 and <0 seems to be stored at a different location by the game (valid result vs error code?) +*/ +static int sceNpAuthCreateStartRequest(u32 unknownPtr) +{ + ERROR_LOG(HLE, "UNIMPL %s(%08x) at %08x", __FUNCTION__, unknownPtr, currentMIPS->pc); + if (!Memory::IsValidAddress(unknownPtr)) + return hleLogError(HLE, -1, "invalid arg"); + + u32* params = (u32*)Memory::GetPointer(unknownPtr); + INFO_LOG(HLE, "%s - Product ID: %s", __FUNCTION__, Memory::IsValidAddress(params[2]) ? Memory::GetCharPointer(params[2]):""); + // Forcing callback args to bypass all the proper procedure and attempt to go straight to a fake success, might not works properly tho. + // 1st Arg usually either an ID returned from Create/AddHandler function or an Event ID if the game expecting a sequence of events. + // 2nd Arg seems to be used if not a negative number and exits the handler if it's negative (error code?) + // 3rd Arg seems to be a data (ie. 92 bytes of data?) pointer and tested for null within callback handler (optional callback args?) + if (params[0] >= 32) { + // These callback's args seems to be similar to the args of Adhocctl handler? (ie. event/flag, error, handlerArg) + u32 args[3] = { 0, 0, (params[0] >= 36) ? params[8] : 0 }; + hleEnqueueCall(params[7], 3, args); + } + + hleDelayResult(0, "give time", 500000); + return 0; +} + +// Used within callback of sceNpAuthCreateStartRequest (arg1 = callback's args[0], arg2 = structPtr?, arg3 = args[1]) +static int sceNpAuthGetTicket(u32 arg1, u32 arg2Ptr, u32 arg3) +{ + ERROR_LOG(HLE, "UNIMPL %s(%d, %08x, %d)", __FUNCTION__, arg1, arg2Ptr, arg3); + return 0; +} + +// Used within callback of sceNpAuthCreateStartRequest (arg1 = structPtr?, arg2 = args[1], arg3 = DLCcode? ie. "EP9000-UCES01421_00-DLL001", arg4 = 0) +static int sceNpAuthGetEntitlementById(u32 arg1Ptr, u32 arg2, u32 arg3Ptr, u32 arg4) +{ + ERROR_LOG(HLE, "UNIMPL %s(%08x, %d, %08x, %d)", __FUNCTION__, arg1Ptr, arg2, arg3Ptr, arg4); + INFO_LOG(HLE, "%s - Product ID: %s", __FUNCTION__, Memory::IsValidAddress(arg3Ptr) ? Memory::GetCharPointer(arg3Ptr) : ""); return 0; } const HLEFunction sceNpAuth[] = { - {0X4EC1F667, &WrapI_V, "sceNpAuth_4EC1F667", 'i', "" }, - {0XA1DE86F8, &WrapI_UUU, "sceNpAuth_A1DE86F8", 'i', "xxx"}, + {0X4EC1F667, &WrapI_V, "sceNpAuthTerm", 'i', "" }, + {0XA1DE86F8, &WrapI_UUU, "sceNpAuthInit", 'i', "xxx" }, + {0XCD86A656, &WrapI_U, "sceNpAuthCreateStartRequest", 'i', "x" }, + {0X3F1C1F70, &WrapI_UUU, "sceNpAuthGetTicket", 'i', "xxx" }, + {0X6900F084, &WrapI_UUUU, "sceNpAuthGetEntitlementById", 'i', "xxxx" }, }; void Register_sceNpAuth() @@ -70,22 +127,22 @@ void Register_sceNpAuth() RegisterModule("sceNpAuth", ARRAY_SIZE(sceNpAuth), sceNpAuth); } -static int sceNpService_00ACFAC3() +static int sceNpServiceTerm() { // No parameters - ERROR_LOG(HLE, "UNIMPL sceNpService_00ACFAC3()"); + ERROR_LOG(HLE, "UNIMPL %s()", __FUNCTION__); return 0; } -static int sceNpService_0F8F5821(u32 poolSize, u32 stackSize, u32 threadPrio) +static int sceNpServiceInit(u32 poolSize, u32 stackSize, u32 threadPrio) { - ERROR_LOG(HLE, "UNIMPL sceNpService_0F8F5821(%08x, %08x, %08x)",poolSize, stackSize, threadPrio); + ERROR_LOG(HLE, "UNIMPL %s(%08x, %08x, %08x)", __FUNCTION__, poolSize, stackSize, threadPrio); return 0; } const HLEFunction sceNpService[] = { - {0X00ACFAC3, &WrapI_V, "sceNpService_00ACFAC3", 'i', "" }, - {0X0F8F5821, &WrapI_UUU, "sceNpService_0F8F5821", 'i', "xxx"}, + {0X00ACFAC3, &WrapI_V, "sceNpServiceTerm", 'i', "" }, + {0X0F8F5821, &WrapI_UUU, "sceNpServiceInit", 'i', "xxx"}, }; void Register_sceNpService() @@ -94,25 +151,25 @@ void Register_sceNpService() } const HLEFunction sceNpCommerce2[] = { - {0X005B5F20, nullptr, "sceNpCommerce2_005B5F20", '?', "" }, - {0X0E9956E3, nullptr, "sceNpCommerce2_0e9956e3", '?', "" }, - {0X1888A9FE, nullptr, "sceNpCommerce2_1888a9fe", '?', "" }, - {0X1C952DCB, nullptr, "sceNpCommerce2_1c952dcb", '?', "" }, - {0X2B25F6E9, nullptr, "sceNpCommerce2_2b25f6e9", '?', "" }, - {0X3371D5F1, nullptr, "sceNpCommerce2_3371d5f1", '?', "" }, - {0X4ECD4503, nullptr, "sceNpCommerce2_4ecd4503", '?', "" }, - {0X590A3229, nullptr, "sceNpCommerce2_590a3229", '?', "" }, - {0X6F1FE37F, nullptr, "sceNpCommerce2_6f1fe37f", '?', "" }, - {0XA5A34EA4, nullptr, "sceNpCommerce2_a5a34ea4", '?', "" }, - {0XAA4A1E3D, nullptr, "sceNpCommerce2_aa4a1e3d", '?', "" }, - {0XBC61FFC8, nullptr, "sceNpCommerce2_bc61ffc8", '?', "" }, - {0XC7F32242, nullptr, "sceNpCommerce2_c7f32242", '?', "" }, - {0XF2278B90, nullptr, "sceNpCommerce2_f2278b90", '?', "" }, - {0XF297AB9C, nullptr, "sceNpCommerce2_f297ab9c", '?', "" }, - {0XFC30C19E, nullptr, "sceNpCommerce2_fc30c19e", '?', "" }, + {0X005B5F20, nullptr, "sceNpCommerce2GetProductInfoStart", '?', "" }, + {0X0E9956E3, nullptr, "sceNpCommerce2Init", '?', "" }, + {0X1888A9FE, nullptr, "sceNpCommerce2DestroyReq", '?', "" }, + {0X1C952DCB, nullptr, "sceNpCommerce2GetGameProductInfo", '?', "" }, + {0X2B25F6E9, nullptr, "sceNpCommerce2CreateSessionStart", '?', "" }, + {0X3371D5F1, nullptr, "sceNpCommerce2GetProductInfoCreateReq", '?', "" }, + {0X4ECD4503, nullptr, "sceNpCommerce2CreateSessionCreateReq", '?', "" }, + {0X590A3229, nullptr, "sceNpCommerce2GetSessionInfo", '?', "" }, + {0X6F1FE37F, nullptr, "sceNpCommerce2CreateCtx", '?', "" }, + {0XA5A34EA4, nullptr, "sceNpCommerce2Term", '?', "" }, + {0XAA4A1E3D, nullptr, "sceNpCommerce2GetProductInfoGetResult", '?', "" }, + {0XBC61FFC8, nullptr, "sceNpCommerce2CreateSessionGetResult", '?', "" }, + {0XC7F32242, nullptr, "sceNpCommerce2AbortReq", '?', "" }, + {0XF2278B90, nullptr, "sceNpCommerce2GetGameSkuInfoFromGameProductInfo", '?', "" }, + {0XF297AB9C, nullptr, "sceNpCommerce2DestroyCtx", '?', "" }, + {0XFC30C19E, nullptr, "sceNpCommerce2InitGetProductInfoResult", '?', "" }, }; void Register_sceNpCommerce2() { RegisterModule("sceNpCommerce2", ARRAY_SIZE(sceNpCommerce2), sceNpCommerce2); -} \ No newline at end of file +} From 2620957aba8b8f7b70744d7f11f7c834b43fb96d Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 12 Aug 2020 20:28:14 +0700 Subject: [PATCH 487/848] An attempt to simulate a fake PSN authentication on Patapon 3 --- Core/HLE/sceNet.cpp | 22 +++ Core/HLE/sceNp.cpp | 332 +++++++++++++++++++++++++++++++++++++++----- Core/HLE/sceNp.h | 261 +++++++++++++++++++++++++++++++++- 3 files changed, 577 insertions(+), 38 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index a631ee09c9..f26f6dee4f 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -44,6 +44,7 @@ #include "Core/HLE/proAdhoc.h" #include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/sceNet.h" +#include "Core/HLE/sceNp.h" #include "Core/Reporting.h" #include "Core/Instance.h" @@ -481,6 +482,27 @@ void __NetApctlCallbacks() } } + // We are temporarily borrowing APctl thread for NpAuth callbacks for testing to simulate authentication + if (!npAuthEvents.empty()) + { + auto args = npAuthEvents.front(); + auto id = &args.data[0]; + auto result = &args.data[1]; + auto argAddr = &args.data[2]; + npAuthEvents.pop_front(); + + delayus = (adhocEventDelayMS + 2 * adhocExtraPollDelayMS) * 1000; + + int handlerID = *id - 1; + for (std::map::iterator it = npAuthHandlers.begin(); it != npAuthHandlers.end(); ++it) { + if (it->first == handlerID) { + DEBUG_LOG(SCENET, "NpAuthCallback [HandlerID=%i][RequestID=%d][Result=%d][ArgsPtr=%08x]", it->first, *id, *result, it->second.argument); + // TODO: Update result / args.data[1] with the actual ticket length (or error code?) + hleEnqueueCall(it->second.entryPoint, 3, args.data); + } + } + } + // Must be delayed long enough whenever there is a pending callback. hleDelayResult(0, "Prevent Apctl thread from blocking", delayus); } diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index 70dc77d9c7..639776485d 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -18,14 +18,89 @@ // This is pretty much a stub implementation. Doesn't actually do anything, just tries to return values // to keep games happy anyway. +#include +#include +#include +#include +#include "Core/MemMapHelpers.h" +#include #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceNp.h" +#include -static int sceNpInit(u32 poolsize, u32 poolptr) + +bool npAuthInited = false; +SceNpAuthMemoryStat npAuthMemStat = {}; +std::string serviceId = ""; + +int parentalControl = PARENTAL_CONTROL_ENABLED; +int userAge = 24; // faking user Age to 24 yo +int chatRestriction = 0; // default/initial value on Patapon 3 is 1 (restricted boolean?) +std::string onlineId = "DummyOnlineId"; +std::string avatarUrl = "http://DummyAvatarUrl"; + +std::recursive_mutex npAuthEvtMtx; +std::deque npAuthEvents; +std::map npAuthHandlers; + + +// Tickets data are in big-endian based on captured packets +int writeTicketParam(u8* buffer, const u16_be type, const char* data = nullptr, const u16_be size = 0) { + if (buffer == nullptr) return 0; + + u16_be sz = (data == nullptr)? static_cast(0): size; + memcpy(buffer, &type, 2); + memcpy(buffer + 2, &sz, 2); + if (sz>0) memcpy(buffer + 4, data, sz); + + return sz + 4; +} + +int writeTicketStringParam(u8* buffer, const u16_be type, const char* data = nullptr, const u16_be size = 0) { + if (buffer == nullptr) return 0; + + u16_be sz = (data == nullptr) ? static_cast(0) : size; + memcpy(buffer, &type, 2); + memcpy(buffer + 2, &sz, 2); + if (sz > 0) { + memset(buffer + 4, 0, sz); + truncate_cpy((char*)buffer + 4, sz, data); + } + return sz + 4; +} + +int writeTicketU32Param(u8* buffer, const u16_be type, const u32_be data) { + if (buffer == nullptr) return 0; + + u16_be sz = 4; + memcpy(buffer, &type, 2); + memcpy(buffer + 2, &sz, 2); + memcpy(buffer + 4, &data, 4); + + return sz + 4; +} + +int writeTicketU64Param(u8* buffer, const u16_be type, const u64_be data) { + if (buffer == nullptr) return 0; + + u16_be sz = 8; + memcpy(buffer, &type, 2); + memcpy(buffer + 2, &sz, 2); + memcpy(buffer + 4, &data, sz); + + return sz + 4; +} + +void notifyNpAuthHandlers(u32 id, u32 result, u32 argAddr) { + std::lock_guard npAuthGuard(npAuthEvtMtx); + npAuthEvents.push_back({ id, result, argAddr }); +} + +static int sceNpInit() { - ERROR_LOG(HLE, "UNIMPL %s(%08x, %08x) at %08x", __FUNCTION__, poolsize, poolptr, currentMIPS->pc); + ERROR_LOG(HLE, "UNIMPL %s()", __FUNCTION__); return 0; } @@ -36,16 +111,36 @@ static int sceNpTerm() return 0; } -static int sceNpGetContentRatingFlag() +static int sceNpGetContentRatingFlag(u32 parentalControlAddr, u32 userAgeAddr) { - ERROR_LOG(HLE, "UNIMPL %s()", __FUNCTION__); + WARN_LOG(HLE, "UNTESTED %s(%08x, %08x)", __FUNCTION__, parentalControlAddr, userAgeAddr); + + if (!Memory::IsValidAddress(parentalControlAddr) || !Memory::IsValidAddress(userAgeAddr)) + return hleLogError(HLE, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); + + Memory::Write_U32(parentalControl, parentalControlAddr); + Memory::Write_U32(userAge, userAgeAddr); + + return 0; +} + +static int sceNpGetChatRestrictionFlag(u32 flagAddr) +{ + WARN_LOG(HLE, "UNTESTED %s(%08x)", __FUNCTION__, flagAddr); + + if (!Memory::IsValidAddress(flagAddr)) + return hleLogError(HLE, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); + + Memory::Write_U32(chatRestriction, flagAddr); + return 0; } const HLEFunction sceNp[] = { - {0X857B47D3, &WrapI_UU, "sceNpInit", 'i', "xx" }, + {0X857B47D3, &WrapI_V, "sceNpInit", 'i', "" }, {0X37E1E274, &WrapI_V, "sceNpTerm", 'i', "" }, - {0XBB069A87, &WrapI_V, "sceNpGetContentRatingFlag", 'i', "" }, + {0XBB069A87, &WrapI_UU, "sceNpGetContentRatingFlag", 'i', "xx" }, + {0X1D60AE4B, &WrapI_U, "sceNpGetChatRestrictionFlag", 'i', "x" }, }; void Register_sceNp() @@ -57,69 +152,205 @@ static int sceNpAuthTerm() { // No parameters ERROR_LOG(HLE, "UNIMPL %s()", __FUNCTION__); + npAuthInited = false; return 0; } static int sceNpAuthInit(u32 poolSize, u32 stackSize, u32 threadPrio) { - ERROR_LOG(HLE, "UNIMPL %s(%08x, %08x, %08x)", __FUNCTION__, poolSize, stackSize, threadPrio); + ERROR_LOG(HLE, "UNIMPL %s(%d, %d, %d)", __FUNCTION__, poolSize, stackSize, threadPrio); + npAuthMemStat.npMemSize = poolSize; + npAuthMemStat.npMaxMemSize = poolSize / 2; // Dummy + npAuthMemStat.npFreeMemSize = poolSize - 16; // Dummy. + + npAuthInited = true; + return 0; +} + +static int sceNpAuthGetMemoryStat(u32 memStatAddr) +{ + ERROR_LOG(HLE, "UNIMPL %s(%08x)", __FUNCTION__, memStatAddr); + + if (!Memory::IsValidAddress(memStatAddr)) + return hleLogError(HLE, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg"); + + Memory::WriteStruct(memStatAddr, &npAuthMemStat); + return 0; } /* "Authenticating matching server usage license" on Patapon 3. Could be waiting for a state change for eternity? probably need to trigger a callback handler? -unknownPtr seems to be a struct where offset: +TODO: Login to "https://auth.np.ac.playstation.net/nav/auth" based on https://www.psdevwiki.com/ps3/Online_Connections +param seems to be a struct where offset: +00: 32-bit is the size of the struct (ie. 36 bytes), - +04: 32-bit is also a small number (ie. 3) a mode/event/flag enum may be?, + +04: 32-bit is also a small number (ie. 3) a mode/event/flag/version may be?, +08: 32-bit is a pointer to a productId? (ie. "EP9000-UCES01421_00"), +0C: 4x 32-bit reserved? all zero - +1C: 32-bit random data or callback handler? optional handler? seems to be a valid pointer and pointing to a starting point of a function (have a label on the disassembly) + +1C: 32-bit callback handler? optional handler? seems to be a valid pointer and pointing to a starting point of a function (have a label on the disassembly) +20: 32-bit a pointer to a random data (4 to 8-bytes data max? both 2x 32-bit seems to be a valid pointer). optional handler args? return value >= 0 and <0 seems to be stored at a different location by the game (valid result vs error code?) */ -static int sceNpAuthCreateStartRequest(u32 unknownPtr) +static int sceNpAuthCreateStartRequest(u32 paramAddr) { - ERROR_LOG(HLE, "UNIMPL %s(%08x) at %08x", __FUNCTION__, unknownPtr, currentMIPS->pc); - if (!Memory::IsValidAddress(unknownPtr)) - return hleLogError(HLE, -1, "invalid arg"); + WARN_LOG(HLE, "UNTESTED %s(%08x) at %08x", __FUNCTION__, paramAddr, currentMIPS->pc); - u32* params = (u32*)Memory::GetPointer(unknownPtr); - INFO_LOG(HLE, "%s - Product ID: %s", __FUNCTION__, Memory::IsValidAddress(params[2]) ? Memory::GetCharPointer(params[2]):""); - // Forcing callback args to bypass all the proper procedure and attempt to go straight to a fake success, might not works properly tho. - // 1st Arg usually either an ID returned from Create/AddHandler function or an Event ID if the game expecting a sequence of events. - // 2nd Arg seems to be used if not a negative number and exits the handler if it's negative (error code?) - // 3rd Arg seems to be a data (ie. 92 bytes of data?) pointer and tested for null within callback handler (optional callback args?) - if (params[0] >= 32) { - // These callback's args seems to be similar to the args of Adhocctl handler? (ie. event/flag, error, handlerArg) - u32 args[3] = { 0, 0, (params[0] >= 36) ? params[8] : 0 }; - hleEnqueueCall(params[7], 3, args); + if (!Memory::IsValidAddress(paramAddr)) + return hleLogError(HLE, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg"); + + SceNpAuthRequestParameter params = {}; + int size = Memory::Read_U32(paramAddr); + Memory::Memcpy(¶ms, paramAddr, size); + serviceId = Memory::GetCharPointer(params.serviceIdAddr); + + INFO_LOG(HLE, "%s - Max Version: %u.%u", __FUNCTION__, params.version.major, params.version.minor); + INFO_LOG(HLE, "%s - Service ID: %s", __FUNCTION__, Memory::GetCharPointer(params.serviceIdAddr)); + INFO_LOG(HLE, "%s - Entitlement ID: %s", __FUNCTION__, Memory::GetCharPointer(params.entitlementIdAddr)); + INFO_LOG(HLE, "%s - Cookie (size = %d): %s", __FUNCTION__, params.cookieSize, Memory::GetCharPointer(params.cookieAddr)); + + u32 retval = 0; + if (params.size >= 32 && params.ticketCbAddr != 0) { + bool foundHandler = false; + + struct NpAuthHandler handler; + memset(&handler, 0, sizeof(handler)); + + while (npAuthHandlers.find(retval) != npAuthHandlers.end()) + ++retval; + + handler.entryPoint = params.ticketCbAddr; + handler.argument = params.cbArgAddr; + + for (std::map::iterator it = npAuthHandlers.begin(); it != npAuthHandlers.end(); it++) { + if (it->second.entryPoint == handler.entryPoint) { + foundHandler = true; + retval = it->first; + break; + } + } + + if (!foundHandler && Memory::IsValidAddress(handler.entryPoint)) { + npAuthHandlers[retval] = handler; + WARN_LOG(SCENET, "%s - Added handler(%08x, %08x) : %d", __FUNCTION__, handler.entryPoint, handler.argument, retval); + } + else { + ERROR_LOG(SCENET, "%s - Same handler(%08x, %08x) already exists", __FUNCTION__, handler.entryPoint, handler.argument); + } + // Patapon 3 will only Abort & Destroy AuthRequest if the ID is larger than 0. Is 0 a valid request id? + retval++; + + // 1st Arg usually either an ID returned from Create/AddHandler function or an Event ID if the game is expecting a sequence of events. + // 2nd Arg seems to be used if not a negative number and exits the handler if it's negative (error code?) + // 3rd Arg seems to be a data (ie. 92 bytes of data?) pointer and tested for null within callback handler (optional callback args?) + u32 ticketLength = 248; // default ticket length? should be updated using the ticket length returned from login + notifyNpAuthHandlers(retval, ticketLength, (params.size >= 36) ? params.cbArgAddr : 0); } - hleDelayResult(0, "give time", 500000); + //hleDelayResult(0, "give time", 500000); + return retval; +} + +// Used within callback of sceNpAuthCreateStartRequest (arg1 = callback's args[0], arg2 = output structPtr?, arg3 = callback's args[1]) +// Is this using request id for Arg1 or cbId? +// JPCSP is using length = 248 for dummy ticket +static int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length) +{ + ERROR_LOG(HLE, "UNIMPL %s(%d, %08x, %d) at %08x", __FUNCTION__, requestId, bufferAddr, length, currentMIPS->pc); + + if (!Memory::IsValidAddress(bufferAddr)) + return hleLogError(HLE, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg"); + + int result = length; + Memory::Memset(bufferAddr, 0, length); + SceNpTicket ticket = {}; + // Dummy Login ticket returned as Login response. Dummy ticket contents were taken from https://www.psdevwiki.com/ps3/X-I-5-Ticket + ticket.header.version = TICKET_VER_2_1; + ticket.header.size = 0xF0; // size excluding the header + u8* buf = Memory::GetPointer(bufferAddr + sizeof(ticket)); + int ofs = 0; + ofs += writeTicketParam(buf, PARAM_TYPE_STRING_ASCII, "\x4c\x47\x56\x3b\x81\x39\x4a\x22\xd8\x6b\xc1\x57\x71\x6e\xfd\xb8\xab\x63\xcc\x51", 20); // 20 random letters, token key? + ofs += writeTicketU32Param(buf + ofs, PARAM_TYPE_INT, 0x0100); // a flags? + PSPTimeval tv; + __RtcTimeOfDay(&tv); + u64 now = 1000ULL*tv.tv_sec + tv.tv_usec/1000ULL; // in milliseconds, since 1900? + ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_DATE, now); + ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_DATE, now + 10 * 60 * 1000); // now + 10 minutes, expired time? + ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_LONG, 0x592e71c546e86859); // seems to be consistent, 8-bytes password hash may be? or related to entitlement? or console id? + ofs += writeTicketStringParam(buf + ofs, PARAM_TYPE_STRING, onlineId.c_str(), 32); // username + ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, "fr\0\2", 4); // SceNpCountryCode ? ie. "fr" + 00 02 + ofs += writeTicketStringParam(buf + ofs, PARAM_TYPE_STRING, "c9", 4); // 2-char code? related to country/lang code? ie. "c9" + 00 00 + ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, serviceId.c_str(), 24); + int status = 0; + if (parentalControl == PARENTAL_CONTROL_ENABLED) { + status |= STATUS_ACCOUNT_PARENTAL_CONTROL_ENABLED; + } + status |= (userAge & 0x7F) << 24; + ofs += writeTicketU32Param(buf + ofs, PARAM_TYPE_INT, status); + ofs += writeTicketParam(buf + ofs, PARAM_TYPE_NULL); + ofs += writeTicketParam(buf + ofs, PARAM_TYPE_NULL); + ticket.section.type = SECTION_TYPE_BODY; + ticket.section.size = ofs; + Memory::WriteStruct(bufferAddr, &ticket); + SceNpTicketSection footer = { SECTION_TYPE_FOOTER, 32 }; // footer section? ie. 32-bytes on ver 2.1 containing 4-chars ASCII + 20-chars ASCII + Memory::WriteStruct(bufferAddr + sizeof(ticket) + ofs, &footer); + ofs += sizeof(footer); + ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, "\x34\xcd\x3c\xa9", 4); + ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, "\x3a\x4b\x42\x66\x92\xda\x6b\x7c\xb7\x4c\xe8\xd9\x4f\x2b\x77\x15\x91\xb8\xa4\xa9", 20); + u8 unknownBytes[36] = {}; + Memory::WriteStruct(bufferAddr + sizeof(ticket) + ofs, unknownBytes); + + result = ticket.header.size + sizeof(ticket.header); // dummy ticket is 248 bytes + + return result; +} + +// Used within callback of sceNpAuthCreateStartRequest (arg1 = structPtr?, arg2 = callback's args[1], arg3 = DLCcode? ie. "EP9000-UCES01421_00-DLL001", arg4 = Patapon 3 always set to 0?) +// Patapon 3 will loop (for each DLC?) through an array of 4+4 bytes, ID addr (pchar) + result (int). Each loop calls this function using the same ticket addr but use different ID addr (arg3) and store the return value in result field (default/initial = -1) +static int sceNpAuthGetEntitlementById(u32 ticketBufferAddr, u32 ticketLength, u32 entitlementIdAddr, u32 arg4) +{ + ERROR_LOG(HLE, "UNIMPL %s(%08x, %d, %08x, %d)", __FUNCTION__, ticketBufferAddr, ticketLength, entitlementIdAddr, arg4); + INFO_LOG(HLE, "%s - Entitlement ID: %s", __FUNCTION__, Memory::GetCharPointer(entitlementIdAddr)); + // Do we return the entitlement through function result? or update the ticket content? or replace the arg3 data with SceNpEntitlement struct? + return 1; // dummy value assuming it's a boolean/flag, since we don't know how to return the entitlement result yet +} + +static int sceNpAuthAbortRequest(int requestId) +{ + WARN_LOG(HLE, "UNTESTED %s(%i)", __FUNCTION__, requestId); + // TODO: Disconnect HTTPS connection & cancel the callback event + std::lock_guard npAuthGuard(npAuthEvtMtx); + for (auto it = npAuthEvents.begin(); it != npAuthEvents.end(); ) { + (it->data[0] == requestId) ? it = npAuthEvents.erase(it) : ++it; + } return 0; } -// Used within callback of sceNpAuthCreateStartRequest (arg1 = callback's args[0], arg2 = structPtr?, arg3 = args[1]) -static int sceNpAuthGetTicket(u32 arg1, u32 arg2Ptr, u32 arg3) +static int sceNpAuthDestroyRequest(int requestId) { - ERROR_LOG(HLE, "UNIMPL %s(%d, %08x, %d)", __FUNCTION__, arg1, arg2Ptr, arg3); + WARN_LOG(HLE, "UNTESTED %s(%i)", __FUNCTION__, requestId); + // Remove callback handler + int handlerID = requestId - 1; + if (npAuthHandlers.find(handlerID) != npAuthHandlers.end()) { + npAuthHandlers.erase(handlerID); + WARN_LOG(SCENET, "%s: Deleted handler %d", __FUNCTION__, handlerID); + } + else { + ERROR_LOG(SCENET, "%s: Invalid request ID %d", __FUNCTION__, requestId); + } + // Patapon 3 is checking for error code 0x80550402 return 0; } -// Used within callback of sceNpAuthCreateStartRequest (arg1 = structPtr?, arg2 = args[1], arg3 = DLCcode? ie. "EP9000-UCES01421_00-DLL001", arg4 = 0) -static int sceNpAuthGetEntitlementById(u32 arg1Ptr, u32 arg2, u32 arg3Ptr, u32 arg4) -{ - ERROR_LOG(HLE, "UNIMPL %s(%08x, %d, %08x, %d)", __FUNCTION__, arg1Ptr, arg2, arg3Ptr, arg4); - INFO_LOG(HLE, "%s - Product ID: %s", __FUNCTION__, Memory::IsValidAddress(arg3Ptr) ? Memory::GetCharPointer(arg3Ptr) : ""); - return 0; -} const HLEFunction sceNpAuth[] = { {0X4EC1F667, &WrapI_V, "sceNpAuthTerm", 'i', "" }, {0XA1DE86F8, &WrapI_UUU, "sceNpAuthInit", 'i', "xxx" }, + {0XF4531ADC, &WrapI_U, "sceNpAuthGetMemoryStat", 'i', "x" }, {0XCD86A656, &WrapI_U, "sceNpAuthCreateStartRequest", 'i', "x" }, {0X3F1C1F70, &WrapI_UUU, "sceNpAuthGetTicket", 'i', "xxx" }, {0X6900F084, &WrapI_UUUU, "sceNpAuthGetEntitlementById", 'i', "xxxx" }, + {0XD99455DD, &WrapI_I, "sceNpAuthAbortRequest", 'i', "i" }, + {0X72BB0467, &WrapI_I, "sceNpAuthDestroyRequest", 'i', "i" }, }; void Register_sceNpAuth() @@ -140,9 +371,36 @@ static int sceNpServiceInit(u32 poolSize, u32 stackSize, u32 threadPrio) return 0; } +static int sceNpLookupCreateTransactionCtx(u32 lookupTitleCtxIdAddr) +{ + ERROR_LOG(HLE, "UNIMPL %s(%08x)", __FUNCTION__, lookupTitleCtxIdAddr); + INFO_LOG(SCENET, "%s - Title ID: %s", __FUNCTION__, Memory::GetCharPointer(lookupTitleCtxIdAddr)); + // Patapon 3 will only Destroy if returned Id > 0. Is 0 a valid id? + return 1; // returning dummy transaction id +} + +// transId: id returned from sceNpLookupCreateTransactionCtx +static int sceNpLookupDestroyTransactionCtx(u32 transId) +{ + ERROR_LOG(HLE, "UNIMPL %s(%d)", __FUNCTION__, transId); + return 0; +} + +// transId: id returned from sceNpLookupCreateTransactionCtx +// Patapon 3 always set Arg5 to 0 +// Addr args have something to do with GameUpdate? +static int sceNpLookupTitleSmallStorage(u32 transId, u32 arg2Addr, u32 arg3, u32 arg4Addr, u32 arg5) +{ + ERROR_LOG(HLE, "UNIMPL %s(%d, %08x, %08x, %08x, %08x)", __FUNCTION__, transId, arg2Addr, arg3, arg4Addr, arg5); + return 0; +} + const HLEFunction sceNpService[] = { - {0X00ACFAC3, &WrapI_V, "sceNpServiceTerm", 'i', "" }, - {0X0F8F5821, &WrapI_UUU, "sceNpServiceInit", 'i', "xxx"}, + {0X00ACFAC3, &WrapI_V, "sceNpServiceTerm", 'i', "" }, + {0X0F8F5821, &WrapI_UUU, "sceNpServiceInit", 'i', "xxx" }, + {0X5494274B, &WrapI_U, "sceNpLookupCreateTransactionCtx", 'i', "x" }, + {0XA670D3A3, &WrapI_U, "sceNpLookupDestroyTransactionCtx", 'i', "x" }, + {0XC76F55ED, &WrapI_UUUUU, "sceNpLookupTitleSmallStorage", 'i', "xxxxx" }, }; void Register_sceNpService() diff --git a/Core/HLE/sceNp.h b/Core/HLE/sceNp.h index 7985a4d739..3c117b33c7 100644 --- a/Core/HLE/sceNp.h +++ b/Core/HLE/sceNp.h @@ -17,7 +17,266 @@ #pragma once +#ifdef _MSC_VER +#pragma pack(push,1) +#endif + +// Based on https://playstationdev.wiki/psvitadevwiki/index.php?title=Error_Codes +#define SCE_NP_ERROR_ALREADY_INITIALIZED 0x80550001 +#define SCE_NP_ERROR_NOT_INITIALIZED 0x80550002 +#define SCE_NP_ERROR_INVALID_ARGUMENT 0x80550003 + +#define SCE_NP_AUTH_ERROR_ALREADY_INITIALIZED 0x80550301 +#define SCE_NP_AUTH_ERROR_NOT_INITIALIZED 0x80550302 +#define SCE_NP_AUTH_ERROR_EINVAL 0x80550303 +#define SCE_NP_AUTH_ERROR_ENOMEM 0x80550304 +#define SCE_NP_AUTH_ERROR_ESRCH 0x80550305 +#define SCE_NP_AUTH_ERROR_EBUSY 0x80550306 +#define SCE_NP_AUTH_ERROR_ABORTED 0x80550307 +#define SCE_NP_AUTH_ERROR_INVALID_SERVICE_ID 0x80550308 +#define SCE_NP_AUTH_ERROR_INVALID_CREDENTIAL 0x80550309 +#define SCE_NP_AUTH_ERROR_INVALID_ENTITLEMENT_ID 0x8055030a +#define SCE_NP_AUTH_ERROR_INVALID_DATA_LENGTH 0x8055030b +#define SCE_NP_AUTH_ERROR_UNSUPPORTED_TICKET_VERSION 0x8055030c +#define SCE_NP_AUTH_ERROR_STACKSIZE_TOO_SHORT 0x8055030d +#define SCE_NP_AUTH_ERROR_TICKET_STATUS_CODE_INVALID 0x8055030e +#define SCE_NP_AUTH_ERROR_TICKET_PARAM_NOT_FOUND 0x8055030f +#define SCE_NP_AUTH_ERROR_INVALID_TICKET_VERSION 0x80550310 +#define SCE_NP_AUTH_ERROR_INVALID_ARGUMENT 0x80550311 + +#define SCE_NP_AUTH_ERROR_SERVICE_END 0x80550400 +#define SCE_NP_AUTH_ERROR_SERVICE_DOWN 0x80550401 +#define SCE_NP_AUTH_ERROR_SERVICE_BUSY 0x80550402 + +// Based on https://github.com/RPCS3/rpcs3/blob/psp2/rpcs3/Emu/PSP2/Modules/sceNpCommon.h +enum SceNpServiceState : s32 +{ + SCE_NP_SERVICE_STATE_UNKNOWN = 0, + SCE_NP_SERVICE_STATE_SIGNED_OUT, + SCE_NP_SERVICE_STATE_SIGNED_IN, + SCE_NP_SERVICE_STATE_ONLINE +}; + +struct SceNpCommunicationId +{ + char data[9]; + char term; + u8 num; + char dummy; +}; + +struct SceNpCommunicationPassphrase +{ + u8 data[128]; +}; + +struct SceNpCommunicationSignature +{ + u8 data[160]; +}; + +struct SceNpCommunicationConfig +{ + PSPPointer commId; + PSPPointer commPassphrase; + PSPPointer commSignature; +}; + +struct SceNpCountryCode +{ + char data[2]; + char term; + char padding[1]; +}; + +// Username? +struct SceNpOnlineId +{ + char data[16]; + char term; + char dummy[3]; +}; + +struct SceNpId +{ + SceNpOnlineId handle; + u8 opt[8]; + u8 reserved[8]; +}; + +struct SceNpAvatarUrl +{ + char data[127]; + char term; +}; + +struct SceNpUserInformation +{ + SceNpId userId; + SceNpAvatarUrl icon; + u8 reserved[52]; +}; + +struct SceNpMyLanguages +{ + s32_le language1; + s32_le language2; + s32_le language3; + u8 padding[4]; +}; + +struct SceNpAvatarImage +{ + u8 data[200 * 1024]; + u32_le size; + u8 reserved[12]; +}; + +enum SceNpAvatarSizeType : s32 +{ + SCE_NP_AVATAR_SIZE_LARGE, + SCE_NP_AVATAR_SIZE_MIDDLE, + SCE_NP_AVATAR_SIZE_SMALL +}; + +struct SceNpAboutMe +{ + char data[64]; +}; + +struct SceNpDate +{ + u16_le year; + u8 month; + u8 day; +}; + +union SceNpTicketParam +{ + s32_le _s32; + s64_le _s64; + u32_le _u32; + u64_le _u64; + SceNpDate date; + u8 data[256]; +}; + +struct SceNpTicketVersion +{ + u16_le major; + u16_le minor; +}; + +struct NpAuthHandler { + u32 entryPoint; + u32 argument; +}; + +struct NpAuthArgs { + u32_le data[3]; // id, result, ArgAddr +}; + +using SceNpAuthCallback = s32(s32 id, s32 result, PSPPointer arg); + +struct SceNpAuthRequestParameter +{ + u32_le size; // Size of this struct + SceNpTicketVersion version; // Highest ticket version supported by this game/device? so PSN server can return supported ticket + u32_le serviceIdAddr; //PSPPointer serviceId; // null-terminated string + u32_le cookieAddr; //PSPPointer cookie; // null-terminated string? + u32_le cookieSize; + u32_le entitlementIdAddr; //PSPPointer entitlementId; // null-terminated string + u32_le consumedCount; // related to entitlement? + u32 ticketCbAddr; //PSPPointer ticketCb + u32_le cbArgAddr; //PSPPointer cbArg +}; + +struct SceNpEntitlementId +{ + u8 data[32]; +}; + +struct SceNpEntitlement +{ + SceNpEntitlementId id; + u64_le createdDate; + u64_le expireDate; + u32_le type; + s32_le remainingCount; + u32_le consumedCount; + u8 padding[4]; +}; + +#define TICKET_VER_2_0 0x21000000; +#define TICKET_VER_2_1 0x21010000; +#define TICKET_VER_3_0 0x31000000; +#define TICKET_VER_4_0 0x41000000; + +#define NUMBER_PARAMETERS 12 + +#define PARAM_TYPE_NULL 0 +#define PARAM_TYPE_INT 1 +#define PARAM_TYPE_LONG 2 +#define PARAM_TYPE_STRING 4 // PSP returns maximum 255 bytes +#define PARAM_TYPE_DATE 7 +#define PARAM_TYPE_STRING_ASCII 8 // PSP returns maximum 255 bytes, can contains control code + +#define SECTION_TYPE_BODY 0x3000 +#define SECTION_TYPE_FOOTER 0x3002 + +// Tickets data are in big-endian based on captured packets +struct SceNpTicketParamData +{ + u16_be type; + u16_be length; + //u8 value[]; // optional data +}; + +struct SceNpTicketHeader +{ + u32_be version; // Version contents byte are: V1 0M 00 00, where V = major version, M = minor version according to https://www.psdevwiki.com/ps3/X-I-5-Ticket + s32_be size; // total ticket size (excluding this 8-bytes header struct) +}; + +// Section contents byte are: 30 XX 00 YY, where XX = section type, YY = section size according to https://www.psdevwiki.com/ps3/X-I-5-Ticket +// A section can contain other sections or param data, thus sharing their enum/def? +struct SceNpTicketSection +{ + u16_be type; // section type? ie. 30 XX where known XX are 00, 02, 10, 11 + u16_be size; // total section size (excluding this 4-bytes section delimiter struct) +}; + +struct SceNpTicket +{ + SceNpTicketHeader header; + SceNpTicketSection section; // Body or Parameter sections? + //SceNpTicketParamData parameters[]; // a list of TicketParamData + //u8 unknownBytes[]; // optional data? +}; + +#define PARENTAL_CONTROL_DISABLED 0 +#define PARENTAL_CONTROL_ENABLED 1 + +#define STATUS_ACCOUNT_SUSPENDED 0x80 +#define STATUS_ACCOUNT_CHAT_RESTRICTED 0x100 +#define STATUS_ACCOUNT_PARENTAL_CONTROL_ENABLED 0x200 + +struct SceNpAuthMemoryStat { + int npMemSize; // Memory allocated by the NP utility. + int npMaxMemSize; // Maximum memory used by the NP utility. + int npFreeMemSize; // Free memory available to use by the NP utility. +}; + +#ifdef _MSC_VER +#pragma pack(pop) +#endif + + +extern std::recursive_mutex npAuthEvtMtx; +extern std::deque npAuthEvents; +extern std::map npAuthHandlers; + void Register_sceNp(); void Register_sceNpCommerce2(); void Register_sceNpService(); -void Register_sceNpAuth(); \ No newline at end of file +void Register_sceNpAuth(); From 8dec09703fc6ec2e8528259654ea048cc455261f Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 8 Aug 2020 03:53:55 +0700 Subject: [PATCH 488/848] Moving reused adhoc function out of sceNet function to prevent getting extra SCENET log --- Core/HLE/sceNet.cpp | 71 ++++++++++++---------- Core/HLE/sceNet.h | 3 + Core/HLE/sceNetAdhoc.cpp | 127 ++++++++++++++++++++------------------- Core/HLE/sceNetAdhoc.h | 1 + 4 files changed, 110 insertions(+), 92 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index f26f6dee4f..e0119ead88 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -917,9 +917,7 @@ static int sceNetApctlGetInfo(int code, u32 pInfoAddr) { return hleLogSuccessI(SCENET, 0); } -// TODO: How many handlers can the PSP actually have for Apctl? -// TODO: Should we allow the same handler to be added more than once? -static u32 sceNetApctlAddHandler(u32 handlerPtr, u32 handlerArg) { +int NetApctl_AddHandler(u32 handlerPtr, u32 handlerArg) { bool foundHandler = false; u32 retval = 0; struct ApctlHandler handler; @@ -931,41 +929,53 @@ static u32 sceNetApctlAddHandler(u32 handlerPtr, u32 handlerArg) { handler.entryPoint = handlerPtr; handler.argument = handlerArg; - for(std::map::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); it++) { - if(it->second.entryPoint == handlerPtr) { + for (std::map::iterator it = apctlHandlers.begin(); it != apctlHandlers.end(); it++) { + if (it->second.entryPoint == handlerPtr) { foundHandler = true; break; } } - if(!foundHandler && Memory::IsValidAddress(handlerPtr)) { - if(apctlHandlers.size() >= MAX_APCTL_HANDLERS) { - ERROR_LOG(SCENET, "UNTESTED sceNetApctlAddHandler(%x, %x): Too many handlers", handlerPtr, handlerArg); + if (!foundHandler && Memory::IsValidAddress(handlerPtr)) { + if (apctlHandlers.size() >= MAX_APCTL_HANDLERS) { + ERROR_LOG(SCENET, "Failed to Add handler(%x, %x): Too many handlers", handlerPtr, handlerArg); retval = ERROR_NET_ADHOCCTL_TOO_MANY_HANDLERS; // TODO: What's the proper error code for Apctl's TOO_MANY_HANDLERS? return retval; } apctlHandlers[retval] = handler; - WARN_LOG(SCENET, "UNTESTED sceNetApctlAddHandler(%x, %x): added handler %d", handlerPtr, handlerArg, retval); + WARN_LOG(SCENET, "Added Apctl handler(%x, %x): %d", handlerPtr, handlerArg, retval); } else { - ERROR_LOG(SCENET, "UNTESTED sceNetApctlAddHandler(%x, %x): Same handler already exists", handlerPtr, handlerArg); + ERROR_LOG(SCENET, "Existing Apctl handler(%x, %x)", handlerPtr, handlerArg); } // The id to return is the number of handlers currently registered return retval; } -static int sceNetApctlDelHandler(u32 handlerID) { - if(apctlHandlers.find(handlerID) != apctlHandlers.end()) { +// TODO: How many handlers can the PSP actually have for Apctl? +// TODO: Should we allow the same handler to be added more than once? +static u32 sceNetApctlAddHandler(u32 handlerPtr, u32 handlerArg) { + INFO_LOG(SCENET, "%s(%08x, %08x)", __FUNCTION__, handlerPtr, handlerArg); + return NetApctl_AddHandler(handlerPtr, handlerArg); +} + +int NetApctl_DelHandler(u32 handlerID) { + if (apctlHandlers.find(handlerID) != apctlHandlers.end()) { apctlHandlers.erase(handlerID); - WARN_LOG(SCENET, "UNTESTED sceNetapctlDelHandler(%d): deleted handler %d", handlerID, handlerID); + WARN_LOG(SCENET, "Deleted Apctl handler: %d", handlerID); } else { - ERROR_LOG(SCENET, "UNTESTED sceNetapctlDelHandler(%d): asked to delete invalid handler %d", handlerID, handlerID); + ERROR_LOG(SCENET, "Invalid Apctl handler: %d", handlerID); } return 0; } +static int sceNetApctlDelHandler(u32 handlerID) { + INFO_LOG(SCENET, "%s(%d)", __FUNCTION__, handlerID); + return NetApctl_DelHandler(handlerID); +} + static int sceNetInetInetAton(const char *hostname, u32 addrPtr) { ERROR_LOG(SCENET, "UNIMPL sceNetInetInetAton(%s, %08x)", hostname, addrPtr); return -1; @@ -1067,7 +1077,7 @@ static int sceNetInetConnect(int socket, u32 sockAddrInternetPtr, int addressLen return -1; } -static int sceNetApctlConnect(int connIndex) { +int sceNetApctlConnect(int connIndex) { ERROR_LOG(SCENET, "UNIMPL %s(%i)", __FUNCTION__, connIndex); // Is this connIndex is the index to the scanning's result data or sceNetApctlGetBSSDescIDListUser result? __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_CONNECT_REQUEST, 0); @@ -1083,15 +1093,17 @@ static int sceNetApctlDisconnect() { return 0; } +int NetApctl_GetState() { + return netApctlState; +} + static int sceNetApctlGetState(u32 pStateAddr) { - WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, pStateAddr); - //if (!netApctlInited) return hleLogError(SCENET, ERROR_NET_APCTL_NOT_IN_BSS, "apctl not in bss"); // Valid Arguments if (Memory::IsValidAddress(pStateAddr)) { // Return Thread Status - Memory::Write_U32(netApctlState, pStateAddr); + Memory::Write_U32(NetApctl_GetState(), pStateAddr); // Return Success return hleLogSuccessI(SCENET, 0); } @@ -1099,9 +1111,7 @@ static int sceNetApctlGetState(u32 pStateAddr) { return hleLogError(SCENET, -1, "apctl invalid arg"); } -static int sceNetApctlScanUser() { - ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); - +int NetApctl_ScanUser() { // Scan probably only works when not in connected state, right? if (netApctlState != PSP_NET_APCTL_STATE_DISCONNECTED) return hleLogError(SCENET, ERROR_NET_APCTL_NOT_DISCONNECTED, "apctl not disconnected"); @@ -1110,6 +1120,11 @@ static int sceNetApctlScanUser() { return 0; } +static int sceNetApctlScanUser() { + ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); + return NetApctl_ScanUser(); +} + static int sceNetApctlGetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) { WARN_LOG(SCENET, "UNTESTED %s(%08x, %08x)", __FUNCTION__, sizeAddr, bufAddr); @@ -1183,13 +1198,7 @@ static int sceNetApctlGetBSSDescEntryUser(int entryId, int infoId, u32 resultAdd static int sceNetApctlScanSSID2() { ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); - - // Scan probably only works when not in connected state, right? - if (netApctlState != PSP_NET_APCTL_STATE_DISCONNECTED) - return hleLogError(SCENET, ERROR_NET_APCTL_NOT_DISCONNECTED, "apctl not disconnected"); - - __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_SCAN_REQUEST, 0); - return 0; + return NetApctl_ScanUser(); } static int sceNetApctlGetBSSDescIDList2(u32 Arg1, u32 Arg2, u32 Arg3, u32 Arg4) { @@ -1209,13 +1218,13 @@ static int sceNetResolverInit() static int sceNetApctlAddInternalHandler(u32 handlerPtr, u32 handlerArg) { ERROR_LOG(SCENET, "UNIMPL %s(%08x, %08x)", __FUNCTION__, handlerPtr, handlerArg); // This seems to be a 2nd kind of handler - return sceNetApctlAddHandler(handlerPtr, handlerArg); + return NetApctl_AddHandler(handlerPtr, handlerArg); } static int sceNetApctlDelInternalHandler(u32 handlerID) { ERROR_LOG(SCENET, "UNIMPL %s(%i)", __FUNCTION__, handlerID); // This seems to be a 2nd kind of handler - return sceNetApctlDelHandler(handlerID); + return NetApctl_DelHandler(handlerID); } static int sceNetApctl_A7BB73DF(u32 handlerPtr, u32 handlerArg) { @@ -1241,7 +1250,7 @@ static int sceNetApctl_lib2_4C19731F(int code, u32 pInfoAddr) { static int sceNetApctlScan() { ERROR_LOG(SCENET, "UNIMPL %s()", __FUNCTION__); - return sceNetApctlScanUser(); + return NetApctl_ScanUser(); } static int sceNetApctlGetBSSDescIDList(u32 sizeAddr, u32 bufAddr) { diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index 73f4566eb9..12e9c4413a 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -233,6 +233,9 @@ void __NetInit(); void __NetShutdown(); void __NetDoState(PointerWrap &p); +int NetApctl_GetState(); + +int sceNetApctlConnect(int connIndex); int sceNetInetPoll(void *fds, u32 nfds, int timeout); int sceNetInetTerm(); int sceNetApctlTerm(); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 1260fcaead..05e5e663c0 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -274,23 +274,24 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { return 0; } +int NetAdhocctl_GetState() { + return threadStatus; +} + static int sceNetAdhocctlGetState(u32 ptrToStatus) { - // Library initialized - if (netAdhocctlInited) { - // Valid Arguments - if (Memory::IsValidAddress(ptrToStatus)) { - // Return Thread Status - Memory::Write_U32(threadStatus, ptrToStatus); - // Return Success - return 0; - } - - // Invalid Arguments - return ERROR_NET_ADHOCCTL_INVALID_ARG; - } - // Library uninitialized - return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; + if (!netAdhocctlInited) + return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; + + // Invalid Arguments + if (!Memory::IsValidAddress(ptrToStatus)) + return ERROR_NET_ADHOCCTL_INVALID_ARG; + + // Return Thread Status + Memory::Write_U32(NetAdhocctl_GetState(), ptrToStatus); + // Return Success + return hleLogSuccessVerboseI(SCENET, 0); + } /** @@ -1431,34 +1432,6 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } -static int sceNetAdhocctlJoin(u32 scanInfoAddr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlJoin(%08x) at %08x", scanInfoAddr, currentMIPS->pc); - if (!g_Config.bEnableWlan) { - return -1; - } - - // Library initialized - if (netAdhocctlInited) - { - // Valid Argument - if (Memory::IsValidAddress(scanInfoAddr)) - { - SceNetAdhocctlScanInfoEmu * sinfo = (SceNetAdhocctlScanInfoEmu *)Memory::GetPointer(scanInfoAddr); - //while (true) sleep_ms(1); - - // We can ignore minor connection process differences here - // TODO: Adhoc Server may need to be changed to differentiate between Host/Create and Join, otherwise it can't support multiple Host using the same Group name, thus causing one of the Host to be confused being treated as Join. - return sceNetAdhocctlCreate((const char*)&sinfo->group_name); - } - - // Invalid Argument - return ERROR_NET_ADHOCCTL_INVALID_ARG; - } - - // Uninitialized Library - return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; -} - int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { VERBOSE_LOG(SCENET, "sceNetAdhocctlGetPeerInfo(%s, %i, %08x) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), size, peerInfoAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) { @@ -1528,20 +1501,8 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } -/** - * Create and / or Join a Virtual Network of the specified Name - * @param group_name Virtual Network Name - * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG, ADHOCCTL_BUSY - */ -int sceNetAdhocctlCreate(const char *groupName) { - char grpName[9] = { 0 }; - memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs - INFO_LOG(SCENET, "sceNetAdhocctlCreate(%s) at %08x", grpName, currentMIPS->pc); - if (!g_Config.bEnableWlan) { - return -1; - } - - const SceNetAdhocctlGroupName * groupNameStruct = (const SceNetAdhocctlGroupName *)groupName; +int NetAdhocctl_Create(const char* groupName) { + const SceNetAdhocctlGroupName* groupNameStruct = (const SceNetAdhocctlGroupName*)groupName; // Library initialized if (netAdhocctlInited) { // Valid Argument @@ -1578,7 +1539,7 @@ int sceNetAdhocctlCreate(const char *groupName) { // Acquire Network Lock // Send Packet - int iResult = send(metasocket, (const char *)&packet, sizeof(packet), 0); + int iResult = send(metasocket, (const char*)&packet, sizeof(packet), 0); if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "Socket error (%i) when sending", errno); //return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY; @@ -1614,11 +1575,11 @@ int sceNetAdhocctlCreate(const char *groupName) { // Return Success return 0; } - + // Connected State return ERROR_NET_ADHOCCTL_BUSY; // ERROR_NET_ADHOCCTL_BUSY may trigger the game (ie. Ford Street Racing) to call sceNetAdhocctlDisconnect } - + // Invalid Argument return ERROR_NET_ADHOC_INVALID_ARG; } @@ -1626,6 +1587,22 @@ int sceNetAdhocctlCreate(const char *groupName) { return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } +/** + * Create and / or Join a Virtual Network of the specified Name + * @param group_name Virtual Network Name + * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG, ADHOCCTL_BUSY + */ +int sceNetAdhocctlCreate(const char *groupName) { + char grpName[9] = { 0 }; + memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + INFO_LOG(SCENET, "sceNetAdhocctlCreate(%s) at %08x", grpName, currentMIPS->pc); + if (!g_Config.bEnableWlan) { + return -1; + } + + return NetAdhocctl_Create(groupName); +} + static int sceNetAdhocctlConnect(u32 ptrToGroupName) { if (Memory::IsValidAddress(ptrToGroupName)) { const char* groupName = Memory::GetCharPointer(ptrToGroupName); @@ -1633,12 +1610,40 @@ static int sceNetAdhocctlConnect(u32 ptrToGroupName) { memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs INFO_LOG(SCENET, "sceNetAdhocctlConnect(groupName=%s) at %08x", grpName, currentMIPS->pc); - return sceNetAdhocctlCreate(groupName); + return NetAdhocctl_Create(groupName); } return ERROR_NET_ADHOC_INVALID_ARG; // ERROR_NET_ADHOC_INVALID_ADDR; } +static int sceNetAdhocctlJoin(u32 scanInfoAddr) { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlJoin(%08x) at %08x", scanInfoAddr, currentMIPS->pc); + if (!g_Config.bEnableWlan) { + return -1; + } + + // Library initialized + if (netAdhocctlInited) + { + // Valid Argument + if (Memory::IsValidAddress(scanInfoAddr)) + { + SceNetAdhocctlScanInfoEmu* sinfo = (SceNetAdhocctlScanInfoEmu*)Memory::GetPointer(scanInfoAddr); + //while (true) sleep_ms(1); + + // We can ignore minor connection process differences here + // TODO: Adhoc Server may need to be changed to differentiate between Host/Create and Join, otherwise it can't support multiple Host using the same Group name, thus causing one of the Host to be confused being treated as Join. + return NetAdhocctl_Create((const char*)&sinfo->group_name); + } + + // Invalid Argument + return ERROR_NET_ADHOCCTL_INVALID_ARG; + } + + // Uninitialized Library + return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; +} + // Connect to the Adhoc control game mode (as a Host) static int sceNetAdhocctlCreateEnterGameMode(const char *groupName, int unknown, int playerNum, u32 macsAddr, int timeout, int unknown2) { char grpName[9] = { 0 }; diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 68fb4e2bcc..98a859411d 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -62,4 +62,5 @@ extern u32_le matchingThreadCode[3]; int NetAdhocMatching_Term(); int NetAdhocctl_Term(); +int NetAdhocctl_GetState(); int NetAdhoc_Term(); From d9d8c031d48a2ad900e28fda91d8f4bc609d85e4 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 11 Aug 2020 22:55:52 +0700 Subject: [PATCH 489/848] Making sure std::min/max are not overridden by windows header's min/max --- Core/Dialog/PSPNetconfDialog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 1898cbcd94..36a4476eca 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -15,6 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#if defined(_WIN32) +#include "Common/CommonWindows.h" +#endif #include "i18n/i18n.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" From bd36b9dff19e9802dc3326d6d93f523da14cedba Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 12 Aug 2020 17:57:11 +0700 Subject: [PATCH 490/848] Shows AdHoc and Access Point Connecting... Dialog --- Core/Dialog/PSPNetconfDialog.cpp | 299 +++++++++++++++++++++++++++---- Core/Dialog/PSPNetconfDialog.h | 24 ++- Core/HLE/sceNet.cpp | 12 +- Core/HLE/sceNet.h | 1 + 4 files changed, 297 insertions(+), 39 deletions(-) diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 36a4476eca..f4436d5564 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -22,12 +22,14 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" -#include "Core/Dialog/PSPNetconfDialog.h" #include "Core/MemMapHelpers.h" -#include "Core/HLE/sceNetAdhoc.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" #include "Core/HLE/sceUtility.h" +#include +#include "Core/Dialog/PSPNetconfDialog.h" +#include + #define NETCONF_CONNECT_APNET 0 #define NETCONF_STATUS_APNET 1 @@ -36,9 +38,12 @@ #define NETCONF_CREATE_ADHOC 4 #define NETCONF_JOIN_ADHOC 5 +static const float FONT_SCALE = 0.65f; + // Needs testing. const static int NET_INIT_DELAY_US = 300000; const static int NET_SHUTDOWN_DELAY_US = 26000; +const static int NET_RUNNING_DELAY_US = 1000000; // KHBBS is showing adhoc dialog for about 3-4 seconds, but feels too long, so we're faking it to 1 sec instead to let players read the text PSPNetconfDialog::PSPNetconfDialog() { } @@ -51,6 +56,7 @@ int PSPNetconfDialog::Init(u32 paramAddr) { if (status != SCE_UTILITY_STATUS_NONE) return SCE_ERROR_UTILITY_INVALID_STATUS; + requestAddr = paramAddr; int size = Memory::Read_U32(paramAddr); memset(&request, 0, sizeof(request)); // Only copy the right size to support different request format @@ -60,6 +66,17 @@ int PSPNetconfDialog::Init(u32 paramAddr) { // Eat any keys pressed before the dialog inited. UpdateButtons(); + okButtonImg = ImageID("I_CIRCLE"); + cancelButtonImg = ImageID("I_CROSS"); + okButtonFlag = CTRL_CIRCLE; + cancelButtonFlag = CTRL_CROSS; + if (request.common.buttonSwap == 1) + { + okButtonImg = ImageID("I_CROSS"); + cancelButtonImg = ImageID("I_CIRCLE"); + okButtonFlag = CTRL_CROSS; + cancelButtonFlag = CTRL_CIRCLE; + } StartFade(true); return 0; @@ -67,15 +84,141 @@ int PSPNetconfDialog::Init(u32 paramAddr) { void PSPNetconfDialog::DrawBanner() { - PPGeDrawRect(0, 0, 480, 23, CalcFadedColor(0x65636358)); + PPGeDrawRect(0, 0, 480, 22, CalcFadedColor(0x65636358)); PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f); textStyle.hasShadow = false; // TODO: Draw a hexagon icon - PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, textStyle.color); + PPGeDrawImage(10, 5, 11.0f, 10.0f, 1, 10, 1, 10, 10, 10, CalcFadedColor(0xFFFFFFFF)); auto di = GetI18NCategory("Dialog"); - PPGeDrawText(di->T("Network Connection"), 30, 11, textStyle); + PPGeDrawText(di->T("Network Connection"), 31, 10, textStyle); +} + +void PSPNetconfDialog::DrawIndicator() { + + // TODO: Draw animated circle as processing indicator + PPGeDrawImage(456, 248, 20.0f, 20.0f, 1, 10, 1, 10, 10, 10, CalcFadedColor(0xFFFFFFFF)); +} + +void PSPNetconfDialog::DisplayMessage(std::string text1, std::string text2a, std::string text2b, std::string text3a, std::string text3b, bool hasYesNo, bool hasOK) { + auto di = GetI18NCategory("Dialog"); + + PPGeStyle buttonStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE); + PPGeStyle messageStyle = FadedStyle(PPGeAlign::BOX_HCENTER, FONT_SCALE); + PPGeStyle messageStyleRight = FadedStyle(PPGeAlign::BOX_RIGHT, FONT_SCALE); + PPGeStyle messageStyleLeft = FadedStyle(PPGeAlign::BOX_LEFT, FONT_SCALE); + + std::string text2 = text2a + " " + text2b; + std::string text3 = text3a + " " + text3b; + + // Without the scrollbar, we have 350 total pixels. + float WRAP_WIDTH = 300.0f; + if (UTF8StringNonASCIICount(text1.c_str()) >= text1.size() / 4) { + WRAP_WIDTH = 336.0f; + if (text1.size() > 12) { + messageStyle.scale = 0.6f; + } + } + + float totalHeight1 = 0.0f; + PPGeMeasureText(nullptr, &totalHeight1, text1.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH); + float totalHeight2 = 0.0f; + if (text2 != " ") + PPGeMeasureText(nullptr, &totalHeight2, text2.c_str(), FONT_SCALE, PPGE_LINE_USE_ELLIPSIS, WRAP_WIDTH); + float totalHeight3 = 0.0f; + if (text3 != " ") + PPGeMeasureText(nullptr, &totalHeight3, text3.c_str(), FONT_SCALE, PPGE_LINE_USE_ELLIPSIS, WRAP_WIDTH); + float marginTop = 0.0f; + if (text2 != " " || text3 != " ") + marginTop = 11.0f; + float totalHeight = totalHeight1 + totalHeight2 + totalHeight3 + marginTop; + // The PSP normally only shows about 8 lines at a time. + // For improved UX, we intentionally show part of the next line. + float visibleHeight = std::min(totalHeight, 175.0f); + float h2 = visibleHeight / 2.0f; + + float centerY = 135.0f; + float sy = centerY - h2 - 15.0f; + float ey = centerY + h2 + 20.0f; + float buttonY = centerY + h2 + 5.0f; + + auto drawSelectionBoxAndAdjust = [&](float x) { + // Box has a fixed size. + float w = 15.0f; + float h = 8.0f; + PPGeDrawRect(x - w, buttonY - h, x + w, buttonY + h, CalcFadedColor(0x6DCFCFCF)); + + centerY -= h + 5.0f; + sy -= h + 5.0f; + ey = buttonY + h * 2.0f + 5.0f; + }; + + if (hasYesNo) { + if (yesnoChoice == 1) { + drawSelectionBoxAndAdjust(204.0f); + } + else { + drawSelectionBoxAndAdjust(273.0f); + } + + PPGeDrawText(di->T("Yes"), 203.0f, buttonY - 1.0f, buttonStyle); + PPGeDrawText(di->T("No"), 272.0f, buttonY - 1.0f, buttonStyle); + if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) { + yesnoChoice = 1; + } + else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) { + yesnoChoice = 0; + } + buttonY += 8.0f + 5.0f; + } + + if (hasOK) { + drawSelectionBoxAndAdjust(240.0f); + + PPGeDrawText(di->T("OK"), 239.0f, buttonY - 1.0f, buttonStyle); + buttonY += 8.0f + 5.0f; + } + + PPGeScissor(0, (int)(centerY - h2 - 2), 480, (int)(centerY + h2 + 2)); + PPGeDrawTextWrapped(text1.c_str(), 240.0f, centerY - h2 - scrollPos_, WRAP_WIDTH, 0, messageStyle); + if (text2a != "") + PPGeDrawTextWrapped(text2a.c_str(), 240.0f - 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + marginTop, WRAP_WIDTH, 0, messageStyleRight); + if (text2b != "") + PPGeDrawTextWrapped(text2b.c_str(), 240.0f + 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + marginTop, WRAP_WIDTH, 0, messageStyleLeft); + if (text3a != "") + PPGeDrawTextWrapped(text3a.c_str(), 240.0f - 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + totalHeight2 + marginTop, WRAP_WIDTH, 0, messageStyleRight); + if (text3b != "") + PPGeDrawTextWrapped(text3b.c_str(), 240.0f + 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + totalHeight2 + marginTop, WRAP_WIDTH, 0, messageStyleLeft); + PPGeScissorReset(); + + // Do we need a scrollbar? + if (visibleHeight < totalHeight) { + float scrollSpeed = 5.0f; + float scrollMax = totalHeight - visibleHeight; + + float bobHeight = (visibleHeight / totalHeight) * visibleHeight; + float bobOffset = (scrollPos_ / scrollMax) * (visibleHeight - bobHeight); + float bobY1 = centerY - h2 + bobOffset; + PPGeDrawRect(415.0f, bobY1, 420.0f, bobY1 + bobHeight, CalcFadedColor(0xFFCCCCCC)); + + auto buttonDown = [this](int btn, int& held) { + if (IsButtonPressed(btn)) { + held = 0; + return true; + } + return IsButtonHeld(btn, held, 1, 1); + }; + if (buttonDown(CTRL_DOWN, framesDownHeld_) && scrollPos_ < scrollMax) { + scrollPos_ = std::min(scrollMax, scrollPos_ + scrollSpeed); + } + if (buttonDown(CTRL_UP, framesUpHeld_) && scrollPos_ > 0.0f) { + scrollPos_ = std::max(0.0f, scrollPos_ - scrollSpeed); + } + } + + PPGeDrawRect(60.0f, sy, 420.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawRect(60.0f, ey, 420.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF)); } int PSPNetconfDialog::Update(int animSpeed) { @@ -86,42 +229,133 @@ int PSPNetconfDialog::Update(int animSpeed) { UpdateButtons(); auto di = GetI18NCategory("Dialog"); auto err = GetI18NCategory("Error"); - const float WRAP_WIDTH = 254.0f; - const ImageID confirmBtnImage = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? ImageID("I_CROSS") : ImageID("I_CIRCLE"); - const int confirmBtn = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? CTRL_CROSS : CTRL_CIRCLE; - - PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, 0.5f); - PPGeStyle buttonStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f); - + + // It seems JPCSP doesn't check for NETCONF_STATUS_APNET if (request.netAction == NETCONF_CONNECT_APNET || request.netAction == NETCONF_STATUS_APNET || request.netAction == NETCONF_CONNECT_APNET_LAST) { + int state = NetApctl_GetState(); + UpdateFade(animSpeed); StartDraw(); - DrawBanner(); - PPGeDrawRect(0, 0, 480, 272, CalcFadedColor(0x63636363)); - PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, 0, textStyle); - PPGeDrawImage(confirmBtnImage, 195, 250, 20, 20, buttonStyle); - PPGeDrawText(di->T("OK"), 225, 252, buttonStyle); - if (IsButtonPressed(confirmBtn)) { + if (!hideNotice) { + const float WRAP_WIDTH = 254.0f; + const ImageID confirmBtnImage = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? ImageID("I_CROSS") : ImageID("I_CIRCLE"); + const int confirmBtn = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? CTRL_CROSS : CTRL_CIRCLE; + const ImageID cancelBtnImage = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? ImageID("I_CIRCLE") : ImageID("I_CROSS"); + const int cancelBtn = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? CTRL_CIRCLE : CTRL_CROSS; + + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, 0.5f); + PPGeStyle buttonStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f); + + PPGeDrawRect(0, 0, 480, 272, CalcFadedColor(0x63636363)); + DrawBanner(); + PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates.\nContinuing may cause unexpected behavior or freezes."), 241, 132, WRAP_WIDTH, 0, textStyle); + PPGeDrawImage(confirmBtnImage, 185, 240, 20, 20, buttonStyle); + PPGeDrawText(di->T("OK"), 215, 243, buttonStyle); + PPGeDrawImage(cancelBtnImage, 255, 240, 20, 20, buttonStyle); + PPGeDrawText(di->T("Cancel"), 285, 243, buttonStyle); + + // Since we don't support Infrastructure API yet.. Let the Player read the message first and choose to continue or not (ie. for testing networks API) + if (IsButtonPressed(cancelBtn)) { + StartFade(false); + ChangeStatus(SCE_UTILITY_STATUS_FINISHED, NET_SHUTDOWN_DELAY_US); + // TODO: When the dialog is aborted, does it really set the result to this? + // It seems to make Phantasy Star Portable 2 happy, so it should be okay for now. + request.common.result = SCE_UTILITY_DIALOG_RESULT_ABORT; + } + else if (IsButtonPressed(confirmBtn)) { + hideNotice = true; + StartFade(true); + } + } + else { + PPGeDrawRect(0, 0, 480, 272, CalcFadedColor(0xC0C8B2AC)); + DrawBanner(); + DrawIndicator(); + + if (state == PSP_NET_APCTL_STATE_GOT_IP || state == PSP_NET_APCTL_STATE_GETTING_IP) { + DisplayMessage(di->T("ObtainingIP", "Obtaining IP address.\nPlease wait..."), di->T("ConnectionName", "Connection Name"), netApctlInfo.name, di->T("SSID"), netApctlInfo.ssid); + } + else { + // Skipping the Select Connection screen since we only have 1 fake profile + DisplayMessage(di->T("ConnectingAP", "Connecting to the access point.\nPlease wait..."), di->T("ConnectionName", "Connection Name"), netApctlInfo.name, di->T("SSID"), netApctlInfo.ssid); + } + DisplayButtons(DS_BUTTON_CANCEL, di->T("Cancel")); + + // The Netconf dialog stays visible until the network reaches + // the state PSP_NET_APCTL_STATE_GOT_IP. + if (state == PSP_NET_APCTL_STATE_GOT_IP) { + if (pendingStatus != SCE_UTILITY_STATUS_FINISHED) { + ChangeStatus(SCE_UTILITY_STATUS_FINISHED, NET_RUNNING_DELAY_US); + } + else if (GetStatus() == SCE_UTILITY_STATUS_FINISHED) { + // We are done! + StartFade(false); + } + } + + else if (state == PSP_NET_APCTL_STATE_GETTING_IP) { + // Switch to the next message + StartFade(true); + } + + else if (state == PSP_NET_APCTL_STATE_DISCONNECTED) { + // When connecting with infrastructure, simulate a connection + // using the first network configuration entry. + connResult = sceNetApctlConnect(1); + } + } + + EndDraw(); + } + else if (request.netAction == NETCONF_CONNECT_ADHOC || request.netAction == NETCONF_CREATE_ADHOC || request.netAction == NETCONF_JOIN_ADHOC) { + int state = NetAdhocctl_GetState(); + + UpdateFade(animSpeed); + StartDraw(); + PPGeDrawRect(0, 0, 480, 272, CalcFadedColor(0xC0C8B2AC)); + DrawBanner(); + DrawIndicator(); + + std::string channel = std::to_string(g_Config.iWlanAdhocChannel); + if (g_Config.iWlanAdhocChannel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) + channel = "Automatic"; + + DisplayMessage(di->T("ConnectingChannel", "Connecting.\nPlease wait...\n\nChannel")+std::string(" ")+di->T(channel)); + + // Only Join mode is showing Cancel button on KHBBS and the button will fade out before the dialog is fading out, probably because it's already connected thus can't be canceled anymore + if (request.netAction == NETCONF_JOIN_ADHOC) + DisplayButtons(DS_BUTTON_CANCEL, di->T("Cancel")); + + if (state == ADHOCCTL_STATE_DISCONNECTED && request.NetconfData.IsValid()) { + connResult = sceNetAdhocctlCreate(request.NetconfData->groupName); + } + + // The Netconf dialog stays visible until the network reaches + // the state ADHOCCTL_STATE_CONNECTED. + if (state == ADHOCCTL_STATE_CONNECTED) { + // Checking pendingStatus to make sure ChangeStatus not to continously extending the delay ticks on every call for eternity + if (pendingStatus != SCE_UTILITY_STATUS_FINISHED) { + ChangeStatus(SCE_UTILITY_STATUS_FINISHED, NET_RUNNING_DELAY_US); + } + // Start fading only when the actual status has changed + else if (GetStatus() == SCE_UTILITY_STATUS_FINISHED) { + StartFade(false); + } + } + + if (request.netAction == NETCONF_JOIN_ADHOC && IsButtonPressed(cancelButtonFlag)) { StartFade(false); - ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); - // TODO: When the dialog is aborted, does it really set the result to this? - // It seems to make Phantasy Star Portable 2 happy, so it should be okay for now. + ChangeStatus(SCE_UTILITY_STATUS_FINISHED, NET_SHUTDOWN_DELAY_US); request.common.result = SCE_UTILITY_DIALOG_RESULT_ABORT; } EndDraw(); - } else if (request.netAction == NETCONF_CONNECT_ADHOC || request.netAction == NETCONF_CREATE_ADHOC || request.netAction == NETCONF_JOIN_ADHOC) { - if (request.NetconfData.IsValid()) { - Shutdown(true); - if (sceNetAdhocctlCreate(request.NetconfData->groupName) == 0) { - ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); - return 0; - } - return -1; - } } + if (GetStatus() == SCE_UTILITY_STATUS_FINISHED || pendingStatus == SCE_UTILITY_STATUS_FINISHED) + Memory::Memcpy(requestAddr, &request, request.common.size); + return 0; } @@ -146,3 +380,8 @@ void PSPNetconfDialog::DoState(PointerWrap &p) { Do(p, request); } + +pspUtilityDialogCommon* PSPNetconfDialog::GetCommonParam() +{ + return &request.common; +} diff --git a/Core/Dialog/PSPNetconfDialog.h b/Core/Dialog/PSPNetconfDialog.h index c3f891efd2..ea10471cc7 100644 --- a/Core/Dialog/PSPNetconfDialog.h +++ b/Core/Dialog/PSPNetconfDialog.h @@ -18,7 +18,7 @@ #pragma once #include "Core/Dialog/PSPDialog.h" -#include "Core/MemMap.h" +#include "Core/MemMapHelpers.h" struct SceUtilityNetconfData { char groupName[8]; @@ -27,11 +27,11 @@ struct SceUtilityNetconfData { struct SceUtilityNetconfParam { pspUtilityDialogCommon common; - int netAction; + int netAction; // sets how to connect PSPPointer NetconfData; - int netHotspot; - int netHotspotConnected; - int netWifiSpot; + int netHotspot; // Flag to allow hotspot connections + int netHotspotConnected; // Flag to check if a hotspot connection is active + int netWifiSpot; // Flag to allow WIFI connections }; class PSPNetconfDialog: public PSPDialog { @@ -43,6 +43,7 @@ public: virtual int Update(int animSpeed) override; virtual int Shutdown(bool force = false) override; virtual void DoState(PointerWrap &p) override; + virtual pspUtilityDialogCommon* GetCommonParam() override; protected: bool UseAutoStatus() override { @@ -50,6 +51,17 @@ protected: } private: + void DisplayMessage(std::string text1, std::string text2a = "", std::string text2b = "", std::string text3a = "", std::string text3b = "", bool hasYesNo = false, bool hasOK = false); void DrawBanner(); - SceUtilityNetconfParam request; + void DrawIndicator(); + + SceUtilityNetconfParam request = {}; + u32 requestAddr = 0; + int connResult = 0; + bool hideNotice = false; + + int yesnoChoice = 0; + float scrollPos_ = 0.0f; + int framesUpHeld_ = 0; + int framesDownHeld_ = 0; }; diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index e0119ead88..1b3f900aeb 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -61,7 +61,7 @@ static struct SceNetMallocStat netMallocStat; static std::map apctlHandlers; -static struct SceNetApctlInfoInternal netApctlInfo; +SceNetApctlInfoInternal netApctlInfo; bool netApctlInited; u32 netApctlState; @@ -407,7 +407,7 @@ void __NetApctlCallbacks() apctlEvents.pop_front(); // Adjust delay according to current event. Added an extra delay to prevent I/O Timing method from causing disconnection - if (*event == PSP_NET_APCTL_EVENT_CONNECT_REQUEST) // || *event == PSP_NET_APCTL_EVENT_SCAN_REQUEST) + if (*event == PSP_NET_APCTL_EVENT_CONNECT_REQUEST || *event == PSP_NET_APCTL_EVENT_GET_IP || *event == PSP_NET_APCTL_EVENT_SCAN_REQUEST) delayus = (adhocEventDelayMS + 2 * adhocExtraPollDelayMS) * 1000; else delayus = (adhocEventPollDelayMS + 2 * adhocExtraPollDelayMS) * 1000; @@ -794,6 +794,11 @@ static int sceNetApctlInit(int stackSize, int initPriority) { // Set default value before connected to an AP memset(&netApctlInfo, 0, sizeof(netApctlInfo)); // NetApctl_InitInfo(); + std::string APname = "Wifi"; // fake AP/hotspot + truncate_cpy(netApctlInfo.name, sizeof(netApctlInfo.name), APname.c_str()); + truncate_cpy(netApctlInfo.ssid, sizeof(netApctlInfo.ssid), APname.c_str()); + memcpy(netApctlInfo.bssid, "\1\1\2\2\3\3", sizeof(netApctlInfo.bssid)); // fake AP's mac address + netApctlInfo.ssidLength = static_cast(APname.length()); truncate_cpy(netApctlInfo.ip, sizeof(netApctlInfo.ip), "0.0.0.0"); truncate_cpy(netApctlInfo.gateway, sizeof(netApctlInfo.gateway), "0.0.0.0"); truncate_cpy(netApctlInfo.primaryDns, sizeof(netApctlInfo.primaryDns), "0.0.0.0"); @@ -1078,9 +1083,10 @@ static int sceNetInetConnect(int socket, u32 sockAddrInternetPtr, int addressLen } int sceNetApctlConnect(int connIndex) { - ERROR_LOG(SCENET, "UNIMPL %s(%i)", __FUNCTION__, connIndex); + WARN_LOG(SCENET, "UNTESTED %s(%i)", __FUNCTION__, connIndex); // Is this connIndex is the index to the scanning's result data or sceNetApctlGetBSSDescIDListUser result? __UpdateApctlHandlers(0, 0, PSP_NET_APCTL_EVENT_CONNECT_REQUEST, 0); + //hleDelayResult(0, "give time to init/cleanup", adhocEventDelayMS * 1000); return 0; } diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index 12e9c4413a..a4a2f52788 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -219,6 +219,7 @@ private: extern bool netInetInited; extern bool netApctlInited; +extern SceNetApctlInfoInternal netApctlInfo; template std::string num2hex(I w, size_t hex_len = sizeof(I) << 1); std::string error2str(u32 errorcode); From 60d249a9090b4942c371c9c1557684f21b096336 Mon Sep 17 00:00:00 2001 From: sorgts Date: Wed, 12 Aug 2020 20:15:32 +0200 Subject: [PATCH 491/848] Fix Windows/CMake build with Visual Studio --- CMakeLists.txt | 25 +++++++++++++++---------- Windows/InputDevice.cpp | 1 + Windows/WASAPIStream.cpp | 1 + 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0137d06d5a..76e754e72d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -915,6 +915,7 @@ if(WIN32) set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS} ext/native/thin3d/thin3d_d3d9.cpp ext/native/thin3d/thin3d_d3d11.cpp + ext/native/thin3d/d3d9_d3dcompiler_loader.cpp ext/native/thin3d/d3dx9_loader.cpp ext/native/thin3d/d3dx9_loader.h ext/native/thin3d/d3d11_loader.cpp @@ -1848,8 +1849,6 @@ if(USE_MINIUPNPC) if (NOT WIN32) add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT) add_definitions (-D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L) - else() - add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends endif() if (MACOSX) add_definitions (-D_DARWIN_C_SOURCE) @@ -1897,25 +1896,31 @@ if(USE_MINIUPNPC) # find_library (RESOLV_LIBRARY NAMES resolv) # set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS}) endif() - if (MSVC) - # Suppress noise warnings - target_compile_definitions(miniupnpc _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS) - endif() if (UPNPC_BUILD_STATIC) add_library(miniupnpc STATIC ${MINIUPNPC_SOURCES}) target_link_libraries(${CoreLibName} miniupnpc ${LDLIBS}) set(UPNPC_LIBRARY miniupnpc) + if (MSVC) + # Suppress noise warnings + target_compile_definitions(miniupnpc PRIVATE _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS) + endif() endif() endif() setup_target_project(${CoreLibName} Core) -# Generate git-version.cpp at build time. -add_custom_target(GitVersion ALL - DEPENDS something_that_never_exists) +# Generate git-version at build time. +add_custom_target(GitVersion DEPENDS something_that_never_exists) + +set(WIN_VERSION_CMD "") +if (WIN32) + set(WIN_VERSION_CMD COMMAND ${CMAKE_SOURCE_DIR}/Windows/git-version-gen.cmd PPSSPPWindows) +endif() + add_custom_command(OUTPUT something_that_never_exists COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} - -P ${CMAKE_CURRENT_SOURCE_DIR}/git-version.cmake) + -P ${CMAKE_CURRENT_SOURCE_DIR}/git-version.cmake + ${WIN_VERSION_CMD}) set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/git-version.cpp PROPERTIES GENERATED TRUE diff --git a/Windows/InputDevice.cpp b/Windows/InputDevice.cpp index 3c59c8323e..d800c87713 100644 --- a/Windows/InputDevice.cpp +++ b/Windows/InputDevice.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "stdafx.h" #include #include diff --git a/Windows/WASAPIStream.cpp b/Windows/WASAPIStream.cpp index d399781c46..9662bf2891 100644 --- a/Windows/WASAPIStream.cpp +++ b/Windows/WASAPIStream.cpp @@ -1,3 +1,4 @@ +#include "stdafx.h" #include "WindowsAudio.h" #include "WASAPIStream.h" #include "Common/Log.h" From 0ae12da3a7c58de41324ad19532e3bc3217d0c85 Mon Sep 17 00:00:00 2001 From: sorgts Date: Thu, 13 Aug 2020 16:48:19 +0200 Subject: [PATCH 492/848] Fix SSE detection with clang-cl clang-cl advertises its SSE support through the macros and expects the program to adhere to them, so check if any macro definition is available before falling back to the latest level as a default --- Common/Common.h | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/Common/Common.h b/Common/Common.h index 9fffa42922..9894771c53 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -70,18 +70,16 @@ #define __forceinline inline __attribute__((always_inline)) #endif -#if !defined(__GNUC__) && (defined(_M_X64) || defined(_M_IX86)) +#if defined __SSE4_2__ +# define _M_SSE 0x402 +#elif defined __SSE4_1__ +# define _M_SSE 0x401 +#elif defined __SSSE3__ +# define _M_SSE 0x301 +#elif defined __SSE3__ +# define _M_SSE 0x300 +#elif defined __SSE2__ +# define _M_SSE 0x200 +#elif !defined(__GNUC__) && (defined(_M_X64) || defined(_M_IX86)) # define _M_SSE 0x402 -#else -# if defined __SSE4_2__ -# define _M_SSE 0x402 -# elif defined __SSE4_1__ -# define _M_SSE 0x401 -# elif defined __SSSE3__ -# define _M_SSE 0x301 -# elif defined __SSE3__ -# define _M_SSE 0x300 -# elif defined __SSE2__ -# define _M_SSE 0x200 -# endif #endif From a8a1c67df0451a7cc8ec98610e3ea30abd1eb23f Mon Sep 17 00:00:00 2001 From: sorgts Date: Thu, 13 Aug 2020 16:48:48 +0200 Subject: [PATCH 493/848] Fix build with clang-cl --- CMakeLists.txt | 4 +++- Core/HLE/sceKernel.h | 2 +- Core/HLE/sceKernelModule.cpp | 2 +- Windows/InputDevice.cpp | 2 +- Windows/aboutbox.rc | Bin 2418 -> 1179 bytes Windows/version.rc | Bin 2486 -> 1214 bytes 6 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76e754e72d..6e51ca995e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,7 +311,9 @@ if(NOT MSVC) else() # Disable warnings about MS-specific _s variants of libc functions add_definitions(-D_CRT_SECURE_NO_WARNINGS) - add_definitions(-MP) + if (NOT CLANG) + add_compile_options(-MP) + endif() set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D_NDEBUG") endif() diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 9e2a8ff3ac..c9d4e20d4c 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -25,7 +25,7 @@ class PointerWrap; -enum { +enum : u32 { SCE_KERNEL_ERROR_OK = 0, SCE_KERNEL_ERROR_ALREADY = 0x80000020, SCE_KERNEL_ERROR_BUSY = 0x80000021, diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index c049729246..3d096e8a43 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -72,7 +72,7 @@ enum { PSP_THREAD_ATTR_USER = 0x80000000, }; -enum { +enum : u32 { // Function exports. NID_MODULE_START = 0xD632ACDB, NID_MODULE_STOP = 0xCEE8593C, diff --git a/Windows/InputDevice.cpp b/Windows/InputDevice.cpp index d800c87713..70d4a6ff48 100644 --- a/Windows/InputDevice.cpp +++ b/Windows/InputDevice.cpp @@ -27,7 +27,7 @@ static std::atomic_flag threadRunningFlag; static std::thread inputThread; -static std::atomic_bool focused = true; +static std::atomic_bool focused = ATOMIC_VAR_INIT(true); inline static void ExecuteInputPoll() { if (host && (focused.load(std::memory_order_relaxed) || !g_Config.bGamepadOnlyFocused)) { diff --git a/Windows/aboutbox.rc b/Windows/aboutbox.rc index 1e669a134b7b8236aa39c98cced9566a0eafad2e..43e3b7200515c8b1dc71e5bd7e9879a29d2fd615 100644 GIT binary patch literal 1179 zcmaJ=+is&U5Pe7DA4c>gk=ztW)291I0%>WJfMU{3rIjKA4q;2MWuV=x_ILJ6_Q!UB z?4_+*3t^8vbI!~eTUE}^f?Zm`Hq98|oaRwh#Vp1J2vHP5^kf9jX}JUKc&7DKq6ZW9He`bh5B!PHRuxm1ENfiq>bk_C0^;x66B%x+4T=_Q#eVxZb=q(0k_0 zm#Xq-SF<*}Dm7JUXodu|83npySq65NXiZ*qcHeYW89CSPTvY&v?M(b7y%{Zo0HFai z?@lAG?cEXcyibgCoeXrGT4#6M_|$RDaBX+(`;_`VhK$!VumX2X44qsN(;y}?)o#Ff42+J676y%p3- zG%I_r)13dAS%3e$wpaF!ab#buVkU z{@VE){8PRjJXh>SHnstyZ$tJ$M%`|>X`|uF7Fd;?GU)5LzAjwT8YN@I(7b@G27K2p zK{_+6WM|5kfkwXRD_fCqW*fF?hi-J`!v!cr{S(SO;x$f>uXg}esh>TOd!26linN{GeU~6US z^caqqZ!@t#vI2bp`4#k+-Hu5~LAG=sAW!kQPn&_a4nAX0$T-EFH|y?y2HRy{48AR5 z++|(l--cfCnT*<^{a`OWo9Nueq66PW&}kGoExB*8?LebUI!dh8eTMa}%N1@~XDx5b z#6JrT%dTt1|Jq4UD!GhjLLuGXpCzyCv8~`qj13iJ>a^fE9uWscu;7~H(|f+W=RiL3 zDV4bgr7}i{KQ=NhJ=LNprFxFxtD-$1l}$WSoO9?}bFGtJ&DK-^y8#t7qz2j`q^f&M zEzB{8O4|Xop5I?^R)w|+aa&|mW|aLGKh3-3=_$<|=qfVKLH`bnSOmHN`*G;&IHjNn1XzB^~1 zzR`2O5nbX7Yjr=#Y}qAM&_&x7(j+16iD9SiH6|Lm??BOGrCO-5QY6)}q@&B-09lH< z&=|lqdpT|I`p$|V)~ zvb-u#b1@wv;G{S0l1M6>^sWRvBhU?RU0OSOD-PjPy;q;KP&K@kWPY&sxtSj#7SoY- zu`<-|8*Ee#hul(SpS#V}cY}bZs|0+Tna; TAD)c0v@SoAqk4ObUOoQ+k-AYt diff --git a/Windows/version.rc b/Windows/version.rc index dbefa2cef81bddf6eee3566d166fad2fdea2a9c0..1c6d3982b19d71cfa8fbbfaafc438cafe9b154ad 100644 GIT binary patch literal 1214 zcmb7D+is&U5Pgr7e;BbZt<+Gb%665ECucT}^ply!VQtWH~o?nl?d>f=b2ve1wF__iRrk%rJ{IWkV0f zRkfihH^FveF9XMOw~jmYpxNkkw*ymWZZ{F|{UGrD?GML2Rao9)F;Xyp=}p$w>Jvy! zIGvAX!D19V0eS0xn`?b>gfVO<_IN#OPOU&1p!1lP_*a}%aUQX_NqB)m4^*@gz540f zYOhh%K3I=0LSuX8xGJN*@!YeXzzC#ZJejIiIXuplGga;kyMU4b8Ir*>X+SMN9omfM zYa0wJ&obn)H15Et4Fo^%0keHdWiBo_u8RuFk1own*L_DW*b6L=QS$qjh}vtk^a+-s zV1-n(aX#H+@LT`R_wpb=(Nyj0$f(i94jNBd9$SH6`%1%ff2 z78pwQijW`F(<#k%*`AWi)Gf8Kn(^$YiEr3mdiCFV*1H1EQV_8Qwu(HQ<7_;{F3hW=He@ literal 2486 zcmcJR-HsAL5QXd7#CMpCH<}2thG@LxUm`9WK#W&pmp_Rx5MbT)fqf12t7@8NfF)tG zX2ML*bk(WTRi~@@`{%hllQ&$EbmY5CWW{L2b1Fkd?tLhU^kpssz76ba!u<;#RmsSO zypz|w-;w0dzEptH{-wS`XVgq(!ewA9my3}n@gWP`D$o~ zF-qWn<|-H$^=k2@OpQxa`Drjc!zw%rQiGGmYs)9t=j0w8y=O*Oqxl9!>Z;+x*5hWV$2Y$WvuA@3F#s8^%Sl zcg(7YU(IUa;zgiDSU1Re$ubfXd5ua{v16+1c4VEm5vp~XabD_o3@yy=qUIz|wmhc(%ctt-T)Jg-1imTED=YR3MaitaP*3&(k! zinPEtp^IGd)Tln*M`NIw`$3!*76UT)n;3($qWGMb!CSGv6>$Mu*EM{!-TigW8a#Rz z^w5hO>MrKPd$x_XTBaetFMPJr&vcbkLE3|tJg>?Be)e`_SFA?otf~R>*l<-13v#bn z8`ELe+xi^NMDh~#yrNofQDlzuBx9osbQ+;jJt>~5s)1n#Zr9djW;~auC1|!lW~M}4 z@LkWnTk5YTndVHjrl+L(=ozWIbRQ?eOMBOvl@H0llCfIr*)=q*iJd}fcL%D|K=v$s zHbK+XWRAUf!GoZeJXJN%!5ZRn}+o jF&#I( Date: Thu, 13 Aug 2020 16:12:27 -0400 Subject: [PATCH 494/848] Fix menu navigation from axis in linux Up is down and down is up - mimic the change in android for linux to compensate and correct. Tested and working. --- ext/native/ui/root.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index b71641895e..460945204c 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -335,10 +335,10 @@ bool AxisEvent(const AxisInput &axis, ViewGroup *root) { old.x = dir; } if (axis.axisId == JOYSTICK_AXIS_Y || axis.axisId == JOYSTICK_AXIS_HAT_Y) { - // We stupidly interpret the joystick Y axis backwards on Android instead of reversing + // We stupidly interpret the joystick Y axis backwards on Android and Linux instead of reversing // it early (see keymaps...). Too late to fix without invalidating a lot of config files, so we // reverse it here too. -#if PPSSPP_PLATFORM(ANDROID) +#if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(LINUX) GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_UP, NKCODE_DPAD_DOWN); #else GenerateKeyFromAxis(old.y, dir, NKCODE_DPAD_DOWN, NKCODE_DPAD_UP); From 0fcc0994b4c3b650e3212d16895a27a2cf04ccb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 11:51:22 +0200 Subject: [PATCH 495/848] Recategorize some logging, in preparation for what's to come. --- Common/Log.h | 4 +++- Common/LogManager.cpp | 8 ++++---- Core/HLE/sceKernelModule.cpp | 2 +- Core/Screenshot.cpp | 20 +++++++------------- Core/TextureReplacer.cpp | 6 +----- Core/WaveFile.cpp | 6 ++---- GPU/Common/FramebufferManagerCommon.cpp | 3 ++- ext/native/file/chunk_file.cpp | 4 ++-- ext/native/thin3d/thin3d_gl.cpp | 16 ++++++++-------- 9 files changed, 30 insertions(+), 39 deletions(-) diff --git a/Common/Log.h b/Common/Log.h index 1b1ab1ed07..481795bde2 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -38,7 +38,7 @@ namespace LogTypes { enum LOG_TYPE { - SYSTEM = 0, + SYSTEM = 0, // Catch-all for uncategorized things BOOT, COMMON, CPU, @@ -52,6 +52,8 @@ enum LOG_TYPE { SASMIX, SAVESTATE, FRAMEBUF, + AUDIO, + IO, SCEAUDIO, SCECTRL, diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index c13a3d712f..f16971c70c 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -93,7 +93,9 @@ static const LogNameTableEntry logTable[] = { {LogTypes::MEMMAP, "MEMMAP"}, {LogTypes::SASMIX, "SASMIX"}, {LogTypes::SAVESTATE, "SAVESTATE"}, - {LogTypes::FRAMEBUF, "FRAMEBUF"}, + {LogTypes::FRAMEBUF, "FRAMEBUF"}, + {LogTypes::AUDIO, "AUDIO"}, + {LogTypes::IO, "IO"}, {LogTypes::SCEAUDIO, "SCEAUDIO"}, {LogTypes::SCECTRL, "SCECTRL"}, @@ -113,9 +115,7 @@ static const LogNameTableEntry logTable[] = { LogManager::LogManager() { for (size_t i = 0; i < ARRAY_SIZE(logTable); i++) { - if (i != logTable[i].logType) { - FLOG("Bad logtable at %i", (int)i); - } + _assert_msg_(i == logTable[i].logType, "Bad logtable at %i", (int)i); truncate_cpy(log_[logTable[i].logType].m_shortName, logTable[i].name); log_[logTable[i].logType].enabled = true; #if defined(_DEBUG) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index c049729246..987b626d6b 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1799,7 +1799,7 @@ void __KernelGPUReplay() { // Special ABI: s0 and s1 are the "args". Not null terminated. const char *filenamep = Memory::GetCharPointer(currentMIPS->r[MIPS_REG_S1]); if (!filenamep) { - ERROR_LOG(SYSTEM, "Failed to load dump filename"); + ERROR_LOG(G3D, "Failed to load dump filename"); Core_Stop(); return; } diff --git a/Core/Screenshot.cpp b/Core/Screenshot.cpp index fb1ef83944..74c10ca2fe 100644 --- a/Core/Screenshot.cpp +++ b/Core/Screenshot.cpp @@ -71,13 +71,12 @@ private: static bool WriteScreenshotToJPEG(const char *filename, int width, int height, int num_channels, const uint8_t *image_data, const jpge::params &comp_params) { JPEGFileStream dst_stream(filename); if (!dst_stream.Valid()) { - ERROR_LOG(SYSTEM, "Unable to open screenshot file for writing."); + ERROR_LOG(IO, "Unable to open screenshot file for writing."); return false; } jpge::jpeg_encoder dst_image; if (!dst_image.init(&dst_stream, width, height, num_channels, comp_params)) { - ERROR_LOG(SYSTEM, "Screenshot JPEG encode init failed."); return false; } @@ -85,12 +84,10 @@ static bool WriteScreenshotToJPEG(const char *filename, int width, int height, i for (int i = 0; i < height; i++) { const uint8_t *buf = image_data + i * width * num_channels; if (!dst_image.process_scanline(buf)) { - ERROR_LOG(SYSTEM, "Screenshot JPEG encode scanline failed."); return false; } } if (!dst_image.process_scanline(NULL)) { - ERROR_LOG(SYSTEM, "Screenshot JPEG encode scanline flush failed."); return false; } } @@ -106,18 +103,15 @@ static bool WriteScreenshotToJPEG(const char *filename, int width, int height, i static bool WriteScreenshotToPNG(png_imagep image, const char *filename, int convert_to_8bit, const void *buffer, png_int_32 row_stride, const void *colormap) { FILE *fp = File::OpenCFile(filename, "wb"); if (!fp) { - ERROR_LOG(SYSTEM, "Unable to open screenshot file for writing."); + ERROR_LOG(IO, "Unable to open screenshot file for writing."); return false; } if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, row_stride, colormap)) { - if (fclose(fp) != 0) { - ERROR_LOG(SYSTEM, "Screenshot file write failed."); - return false; - } + fclose(fp); return true; } else { - ERROR_LOG(SYSTEM, "Screenshot PNG encode failed."); + ERROR_LOG(IO, "Screenshot PNG encode failed."); fclose(fp); remove(filename); return false; @@ -347,7 +341,7 @@ bool TakeGameScreenshot(const char *filename, ScreenshotFormat fmt, ScreenshotTy delete [] flipbuffer; if (!success) { - ERROR_LOG(SYSTEM, "Failed to write screenshot."); + ERROR_LOG(IO, "Failed to write screenshot."); } return success; } @@ -368,7 +362,7 @@ bool Save888RGBScreenshot(const char *filename, ScreenshotFormat fmt, const u8 * png_image_free(&png); if (png.warning_or_error >= 2) { - ERROR_LOG(SYSTEM, "Saving screenshot to PNG produced errors."); + ERROR_LOG(IO, "Saving screenshot to PNG produced errors."); success = false; } return success; @@ -397,7 +391,7 @@ bool Save8888RGBAScreenshot(const char *filename, const u8 *buffer, int w, int h png_image_free(&png); if (png.warning_or_error >= 2) { - ERROR_LOG(SYSTEM, "Saving screenshot to PNG produced errors."); + ERROR_LOG(IO, "Saving screenshot to PNG produced errors."); success = false; } return success; diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index f403deba44..ad1de50dd4 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -380,15 +380,11 @@ void TextureReplacer::PopulateReplacement(ReplacedTexture *result, u64 cachekey, static bool WriteTextureToPNG(png_imagep image, const std::string &filename, int convert_to_8bit, const void *buffer, png_int_32 row_stride, const void *colormap) { FILE *fp = File::OpenCFile(filename, "wb"); if (!fp) { - ERROR_LOG(SYSTEM, "Unable to open texture file for writing."); + ERROR_LOG(IO, "Unable to open texture file for writing."); return false; } if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, row_stride, colormap)) { - if (fclose(fp) != 0) { - ERROR_LOG(SYSTEM, "Texture file write failed."); - return false; - } return true; } else { ERROR_LOG(SYSTEM, "Texture PNG encode failed."); diff --git a/Core/WaveFile.cpp b/Core/WaveFile.cpp index 038c66e80f..b1c56b002c 100644 --- a/Core/WaveFile.cpp +++ b/Core/WaveFile.cpp @@ -11,9 +11,7 @@ constexpr size_t WaveFileWriter::BUFFER_SIZE; -WaveFileWriter::WaveFileWriter() -{ -} +WaveFileWriter::WaveFileWriter() {} WaveFileWriter::~WaveFileWriter() { @@ -30,7 +28,7 @@ bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRa file.Open(filename, "wb"); if (!file) { - ERROR_LOG(SYSTEM, "The file %s could not be opened for writing. Please check if it's already opened by another program.", filename.c_str()); + ERROR_LOG(IO, "The file %s could not be opened for writing. Please check if it's already opened by another program.", filename.c_str()); return false; } diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 8e291942db..864cf678e6 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -887,7 +887,8 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { if (vfb) { // Okay, we found one above. - INFO_LOG_REPORT_ONCE(displayoffset, HLE, "Rendering from framebuf with offset %08x -> %08x+%dx%d", addr, vfb->fb_address, offsetX, offsetY); + // Log should be "Displaying from framebuf" but not worth changing the report. + INFO_LOG_REPORT_ONCE(displayoffset, FRAMEBUF, "Rendering from framebuf with offset %08x -> %08x+%dx%d", addr, vfb->fb_address, offsetX, offsetY); } } diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index 4cd4e5157c..0804040038 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -49,7 +49,7 @@ bool RIFFReader::Descend(uint32_t intoId) { int startLocation = pos_; if (pos_ + length > fileSize_) { - ERROR_LOG(SYSTEM, "Block extends outside of RIFF file - failing descend"); + ERROR_LOG(IO, "Block extends outside of RIFF file - failing descend"); pos_ = stack[depth_].parentStartLocation; return false; } @@ -64,7 +64,7 @@ bool RIFFReader::Descend(uint32_t intoId) { if (length > 0) { pos_ += length; // try next block } else { - ERROR_LOG(SYSTEM, "Bad data in RIFF file : block length %d. Not descending.", length); + ERROR_LOG(IO, "Bad data in RIFF file : block length %d. Not descending.", length); pos_ = stack[depth_].parentStartLocation; return false; } diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 61ce579814..b77a8fd4fd 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -791,30 +791,30 @@ static void LogReadPixelsError(GLenum error) { case GL_NO_ERROR: break; case GL_INVALID_ENUM: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_ENUM"); + ERROR_LOG(G3D, "glReadPixels: GL_INVALID_ENUM"); break; case GL_INVALID_VALUE: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_VALUE"); + ERROR_LOG(G3D, "glReadPixels: GL_INVALID_VALUE"); break; case GL_INVALID_OPERATION: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_OPERATION"); + ERROR_LOG(G3D, "glReadPixels: GL_INVALID_OPERATION"); break; case GL_INVALID_FRAMEBUFFER_OPERATION: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_INVALID_FRAMEBUFFER_OPERATION"); + ERROR_LOG(G3D, "glReadPixels: GL_INVALID_FRAMEBUFFER_OPERATION"); break; case GL_OUT_OF_MEMORY: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_OUT_OF_MEMORY"); + ERROR_LOG(G3D, "glReadPixels: GL_OUT_OF_MEMORY"); break; #ifndef USING_GLES2 case GL_STACK_UNDERFLOW: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_STACK_UNDERFLOW"); + ERROR_LOG(G3D, "glReadPixels: GL_STACK_UNDERFLOW"); break; case GL_STACK_OVERFLOW: - ERROR_LOG(FRAMEBUF, "glReadPixels: GL_STACK_OVERFLOW"); + ERROR_LOG(G3D, "glReadPixels: GL_STACK_OVERFLOW"); break; #endif default: - ERROR_LOG(FRAMEBUF, "glReadPixels: %08x", error); + ERROR_LOG(G3D, "glReadPixels: %08x", error); break; } } From 5117ded378b1ba0362eb1bfb6816447b723a1cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 12:03:39 +0200 Subject: [PATCH 496/848] Remove ELOG/ILOG/WLOG from the Android C++ code (mostly) --- Core/Debugger/WebSocket/WebSocketUtils.h | 2 + Core/Font/PGF.h | 1 - GPU/Common/TransformCommon.h | 2 +- GPU/Common/VertexDecoderCommon.h | 1 + android/jni/AndroidAudio.cpp | 21 ++-- android/jni/AndroidEGLContext.cpp | 13 ++- android/jni/AndroidJavaGLContext.cpp | 4 +- android/jni/AndroidVulkanContext.cpp | 37 +++--- android/jni/Arm64EmitterTest.cpp | 1 - android/jni/app-android.cpp | 143 +++++++++++------------ ext/native/thin3d/GLRenderManager.cpp | 18 +++ ext/native/thin3d/GLRenderManager.h | 55 +++------ 12 files changed, 151 insertions(+), 147 deletions(-) diff --git a/Core/Debugger/WebSocket/WebSocketUtils.h b/Core/Debugger/WebSocket/WebSocketUtils.h index ac75838583..93110db6a0 100644 --- a/Core/Debugger/WebSocket/WebSocketUtils.h +++ b/Core/Debugger/WebSocket/WebSocketUtils.h @@ -19,9 +19,11 @@ #include #include + #include "json/json_reader.h" #include "json/json_writer.h" #include "net/websocket_server.h" + #include "Common/Log.h" #include "ppsspp_config.h" diff --git a/Core/Font/PGF.h b/Core/Font/PGF.h index 7b721726d4..a4e3f420d8 100644 --- a/Core/Font/PGF.h +++ b/Core/Font/PGF.h @@ -22,7 +22,6 @@ #include #include -#include "Common/Log.h" #include "Common/CommonTypes.h" class PointerWrap; diff --git a/GPU/Common/TransformCommon.h b/GPU/Common/TransformCommon.h index 0c528133c5..d3b78dd663 100644 --- a/GPU/Common/TransformCommon.h +++ b/GPU/Common/TransformCommon.h @@ -18,8 +18,8 @@ #pragma once #include + #include "base/basictypes.h" -#include "Common/Log.h" #include "Common/CommonTypes.h" #include "Core/Reporting.h" #include "GPU/ge_constants.h" diff --git a/GPU/Common/VertexDecoderCommon.h b/GPU/Common/VertexDecoderCommon.h index 209186fd96..333f2b1c36 100644 --- a/GPU/Common/VertexDecoderCommon.h +++ b/GPU/Common/VertexDecoderCommon.h @@ -18,6 +18,7 @@ #pragma once #include + #include "ppsspp_config.h" #include "base/basictypes.h" #include "Common/Hashmaps.h" diff --git a/android/jni/AndroidAudio.cpp b/android/jni/AndroidAudio.cpp index 98cf3a87be..56145b516e 100644 --- a/android/jni/AndroidAudio.cpp +++ b/android/jni/AndroidAudio.cpp @@ -1,4 +1,5 @@ -#include "base/logging.h" +#include "Common/Log.h" + #include "android/jni/AndroidAudio.h" #include "android/jni/OpenSLContext.h" @@ -31,13 +32,13 @@ AndroidAudioState *AndroidAudio_Init(AndroidAudioCallback callback, int optimalF bool AndroidAudio_Resume(AndroidAudioState *state) { if (!state) { - ELOG("Audio was shutdown, cannot resume!"); + ERROR_LOG(AUDIO, "Audio was shutdown, cannot resume!"); return false; } if (!state->ctx) { - ILOG("Calling OpenSLWrap_Init_T..."); + INFO_LOG(AUDIO, "Calling OpenSLWrap_Init_T..."); state->ctx = new OpenSLContext(state->callback, state->frames_per_buffer, state->sample_rate); - ILOG("Returned from OpenSLWrap_Init_T"); + INFO_LOG(AUDIO, "Returned from OpenSLWrap_Init_T"); bool init_retval = state->ctx->Init(); if (!init_retval) { delete state->ctx; @@ -50,14 +51,14 @@ bool AndroidAudio_Resume(AndroidAudioState *state) { bool AndroidAudio_Pause(AndroidAudioState *state) { if (!state) { - ELOG("Audio was shutdown, cannot pause!"); + ERROR_LOG(AUDIO, "Audio was shutdown, cannot pause!"); return false; } if (state->ctx) { - ILOG("Calling OpenSLWrap_Shutdown_T..."); + INFO_LOG(AUDIO, "Calling OpenSLWrap_Shutdown_T..."); delete state->ctx; state->ctx = nullptr; - ILOG("Returned from OpenSLWrap_Shutdown_T ..."); + INFO_LOG(AUDIO, "Returned from OpenSLWrap_Shutdown_T ..."); return true; } return false; @@ -65,14 +66,14 @@ bool AndroidAudio_Pause(AndroidAudioState *state) { bool AndroidAudio_Shutdown(AndroidAudioState *state) { if (!state) { - ELOG("Audio already shutdown!"); + ERROR_LOG(AUDIO, "Audio already shutdown!"); return false; } if (state->ctx) { - ELOG("Should not shut down when playing! Something is wrong!"); + ERROR_LOG(AUDIO, "Should not shut down when playing! Something is wrong!"); return false; } delete state; - ILOG("OpenSLWrap completely unloaded."); + INFO_LOG(AUDIO, "OpenSLWrap completely unloaded."); return true; } diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index de58b828c1..97b4ecd55a 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -1,25 +1,26 @@ #include -#include "base/logging.h" + #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "thin3d/thin3d_create.h" +#include "Common/Log.h" #include "AndroidEGLContext.h" #include "GL/GLInterface/EGLAndroid.h" #include "Core/ConfigValues.h" #include "Core/System.h" bool AndroidEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { - ILOG("AndroidEGLGraphicsContext::Init()"); + INFO_LOG(G3D, "AndroidEGLGraphicsContext::Init()"); wnd_ = wnd; gl = HostGL_CreateGLInterface(); if (!gl) { - ELOG("ERROR: Failed to create GL interface"); + ERROR_LOG(G3D, "ERROR: Failed to create GL interface"); return false; } int backbufferWidth = desiredBackbufferSizeX; int backbufferHeight = desiredBackbufferSizeY; - ILOG("EGL interface created. Desired backbuffer size: %dx%d", backbufferWidth, backbufferHeight); + INFO_LOG(G3D, "EGL interface created. Desired backbuffer size: %dx%d", backbufferWidth, backbufferHeight); // Apparently we still have to set this through Java through setFixedSize on the bufferHolder for it to take effect... gl->SetBackBufferDimensions(backbufferWidth, backbufferHeight); @@ -39,7 +40,7 @@ bool AndroidEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int des } if (!gl->Create(wnd, false, use565)) { - ELOG("EGL creation failed! (use565=%d)", (int)use565); + ERROR_LOG(G3D, "EGL creation failed! (use565=%d)", (int)use565); // TODO: What do we do now? delete gl; return false; @@ -58,7 +59,7 @@ bool AndroidEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int des } void AndroidEGLGraphicsContext::ShutdownFromRenderThread() { - ILOG("AndroidEGLGraphicsContext::Shutdown"); + INFO_LOG(G3D, "AndroidEGLGraphicsContext::Shutdown"); renderManager_->WaitUntilQueueIdle(); renderManager_ = nullptr; // owned by draw_. delete draw_; diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index d1b8e17a6a..36a2259f43 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -13,7 +13,7 @@ AndroidJavaEGLGraphicsContext::AndroidJavaEGLGraphicsContext() { } bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { - ILOG("AndroidJavaEGLGraphicsContext::InitFromRenderThread"); + INFO_LOG(G3D, "AndroidJavaEGLGraphicsContext::InitFromRenderThread"); CheckGLExtensions(); // OpenGL handles rotated rendering in the driver. g_display_rotation = DisplayRotation::ROTATE_0; @@ -26,7 +26,7 @@ bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int } void AndroidJavaEGLGraphicsContext::ShutdownFromRenderThread() { - ILOG("AndroidJavaEGLGraphicsContext::Shutdown"); + INFO_LOG(G3D, "AndroidJavaEGLGraphicsContext::Shutdown"); renderManager_->WaitUntilQueueIdle(); renderManager_ = nullptr; // owned by draw_. delete draw_; diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 76fc4d3e3c..b61ad99b84 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -3,6 +3,7 @@ #include "AndroidVulkanContext.h" #include "base/NativeApp.h" #include "base/display.h" +#include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanDebug.h" #include "Common/Vulkan/VulkanLoader.h" @@ -28,18 +29,18 @@ static uint32_t FlagsFromConfig() { } bool AndroidVulkanContext::InitAPI() { - ILOG("AndroidVulkanContext::Init"); + INFO_LOG(G3D, "AndroidVulkanContext::Init"); init_glslang(); g_LogOptions.breakOnError = true; g_LogOptions.breakOnWarning = true; g_LogOptions.msgBoxOnError = false; - ILOG("Creating Vulkan context"); + INFO_LOG(G3D, "Creating Vulkan context"); Version gitVer(PPSSPP_GIT_VERSION); if (!VulkanLoad()) { - ELOG("Failed to load Vulkan driver library"); + ERROR_LOG(G3D, "Failed to load Vulkan driver library"); return false; } @@ -54,7 +55,7 @@ bool AndroidVulkanContext::InitAPI() { info.flags = FlagsFromConfig(); VkResult res = g_Vulkan->CreateInstance(info); if (res != VK_SUCCESS) { - ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str()); + ERROR_LOG(G3D, "Failed to create vulkan context: %s", g_Vulkan->InitError().c_str()); VulkanSetAvailable(false); delete g_Vulkan; g_Vulkan = nullptr; @@ -63,7 +64,7 @@ bool AndroidVulkanContext::InitAPI() { int physicalDevice = g_Vulkan->GetBestPhysicalDevice(); if (physicalDevice < 0) { - ELOG("No usable Vulkan device found."); + ERROR_LOG(G3D, "No usable Vulkan device found."); g_Vulkan->DestroyInstance(); delete g_Vulkan; g_Vulkan = nullptr; @@ -72,9 +73,9 @@ bool AndroidVulkanContext::InitAPI() { g_Vulkan->ChooseDevice(physicalDevice); - ILOG("Creating Vulkan device"); + INFO_LOG(G3D, "Creating Vulkan device"); if (g_Vulkan->CreateDevice() != VK_SUCCESS) { - ILOG("Failed to create vulkan device: %s", g_Vulkan->InitError().c_str()); + INFO_LOG(G3D, "Failed to create vulkan device: %s", g_Vulkan->InitError().c_str()); System_SendMessage("toast", "No Vulkan driver found. Using OpenGL instead."); g_Vulkan->DestroyInstance(); delete g_Vulkan; @@ -82,20 +83,20 @@ bool AndroidVulkanContext::InitAPI() { return false; } - ILOG("Vulkan device created!"); + INFO_LOG(G3D, "Vulkan device created!"); return true; } bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { - ILOG("AndroidVulkanContext::InitFromRenderThread: desiredwidth=%d desiredheight=%d", desiredBackbufferSizeX, desiredBackbufferSizeY); + INFO_LOG(G3D, "AndroidVulkanContext::InitFromRenderThread: desiredwidth=%d desiredheight=%d", desiredBackbufferSizeX, desiredBackbufferSizeY); if (!g_Vulkan) { - ELOG("AndroidVulkanContext::InitFromRenderThread: No Vulkan context"); + ERROR_LOG(G3D, "AndroidVulkanContext::InitFromRenderThread: No Vulkan context"); return false; } VkResult res = g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr); if (res != VK_SUCCESS) { - ELOG("g_Vulkan->InitSurface failed: '%s'", VulkanResultToString(res)); + ERROR_LOG(G3D, "g_Vulkan->InitSurface failed: '%s'", VulkanResultToString(res)); return false; } @@ -114,7 +115,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB success = false; } - ILOG("AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed"); + INFO_LOG(G3D, "AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed"); if (!success) { g_Vulkan->DestroySwapchain(); g_Vulkan->DestroySurface(); @@ -125,7 +126,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB } void AndroidVulkanContext::ShutdownFromRenderThread() { - ILOG("AndroidVulkanContext::Shutdown"); + INFO_LOG(G3D, "AndroidVulkanContext::Shutdown"); draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); delete draw_; draw_ = nullptr; @@ -133,23 +134,23 @@ void AndroidVulkanContext::ShutdownFromRenderThread() { g_Vulkan->PerformPendingDeletes(); g_Vulkan->DestroySwapchain(); g_Vulkan->DestroySurface(); - ILOG("Done with ShutdownFromRenderThread"); + INFO_LOG(G3D, "Done with ShutdownFromRenderThread"); } void AndroidVulkanContext::Shutdown() { - ILOG("Calling NativeShutdownGraphics"); + INFO_LOG(G3D, "Calling NativeShutdownGraphics"); g_Vulkan->DestroyDevice(); g_Vulkan->DestroyInstance(); // We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app. finalize_glslang(); - ILOG("AndroidVulkanContext::Shutdown completed"); + INFO_LOG(G3D, "AndroidVulkanContext::Shutdown completed"); } void AndroidVulkanContext::SwapBuffers() { } void AndroidVulkanContext::Resize() { - ILOG("AndroidVulkanContext::Resize begin (oldsize: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + INFO_LOG(G3D, "AndroidVulkanContext::Resize begin (oldsize: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); g_Vulkan->DestroySwapchain(); @@ -160,7 +161,7 @@ void AndroidVulkanContext::Resize() { g_Vulkan->ReinitSurface(); g_Vulkan->InitSwapchain(); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - ILOG("AndroidVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + INFO_LOG(G3D, "AndroidVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); } void AndroidVulkanContext::SwapInterval(int interval) { diff --git a/android/jni/Arm64EmitterTest.cpp b/android/jni/Arm64EmitterTest.cpp index b9240fc352..e14c98532d 100644 --- a/android/jni/Arm64EmitterTest.cpp +++ b/android/jni/Arm64EmitterTest.cpp @@ -1,5 +1,4 @@ #include "base/logging.h" -#include "Arm64EmitterTest.h" #include "Common/Arm64Emitter.h" #include "Common/BitSet.h" diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 0ac1036011..aad11b14f1 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -15,7 +15,6 @@ #ifndef _MSC_VER #include -#include #include #elif !defined(JNIEXPORT) // Just for better highlighting in MSVC if opening this file. @@ -52,7 +51,6 @@ struct JNIEnv {}; #include "base/stringutil.h" #include "base/display.h" #include "base/NativeApp.h" -#include "base/logging.h" #include "base/timeutil.h" #include "thread/threadutil.h" #include "file/zip_read.h" @@ -66,6 +64,7 @@ struct JNIEnv {}; #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" +#include "Common/Log.h" #include "Common/GraphicsContext.h" #include "AndroidGraphicsContext.h" #include "AndroidVulkanContext.h" @@ -191,7 +190,7 @@ jclass findClass(const char* name) { } JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *pjvm, void *reserved) { - ILOG("JNI_OnLoad"); + INFO_LOG(SYSTEM, "JNI_OnLoad"); gJvm = pjvm; // cache the JavaVM pointer auto env = getEnv(); //replace with one of your classes in the line below @@ -211,20 +210,20 @@ static void EmuThreadFunc() { gJvm->AttachCurrentThread(&env, nullptr); setCurrentThreadName("Emu"); - ILOG("Entering emu thread"); + INFO_LOG(SYSTEM, "Entering emu thread"); // Wait for render loop to get started. if (!graphicsContext || !graphicsContext->Initialized()) { - ILOG("Runloop: Waiting for displayInit..."); + INFO_LOG(SYSTEM, "Runloop: Waiting for displayInit..."); while (!graphicsContext || !graphicsContext->Initialized()) { sleep_ms(20); } } else { - ILOG("Runloop: Graphics context available! %p", graphicsContext); + INFO_LOG(SYSTEM, "Runloop: Graphics context available! %p", graphicsContext); } NativeInitGraphics(graphicsContext); - ILOG("Graphics initialized. Entering loop."); + INFO_LOG(SYSTEM, "Graphics initialized. Entering loop."); // There's no real requirement that NativeInit happen on this thread. // We just call the update/render loop here. @@ -232,7 +231,7 @@ static void EmuThreadFunc() { while (emuThreadState != (int)EmuThreadState::QUIT_REQUESTED) { UpdateRunLoopAndroid(env); } - ILOG("QUIT_REQUESTED found, left loop. Setting state to STOPPED."); + INFO_LOG(SYSTEM, "QUIT_REQUESTED found, left loop. Setting state to STOPPED."); emuThreadState = (int)EmuThreadState::STOPPED; NativeShutdownGraphics(); @@ -241,11 +240,11 @@ static void EmuThreadFunc() { graphicsContext->StopThread(); gJvm->DetachCurrentThread(); - ILOG("Leaving emu thread"); + INFO_LOG(SYSTEM, "Leaving emu thread"); } static void EmuThreadStart() { - ILOG("EmuThreadStart"); + INFO_LOG(SYSTEM, "EmuThreadStart"); emuThreadState = (int)EmuThreadState::START_REQUESTED; emuThread = std::thread(&EmuThreadFunc); } @@ -254,14 +253,14 @@ static void EmuThreadStart() { // as long as emuThreadState isn't STOPPED and/or there are still things queued up. // Only after that, call EmuThreadJoin. static void EmuThreadStop(const char *caller) { - ILOG("EmuThreadStop - stopping (%s)...", caller); + INFO_LOG(SYSTEM, "EmuThreadStop - stopping (%s)...", caller); emuThreadState = (int)EmuThreadState::QUIT_REQUESTED; } static void EmuThreadJoin() { emuThread.join(); emuThread = std::thread(); - ILOG("EmuThreadJoin - joined"); + INFO_LOG(SYSTEM, "EmuThreadJoin - joined"); } static void ProcessFrameCommands(JNIEnv *env); @@ -496,7 +495,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init // Makes sure we get early permission grants. ProcessFrameCommands(env); - ILOG("NativeApp.init() -- begin"); + INFO_LOG(SYSTEM, "NativeApp.init() -- begin"); PROFILE_INIT(); renderer_inited = false; @@ -516,7 +515,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init systemName = GetJavaString(env, jmodel); langRegion = GetJavaString(env, jlangRegion); - ILOG("NativeApp.init(): device name: '%s'", systemName.c_str()); + INFO_LOG(SYSTEM, "NativeApp.init(): device name: '%s'", systemName.c_str()); std::string externalDir = GetJavaString(env, jexternalDir); std::string user_data_path = GetJavaString(env, jdataDir); @@ -527,8 +526,8 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init std::string cacheDir = GetJavaString(env, jcacheDir); std::string buildBoard = GetJavaString(env, jboard); boardName = buildBoard; - ILOG("NativeApp.init(): External storage path: %s", externalDir.c_str()); - ILOG("NativeApp.init(): Launch shortcut parameter: %s", shortcut_param.c_str()); + INFO_LOG(SYSTEM, "NativeApp.init(): External storage path: %s", externalDir.c_str()); + INFO_LOG(SYSTEM, "NativeApp.init(): Launch shortcut parameter: %s", shortcut_param.c_str()); std::string app_name; std::string app_nice_name; @@ -567,7 +566,7 @@ retry: case (int)GPUBackend::OPENGL: useCPUThread = true; if (javaGL) { - ILOG("NativeApp.init() -- creating OpenGL context (JavaGL)"); + INFO_LOG(SYSTEM, "NativeApp.init() -- creating OpenGL context (JavaGL)"); graphicsContext = new AndroidJavaEGLGraphicsContext(); } else { graphicsContext = new AndroidEGLGraphicsContext(); @@ -575,12 +574,12 @@ retry: break; case (int)GPUBackend::VULKAN: { - ILOG("NativeApp.init() -- creating Vulkan context"); + INFO_LOG(SYSTEM, "NativeApp.init() -- creating Vulkan context"); useCPUThread = false; // The Vulkan render manager manages its own thread. // We create and destroy the Vulkan graphics context in the "EGL" thread. AndroidVulkanContext *ctx = new AndroidVulkanContext(); if (!ctx->InitAPI()) { - ILOG("Failed to initialize Vulkan, switching to OpenGL"); + INFO_LOG(SYSTEM, "Failed to initialize Vulkan, switching to OpenGL"); g_Config.iGPUBackend = (int)GPUBackend::OPENGL; SetGPUBackend(GPUBackend::OPENGL); goto retry; @@ -590,13 +589,13 @@ retry: break; } default: - ELOG("NativeApp.init(): iGPUBackend %d not supported. Switching to OpenGL.", (int)g_Config.iGPUBackend); + ERROR_LOG(SYSTEM, "NativeApp.init(): iGPUBackend %d not supported. Switching to OpenGL.", (int)g_Config.iGPUBackend); g_Config.iGPUBackend = (int)GPUBackend::OPENGL; goto retry; } if (useCPUThread) { - ILOG("NativeApp.init() - launching emu thread"); + INFO_LOG(SYSTEM, "NativeApp.init() - launching emu thread"); EmuThreadStart(); } } @@ -619,11 +618,11 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioInit(JNIEnv *, jclass) { sampleRate = 44100; } - ILOG("NativeApp.audioInit() -- Using OpenSL audio! frames/buffer: %i optimal sr: %i actual sr: %i", optimalFramesPerBuffer, optimalSampleRate, sampleRate); + INFO_LOG(AUDIO, "NativeApp.audioInit() -- Using OpenSL audio! frames/buffer: %i optimal sr: %i actual sr: %i", optimalFramesPerBuffer, optimalSampleRate, sampleRate); if (!g_audioState) { g_audioState = AndroidAudio_Init(&NativeMix, framesPerBuffer, sampleRate); } else { - ELOG("Audio state already initialized"); + ERROR_LOG(AUDIO, "Audio state already initialized"); } } @@ -632,17 +631,17 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioShutdown(JNIEnv *, jclass) AndroidAudio_Shutdown(g_audioState); g_audioState = nullptr; } else { - ELOG("Audio state already shutdown!"); + ERROR_LOG(AUDIO, "Audio state already shutdown!"); } } extern "C" void Java_org_ppsspp_ppsspp_NativeApp_resume(JNIEnv *, jclass) { - ILOG("NativeApp.resume() - resuming audio"); + INFO_LOG(SYSTEM, "NativeApp.resume() - resuming audio"); AndroidAudio_Resume(g_audioState); } extern "C" void Java_org_ppsspp_ppsspp_NativeApp_pause(JNIEnv *, jclass) { - ILOG("NativeApp.pause() - pausing audio"); + INFO_LOG(SYSTEM, "NativeApp.pause() - pausing audio"); AndroidAudio_Pause(g_audioState); } @@ -650,31 +649,31 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) { if (renderer_inited && useCPUThread && graphicsContext) { // Only used in Java EGL path. EmuThreadStop("shutdown"); - ILOG("BeginAndroidShutdown"); + INFO_LOG(SYSTEM, "BeginAndroidShutdown"); graphicsContext->BeginAndroidShutdown(); // Skipping GL calls, the old context is gone. while (graphicsContext->ThreadFrame()) { - ILOG("graphicsContext->ThreadFrame executed to clear buffers"); + INFO_LOG(SYSTEM, "graphicsContext->ThreadFrame executed to clear buffers"); } - ILOG("Joining emuthread"); + INFO_LOG(SYSTEM, "Joining emuthread"); EmuThreadJoin(); - ILOG("Joined emuthread"); + INFO_LOG(SYSTEM, "Joined emuthread"); graphicsContext->ThreadEnd(); graphicsContext->ShutdownFromRenderThread(); - ILOG("Graphics context now shut down from NativeApp_shutdown"); + INFO_LOG(SYSTEM, "Graphics context now shut down from NativeApp_shutdown"); } - ILOG("NativeApp.shutdown() -- begin"); + INFO_LOG(SYSTEM, "NativeApp.shutdown() -- begin"); if (renderer_inited) { - ILOG("Shutting down renderer"); + INFO_LOG(G3D, "Shutting down renderer"); // This will be from the wrong thread? :/ graphicsContext->Shutdown(); delete graphicsContext; graphicsContext = nullptr; renderer_inited = false; } else { - ILOG("Not shutting down renderer - not initialized"); + INFO_LOG(G3D, "Not shutting down renderer - not initialized"); } inputBoxCallbacks.clear(); @@ -682,7 +681,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) { VFSShutdown(); while (frameCommands.size()) frameCommands.pop(); - ILOG("NativeApp.shutdown() -- end"); + INFO_LOG(SYSTEM, "NativeApp.shutdown() -- end"); } // JavaEGL @@ -691,16 +690,16 @@ extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, std::string errorMessage; if (renderer_inited) { // Would be really nice if we could get something on the GL thread immediately when shutting down. - ILOG("NativeApp.displayInit() restoring"); + INFO_LOG(G3D, "NativeApp.displayInit() restoring"); if (useCPUThread) { EmuThreadStop("displayInit"); graphicsContext->BeginAndroidShutdown(); - ILOG("BeginAndroidShutdown. Looping until emu thread done..."); + INFO_LOG(G3D, "BeginAndroidShutdown. Looping until emu thread done..."); // Skipping GL calls here because the old context is lost. while (graphicsContext->ThreadFrame()) { continue; } - ILOG("Joining emu thread"); + INFO_LOG(G3D, "Joining emu thread"); EmuThreadJoin(); } else { NativeShutdownGraphics(); @@ -708,7 +707,7 @@ extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, graphicsContext->ThreadEnd(); graphicsContext->ShutdownFromRenderThread(); - ILOG("Shut down both threads. Now let's bring it up again!"); + INFO_LOG(G3D, "Shut down both threads. Now let's bring it up again!"); if (!graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0)) { SystemToast("Graphics initialization failed. Quitting."); @@ -726,9 +725,9 @@ extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, } graphicsContext->ThreadStart(); - ILOG("Restored."); + INFO_LOG(G3D, "Restored."); } else { - ILOG("NativeApp.displayInit() first time"); + INFO_LOG(G3D, "NativeApp.displayInit() first time"); if (!graphicsContext->InitFromRenderThread(nullptr, 0, 0, 0, 0)) { SystemToast("Graphics initialization failed. Quitting."); return false; @@ -758,15 +757,15 @@ static void recalculateDpi() { pixel_in_dps_x = (float)pixel_xres / dp_xres; pixel_in_dps_y = (float)pixel_yres / dp_yres; - ILOG("RecalcDPI: display_xres=%d display_yres=%d", display_xres, display_yres); - ILOG("RecalcDPI: g_dpi=%f g_dpi_scale_x=%f g_dpi_scale_y=%f", g_dpi, g_dpi_scale_x, g_dpi_scale_y); - ILOG("RecalcDPI: dp_xscale=%f dp_yscale=%f", dp_xscale, dp_yscale); - ILOG("RecalcDPI: dp_xres=%d dp_yres=%d", dp_xres, dp_yres); - ILOG("RecalcDPI: pixel_xres=%d pixel_yres=%d", pixel_xres, pixel_yres); + INFO_LOG(G3D, "RecalcDPI: display_xres=%d display_yres=%d", display_xres, display_yres); + INFO_LOG(G3D, "RecalcDPI: g_dpi=%f g_dpi_scale_x=%f g_dpi_scale_y=%f", g_dpi, g_dpi_scale_x, g_dpi_scale_y); + INFO_LOG(G3D, "RecalcDPI: dp_xscale=%f dp_yscale=%f", dp_xscale, dp_yscale); + INFO_LOG(G3D, "RecalcDPI: dp_xres=%d dp_yres=%d", dp_xres, dp_yres); + INFO_LOG(G3D, "RecalcDPI: pixel_xres=%d pixel_yres=%d", pixel_xres, pixel_yres); } extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv *, jclass, jint bufw, jint bufh, jint format) { - ILOG("NativeApp.backbufferResize(%d x %d)", bufw, bufh); + INFO_LOG(SYSTEM, "NativeApp.backbufferResize(%d x %d)", bufw, bufh); bool new_size = pixel_xres != bufw || pixel_yres != bufh; int old_w = pixel_xres; @@ -779,10 +778,10 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv recalculateDpi(); if (new_size) { - ILOG("Size change detected (previously %d,%d) - calling NativeResized()", old_w, old_h); + INFO_LOG(G3D, "Size change detected (previously %d,%d) - calling NativeResized()", old_w, old_h); NativeResized(); } else { - ILOG("NativeApp::backbufferResize: Size didn't change."); + INFO_LOG(G3D, "NativeApp::backbufferResize: Size didn't change."); } } @@ -801,20 +800,20 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_sendInputBox(JNIEnv *en static std::string lastSeqID = ""; if (lastSeqID == seqID) { // We send this on dismiss, so twice in many cases. - DLOG("Ignoring duplicate sendInputBox"); + DEBUG_LOG(SYSTEM, "Ignoring duplicate sendInputBox"); return; } lastSeqID = seqID; int seq = 0; if (!TryParse(seqID, &seq)) { - ELOG("Invalid inputbox seqID value: %s", seqID.c_str()); + ERROR_LOG(SYSTEM, "Invalid inputbox seqID value: %s", seqID.c_str()); return; } auto entry = inputBoxCallbacks.find(seq); if (entry == inputBoxCallbacks.end()) { - ELOG("Did not find inputbox callback for %s, shutdown?", seqID.c_str()); + ERROR_LOG(SYSTEM, "Did not find inputbox callback for %s, shutdown?", seqID.c_str()); return; } @@ -988,19 +987,19 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_sendMessage(JNIEnv *env if (msg == "moga") { mogaVersion = prm; } else if (msg == "permission_pending") { - ILOG("STORAGE PERMISSION: PENDING"); + INFO_LOG(SYSTEM, "STORAGE PERMISSION: PENDING"); // TODO: Add support for other permissions permissions[SYSTEM_PERMISSION_STORAGE] = PERMISSION_STATUS_PENDING; } else if (msg == "permission_denied") { - ILOG("STORAGE PERMISSION: DENIED"); + INFO_LOG(SYSTEM, "STORAGE PERMISSION: DENIED"); permissions[SYSTEM_PERMISSION_STORAGE] = PERMISSION_STATUS_DENIED; } else if (msg == "permission_granted") { - ILOG("STORAGE PERMISSION: GRANTED"); + INFO_LOG(SYSTEM, "STORAGE PERMISSION: GRANTED"); permissions[SYSTEM_PERMISSION_STORAGE] = PERMISSION_STATUS_GRANTED; } else if (msg == "sustained_perf_supported") { sustainedPerfSupported = true; } else if (msg == "safe_insets") { - ILOG("Got insets: %s", prm.c_str()); + INFO_LOG(SYSTEM, "Got insets: %s", prm.c_str()); // We don't bother with supporting exact rectangular regions. Safe insets are good enough. int left, right, top, bottom; if (4 == sscanf(prm.c_str(), "%d:%d:%d:%d", &left, &right, &top, &bottom)) { @@ -1017,7 +1016,7 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_sendMessage(JNIEnv *env extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeActivity_exitEGLRenderLoop(JNIEnv *env, jobject obj) { if (!renderLoopRunning) { - ELOG("Render loop already exited"); + ERROR_LOG(SYSTEM, "Render loop already exited"); return; } exitRenderLoop = true; @@ -1030,7 +1029,7 @@ void correctRatio(int &sz_x, int &sz_y, float scale) { float x = (float)sz_x; float y = (float)sz_y; float ratio = x / y; - ILOG("CorrectRatio: Considering size: %0.2f/%0.2f=%0.2f for scale %f", x, y, ratio, scale); + INFO_LOG(G3D, "CorrectRatio: Considering size: %0.2f/%0.2f=%0.2f for scale %f", x, y, ratio, scale); float targetRatio; // Try to get the longest dimension to match scale*PSP resolution. @@ -1045,7 +1044,7 @@ void correctRatio(int &sz_x, int &sz_y, float scale) { } float correction = targetRatio / ratio; - ILOG("Target ratio: %0.2f ratio: %0.2f correction: %0.2f", targetRatio, ratio, correction); + INFO_LOG(G3D, "Target ratio: %0.2f ratio: %0.2f correction: %0.2f", targetRatio, ratio, correction); if (ratio < targetRatio) { y *= correction; } else { @@ -1054,7 +1053,7 @@ void correctRatio(int &sz_x, int &sz_y, float scale) { sz_x = x; sz_y = y; - ILOG("Corrected ratio: %dx%d", sz_x, sz_y); + INFO_LOG(G3D, "Corrected ratio: %dx%d", sz_x, sz_y); } void getDesiredBackbufferSize(int &sz_x, int &sz_y) { @@ -1071,7 +1070,7 @@ void getDesiredBackbufferSize(int &sz_x, int &sz_y) { } extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_setDisplayParameters(JNIEnv *, jclass, jint xres, jint yres, jint dpi, jfloat refreshRate) { - ILOG("NativeApp.setDisplayParameters(%d x %d, dpi=%d, refresh=%0.2f)", xres, yres, dpi, refreshRate); + INFO_LOG(G3D, "NativeApp.setDisplayParameters(%d x %d, dpi=%d, refresh=%0.2f)", xres, yres, dpi, refreshRate); bool changed = false; changed = changed || display_xres != xres || display_yres != yres; changed = changed || display_dpi_x != dpi || display_dpi_y != dpi; @@ -1156,7 +1155,7 @@ static void ProcessFrameCommands(JNIEnv *env) { frameCmd = frameCommands.front(); frameCommands.pop(); - ILOG("frameCommand '%s' '%s'", frameCmd.command.c_str(), frameCmd.params.c_str()); + INFO_LOG(SYSTEM, "frameCommand '%s' '%s'", frameCmd.command.c_str(), frameCmd.params.c_str()); jstring cmd = env->NewStringUTF(frameCmd.command.c_str()); jstring param = env->NewStringUTF(frameCmd.params.c_str()); @@ -1168,7 +1167,7 @@ static void ProcessFrameCommands(JNIEnv *env) { extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) { if (!graphicsContext) { - ELOG("runEGLRenderLoop: Tried to enter without a created graphics context."); + ERROR_LOG(G3D, "runEGLRenderLoop: Tried to enter without a created graphics context."); return false; } @@ -1180,10 +1179,10 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J ANativeWindow *wnd = _surf ? ANativeWindow_fromSurface(env, _surf) : nullptr; - WLOG("runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres); + WARN_LOG(G3D, "runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres); if (wnd == nullptr) { - ELOG("Error: Surface is null."); + ERROR_LOG(G3D, "Error: Surface is null."); renderLoopRunning = false; return false; } @@ -1192,7 +1191,7 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J if (graphicsContext->InitFromRenderThread(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format, androidVersion)) { return true; } else { - ELOG("Failed to initialize graphics context."); + ERROR_LOG(G3D, "Failed to initialize graphics context."); SystemToast("Failed to initialize graphics context."); return false; } @@ -1201,7 +1200,7 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J bool initSuccess = tryInit(); if (!initSuccess) { if (!exitRenderLoop && g_Config.iGPUBackend == (int)GPUBackend::VULKAN) { - ILOG("Trying again, this time with OpenGL."); + INFO_LOG(G3D, "Trying again, this time with OpenGL."); SetGPUBackend(GPUBackend::OPENGL); g_Config.iGPUBackend = (int)GetGPUBackend(); @@ -1220,7 +1219,7 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J if (!exitRenderLoop) { if (!useCPUThread) { if (!NativeInitGraphics(graphicsContext)) { - ELOG("Failed to initialize graphics."); + ERROR_LOG(G3D, "Failed to initialize graphics."); // Gonna be in a weird state here.. } } @@ -1237,7 +1236,7 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J } if (useCPUThread) { - ELOG("Running graphics loop"); + ERROR_LOG(SYSTEM, "Running graphics loop"); while (!exitRenderLoop) { // This is the "GPU thread". graphicsContext->ThreadFrame(); @@ -1256,7 +1255,7 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J } } - ILOG("Leaving EGL/Vulkan render loop."); + INFO_LOG(G3D, "Leaving EGL/Vulkan render loop."); if (useCPUThread) { EmuThreadStop("exitrenderloop"); @@ -1271,10 +1270,10 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J graphicsContext->ThreadEnd(); // Shut the graphics context down to the same state it was in when we entered the render thread. - ILOG("Shutting down graphics context from render thread..."); + INFO_LOG(G3D, "Shutting down graphics context from render thread..."); graphicsContext->ShutdownFromRenderThread(); renderLoopRunning = false; - WLOG("Render loop function exited."); + WARN_LOG(G3D, "Render loop function exited."); return true; } diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 220b54aec4..f21f67aac0 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -20,6 +20,24 @@ static bool OnRenderThread() { } #endif +void GLDeleter::Take(GLDeleter &other) { + _assert_msg_(IsEmpty(), "Deleter already has stuff"); + shaders = std::move(other.shaders); + programs = std::move(other.programs); + buffers = std::move(other.buffers); + textures = std::move(other.textures); + inputLayouts = std::move(other.inputLayouts); + framebuffers = std::move(other.framebuffers); + pushBuffers = std::move(other.pushBuffers); + other.shaders.clear(); + other.programs.clear(); + other.buffers.clear(); + other.textures.clear(); + other.inputLayouts.clear(); + other.framebuffers.clear(); + other.pushBuffers.clear(); +} + // Runs on the GPU thread. void GLDeleter::Perform(GLRenderManager *renderManager, bool skipGLCalls) { for (auto pushBuffer : pushBuffers) { diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 13aa599741..3e5870507d 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -8,9 +8,7 @@ #include #include #include -#include -#include "base/logging.h" #include "gfx/gl_common.h" #include "math/dataconv.h" #include "Common/Log.h" @@ -30,6 +28,7 @@ public: glDeleteTextures(1, &texture); } } + GLuint texture = 0; // Could also trust OpenGL defaults I guess.. GLenum target = 0xFFFF; @@ -217,7 +216,7 @@ private: // Note: we must defrag because some buffers may be smaller than size_. Defragment(); Map(); - assert(writePtr_); + _dbg_assert_(writePtr_); } void BeginNoReset() { @@ -253,14 +252,14 @@ public: // Returns the offset that should be used when binding this buffer to get this data. size_t Push(const void *data, size_t size, GLRBuffer **vkbuf) { - assert(writePtr_); + _dbg_assert_(writePtr_); size_t off = Allocate(size, vkbuf); memcpy(writePtr_ + off, data, size); return off; } uint32_t PushAligned(const void *data, size_t size, int align, GLRBuffer **vkbuf) { - assert(writePtr_); + _dbg_assert_(writePtr_); offset_ = (offset_ + align - 1) & ~(align - 1); size_t off = Allocate(size, vkbuf); memcpy(writePtr_ + off, data, size); @@ -274,13 +273,13 @@ public: // "Zero-copy" variant - you can write the data directly as you compute it. // Recommended. void *Push(size_t size, uint32_t *bindOffset, GLRBuffer **vkbuf) { - assert(writePtr_); + _dbg_assert_(writePtr_); size_t off = Allocate(size, vkbuf); *bindOffset = (uint32_t)off; return writePtr_ + off; } void *PushAligned(size_t size, uint32_t *bindOffset, GLRBuffer **vkbuf, int align) { - assert(writePtr_); + _dbg_assert_(writePtr_); offset_ = (offset_ + align - 1) & ~(align - 1); size_t off = Allocate(size, vkbuf); *bindOffset = (uint32_t)off; @@ -324,23 +323,7 @@ public: return shaders.empty() && programs.empty() && buffers.empty() && textures.empty() && inputLayouts.empty() && framebuffers.empty() && pushBuffers.empty(); } - void Take(GLDeleter &other) { - _assert_msg_(IsEmpty(), "Deleter already has stuff"); - shaders = std::move(other.shaders); - programs = std::move(other.programs); - buffers = std::move(other.buffers); - textures = std::move(other.textures); - inputLayouts = std::move(other.inputLayouts); - framebuffers = std::move(other.framebuffers); - pushBuffers = std::move(other.pushBuffers); - other.shaders.clear(); - other.programs.clear(); - other.buffers.clear(); - other.textures.clear(); - other.inputLayouts.clear(); - other.framebuffers.clear(); - other.pushBuffers.clear(); - } + void Take(GLDeleter &other); std::vector shaders; std::vector programs; @@ -431,7 +414,7 @@ public: std::vector shaders, std::vector semantics, std::vector queries, std::vector initalizers, bool supportDualSource) { GLRInitStep step{ GLRInitStepType::CREATE_PROGRAM }; - assert(shaders.size() <= ARRAY_SIZE(step.create_program.shaders)); + _assert_(shaders.size() <= ARRAY_SIZE(step.create_program.shaders)); step.create_program.program = new GLRProgram(); step.create_program.program->semantics_ = semantics; step.create_program.program->queries_ = queries; @@ -443,10 +426,10 @@ public: } #ifdef _DEBUG for (auto &iter : queries) { - assert(iter.name); + _dbg_assert_(iter.name); } for (auto &sem : semantics) { - assert(sem.attrib); + _dbg_assert_(sem.attrib); } #endif step.create_program.num_shaders = (int)shaders.size(); @@ -616,7 +599,7 @@ public: void BindVertexBuffer(GLRInputLayout *inputLayout, GLRBuffer *buffer, size_t offset) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); - assert(inputLayout); + _dbg_assert_(inputLayout); GLRRenderData data{ GLRRenderCommand::BIND_VERTEX_BUFFER }; data.bindVertexBuffer.inputLayout = inputLayout; data.bindVertexBuffer.offset = offset; @@ -650,7 +633,7 @@ public: void SetUniformI(const GLint *loc, int count, const int *udata) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG - assert(curProgram_); + _dbg_assert_(curProgram_); #endif GLRRenderData data{ GLRRenderCommand::UNIFORM4I }; data.uniform4.loc = loc; @@ -662,7 +645,7 @@ public: void SetUniformI1(const GLint *loc, int udata) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG - assert(curProgram_); + _dbg_assert_(curProgram_); #endif GLRRenderData data{ GLRRenderCommand::UNIFORM4I }; data.uniform4.loc = loc; @@ -674,7 +657,7 @@ public: void SetUniformF(const GLint *loc, int count, const float *udata) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG - assert(curProgram_); + _dbg_assert_(curProgram_); #endif GLRRenderData data{ GLRRenderCommand::UNIFORM4F }; data.uniform4.loc = loc; @@ -686,7 +669,7 @@ public: void SetUniformF1(const GLint *loc, const float udata) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG - assert(curProgram_); + _dbg_assert_(curProgram_); #endif GLRRenderData data{ GLRRenderCommand::UNIFORM4F }; data.uniform4.loc = loc; @@ -698,7 +681,7 @@ public: void SetUniformF(const char *name, int count, const float *udata) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG - assert(curProgram_); + _dbg_assert_(curProgram_); #endif GLRRenderData data{ GLRRenderCommand::UNIFORM4F }; data.uniform4.name = name; @@ -710,7 +693,7 @@ public: void SetUniformM4x4(const GLint *loc, const float *udata) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG - assert(curProgram_); + _dbg_assert_(curProgram_); #endif GLRRenderData data{ GLRRenderCommand::UNIFORMMATRIX }; data.uniformMatrix4.loc = loc; @@ -721,7 +704,7 @@ public: void SetUniformM4x4(const char *name, const float *udata) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG - assert(curProgram_); + _dbg_assert_(curProgram_); #endif GLRRenderData data{ GLRRenderCommand::UNIFORMMATRIX }; data.uniformMatrix4.name = name; @@ -902,7 +885,7 @@ public: foundCount++; } } - assert(foundCount == 1); + _dbg_assert_(foundCount == 1); } void SetSwapFunction(std::function swapFunction) { From 8835728f87f9e57905a8bb5066bdb30f7124b53f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 12:12:57 +0200 Subject: [PATCH 497/848] Replace base/logging.h in VulkanContext and parts of native --- Common/Vulkan/VulkanContext.cpp | 124 ++++++++++++------------ Common/Vulkan/VulkanContext.h | 2 +- Common/Vulkan/VulkanImage.cpp | 10 +- Common/Vulkan/VulkanMemory.cpp | 39 ++++---- GPU/Vulkan/VulkanUtil.cpp | 1 + ext/native/thin3d/VulkanQueueRunner.cpp | 68 ++++++------- ext/native/ui/screen.h | 1 - ext/native/ui/view.h | 1 - ext/native/ui/viewgroup.cpp | 6 ++ ext/native/ui/viewgroup.h | 7 +- 10 files changed, 130 insertions(+), 129 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 7d483f11ad..2cb47926f0 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -1,12 +1,12 @@ #define __STDC_LIMIT_MACROS #include #include -#include #include #include #include "base/basictypes.h" #include "base/display.h" +#include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanDebug.h" #include "GPU/Common/ShaderCommon.h" @@ -139,9 +139,9 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { } instance_extensions_enabled_.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); extensionsLookup_.EXT_debug_utils = true; - ILOG("Vulkan debug_utils validation enabled."); + INFO_LOG(G3D, "Vulkan debug_utils validation enabled."); } else { - ELOG("Validation layer extension not available - not enabling Vulkan validation."); + ERROR_LOG(G3D, "Validation layer extension not available - not enabling Vulkan validation."); flags_ &= ~VULKAN_FLAG_VALIDATE; } } @@ -154,7 +154,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { // Validate that all the instance extensions we ask for are actually available. for (auto ext : instance_extensions_enabled_) { if (!IsInstanceExtensionAvailable(ext)) - WLOG("WARNING: Does not seem that instance extension '%s' is available. Trying to proceed anyway.", ext); + WARN_LOG(G3D, "WARNING: Does not seem that instance extension '%s' is available. Trying to proceed anyway.", ext); } VkApplicationInfo app_info{ VK_STRUCTURE_TYPE_APPLICATION_INFO }; @@ -180,7 +180,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { #endif if (res != VK_SUCCESS) { if (res == VK_ERROR_LAYER_NOT_PRESENT) { - WLOG("Validation on but instance layer not available - dropping layers"); + WARN_LOG(G3D, "Validation on but instance layer not available - dropping layers"); // Drop the validation layers and try again. instance_layer_names_.clear(); device_layer_names_.clear(); @@ -188,9 +188,9 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { inst_info.ppEnabledLayerNames = nullptr; res = vkCreateInstance(&inst_info, nullptr, &instance_); if (res != VK_SUCCESS) - ELOG("Failed to create instance even without validation: %d", res); + ERROR_LOG(G3D, "Failed to create instance even without validation: %d", res); } else { - ELOG("Failed to create instance : %d", res); + ERROR_LOG(G3D, "Failed to create instance : %d", res); } } if (res != VK_SUCCESS) { @@ -200,7 +200,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { VulkanLoadInstanceFunctions(instance_, extensionsLookup_); if (!CheckLayers(instance_layer_properties_, instance_layer_names_)) { - WLOG("CheckLayers for instance failed"); + WARN_LOG(G3D, "CheckLayers for instance failed"); // init_error_ = "Failed to validate instance layers"; // return; } @@ -212,14 +212,14 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { res = vkEnumeratePhysicalDevices(instance_, &gpu_count, nullptr); #endif if (gpu_count <= 0) { - ELOG("Vulkan driver found but no supported GPU is available"); + ERROR_LOG(G3D, "Vulkan driver found but no supported GPU is available"); init_error_ = "No Vulkan physical devices found"; vkDestroyInstance(instance_, nullptr); instance_ = nullptr; return VK_ERROR_INITIALIZATION_FAILED; } - assert(gpu_count > 0); + _dbg_assert_(gpu_count > 0); physical_devices_.resize(gpu_count); physicalDeviceProperties_.resize(gpu_count); res = vkEnumeratePhysicalDevices(instance_, &gpu_count, physical_devices_.data()); @@ -259,7 +259,7 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) { } VulkanContext::~VulkanContext() { - assert(instance_ == VK_NULL_HANDLE); + _dbg_assert_(instance_ == VK_NULL_HANDLE); } void VulkanContext::DestroyInstance() { @@ -290,7 +290,7 @@ void VulkanContext::EndFrame() { } void VulkanContext::UpdateInflightFrames(int n) { - assert(n >= 1 && n <= MAX_INFLIGHT_FRAMES); + _dbg_assert_(n >= 1 && n <= MAX_INFLIGHT_FRAMES); inflightFrames_ = n; if (curFrame_ >= inflightFrames_) { curFrame_ = 0; @@ -508,19 +508,19 @@ int VulkanContext::GetBestPhysicalDevice() { void VulkanContext::ChooseDevice(int physical_device) { physical_device_ = physical_device; - ILOG("Chose physical device %d: %p", physical_device, physical_devices_[physical_device]); + INFO_LOG(G3D, "Chose physical device %d: %p", physical_device, physical_devices_[physical_device]); GetDeviceLayerProperties(); if (!CheckLayers(device_layer_properties_, device_layer_names_)) { - WLOG("CheckLayers for device %d failed", physical_device); + WARN_LOG(G3D, "CheckLayers for device %d failed", physical_device); } vkGetPhysicalDeviceQueueFamilyProperties(physical_devices_[physical_device_], &queue_count, nullptr); - assert(queue_count >= 1); + _dbg_assert_(queue_count >= 1); queueFamilyProperties_.resize(queue_count); vkGetPhysicalDeviceQueueFamilyProperties(physical_devices_[physical_device_], &queue_count, queueFamilyProperties_.data()); - assert(queue_count >= 1); + _dbg_assert_(queue_count >= 1); // Detect preferred formats, in this order. static const VkFormat depthStencilFormats[] = { @@ -539,17 +539,17 @@ void VulkanContext::ChooseDevice(int physical_device) { } if (deviceInfo_.preferredDepthStencilFormat == VK_FORMAT_UNDEFINED) { // WTF? This is bad. - ELOG("Could not find a usable depth stencil format."); + ERROR_LOG(G3D, "Could not find a usable depth stencil format."); } // This is as good a place as any to do this. vkGetPhysicalDeviceMemoryProperties(physical_devices_[physical_device_], &memory_properties); - ILOG("Memory Types (%d):", memory_properties.memoryTypeCount); + INFO_LOG(G3D, "Memory Types (%d):", memory_properties.memoryTypeCount); for (int i = 0; i < (int)memory_properties.memoryTypeCount; i++) { // Don't bother printing dummy memory types. if (!memory_properties.memoryTypes[i].propertyFlags) continue; - ILOG(" %d: Heap %d; Flags: %s%s%s%s ", i, memory_properties.memoryTypes[i].heapIndex, + INFO_LOG(G3D, " %d: Heap %d; Flags: %s%s%s%s ", i, memory_properties.memoryTypes[i].heapIndex, (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ? "DEVICE_LOCAL " : "", (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ? "HOST_VISIBLE " : "", (memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) ? "HOST_CACHED " : "", @@ -611,7 +611,7 @@ bool VulkanContext::EnableDeviceExtension(const char *extension) { VkResult VulkanContext::CreateDevice() { if (!init_error_.empty() || physical_device_ < 0) { - ELOG("Vulkan init failed: %s", init_error_.c_str()); + ERROR_LOG(G3D, "Vulkan init failed: %s", init_error_.c_str()); return VK_ERROR_INITIALIZATION_FAILED; } @@ -627,7 +627,7 @@ VkResult VulkanContext::CreateDevice() { break; } } - assert(found); + _dbg_assert_(found); extensionsLookup_.KHR_maintenance1 = EnableDeviceExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME); extensionsLookup_.KHR_maintenance2 = EnableDeviceExtension(VK_KHR_MAINTENANCE2_EXTENSION_NAME); @@ -661,11 +661,11 @@ VkResult VulkanContext::CreateDevice() { VkResult res = vkCreateDevice(physical_devices_[physical_device_], &device_info, nullptr, &device_); if (res != VK_SUCCESS) { init_error_ = "Unable to create Vulkan device"; - ELOG("Unable to create Vulkan device"); + ERROR_LOG(G3D, "Unable to create Vulkan device"); } else { VulkanLoadDeviceFunctions(device_, extensionsLookup_); } - ILOG("Device created.\n"); + INFO_LOG(G3D, "Device created.\n"); VulkanSetAvailable(true); return res; } @@ -685,10 +685,10 @@ VkResult VulkanContext::InitDebugUtilsCallback() { VkDebugUtilsMessengerEXT messenger; VkResult res = vkCreateDebugUtilsMessengerEXT(instance_, &callback1, nullptr, &messenger); if (res != VK_SUCCESS) { - ELOG("Failed to register debug callback with vkCreateDebugUtilsMessengerEXT"); + ERROR_LOG(G3D, "Failed to register debug callback with vkCreateDebugUtilsMessengerEXT"); // Do error handling for VK_ERROR_OUT_OF_MEMORY } else { - ILOG("Debug callback registered with vkCreateDebugUtilsMessengerEXT."); + INFO_LOG(G3D, "Debug callback registered with vkCreateDebugUtilsMessengerEXT."); utils_callbacks.push_back(messenger); } return res; @@ -711,12 +711,12 @@ VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data VkResult VulkanContext::ReinitSurface() { if (surface_ != VK_NULL_HANDLE) { - ILOG("Destroying Vulkan surface (%d, %d)", swapChainExtent_.width, swapChainExtent_.height); + INFO_LOG(G3D, "Destroying Vulkan surface (%d, %d)", swapChainExtent_.width, swapChainExtent_.height); vkDestroySurfaceKHR(instance_, surface_, nullptr); surface_ = VK_NULL_HANDLE; } - ILOG("Creating Vulkan surface for window (%p %p)", winsysData1_, winsysData2_); + INFO_LOG(G3D, "Creating Vulkan surface for window (%p %p)", winsysData1_, winsysData2_); VkResult retval = VK_SUCCESS; @@ -842,7 +842,7 @@ bool VulkanContext::ChooseQueue() { // Generate error if could not find both a graphics and a present queue if (graphicsQueueNodeIndex == UINT32_MAX || presentQueueNodeIndex == UINT32_MAX) { - ELOG("Could not find a graphics and a present queue"); + ERROR_LOG(G3D, "Could not find a graphics and a present queue"); return false; } @@ -858,7 +858,7 @@ bool VulkanContext::ChooseQueue() { std::vector surfFormats(formatCount); res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, surfFormats.data()); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); if (res != VK_SUCCESS) { return false; } @@ -866,7 +866,7 @@ bool VulkanContext::ChooseQueue() { // the surface has no preferred format. Otherwise, at least one // supported format will be returned. if (formatCount == 0 || (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED)) { - ILOG("swapchain_format: Falling back to B8G8R8A8_UNORM"); + INFO_LOG(G3D, "swapchain_format: Falling back to B8G8R8A8_UNORM"); swapchainFormat_ = VK_FORMAT_B8G8R8A8_UNORM; } else { swapchainFormat_ = VK_FORMAT_UNDEFINED; @@ -884,7 +884,7 @@ bool VulkanContext::ChooseQueue() { // Okay, take the first one then. swapchainFormat_ = surfFormats[0].format; } - ILOG("swapchain_format: %d (/%d)", swapchainFormat_, formatCount); + INFO_LOG(G3D, "swapchain_format: %d (/%d)", swapchainFormat_, formatCount); } vkGetDeviceQueue(device_, graphics_queue_family_index_, 0, &gfx_queue_); @@ -915,20 +915,20 @@ static std::string surface_transforms_to_string(VkSurfaceTransformFlagsKHR trans bool VulkanContext::InitSwapchain() { VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[physical_device_], surface_, &surfCapabilities_); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); uint32_t presentModeCount; res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[physical_device_], surface_, &presentModeCount, nullptr); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); VkPresentModeKHR *presentModes = new VkPresentModeKHR[presentModeCount]; - assert(presentModes); + _dbg_assert_(presentModes); res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[physical_device_], surface_, &presentModeCount, presentModes); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); swapChainExtent_.width = clamp(surfCapabilities_.currentExtent.width, surfCapabilities_.minImageExtent.width, surfCapabilities_.maxImageExtent.width); swapChainExtent_.height = clamp(surfCapabilities_.currentExtent.height, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.height); - ILOG("surfCapabilities_.current: %dx%d min: %dx%d max: %dx%d computed: %dx%d", + INFO_LOG(G3D, "surfCapabilities_.current: %dx%d min: %dx%d max: %dx%d computed: %dx%d", surfCapabilities_.currentExtent.width, surfCapabilities_.currentExtent.height, surfCapabilities_.minImageExtent.width, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.width, surfCapabilities_.maxImageExtent.height, @@ -944,7 +944,7 @@ bool VulkanContext::InitSwapchain() { modes += ", "; } } - ILOG("Supported present modes: %s", modes.c_str()); + INFO_LOG(G3D, "Supported present modes: %s", modes.c_str()); for (size_t i = 0; i < presentModeCount; i++) { bool match = false; match = match || ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR); @@ -976,7 +976,7 @@ bool VulkanContext::InitSwapchain() { desiredNumberOfSwapChainImages = surfCapabilities_.maxImageCount; } - ILOG("Chosen present mode: %d (%s). numSwapChainImages: %d/%d", + INFO_LOG(G3D, "Chosen present mode: %d (%s). numSwapChainImages: %d/%d", swapchainPresentMode, PresentModeString(swapchainPresentMode), desiredNumberOfSwapChainImages, surfCapabilities_.maxImageCount); @@ -1011,7 +1011,7 @@ bool VulkanContext::InitSwapchain() { std::swap(swapChainExtent_.width, swapChainExtent_.height); break; default: - assert(false); + _dbg_assert_(false); } } else { // Let the OS rotate the image (potentially slow on many Android devices) @@ -1020,10 +1020,10 @@ bool VulkanContext::InitSwapchain() { std::string preTransformStr = surface_transforms_to_string(preTransform); - ILOG("Transform supported: %s current: %s chosen: %s", supportedTransforms.c_str(), currentTransform.c_str(), preTransformStr.c_str()); + INFO_LOG(G3D, "Transform supported: %s current: %s chosen: %s", supportedTransforms.c_str(), currentTransform.c_str(), preTransformStr.c_str()); if (physicalDeviceProperties_[physical_device_].properties.vendorID == VULKAN_VENDOR_IMGTEC) { - ILOG("Applying PowerVR hack (rounding off the width!)"); + INFO_LOG(G3D, "Applying PowerVR hack (rounding off the width!)"); // Swap chain width hack to avoid issue #11743 (PowerVR driver bug). // To keep the size consistent even with pretransform, do this after the swap. Should be fine. // This is fixed in newer PowerVR drivers but I don't know the cutoff. @@ -1068,10 +1068,10 @@ bool VulkanContext::InitSwapchain() { res = vkCreateSwapchainKHR(device_, &swap_chain_info, NULL, &swapchain_); if (res != VK_SUCCESS) { - ELOG("vkCreateSwapchainKHR failed!"); + ERROR_LOG(G3D, "vkCreateSwapchainKHR failed!"); return false; } - ILOG("Created swapchain: %dx%d", swap_chain_info.imageExtent.width, swap_chain_info.imageExtent.height); + INFO_LOG(G3D, "Created swapchain: %dx%d", swap_chain_info.imageExtent.width, swap_chain_info.imageExtent.height); return true; } @@ -1092,13 +1092,13 @@ void VulkanContext::PerformPendingDeletes() { void VulkanContext::DestroyDevice() { if (swapchain_) { - ELOG("DestroyDevice: Swapchain should have been destroyed."); + ERROR_LOG(G3D, "DestroyDevice: Swapchain should have been destroyed."); } if (surface_) { - ELOG("DestroyDevice: Surface should have been destroyed."); + ERROR_LOG(G3D, "DestroyDevice: Surface should have been destroyed."); } - ILOG("VulkanContext::DestroyDevice (performing deletes)"); + INFO_LOG(G3D, "VulkanContext::DestroyDevice (performing deletes)"); PerformPendingDeletes(); vkDestroyDevice(device_, nullptr); @@ -1274,22 +1274,22 @@ const char *VulkanResultToString(VkResult res) { } void VulkanDeleteList::Take(VulkanDeleteList &del) { - assert(cmdPools_.empty()); - assert(descPools_.empty()); - assert(modules_.empty()); - assert(buffers_.empty()); - assert(bufferViews_.empty()); - assert(images_.empty()); - assert(imageViews_.empty()); - assert(deviceMemory_.empty()); - assert(samplers_.empty()); - assert(pipelines_.empty()); - assert(pipelineCaches_.empty()); - assert(renderPasses_.empty()); - assert(framebuffers_.empty()); - assert(pipelineLayouts_.empty()); - assert(descSetLayouts_.empty()); - assert(callbacks_.empty()); + _dbg_assert_(cmdPools_.empty()); + _dbg_assert_(descPools_.empty()); + _dbg_assert_(modules_.empty()); + _dbg_assert_(buffers_.empty()); + _dbg_assert_(bufferViews_.empty()); + _dbg_assert_(images_.empty()); + _dbg_assert_(imageViews_.empty()); + _dbg_assert_(deviceMemory_.empty()); + _dbg_assert_(samplers_.empty()); + _dbg_assert_(pipelines_.empty()); + _dbg_assert_(pipelineCaches_.empty()); + _dbg_assert_(renderPasses_.empty()); + _dbg_assert_(framebuffers_.empty()); + _dbg_assert_(pipelineLayouts_.empty()); + _dbg_assert_(descSetLayouts_.empty()); + _dbg_assert_(callbacks_.empty()); cmdPools_ = std::move(del.cmdPools_); descPools_ = std::move(del.descPools_); modules_ = std::move(del.modules_); diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 7c9174f38f..b1c998b8b5 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -1,11 +1,11 @@ #pragma once #include +#include #include #include #include -#include "base/logging.h" #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanDebug.h" diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 247df10ff9..82d07cd264 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -67,7 +67,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all VkResult res = vkCreateImage(vulkan_->GetDevice(), &image_create_info, NULL, &image_); if (res != VK_SUCCESS) { _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); - ELOG("vkCreateImage failed: %s", VulkanResultToString(res)); + ERROR_LOG(G3D, "vkCreateImage failed: %s", VulkanResultToString(res)); return false; } @@ -82,7 +82,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all 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); + ERROR_LOG(G3D, "Image memory allocation failed (mem_reqs.size=%d, typebits=%08x", (int)mem_reqs.size, (int)mem_reqs.memoryTypeBits); // Destructor will take care of the image. return false; } @@ -103,7 +103,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mem_); if (res != VK_SUCCESS) { - ELOG("vkAllocateMemory failed: %s", VulkanResultToString(res)); + ERROR_LOG(G3D, "vkAllocateMemory failed: %s", VulkanResultToString(res)); _assert_msg_(res != VK_ERROR_TOO_MANY_OBJECTS, "Too many Vulkan memory objects!"); _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; @@ -114,7 +114,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all res = vkBindImageMemory(vulkan_->GetDevice(), image_, mem_, offset_); if (res != VK_SUCCESS) { - ELOG("vkBindImageMemory failed: %s", VulkanResultToString(res)); + ERROR_LOG(G3D, "vkBindImageMemory failed: %s", VulkanResultToString(res)); // This leaks the image and memory. Should not really happen though... _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; @@ -156,7 +156,7 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all res = vkCreateImageView(vulkan_->GetDevice(), &view_info, NULL, &view_); if (res != VK_SUCCESS) { - ELOG("vkCreateImageView failed: %s", VulkanResultToString(res)); + ERROR_LOG(G3D, "vkCreateImageView failed: %s", VulkanResultToString(res)); // This leaks the image. _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); return false; diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 9cead85745..062472c377 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -18,19 +18,20 @@ // Additionally, Common/Vulkan/* , including this file, are also licensed // under the public domain. -#include "Common/Log.h" -#include "Common/Vulkan/VulkanMemory.h" #include "base/timeutil.h" #include "math/math_util.h" +#include "Common/Log.h" +#include "Common/Vulkan/VulkanMemory.h" + VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryPropertyMask) : vulkan_(vulkan), memoryPropertyMask_(memoryPropertyMask), size_(size), usage_(usage) { bool res = AddBuffer(); - assert(res); + _assert_(res); } VulkanPushBuffer::~VulkanPushBuffer() { - assert(buffers_.empty()); + _assert_(buffers_.empty()); } bool VulkanPushBuffer::AddBuffer() { @@ -68,7 +69,7 @@ bool VulkanPushBuffer::AddBuffer() { } res = vkBindBufferMemory(device, info.buffer, info.deviceMemory, 0); if (VK_SUCCESS != res) { - ELOG("vkBindBufferMemory failed! result=%d", (int)res); + ERROR_LOG(G3D, "vkBindBufferMemory failed! result=%d", (int)res); vkFreeMemory(device, info.deviceMemory, nullptr); vkDestroyBuffer(device, info.buffer, nullptr); return false; @@ -100,7 +101,7 @@ void VulkanPushBuffer::NextBuffer(size_t minSize) { } bool res = AddBuffer(); - assert(res); + _assert_(res); if (!res) { // Let's try not to crash at least? buf_ = 0; @@ -124,7 +125,7 @@ void VulkanPushBuffer::Defragment(VulkanContext *vulkan) { size_ = newSize; bool res = AddBuffer(); - assert(res); + _assert_(res); } size_t VulkanPushBuffer::GetTotalSize() const { @@ -139,7 +140,7 @@ void VulkanPushBuffer::Map() { _dbg_assert_(!writePtr_); VkResult res = vkMapMemory(vulkan_->GetDevice(), buffers_[buf_].deviceMemory, 0, size_, 0, (void **)(&writePtr_)); _dbg_assert_(writePtr_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); } void VulkanPushBuffer::Unmap() { @@ -161,12 +162,12 @@ void VulkanPushBuffer::Unmap() { VulkanDeviceAllocator::VulkanDeviceAllocator(VulkanContext *vulkan, size_t minSlabSize, size_t maxSlabSize) : vulkan_(vulkan), minSlabSize_(minSlabSize), maxSlabSize_(maxSlabSize) { - assert((minSlabSize_ & (SLAB_GRAIN_SIZE - 1)) == 0); + _assert_((minSlabSize_ & (SLAB_GRAIN_SIZE - 1)) == 0); } VulkanDeviceAllocator::~VulkanDeviceAllocator() { - assert(destroyed_); - assert(slabs_.empty()); + _assert_(destroyed_); + _assert_(slabs_.empty()); } void VulkanDeviceAllocator::Destroy() { @@ -183,7 +184,7 @@ void VulkanDeviceAllocator::Destroy() { } } - assert(slab.deviceMemory); + _assert_(slab.deviceMemory); vulkan_->Delete().QueueDeleteDeviceMemory(slab.deviceMemory); } slabs_.clear(); @@ -191,11 +192,11 @@ void VulkanDeviceAllocator::Destroy() { } size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDeviceMemory *deviceMemory, const std::string &tag) { - assert(!destroyed_); + _assert_(!destroyed_); uint32_t memoryTypeIndex; bool pass = vulkan_->MemoryTypeFromProperties(reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memoryTypeIndex); if (!pass) { - ELOG("Failed to pick an appropriate memory type (req: %08x)", reqs.memoryTypeBits); + ERROR_LOG(G3D, "Failed to pick an appropriate memory type (req: %08x)", reqs.memoryTypeBits); return ALLOCATE_FAILED; } @@ -244,7 +245,7 @@ size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDevic } bool VulkanDeviceAllocator::AllocateFromSlab(Slab &slab, size_t &start, size_t blocks, const std::string &tag) { - assert(!destroyed_); + _assert_(!destroyed_); bool matched = true; if (start + blocks > slab.usage.size()) { @@ -320,7 +321,7 @@ void VulkanDeviceAllocator::DoTouch(VkDeviceMemory deviceMemory, size_t offset) } void VulkanDeviceAllocator::Free(VkDeviceMemory deviceMemory, size_t offset) { - assert(!destroyed_); + _assert_(!destroyed_); _assert_msg_(!slabs_.empty(), "No slabs - can't be anything to free! double-freed?"); @@ -401,7 +402,7 @@ void VulkanDeviceAllocator::ExecuteFree(FreeInfo *userdata) { } bool VulkanDeviceAllocator::AllocateSlab(VkDeviceSize minBytes, int memoryTypeIndex) { - assert(!destroyed_); + _assert_(!destroyed_); if (!slabs_.empty() && minSlabSize_ < maxSlabSize_) { // We're allocating an additional slab, so rachet up its size. // TODO: Maybe should not do this when we are allocating a new slab due to memoryTypeIndex not matching? @@ -420,7 +421,7 @@ bool VulkanDeviceAllocator::AllocateSlab(VkDeviceSize minBytes, int memoryTypeIn VkResult res = vkAllocateMemory(vulkan_->GetDevice(), &alloc, NULL, &deviceMemory); if (res != VK_SUCCESS) { // If it's something else, we used it wrong? - assert(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); + _assert_(res == VK_ERROR_OUT_OF_HOST_MEMORY || res == VK_ERROR_OUT_OF_DEVICE_MEMORY || res == VK_ERROR_TOO_MANY_OBJECTS); // Okay, so we ran out of memory. return false; } @@ -464,7 +465,7 @@ void VulkanDeviceAllocator::ReportOldUsage() { } void VulkanDeviceAllocator::Decimate() { - assert(!destroyed_); + _assert_(!destroyed_); bool foundFree = false; if (TRACK_TOUCH) { diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index 0e653be2b1..7e0ad69ba7 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "base/logging.h" // For OutputDebugStringUTF8. TODO: Move it. #include "base/basictypes.h" #include "base/stringutil.h" #include "Common/Log.h" diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index cffb65f8a5..6ce2eb4249 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -9,7 +9,7 @@ // Debug help: adb logcat -s DEBUG PPSSPPNativeActivity PPSSPP NativeGLView NativeRenderer NativeSurfaceView PowerSaveModeReceiver InputDeviceState void VulkanQueueRunner::CreateDeviceObjects() { - ILOG("VulkanQueueRunner::CreateDeviceObjects"); + INFO_LOG(G3D, "VulkanQueueRunner::CreateDeviceObjects"); InitBackbufferRenderPass(); framebufferRenderPass_ = GetRenderPass(VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, VKRRenderPassAction::CLEAR, @@ -19,14 +19,14 @@ void VulkanQueueRunner::CreateDeviceObjects() { // Just to check whether it makes sense to split some of these. drawidx is way bigger than the others... // We should probably just move to variable-size data in a raw buffer anyway... VkRenderData rd; - ILOG("sizeof(pipeline): %d", (int)sizeof(rd.pipeline)); - ILOG("sizeof(draw): %d", (int)sizeof(rd.draw)); - ILOG("sizeof(drawidx): %d", (int)sizeof(rd.drawIndexed)); - ILOG("sizeof(clear): %d", (int)sizeof(rd.clear)); - ILOG("sizeof(viewport): %d", (int)sizeof(rd.viewport)); - ILOG("sizeof(scissor): %d", (int)sizeof(rd.scissor)); - ILOG("sizeof(blendColor): %d", (int)sizeof(rd.blendColor)); - ILOG("sizeof(push): %d", (int)sizeof(rd.push)); + INFO_LOG(G3D, "sizeof(pipeline): %d", (int)sizeof(rd.pipeline)); + INFO_LOG(G3D, "sizeof(draw): %d", (int)sizeof(rd.draw)); + INFO_LOG(G3D, "sizeof(drawidx): %d", (int)sizeof(rd.drawIndexed)); + INFO_LOG(G3D, "sizeof(clear): %d", (int)sizeof(rd.clear)); + INFO_LOG(G3D, "sizeof(viewport): %d", (int)sizeof(rd.viewport)); + INFO_LOG(G3D, "sizeof(scissor): %d", (int)sizeof(rd.scissor)); + INFO_LOG(G3D, "sizeof(blendColor): %d", (int)sizeof(rd.blendColor)); + INFO_LOG(G3D, "sizeof(push): %d", (int)sizeof(rd.push)); #endif } @@ -87,7 +87,7 @@ void VulkanQueueRunner::ResizeReadbackBuffer(VkDeviceSize requiredSize) { } void VulkanQueueRunner::DestroyDeviceObjects() { - ILOG("VulkanQueueRunner::DestroyDeviceObjects"); + INFO_LOG(G3D, "VulkanQueueRunner::DestroyDeviceObjects"); vulkan_->Delete().QueueDeleteDeviceMemory(readbackMemory_); vulkan_->Delete().QueueDeleteBuffer(readbackBuffer_); readbackBufferSize_ = 0; @@ -98,7 +98,7 @@ void VulkanQueueRunner::DestroyDeviceObjects() { }); renderPasses_.Clear(); - assert(backbufferRenderPass_ != VK_NULL_HANDLE); + _assert_(backbufferRenderPass_ != VK_NULL_HANDLE); vulkan_->Delete().QueueDeleteRenderPass(backbufferRenderPass_); backbufferRenderPass_ = VK_NULL_HANDLE; } @@ -559,7 +559,7 @@ void VulkanQueueRunner::ApplyMGSHack(std::vector &steps) { for (int j = 0; j < (int)renders.size(); j++) { steps[i + j + copies.size()] = renders[j]; } - assert(steps[i + copies.size()]->stepType == VKRStepType::RENDER); + _assert_(steps[i + copies.size()]->stepType == VKRStepType::RENDER); // Combine the renders. for (int j = 1; j < (int)renders.size(); j++) { for (int k = 0; k < (int)renders[j]->commands.size(); k++) { @@ -850,10 +850,10 @@ void VulkanQueueRunner::ApplyRenderPassMerge(std::vector &steps) { } void VulkanQueueRunner::LogSteps(const std::vector &steps) { - ILOG("======================================="); + INFO_LOG(G3D, "======================================="); for (size_t i = 0; i < steps.size(); i++) { const VKRStep &step = *steps[i]; - ILOG("%s", StepToString(step).c_str()); + INFO_LOG(G3D, "%s", StepToString(step).c_str()); switch (step.stepType) { case VKRStepType::RENDER: LogRenderPass(step); @@ -871,7 +871,7 @@ void VulkanQueueRunner::LogSteps(const std::vector &steps) { LogReadbackImage(step); break; case VKRStepType::RENDER_SKIP: - ILOG("(skipped render pass)"); + INFO_LOG(G3D, "(skipped render pass)"); break; } } @@ -892,62 +892,62 @@ const char *RenderPassActionName(VKRRenderPassAction a) { void VulkanQueueRunner::LogRenderPass(const VKRStep &pass) { const auto &r = pass.render; int fb = (int)(intptr_t)(r.framebuffer ? r.framebuffer->framebuf : 0); - ILOG("RenderPass Begin(%x, %s, %s, %s)", fb, RenderPassActionName(r.color), RenderPassActionName(r.depth), RenderPassActionName(r.stencil)); + INFO_LOG(G3D, "RenderPass Begin(%x, %s, %s, %s)", fb, RenderPassActionName(r.color), RenderPassActionName(r.depth), RenderPassActionName(r.stencil)); for (auto &cmd : pass.commands) { switch (cmd.cmd) { case VKRRenderCommand::REMOVED: - ILOG(" (Removed)"); + INFO_LOG(G3D, " (Removed)"); break; case VKRRenderCommand::BIND_PIPELINE: - ILOG(" BindPipeline(%x)", (int)(intptr_t)cmd.pipeline.pipeline); + INFO_LOG(G3D, " BindPipeline(%x)", (int)(intptr_t)cmd.pipeline.pipeline); break; case VKRRenderCommand::BLEND: - ILOG(" BlendColor(%08x)", cmd.blendColor.color); + INFO_LOG(G3D, " BlendColor(%08x)", cmd.blendColor.color); break; case VKRRenderCommand::CLEAR: - ILOG(" Clear"); + INFO_LOG(G3D, " Clear"); break; case VKRRenderCommand::DRAW: - ILOG(" Draw(%d)", cmd.draw.count); + INFO_LOG(G3D, " Draw(%d)", cmd.draw.count); break; case VKRRenderCommand::DRAW_INDEXED: - ILOG(" DrawIndexed(%d)", cmd.drawIndexed.count); + INFO_LOG(G3D, " DrawIndexed(%d)", cmd.drawIndexed.count); break; case VKRRenderCommand::SCISSOR: - ILOG(" Scissor(%d, %d, %d, %d)", (int)cmd.scissor.scissor.offset.x, (int)cmd.scissor.scissor.offset.y, (int)cmd.scissor.scissor.extent.width, (int)cmd.scissor.scissor.extent.height); + INFO_LOG(G3D, " Scissor(%d, %d, %d, %d)", (int)cmd.scissor.scissor.offset.x, (int)cmd.scissor.scissor.offset.y, (int)cmd.scissor.scissor.extent.width, (int)cmd.scissor.scissor.extent.height); break; case VKRRenderCommand::STENCIL: - ILOG(" Stencil(ref=%d, compare=%d, write=%d)", cmd.stencil.stencilRef, cmd.stencil.stencilCompareMask, cmd.stencil.stencilWriteMask); + INFO_LOG(G3D, " Stencil(ref=%d, compare=%d, write=%d)", cmd.stencil.stencilRef, cmd.stencil.stencilCompareMask, cmd.stencil.stencilWriteMask); break; case VKRRenderCommand::VIEWPORT: - ILOG(" Viewport(%f, %f, %f, %f, %f, %f)", cmd.viewport.vp.x, cmd.viewport.vp.y, cmd.viewport.vp.width, cmd.viewport.vp.height, cmd.viewport.vp.minDepth, cmd.viewport.vp.maxDepth); + INFO_LOG(G3D, " Viewport(%f, %f, %f, %f, %f, %f)", cmd.viewport.vp.x, cmd.viewport.vp.y, cmd.viewport.vp.width, cmd.viewport.vp.height, cmd.viewport.vp.minDepth, cmd.viewport.vp.maxDepth); break; case VKRRenderCommand::PUSH_CONSTANTS: - ILOG(" PushConstants(%d)", cmd.push.size); + INFO_LOG(G3D, " PushConstants(%d)", cmd.push.size); break; case VKRRenderCommand::NUM_RENDER_COMMANDS: break; } } - ILOG("RenderPass End(%x)", fb); + INFO_LOG(G3D, "RenderPass End(%x)", fb); } void VulkanQueueRunner::LogCopy(const VKRStep &step) { - ILOG("%s", StepToString(step).c_str()); + INFO_LOG(G3D, "%s", StepToString(step).c_str()); } void VulkanQueueRunner::LogBlit(const VKRStep &step) { - ILOG("%s", StepToString(step).c_str()); + INFO_LOG(G3D, "%s", StepToString(step).c_str()); } void VulkanQueueRunner::LogReadback(const VKRStep &step) { - ILOG("%s", StepToString(step).c_str()); + INFO_LOG(G3D, "%s", StepToString(step).c_str()); } void VulkanQueueRunner::LogReadbackImage(const VKRStep &step) { - ILOG("%s", StepToString(step).c_str()); + INFO_LOG(G3D, "%s", StepToString(step).c_str()); } void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer cmd) { @@ -1232,7 +1232,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c break; } default: - ELOG("Unimpl queue command"); + ERROR_LOG(G3D, "Unimpl queue command"); ; } } @@ -1707,7 +1707,7 @@ void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataForm } if (res != VK_SUCCESS) { - ELOG("CopyReadbackBuffer: vkMapMemory failed! result=%d", (int)res); + ERROR_LOG(G3D, "CopyReadbackBuffer: vkMapMemory failed! result=%d", (int)res); return; } @@ -1729,7 +1729,7 @@ void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataForm ConvertToD32F(pixels, (const uint8_t *)mappedData, pixelStride, width, width, height, srcFormat); } else { // TODO: Maybe a depth conversion or something? - ELOG("CopyReadbackBuffer: Unknown format"); + ERROR_LOG(G3D, "CopyReadbackBuffer: Unknown format"); _assert_msg_(false, "CopyReadbackBuffer: Unknown src format %d", (int)srcFormat); } vkUnmapMemory(vulkan_->GetDevice(), readbackMemory_); diff --git a/ext/native/ui/screen.h b/ext/native/ui/screen.h index 0b97108afd..d269995880 100644 --- a/ext/native/ui/screen.h +++ b/ext/native/ui/screen.h @@ -17,7 +17,6 @@ #include #include "base/basictypes.h" -#include "base/logging.h" #include "base/NativeApp.h" #include "input/input_state.h" diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index e8baa55702..0f0976b12f 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -15,7 +15,6 @@ #include #include -#include "base/logging.h" #include "base/basictypes.h" #include "gfx/texture_atlas.h" #include "math/lin/matrix4x4.h" diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index e9f2f88176..82a74faad8 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -1080,6 +1080,12 @@ void AnchorLayout::Layout() { } } +GridLayout::GridLayout(GridLayoutSettings settings, LayoutParams *layoutParams) + : ViewGroup(layoutParams), settings_(settings), numColumns_(1) { + if (settings.orientation != ORIENT_HORIZONTAL) + ELOG("GridLayout: Vertical layouts not yet supported"); +} + void GridLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { MeasureSpecType measureType = settings_.fillCells ? EXACTLY : AT_MOST; diff --git a/ext/native/ui/viewgroup.h b/ext/native/ui/viewgroup.h index 286f922925..0eb3f39328 100644 --- a/ext/native/ui/viewgroup.h +++ b/ext/native/ui/viewgroup.h @@ -5,7 +5,6 @@ #include #include -#include "base/logging.h" #include "math/geom2d.h" #include "input/gesture_detector.h" #include "ui/view.h" @@ -209,11 +208,7 @@ struct GridLayoutSettings { class GridLayout : public ViewGroup { public: - GridLayout(GridLayoutSettings settings, LayoutParams *layoutParams = 0) - : ViewGroup(layoutParams), settings_(settings), numColumns_(1) { - if (settings.orientation != ORIENT_HORIZONTAL) - ELOG("GridLayout: Vertical layouts not yet supported"); - } + GridLayout(GridLayoutSettings settings, LayoutParams *layoutParams = 0); void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) override; void Layout() override; From b43698a13d3345209f16f322630b0354af6fb793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 12:25:39 +0200 Subject: [PATCH 498/848] Remove most instances of base/logging.h from Common, Core, GPU, more --- Common/ArmEmitter.cpp | 12 ++-- Common/CPUDetect.cpp | 10 +-- Common/KeyMap.cpp | 10 +-- Common/MachineContext.h | 4 +- Common/MemArenaAndroid.cpp | 18 ++--- Common/MemoryUtil.cpp | 2 +- Common/MipsEmitter.cpp | 10 ++- Common/MsgHandler.cpp | 4 +- Common/Vulkan/VulkanDebug.cpp | 6 +- Common/Vulkan/VulkanLoader.cpp | 71 ++++++++++---------- Core/CoreTiming.cpp | 1 - Core/Dialog/SavedataParam.cpp | 4 +- Core/HLE/HLE.cpp | 2 +- Core/HLE/ReplaceTables.cpp | 1 - Core/HLE/sceDisplay.cpp | 4 -- Core/HLE/sceKernelThread.cpp | 2 - Core/HW/StereoResampler.cpp | 4 +- Core/MIPS/ARM64/Arm64Asm.cpp | 13 ++-- Core/MIPS/ARM64/Arm64Jit.cpp | 20 +++--- Core/MIPS/ARM64/Arm64RegCache.cpp | 20 +++--- Core/MIPS/ARM64/Arm64RegCacheFPU.cpp | 2 +- Core/MIPS/IR/IRAsm.cpp | 5 +- Core/MIPS/IR/IRFrontend.cpp | 3 +- Core/MIPS/IR/IRJit.cpp | 6 +- Core/MIPS/x86/CompVFPU.cpp | 2 +- GPU/Common/ShaderTranslation.cpp | 6 +- GPU/Common/VertexDecoderArm64.cpp | 8 +-- GPU/Common/VertexDecoderCommon.cpp | 2 +- GPU/D3D11/D3D11Util.cpp | 4 +- GPU/D3D11/DepalettizeShaderD3D11.cpp | 1 - GPU/D3D11/DrawEngineD3D11.cpp | 2 +- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/D3D11/ShaderManagerD3D11.cpp | 2 +- GPU/D3D11/StencilBufferD3D11.cpp | 4 +- GPU/Directx9/DepalettizeShaderDX9.cpp | 1 - GPU/Directx9/DrawEngineDX9.cpp | 2 +- GPU/Directx9/GPU_DX9.cpp | 1 - GPU/Directx9/ShaderManagerDX9.cpp | 2 +- GPU/Directx9/StencilBufferDX9.cpp | 2 - GPU/GLES/DepalettizeShaderGLES.cpp | 1 - GPU/GLES/DrawEngineGLES.cpp | 1 - GPU/GLES/FragmentShaderGeneratorGLES.cpp | 2 +- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GLES/ShaderManagerGLES.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 2 +- GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp | 5 +- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/StencilBufferVulkan.cpp | 4 +- GPU/Vulkan/VulkanUtil.cpp | 1 + Qt/QtMain.h | 1 - UI/BackgroundAudio.cpp | 4 +- UI/EmuScreen.cpp | 2 +- UI/GameInfoCache.cpp | 2 +- UWP/StorageFileLoader.cpp | 3 +- Windows/GPU/D3D11Context.cpp | 4 +- Windows/GPU/D3D9Context.cpp | 2 +- headless/SDLHeadlessHost.cpp | 1 - headless/WindowsHeadlessHost.cpp | 1 - 59 files changed, 150 insertions(+), 169 deletions(-) diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index d289bdfb99..b3878fd443 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -17,9 +17,6 @@ #include "ppsspp_config.h" -#include "base/logging.h" - -#include #include #include #include @@ -31,9 +28,10 @@ #include #endif -#include "MemoryUtil.h" -#include "ArmEmitter.h" -#include "CPUDetect.h" +#include "Common/Log.h" +#include "Common/MemoryUtil.h" +#include "Common/ArmEmitter.h" +#include "Common/CPUDetect.h" #ifdef _WIN32 #include "CommonWindows.h" @@ -1780,7 +1778,7 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src) _assert_msg_(SrcSize == DestSize, "VMOV doesn't support moving different register sizes"); if (SrcSize != DestSize) { - ELOG("SrcSize: %i (%s) DestDize: %i (%s)", SrcSize, ARMRegAsString(Src), DestSize, ARMRegAsString(Dest)); + ERROR_LOG(JIT, "SrcSize: %i (%s) DestDize: %i (%s)", SrcSize, ARMRegAsString(Src), DestSize, ARMRegAsString(Dest)); } Dest = SubBase(Dest); diff --git a/Common/CPUDetect.cpp b/Common/CPUDetect.cpp index ac5cd2e640..ce3ad48a81 100644 --- a/Common/CPUDetect.cpp +++ b/Common/CPUDetect.cpp @@ -28,14 +28,14 @@ #include #include -#include "base/logging.h" + #include "base/basictypes.h" #include "file/file_util.h" -#include "Common.h" -#include "CPUDetect.h" -#include "FileUtil.h" -#include "StringUtils.h" +#include "Common/Common.h" +#include "Common/CPUDetect.h" +#include "Common/FileUtil.h" +#include "Common/StringUtils.h" #if defined(_WIN32) && !defined(__MINGW32__) #define WIN32_LEAN_AND_MEAN diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 1652b51da8..19b93711df 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -24,14 +24,14 @@ #include "CommonWindows.h" #endif -#include "base/logging.h" #include "base/stringutil.h" #include "base/NativeApp.h" #include "file/ini_file.h" #include "input/input_state.h" #include "ppsspp_config.h" -#include "KeyMap.h" +#include "Common/Log.h" +#include "Common/KeyMap.h" #include "Core/HLE/sceUtility.h" #include "Core/Config.h" @@ -898,10 +898,10 @@ void RestoreDefault() { } else if (IsXperiaPlay(name)) { SetDefaultKeyMap(DEFAULT_MAPPING_XPERIA_PLAY, true); } else if (IsMOQII7S(name)) { - ILOG("MOQI pad map"); + INFO_LOG(SYSTEM, "MOQI pad map"); SetDefaultKeyMap(DEFAULT_MAPPING_MOQI_I7S, true); } else { - ILOG("Default pad map"); + INFO_LOG(SYSTEM, "Default pad map"); SetDefaultKeyMap(DEFAULT_MAPPING_PAD, true); } #else @@ -992,7 +992,7 @@ void NotifyPadConnected(const std::string &name) { } void AutoConfForPad(const std::string &name) { - ILOG("Autoconfiguring pad for '%s'", name.c_str()); + INFO_LOG(SYSTEM, "Autoconfiguring pad for '%s'", name.c_str()); if (name == "Xbox 360 Pad") { SetDefaultKeyMap(DEFAULT_MAPPING_X360, true); } else { diff --git a/Common/MachineContext.h b/Common/MachineContext.h index dabc854003..0cac3d97ce 100644 --- a/Common/MachineContext.h +++ b/Common/MachineContext.h @@ -14,7 +14,9 @@ #include typedef CONTEXT SContext; -#if PPSSPP_ARCH(AMD64) +#if defined(__LIBRETRO__) + +#elif PPSSPP_ARCH(AMD64) #define MACHINE_CONTEXT_SUPPORTED diff --git a/Common/MemArenaAndroid.cpp b/Common/MemArenaAndroid.cpp index 67e1861e5a..b43a0815b2 100644 --- a/Common/MemArenaAndroid.cpp +++ b/Common/MemArenaAndroid.cpp @@ -19,12 +19,6 @@ #ifdef __ANDROID__ -#include "base/logging.h" -#include "base/NativeApp.h" -#include "MemoryUtil.h" -#include "MemArena.h" -#include "StringUtils.h" - #include #include #include @@ -33,6 +27,12 @@ #include #include +#include "base/NativeApp.h" +#include "Common/Log.h" +#include "Common/MemoryUtil.h" +#include "Common/MemArena.h" +#include "Common/StringUtils.h" + // Hopefully this ABI will never change... #define ASHMEM_DEVICE "/dev/ashmem" @@ -141,14 +141,14 @@ u8* MemArena::Find4GBBase() { const uint64_t EIGHT_GIGS = 0x200000000ULL; void *base = mmap(0, EIGHT_GIGS, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); if (base) { - ILOG("base: %p", base); + INFO_LOG(SYSTEM, "base: %p", base); uint64_t aligned_base = ((uint64_t)base + 0xFFFFFFFF) & ~0xFFFFFFFFULL; - ILOG("aligned_base: %p", (void *)aligned_base); + INFO_LOG(SYSTEM, "aligned_base: %p", (void *)aligned_base); munmap(base, EIGHT_GIGS); return reinterpret_cast(aligned_base); } else { u8 *hardcoded_ptr = reinterpret_cast(0x2300000000ULL); - ILOG("Failed to anonymously map 8GB. Fall back to the hardcoded pointer %p.", hardcoded_ptr); + INFO_LOG(SYSTEM, "Failed to anonymously map 8GB. Fall back to the hardcoded pointer %p.", hardcoded_ptr); // Just grab some random 4GB... // This has been known to fail lately though, see issue #12249. return hardcoded_ptr; diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index 9a078ea728..c834444563 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -17,7 +17,7 @@ #include "ppsspp_config.h" -#include "base/logging.h" +#include #include "Common/Common.h" #include "Common/Log.h" diff --git a/Common/MipsEmitter.cpp b/Common/MipsEmitter.cpp index bd4e878959..5d6288be3e 100644 --- a/Common/MipsEmitter.cpp +++ b/Common/MipsEmitter.cpp @@ -15,18 +15,16 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" - -#include #include #include #include #include #include -#include "MemoryUtil.h" -#include "MipsEmitter.h" -#include "CPUDetect.h" +#include "Common/Log.h" +#include "Common/MemoryUtil.h" +#include "Common/MipsEmitter.h" +#include "Common/CPUDetect.h" namespace MIPSGen { void MIPSEmitter::SetCodePtr(u8 *ptr) { diff --git a/Common/MsgHandler.cpp b/Common/MsgHandler.cpp index f2ec4dcadd..428790d0df 100644 --- a/Common/MsgHandler.cpp +++ b/Common/MsgHandler.cpp @@ -20,8 +20,8 @@ #include "ppsspp_config.h" #include "Common.h" +#include "Common/Log.h" #include "StringUtils.h" -#include "base/logging.h" #include "util/text/utf8.h" bool MsgHandler(const char *caption, const char *text, const char *file, int line, bool yes_no, int Style); @@ -69,7 +69,7 @@ bool MsgHandler(const char* caption, const char* text, const char *file, int lin return false; #else // Will use android-log if available, printf if not. - ELOG("(%s:%d) %s", file, line, text); + ERROR_LOG(SYSTEM, "(%s:%d) %s", file, line, text); return false; #endif } diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index c60898deef..687070640f 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -19,7 +19,7 @@ #include #include -#include "base/logging.h" +#include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanDebug.h" @@ -79,9 +79,9 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( #else // TODO: Improve. if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { - ELOG("VKDEBUG: %s", msg.c_str()); + ERROR_LOG(G3D, "VKDEBUG: %s", msg.c_str()); } else { - WLOG("VKDEBUG: %s", msg.c_str()); + WARN_LOG(G3D, "VKDEBUG: %s", msg.c_str()); } #endif diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index 59b3fb5bd3..4fff74c28d 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -18,8 +18,9 @@ #include "Common/Vulkan/VulkanLoader.h" #include #include +#include -#include "base/logging.h" +#include "Common/Log.h" #include "base/basictypes.h" #include "base/NativeApp.h" @@ -224,9 +225,9 @@ const char *VulkanResultToString(VkResult res); bool g_vulkanAvailabilityChecked = false; bool g_vulkanMayBeAvailable = false; -#define LOAD_INSTANCE_FUNC(instance, x) x = (PFN_ ## x)vkGetInstanceProcAddr(instance, #x); if (!x) {ILOG("Missing (instance): %s", #x);} -#define LOAD_DEVICE_FUNC(instance, x) x = (PFN_ ## x)vkGetDeviceProcAddr(instance, #x); if (!x) {ILOG("Missing (device): %s", #x);} -#define LOAD_GLOBAL_FUNC(x) x = (PFN_ ## x)dlsym(vulkanLibrary, #x); if (!x) {ILOG("Missing (global): %s", #x);} +#define LOAD_INSTANCE_FUNC(instance, x) x = (PFN_ ## x)vkGetInstanceProcAddr(instance, #x); if (!x) {INFO_LOG(G3D, "Missing (instance): %s", #x);} +#define LOAD_DEVICE_FUNC(instance, x) x = (PFN_ ## x)vkGetDeviceProcAddr(instance, #x); if (!x) {INFO_LOG(G3D, "Missing (device): %s", #x);} +#define LOAD_GLOBAL_FUNC(x) x = (PFN_ ## x)dlsym(vulkanLibrary, #x); if (!x) {INFO_LOG(G3D,"Missing (global): %s", #x);} #define LOAD_GLOBAL_FUNC_LOCAL(lib, x) (PFN_ ## x)dlsym(lib, #x); @@ -259,20 +260,20 @@ bool VulkanMayBeAvailable() { std::string name = System_GetProperty(SYSPROP_NAME); for (const char *blacklisted_name : device_name_blacklist) { if (!strcmp(name.c_str(), blacklisted_name)) { - ILOG("VulkanMayBeAvailable: Device blacklisted ('%s')", name.c_str()); + INFO_LOG(G3D, "VulkanMayBeAvailable: Device blacklisted ('%s')", name.c_str()); g_vulkanAvailabilityChecked = true; g_vulkanMayBeAvailable = false; return false; } } - ILOG("VulkanMayBeAvailable: Device allowed ('%s')", name.c_str()); + INFO_LOG(G3D, "VulkanMayBeAvailable: Device allowed ('%s')", name.c_str()); #ifndef _WIN32 void *lib = nullptr; for (int i = 0; i < ARRAY_SIZE(so_names); i++) { lib = dlopen(so_names[i], RTLD_NOW | RTLD_LOCAL); if (lib) { - ILOG("VulkanMayBeAvailable: Library loaded ('%s')", so_names[i]); + INFO_LOG(G3D, "VulkanMayBeAvailable: Library loaded ('%s')", so_names[i]); break; } } @@ -281,7 +282,7 @@ bool VulkanMayBeAvailable() { HINSTANCE lib = LoadLibrary(L"vulkan-1.dll"); #endif if (!lib) { - ILOG("Vulkan loader: Library not available"); + INFO_LOG(G3D, "Vulkan loader: Library not available"); g_vulkanAvailabilityChecked = true; g_vulkanMayBeAvailable = false; return false; @@ -321,32 +322,32 @@ bool VulkanMayBeAvailable() { #endif if (!localEnumerateInstanceExtensionProperties || !localCreateInstance || !localEnumerate || !localDestroyInstance || !localGetPhysicalDeviceProperties) { - WLOG("VulkanMayBeAvailable: Function pointer missing, bailing"); + WARN_LOG(G3D, "VulkanMayBeAvailable: Function pointer missing, bailing"); goto bail; } - ILOG("VulkanMayBeAvailable: Enumerating instance extensions"); + INFO_LOG(G3D, "VulkanMayBeAvailable: Enumerating instance extensions"); res = localEnumerateInstanceExtensionProperties(nullptr, &instanceExtCount, nullptr); // Maximum paranoia. if (res != VK_SUCCESS) { - ELOG("Enumerating VK extensions failed (%s)", VulkanResultToString(res)); + ERROR_LOG(G3D, "Enumerating VK extensions failed (%s)", VulkanResultToString(res)); goto bail; } if (instanceExtCount == 0) { - ELOG("No VK instance extensions - won't be able to present."); + ERROR_LOG(G3D, "No VK instance extensions - won't be able to present."); goto bail; } - ILOG("VulkanMayBeAvailable: Instance extension count: %d", instanceExtCount); + INFO_LOG(G3D, "VulkanMayBeAvailable: Instance extension count: %d", instanceExtCount); instanceExts.resize(instanceExtCount); res = localEnumerateInstanceExtensionProperties(nullptr, &instanceExtCount, instanceExts.data()); if (res != VK_SUCCESS) { - ELOG("Enumerating VK extensions failed (%s)", VulkanResultToString(res)); + ERROR_LOG(G3D, "Enumerating VK extensions failed (%s)", VulkanResultToString(res)); goto bail; } for (auto iter : instanceExts) { - ILOG("VulkanMaybeAvailable: Instance extension found: %s (%08x)", iter.extensionName, iter.specVersion); + INFO_LOG(G3D, "VulkanMaybeAvailable: Instance extension found: %s (%08x)", iter.extensionName, iter.specVersion); if (platformSurfaceExtension && !strcmp(iter.extensionName, platformSurfaceExtension)) { - ILOG("VulkanMayBeAvailable: Found platform surface extension '%s'", platformSurfaceExtension); + INFO_LOG(G3D, "VulkanMayBeAvailable: Found platform surface extension '%s'", platformSurfaceExtension); instanceExtensions[ci.enabledExtensionCount++] = platformSurfaceExtension; platformSurfaceExtensionFound = true; break; @@ -357,19 +358,19 @@ bool VulkanMayBeAvailable() { } if (platformSurfaceExtension) { if (!platformSurfaceExtensionFound || !surfaceExtensionFound) { - ELOG("Platform surface extension not found"); + ERROR_LOG(G3D, "Platform surface extension not found"); goto bail; } } else { if (!surfaceExtensionFound) { - ELOG("Surface extension not found"); + ERROR_LOG(G3D, "Surface extension not found"); goto bail; } } // This can't happen unless the driver is double-reporting a surface extension. if (ci.enabledExtensionCount > 2) { - ELOG("Unexpected number of enabled instance extensions"); + ERROR_LOG(G3D, "Unexpected number of enabled instance extensions"); goto bail; } @@ -382,27 +383,27 @@ bool VulkanMayBeAvailable() { info.pEngineName = "VulkanCheckerEngine"; ci.pApplicationInfo = &info; ci.flags = 0; - ILOG("VulkanMayBeAvailable: Calling vkCreateInstance"); + INFO_LOG(G3D, "VulkanMayBeAvailable: Calling vkCreateInstance"); res = localCreateInstance(&ci, nullptr, &instance); if (res != VK_SUCCESS) { instance = nullptr; - ELOG("VulkanMayBeAvailable: Failed to create vulkan instance (%s)", VulkanResultToString(res)); + ERROR_LOG(G3D, "VulkanMayBeAvailable: Failed to create vulkan instance (%s)", VulkanResultToString(res)); goto bail; } - ILOG("VulkanMayBeAvailable: Vulkan test instance created successfully."); + INFO_LOG(G3D, "VulkanMayBeAvailable: Vulkan test instance created successfully."); res = localEnumerate(instance, &physicalDeviceCount, nullptr); if (res != VK_SUCCESS) { - ELOG("VulkanMayBeAvailable: Failed to count physical devices (%s)", VulkanResultToString(res)); + ERROR_LOG(G3D, "VulkanMayBeAvailable: Failed to count physical devices (%s)", VulkanResultToString(res)); goto bail; } if (physicalDeviceCount == 0) { - ELOG("VulkanMayBeAvailable: No physical Vulkan devices (count = 0)."); + ERROR_LOG(G3D, "VulkanMayBeAvailable: No physical Vulkan devices (count = 0)."); goto bail; } devices.resize(physicalDeviceCount); res = localEnumerate(instance, &physicalDeviceCount, devices.data()); if (res != VK_SUCCESS) { - ELOG("VulkanMayBeAvailable: Failed to enumerate physical devices (%s)", VulkanResultToString(res)); + ERROR_LOG(G3D, "VulkanMayBeAvailable: Failed to enumerate physical devices (%s)", VulkanResultToString(res)); goto bail; } anyGood = false; @@ -416,24 +417,24 @@ bool VulkanMayBeAvailable() { anyGood = true; break; default: - ILOG("VulkanMayBeAvailable: Ineligible device found and ignored: '%s'", props.deviceName); + INFO_LOG(G3D, "VulkanMayBeAvailable: Ineligible device found and ignored: '%s'", props.deviceName); break; } // TODO: Should also check queuefamilyproperties for a GRAPHICS queue family? Oh well. } if (!anyGood) { - WLOG("VulkanMayBeAvailable: Found Vulkan API, but no good Vulkan device!"); + WARN_LOG(G3D, "VulkanMayBeAvailable: Found Vulkan API, but no good Vulkan device!"); g_vulkanMayBeAvailable = false; } else { - ILOG("VulkanMayBeAvailable: Found working Vulkan API!"); + INFO_LOG(G3D, "VulkanMayBeAvailable: Found working Vulkan API!"); g_vulkanMayBeAvailable = true; } bail: g_vulkanAvailabilityChecked = true; if (instance) { - ILOG("VulkanMayBeAvailable: Destroying instance"); + INFO_LOG(G3D, "VulkanMayBeAvailable: Destroying instance"); localDestroyInstance(instance, nullptr); } if (lib) { @@ -443,7 +444,7 @@ bail: FreeLibrary(lib); #endif } else { - ELOG("Vulkan with working device not detected."); + ERROR_LOG(G3D, "Vulkan with working device not detected."); } return g_vulkanMayBeAvailable; } @@ -454,7 +455,7 @@ bool VulkanLoad() { for (int i = 0; i < ARRAY_SIZE(so_names); i++) { vulkanLibrary = dlopen(so_names[i], RTLD_NOW | RTLD_LOCAL); if (vulkanLibrary) { - ILOG("VulkanLoad: Found library '%s'", so_names[i]); + INFO_LOG(G3D, "VulkanLoad: Found library '%s'", so_names[i]); break; } } @@ -475,10 +476,10 @@ bool VulkanLoad() { LOAD_GLOBAL_FUNC(vkEnumerateInstanceLayerProperties); if (vkCreateInstance && vkGetInstanceProcAddr && vkGetDeviceProcAddr && vkEnumerateInstanceExtensionProperties && vkEnumerateInstanceLayerProperties) { - WLOG("VulkanLoad: Base functions loaded."); + WARN_LOG(G3D, "VulkanLoad: Base functions loaded."); return true; } else { - ELOG("VulkanLoad: Failed to load Vulkan base functions."); + ERROR_LOG(G3D, "VulkanLoad: Failed to load Vulkan base functions."); #ifndef _WIN32 dlclose(vulkanLibrary); #else @@ -548,14 +549,14 @@ void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &en LOAD_INSTANCE_FUNC(instance, vkSetDebugUtilsObjectTagEXT); } - WLOG("Vulkan instance functions loaded."); + WARN_LOG(G3D, "Vulkan instance functions loaded."); } // On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may // increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very // good for multi-device - not likely we'll ever try that anyway though. void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions) { - WLOG("Vulkan device functions loaded."); + WARN_LOG(G3D, "Vulkan device functions loaded."); LOAD_DEVICE_FUNC(device, vkQueueSubmit); LOAD_DEVICE_FUNC(device, vkQueueWaitIdle); diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index b87ee057ed..62fb2afca3 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -20,7 +20,6 @@ #include #include -#include "base/logging.h" #include "profiler/profiler.h" #include "Common/MsgHandler.h" diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 1e021d94fc..d14f3395e3 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "i18n/i18n.h" -#include "base/logging.h" +#include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" @@ -213,7 +213,7 @@ void SavedataParam::Init() if (handle >= 0) { pspFileSystem.CloseFile(handle); } else { - ELOG("Failed to create .nomedia file"); + ERROR_LOG(IO, "Failed to create .nomedia file"); } #endif } diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 06cdf4f390..d83c9e3fe5 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -20,10 +20,10 @@ #include #include -#include "base/logging.h" #include "base/timeutil.h" #include "profiler/profiler.h" +#include "Common/Log.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" #include "Core/Core.h" diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index a1d9e25e5c..359b76e23c 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -20,7 +20,6 @@ #include #include "base/basictypes.h" -#include "base/logging.h" #include "Common/Log.h" #include "Core/Config.h" #include "Core/Debugger/Breakpoints.h" diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 5551513e7f..406c757635 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -26,10 +26,6 @@ #include #endif -// TODO: Move the relevant parts into common. Don't want the core -// to be dependent on "native", I think. Or maybe should get rid of common -// and move everything into native... -#include "base/logging.h" #include "base/timeutil.h" #include "i18n/i18n.h" #include "profiler/profiler.h" diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 5e4ebe84d1..c11bf8b2ad 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -21,8 +21,6 @@ #include #include -#include "base/logging.h" - #include "Common/CommonTypes.h" #include "Common/LogManager.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index 29ecf60b76..5075465589 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -35,11 +35,11 @@ #include #include -#include "base/logging.h" #include "base/timeutil.h" #include "base/NativeApp.h" #include "Common/Serialize/Serializer.h" #include "Common/MathUtil.h" +#include "Common/Log.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/HW/StereoResampler.h" @@ -71,7 +71,7 @@ StereoResampler::StereoResampler() // If framerate is "close"... if (refresh != 60.0f && refresh > 50.0f && refresh < 70.0f) { int input_sample_rate = (int)(44100 * (refresh / 60.0f)); - ILOG("StereoResampler: Adjusting target sample rate to %dHz", input_sample_rate); + INFO_LOG(AUDIO, "StereoResampler: Adjusting target sample rate to %dHz", input_sample_rate); m_input_sample_rate = input_sample_rate; } diff --git a/Core/MIPS/ARM64/Arm64Asm.cpp b/Core/MIPS/ARM64/Arm64Asm.cpp index 81f67fa3a3..99f4dadf65 100644 --- a/Core/MIPS/ARM64/Arm64Asm.cpp +++ b/Core/MIPS/ARM64/Arm64Asm.cpp @@ -18,15 +18,14 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM64) -#include "base/logging.h" - +#include "Common/Log.h" +#include "Common/MemoryUtil.h" +#include "Common/CPUDetect.h" +#include "Common/Arm64Emitter.h" #include "Core/MemMap.h" #include "Core/MIPS/MIPS.h" #include "Core/System.h" #include "Core/CoreTiming.h" -#include "Common/MemoryUtil.h" -#include "Common/CPUDetect.h" -#include "Common/Arm64Emitter.h" #include "Core/MIPS/ARM64/Arm64Jit.h" #include "Core/MIPS/JitCommon/JitCommon.h" @@ -77,9 +76,9 @@ extern volatile CoreState coreState; void ShowPC(u32 downcount, void *membase, void *jitbase) { static int count = 0; if (currentMIPS) { - ELOG("ShowPC : %08x Downcount : %08x %d %p %p", currentMIPS->pc, downcount, count, membase, jitbase); + ERROR_LOG(JIT, "ShowPC : %08x Downcount : %08x %d %p %p", currentMIPS->pc, downcount, count, membase, jitbase); } else { - ELOG("Universe corrupt?"); + ERROR_LOG(JIT, "Universe corrupt?"); } //if (count > 2000) // exit(0); diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index c1d2bac89f..e626599019 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -18,8 +18,8 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM64) -#include "base/logging.h" #include "profiler/profiler.h" +#include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/CPUDetect.h" @@ -49,17 +49,17 @@ using namespace Arm64JitConstants; static void DisassembleArm64Print(const u8 *data, int size) { std::vector lines = DisassembleArm64(data, size); for (auto s : lines) { - ILOG("%s", s.c_str()); + INFO_LOG(JIT, "%s", s.c_str()); } /* - ILOG("+++"); + INFO_LOG(JIT, "+++"); // A format friendly to Online Disassembler which gets endianness wrong for (size_t i = 0; i < lines.size(); i++) { uint32_t opcode = ((const uint32_t *)data)[i]; - ILOG("%d/%d: %08x", (int)(i+1), (int)lines.size(), swap32(opcode)); + INFO_LOG(JIT, "%d/%d: %08x", (int)(i+1), (int)lines.size(), swap32(opcode)); } - ILOG("==="); - ILOG("===");*/ + INFO_LOG(JIT, "==="); + INFO_LOG(JIT, "===");*/ } static u32 JitBreakpoint() { @@ -169,7 +169,7 @@ void Arm64Jit::FlushPrefixV() { } void Arm64Jit::ClearCache() { - ILOG("ARM64Jit: Clearing the cache!"); + INFO_LOG(JIT, "ARM64Jit: Clearing the cache!"); blocks.Clear(); ClearCodeSpace(jitStartOffset); FlushIcacheSection(region + jitStartOffset, region + region_size - jitStartOffset); @@ -361,16 +361,16 @@ const u8 *Arm64Jit::DoJit(u32 em_address, JitBlock *b) { char temp[256]; if (logBlocks > 0 && dontLogBlocks == 0) { - ILOG("=============== mips %d ===============", blocks.GetNumBlocks()); + INFO_LOG(JIT, "=============== mips %d ===============", blocks.GetNumBlocks()); for (u32 cpc = em_address; cpc != GetCompilerPC() + 4; cpc += 4) { MIPSDisAsm(Memory::Read_Opcode_JIT(cpc), cpc, temp, true); - ILOG("M: %08x %s", cpc, temp); + INFO_LOG(JIT, "M: %08x %s", cpc, temp); } } b->codeSize = GetCodePtr() - b->normalEntry; if (logBlocks > 0 && dontLogBlocks == 0) { - ILOG("=============== ARM (%d instructions -> %d bytes) ===============", js.numInstructions, b->codeSize); + INFO_LOG(JIT, "=============== ARM (%d instructions -> %d bytes) ===============", js.numInstructions, b->codeSize); DisassembleArm64Print(b->normalEntry, GetCodePtr() - b->normalEntry); } if (logBlocks > 0) diff --git a/Core/MIPS/ARM64/Arm64RegCache.cpp b/Core/MIPS/ARM64/Arm64RegCache.cpp index a853359ae4..b084adf109 100644 --- a/Core/MIPS/ARM64/Arm64RegCache.cpp +++ b/Core/MIPS/ARM64/Arm64RegCache.cpp @@ -18,7 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM64) -#include "base/logging.h" +#include "Common/Log.h" #include "Core/MemMap.h" #include "Core/MIPS/ARM64/Arm64RegCache.h" #include "Core/MIPS/ARM64/Arm64Jit.h" @@ -150,7 +150,7 @@ bool Arm64RegCache::IsMappedAsPointer(MIPSGPReg mipsReg) { return ar[mr[mipsReg].reg].pointerified; } else if (mr[mipsReg].loc == ML_ARMREG_IMM) { if (ar[mr[mipsReg].reg].pointerified) { - ELOG("Really shouldn't be pointerified here"); + ERROR_LOG(JIT, "Really shouldn't be pointerified here"); } } else if (mr[mipsReg].loc == ML_ARMREG_AS_PTR) { return true; @@ -164,7 +164,7 @@ void Arm64RegCache::MarkDirty(ARM64Reg reg) { void Arm64RegCache::SetRegImm(ARM64Reg reg, u64 imm) { if (reg == INVALID_REG) { - ELOG("SetRegImm to invalid register: at %08x", js_->compilerPC); + ERROR_LOG(JIT, "SetRegImm to invalid register: at %08x", js_->compilerPC); return; } // On ARM64, at least Cortex A57, good old MOVT/MOVW (MOVK in 64-bit) is really fast. @@ -174,7 +174,7 @@ void Arm64RegCache::SetRegImm(ARM64Reg reg, u64 imm) { void Arm64RegCache::MapRegTo(ARM64Reg reg, MIPSGPReg mipsReg, int mapFlags) { if (mr[mipsReg].isStatic) { - ELOG("Cannot MapRegTo static register %d", mipsReg); + ERROR_LOG(JIT, "Cannot MapRegTo static register %d", mipsReg); return; } ar[reg].isDirty = (mapFlags & MAP_DIRTY) ? true : false; @@ -450,7 +450,7 @@ Arm64Gen::ARM64Reg Arm64RegCache::MapRegAsPointer(MIPSGPReg reg) { ar[a].pointerified = true; } } else { - ELOG("MapRegAsPointer : MapReg failed to allocate a register?"); + ERROR_LOG(JIT, "MapRegAsPointer : MapReg failed to allocate a register?"); } return retval; } @@ -506,7 +506,7 @@ void Arm64RegCache::MapDirtyDirtyInIn(MIPSGPReg rd1, MIPSGPReg rd2, MIPSGPReg rs void Arm64RegCache::FlushArmReg(ARM64Reg r) { if (r == INVALID_REG) { - ELOG("FlushArmReg called on invalid register %d", r); + ERROR_LOG(JIT, "FlushArmReg called on invalid register %d", r); return; } if (ar[r].mipsReg == MIPS_REG_INVALID) { @@ -517,7 +517,7 @@ void Arm64RegCache::FlushArmReg(ARM64Reg r) { return; } if (mr[ar[r].mipsReg].isStatic) { - ELOG("Cannot FlushArmReg a statically mapped register"); + ERROR_LOG(JIT, "Cannot FlushArmReg a statically mapped register"); return; } auto &mreg = mr[ar[r].mipsReg]; @@ -629,7 +629,7 @@ ARM64Reg Arm64RegCache::ARM64RegForFlush(MIPSGPReg r) { void Arm64RegCache::FlushR(MIPSGPReg r) { if (mr[r].isStatic) { - ELOG("Cannot flush static reg %d", r); + ERROR_LOG(JIT, "Cannot flush static reg %d", r); return; } @@ -753,7 +753,7 @@ void Arm64RegCache::FlushAll() { } else if (mr[i].loc == ML_ARMREG_IMM) { // The register already contains the immediate. if (ar[armReg].pointerified) { - ELOG("ML_ARMREG_IMM but pointerified. Wrong."); + ERROR_LOG(JIT, "ML_ARMREG_IMM but pointerified. Wrong."); ar[armReg].pointerified = false; } mr[i].loc = ML_ARMREG; @@ -762,7 +762,7 @@ void Arm64RegCache::FlushAll() { mr[i].loc = ML_ARMREG; } if (i != MIPS_REG_ZERO && mr[i].reg == INVALID_REG) { - ELOG("ARM reg of static %i is invalid", i); + ERROR_LOG(JIT, "ARM reg of static %i is invalid", i); continue; } } else { diff --git a/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp b/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp index 7df249eaaa..3861fb44a1 100644 --- a/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp +++ b/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp @@ -20,8 +20,8 @@ #include -#include "base/logging.h" #include "Common/CPUDetect.h" +#include "Common/Log.h" #include "Core/Reporting.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/ARM64/Arm64RegCacheFPU.h" diff --git a/Core/MIPS/IR/IRAsm.cpp b/Core/MIPS/IR/IRAsm.cpp index f5d9c7ad31..38d40469d8 100644 --- a/Core/MIPS/IR/IRAsm.cpp +++ b/Core/MIPS/IR/IRAsm.cpp @@ -15,13 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" - +#include "Common/Log.h" +#include "Common/MemoryUtil.h" #include "Core/MemMap.h" #include "Core/MIPS/MIPS.h" #include "Core/System.h" #include "Core/CoreTiming.h" -#include "Common/MemoryUtil.h" #include "Core/MIPS/IR/IRJit.h" #include "Core/MIPS/JitCommon/JitCommon.h" diff --git a/Core/MIPS/IR/IRFrontend.cpp b/Core/MIPS/IR/IRFrontend.cpp index 86f6b0e198..c3a2df444a 100644 --- a/Core/MIPS/IR/IRFrontend.cpp +++ b/Core/MIPS/IR/IRFrontend.cpp @@ -15,8 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" - +#include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/Debugger/Breakpoints.h" diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 12af157044..ec279776cd 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -16,9 +16,11 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "base/logging.h" + #include "ext/xxhash.h" #include "profiler/profiler.h" + +#include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/StringUtils.h" @@ -61,7 +63,7 @@ void IRJit::UpdateFCR31() { } void IRJit::ClearCache() { - ILOG("IRJit: Clearing the cache!"); + INFO_LOG(JIT, "IRJit: Clearing the cache!"); blocks_.Clear(); } diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index da083d97bb..de23b3b2d2 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -25,10 +25,10 @@ #include #include -#include "base/logging.h" #include "math/math_util.h" #include "Common/CPUDetect.h" +#include "Common/Log.h" #include "Core/Compatibility.h" #include "Core/Config.h" #include "Core/MemMap.h" diff --git a/GPU/Common/ShaderTranslation.cpp b/GPU/Common/ShaderTranslation.cpp index 3693e2393d..d535d063c1 100644 --- a/GPU/Common/ShaderTranslation.cpp +++ b/GPU/Common/ShaderTranslation.cpp @@ -34,10 +34,10 @@ #undef free #endif -#include "base/logging.h" #include "base/basictypes.h" #include "base/stringutil.h" -#include "ShaderTranslation.h" +#include "Common/Log.h" +#include "GPU/Common/ShaderTranslation.h" #include "ext/glslang/SPIRV/GlslangToSpv.h" #include "thin3d/thin3d.h" #include "gfx_es2/gpu_features.h" @@ -211,7 +211,7 @@ bool ConvertToVulkanGLSL(std::string *dest, TranslatedShaderMetadata *destMetada } // DUMPLOG(src.c_str()); - // ILOG("---->"); + // INFO_LOG(SYSTEM, "---->"); // DUMPLOG(LineNumberString(out.str()).c_str()); *dest = out.str(); diff --git a/GPU/Common/VertexDecoderArm64.cpp b/GPU/Common/VertexDecoderArm64.cpp index a4714ee070..7ba612affa 100644 --- a/GPU/Common/VertexDecoderArm64.cpp +++ b/GPU/Common/VertexDecoderArm64.cpp @@ -23,8 +23,8 @@ #define ARM64 #endif -#include "base/logging.h" #include "Common/CPUDetect.h" +#include "Common/Log.h" #include "Core/Config.h" #include "Core/Reporting.h" #include "Common/Arm64Emitter.h" @@ -287,12 +287,12 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int if (log) { char temp[1024] = { 0 }; dec.ToString(temp); - ILOG("=== %s (%d bytes) ===", temp, (int)(GetCodePtr() - start)); + INFO_LOG(JIT, "=== %s (%d bytes) ===", temp, (int)(GetCodePtr() - start)); std::vector lines = DisassembleArm64(start, (int)(GetCodePtr() - start)); for (auto line : lines) { - ILOG("%s", line.c_str()); + INFO_LOG(JIT, "%s", line.c_str()); } - ILOG("=========="); + INFO_LOG(JIT, "=========="); } *jittedSize = (int)(GetCodePtr() - start); diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index 0b8ee6736c..87b8114303 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -19,8 +19,8 @@ #include #include "base/basictypes.h" -#include "base/logging.h" +#include "Common/Log.h" #include "Common/CPUDetect.h" #include "Common/ColorConv.h" #include "Core/Config.h" diff --git a/GPU/D3D11/D3D11Util.cpp b/GPU/D3D11/D3D11Util.cpp index a3b2e963af..7a7b0aac25 100644 --- a/GPU/D3D11/D3D11Util.cpp +++ b/GPU/D3D11/D3D11Util.cpp @@ -13,10 +13,10 @@ #include "thin3d/d3d11_loader.h" #endif -#include "base/logging.h" #include "base/stringutil.h" #include "D3D11Util.h" +#include "Common/Log.h" static std::vector CompileShaderToBytecode(const char *code, size_t codeSize, const char *target, UINT flags) { ID3DBlob *compiledCode = nullptr; @@ -25,7 +25,7 @@ static std::vector CompileShaderToBytecode(const char *code, size_t cod std::string errors; if (errorMsgs) { errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize()); - ELOG("%s: %s", SUCCEEDED(result) ? "warnings" : "errors", errors.c_str()); + ERROR_LOG(G3D, "%s: %s", SUCCEEDED(result) ? "warnings" : "errors", errors.c_str()); OutputDebugStringA(LineNumberString(code).c_str()); errorMsgs->Release(); } diff --git a/GPU/D3D11/DepalettizeShaderD3D11.cpp b/GPU/D3D11/DepalettizeShaderD3D11.cpp index 854c38b34b..c67ce845f0 100644 --- a/GPU/D3D11/DepalettizeShaderD3D11.cpp +++ b/GPU/D3D11/DepalettizeShaderD3D11.cpp @@ -19,7 +19,6 @@ #include #include "base/basictypes.h" -#include "base/logging.h" #include "Common/Log.h" #include "Common/ColorConv.h" #include "Common/StringUtils.h" diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 2eb66a4472..a4780b0b80 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -17,9 +17,9 @@ #include -#include "base/logging.h" #include "base/timeutil.h" +#include "Common/Log.h" #include "Common/MemoryUtil.h" #include "Core/MemMap.h" #include "Core/System.h" diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 31a2faa449..fcd1fa0d8d 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -36,10 +36,10 @@ #include +#include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/GraphicsContext.h" #include "base/NativeApp.h" -#include "base/logging.h" #include "profiler/profiler.h" #include "i18n/i18n.h" #include "Core/Debugger/Breakpoints.h" diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index 5e4a39c062..7ca95da1fb 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -22,12 +22,12 @@ #include -#include "base/logging.h" #include "math/lin/matrix4x4.h" #include "math/math_util.h" #include "math/dataconv.h" #include "thin3d/thin3d.h" #include "util/text/utf8.h" +#include "Common/Log.h" #include "Common/Common.h" #include "Core/Config.h" #include "Core/Reporting.h" diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index 7c47806c74..d4b6dc164e 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -17,9 +17,9 @@ #include -#include "base/logging.h" - #include "ext/native/thin3d/thin3d.h" + +#include "Common/Log.h" #include "Core/Reporting.h" #include "GPU/Common/StencilCommon.h" #include "GPU/D3D11/FramebufferManagerD3D11.h" diff --git a/GPU/Directx9/DepalettizeShaderDX9.cpp b/GPU/Directx9/DepalettizeShaderDX9.cpp index 2365e41d58..ec91de50ba 100644 --- a/GPU/Directx9/DepalettizeShaderDX9.cpp +++ b/GPU/Directx9/DepalettizeShaderDX9.cpp @@ -18,7 +18,6 @@ #include #include -#include "base/logging.h" #include "thin3d/thin3d.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 521393b548..a10a6fca2d 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -15,9 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" #include "base/timeutil.h" +#include "Common/Log.h" #include "Common/MemoryUtil.h" #include "Core/MemMap.h" #include "Core/System.h" diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 73049a864b..1ba0958f66 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -20,7 +20,6 @@ #include "Common/Serialize/Serializer.h" #include "Common/GraphicsContext.h" #include "base/NativeApp.h" -#include "base/logging.h" #include "profiler/profiler.h" #include "i18n/i18n.h" #include "Core/Debugger/Breakpoints.h" diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index e3157371e8..64a1d28137 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -21,8 +21,8 @@ #include #include + #include "gfx/d3d9_shader.h" -#include "base/logging.h" #include "base/stringutil.h" #include "i18n/i18n.h" #include "math/lin/matrix4x4.h" diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 5c0459c6e8..4310a1654e 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -17,8 +17,6 @@ #include -#include "base/logging.h" - #include "gfx/d3d9_state.h" #include "ext/native/thin3d/thin3d.h" #include "Core/Reporting.h" diff --git a/GPU/GLES/DepalettizeShaderGLES.cpp b/GPU/GLES/DepalettizeShaderGLES.cpp index 348411e082..59517c0f4d 100644 --- a/GPU/GLES/DepalettizeShaderGLES.cpp +++ b/GPU/GLES/DepalettizeShaderGLES.cpp @@ -17,7 +17,6 @@ #include -#include "base/logging.h" #include "Common/Log.h" #include "Common/StringUtils.h" #include "Core/Reporting.h" diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 737548acd1..e245fe3112 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" #include "base/timeutil.h" #include "Common/MemoryUtil.h" diff --git a/GPU/GLES/FragmentShaderGeneratorGLES.cpp b/GPU/GLES/FragmentShaderGeneratorGLES.cpp index 97f319fd7e..945f3fb17b 100644 --- a/GPU/GLES/FragmentShaderGeneratorGLES.cpp +++ b/GPU/GLES/FragmentShaderGeneratorGLES.cpp @@ -18,8 +18,8 @@ #include #include +#include "Common/Log.h" #include "Common/StringUtils.h" -#include "base/logging.h" #include "gfx_es2/gpu_features.h" #include "Core/Reporting.h" #include "Core/Config.h" diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 1597ae0218..40fda18e5e 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -15,10 +15,10 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" #include "profiler/profiler.h" #include "i18n/i18n.h" +#include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index eb992d642a..58001193b8 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -24,7 +24,6 @@ #include #include "math/dataconv.h" -#include "base/logging.h" #include "base/timeutil.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/gpu_features.h" @@ -35,6 +34,7 @@ #include "thin3d/thin3d.h" #include "thin3d/GLRenderManager.h" +#include "Common/Log.h" #include "Common/FileUtil.h" #include "Core/Config.h" #include "Core/Host.h" diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index cad3b34225..963fa0f0a6 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -17,12 +17,12 @@ #include -#include "base/logging.h" #include "base/timeutil.h" #include "math/dataconv.h" #include "profiler/profiler.h" #include "thin3d/VulkanRenderManager.h" +#include "Common/Log.h" #include "Common/MemoryUtil.h" #include "Core/MemMap.h" #include "Core/System.h" diff --git a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp index 87e07857c0..87920c52a7 100644 --- a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp @@ -18,9 +18,10 @@ #include #include -#include "Common/StringUtils.h" -#include "base/logging.h" #include "gfx_es2/gpu_features.h" + +#include "Common/Log.h" +#include "Common/StringUtils.h" #include "Core/Reporting.h" #include "Core/Config.h" #include "GPU/Common/GPUStateUtils.h" diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index eb31fbc95e..6442b3e8d7 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -18,10 +18,10 @@ #include -#include "base/logging.h" #include "base/timeutil.h" #include "profiler/profiler.h" +#include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 4cd2c98363..c3d937049f 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -19,7 +19,6 @@ //#define SHADERLOG #endif -#include "base/logging.h" #include "base/stringutil.h" #include "math/lin/matrix4x4.h" #include "math/math_util.h" @@ -27,6 +26,7 @@ #include "profiler/profiler.h" #include "thin3d/thin3d.h" #include "util/text/utf8.h" + #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanMemory.h" #include "Common/Log.h" diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index c952a57b37..e655780476 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -15,10 +15,10 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" - #include "ext/native/thin3d/thin3d.h" #include "ext/native/thin3d/VulkanRenderManager.h" + +#include "Common/Log.h" #include "Core/Reporting.h" #include "GPU/Common/StencilCommon.h" #include "GPU/Vulkan/FramebufferManagerVulkan.h" diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index 7e0ad69ba7..3d5d196e94 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "base/logging.h" // For OutputDebugStringUTF8. TODO: Move it. + #include "base/basictypes.h" #include "base/stringutil.h" #include "Common/Log.h" diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 19a820e7fb..9a69162919 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -23,7 +23,6 @@ QTM_USE_NAMESPACE #include #include "base/display.h" -#include "base/logging.h" #include "base/timeutil.h" #include "file/zip_read.h" #include "gfx/gl_common.h" diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index d8db2bea6f..1de2def802 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -1,12 +1,12 @@ #include #include -#include "base/logging.h" #include "base/timeutil.h" #include "file/chunk_file.h" #include "file/vfs.h" #include "ui/root.h" +#include "Common/Log.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/CommonTypes.h" #include "Common/FixedSizeQueue.h" @@ -178,7 +178,7 @@ public: if (wave_.codec == PSP_CODEC_AT3) { decoder_->SetExtraData(&wave_.at3_extradata[2], 14, wave_.raw_bytes_per_frame); } - ILOG("read ATRAC, frames: %d, rate %d", wave_.numFrames, wave_.sample_rate); + INFO_LOG(AUDIO, "read ATRAC, frames: %d, rate %d", wave_.numFrames, wave_.sample_rate); } ~AT3PlusReader() { diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 08476fbad0..59f5abed66 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1231,7 +1231,7 @@ void EmuScreen::checkPowerDown() { if (PSP_IsInited()) { PSP_Shutdown(); } - ILOG("SELF-POWERDOWN!"); + INFO_LOG(SYSTEM, "SELF-POWERDOWN!"); screenManager()->switchScreen(new MainScreen()); bootPending_ = false; invalid_ = true; diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index e1c2db94f0..4b1746fb2b 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -634,7 +634,7 @@ handleELF: info_->pending = false; info_->working = false; - // ILOG("Completed writing info for %s", info_->GetTitle().c_str()); + // INFO_LOG(SYSTEM, "Completed writing info for %s", info_->GetTitle().c_str()); } float priority() override { diff --git a/UWP/StorageFileLoader.cpp b/UWP/StorageFileLoader.cpp index 7253288fd4..0c52448a58 100644 --- a/UWP/StorageFileLoader.cpp +++ b/UWP/StorageFileLoader.cpp @@ -1,6 +1,5 @@ #include "pch.h" #include "ppltasks.h" -#include "base/logging.h" #include "file/file_util.h" #include "thread/threadutil.h" #include "StorageFileLoader.h" @@ -96,7 +95,7 @@ void StorageFileLoader::threadfunc() { break; } default: - ELOG("Unknown operation"); + ERROR_LOG(SYSTEM, "Unknown operation"); operationRequested_ = false; break; } diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 498467ea37..19fdd64dd1 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -5,8 +5,8 @@ #include #include -#include "base/logging.h" -#include "Base/display.h" +#include "Common/Log.h" +#include "base/display.h" #include "util/text/utf8.h" #include "i18n/i18n.h" diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index e87ed1ea60..c948654b98 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -5,11 +5,11 @@ #include "gfx/d3d9_state.h" -#include "base/logging.h" #include "base/display.h" #include "util/text/utf8.h" #include "i18n/i18n.h" +#include "Common/Log.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Reporting.h" diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index b45b50724d..b81b47a51e 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -32,7 +32,6 @@ #include "GPU/Common/GPUDebugInterface.h" #include "GPU/GPUState.h" -#include "base/logging.h" #include "base/timeutil.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index dba04b79ad..30a9f1b7b2 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -33,7 +33,6 @@ #include "Windows/GPU/D3D11Context.h" #include "Windows/GPU/WindowsVulkanContext.h" -#include "base/logging.h" #include "base/timeutil.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" From 6f1915110fb549162b354987bf78d25349785711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 15:22:44 +0200 Subject: [PATCH 499/848] Remove base/logging from UI and more --- Core/MIPS/ARM/ArmCompVFPUNEON.cpp | 6 ++---- Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp | 13 ++++++------- Core/MIPS/ARM/ArmJit.cpp | 3 ++- Core/MIPS/ARM/ArmRegCacheFPU.cpp | 12 ++++++------ Core/MIPS/ARM64/Arm64RegCacheFPU.cpp | 2 +- Core/MIPS/MIPS/MipsJit.cpp | 1 - Core/MIPS/MIPSTables.cpp | 1 - GPU/Common/VertexDecoderArm.cpp | 2 +- UI/ControlMappingScreen.cpp | 1 - UI/DisplayLayoutEditor.cpp | 1 + UI/EmuScreen.cpp | 6 +++--- UI/GameInfoCache.cpp | 2 +- UI/InstallZipScreen.cpp | 1 - UI/NativeApp.cpp | 4 +++- UI/TiltEventProcessor.cpp | 7 +++---- android/jni/OpenSLContext.cpp | 23 +++++++++++------------ 16 files changed, 40 insertions(+), 45 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp index 41961e944b..990e36e293 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp @@ -30,7 +30,6 @@ #include -#include "base/logging.h" #include "math/math_util.h" #include "Common/CPUDetect.h" @@ -55,8 +54,7 @@ // #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } #define CONDITIONAL_DISABLE(flag) if (jo.Disabled(JitDisable::flag)) { Comp_Generic(op); return; } #define DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } -#define DISABLE_UNKNOWN_PREFIX { WLOG("DISABLE: Unknown Prefix in %s", __FUNCTION__); fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } - +#define DISABLE_UNKNOWN_PREFIX { WARN_LOG(JIT, "DISABLE: Unknown Prefix in %s", __FUNCTION__); fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; } #define _RS MIPS_GET_RS(op) #define _RT MIPS_GET_RT(op) @@ -864,7 +862,7 @@ void ArmJit::CompNEON_Vmmul(MIPSOpcode op) { bool overlap = GetMatrixOverlap(_VD, _VS, msz) || GetMatrixOverlap(_VD, _VT, msz); if (overlap) { // Later. Fortunately, the VFPU also seems to prohibit overlap for matrix mul. - ILOG("Matrix overlap, ignoring."); + INFO_LOG(JIT, "Matrix overlap, ignoring."); DISABLE; } diff --git a/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp b/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp index 546c791a46..7fada69a92 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp @@ -30,7 +30,6 @@ #include -#include "base/logging.h" #include "math/math_util.h" #include "Common/CPUDetect.h" @@ -271,7 +270,7 @@ ArmJit::DestARMReg ArmJit::NEONMapPrefixD(int vreg, VectorSize sz, int mapFlags) dest.backingRd = dest.rd; } else { // Allocate a temporary register. - ELOG("PREFIXD: Write mask allocated! %i/%i", writeMask, full_mask); + ERROR_LOG(JIT, "PREFIXD: Write mask allocated! %i/%i", writeMask, full_mask); dest.rd = fpr.QAllocTemp(sz); dest.backingRd = fpr.QMapReg(vreg, sz, mapFlags & ~MAP_NOINIT); // Force initialization of the backing reg. } @@ -295,12 +294,12 @@ void ArmJit::NEONApplyPrefixD(DestARMReg dest) { if (sat1_mask && sat3_mask) { // Why would anyone do this? - ELOG("PREFIXD: Can't have both sat[0-1] and sat[-1-1] at the same time yet"); + ERROR_LOG(JIT, "PREFIXD: Can't have both sat[0-1] and sat[-1-1] at the same time yet"); } if (sat1_mask) { if (sat1_mask != full_mask) { - ELOG("PREFIXD: Can't have partial sat1 mask yet (%i vs %i)", sat1_mask, full_mask); + ERROR_LOG(JIT, "PREFIXD: Can't have partial sat1 mask yet (%i vs %i)", sat1_mask, full_mask); } if (IsD(dest.rd)) { VMOV_immf(D0, 0.0); @@ -317,7 +316,7 @@ void ArmJit::NEONApplyPrefixD(DestARMReg dest) { if (sat3_mask && sat1_mask != full_mask) { if (sat3_mask != full_mask) { - ELOG("PREFIXD: Can't have partial sat3 mask yet (%i vs %i)", sat3_mask, full_mask); + ERROR_LOG(JIT, "PREFIXD: Can't have partial sat3 mask yet (%i vs %i)", sat3_mask, full_mask); } if (IsD(dest.rd)) { VMOV_immf(D0, 0.0); @@ -341,11 +340,11 @@ void ArmJit::NEONApplyPrefixD(DestARMReg dest) { int writeMask = (~(js.prefixD >> 8)) & 0xF; if (writeMask == 3) { - ILOG("Doing writemask = 3"); + INFO_LOG(JIT, "Doing writemask = 3"); VMOV(D_0(dest.rd), D_0(dest.backingRd)); } else { // TODO - ELOG("PREFIXD: Arbitrary write masks not supported (%i / %i)", writeMask, full_mask); + ERROR_LOG(JIT, "PREFIXD: Arbitrary write masks not supported (%i / %i)", writeMask, full_mask); VMOV(dest.backingRd, dest.rd); } } diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 1ff3c29ee8..829307b419 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -18,8 +18,9 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM) -#include "base/logging.h" #include "profiler/profiler.h" + +#include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/MIPS/ARM/ArmRegCacheFPU.cpp b/Core/MIPS/ARM/ArmRegCacheFPU.cpp index a1378a67b3..21001b2b58 100644 --- a/Core/MIPS/ARM/ArmRegCacheFPU.cpp +++ b/Core/MIPS/ARM/ArmRegCacheFPU.cpp @@ -17,8 +17,8 @@ #include -#include "base/logging.h" #include "Common/CPUDetect.h" +#include "Common/Log.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/ARM/ArmRegCacheFPU.h" #include "Core/MIPS/ARM/ArmJit.h" @@ -463,13 +463,13 @@ void ArmRegCacheFPU::FlushAll() { if (ar[a].isDirty) { if (m == -1) { - ILOG("ARM reg %i is dirty but has no mipsreg", a); + INFO_LOG(JIT, "ARM reg %i is dirty but has no mipsreg", a); continue; } int c = FlushGetSequential(a, GetNumARMFPURegs()); if (c == 1) { - // ILOG("Got single register: %i (%i)", a, m); + // INFO_LOG(JIT, "Got single register: %i (%i)", a, m); emit_->VSTR((ARMReg)(a + S0), CTXREG, GetMipsRegOffset(m)); } else if (c == 2) { // Probably not worth using VSTMIA for two. @@ -477,9 +477,9 @@ void ArmRegCacheFPU::FlushAll() { emit_->VSTR((ARMReg)(a + S0), CTXREG, offset); emit_->VSTR((ARMReg)(a + 1 + S0), CTXREG, offset + 4); } else { - // ILOG("Got sequence: %i at %i (%i)", c, a, m); + // INFO_LOG(JIT, "Got sequence: %i at %i (%i)", c, a, m); emit_->ADDI2R(SCRATCHREG1, CTXREG, GetMipsRegOffset(m), SCRATCHREG2); - // ILOG("VSTMIA R0, %i, %i", a, c); + // INFO_LOG(JIT, "VSTMIA R0, %i, %i", a, c); emit_->VSTMIA(SCRATCHREG1, false, (ARMReg)(S0 + a), c); } @@ -908,7 +908,7 @@ ARMReg ArmRegCacheFPU::QMapReg(int vreg, VectorSize sz, int flags) { // We didn't find the extra register, but we got a list of regs to flush. Flush 'em. // Here we can check for opportunities to do a "transpose-flush" of row vectors, etc. if (!quadsToFlush.empty()) { - ILOG("New mapping %s collided with %i quads, flushing them.", GetVectorNotation(vreg, sz), (int)quadsToFlush.size()); + INFO_LOG(JIT, "New mapping %s collided with %d quads, flushing them.", GetVectorNotation(vreg, sz), (int)quadsToFlush.size()); } for (size_t i = 0; i < quadsToFlush.size(); i++) { QFlush(quadsToFlush[i]); diff --git a/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp b/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp index 3861fb44a1..ebb0d09494 100644 --- a/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp +++ b/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp @@ -400,7 +400,7 @@ void Arm64RegCacheFPU::FlushAll() { if (ar[a].isDirty) { if (m == -1) { - ILOG("ARM reg %i is dirty but has no mipsreg", a); + INFO_LOG(JIT, "ARM reg %i is dirty but has no mipsreg", a); continue; } diff --git a/Core/MIPS/MIPS/MipsJit.cpp b/Core/MIPS/MIPS/MipsJit.cpp index 345ff74018..0874282d50 100644 --- a/Core/MIPS/MIPS/MipsJit.cpp +++ b/Core/MIPS/MIPS/MipsJit.cpp @@ -18,7 +18,6 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(MIPS) -#include "base/logging.h" #include "profiler/profiler.h" #include "Common/Serialize/Serializer.h" #include "Core/Reporting.h" diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index d958c4cd2a..2270fc3630 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -28,7 +28,6 @@ #include "Core/CoreTiming.h" #include "Core/Reporting.h" #include "Core/Debugger/Breakpoints.h" -#include "base/logging.h" #include "JitCommon/JitCommon.h" diff --git a/GPU/Common/VertexDecoderArm.cpp b/GPU/Common/VertexDecoderArm.cpp index 5f9dd3371a..0feb2df100 100644 --- a/GPU/Common/VertexDecoderArm.cpp +++ b/GPU/Common/VertexDecoderArm.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "ppsspp_config.h" + #if PPSSPP_ARCH(ARM) // This allows highlighting to work. Yay. @@ -25,7 +26,6 @@ #include -#include "base/logging.h" #include "Common/CPUDetect.h" #include "Core/Config.h" #include "Core/Reporting.h" diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 2008c19f50..3d711eda2f 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -20,7 +20,6 @@ #include #include "base/colorutil.h" -#include "base/logging.h" #include "base/display.h" #include "gfx/texture_atlas.h" #include "i18n/i18n.h" diff --git a/UI/DisplayLayoutEditor.cpp b/UI/DisplayLayoutEditor.cpp index 77da5f407e..6c3e6e1f5a 100644 --- a/UI/DisplayLayoutEditor.cpp +++ b/UI/DisplayLayoutEditor.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + #include "ui/ui_context.h" #include "UI/DisplayLayoutEditor.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 59f5abed66..1d44551622 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -20,7 +20,6 @@ #include #include "base/display.h" -#include "base/logging.h" #include "base/timeutil.h" #include "profiler/profiler.h" @@ -38,6 +37,7 @@ #include "i18n/i18n.h" #include "Common/KeyMap.h" +#include "Common/Log.h" #ifndef MOBILE_DEVICE #include "Core/AVIDump.h" @@ -404,7 +404,7 @@ void EmuScreen::sendMessage(const char *message, const char *value) { std::string resetError; if (!PSP_InitStart(PSP_CoreParameter(), &resetError)) { - ELOG("Error resetting: %s", resetError.c_str()); + ERROR_LOG(LOADER, "Error resetting: %s", resetError.c_str()); stopRender_ = true; screenManager()->switchScreen(new MainScreen()); System_SendMessage("event", "failstartgame"); @@ -856,7 +856,7 @@ void EmuScreen::pspKey(int pspKeyCode, int flags) { onVKeyUp(pspKeyCode); } } else { - // ILOG("pspKey %i %i", pspKeyCode, flags); + // INFO_LOG(SYSTEM, "pspKey %i %i", pspKeyCode, flags); if (flags & KEY_DOWN) __CtrlButtonDown(pspKeyCode); if (flags & KEY_UP) diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 4b1746fb2b..1fa929f5a4 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -22,13 +22,13 @@ #include #include -#include "base/logging.h" #include "base/timeutil.h" #include "base/stringutil.h" #include "file/file_util.h" #include "file/zip_read.h" #include "thin3d/thin3d.h" #include "thread/prioritizedworkqueue.h" + #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Core/FileSystems/ISOFileSystem.h" diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index 873ddaf0c5..3a586b776b 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" #include "i18n/i18n.h" #include "ui/ui.h" #include "ui/view.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 3db216d802..919d7ce2f6 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -44,7 +44,9 @@ #endif #include "base/display.h" -#include "base/logging.h" + +#include "base/logging.h" // For "AndroidLogger". TODO: Remove. + #include "base/stringutil.h" #include "base/timeutil.h" #include "base/NativeApp.h" diff --git a/UI/TiltEventProcessor.cpp b/UI/TiltEventProcessor.cpp index 97b5bcd90a..2f66906239 100644 --- a/UI/TiltEventProcessor.cpp +++ b/UI/TiltEventProcessor.cpp @@ -1,11 +1,10 @@ #define _USE_MATH_DEFINES + #include -#include "UI/TiltEventProcessor.h" + #include "Core/Config.h" #include "Core/HLE/sceCtrl.h" -#include "math.h" -#include "base/logging.h" - +#include "UI/TiltEventProcessor.h" using namespace TiltEventProcessor; diff --git a/android/jni/OpenSLContext.cpp b/android/jni/OpenSLContext.cpp index 26965a72d5..77ccfde2eb 100644 --- a/android/jni/OpenSLContext.cpp +++ b/android/jni/OpenSLContext.cpp @@ -9,7 +9,6 @@ #include #include -#include "base/logging.h" #include "Common/Log.h" #include "OpenSLContext.h" @@ -24,7 +23,7 @@ void OpenSLContext::bqPlayerCallbackWrap(SLAndroidSimpleBufferQueueItf bq, void void OpenSLContext::BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq) { if (bq != bqPlayerBufferQueue) { - ELOG("OpenSL: Wrong bq!"); + ERROR_LOG(AUDIO, "OpenSL: Wrong bq!"); return; } @@ -41,7 +40,7 @@ void OpenSLContext::BqPlayerCallback(SLAndroidSimpleBufferQueueItf bq) { // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, // which for this code example would indicate a programming error if (result != SL_RESULT_SUCCESS) { - ELOG("OpenSL: Failed to enqueue! %i %i", renderedFrames, sizeInBytes); + ERROR_LOG(AUDIO, "OpenSL: Failed to enqueue! %i %i", renderedFrames, sizeInBytes); } curBuffer += 1; // Switch buffer @@ -58,7 +57,7 @@ bool OpenSLContext::Init() { // create engine result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); if (result != SL_RESULT_SUCCESS) { - ELOG("OpenSL: Failed to create the engine: %d", (int)result); + ERROR_LOG(AUDIO, "OpenSL: Failed to create the engine: %d", (int)result); engineObject = nullptr; return false; } @@ -70,7 +69,7 @@ bool OpenSLContext::Init() { result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0); if (result != SL_RESULT_SUCCESS) { - ELOG("OpenSL: Failed to create output mix: %d", (int)result); + ERROR_LOG(AUDIO, "OpenSL: Failed to create output mix: %d", (int)result); (*engineObject)->Destroy(engineObject); engineEngine = nullptr; engineObject = nullptr; @@ -104,7 +103,7 @@ bool OpenSLContext::Init() { const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req); if (result != SL_RESULT_SUCCESS) { - ELOG("OpenSL: CreateAudioPlayer failed: %d", (int)result); + ERROR_LOG(AUDIO, "OpenSL: CreateAudioPlayer failed: %d", (int)result); (*outputMixObject)->Destroy(outputMixObject); outputMixObject = nullptr; @@ -149,15 +148,15 @@ bool OpenSLContext::Init() { // shut down the native audio system OpenSLContext::~OpenSLContext() { if (bqPlayerPlay) { - ILOG("OpenSL: Shutdown - stopping playback"); + INFO_LOG(AUDIO, "OpenSL: Shutdown - stopping playback"); SLresult result; result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED); if (SL_RESULT_SUCCESS != result) { - ELOG("SetPlayState failed"); + ERROR_LOG(AUDIO, "SetPlayState failed"); } } - ILOG("OpenSL: Shutdown - deleting player object"); + INFO_LOG(AUDIO, "OpenSL: Shutdown - deleting player object"); if (bqPlayerObject) { (*bqPlayerObject)->Destroy(bqPlayerObject); @@ -167,14 +166,14 @@ OpenSLContext::~OpenSLContext() { bqPlayerVolume = nullptr; } - ILOG("OpenSL: Shutdown - deleting mix object"); + INFO_LOG(AUDIO, "OpenSL: Shutdown - deleting mix object"); if (outputMixObject) { (*outputMixObject)->Destroy(outputMixObject); outputMixObject = nullptr; } - ILOG("OpenSL: Shutdown - deleting engine object"); + INFO_LOG(AUDIO, "OpenSL: Shutdown - deleting engine object"); if (engineObject) { (*engineObject)->Destroy(engineObject); @@ -186,6 +185,6 @@ OpenSLContext::~OpenSLContext() { delete[] buffer[i]; buffer[i] = nullptr; } - ILOG("OpenSL: Shutdown - finished"); + INFO_LOG(AUDIO, "OpenSL: Shutdown - finished"); } From bf72f746ea714ba48c2e211184b732c80efa05cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 15:40:35 +0200 Subject: [PATCH 500/848] Remove base/logging.h from a whole bunch of files in native --- ext/native/data/compression.cpp | 8 +++---- ext/native/file/chunk_file.cpp | 1 - ext/native/file/fd_util.cpp | 12 +++++----- ext/native/file/file_util.cpp | 1 - ext/native/file/ini_file.cpp | 1 - ext/native/file/zip_read.cpp | 21 +++++++++-------- ext/native/gfx/gl_debug_log.cpp | 5 ++-- ext/native/gfx/texture_atlas.cpp | 2 +- ext/native/gfx_es2/draw_buffer.cpp | 10 ++++---- ext/native/gfx_es2/draw_text.cpp | 1 - ext/native/gfx_es2/draw_text_android.cpp | 20 ++++++++-------- ext/native/gfx_es2/draw_text_qt.cpp | 9 ++++---- ext/native/gfx_es2/draw_text_uwp.cpp | 5 +--- ext/native/gfx_es2/draw_text_win.cpp | 7 +++--- ext/native/gfx_es2/glsl_program.cpp | 29 ++++++++++++------------ ext/native/gfx_es2/gpu_features.cpp | 25 ++++++++++---------- ext/native/i18n/i18n.cpp | 9 ++++---- ext/native/image/png_load.cpp | 17 +++++++------- ext/native/image/zim_load.cpp | 19 ++++++++-------- ext/native/image/zim_save.cpp | 14 +++++++----- 20 files changed, 105 insertions(+), 111 deletions(-) diff --git a/ext/native/data/compression.cpp b/ext/native/data/compression.cpp index f2bc6494ee..751a9595cf 100644 --- a/ext/native/data/compression.cpp +++ b/ext/native/data/compression.cpp @@ -11,7 +11,7 @@ #include -#include "base/logging.h" +#include "Common/Log.h" /** Compress a STL string using zlib with given compression level and return * the binary data. */ @@ -20,7 +20,7 @@ bool compress_string(const std::string& str, std::string *dest, int compressionl memset(&zs, 0, sizeof(zs)); if (deflateInit(&zs, compressionlevel) != Z_OK) { - ELOG("deflateInit failed while compressing."); + ERROR_LOG(IO, "deflateInit failed while compressing."); return false; } @@ -67,7 +67,7 @@ bool decompress_string(const std::string& str, std::string *dest) { // modification by hrydgard: inflateInit2, 16+MAXWBITS makes it read gzip data too if (inflateInit2(&zs, 32+MAX_WBITS) != Z_OK) { - ELOG("inflateInit failed while decompressing."); + ERROR_LOG(IO, "inflateInit failed while decompressing."); return false; } @@ -96,7 +96,7 @@ bool decompress_string(const std::string& str, std::string *dest) { if (ret != Z_STREAM_END) { // an error occurred that was not EOF std::ostringstream oss; - ELOG("Exception during zlib decompression: (%i) %s", ret, zs.msg); + ERROR_LOG(IO, "Exception during zlib decompression: (%i) %s", ret, zs.msg); return false; } diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index 0804040038..20553a8657 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -1,4 +1,3 @@ -#include "base/logging.h" #include "file/chunk_file.h" #include "file/zip_read.h" #include "file/file_util.h" diff --git a/ext/native/file/fd_util.cpp b/ext/native/file/fd_util.cpp index 38a84f0f22..1b47c215fc 100644 --- a/ext/native/file/fd_util.cpp +++ b/ext/native/file/fd_util.cpp @@ -18,7 +18,7 @@ #endif #include -#include "base/logging.h" +#include "Common/Log.h" namespace fd_util { @@ -45,7 +45,7 @@ ssize_t ReadLine(int fd, char *vptr, size_t buf_size) { else { if (errno == EINTR) continue; - FLOG("Error in Readline()"); + _assert_msg_(false, "Error in Readline()"); } } @@ -64,7 +64,7 @@ ssize_t WriteLine(int fd, const char *vptr, size_t n) { if (errno == EINTR) nwritten = 0; else - FLOG("Error in Writeline()"); + _assert_msg_(false, "Error in Writeline()"); } nleft -= nwritten; buffer += nwritten; @@ -113,7 +113,7 @@ void SetNonBlocking(int sock, bool non_blocking) { int opts = fcntl(sock, F_GETFL); if (opts < 0) { perror("fcntl(F_GETFL)"); - ELOG("Error getting socket status while changing nonblocking status"); + ERROR_LOG(IO, "Error getting socket status while changing nonblocking status"); } if (non_blocking) { opts = (opts | O_NONBLOCK); @@ -123,12 +123,12 @@ void SetNonBlocking(int sock, bool non_blocking) { if (fcntl(sock, F_SETFL, opts) < 0) { perror("fcntl(F_SETFL)"); - ELOG("Error setting socket nonblocking status"); + ERROR_LOG(IO, "Error setting socket nonblocking status"); } #else u_long val = non_blocking ? 1 : 0; if (ioctlsocket(sock, FIONBIO, &val) != 0) { - ELOG("Error setting socket nonblocking status"); + ERROR_LOG(IO, "Error setting socket nonblocking status"); } #endif } diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index d95dcef311..7206c36e3c 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -18,7 +18,6 @@ #include #include -#include "base/logging.h" #include "base/basictypes.h" #include "base/stringutil.h" #include "file/file_util.h" diff --git a/ext/native/file/ini_file.cpp b/ext/native/file/ini_file.cpp index 1e4beadaeb..c4c1b7934e 100644 --- a/ext/native/file/ini_file.cpp +++ b/ext/native/file/ini_file.cpp @@ -16,7 +16,6 @@ #include #include -#include "base/logging.h" #include "base/stringutil.h" #include "file/ini_file.h" #include "file/vfs.h" diff --git a/ext/native/file/zip_read.cpp b/ext/native/file/zip_read.cpp index 8c12860246..b6e997877b 100644 --- a/ext/native/file/zip_read.cpp +++ b/ext/native/file/zip_read.cpp @@ -8,16 +8,17 @@ #endif #include "base/basictypes.h" -#include "base/logging.h" #include "file/zip_read.h" +#include "Common/Log.h" + #ifdef __ANDROID__ uint8_t *ReadFromZip(zip *archive, const char* filename, size_t *size) { // Figure out the file size first. struct zip_stat zstat; zip_file *file = zip_fopen(archive, filename, ZIP_FL_NOCASE|ZIP_FL_UNCHANGED); if (!file) { - ELOG("Error opening %s from ZIP", filename); + ERROR_LOG(IO, "Error opening %s from ZIP", filename); return 0; } zip_stat(archive, filename, ZIP_FL_NOCASE|ZIP_FL_UNCHANGED, &zstat); @@ -67,16 +68,16 @@ ZipAssetReader::ZipAssetReader(const char *zip_file, const char *in_zip_path) { zip_file_ = zip_open(zip_file, 0, NULL); strcpy(in_zip_path_, in_zip_path); if (!zip_file_) { - ELOG("Failed to open %s as a zip file", zip_file); + ERROR_LOG(IO, "Failed to open %s as a zip file", zip_file); } std::vector info; GetFileListing("assets", &info, 0); for (size_t i = 0; i < info.size(); i++) { if (info[i].isDirectory) { - DLOG("Directory: %s", info[i].name.c_str()); + DEBUG_LOG(IO, "Directory: %s", info[i].name.c_str()); } else { - DLOG("File: %s", info[i].name.c_str()); + DEBUG_LOG(IO, "File: %s", info[i].name.c_str()); } } } @@ -264,7 +265,7 @@ static int num_entries = 0; void VFSRegister(const char *prefix, AssetReader *reader) { entries[num_entries].prefix = prefix; entries[num_entries].reader = reader; - DLOG("Registered VFS for prefix %s: %s", prefix, reader->toString().c_str()); + DEBUG_LOG(IO, "Registered VFS for prefix %s: %s", prefix, reader->toString().c_str()); num_entries++; } @@ -289,7 +290,7 @@ static bool IsLocalPath(const char *path) { uint8_t *VFSReadFile(const char *filename, size_t *size) { if (IsLocalPath(filename)) { // Local path, not VFS. - // ILOG("Not a VFS path: %s . Reading local file.", filename); + // INFO_LOG(IO, "Not a VFS path: %s . Reading local file.", filename); return ReadLocalFile(filename, size); } @@ -310,7 +311,7 @@ uint8_t *VFSReadFile(const char *filename, size_t *size) { } } if (!fileSystemFound) { - ELOG("Missing filesystem for '%s'", filename); + ERROR_LOG(IO, "Missing filesystem for '%s'", filename); } // Otherwise, the file was just missing. No need to log. return 0; } @@ -337,7 +338,7 @@ bool VFSGetFileListing(const char *path, std::vector *listing, const c } if (!fileSystemFound) { - ELOG("Missing filesystem for %s", path); + ERROR_LOG(IO, "Missing filesystem for %s", path); } // Otherwise, the file was just missing. No need to log. return false; } @@ -363,7 +364,7 @@ bool VFSGetFileInfo(const char *path, FileInfo *info) { } } if (!fileSystemFound) { - ELOG("Missing filesystem for %s", path); + ERROR_LOG(IO, "Missing filesystem for %s", path); } // Otherwise, the file was just missing. No need to log. return false; } diff --git a/ext/native/gfx/gl_debug_log.cpp b/ext/native/gfx/gl_debug_log.cpp index e72e286e7f..078b4ed843 100644 --- a/ext/native/gfx/gl_debug_log.cpp +++ b/ext/native/gfx/gl_debug_log.cpp @@ -1,9 +1,10 @@ #include -#include "base/logging.h" #include "gfx/gl_common.h" #include "gfx/gl_debug_log.h" +#include "Common/Log.h" + // This we can expand as needed. std::string GLEnumToString(uint16_t value) { char str[64]; @@ -36,6 +37,6 @@ std::string GLEnumToString(uint16_t value) { void CheckGLError(const char *file, int line) { GLenum err = glGetError(); if (err != GL_NO_ERROR) { - ELOG("GL error %s on %s:%d", GLEnumToString(err).c_str(), file, line); + ERROR_LOG(G3D, "GL error %s on %s:%d", GLEnumToString(err).c_str(), file, line); } } diff --git a/ext/native/gfx/texture_atlas.cpp b/ext/native/gfx/texture_atlas.cpp index 1622b3a42b..a38a791fa3 100644 --- a/ext/native/gfx/texture_atlas.cpp +++ b/ext/native/gfx/texture_atlas.cpp @@ -1,6 +1,6 @@ #include #include -#include "base/logging.h" + #include "gfx/texture_atlas.h" class ByteReader { diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index 94e5f28ae8..da23c142cb 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -4,7 +4,6 @@ #include #include "base/display.h" -#include "base/logging.h" #include "base/stringutil.h" #include "math/math_util.h" #include "gfx/texture_atlas.h" @@ -14,6 +13,8 @@ #include "util/text/utf8.h" #include "util/text/wrap_text.h" +#include "Common/Log.h" + enum { // Enough? MAX_VERTS = 65536, @@ -85,7 +86,7 @@ void DrawBuffer::Flush(bool set_blend_state) { if (count_ == 0) return; if (!pipeline_) { - ELOG("DrawBuffer: No program set, skipping flush!"); + ERROR_LOG(G3D, "DrawBuffer: No program set, skipping flush!"); count_ = 0; return; } @@ -106,10 +107,7 @@ void DrawBuffer::Flush(bool set_blend_state) { } void DrawBuffer::V(float x, float y, float z, uint32_t color, float u, float v) { - if (count_ >= MAX_VERTS) { - FLOG("Overflowed the DrawBuffer"); - return; - } + _assert_msg_(count_ < MAX_VERTS, "Overflowed the DrawBuffer"); Vertex *vert = &verts_[count_++]; vert->x = x; diff --git a/ext/native/gfx_es2/draw_text.cpp b/ext/native/gfx_es2/draw_text.cpp index 4463bdbb55..a205fbca61 100644 --- a/ext/native/gfx_es2/draw_text.cpp +++ b/ext/native/gfx_es2/draw_text.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/logging.h" #include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index 608d0cfa0d..91298f6de4 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/logging.h" #include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" @@ -9,7 +8,8 @@ #include "gfx_es2/draw_text_android.h" #include "android/jni/app-android.h" -#include + +#include "Common/Log.h" #if PPSSPP_PLATFORM(ANDROID) && !defined(__LIBRETRO__) @@ -24,10 +24,10 @@ TextDrawerAndroid::TextDrawerAndroid(Draw::DrawContext *draw) : TextDrawer(draw) method_measureText = env->GetStaticMethodID(cls_textRenderer, "measureText", "(Ljava/lang/String;D)I"); method_renderText = env->GetStaticMethodID(cls_textRenderer, "renderText", "(Ljava/lang/String;D)[I"); } else { - ELOG("Failed to find class: '%s'", textRendererClassName); + ERROR_LOG(G3D, "Failed to find class: '%s'", textRendererClassName); } dpiScale_ = CalculateDPIScale(); - ILOG("Initializing TextDrawerAndroid with DPI scale %f", dpiScale_); + INFO_LOG(G3D, "Initializing TextDrawerAndroid with DPI scale %f", dpiScale_); } TextDrawerAndroid::~TextDrawerAndroid() { @@ -68,7 +68,7 @@ void TextDrawerAndroid::SetFont(uint32_t fontHandle) { if (iter != fontMap_.end()) { fontHash_ = fontHandle; } else { - ELOG("Invalid font handle %08x", fontHandle); + ERROR_LOG(G3D, "Invalid font handle %08x", fontHandle); } } @@ -88,7 +88,7 @@ void TextDrawerAndroid::MeasureString(const char *str, size_t len, float *w, flo if (iter != fontMap_.end()) { scaledSize = iter->second.size; } else { - ELOG("Missing font"); + ERROR_LOG(G3D, "Missing font"); } std::string text(NormalizeString(std::string(str, len))); auto env = getEnv(); @@ -112,7 +112,7 @@ void TextDrawerAndroid::MeasureStringRect(const char *str, size_t len, const Bou if (iter != fontMap_.end()) { scaledSize = iter->second.size; } else { - ELOG("Missing font"); + ERROR_LOG(G3D, "Missing font"); } std::string toMeasure = std::string(str, len); @@ -168,7 +168,7 @@ void TextDrawerAndroid::DrawStringBitmap(std::vector &bitmapData, TextS if (iter != fontMap_.end()) { size = iter->second.size; } else { - ELOG("Missing font"); + ERROR_LOG(G3D, "Missing font"); } auto env = getEnv(); @@ -213,7 +213,7 @@ void TextDrawerAndroid::DrawStringBitmap(std::vector &bitmapData, TextS } } } else { - ELOG("Bad TextDrawer format"); + ERROR_LOG(G3D, "Bad TextDrawer format"); assert(false); } env->ReleaseIntArrayElements(imageData, jimage, 0); @@ -285,7 +285,7 @@ void TextDrawerAndroid::OncePerFrame() { float newDpiScale = CalculateDPIScale(); if (newDpiScale != dpiScale_) { // TODO: Don't bother if it's a no-op (cache already empty) - ILOG("DPI Scale changed (%f to %f) - wiping font cache (%d items, %d fonts)", dpiScale_, newDpiScale, (int)cache_.size(), (int)fontMap_.size()); + INFO_LOG(G3D, "DPI Scale changed (%f to %f) - wiping font cache (%d items, %d fonts)", dpiScale_, newDpiScale, (int)cache_.size(), (int)fontMap_.size()); dpiScale_ = newDpiScale; ClearCache(); fontMap_.clear(); // size is precomputed using dpiScale_. diff --git a/ext/native/gfx_es2/draw_text_qt.cpp b/ext/native/gfx_es2/draw_text_qt.cpp index 6589bf0743..12929e25cf 100644 --- a/ext/native/gfx_es2/draw_text_qt.cpp +++ b/ext/native/gfx_es2/draw_text_qt.cpp @@ -1,6 +1,4 @@ -#include #include "base/display.h" -#include "base/logging.h" #include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" @@ -9,6 +7,8 @@ #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_text_qt.h" +#include "Common/Log.h" + #if defined(USING_QT_UI) #include @@ -47,7 +47,7 @@ void TextDrawerQt::SetFont(uint32_t fontHandle) { if (iter != fontMap_.end()) { fontHash_ = fontHandle; } else { - ELOG("Invalid font handle %08x", fontHandle); + ERROR_LOG(G3D, "Invalid font handle %08x", fontHandle); } } @@ -134,8 +134,7 @@ void TextDrawerQt::DrawStringBitmap(std::vector &bitmapData, TextString } } } else { - ELOG("Bad TextDrawer format"); - assert(false); + _assert_msg_("Bad TextDrawer format"); } } diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index a78240b227..a8c67d211b 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -1,6 +1,4 @@ -#include #include "base/display.h" -#include "base/logging.h" #include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" @@ -425,8 +423,7 @@ void TextDrawerUWP::DrawStringBitmap(std::vector &bitmapData, TextStrin } } } else { - ELOG("Bad TextDrawer format"); - assert(false); + _assert_msg_(false, "Bad TextDrawer format"); } ctx_->mirror_bmp->Unmap(); diff --git a/ext/native/gfx_es2/draw_text_win.cpp b/ext/native/gfx_es2/draw_text_win.cpp index 2570236feb..1d08616131 100644 --- a/ext/native/gfx_es2/draw_text_win.cpp +++ b/ext/native/gfx_es2/draw_text_win.cpp @@ -1,6 +1,4 @@ -#include #include "base/display.h" -#include "base/logging.h" #include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" @@ -9,6 +7,8 @@ #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_text_win.h" +#include "Common/Log.h" + #if defined(_WIN32) && !defined(USING_QT_UI) && !PPSSPP_PLATFORM(UWP) #define WIN32_LEAN_AND_MEAN @@ -286,8 +286,7 @@ void TextDrawerWin32::DrawStringBitmap(std::vector &bitmapData, TextStr } } } else { - ELOG("Bad TextDrawer format"); - assert(false); + _assert_msg_(false, "Bad TextDrawer format"); } } diff --git a/ext/native/gfx_es2/glsl_program.cpp b/ext/native/gfx_es2/glsl_program.cpp index 91ced3dad2..3400b381b3 100644 --- a/ext/native/gfx_es2/glsl_program.cpp +++ b/ext/native/gfx_es2/glsl_program.cpp @@ -4,11 +4,12 @@ #include #include -#include "base/logging.h" #include "file/vfs.h" #include "file/zip_read.h" #include "glsl_program.h" +#include "Common/Log.h" + static std::set active_programs; bool CompileShader(const char *source, GLuint shader, const char *filename, std::string *error_message) { @@ -22,9 +23,9 @@ bool CompileShader(const char *source, GLuint shader, const char *filename, std: GLsizei len; glGetShaderInfoLog(shader, MAX_INFO_LOG_SIZE, &len, infoLog); infoLog[len] = '\0'; - ELOG("Error in shader compilation of %s!\n", filename); - ELOG("Info log: %s\n", infoLog); - ELOG("Shader source:\n%s\n", (const char *)source); + ERROR_LOG(G3D, "Error in shader compilation of %s!\n", filename); + ERROR_LOG(G3D, "Info log: %s\n", infoLog); + ERROR_LOG(G3D, "Shader source:\n%s\n", (const char *)source); if (error_message) *error_message = infoLog; return false; @@ -45,7 +46,7 @@ GLSLProgram *glsl_create(const char *vshader, const char *fshader, std::string * if (glsl_recompile(program, error_message)) { active_programs.insert(program); } else { - ELOG("Failed compiling GLSL program: %s %s", vshader, fshader); + ERROR_LOG(G3D, "Failed compiling GLSL program: %s %s", vshader, fshader); delete program; return 0; } @@ -65,7 +66,7 @@ GLSLProgram *glsl_create_source(const char *vshader_src, const char *fshader_src if (glsl_recompile(program, error_message)) { active_programs.insert(program); } else { - ELOG("Failed compiling GLSL program from source strings"); + ERROR_LOG(G3D, "Failed compiling GLSL program from source strings"); delete program; return 0; } @@ -124,7 +125,7 @@ bool glsl_recompile(GLSLProgram *program, std::string *error_message) { vsh_src.reset((char *)VFSReadFile(program->vshader_filename, &sz)); } if (!program->vshader_source && !vsh_src) { - ELOG("File missing: %s", program->vshader_filename); + ERROR_LOG(G3D, "File missing: %s", program->vshader_filename); if (error_message) { *error_message = std::string("File missing: ") + program->vshader_filename; } @@ -135,7 +136,7 @@ bool glsl_recompile(GLSLProgram *program, std::string *error_message) { fsh_src.reset((char *)VFSReadFile(program->fshader_filename, &sz)); } if (!program->fshader_source && !fsh_src) { - ELOG("File missing: %s", program->fshader_filename); + ERROR_LOG(G3D, "File missing: %s", program->fshader_filename); if (error_message) { *error_message = std::string("File missing: ") + program->fshader_filename; } @@ -169,15 +170,15 @@ bool glsl_recompile(GLSLProgram *program, std::string *error_message) { if (bufLength) { char* buf = new char[bufLength + 1]; // safety glGetProgramInfoLog(prog, bufLength, NULL, buf); - ILOG("vsh: %i fsh: %i", vsh, fsh); - ELOG("Could not link shader program (linkstatus=%i):\n %s \n", linkStatus, buf); + INFO_LOG(G3D, "vsh: %i fsh: %i", vsh, fsh); + ERROR_LOG(G3D, "Could not link shader program (linkstatus=%i):\n %s \n", linkStatus, buf); if (error_message) { *error_message = buf; } delete [] buf; } else { - ILOG("vsh: %i fsh: %i", vsh, fsh); - ELOG("Could not link shader program (linkstatus=%i). No OpenGL error log was available.", linkStatus); + INFO_LOG(G3D, "vsh: %i fsh: %i", vsh, fsh); + ERROR_LOG(G3D, "Could not link shader program (linkstatus=%i). No OpenGL error log was available.", linkStatus); if (error_message) { *error_message = "(no error message available)"; } @@ -212,7 +213,7 @@ bool glsl_recompile(GLSLProgram *program, std::string *error_message) { program->u_sundir = glGetUniformLocation(program->program_, "u_sundir"); program->u_camerapos = glGetUniformLocation(program->program_, "u_camerapos"); - //ILOG("Shader compilation success: %s %s", + //INFO_LOG(G3D, "Shader compilation success: %s %s", // program->vshader_filename, // program->fshader_filename); return true; @@ -233,7 +234,7 @@ void glsl_destroy(GLSLProgram *program) { glDeleteProgram(program->program_); active_programs.erase(program); } else { - ELOG("Deleting null GLSL program!"); + ERROR_LOG(G3D, "Deleting null GLSL program!"); } delete program; } diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index e22b702e21..930a489aae 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -3,7 +3,6 @@ #include #include -#include "base/logging.h" #include "base/stringutil.h" #if PPSSPP_API(ANY_GL) @@ -16,6 +15,7 @@ #include "gfx_es2/gpu_features.h" +#include "Common/Log.h" #if defined(USING_GLES2) #if defined(__ANDROID__) @@ -96,7 +96,7 @@ int GLExtensions::GLSLVersion() { void ProcessGPUFeatures() { gl_extensions.bugs = 0; - DLOG("Checking for GL driver bugs... vendor=%i model='%s'", (int)gl_extensions.gpuVendor, gl_extensions.model); + DEBUG_LOG(G3D, "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 545") || @@ -106,11 +106,11 @@ void ProcessGPUFeatures() { !strcmp(gl_extensions.model, "PowerVR SGX 540") || !strcmp(gl_extensions.model, "PowerVR SGX 530") || !strcmp(gl_extensions.model, "PowerVR SGX 520") ) { - WLOG("GL DRIVER BUG: PVR with bad and terrible precision"); + WARN_LOG(G3D, "GL DRIVER BUG: PVR with bad and terrible precision"); gl_extensions.bugs |= BUG_PVR_SHADER_PRECISION_TERRIBLE | BUG_PVR_SHADER_PRECISION_BAD; } else { // TODO: I'm not sure if the Rogue series is affected by this. - WLOG("GL DRIVER BUG: PVR with bad precision"); + WARN_LOG(G3D, "GL DRIVER BUG: PVR with bad precision"); gl_extensions.bugs |= BUG_PVR_SHADER_PRECISION_BAD; } } @@ -172,7 +172,7 @@ void CheckGLExtensions() { gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN; } - ILOG("GPU Vendor : %s ; renderer: %s version str: %s ; GLSL version str: %s", cvendor, renderer ? renderer : "N/A", versionStr ? versionStr : "N/A", glslVersionStr ? glslVersionStr : "N/A"); + INFO_LOG(G3D, "GPU Vendor : %s ; renderer: %s version str: %s ; GLSL version str: %s", cvendor, renderer ? renderer : "N/A", versionStr ? versionStr : "N/A", glslVersionStr ? glslVersionStr : "N/A"); if (renderer) { strncpy(gl_extensions.model, renderer, sizeof(gl_extensions.model)); @@ -245,7 +245,7 @@ void CheckGLExtensions() { gl_extensions.ver[1] = 0; } else if (parsed[0] && (gl_extensions.ver[0] != parsed[0] || gl_extensions.ver[1] != parsed[1])) { // Something going wrong. Possible bug in GL ES drivers. See #9688 - ILOG("GL ES version mismatch. Version string '%s' parsed as %d.%d but API return %d.%d. Fallback to GL ES 2.0.", + INFO_LOG(G3D, "GL ES version mismatch. Version string '%s' parsed as %d.%d but API return %d.%d. Fallback to GL ES 2.0.", versionStr ? versionStr : "N/A", parsed[0], parsed[1], gl_extensions.ver[0], gl_extensions.ver[1]); gl_extensions.ver[0] = 2; @@ -289,9 +289,9 @@ void CheckGLExtensions() { if (gl_extensions.GLES3) { if (gl_extensions.ver[1] >= 1) { - ILOG("OpenGL ES 3.1 support detected!\n"); + INFO_LOG(G3D, "OpenGL ES 3.1 support detected!\n"); } else { - ILOG("OpenGL ES 3.0 support detected!\n"); + INFO_LOG(G3D, "OpenGL ES 3.0 support detected!\n"); } } } @@ -376,7 +376,7 @@ void CheckGLExtensions() { #ifdef _DEBUG void *invalidAddress = (void *)eglGetProcAddress("InvalidGlCall1"); void *invalidAddress2 = (void *)eglGetProcAddress("AnotherInvalidGlCall2"); - DLOG("Addresses returned for invalid extensions: %p %p", invalidAddress, invalidAddress2); + DEBUG_LOG(G3D, "Addresses returned for invalid extensions: %p %p", invalidAddress, invalidAddress2); #endif // These are all the same. Let's alias. @@ -473,7 +473,7 @@ void CheckGLExtensions() { // Now, Adreno lies. So let's override it. if (gl_extensions.gpuVendor == GPU_VENDOR_QUALCOMM) { - WLOG("Detected Adreno - lowering int precision"); + WARN_LOG(G3D, "Detected Adreno - lowering int precision"); gl_extensions.range[1][5][0] = 15; gl_extensions.range[1][5][1] = 15; } @@ -549,15 +549,14 @@ void CheckGLExtensions() { int error = glGetError(); if (error) - ELOG("GL error in init: %i", error); + ERROR_LOG(G3D, "GL error in init: %i", error); #endif } void SetGLCoreContext(bool flag) { - if (extensionsDone) - FLOG("SetGLCoreContext() after CheckGLExtensions()"); + _assert_msg_(!extensionsDone, "SetGLCoreContext() after CheckGLExtensions()"); useCoreContext = flag; // For convenience, it'll get reset later. diff --git a/ext/native/i18n/i18n.cpp b/ext/native/i18n/i18n.cpp index 2b0aa77f8d..bbafbd9534 100644 --- a/ext/native/i18n/i18n.cpp +++ b/ext/native/i18n/i18n.cpp @@ -1,4 +1,3 @@ -#include "base/logging.h" #include "base/stringutil.h" #include "i18n/i18n.h" #include "file/ini_file.h" @@ -32,7 +31,7 @@ const char *I18NCategory::T(const char *key, const char *def) { auto iter = map_.find(modifiedKey); if (iter != map_.end()) { -// ILOG("translation key found in %s: %s", name_.c_str(), key); +// INFO_LOG(SYSTEM, "translation key found in %s: %s", name_.c_str(), key); return iter->second.text.c_str(); } else { std::lock_guard guard(missedKeyLock_); @@ -40,7 +39,7 @@ const char *I18NCategory::T(const char *key, const char *def) { missedKeyLog_[key] = def; else missedKeyLog_[key] = modifiedKey.c_str(); -// ILOG("Missed translation key in %s: %s", name_.c_str(), key); +// INFO_LOG(SYSTEM, "Missed translation key in %s: %s", name_.c_str(), key); return def ? def : key; } } @@ -50,7 +49,7 @@ void I18NCategory::SetMap(const std::map &m) { if (map_.find(iter->first) == map_.end()) { std::string text = ReplaceAll(iter->second, "\\n", "\n"); map_[iter->first] = I18NEntry(text); -// ILOG("Language entry: %s -> %s", iter->first.c_str(), text.c_str()); +// INFO_LOG(SYSTEM, "Language entry: %s -> %s", iter->first.c_str(), text.c_str()); } } } @@ -84,7 +83,7 @@ bool I18NRepo::LoadIni(const std::string &languageID, const std::string &overrid IniFile ini; std::string iniPath; -// ILOG("Loading lang ini %s", iniPath.c_str()); +// INFO_LOG(SYSTEM, "Loading lang ini %s", iniPath.c_str()); if (!overridePath.empty()) { iniPath = overridePath + languageID + ".ini"; } else { diff --git a/ext/native/image/png_load.cpp b/ext/native/image/png_load.cpp index c6be6b5c38..b8a273c17e 100644 --- a/ext/native/image/png_load.cpp +++ b/ext/native/image/png_load.cpp @@ -9,7 +9,8 @@ #endif #include "png_load.h" -#include "base/logging.h" + +#include "Common/Log.h" // *image_data_ptr should be deleted with free() // return value of 1 == success. @@ -17,7 +18,7 @@ int pngLoad(const char *file, int *pwidth, int *pheight, unsigned char **image_d #ifdef USING_QT_UI QImage image(file, "PNG"); if (image.isNull()) { - ELOG("pngLoad: Error loading image %s", file); + ERROR_LOG(IO, "pngLoad: Error loading image %s", file); return 0; } @@ -36,7 +37,7 @@ int pngLoad(const char *file, int *pwidth, int *pheight, unsigned char **image_d } #else if (flip) - ELOG("pngLoad: flip flag not supported, image will be loaded upside down"); + ERROR_LOG(IO, "pngLoad: flip flag not supported, image will be loaded upside down"); png_image png; memset(&png, 0, sizeof(png)); png.version = PNG_IMAGE_VERSION; @@ -45,7 +46,7 @@ int pngLoad(const char *file, int *pwidth, int *pheight, unsigned char **image_d if (PNG_IMAGE_FAILED(png)) { - ELOG("pngLoad: %s", png.message); + ERROR_LOG(IO, "pngLoad: %s", png.message); return 0; } *pwidth = png.width; @@ -65,7 +66,7 @@ int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, in #ifdef USING_QT_UI QImage image; if (!image.loadFromData(input_ptr, input_len, "PNG")) { - ELOG("pngLoad: Error loading image"); + ERROR_LOG(IO, "pngLoad: Error loading image"); return 0; } if (flip) @@ -83,14 +84,14 @@ int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, in } #else if (flip) - ELOG("pngLoad: flip flag not supported, image will be loaded upside down"); + ERROR_LOG(IO, "pngLoad: flip flag not supported, image will be loaded upside down"); png_image png{}; png.version = PNG_IMAGE_VERSION; png_image_begin_read_from_memory(&png, input_ptr, input_len); if (PNG_IMAGE_FAILED(png)) { - ELOG("pngLoad: %s", png.message); + ERROR_LOG(IO, "pngLoad: %s", png.message); return 0; } *pwidth = png.width; @@ -101,7 +102,7 @@ int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, in size_t size = PNG_IMAGE_SIZE(png); if (!size) { - ELOG("pngLoad: empty image"); + ERROR_LOG(IO, "pngLoad: empty image"); return 0; } diff --git a/ext/native/image/zim_load.cpp b/ext/native/image/zim_load.cpp index 89901f5dc7..86d2627f0c 100644 --- a/ext/native/image/zim_load.cpp +++ b/ext/native/image/zim_load.cpp @@ -2,12 +2,13 @@ #include #include -#include "base/logging.h" #include "zlib.h" #include "image/zim_load.h" #include "math/math_util.h" #include "file/vfs.h" +#include "Common/Log.h" + int ezuncompress(unsigned char* pDest, long* pnDestLen, const unsigned char* pSrc, long nSrcLen) { z_stream stream; stream.next_in = (Bytef*)pSrc; @@ -49,7 +50,7 @@ int ezuncompress(unsigned char* pDest, long* pnDestLen, const unsigned char* pSr int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int *flags, uint8_t **image) { if (zim[0] != 'Z' || zim[1] != 'I' || zim[2] != 'M' || zim[3] != 'G') { - ELOG("Not a ZIM file"); + ERROR_LOG(IO, "Not a ZIM file"); return 0; } memcpy(width, zim + 4, 4); @@ -76,14 +77,14 @@ int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int image_data_size[i] = width[i] * height[i] * 2; break; default: - ELOG("Invalid ZIM format %i", *flags & ZIM_FORMAT_MASK); + ERROR_LOG(IO, "Invalid ZIM format %i", *flags & ZIM_FORMAT_MASK); return 0; } total_data_size += image_data_size[i]; } if (total_data_size == 0) { - ELOG("Invalid ZIM data size 0"); + ERROR_LOG(IO, "Invalid ZIM data size 0"); return 0; } @@ -96,19 +97,19 @@ int LoadZIMPtr(const uint8_t *zim, size_t datasize, int *width, int *height, int long outlen = (long)total_data_size; int retcode = ezuncompress(*image, &outlen, (unsigned char *)(zim + 16), (long)datasize - 16); if (Z_OK != retcode) { - ELOG("ZIM zlib format decompression failed: %d", retcode); + ERROR_LOG(IO, "ZIM zlib format decompression failed: %d", retcode); free(*image); *image = 0; return 0; } if (outlen != total_data_size) { // Shouldn't happen if return value was Z_OK. - ELOG("Wrong size data in ZIM: %i vs %i", (int)outlen, (int)total_data_size); + ERROR_LOG(IO, "Wrong size data in ZIM: %i vs %i", (int)outlen, (int)total_data_size); } } else { memcpy(*image, zim + 16, datasize - 16); if (datasize - 16 != (size_t)total_data_size) { - ELOG("Wrong size data in ZIM: %i vs %i", (int)(datasize-16), (int)total_data_size); + ERROR_LOG(IO, "Wrong size data in ZIM: %i vs %i", (int)(datasize-16), (int)total_data_size); } } return num_levels; @@ -118,13 +119,13 @@ int LoadZIM(const char *filename, int *width, int *height, int *format, uint8_t size_t size; uint8_t *buffer = VFSReadFile(filename, &size); if (!buffer) { - ELOG("Couldn't read data for '%s'", buffer); + ERROR_LOG(IO, "Couldn't read data for '%s'", buffer); return 0; } int retval = LoadZIMPtr(buffer, (int)size, width, height, format, image); if (!retval) { - ELOG("Not a valid ZIM file: %s (size: %d bytes)", filename, (int)size); + ERROR_LOG(IO, "Not a valid ZIM file: %s (size: %d bytes)", filename, (int)size); } delete [] buffer; return retval; diff --git a/ext/native/image/zim_save.cpp b/ext/native/image/zim_save.cpp index 93dd945b67..b62ba3adb8 100644 --- a/ext/native/image/zim_save.cpp +++ b/ext/native/image/zim_save.cpp @@ -1,10 +1,12 @@ -#include -#include -#include -#include "base/logging.h" +#include +#include +#include + #include "image/zim_save.h" #include "zlib.h" +#include "Common/Log.h" + static const char magic[5] = "ZIMG"; /*int num_levels = 1; @@ -141,7 +143,7 @@ void Convert(const uint8_t *image_data, int width, int height, int pitch, int fl break; default: - ELOG("Unhandled ZIM format %i", flags & ZIM_FORMAT_MASK); + ERROR_LOG(IO, "Unhandled ZIM format %d", flags & ZIM_FORMAT_MASK); *data = 0; *data_size = 0; return; @@ -197,7 +199,7 @@ void SaveZIM(FILE *f, int width, int height, int pitch, int flags, const uint8_t if (Z_OK == ezcompress(dest, &dest_len, data, data_size)) { fwrite(dest, 1, dest_len, f); } else { - ELOG("Zlib compression failed.\n"); + ERROR_LOG(IO, "Zlib compression failed.\n"); } delete [] dest; } else { From 5eb13378c6845b147b8c34b9e0e42262c488db43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 15:51:41 +0200 Subject: [PATCH 501/848] Remove base/logging from a lot more files in native --- Core/Util/GameManager.cpp | 2 +- ext/native/base/buffer.cpp | 19 +++++------ ext/native/base/buffer.h | 8 ++--- ext/native/base/stringutil.cpp | 2 +- ext/native/base/timeutil.cpp | 5 +-- ext/native/file/path.cpp | 2 +- ext/native/input/gesture_detector.cpp | 2 -- ext/native/json/json_reader.cpp | 6 ++-- ext/native/json/json_reader.h | 5 +-- ext/native/net/http_client.cpp | 39 +++++++++++------------ ext/native/net/http_headers.cpp | 13 ++++---- ext/native/net/http_server.cpp | 27 ++++++++-------- ext/native/net/resolve.cpp | 7 ++-- ext/native/net/sinks.cpp | 15 +++++---- ext/native/net/url.cpp | 5 +-- ext/native/profiler/profiler.cpp | 11 +++---- ext/native/thin3d/DataFormatGL.cpp | 1 - ext/native/thin3d/GLQueueRunner.cpp | 31 ++++++++++-------- ext/native/thin3d/GLRenderManager.cpp | 5 +-- ext/native/thin3d/VulkanRenderManager.cpp | 27 ++++++++-------- ext/native/thin3d/d3dx9_loader.cpp | 9 +++--- 21 files changed, 125 insertions(+), 116 deletions(-) diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 031f51b119..19f8c67009 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -601,7 +601,7 @@ bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, std::string std::string outputISOFilename = g_Config.currentDirectory + "/" + fn.substr(nameOffset); size_t bytesCopied = 0; if (ExtractFile(z, isoFileIndex, outputISOFilename, &bytesCopied, allBytes)) { - ILOG("Successfully extracted ISO file to '%s'", outputISOFilename.c_str()); + INFO_LOG(IO, "Successfully extracted ISO file to '%s'", outputISOFilename.c_str()); } zip_close(z); if (deleteAfter) { diff --git a/ext/native/base/buffer.cpp b/ext/native/base/buffer.cpp index 2c28a09f7b..e603ff059f 100644 --- a/ext/native/base/buffer.cpp +++ b/ext/native/base/buffer.cpp @@ -18,10 +18,11 @@ #define MSG_NOSIGNAL 0x00 #endif -#include "base/logging.h" #include "base/timeutil.h" #include "file/fd_util.h" +#include "Common/Log.h" + Buffer::Buffer() { } Buffer::~Buffer() { } @@ -63,7 +64,7 @@ void Buffer::AppendValue(int value) { void Buffer::Take(size_t length, std::string *dest) { if (length > data_.size()) { - ELOG("Truncating length in Buffer::Take()"); + ERROR_LOG(IO, "Truncating length in Buffer::Take()"); length = data_.size(); } dest->resize(length); @@ -90,7 +91,7 @@ int Buffer::TakeLineCRLF(std::string *dest) { void Buffer::Skip(size_t length) { if (length > data_.size()) { - ELOG("Truncating length in Buffer::Skip()"); + ERROR_LOG(IO, "Truncating length in Buffer::Skip()"); length = data_.size(); } data_.erase(data_.begin(), data_.begin() + length); @@ -122,10 +123,10 @@ void Buffer::Printf(const char *fmt, ...) { ssize_t retval = vsnprintf(buffer, sizeof(buffer), fmt, vl); if (retval >= (ssize_t)sizeof(buffer)) { // Output was truncated. TODO: Do something. - ELOG("Buffer::Printf truncated output"); + ERROR_LOG(IO, "Buffer::Printf truncated output"); } if (retval < 0) { - ELOG("Buffer::Printf failed"); + ERROR_LOG(IO, "Buffer::Printf failed"); } va_end(vl); char *ptr = Append(retval); @@ -164,14 +165,14 @@ bool Buffer::FlushSocket(uintptr_t sock, double timeout, bool *cancelled) { if (!ready && leftTimeout >= 0.0) { leftTimeout -= CANCEL_INTERVAL; if (leftTimeout < 0) { - ELOG("FlushSocket timed out"); + ERROR_LOG(IO, "FlushSocket timed out"); return false; } } } int sent = send(sock, &data_[pos], (int)(end - pos), MSG_NOSIGNAL); if (sent < 0) { - ELOG("FlushSocket failed"); + ERROR_LOG(IO, "FlushSocket failed"); return false; } pos += sent; @@ -200,7 +201,7 @@ bool Buffer::ReadAll(int fd, int hintSize) { if (retval == 0) { break; } else if (retval < 0) { - ELOG("Error reading from buffer: %i", retval); + ERROR_LOG(IO, "Error reading from buffer: %i", retval); return false; } char *p = Append((size_t)retval); @@ -232,7 +233,7 @@ bool Buffer::ReadAllWithProgress(int fd, int knownSize, float *progress, bool *c if (retval == 0) { return true; } else if (retval < 0) { - ELOG("Error reading from buffer: %i", retval); + ERROR_LOG(IO, "Error reading from buffer: %i", retval); return false; } char *p = Append((size_t)retval); diff --git a/ext/native/base/buffer.h b/ext/native/base/buffer.h index 87018a3999..96abfbbd3f 100644 --- a/ext/native/base/buffer.h +++ b/ext/native/base/buffer.h @@ -1,11 +1,11 @@ -#ifndef _IO_BUFFER_H -#define _IO_BUFFER_H +#pragma once #include #include #include "base/basictypes.h" -#include "base/logging.h" + +#include "Common/Common.h" // Acts as a queue. Intended to be as fast as possible for most uses. // Does not do synchronization, must use external mutexes. @@ -84,5 +84,3 @@ class Buffer { DISALLOW_COPY_AND_ASSIGN(Buffer); }; - -#endif // _IO_BUFFER_H diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp index 5fa467c577..ce2e1094fb 100644 --- a/ext/native/base/stringutil.cpp +++ b/ext/native/base/stringutil.cpp @@ -37,7 +37,7 @@ void OutputDebugStringUTF8(const char *p) { #else void OutputDebugStringUTF8(const char *p) { - ILOG("%s", p); + INFO_LOG(SYSTEM, "%s", p); } #endif diff --git a/ext/native/base/timeutil.cpp b/ext/native/base/timeutil.cpp index 5c70e80053..c2446c3989 100644 --- a/ext/native/base/timeutil.cpp +++ b/ext/native/base/timeutil.cpp @@ -1,7 +1,6 @@ #include #include "base/basictypes.h" -#include "base/logging.h" #include "base/timeutil.h" #ifdef _WIN32 @@ -15,6 +14,8 @@ #include #endif // HAVE_LIBNX +#include "Common/Log.h" + static double curtime = 0; static float curtime_f = 0; @@ -107,7 +108,7 @@ bool LoggingDeadline::End() { if (time_now_d() > endTime_) { double late = (time_now_d() - endTime_); double totalTime = late + totalTime_; - ELOG("===== %0.2fms DEADLINE PASSED FOR %s at %0.2fms - %0.2fms late =====", totalTime_ * 1000.0, name_, 1000.0 * totalTime, 1000.0 * late); + ERROR_LOG(SYSTEM, "===== %0.2fms DEADLINE PASSED FOR %s at %0.2fms - %0.2fms late =====", totalTime_ * 1000.0, name_, 1000.0 * totalTime, 1000.0 * late); return false; } return true; diff --git a/ext/native/file/path.cpp b/ext/native/file/path.cpp index 6aa562dbbc..2bcb7e1cdb 100644 --- a/ext/native/file/path.cpp +++ b/ext/native/file/path.cpp @@ -57,7 +57,7 @@ bool LoadRemoteFileList(const std::string &url, bool *cancel, std::vectorvalue.toString(); - FLOG("String '%s' missing from node", child_name); + ERROR_LOG(IO, "String '%s' missing from node", child_name); return nullptr; } diff --git a/ext/native/json/json_reader.h b/ext/native/json/json_reader.h index a18915f488..472a19140d 100644 --- a/ext/native/json/json_reader.h +++ b/ext/native/json/json_reader.h @@ -2,9 +2,10 @@ #include #include "base/basictypes.h" -#include "base/logging.h" #include "ext/gason/gason.h" +#include "Common/Log.h" + namespace json { struct JsonGet { @@ -72,7 +73,7 @@ private: char *error_pos; int status = jsonParse(buffer_, &error_pos, &root_, alloc_); if (status != JSON_OK) { - ELOG("Error at (%i): %s\n%s\n\n", (int)(error_pos - buffer_), jsonStrError(status), error_pos); + ERROR_LOG(IO, "Error at (%i): %s\n%s\n\n", (int)(error_pos - buffer_), jsonStrError(status), error_pos); return false; } ok_ = true; diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index 29641aff77..7ff05ec99e 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -18,7 +18,6 @@ #include #include -#include "base/logging.h" #include "base/buffer.h" #include "base/stringutil.h" #include "data/compression.h" @@ -27,6 +26,8 @@ #include "net/url.h" #include "thread/threadutil.h" +#include "Common/Log.h" + namespace net { Connection::Connection() @@ -48,11 +49,11 @@ inline unsigned short myhtons(unsigned short x) { bool Connection::Resolve(const char *host, int port, DNSType type) { if ((intptr_t)sock_ != -1) { - ELOG("Resolve: Already have a socket"); + ERROR_LOG(IO, "Resolve: Already have a socket"); return false; } if (!host || port < 1 || port > 65535) { - ELOG("Resolve: Invalid host or port (%d)", port); + ERROR_LOG(IO, "Resolve: Invalid host or port (%d)", port); return false; } @@ -64,7 +65,7 @@ bool Connection::Resolve(const char *host, int port, DNSType type) { std::string err; if (!net::DNSResolve(host, port_str, &resolved_, err, type)) { - ELOG("Failed to resolve host %s: %s", host, err.c_str()); + ERROR_LOG(IO, "Failed to resolve host %s: %s", host, err.c_str()); // So that future calls fail. port_ = 0; return false; @@ -75,7 +76,7 @@ bool Connection::Resolve(const char *host, int port, DNSType type) { bool Connection::Connect(int maxTries, double timeout, bool *cancelConnect) { if (port_ <= 0) { - ELOG("Bad port"); + ERROR_LOG(IO, "Bad port"); return false; } sock_ = -1; @@ -91,7 +92,7 @@ bool Connection::Connect(int maxTries, double timeout, bool *cancelConnect) { int sock = socket(possible->ai_family, SOCK_STREAM, IPPROTO_TCP); if ((intptr_t)sock == -1) { - ELOG("Bad socket"); + ERROR_LOG(IO, "Bad socket"); continue; } fd_util::SetNonBlocking(sock, true); @@ -326,14 +327,14 @@ int Client::ReadResponseHeaders(Buffer *readbuf, std::vector &respo if (!ready && leftTimeout >= 0.0) { leftTimeout -= CANCEL_INTERVAL; if (leftTimeout < 0) { - ELOG("HTTP headers timed out"); + ERROR_LOG(IO, "HTTP headers timed out"); return -1; } } }; // Let's hope all the headers are available in a single packet... if (readbuf->Read(sock(), 4096) < 0) { - ELOG("Failed to read HTTP headers :("); + ERROR_LOG(IO, "Failed to read HTTP headers :("); return -1; } @@ -429,7 +430,7 @@ int Client::ReadResponseEntity(Buffer *readbuf, const std::vector & output->TakeAll(&compressed); bool result = decompress_string(compressed, &decompressed); if (!result) { - ELOG("Error decompressing using zlib"); + ERROR_LOG(IO, "Error decompressing using zlib"); if (progress) *progress = 0.0f; return -1; @@ -448,9 +449,7 @@ Download::Download(const std::string &url, const std::string &outfile) } Download::~Download() { - if (!joined_) { - FLOG("Download destructed without join"); - } + _assert_msg_(joined_, "Download destructed without join"); } void Download::Start() { @@ -459,7 +458,7 @@ void Download::Start() { void Download::Join() { if (joined_) { - ELOG("Already joined thread!"); + ERROR_LOG(IO, "Already joined thread!"); } thread_.join(); joined_ = true; @@ -479,7 +478,7 @@ int Download::PerformGET(const std::string &url) { http::Client client; if (!client.Resolve(fileUrl.Host().c_str(), fileUrl.Port())) { - ELOG("Failed resolving %s", url.c_str()); + ERROR_LOG(IO, "Failed resolving %s", url.c_str()); return -1; } @@ -488,7 +487,7 @@ int Download::PerformGET(const std::string &url) { } if (!client.Connect(2, 20.0, &cancelled_)) { - ELOG("Failed connecting to server or cancelled."); + ERROR_LOG(IO, "Failed connecting to server or cancelled."); return -1; } @@ -525,7 +524,7 @@ void Download::Do() { if (resultCode == 301 || resultCode == 302 || resultCode == 303 || resultCode == 307 || resultCode == 308) { std::string redirectURL = RedirectLocation(downloadURL); if (redirectURL.empty()) { - ELOG("Could not find Location header for redirect"); + ERROR_LOG(IO, "Could not find Location header for redirect"); resultCode_ = resultCode; } else if (redirectURL == downloadURL || redirectURL == url_) { // Simple loop detected, bail out. @@ -534,18 +533,18 @@ void Download::Do() { // Perform the next GET. if (resultCode_ == 0) - ILOG("Download of %s redirected to %s", downloadURL.c_str(), redirectURL.c_str()); + INFO_LOG(IO, "Download of %s redirected to %s", downloadURL.c_str(), redirectURL.c_str()); downloadURL = redirectURL; continue; } if (resultCode == 200) { - ILOG("Completed downloading %s to %s", url_.c_str(), outfile_.empty() ? "memory" : outfile_.c_str()); + INFO_LOG(IO, "Completed downloading %s to %s", url_.c_str(), outfile_.empty() ? "memory" : outfile_.c_str()); if (!outfile_.empty() && !buffer_.FlushToFile(outfile_.c_str())) { - ELOG("Failed writing download to %s", outfile_.c_str()); + ERROR_LOG(IO, "Failed writing download to %s", outfile_.c_str()); } } else { - ELOG("Error downloading %s to %s: %i", url_.c_str(), outfile_.c_str(), resultCode); + ERROR_LOG(IO, "Error downloading %s to %s: %i", url_.c_str(), outfile_.c_str(), resultCode); } resultCode_ = resultCode; } diff --git a/ext/native/net/http_headers.cpp b/ext/native/net/http_headers.cpp index fdfaa2c1ea..e568c7c5c8 100644 --- a/ext/native/net/http_headers.cpp +++ b/ext/native/net/http_headers.cpp @@ -4,11 +4,12 @@ #include #include -#include "base/logging.h" #include "base/stringutil.h" #include "file/fd_util.h" #include "net/sinks.h" +#include "Common/Log.h" + namespace http { RequestHeader::RequestHeader() @@ -32,7 +33,7 @@ bool RequestHeader::GetParamValue(const char *param_name, std::string *value) co for (size_t i = 0; i < v.size(); i++) { std::vector parts; SplitString(v[i], '=', parts); - ILOG("Param: %s Value: %s", parts[0].c_str(), parts[1].c_str()); + INFO_LOG(IO, "Param: %s Value: %s", parts[0].c_str(), parts[1].c_str()); if (parts[0] == param_name) { *value = parts[1]; return true; @@ -120,13 +121,13 @@ int RequestHeader::ParseHttpHeader(const char *buffer) { if (!strncasecmp(key, "User-Agent", key_len)) { user_agent = new char[value_len + 1]; memcpy(user_agent, buffer, value_len + 1); - ILOG("user-agent: %s", user_agent); + INFO_LOG(IO, "user-agent: %s", user_agent); } else if (!strncasecmp(key, "Referer", key_len)) { referer = new char[value_len + 1]; memcpy(referer, buffer, value_len + 1); } else if (!strncasecmp(key, "Content-Length", key_len)) { content_length = atoi(buffer); - ILOG("Content-Length: %i", (int)content_length); + INFO_LOG(IO, "Content-Length: %i", (int)content_length); } else { std::string key_str(key, key_len); std::transform(key_str.begin(), key_str.end(), key_str.begin(), tolower); @@ -149,12 +150,12 @@ void RequestHeader::ParseHeaders(net::InputSink *sink) { line_count++; if (type == SIMPLE) { // Done! - ILOG("Simple: Done parsing http request."); + INFO_LOG(IO, "Simple: Done parsing http request."); break; } } - ILOG("finished parsing request."); + INFO_LOG(IO, "finished parsing request."); ok = line_count > 1; } diff --git a/ext/native/net/http_server.cpp b/ext/native/net/http_server.cpp index c4120bae6a..1520b05873 100644 --- a/ext/native/net/http_server.cpp +++ b/ext/native/net/http_server.cpp @@ -34,13 +34,14 @@ #include #include -#include "base/logging.h" #include "base/buffer.h" #include "file/fd_util.h" #include "net/http_server.h" #include "net/sinks.h" #include "thread/executor.h" +#include "Common/Log.h" + namespace http { // Note: charset here helps prevent XSS. @@ -53,7 +54,7 @@ Request::Request(int fd) header_.ParseHeaders(in_); if (header_.ok) { - ILOG("The request carried with it %i bytes", (int)header_.content_length); + INFO_LOG(IO, "The request carried with it %i bytes", (int)header_.content_length); } else { Close(); } @@ -62,10 +63,10 @@ Request::Request(int fd) Request::~Request() { Close(); - CHECK(in_->Empty()); + _assert_(in_->Empty()); delete in_; if (!out_->Empty()) { - ELOG("Output not empty - connection abort?"); + ERROR_LOG(IO, "Output not empty - connection abort?"); } delete out_; } @@ -108,12 +109,12 @@ void Request::WriteHttpResponseHeader(const char *ver, int status, int64_t size, } void Request::WritePartial() const { - CHECK(fd_); + _assert_(fd_); out_->Flush(); } void Request::Write() { - CHECK(fd_); + _assert_(fd_); WritePartial(); Close(); } @@ -171,7 +172,7 @@ bool Server::Listen4(int port) { if (bind(listener_, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { closesocket(listener_); - ELOG("Failed to bind to port %i. Bailing.", port); + ERROR_LOG(IO, "Failed to bind to port %d. Bailing.", port); return false; } @@ -188,7 +189,7 @@ bool Server::Listen4(int port) { port = ntohs(server_addr.sin_port); } - ILOG("HTTP server started on port %i", port); + INFO_LOG(IO, "HTTP server started on port %d", port); port_ = port; return true; @@ -216,7 +217,7 @@ bool Server::Listen6(int port, bool ipv6_only) { if (bind(listener_, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { closesocket(listener_); - ELOG("Failed to bind to port %i. Bailing.", port); + ERROR_LOG(IO, "Failed to bind to port %d. Bailing.", port); return false; } @@ -233,7 +234,7 @@ bool Server::Listen6(int port, bool ipv6_only) { port = ntohs(server_addr.sin6_port); } - ILOG("HTTP server started on port %i", port); + INFO_LOG(IO, "HTTP server started on port %d", port); port_ = port; return true; @@ -268,7 +269,7 @@ bool Server::RunSlice(double timeout) { return true; } else { - ELOG("socket accept failed: %i", conn_fd); + ERROR_LOG(IO, "socket accept failed: %i", conn_fd); return false; } } @@ -293,7 +294,7 @@ void Server::Stop() { void Server::HandleConnection(int conn_fd) { Request request(conn_fd); if (!request.IsOK()) { - WLOG("Bad request, ignoring."); + WARN_LOG(IO, "Bad request, ignoring."); return; } HandleRequest(request); @@ -321,7 +322,7 @@ void Server::HandleRequestDefault(const Request &request) { } void Server::Handle404(const Request &request) { - ILOG("No handler for '%s', falling back to 404.", request.resource()); + INFO_LOG(IO, "No handler for '%s', falling back to 404.", request.resource()); const char *payload = "404 not found\r\n"; request.WriteHttpResponseHeader("1.0", 404, (int)strlen(payload)); request.Out()->Push(payload); diff --git a/ext/native/net/resolve.cpp b/ext/native/net/resolve.cpp index c4fc78fc62..e1479541a5 100644 --- a/ext/native/net/resolve.cpp +++ b/ext/native/net/resolve.cpp @@ -1,6 +1,5 @@ +#include "ppsspp_config.h" #include "net/resolve.h" -#include "base/logging.h" -#include "base/timeutil.h" #include #include @@ -25,6 +24,7 @@ #include #endif +#include "base/timeutil.h" namespace net { @@ -45,6 +45,7 @@ void Shutdown() } bool DNSResolve(const std::string &host, const std::string &service, addrinfo **res, std::string &error, DNSType type) { + #if PPSSPP_PLATFORM(SWITCH) // Force IPv4 lookups. if (type == DNSType::IPV6) { @@ -102,7 +103,7 @@ void DNSResolveFree(addrinfo *res) freeaddrinfo(res); } -bool GetIPList(std::vector& IP4s) { +bool GetIPList(std::vector &IP4s) { char ipstr[INET6_ADDRSTRLEN]; // We use IPv6 length since it's longer than IPv4 #if defined(getifaddrs) // On Android: Requires __ANDROID_API__ >= 24 struct ifaddrs* ifAddrStruct = NULL; diff --git a/ext/native/net/sinks.cpp b/ext/native/net/sinks.cpp index d9bf32d9d0..8c4434b31d 100644 --- a/ext/native/net/sinks.cpp +++ b/ext/native/net/sinks.cpp @@ -1,4 +1,6 @@ -#ifdef _WIN32 +#include "ppsspp_config.h" + +#if PPSSPP_PLATFORM(WINDOWS) #ifndef NOMINMAX #define NOMINMAX @@ -21,10 +23,11 @@ #include #include -#include "base/logging.h" #include "net/sinks.h" #include "file/fd_util.h" +#include "Common/Log.h" + #ifndef MSG_NOSIGNAL // Default value to 0x00 (do nothing) in systems where it's not supported #define MSG_NOSIGNAL 0 @@ -182,7 +185,7 @@ bool InputSink::Block() { void InputSink::AccountFill(int bytes) { if (bytes < 0) { - ELOG("Error reading from socket"); + ERROR_LOG(IO, "Error reading from socket"); return; } @@ -303,10 +306,10 @@ bool OutputSink::Printf(const char *fmt, ...) { // Okay, did we actually write? if (result >= (int)avail) { // This means the result string was too big for the buffer. - ELOG("Not enough space to format output."); + ERROR_LOG(IO, "Not enough space to format output."); return false; } else if (result < 0) { - ELOG("vsnprintf failed."); + ERROR_LOG(IO, "vsnprintf failed."); return false; } @@ -373,7 +376,7 @@ void OutputSink::AccountPush(size_t bytes) { void OutputSink::AccountDrain(int bytes) { if (bytes < 0) { - ELOG("Error writing to socket"); + ERROR_LOG(IO, "Error writing to socket"); return; } diff --git a/ext/native/net/url.cpp b/ext/native/net/url.cpp index 45175372e7..943ed4e3eb 100644 --- a/ext/native/net/url.cpp +++ b/ext/native/net/url.cpp @@ -1,7 +1,8 @@ -#include "base/logging.h" #include "base/stringutil.h" #include "net/url.h" +#include "Common/Log.h" + const char *UrlEncoder::unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"; const char *UrlEncoder::hexChars = "0123456789ABCDEF"; @@ -10,7 +11,7 @@ int MultipartFormDataEncoder::seq = 0; void Url::Split() { size_t colonSlashSlash = url_.find("://"); if (colonSlashSlash == std::string::npos) { - ELOG("Invalid URL: %s", url_.c_str()); + ERROR_LOG(IO, "Invalid URL: %s", url_.c_str()); return; } diff --git a/ext/native/profiler/profiler.cpp b/ext/native/profiler/profiler.cpp index bf037a9510..2c2457812f 100644 --- a/ext/native/profiler/profiler.cpp +++ b/ext/native/profiler/profiler.cpp @@ -8,12 +8,13 @@ #include -#include "base/logging.h" #include "base/timeutil.h" #include "gfx_es2/draw_buffer.h" #include "ppsspp_config.h" #include "profiler/profiler.h" +#include "Common/Log.h" + #define MAX_CATEGORIES 64 // Can be any number, represents max profiled names. #define MAX_DEPTH 16 // Can be any number, represents max nesting depth of profiled names. #if PPSSPP_PLATFORM(IOS) && defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 @@ -147,7 +148,7 @@ int internal_profiler_enter(const char *category_name, int *out_thread_id) { } internal_profiler_resume(thread_id, category, now); } else { - DLOG("profiler: recursive enter (%i - %s)", category, category_name); + DEBUG_LOG(SYSTEM, "profiler: recursive enter (%i - %s)", category, category_name); } depth++; @@ -164,7 +165,7 @@ void internal_profiler_leave(int thread_id, int category) { int &depth = profiler.depth[thread_id]; if (category < 0 || category >= MAX_CATEGORIES) { - ELOG("Bad category index %d", category); + ERROR_LOG(SYSTEM, "Bad category index %d", category); depth--; return; } @@ -172,9 +173,7 @@ void internal_profiler_leave(int thread_id, int category) { double now = real_time_now(); depth--; - if (depth < 0) { - FLOG("Profiler enter/leave mismatch!"); - } + _assert_msg_(depth >= 0, "Profiler enter/leave mismatch!"); int parent = profiler.parentCategory[thread_id][depth]; // When there's recursion, we don't suspend or resume. diff --git a/ext/native/thin3d/DataFormatGL.cpp b/ext/native/thin3d/DataFormatGL.cpp index b3a8092abf..5037586691 100644 --- a/ext/native/thin3d/DataFormatGL.cpp +++ b/ext/native/thin3d/DataFormatGL.cpp @@ -1,5 +1,4 @@ #include "thin3d/DataFormatGL.h" -#include "base/logging.h" #include "Common/Log.h" namespace Draw { diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index a8ae366eda..72ca079602 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -1,10 +1,7 @@ #include -#include "Common/MemoryUtil.h" -#include "Core/Reporting.h" -#include "GLQueueRunner.h" -#include "GLRenderManager.h" -#include "DataFormatGL.h" -#include "base/logging.h" + +#include "base/logging.h" // For OutputDebugStringUTF8 + #include "base/stringutil.h" #include "gfx/gl_common.h" #include "gfx/gl_debug_log.h" @@ -13,6 +10,14 @@ #include "math/dataconv.h" #include "math/math_util.h" +#include "Common/Log.h" +#include "Common/MemoryUtil.h" + +#include "Core/Reporting.h" +#include "GLQueueRunner.h" +#include "GLRenderManager.h" +#include "DataFormatGL.h" + #define TEXCACHE_NAME_CACHE_SIZE 16 #ifdef IOS @@ -223,7 +228,7 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski if (!anyFailed) Reporting::ReportMessage("Error in shader program link: info: %s\nfs: %s\n%s\nvs: %s\n%s", infoLog.c_str(), fsDesc.c_str(), fsCode, vsDesc.c_str(), vsCode); - ELOG("Could not link program:\n %s", infoLog.c_str()); + ERROR_LOG(G3D, "Could not link program:\n %s", infoLog.c_str()); ERROR_LOG(G3D, "VS desc:\n%s", vsDesc.c_str()); ERROR_LOG(G3D, "FS desc:\n%s", fsDesc.c_str()); ERROR_LOG(G3D, "VS:\n%s\n", vsCode); @@ -277,8 +282,8 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski if (!success) { std::string infoLog = GetInfoLog(shader, glGetShaderiv, glGetShaderInfoLog); #ifdef __ANDROID__ - ELOG("Error in shader compilation! %s\n", infoLog.c_str()); - ELOG("Shader source:\n%s\n", (const char *)code); + ERROR_LOG(G3D, "Error in shader compilation! %s\n", infoLog.c_str()); + ERROR_LOG(G3D, "Shader source:\n%s\n", (const char *)code); #endif ERROR_LOG(G3D, "Error in shader compilation for: %s", step.create_shader.shader->desc.c_str()); ERROR_LOG(G3D, "Info log: %s", infoLog.c_str()); @@ -547,10 +552,10 @@ retry_depth: // ILOG("Framebuffer verified complete."); break; case GL_FRAMEBUFFER_UNSUPPORTED: - ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); + ERROR_LOG(G3D, "GL_FRAMEBUFFER_UNSUPPORTED"); break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); + ERROR_LOG(G3D, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; default: FLOG("Other framebuffer error: %i", status); @@ -1566,10 +1571,10 @@ void GLQueueRunner::fbo_ext_create(const GLRInitStep &step) { // ILOG("Framebuffer verified complete."); break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - ELOG("GL_FRAMEBUFFER_UNSUPPORTED"); + ERROR_LOG(G3D, "GL_FRAMEBUFFER_UNSUPPORTED"); break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - ELOG("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); + ERROR_LOG(G3D, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); break; default: FLOG("Other framebuffer error: %i", status); diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index f21f67aac0..7345e84fa1 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -4,11 +4,12 @@ #include "gfx_es2/gpu_features.h" #include "thin3d/thin3d.h" #include "thread/threadutil.h" -#include "base/logging.h" + +#include "Common/Log.h" #include "Common/MemoryUtil.h" #if 0 // def _DEBUG -#define VLOG ILOG +#define VLOG(...) INFO_LOG(G3D, __VA_ARGS__) #else #define VLOG(...) #endif diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 385d8a580e..4756b4bd09 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -4,14 +4,13 @@ #include #include "Common/Log.h" -#include "base/logging.h" #include "Common/Vulkan/VulkanContext.h" #include "thin3d/VulkanRenderManager.h" #include "thread/threadutil.h" #if 0 // def _DEBUG -#define VLOG ILOG +#define VLOG(...) INFO_LOG(G3D, __VA_ARGS__) #else #define VLOG(...) #endif @@ -162,7 +161,7 @@ void VulkanRenderManager::CreateBackbuffers() { VkImage *swapchainImages = new VkImage[swapchainImageCount_]; res = vkGetSwapchainImagesKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), &swapchainImageCount_, swapchainImages); if (res != VK_SUCCESS) { - ELOG("vkGetSwapchainImagesKHR failed"); + ERROR_LOG(G3D, "vkGetSwapchainImagesKHR failed"); delete[] swapchainImages; return; } @@ -210,7 +209,7 @@ void VulkanRenderManager::CreateBackbuffers() { } if (newInflightFrames_ != -1) { - ILOG("Updating inflight frames to %d", newInflightFrames_); + INFO_LOG(G3D, "Updating inflight frames to %d", newInflightFrames_); vulkan_->UpdateInflightFrames(newInflightFrames_); newInflightFrames_ = -1; } @@ -222,7 +221,7 @@ void VulkanRenderManager::CreateBackbuffers() { run_ = true; // Won't necessarily be 0. threadInitFrame_ = vulkan_->GetCurFrame(); - ILOG("Starting Vulkan submission thread (threadInitFrame_ = %d)", vulkan_->GetCurFrame()); + INFO_LOG(G3D, "Starting Vulkan submission thread (threadInitFrame_ = %d)", vulkan_->GetCurFrame()); thread_ = std::thread(&VulkanRenderManager::ThreadFunc, this); } } @@ -245,7 +244,7 @@ void VulkanRenderManager::StopThread() { frameData.profile.timestampDescriptions.clear(); } thread_.join(); - ILOG("Vulkan submission thread joined. Frame=%d", vulkan_->GetCurFrame()); + INFO_LOG(G3D, "Vulkan submission thread joined. Frame=%d", vulkan_->GetCurFrame()); // Eat whatever has been queued up for this frame if anything. Wipe(); @@ -275,7 +274,7 @@ void VulkanRenderManager::StopThread() { } } } else { - ILOG("Vulkan submission thread was already stopped."); + INFO_LOG(G3D, "Vulkan submission thread was already stopped."); } } @@ -300,7 +299,7 @@ void VulkanRenderManager::DestroyBackbuffers() { } VulkanRenderManager::~VulkanRenderManager() { - ILOG("VulkanRenderManager destructor"); + INFO_LOG(G3D, "VulkanRenderManager destructor"); StopThread(); vulkan_->WaitUntilQueueIdle(); @@ -352,7 +351,7 @@ void VulkanRenderManager::ThreadFunc() { } VLOG("PULL: Running frame %d", threadFrame); if (firstFrame) { - ILOG("Running first frame (%d)", threadFrame); + INFO_LOG(G3D, "Running first frame (%d)", threadFrame); firstFrame = false; } Run(threadFrame); @@ -428,7 +427,7 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) { // Must be after the fence - this performs deletes. VLOG("PUSH: BeginFrame %d", curFrame); if (!run_) { - WLOG("BeginFrame while !run_!"); + WARN_LOG(G3D, "BeginFrame while !run_!"); } vulkan_->BeginFrame(); @@ -614,7 +613,7 @@ bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, VkIma } else { // Backbuffer. if (!(vulkan_->GetSurfaceCapabilities().supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) { - ELOG("Copying from backbuffer not supported, can't take screenshots"); + ERROR_LOG(G3D, "Copying from backbuffer not supported, can't take screenshots"); return false; } switch (vulkan_->GetSwapchainFormat()) { @@ -622,7 +621,7 @@ bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, VkIma case VK_FORMAT_R8G8B8A8_UNORM: srcFormat = Draw::DataFormat::R8G8B8A8_UNORM; break; // NOTE: If you add supported formats here, make sure to also support them in VulkanQueueRunner::CopyReadbackBuffer. default: - ELOG("Unsupported backbuffer format for screenshots"); + ERROR_LOG(G3D, "Unsupported backbuffer format for screenshots"); return false; } } @@ -1074,9 +1073,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"); + WARN_LOG(G3D, "VK_SUBOPTIMAL_KHR returned - ignoring"); } else if (res == VK_ERROR_OUT_OF_DATE_KHR) { - WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - processing the frame, but not presenting"); + WARN_LOG(G3D, "VK_ERROR_OUT_OF_DATE_KHR returned - processing the frame, but not presenting"); frameData.skipSwap = true; } else { _assert_msg_(res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res)); diff --git a/ext/native/thin3d/d3dx9_loader.cpp b/ext/native/thin3d/d3dx9_loader.cpp index f269ecbe04..e67f4b6ae8 100644 --- a/ext/native/thin3d/d3dx9_loader.cpp +++ b/ext/native/thin3d/d3dx9_loader.cpp @@ -6,9 +6,10 @@ #include #include -#include "base/logging.h" #include "thin3d/d3dx9_loader.h" +#include "Common/Log.h" + // TODO: See if we can use the bundled D3Dcompiler_47.dll to compiler for DX9 as well. typedef BOOL(__stdcall *TFunc_D3DXCheckVersion)(UINT D3DSDKVersion, UINT D3DXSDKVersion); @@ -114,7 +115,7 @@ HMODULE loadDllLastVersion(unsigned int* version, bool debugVersion) { } void handleNotFoundAddr(const char* sFuncName) { - ELOG("Failed to find D3DX function %s", sFuncName); + ERROR_LOG(G3D, "Failed to find D3DX function %s", sFuncName); failedFunctions++; } @@ -126,7 +127,7 @@ int LoadD3DX9Dynamic(bool debugVersion) { hm_d3dx = loadDllLastVersion(&d3dx_version, debugVersion); if (!hm_d3dx) { - ELOG("Failed to find D3DX dll."); + ERROR_LOG(G3D, "Failed to find D3DX dll."); return 0; } const int NERROR = -1; @@ -137,7 +138,7 @@ int LoadD3DX9Dynamic(bool debugVersion) { __HANDLE_DLL_ENTRY(D3DXCompileShader); if (failedFunctions > 0) { - ELOG("Failed to load %i D3DX functions. This will not go well.", failedFunctions); + ERROR_LOG(G3D, "Failed to load %i D3DX functions. This will not go well.", failedFunctions); } return failedFunctions > 0 ? 0 : d3dx_version; From c41f875df421bf2b508037ea1569f3500fd78f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 16:13:24 +0200 Subject: [PATCH 502/848] Remove base/logging.h in a whole lot more places. --- Core/Config.cpp | 2 +- Core/Core.cpp | 2 +- Core/MIPS/ARM/ArmJit.cpp | 4 ++-- Core/MIPS/ARM64/Arm64RegCacheFPU.cpp | 4 ++-- GPU/Common/ShaderTranslation.cpp | 8 +++---- GPU/Directx9/ShaderManagerDX9.cpp | 2 ++ GPU/Directx9/StencilBufferDX9.cpp | 1 + GPU/GLES/GPU_GLES.cpp | 4 ++-- GPU/Vulkan/GPU_Vulkan.cpp | 4 ++-- SDL/SDLCocoaMetalLayer.mm | 1 - UI/BackgroundAudio.cpp | 12 +++++----- UI/ControlMappingScreen.cpp | 7 +++--- UI/GameSettingsScreen.cpp | 10 ++++---- UI/Store.cpp | 4 ++-- UI/TextureUtil.cpp | 20 ++++++++-------- UI/TouchControlLayoutScreen.cpp | 2 +- UWP/StorageFolderBrowser.cpp | 1 - Windows/EmuThread.cpp | 2 +- Windows/GPU/D3D9Context.cpp | 2 +- ext/native/profiler/profiler.cpp | 5 +--- ext/native/thin3d/GLRenderManager.cpp | 12 +++++----- ext/native/thin3d/thin3d.cpp | 3 +-- ext/native/thin3d/thin3d.h | 1 - ext/native/thin3d/thin3d_d3d11.cpp | 6 ++--- ext/native/thin3d/thin3d_d3d9.cpp | 28 +++++++++++----------- ext/native/thin3d/thin3d_gl.cpp | 21 ++++++++-------- ext/native/thin3d/thin3d_vulkan.cpp | 20 ++++++++-------- ext/native/thread/prioritizedworkqueue.cpp | 7 +++--- ext/native/thread/threadpool.cpp | 7 +++--- ext/native/thread/threadutil.cpp | 7 ++++-- ext/native/ui/root.cpp | 6 +++-- ext/native/ui/screen.cpp | 27 +++++++++++---------- ext/native/ui/ui_context.cpp | 1 - ext/native/ui/ui_screen.cpp | 9 ++++--- ext/native/ui/viewgroup.cpp | 9 +++---- headless/WindowsHeadlessHost.cpp | 2 ++ 36 files changed, 136 insertions(+), 127 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index f7fd8e9af9..8e53ab9200 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -527,7 +527,7 @@ static int DefaultInternalResolution() { #else int longestDisplaySide = std::max(System_GetPropertyInt(SYSPROP_DISPLAY_XRES), System_GetPropertyInt(SYSPROP_DISPLAY_YRES)); int scale = longestDisplaySide >= 1000 ? 2 : 1; - ILOG("Longest display side: %d pixels. Choosing scale %d", longestDisplaySide, scale); + INFO_LOG(G3D, "Longest display side: %d pixels. Choosing scale %d", longestDisplaySide, scale); return scale; #endif } diff --git a/Core/Core.cpp b/Core/Core.cpp index 01b2970cda..acb1ad44c6 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -190,7 +190,7 @@ bool UpdateScreenScale(int width, int height) { dp_yres = new_dp_yres; pixel_xres = width; pixel_yres = height; - ILOG("pixel_res: %dx%d. Calling NativeResized()", pixel_xres, pixel_yres); + INFO_LOG(G3D, "pixel_res: %dx%d. Calling NativeResized()", pixel_xres, pixel_yres); NativeResized(); return true; } diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 829307b419..5a8316f06b 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -62,13 +62,13 @@ void DisassembleArm(const u8 *data, int size) { int reg1 = (next & 0x0000F000) >> 12; if (reg0 == reg1) { sprintf(temp, "%08x MOV32 %s, %04x%04x", (u32)inst, ArmRegName(reg0), hi, low); - ILOG("A: %s", temp); + INFO_LOG(JIT, "A: %s", temp); i += 4; continue; } } ArmDis((u32)codePtr, inst, temp, sizeof(temp), true); - ILOG("A: %s", temp); + INFO_LOG(JIT, "A: %s", temp); } } diff --git a/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp b/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp index ebb0d09494..fffb38fcc7 100644 --- a/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp +++ b/Core/MIPS/ARM64/Arm64RegCacheFPU.cpp @@ -400,7 +400,7 @@ void Arm64RegCacheFPU::FlushAll() { if (ar[a].isDirty) { if (m == -1) { - INFO_LOG(JIT, "ARM reg %i is dirty but has no mipsreg", a); + INFO_LOG(JIT, "ARM reg %d is dirty but has no mipsreg", a); continue; } @@ -423,7 +423,7 @@ void Arm64RegCacheFPU::FlushAll() { // Sanity check for (int i = 0; i < numARMFpuReg_; i++) { if (ar[i].mipsReg != -1) { - ERROR_LOG(JIT, "Flush fail: ar[%i].mipsReg=%i", i, ar[i].mipsReg); + ERROR_LOG(JIT, "Flush fail: ar[%d].mipsReg=%d", i, ar[i].mipsReg); } } pendingFlush = false; diff --git a/GPU/Common/ShaderTranslation.cpp b/GPU/Common/ShaderTranslation.cpp index d535d063c1..e0b58908fc 100644 --- a/GPU/Common/ShaderTranslation.cpp +++ b/GPU/Common/ShaderTranslation.cpp @@ -252,8 +252,8 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade shaderStrings[0] = src.c_str(); shader.setStrings(shaderStrings, 1); if (!shader.parse(&Resources, 100, EProfile::ECompatibilityProfile, false, false, messages)) { - ELOG("%s", shader.getInfoLog()); - ELOG("%s", shader.getInfoDebugLog()); + ERROR_LOG(G3D, "%s", shader.getInfoLog()); + ERROR_LOG(G3D, "%s", shader.getInfoDebugLog()); if (errorMessage) { *errorMessage = shader.getInfoLog(); (*errorMessage) += shader.getInfoDebugLog(); @@ -265,8 +265,8 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade program.addShader(&shader); if (!program.link(messages)) { - ELOG("%s", shader.getInfoLog()); - ELOG("%s", shader.getInfoDebugLog()); + ERROR_LOG(G3D, "%s", shader.getInfoLog()); + ERROR_LOG(G3D, "%s", shader.getInfoDebugLog()); if (errorMessage) { *errorMessage = shader.getInfoLog(); (*errorMessage) += shader.getInfoDebugLog(); diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 64a1d28137..15cb7777e8 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -23,6 +23,7 @@ #include #include "gfx/d3d9_shader.h" +#include "base/logging.h" // For OutputDebugStringUTF8 #include "base/stringutil.h" #include "i18n/i18n.h" #include "math/lin/matrix4x4.h" @@ -32,6 +33,7 @@ #include "util/text/utf8.h" #include "Common/Common.h" +#include "Common/Log.h" #include "Core/Config.h" #include "Core/Host.h" #include "Core/Reporting.h" diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 4310a1654e..722a43b31f 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -17,6 +17,7 @@ #include +#include "base/logging.h" // For OutputDebugStringUTF8 #include "gfx/d3d9_state.h" #include "ext/native/thin3d/thin3d.h" #include "Core/Reporting.h" diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 40fda18e5e..8c9df27705 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -310,7 +310,7 @@ void GPU_GLES::BuildReportingInfo() { } void GPU_GLES::DeviceLost() { - ILOG("GPU_GLES: DeviceLost"); + INFO_LOG(G3D, "GPU_GLES: DeviceLost"); // Simply drop all caches and textures. // FBOs appear to survive? Or no? @@ -328,7 +328,7 @@ void GPU_GLES::DeviceLost() { void GPU_GLES::DeviceRestore() { draw_ = (Draw::DrawContext *)PSP_CoreParameter().graphicsContext->GetDrawContext(); - ILOG("GPU_GLES: DeviceRestore"); + INFO_LOG(G3D, "GPU_GLES: DeviceRestore"); UpdateCmdInfo(); UpdateVsyncInterval(true); diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 6442b3e8d7..c2ba043348 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -471,7 +471,7 @@ void GPU_Vulkan::ExecuteOp(u32 op, u32 diff) { } void GPU_Vulkan::InitDeviceObjects() { - ILOG("GPU_Vulkan::InitDeviceObjects"); + INFO_LOG(G3D, "GPU_Vulkan::InitDeviceObjects"); // Initialize framedata for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { assert(!frameData_[i].push_); @@ -495,7 +495,7 @@ void GPU_Vulkan::InitDeviceObjects() { } void GPU_Vulkan::DestroyDeviceObjects() { - ILOG("GPU_Vulkan::DestroyDeviceObjects"); + INFO_LOG(G3D, "GPU_Vulkan::DestroyDeviceObjects"); for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { if (frameData_[i].push_) { frameData_[i].push_->Destroy(vulkan_); diff --git a/SDL/SDLCocoaMetalLayer.mm b/SDL/SDLCocoaMetalLayer.mm index d0df82716b..c45158ff5d 100644 --- a/SDL/SDLCocoaMetalLayer.mm +++ b/SDL/SDLCocoaMetalLayer.mm @@ -5,7 +5,6 @@ #endif #import -#include "base/logging.h" #include "SDLCocoaMetalLayer.h" void *makeWindowMetalCompatible(void *window) { diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 1de2def802..a061af2056 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -84,9 +84,9 @@ void WavData::Read(RIFFReader &file_) { } } file_.Ascend(); - // ILOG("got fmt data: %i", samplesPerSec); + // INFO_LOG(AUDIO, "got fmt data: %i", samplesPerSec); } else { - ELOG("Error - no format chunk in wav"); + ERROR_LOG(AUDIO, "Error - no format chunk in wav"); file_.Ascend(); return; } @@ -142,20 +142,20 @@ void WavData::Read(RIFFReader &file_) { if (num_channels == 1 || num_channels == 2) { file_.ReadData(raw_data, numBytes); } else { - ELOG("Error - bad blockalign or channels"); + ERROR_LOG(AUDIO, "Error - bad blockalign or channels"); free(raw_data); raw_data = nullptr; return; } file_.Ascend(); } else { - ELOG("Error - no data chunk in wav"); + ERROR_LOG(AUDIO, "Error - no data chunk in wav"); file_.Ascend(); return; } file_.Ascend(); } else { - ELOG("Could not descend into RIFF file."); + ERROR_LOG(AUDIO, "Could not descend into RIFF file."); return; } sample_rate = samplesPerSec; @@ -269,7 +269,7 @@ BackgroundAudio::Sample *BackgroundAudio::LoadSample(const std::string &path) { delete [] data; if (wave.num_channels != 2 || wave.sample_rate != 44100 || wave.raw_bytes_per_frame != 4) { - ELOG("Wave format not supported for mixer playback. Must be 16-bit raw stereo. '%s'", path.c_str()); + ERROR_LOG(AUDIO, "Wave format not supported for mixer playback. Must be 16-bit raw stereo. '%s'", path.c_str()); return nullptr; } diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 3d711eda2f..1cf93ebb44 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -34,6 +34,7 @@ #include "Core/Host.h" #include "Core/HLE/sceCtrl.h" #include "Core/System.h" +#include "Common/Log.h" #include "Common/KeyMap.h" #include "Core/Config.h" #include "UI/ControlMappingScreen.h" @@ -581,7 +582,7 @@ bool TouchTestScreen::touch(const TouchInput &touch) { bool found = false; for (int i = 0; i < MAX_TOUCH_POINTS; i++) { if (touches_[i].id == touch.id) { - WLOG("Double touch"); + WARN_LOG(SYSTEM, "Double touch"); touches_[i].x = touch.x; touches_[i].y = touch.y; found = true; @@ -608,7 +609,7 @@ bool TouchTestScreen::touch(const TouchInput &touch) { } } if (!found) { - WLOG("Move without touch down: %d", touch.id); + WARN_LOG(SYSTEM, "Move without touch down: %d", touch.id); } } if (touch.flags & TOUCH_UP) { @@ -621,7 +622,7 @@ bool TouchTestScreen::touch(const TouchInput &touch) { } } if (!found) { - WLOG("Touch release without touch down"); + WARN_LOG(SYSTEM, "Touch release without touch down"); } } return true; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4734b179a6..bcb0a293c5 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -998,19 +998,19 @@ UI::EventReturn GameSettingsScreen::OnHardwareTransform(UI::EventParams &e) { } UI::EventReturn GameSettingsScreen::OnScreenRotation(UI::EventParams &e) { - ILOG("New display rotation: %d", g_Config.iScreenRotation); - ILOG("Sending rotate"); + INFO_LOG(SYSTEM, "New display rotation: %d", g_Config.iScreenRotation); + INFO_LOG(SYSTEM, "Sending rotate"); System_SendMessage("rotate", ""); - ILOG("Got back from rotate"); + INFO_LOG(SYSTEM, "Got back from rotate"); return UI::EVENT_DONE; } void RecreateActivity() { const int SYSTEM_JELLYBEAN = 16; if (System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= SYSTEM_JELLYBEAN) { - ILOG("Sending recreate"); + INFO_LOG(SYSTEM, "Sending recreate"); System_SendMessage("recreate", ""); - ILOG("Got back from recreate"); + INFO_LOG(SYSTEM, "Got back from recreate"); } else { auto gr = GetI18NCategory("Graphics"); System_SendMessage("toast", gr->T("Must Restart", "You must restart PPSSPP for this change to take effect")); diff --git a/UI/Store.cpp b/UI/Store.cpp index f52a1ae916..fd27021106 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -370,7 +370,7 @@ void StoreScreen::update() { RecreateViews(); } else { // Failed to contact store. Don't do anything. - ELOG("Download failed : error code %d", listing_->ResultCode()); + ERROR_LOG(IO, "Download failed : error code %d", listing_->ResultCode()); connectionError_ = true; loading_ = false; RecreateViews(); @@ -398,7 +398,7 @@ void StoreScreen::ParseListing(std::string json) { using namespace json; JsonReader reader(json.c_str(), json.size()); if (!reader.ok() || !reader.root()) { - ELOG("Error parsing JSON from store"); + ERROR_LOG(IO, "Error parsing JSON from store"); connectionError_ = true; RecreateViews(); return; diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index 0d05bbc448..dc0cfa2355 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -43,7 +43,7 @@ static bool LoadTextureLevels(const uint8_t *data, size_t size, ImageFileType ty type = DetectImageFileType(data, size); } if (type == TYPE_UNKNOWN) { - ELOG("File (size: %d) has unknown format", (int)size); + ERROR_LOG(G3D, "File (size: %d) has unknown format", (int)size); return false; } @@ -63,11 +63,11 @@ static bool LoadTextureLevels(const uint8_t *data, size_t size, ImageFileType ty *num_levels = 1; *fmt = Draw::DataFormat::R8G8B8A8_UNORM; if (!image[0]) { - ELOG("WTF"); + ERROR_LOG(IO, "WTF"); return false; } } else { - ELOG("PNG load failed"); + ERROR_LOG(IO, "PNG load failed"); return false; } break; @@ -85,7 +85,7 @@ static bool LoadTextureLevels(const uint8_t *data, size_t size, ImageFileType ty break; default: - ELOG("Unsupported image format %d", (int)type); + ERROR_LOG(IO, "Unsupported image format %d", (int)type); return false; } @@ -111,7 +111,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag } if (num_levels < 0 || num_levels >= 16) { - ELOG("Invalid num_levels: %d. Falling back to one. Image: %dx%d", num_levels, width[0], height[0]); + ERROR_LOG(IO, "Invalid num_levels: %d. Falling back to one. Image: %dx%d", num_levels, width[0], height[0]); num_levels = 1; } @@ -149,7 +149,7 @@ bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType typ uint8_t *buffer = VFSReadFile(filename.c_str(), &fileSize); if (!buffer) { filename_ = ""; - ELOG("Failed to read file '%s'", filename.c_str()); + ERROR_LOG(IO, "Failed to read file '%s'", filename.c_str()); return false; } bool retval = LoadFromFileData(buffer, fileSize, type, generateMips, filename.c_str()); @@ -157,7 +157,7 @@ bool ManagedTexture::LoadFromFile(const std::string &filename, ImageFileType typ filename_ = filename; } else { filename_ = ""; - ELOG("Failed to load texture '%s'", filename.c_str()); + ERROR_LOG(IO, "Failed to load texture '%s'", filename.c_str()); } delete[] buffer; return retval; @@ -176,14 +176,14 @@ std::unique_ptr CreateTextureFromFile(Draw::DrawContext *draw, c } void ManagedTexture::DeviceLost() { - ILOG("ManagedTexture::DeviceLost(%s)", filename_.c_str()); + INFO_LOG(G3D, "ManagedTexture::DeviceLost(%s)", filename_.c_str()); if (texture_) texture_->Release(); texture_ = nullptr; } void ManagedTexture::DeviceRestored(Draw::DrawContext *draw) { - ILOG("ManagedTexture::DeviceRestored(%s)", filename_.c_str()); + INFO_LOG(G3D, "ManagedTexture::DeviceRestored(%s)", filename_.c_str()); _assert_(!texture_); draw_ = draw; // Vulkan: Can't load textures before the first frame has started. @@ -194,7 +194,7 @@ void ManagedTexture::DeviceRestored(Draw::DrawContext *draw) { Draw::Texture *ManagedTexture::GetTexture() { if (loadPending_) { if (!LoadFromFile(filename_, ImageFileType::DETECT, generateMips_)) { - ELOG("ManagedTexture failed: '%s'", filename_.c_str()); + ERROR_LOG(IO, "ManagedTexture failed: '%s'", filename_.c_str()); } loadPending_ = false; } diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index e895ebd384..f8835f1e74 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -448,7 +448,7 @@ UI::EventReturn TouchControlLayoutScreen::OnVisibility(UI::EventParams &e) { } UI::EventReturn TouchControlLayoutScreen::OnReset(UI::EventParams &e) { - ILOG("Resetting touch control layout"); + INFO_LOG(G3D, "Resetting touch control layout"); g_Config.ResetControlLayout(); const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); InitPadLayout(bounds.w, bounds.h); diff --git a/UWP/StorageFolderBrowser.cpp b/UWP/StorageFolderBrowser.cpp index e5c6149d4c..3744b3e6dd 100644 --- a/UWP/StorageFolderBrowser.cpp +++ b/UWP/StorageFolderBrowser.cpp @@ -1,7 +1,6 @@ #include "pch.h" #include "ppltasks.h" -#include "base/logging.h" #include "thread/threadutil.h" #include "StorageFolderBrowser.h" diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 7239929dae..83ce9471f7 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -104,7 +104,7 @@ static void EmuThreadStop() { static void EmuThreadJoin() { emuThread.join(); emuThread = std::thread(); - ILOG("EmuThreadJoin - joined"); + INFO_LOG(SYSTEM, "EmuThreadJoin - joined"); } void MainThreadFunc() { diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index c948654b98..0014c31121 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -71,7 +71,7 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { hD3D9_ = LoadLibrary(TEXT("d3d9.dll")); if (!hD3D9_) { - ELOG("Missing d3d9.dll"); + ERROR_LOG(G3D, "Missing d3d9.dll"); *error_message = "D3D9.dll missing - try reinstalling DirectX."; return false; } diff --git a/ext/native/profiler/profiler.cpp b/ext/native/profiler/profiler.cpp index 2c2457812f..60dffd5154 100644 --- a/ext/native/profiler/profiler.cpp +++ b/ext/native/profiler/profiler.cpp @@ -190,10 +190,7 @@ void internal_profiler_leave(int thread_id, int category) { void internal_profiler_end_frame() { int thread_id = internal_profiler_find_thread(); - if (profiler.depth[thread_id] != 0) { - // Threads may be off, but they'll fall into another frame. - FLOG("Can't be inside a profiler scope at end of frame!"); - } + _assert_msg_(profiler.depth[thread_id] == 0, "Can't be inside a profiler scope at end of frame!"); profiler.curFrameStart = real_time_now(); profiler.historyPos++; profiler.historyPos &= (HISTORY_SIZE - 1); diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 7345e84fa1..19a3ac0053 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -114,7 +114,7 @@ void GLRenderManager::ThreadStart(Draw::DrawContext *draw) { renderThreadId = std::this_thread::get_id(); if (newInflightFrames_ != -1) { - ILOG("Updating inflight frames to %d", newInflightFrames_); + INFO_LOG(G3D, "Updating inflight frames to %d", newInflightFrames_); inflightFrames_ = newInflightFrames_; newInflightFrames_ = -1; } @@ -154,7 +154,7 @@ void GLRenderManager::ThreadStart(Draw::DrawContext *draw) { } void GLRenderManager::ThreadEnd() { - ILOG("ThreadEnd"); + INFO_LOG(G3D, "ThreadEnd"); // Wait for any shutdown to complete in StopThread(). std::unique_lock lock(mutex_); @@ -217,7 +217,7 @@ bool GLRenderManager::ThreadFrame() { } VLOG("PULL: Running frame %d", threadFrame_); if (firstFrame) { - ILOG("Running first frame (%d)", threadFrame_); + INFO_LOG(G3D, "Running first frame (%d)", threadFrame_); firstFrame = false; } Run(threadFrame_); @@ -246,7 +246,7 @@ void GLRenderManager::StopThread() { // Wait until we've definitely stopped the threadframe. std::unique_lock lock(mutex_); - ILOG("GL submission thread paused. Frame=%d", curFrame_); + INFO_LOG(G3D, "GL submission thread paused. Frame=%d", curFrame_); // Eat whatever has been queued up for this frame if anything. Wipe(); @@ -274,7 +274,7 @@ void GLRenderManager::StopThread() { } } } else { - ILOG("GL submission thread was already paused."); + INFO_LOG(G3D, "GL submission thread was already paused."); } } @@ -454,7 +454,7 @@ void GLRenderManager::BeginFrame() { // Must be after the fence - this performs deletes. VLOG("PUSH: BeginFrame %d", curFrame); if (!run_) { - WLOG("BeginFrame while !run_!"); + WARN_LOG(G3D, "BeginFrame while !run_!"); } // vulkan_->BeginFrame(); diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index 97b6fe9e0a..aabb1d818b 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -2,7 +2,6 @@ #include #include -#include "base/logging.h" #include "base/display.h" #include "thin3d/thin3d.h" #include "Common/Log.h" @@ -92,7 +91,7 @@ bool RefCountedObject::ReleaseAssertLast() { return true; } } else { - ELOG("Refcount (%d) invalid for object %p - corrupt?", refcount_, this); + ERROR_LOG(G3D, "Refcount (%d) invalid for object %p - corrupt?", refcount_, this); } return false; } diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index ced1d8df67..88001c4aa3 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -12,7 +12,6 @@ #include #include -#include "base/logging.h" #include "DataFormat.h" namespace Lin { diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 8c53ffc7d8..9c371678e0 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -870,7 +870,7 @@ public: ShaderModule *D3D11DrawContext::CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize, const std::string &tag) { if (language != ShaderLanguage::HLSL_D3D11) { - ELOG("Unsupported shader language"); + ERROR_LOG(G3D, "Unsupported shader language"); return nullptr; } @@ -915,7 +915,7 @@ ShaderModule *D3D11DrawContext::CreateShaderModule(ShaderStage stage, ShaderLang } if (errorMsgs) { errors = std::string((const char *)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize()); - ELOG("Failed compiling:\n%s\n%s", data, errors.c_str()); + ERROR_LOG(G3D, "Failed compiling:\n%s\n%s", data, errors.c_str()); errorMsgs->Release(); } @@ -940,7 +940,7 @@ ShaderModule *D3D11DrawContext::CreateShaderModule(ShaderStage stage, ShaderLang result = device_->CreateGeometryShader(data, dataSize, nullptr, &module->gs); break; default: - ELOG("Unsupported shader stage"); + ERROR_LOG(G3D, "Unsupported shader stage"); result = S_FALSE; break; } diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 0b6740963f..2b629149a8 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -33,11 +33,12 @@ #define D3DXERR_INVALIDDATA 0x88760b59 #endif -#include "base/logging.h" #include "math/lin/matrix4x4.h" #include "thin3d/thin3d.h" #include "gfx/d3d9_state.h" +#include "Common/Log.h" + namespace Draw { // Could be declared as u8 @@ -381,7 +382,7 @@ bool D3D9Texture::Create(const TextureDesc &desc) { break; } if (FAILED(hr)) { - ELOG("Texture creation failed"); + ERROR_LOG(G3D, "Texture creation failed"); return false; } @@ -476,7 +477,7 @@ void D3D9Texture::SetImageData(int x, int y, int z, int width, int height, int d } default: - ELOG("Non-LINEAR2D textures not yet supported"); + ERROR_LOG(G3D, "Non-LINEAR2D textures not yet supported"); break; } } @@ -636,7 +637,7 @@ private: D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) : d3d_(d3d), d3dEx_(d3dEx), adapterId_(adapterId), device_(device), deviceEx_(deviceEx), caps_{} { if (FAILED(d3d->GetAdapterIdentifier(adapterId, 0, &identifier_))) { - ELOG("Failed to get adapter identifier: %d", adapterId); + ERROR_LOG(G3D, "Failed to get adapter identifier: %d", adapterId); } switch (identifier_.VendorId) { case 0x10DE: caps_.vendor = GPUVendor::VENDOR_NVIDIA; break; @@ -691,13 +692,13 @@ ShaderModule *D3D9Context::CreateShaderModule(ShaderStage stage, ShaderLanguage Pipeline *D3D9Context::CreateGraphicsPipeline(const PipelineDesc &desc) { if (!desc.shaders.size()) { - ELOG("Pipeline requires at least one shader"); + ERROR_LOG(G3D, "Pipeline requires at least one shader"); return NULL; } D3D9Pipeline *pipeline = new D3D9Pipeline(device_); for (auto iter : desc.shaders) { if (!iter) { - ELOG("NULL shader passed to CreateGraphicsPipeline"); + ERROR_LOG(G3D, "NULL shader passed to CreateGraphicsPipeline"); delete pipeline; return NULL; } @@ -856,7 +857,7 @@ D3D9InputLayout::D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc HRESULT hr = device->CreateVertexDeclaration(elements, &decl_); if (FAILED(hr)) { - ELOG("Error creating vertex decl"); + ERROR_LOG(G3D, "Error creating vertex decl"); } delete[] elements; } @@ -900,8 +901,7 @@ inline void Transpose4x4(float out[16], const float in[16]) { } void D3D9Context::UpdateDynamicUniformBuffer(const void *ub, size_t size) { - if (size != curPipeline_->dynamicUniforms.uniformBufferSize) - Crash(); + _assert_(size == curPipeline_->dynamicUniforms.uniformBufferSize); for (auto &uniform : curPipeline_->dynamicUniforms.uniforms) { int count = 0; switch (uniform.type) { @@ -935,7 +935,7 @@ void D3D9Context::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offse if (!size) return; if (offset + size > buf->maxSize_) { - ELOG("Can't SubData with bigger size than buffer was created with"); + ERROR_LOG(G3D, "Can't SubData with bigger size than buffer was created with"); return; } if (buf->vbuffer_) { @@ -1104,7 +1104,7 @@ Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) { HRESULT rtResult = device_->CreateTexture(fbo->width, fbo->height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &fbo->tex, NULL); if (FAILED(rtResult)) { - ELOG("Failed to create render target"); + ERROR_LOG(G3D, "Failed to create render target"); delete fbo; return NULL; } @@ -1120,7 +1120,7 @@ Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) { dsResult = device_->CreateDepthStencilSurface(fbo->width, fbo->height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &fbo->depthstencil, NULL); } if (FAILED(dsResult)) { - ELOG("Failed to create depth buffer"); + ERROR_LOG(G3D, "Failed to create depth buffer"); fbo->surf->Release(); fbo->tex->Release(); if (fbo->depthstenciltex) { @@ -1264,13 +1264,13 @@ DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapt #if PPSSPP_API(D3DX9) int d3dx_ver = LoadD3DX9Dynamic(); if (!d3dx_ver) { - ELOG("Failed to load D3DX9!"); + ERROR_LOG(G3D, "Failed to load D3DX9!"); return NULL; } #elif PPSSPP_API(D3D9_D3DCOMPILER) bool result = LoadD3DCompilerDynamic(); if (!result) { - ELOG("Failed to load D3DCompiler!"); + ERROR_LOG(G3D, "Failed to load D3DCompiler!"); return NULL; } #endif diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index b77a8fd4fd..c42b186b54 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -4,7 +4,6 @@ #include #include -#include "base/logging.h" #include "math/dataconv.h" #include "math/math_util.h" #include "math/lin/matrix4x4.h" @@ -230,7 +229,7 @@ GLuint ShaderStageToOpenGL(ShaderStage stage) { class OpenGLShaderModule : public ShaderModule { public: OpenGLShaderModule(GLRenderManager *render, ShaderStage stage, const std::string &tag) : render_(render), stage_(stage), tag_(tag) { - DLOG("Shader module created (%p)", this); + DEBUG_LOG(G3D, "Shader module created (%p)", this); glstage_ = ShaderStageToOpenGL(stage); } @@ -644,7 +643,7 @@ GLuint TypeToTarget(TextureType type) { #endif case TextureType::ARRAY2D: return GL_TEXTURE_2D_ARRAY; default: - ELOG("Bad texture type %d", (int)type); + ERROR_LOG(G3D, "Bad texture type %d", (int)type); return GL_NONE; } } @@ -957,15 +956,15 @@ void OpenGLContext::UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t off Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { if (!desc.shaders.size()) { - ELOG("Pipeline requires at least one shader"); + ERROR_LOG(G3D, "Pipeline requires at least one shader"); return nullptr; } if ((int)desc.prim >= (int)Primitive::PRIMITIVE_TYPE_COUNT) { - ELOG("Invalid primitive type"); + ERROR_LOG(G3D, "Invalid primitive type"); return nullptr; } if (!desc.depthStencil || !desc.blend || !desc.raster || !desc.inputLayout) { - ELOG("Incomplete prim desciption"); + ERROR_LOG(G3D, "Incomplete prim desciption"); return nullptr; } @@ -975,7 +974,7 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { iter->AddRef(); pipeline->shaders.push_back(static_cast(iter)); } else { - ELOG("ERROR: Tried to create graphics pipeline with a null shader module"); + ERROR_LOG(G3D, "ERROR: Tried to create graphics pipeline with a null shader module"); delete pipeline; return nullptr; } @@ -997,7 +996,7 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) { pipeline->inputLayout->AddRef(); return pipeline; } else { - ELOG("Failed to create pipeline - shaders failed to link"); + ERROR_LOG(G3D, "Failed to create pipeline - shaders failed to link"); delete pipeline; return nullptr; } @@ -1059,11 +1058,11 @@ bool OpenGLPipeline::LinkShaders() { if (shader) { linkShaders.push_back(shader); } else { - ELOG("LinkShaders: Bad shader module"); + ERROR_LOG(G3D, "LinkShaders: Bad shader module"); return false; } } else { - ELOG("LinkShaders: Bad shader in module"); + ERROR_LOG(G3D, "LinkShaders: Bad shader in module"); return false; } } @@ -1213,7 +1212,7 @@ void OpenGLInputLayout::Compile(const InputLayoutDesc &desc) { break; case DataFormat::UNDEFINED: default: - ELOG("Thin3DGLVertexFormat: Invalid or unknown component type applied."); + ERROR_LOG(G3D, "Thin3DGLVertexFormat: Invalid or unknown component type applied."); break; } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 7c033aeed3..f6c4dc18b9 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -21,9 +21,6 @@ #include #include -#include "Core/Config.h" - -#include "base/logging.h" #include "base/display.h" #include "base/stringutil.h" #include "image/zim_load.h" @@ -32,10 +29,13 @@ #include "thin3d/thin3d.h" #include "thin3d/VulkanRenderManager.h" +#include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanImage.h" #include "Common/Vulkan/VulkanMemory.h" +#include "Core/Config.h" + // We use a simple descriptor set for all rendering: 1 sampler, 1 texture, 1 UBO binding point. // binding 0 - uniform data // binding 1 - sampler @@ -704,7 +704,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur // Zero-sized textures not allowed. _assert_(desc.width * desc.height * desc.depth > 0); // remember to set depth to 1! if (desc.width * desc.height * desc.depth <= 0) { - ELOG("Bad texture dimensions %dx%dx%d", desc.width, desc.height, desc.depth); + ERROR_LOG(G3D, "Bad texture dimensions %dx%dx%d", desc.width, desc.height, desc.depth); return false; } _assert_(push); @@ -727,7 +727,7 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur } 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_); + ERROR_LOG(G3D, "Failed to create VulkanTexture: %dx%dx%d fmt %d, %d levels", width_, height_, depth_, (int)vulkanFormat, mipLevels_); return false; } if (desc.initData.size()) { @@ -1038,7 +1038,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { for (auto &iter : desc.shaders) { VKShaderModule *vkshader = (VKShaderModule *)iter; if (!vkshader) { - ELOG("CreateGraphicsPipeline got passed a null shader"); + ERROR_LOG(G3D, "CreateGraphicsPipeline got passed a null shader"); return nullptr; } VkPipelineShaderStageCreateInfo &stage = stages[i++]; @@ -1100,7 +1100,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc) { VkPipeline pipelines[2]{}; VkResult result = vkCreateGraphicsPipelines(device_, pipelineCache_, 2, createInfo, nullptr, pipelines); if (result != VK_SUCCESS) { - ELOG("Failed to create graphics pipeline"); + ERROR_LOG(G3D, "Failed to create graphics pipeline"); delete pipeline; return nullptr; } @@ -1177,14 +1177,14 @@ Texture *VKContext::CreateTexture(const TextureDesc &desc) { VkCommandBuffer initCmd = renderManager_.GetInitCmd(); if (!push_ || !initCmd) { // Too early! Fail. - ELOG("Can't create textures before the first frame has started."); + ERROR_LOG(G3D, "Can't create textures before the first frame has started."); return nullptr; } VKTexture *tex = new VKTexture(vulkan_, initCmd, push_, desc); if (tex->Create(initCmd, push_, desc, allocator_)) { return tex; } else { - ELOG("Failed to create texture"); + ERROR_LOG(G3D, "Failed to create texture"); delete tex; return nullptr; } @@ -1271,7 +1271,7 @@ ShaderModule *VKContext::CreateShaderModule(ShaderStage stage, ShaderLanguage la if (shader->Compile(vulkan_, language, data, size)) { return shader; } else { - ELOG("Failed to compile shader: %s", (const char *)data); + ERROR_LOG(G3D, "Failed to compile shader: %s", (const char *)data); shader->Release(); return nullptr; } diff --git a/ext/native/thread/prioritizedworkqueue.cpp b/ext/native/thread/prioritizedworkqueue.cpp index 35a1e94a62..dcb233f38c 100644 --- a/ext/native/thread/prioritizedworkqueue.cpp +++ b/ext/native/thread/prioritizedworkqueue.cpp @@ -1,13 +1,14 @@ #include #include -#include "base/logging.h" #include "base/timeutil.h" #include "thread/prioritizedworkqueue.h" +#include "Common/Log.h" + PrioritizedWorkQueue::~PrioritizedWorkQueue() { if (!done_) { - ELOG("PrioritizedWorkQueue destroyed but not done!"); + ERROR_LOG(SYSTEM, "PrioritizedWorkQueue destroyed but not done!"); } } @@ -32,7 +33,7 @@ void PrioritizedWorkQueue::Flush() { } queue_.clear(); if (flush_count > 0) { - ILOG("PrioritizedWorkQueue: Flushed %d un-executed tasks", flush_count); + INFO_LOG(SYSTEM, "PrioritizedWorkQueue: Flushed %d un-executed tasks", flush_count); } } diff --git a/ext/native/thread/threadpool.cpp b/ext/native/thread/threadpool.cpp index a312748014..6f5a83d255 100644 --- a/ext/native/thread/threadpool.cpp +++ b/ext/native/thread/threadpool.cpp @@ -1,6 +1,7 @@ -#include "base/logging.h" #include "thread/threadpool.h" #include "thread/threadutil.h" + +#include "Common/Log.h" #include "Common/MakeUnique.h" ///////////////////////////// WorkerThread @@ -86,9 +87,9 @@ void LoopWorkerThread::WorkFunc() { ThreadPool::ThreadPool(int numThreads) { if (numThreads <= 0) { numThreads_ = 1; - ILOG("ThreadPool: Bad number of threads %i", numThreads); + INFO_LOG(JIT, "ThreadPool: Bad number of threads %d", numThreads); } else if (numThreads > 8) { - ILOG("ThreadPool: Capping number of threads to 8 (was %i)", numThreads); + INFO_LOG(JIT, "ThreadPool: Capping number of threads to 8 (was %d)", numThreads); numThreads_ = 8; } else { numThreads_ = numThreads; diff --git a/ext/native/thread/threadutil.cpp b/ext/native/thread/threadutil.cpp index 403f8cadd9..a47286b96f 100644 --- a/ext/native/thread/threadutil.cpp +++ b/ext/native/thread/threadutil.cpp @@ -8,10 +8,13 @@ #define TLS_SUPPORTED #endif +#include + #include "base/basictypes.h" -#include "base/logging.h" #include "thread/threadutil.h" +#include "Common/Log.h" + #if defined(__ANDROID__) || defined(__APPLE__) || (defined(__GLIBC__) && defined(_GNU_SOURCE)) #include #endif @@ -115,7 +118,7 @@ void setCurrentThreadName(const char* threadName) { void AssertCurrentThreadName(const char *threadName) { #ifdef TLS_SUPPORTED if (strcmp(curThreadName, threadName) != 0) { - ELOG("Thread name assert failed: Expected %s, was %s", threadName, curThreadName); + ERROR_LOG(SYSTEM, "Thread name assert failed: Expected %s, was %s", threadName, curThreadName); } #endif } diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index 460945204c..928d34dbfe 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -7,6 +7,8 @@ #include "ui/root.h" #include "ui/viewgroup.h" +#include "Common/Log.h" + namespace UI { static std::mutex focusLock; @@ -109,7 +111,7 @@ bool IsFocusMovementEnabled() { void LayoutViewHierarchy(const UIContext &dc, ViewGroup *root, bool ignoreInsets) { if (!root) { - ELOG("Tried to layout a view hierarchy from a zero pointer root"); + ERROR_LOG(SYSTEM, "Tried to layout a view hierarchy from a zero pointer root"); return; } @@ -358,7 +360,7 @@ void UpdateViewHierarchy(ViewGroup *root) { frameCount++; if (!root) { - ELOG("Tried to update a view hierarchy from a zero pointer root"); + ERROR_LOG(SYSTEM, "Tried to update a view hierarchy from a zero pointer root"); return; } diff --git a/ext/native/ui/screen.cpp b/ext/native/ui/screen.cpp index 3b99486d69..32a26196cc 100644 --- a/ext/native/ui/screen.cpp +++ b/ext/native/ui/screen.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/logging.h" #include "base/timeutil.h" #include "input/input_state.h" #include "ui/root.h" @@ -7,6 +6,8 @@ #include "ui/ui.h" #include "ui/view.h" +#include "Common/Log.h" + ScreenManager::ScreenManager() { uiContext_ = 0; dialogFinished_ = 0; @@ -18,7 +19,7 @@ ScreenManager::~ScreenManager() { void ScreenManager::switchScreen(Screen *screen) { if (!nextStack_.empty() && screen == nextStack_.front().screen) { - ELOG("Already switching to this screen"); + ERROR_LOG(SYSTEM, "Already switching to this screen"); return; } // Note that if a dialog is found, this will be a silent background switch that @@ -26,12 +27,12 @@ void ScreenManager::switchScreen(Screen *screen) { // until that switch. // TODO: is this still true? if (!nextStack_.empty()) { - ELOG("Already had a nextStack_! Asynchronous open while doing something? Deleting the new screen."); + ERROR_LOG(SYSTEM, "Already had a nextStack_! Asynchronous open while doing something? Deleting the new screen."); delete screen; return; } if (screen == nullptr) { - WLOG("Swiching to a zero screen, this can't be good"); + WARN_LOG(SYSTEM, "Switching to a zero screen, this can't be good"); } if (stack_.empty() || screen != stack_.back().screen) { screen->setScreenManager(this); @@ -53,7 +54,7 @@ void ScreenManager::update() { void ScreenManager::switchToNext() { std::lock_guard guard(inputLock_); if (nextStack_.empty()) { - ELOG("switchToNext: No nextStack_!"); + ERROR_LOG(SYSTEM, "switchToNext: No nextStack_!"); } Layer temp = {nullptr, 0}; @@ -128,7 +129,7 @@ void ScreenManager::deviceRestored() { } void ScreenManager::resized() { - ILOG("ScreenManager::resized(dp: %dx%d)", dp_xres, dp_yres); + INFO_LOG(SYSTEM, "ScreenManager::resized(dp: %dx%d)", dp_xres, dp_yres); std::lock_guard guard(inputLock_); // Have to notify the whole stack, otherwise there will be problems when going back // to non-top screens. @@ -143,7 +144,7 @@ void ScreenManager::render() { case LAYER_SIDEMENU: case LAYER_TRANSPARENT: if (stack_.size() == 1) { - ELOG("Can't have sidemenu over nothing"); + ERROR_LOG(SYSTEM, "Can't have sidemenu over nothing"); break; } else { auto iter = stack_.end(); @@ -170,7 +171,7 @@ void ScreenManager::render() { break; } } else { - ELOG("No current screen!"); + ERROR_LOG(SYSTEM, "No current screen!"); } processFinishDialog(); @@ -235,7 +236,7 @@ void ScreenManager::pop() { delete stack_.back().screen; stack_.pop_back(); } else { - ELOG("Can't pop when stack empty"); + ERROR_LOG(SYSTEM, "Can't pop when stack empty"); } } @@ -247,11 +248,11 @@ void ScreenManager::RecreateAllViews() { void ScreenManager::finishDialog(Screen *dialog, DialogResult result) { if (stack_.empty()) { - ELOG("Must be in a dialog to finishDialog"); + ERROR_LOG(SYSTEM, "Must be in a dialog to finishDialog"); return; } if (dialog != stack_.back().screen) { - ELOG("Wrong dialog being finished!"); + ERROR_LOG(SYSTEM, "Wrong dialog being finished!"); return; } dialog->onFinish(result); @@ -283,10 +284,10 @@ void ScreenManager::processFinishDialog() { } if (!caller) { - ELOG("ERROR: no top screen when finishing dialog"); + ERROR_LOG(SYSTEM, "ERROR: no top screen when finishing dialog"); } else if (caller != topScreen()) { // The caller may get confused if we call dialogFinished() now. - WLOG("Skipping non-top dialog when finishing dialog."); + WARN_LOG(SYSTEM, "Skipping non-top dialog when finishing dialog."); } else { caller->dialogFinished(dialogFinished_, dialogResult_); } diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index 22cc79c24b..c1dbfd4729 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -4,7 +4,6 @@ #include "base/display.h" #include "base/NativeApp.h" -#include "base/logging.h" #include "ui/ui.h" #include "ui/view.h" #include "ui/ui_context.h" diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 180e271aae..ca36957b62 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -1,6 +1,7 @@ #include #include #include + #include "base/display.h" #include "base/stringutil.h" #include "input/input_state.h" @@ -13,6 +14,8 @@ #include "i18n/i18n.h" #include "gfx_es2/draw_buffer.h" +#include "Common/Log.h" + static const bool ClickDebug = false; UIScreen::UIScreen() @@ -137,11 +140,11 @@ TouchInput UIScreen::transformTouch(const TouchInput &touch) { bool UIScreen::touch(const TouchInput &touch) { if (root_) { if (ClickDebug && (touch.flags & TOUCH_DOWN)) { - ILOG("Touch down!"); + INFO_LOG(SYSTEM, "Touch down!"); std::vector views; root_->Query(touch.x, touch.y, views); for (auto view : views) { - ILOG("%s", view->Describe().c_str()); + INFO_LOG(SYSTEM, "%s", view->Describe().c_str()); } } @@ -166,7 +169,7 @@ bool UIDialogScreen::key(const KeyInput &key) { bool retval = UIScreen::key(key); if (!retval && (key.flags & KEY_DOWN) && UI::IsEscapeKey(key)) { if (finished_) { - ELOG("Screen already finished"); + ERROR_LOG(SYSTEM, "Screen already finished"); } else { finished_ = true; TriggerFinish(DR_BACK); diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index 82a74faad8..cf96bc8db3 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -2,7 +2,6 @@ #include #include -#include "base/logging.h" #include "base/stringutil.h" #include "base/timeutil.h" #include "input/keycodes.h" @@ -14,6 +13,8 @@ #include "ui/viewgroup.h" #include "gfx_es2/draw_buffer.h" +#include "Common/Log.h" + #include namespace UI { @@ -236,7 +237,7 @@ float GetDirectionScore(View *origin, View *destination, FocusDirection directio float horizOverlap = HorizontalOverlap(origin->GetBounds(), destination->GetBounds()); float vertOverlap = VerticalOverlap(origin->GetBounds(), destination->GetBounds()); if (horizOverlap == 1.0f && vertOverlap == 1.0f) { - ILOG("Contain overlap"); + INFO_LOG(SYSTEM, "Contain overlap"); return 0.0; } float originSize = 0.0f; @@ -273,7 +274,7 @@ float GetDirectionScore(View *origin, View *destination, FocusDirection directio break; case FOCUS_PREV: case FOCUS_NEXT: - ELOG("Invalid focus direction"); + ERROR_LOG(SYSTEM, "Invalid focus direction"); break; } @@ -1083,7 +1084,7 @@ void AnchorLayout::Layout() { GridLayout::GridLayout(GridLayoutSettings settings, LayoutParams *layoutParams) : ViewGroup(layoutParams), settings_(settings), numColumns_(1) { if (settings.orientation != ORIENT_HORIZONTAL) - ELOG("GridLayout: Vertical layouts not yet supported"); + ERROR_LOG(SYSTEM, "GridLayout: Vertical layouts not yet supported"); } void GridLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index 30a9f1b7b2..d52dfc4053 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -17,8 +17,10 @@ #include +#include "base/logging.h" // For OutputDebugStringUTF8 #include "headless/WindowsHeadlessHost.h" +#include "Common/Log.h" #include "Common/FileUtil.h" #include "Common/CommonWindows.h" From cca7511e6a98495bf8c83946f6030c9d2bbeeef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 16:17:08 +0200 Subject: [PATCH 503/848] More base/logging.h cleanup --- Common/GL/GLInterface/EGL.cpp | 3 +-- Common/GL/GLInterface/EGL.h | 12 +----------- ext/native/tools/atlastool.cpp | 20 ++++++++++---------- ext/native/tools/zimtool.cpp | 1 - 4 files changed, 12 insertions(+), 24 deletions(-) diff --git a/Common/GL/GLInterface/EGL.cpp b/Common/GL/GLInterface/EGL.cpp index fb215af598..5f3c782f2c 100644 --- a/Common/GL/GLInterface/EGL.cpp +++ b/Common/GL/GLInterface/EGL.cpp @@ -5,9 +5,8 @@ #include #include -#include "Common/GL/GLInterface/EGL.h" - #include "Common/Log.h" +#include "Common/GL/GLInterface/EGL.h" // Show the current FPS void cInterfaceEGL::Swap() { diff --git a/Common/GL/GLInterface/EGL.h b/Common/GL/GLInterface/EGL.h index 65169b91da..e9d789748c 100644 --- a/Common/GL/GLInterface/EGL.h +++ b/Common/GL/GLInterface/EGL.h @@ -7,22 +7,12 @@ #include #include +#include "Common/Log.h" #include "Common/GL/GLInterfaceBase.h" -#ifdef __ANDROID__ -// On Android, EGL creation is so early that our regular logging system is not -// up and running yet. Use Android logging. -#include "base/logging.h" -#define EGL_ILOG(...) ILOG(__VA_ARGS__) -#define EGL_ELOG(...) ELOG(__VA_ARGS__) - -#else - #define EGL_ILOG(...) INFO_LOG(G3D, __VA_ARGS__) #define EGL_ELOG(...) INFO_LOG(G3D, __VA_ARGS__) -#endif - class cInterfaceEGL : public cInterfaceBase { public: diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp index 86581c7f34..05c111f59f 100644 --- a/ext/native/tools/atlastool.cpp +++ b/ext/native/tools/atlastool.cpp @@ -18,6 +18,7 @@ // line height // dist-per-pixel +#include #include #include #include @@ -28,7 +29,6 @@ #include #include -#include "base/logging.h" #include "gfx/texture_atlas.h" #include "image/png_load.h" @@ -109,8 +109,8 @@ struct Image { return (int)dat.size(); } void copyfrom(const Image &img, int ox, int oy, Effect effect) { - CHECK(img.dat[0].size() + ox <= dat[0].size()); - CHECK(img.dat.size() + oy <= dat.size()); + assert(img.dat[0].size() + ox <= dat[0].size()); + assert(img.dat.size() + oy <= dat.size()); for (int y = 0; y < (int)img.dat.size(); y++) { for (int x = 0; x < (int)img.dat[y].size(); x++) { switch (effect) { @@ -171,9 +171,9 @@ struct Image { png_structp png_ptr; png_infop info_ptr; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - CHECK(png_ptr); + assert(png_ptr); info_ptr = png_create_info_struct(png_ptr); - CHECK(info_ptr); + assert(info_ptr); png_init_io(png_ptr, fil); //png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); png_set_IHDR(png_ptr, info_ptr, (uint32_t)dat[0].size(), (uint32_t)dat.size(), 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); @@ -248,7 +248,7 @@ struct Bucket { int idx = (int)items[i].first.dat[0].size(); int idy = (int)items[i].first.dat.size(); if (idx > 1 && idy > 1) { - CHECK(idx <= image_width); + assert(idx <= image_width); for (int ty = 0; ty < 2047; ty++) { if (ty + idy + 1 > (int)dest.dat.size()) { masq.resize(image_width, ty + idy + 16); @@ -355,7 +355,7 @@ inline vector merge(const vector &a, const vector &ranges, float *metrics_height, Bucket *bucket) { FT_Library freetype; - CHECK(FT_Init_FreeType(&freetype) == 0); + assert(FT_Init_FreeType(&freetype) == 0); vector fonts; fonts.resize(fontRefs.size()); @@ -374,7 +374,7 @@ void RasterizeFonts(const FontReferenceList &fontRefs, vector &ranges } printf("TTF info: %d glyphs, %08x flags, %d units, %d strikes\n", (int)font->num_glyphs, (int)font->face_flags, (int)font->units_per_EM, (int)font->num_fixed_sizes); - CHECK(FT_Set_Pixel_Sizes(font, 0, fontRefs[i].size_ * supersample) == 0); + assert(FT_Set_Pixel_Sizes(font, 0, fontRefs[i].size_ * supersample) == 0); ranges = merge(ranges, fontRefs[i].ranges_); for (size_t r = 0, rn = fontRefs[i].ranges_.size(); r < rn; ++r) { @@ -858,10 +858,10 @@ int main(int argc, char **argv) { // /usr/share/fonts/truetype/msttcorefonts/Arial_Black.ttf // /usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf if (argc < 3) { - FLOG("Not enough arguments"); + printf("Not enough arguments"); return 1; } - CHECK(argc >= 3); + assert(argc >= 3); if (argc > 3) { if (!strcmp(argv[3], "8888")) { highcolor = true; diff --git a/ext/native/tools/zimtool.cpp b/ext/native/tools/zimtool.cpp index 3692881643..7fadb4218b 100644 --- a/ext/native/tools/zimtool.cpp +++ b/ext/native/tools/zimtool.cpp @@ -2,7 +2,6 @@ #include #include -#include "base/logging.h" #include "image/png_load.h" #include "image/zim_save.h" From b22083e7a6ae04a6612fb35ca582293d53e1ca9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 16:21:30 +0200 Subject: [PATCH 504/848] Even more base/logging.h removal and fixes --- Common/Log.h | 3 +++ Common/LogManager.cpp | 22 +++++++++++++++++++++- Core/Debugger/WebSocket/WebSocketUtils.h | 2 +- GPU/Directx9/ShaderManagerDX9.cpp | 1 - GPU/Directx9/StencilBufferDX9.cpp | 1 - GPU/Vulkan/VulkanUtil.cpp | 2 -- SDL/SDLMain.cpp | 2 +- ext/native/base/logging.h | 3 --- ext/native/base/stringutil.cpp | 21 --------------------- ext/native/json/json_reader.h | 2 +- ext/native/thin3d/GLQueueRunner.cpp | 20 +++++++++----------- headless/WindowsHeadlessHost.cpp | 3 +-- 12 files changed, 37 insertions(+), 45 deletions(-) diff --git a/Common/Log.h b/Common/Log.h index 481795bde2..8dc232319c 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -189,3 +189,6 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * } #endif // __ANDROID__ + +// Just INFO_LOGs on nonWindows. On Windows it outputs to the VS output console. +void OutputDebugStringUTF8(const char *p); diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index f16971c70c..3c4de05878 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -19,7 +19,6 @@ #include -#include "base/logging.h" #include "util/text/utf8.h" #include "LogManager.h" #include "ConsoleListener.h" @@ -325,3 +324,24 @@ void RingbufferLogListener::Log(const LogMessage &message) { curMessage_ -= MAX_LOGS; count_++; } + +#ifdef _WIN32 + +void OutputDebugStringUTF8(const char *p) { + wchar_t temp[4096]; + + int len = std::min(4095, (int)strlen(p)); + int size = (int)MultiByteToWideChar(CP_UTF8, 0, p, len, NULL, 0); + MultiByteToWideChar(CP_UTF8, 0, p, len, temp, size); + temp[size] = 0; + + OutputDebugString(temp); +} + +#else + +void OutputDebugStringUTF8(const char *p) { + INFO_LOG(SYSTEM, "%s", p); +} + +#endif diff --git a/Core/Debugger/WebSocket/WebSocketUtils.h b/Core/Debugger/WebSocket/WebSocketUtils.h index 93110db6a0..0da36402c9 100644 --- a/Core/Debugger/WebSocket/WebSocketUtils.h +++ b/Core/Debugger/WebSocket/WebSocketUtils.h @@ -56,7 +56,7 @@ struct DebuggerErrorEvent { LogTypes::LOG_LEVELS level; std::string ticketRaw; - operator std::string() { + operator std::string() const { JsonWriter j; j.begin(); j.writeString("event", "error"); diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 15cb7777e8..fd64cb4570 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -23,7 +23,6 @@ #include #include "gfx/d3d9_shader.h" -#include "base/logging.h" // For OutputDebugStringUTF8 #include "base/stringutil.h" #include "i18n/i18n.h" #include "math/lin/matrix4x4.h" diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 722a43b31f..4310a1654e 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -17,7 +17,6 @@ #include -#include "base/logging.h" // For OutputDebugStringUTF8 #include "gfx/d3d9_state.h" #include "ext/native/thin3d/thin3d.h" #include "Core/Reporting.h" diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index 3d5d196e94..0e653be2b1 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -15,8 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" // For OutputDebugStringUTF8. TODO: Move it. - #include "base/basictypes.h" #include "base/stringutil.h" #include "Common/Log.h" diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 9bacb7de9f..f385475e66 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -22,7 +22,7 @@ SDLJoystick *joystick = NULL; #include #include "base/display.h" -#include "base/logging.h" +#include "base/logging.h" // early logging. TODO: Remove. #include "base/timeutil.h" #include "ext/glslang/glslang/Public/ShaderLang.h" #include "image/png_load.h" diff --git a/ext/native/base/logging.h b/ext/native/base/logging.h index 3a22a428fc..c364b8f406 100644 --- a/ext/native/base/logging.h +++ b/ext/native/base/logging.h @@ -46,9 +46,6 @@ inline void Crash() { #endif -// Just ILOGs on nonWindows. On Windows it outputs to the VS output console. -void OutputDebugStringUTF8(const char *p); - #if defined(__ANDROID__) #include diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp index ce2e1094fb..adcd94b20a 100644 --- a/ext/native/base/stringutil.cpp +++ b/ext/native/base/stringutil.cpp @@ -21,27 +21,6 @@ #include "base/buffer.h" #include "base/stringutil.h" -#ifdef _WIN32 - -void OutputDebugStringUTF8(const char *p) { - wchar_t temp[4096]; - - int len = std::min(4095, (int)strlen(p)); - int size = (int)MultiByteToWideChar(CP_UTF8, 0, p, len, NULL, 0); - MultiByteToWideChar(CP_UTF8, 0, p, len, temp, size); - temp[size] = 0; - - OutputDebugString(temp); -} - -#else - -void OutputDebugStringUTF8(const char *p) { - INFO_LOG(SYSTEM, "%s", p); -} - -#endif - std::string LineNumberString(const std::string &str) { std::stringstream input(str); std::stringstream output; diff --git a/ext/native/json/json_reader.h b/ext/native/json/json_reader.h index 472a19140d..612a7f9d2f 100644 --- a/ext/native/json/json_reader.h +++ b/ext/native/json/json_reader.h @@ -1,9 +1,9 @@ +#include #include #include #include "base/basictypes.h" #include "ext/gason/gason.h" - #include "Common/Log.h" namespace json { diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 72ca079602..49698384bd 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -1,7 +1,5 @@ #include -#include "base/logging.h" // For OutputDebugStringUTF8 - #include "base/stringutil.h" #include "gfx/gl_common.h" #include "gfx/gl_debug_log.h" @@ -443,7 +441,7 @@ void GLQueueRunner::InitCreateFramebuffer(const GLRInitStep &step) { retry_depth: if (!fbo->z_stencil_) { - ILOG("Creating %i x %i FBO using no depth", fbo->width, fbo->height); + INFO_LOG(G3D, "Creating %d x %d FBO using no depth", fbo->width, fbo->height); fbo->z_stencil_buffer = 0; fbo->stencil_buffer = 0; @@ -456,7 +454,7 @@ retry_depth: glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); } else if (gl_extensions.IsGLES) { if (gl_extensions.OES_packed_depth_stencil && (gl_extensions.OES_depth_texture || gl_extensions.GLES3)) { - ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8 texture", fbo->width, fbo->height); + INFO_LOG(G3D, "Creating %d x %d FBO using DEPTH24_STENCIL8 texture", fbo->width, fbo->height); fbo->z_stencil_buffer = 0; fbo->stencil_buffer = 0; fbo->z_buffer = 0; @@ -477,7 +475,7 @@ retry_depth: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, fbo->z_stencil_texture.texture, 0); } } else if (gl_extensions.OES_packed_depth_stencil) { - ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8", fbo->width, fbo->height); + INFO_LOG(G3D, "Creating %d x %d FBO using DEPTH24_STENCIL8", fbo->width, fbo->height); // Standard method fbo->stencil_buffer = 0; fbo->z_buffer = 0; @@ -492,7 +490,7 @@ retry_depth: glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->z_stencil_buffer); } else { - ILOG("Creating %i x %i FBO using separate stencil", fbo->width, fbo->height); + INFO_LOG(G3D, "Creating %d x %d FBO using separate stencil", fbo->width, fbo->height); // TEGRA fbo->z_stencil_buffer = 0; // 16/24-bit Z, separate 8-bit stencil @@ -513,7 +511,7 @@ retry_depth: glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->stencil_buffer); } } else if (gl_extensions.VersionGEThan(3, 0)) { - ILOG("Creating %i x %i FBO using DEPTH24_STENCIL8 texture", fbo->width, fbo->height); + INFO_LOG(G3D, "Creating %d x %d FBO using DEPTH24_STENCIL8 texture", fbo->width, fbo->height); fbo->z_stencil_buffer = 0; fbo->stencil_buffer = 0; fbo->z_buffer = 0; @@ -549,7 +547,7 @@ retry_depth: switch (status) { case GL_FRAMEBUFFER_COMPLETE: - // ILOG("Framebuffer verified complete."); + // INFO_LOG(G3D, "Framebuffer verified complete."); break; case GL_FRAMEBUFFER_UNSUPPORTED: ERROR_LOG(G3D, "GL_FRAMEBUFFER_UNSUPPORTED"); @@ -558,7 +556,7 @@ retry_depth: ERROR_LOG(G3D, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; default: - FLOG("Other framebuffer error: %i", status); + _assert_msg_(false, "Other framebuffer error: %d", status); break; } @@ -1568,7 +1566,7 @@ void GLQueueRunner::fbo_ext_create(const GLRInitStep &step) { GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); switch (status) { case GL_FRAMEBUFFER_COMPLETE_EXT: - // ILOG("Framebuffer verified complete."); + // INFO_LOG(G3D, "Framebuffer verified complete."); break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: ERROR_LOG(G3D, "GL_FRAMEBUFFER_UNSUPPORTED"); @@ -1577,7 +1575,7 @@ void GLQueueRunner::fbo_ext_create(const GLRInitStep &step) { ERROR_LOG(G3D, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); break; default: - FLOG("Other framebuffer error: %i", status); + _assert_msg_(false, "Other framebuffer error: %d", status); break; } // Unbind state we don't need diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index d52dfc4053..18b90d72bf 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -15,9 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include +#include -#include "base/logging.h" // For OutputDebugStringUTF8 #include "headless/WindowsHeadlessHost.h" #include "Common/Log.h" From 80e0f85332076c187b80d41fa8a640f5a9bc4309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 16:25:50 +0200 Subject: [PATCH 505/848] Getting really close to getting rid of base/logging.h now. Qt buildfix --- Common/FakeCPUDetect.cpp | 1 - Common/LogManager.cpp | 4 ++ Common/XboxCPUDetect.cpp | 68 ---------------------------- Core/MIPS/fake/FakeJit.cpp | 1 - GPU/Common/VertexDecoderFake.cpp | 1 - Qt/QtMain.cpp | 30 ++++++------ SDL/SDLGLGraphicsContext.cpp | 2 +- SDL/SDLMain.cpp | 31 ++++++------- UI/NativeApp.cpp | 38 ++++++++-------- UWP/PPSSPP_UWPMain.cpp | 4 +- UWP/StorageFileLoader.cpp | 8 ++-- android/jni/Arm64EmitterTest.cpp | 25 +++++----- android/jni/ArmEmitterTest.cpp | 23 +++++----- android/jni/TestRunner.cpp | 18 ++++---- ext/native/base/logging.cpp | 2 +- ext/native/file/zip_read.cpp | 6 +-- ext/native/gfx_es2/draw_text_qt.cpp | 2 +- ext/native/gfx_es2/draw_text_uwp.cpp | 8 ++-- ext/native/tools/audiotool.cpp | 17 ------- ios/ViewController.mm | 7 +-- unittest/UnitTest.cpp | 16 +++---- 21 files changed, 113 insertions(+), 199 deletions(-) delete mode 100644 Common/XboxCPUDetect.cpp delete mode 100644 ext/native/tools/audiotool.cpp diff --git a/Common/FakeCPUDetect.cpp b/Common/FakeCPUDetect.cpp index 41251b698a..d314afe773 100644 --- a/Common/FakeCPUDetect.cpp +++ b/Common/FakeCPUDetect.cpp @@ -17,7 +17,6 @@ #include -#include "base/logging.h" #include "base/basictypes.h" #include "Common.h" #include "CPUDetect.h" diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 3c4de05878..c1eef5d2fb 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -18,6 +18,7 @@ #include "ppsspp_config.h" #include +#include #include "util/text/utf8.h" #include "LogManager.h" @@ -46,6 +47,9 @@ void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char LogManager *instance = LogManager::GetInstance(); if (instance) { instance->Log(level, type, file, line, fmt, args); + } else { + // Fall back to printf if we're before the log manager has been initialized. + vprintf(fmt, args); } va_end(args); } diff --git a/Common/XboxCPUDetect.cpp b/Common/XboxCPUDetect.cpp deleted file mode 100644 index b9b502a71a..0000000000 --- a/Common/XboxCPUDetect.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - - -#include -#include "base/logging.h" -#include "base/basictypes.h" -#include "Common.h" -#include "CPUDetect.h" -#include "StringUtils.h" - -CPUInfo cpu_info; - -CPUInfo::CPUInfo() { - Detect(); -} - -// Detects the various cpu features -void CPUInfo::Detect() -{ - memset(this, 0, sizeof(*this)); - num_cores = 3; - strcpy(cpu_string, "Xenon"); - strcpy(brand_string, "Microsoft"); - - memset(cpu_string, 0, sizeof(cpu_string)); - - HTT = true; - logical_cpu_count = 2; -} - -// Turn the cpu info into a string we can show -std::string CPUInfo::Summarize() -{ - std::string sum; - if (num_cores == 1) - sum = StringFromFormat("%s, %i core", cpu_string, num_cores); - else - { - sum = StringFromFormat("%s, %i cores", cpu_string, num_cores); - if (HTT) sum += StringFromFormat(" (%i logical threads per physical core)", logical_cpu_count); - } - if (bSSE) sum += ", SSE"; - if (bSSE2) sum += ", SSE2"; - if (bSSE3) sum += ", SSE3"; - if (bSSSE3) sum += ", SSSE3"; - if (bSSE4_1) sum += ", SSE4.1"; - if (bSSE4_2) sum += ", SSE4.2"; - if (HTT) sum += ", HTT"; - if (bAVX) sum += ", AVX"; - if (bAES) sum += ", AES"; - if (bLongMode) sum += ", 64-bit support"; - return sum; -} \ No newline at end of file diff --git a/Core/MIPS/fake/FakeJit.cpp b/Core/MIPS/fake/FakeJit.cpp index 25e085c0ed..257005a429 100644 --- a/Core/MIPS/fake/FakeJit.cpp +++ b/Core/MIPS/fake/FakeJit.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/logging.h" #include "Common/Serialize/Serializer.h" #include "Core/Reporting.h" #include "Core/Config.h" diff --git a/GPU/Common/VertexDecoderFake.cpp b/GPU/Common/VertexDecoderFake.cpp index 1619b2ba0f..af27e69561 100644 --- a/GPU/Common/VertexDecoderFake.cpp +++ b/GPU/Common/VertexDecoderFake.cpp @@ -18,7 +18,6 @@ //TODO: Doesn't build, FIXME! #if 0 -#include "base/logging.h" #include "Common/CPUDetect.h" #include "Core/Config.h" #include "Core/Reporting.h" diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 7f9726b417..2ba3a2e630 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -71,23 +71,23 @@ static void InitSDLAudioDevice() { if (!g_Config.sAudioDevice.empty()) { audioDev = SDL_OpenAudioDevice(g_Config.sAudioDevice.c_str(), 0, &fmt, &g_retFmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); if (audioDev <= 0) { - WLOG("Failed to open preferred audio device %s", g_Config.sAudioDevice.c_str()); + WARN_LOG(AUDIO, "Failed to open preferred audio device %s", g_Config.sAudioDevice.c_str()); } } if (audioDev <= 0) { audioDev = SDL_OpenAudioDevice(nullptr, 0, &fmt, &g_retFmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); } if (audioDev <= 0) { - ELOG("Failed to open audio: %s", SDL_GetError()); + ERROR_LOG(AUDIO, "Failed to open audio: %s", SDL_GetError()); } else { if (g_retFmt.samples != fmt.samples) // Notify, but still use it - ELOG("Output audio samples: %d (requested: %d)", g_retFmt.samples, fmt.samples); + ERROR_LOG(AUDIO, "Output audio samples: %d (requested: %d)", g_retFmt.samples, fmt.samples); if (g_retFmt.format != fmt.format || g_retFmt.channels != fmt.channels) { - ELOG("Sound buffer format does not match requested format."); - ELOG("Output audio freq: %d (requested: %d)", g_retFmt.freq, fmt.freq); - ELOG("Output audio format: %d (requested: %d)", g_retFmt.format, fmt.format); - ELOG("Output audio channels: %d (requested: %d)", g_retFmt.channels, fmt.channels); - ELOG("Provided output format does not match requirement, turning audio off"); + ERROR_LOG(AUDIO, "Sound buffer format does not match requested format."); + ERROR_LOG(AUDIO, "Output audio freq: %d (requested: %d)", g_retFmt.freq, fmt.freq); + ERROR_LOG(AUDIO, "Output audio format: %d (requested: %d)", g_retFmt.format, fmt.format); + ERROR_LOG(AUDIO, "Output audio channels: %d (requested: %d)", g_retFmt.channels, fmt.channels); + ERROR_LOG(AUDIO, "Provided output format does not match requirement, turning audio off"); SDL_CloseAudioDevice(audioDev); } SDL_PauseAudioDevice(audioDev, 0); @@ -343,9 +343,9 @@ MainUI::MainUI(QWidget *parent) } MainUI::~MainUI() { - ILOG("MainUI::Destructor"); + INFO_LOG(SYSTEM, "MainUI::Destructor"); if (emuThreadState != (int)EmuThreadState::DISABLED) { - ILOG("EmuThreadStop"); + INFO_LOG(SYSTEM, "EmuThreadStop"); EmuThreadStop(); while (graphicsContext->ThreadFrame()) { // Need to keep eating frames to allow the EmuThread to exit correctly. @@ -525,7 +525,7 @@ bool MainUI::event(QEvent *e) { void MainUI::initializeGL() { if (g_Config.iGPUBackend != (int)GPUBackend::OPENGL) { - ILOG("Only GL supported under Qt - switching."); + INFO_LOG(SYSTEM, "Only GL supported under Qt - switching."); g_Config.iGPUBackend = (int)GPUBackend::OPENGL; } @@ -545,12 +545,12 @@ void MainUI::initializeGL() { #endif if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) { // OpenGL uses a background thread to do the main processing and only renders on the gl thread. - ILOG("Initializing GL graphics context"); + INFO_LOG(SYSTEM, "Initializing GL graphics context"); graphicsContext = new QtGLGraphicsContext(); - ILOG("Using thread, starting emu thread"); + INFO_LOG(SYSTEM, "Using thread, starting emu thread"); EmuThreadStart(); } else { - ILOG("Not using thread, backend=%d", (int)g_Config.iGPUBackend); + INFO_LOG(SYSTEM, "Not using thread, backend=%d", (int)g_Config.iGPUBackend); } graphicsContext->ThreadStart(); } @@ -714,7 +714,7 @@ int main(int argc, char *argv[]) g_Config.iGPUBackend = (int)GPUBackend::OPENGL; int ret = mainInternal(a); - ILOG("Left mainInternal here."); + INFO_LOG(SYSTEM, "Left mainInternal here."); #ifdef SDL if (audioDev > 0) { diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index 772f5c764f..e99c15ed75 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -425,7 +425,7 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: }); renderManager_->SetSwapIntervalFunction([&](int interval) { - ILOG("SDL SwapInterval: %d", interval); + INFO_LOG(G3D, "SDL SwapInterval: %d", interval); SDL_GL_SetSwapInterval(interval); }); window_ = window; diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index f385475e66..6c882b5681 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -22,7 +22,6 @@ SDLJoystick *joystick = NULL; #include #include "base/display.h" -#include "base/logging.h" // early logging. TODO: Remove. #include "base/timeutil.h" #include "ext/glslang/glslang/Public/ShaderLang.h" #include "image/png_load.h" @@ -110,24 +109,24 @@ static void InitSDLAudioDevice(const std::string &name = "") { if (!startDevice.empty()) { audioDev = SDL_OpenAudioDevice(startDevice.c_str(), 0, &fmt, &g_retFmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); if (audioDev <= 0) { - WLOG("Failed to open audio device: %s", startDevice.c_str()); + WARN_LOG(AUDIO, "Failed to open audio device: %s", startDevice.c_str()); } } if (audioDev <= 0) { - ILOG("SDL: Trying a different audio device"); + INFO_LOG(AUDIO, "SDL: Trying a different audio device"); audioDev = SDL_OpenAudioDevice(nullptr, 0, &fmt, &g_retFmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); } if (audioDev <= 0) { - ELOG("Failed to open audio device: %s", SDL_GetError()); + ERROR_LOG(AUDIO, "Failed to open audio device: %s", SDL_GetError()); } else { if (g_retFmt.samples != fmt.samples) // Notify, but still use it - ELOG("Output audio samples: %d (requested: %d)", g_retFmt.samples, fmt.samples); + ERROR_LOG(AUDIO, "Output audio samples: %d (requested: %d)", g_retFmt.samples, fmt.samples); if (g_retFmt.format != fmt.format || g_retFmt.channels != fmt.channels) { - ELOG("Sound buffer format does not match requested format."); - ELOG("Output audio freq: %d (requested: %d)", g_retFmt.freq, fmt.freq); - ELOG("Output audio format: %d (requested: %d)", g_retFmt.format, fmt.format); - ELOG("Output audio channels: %d (requested: %d)", g_retFmt.channels, fmt.channels); - ELOG("Provided output format does not match requirement, turning audio off"); + ERROR_LOG(AUDIO, "Sound buffer format does not match requested format."); + ERROR_LOG(AUDIO, "Output audio freq: %d (requested: %d)", g_retFmt.freq, fmt.freq); + ERROR_LOG(AUDIO, "Output audio format: %d (requested: %d)", g_retFmt.format, fmt.format); + ERROR_LOG(AUDIO, "Output audio channels: %d (requested: %d)", g_retFmt.channels, fmt.channels); + ERROR_LOG(AUDIO, "Provided output format does not match requirement, turning audio off"); SDL_CloseAudioDevice(audioDev); } SDL_PauseAudioDevice(audioDev, 0); @@ -206,7 +205,7 @@ void LaunchBrowser(const char *url) { webWifiCreate(&conf, NULL, url, uuid, 0); webWifiShow(&conf, NULL); #elif defined(MOBILE_DEVICE) - ILOG("Would have gone to %s but LaunchBrowser is not implemented on this platform", url); + INFO_LOG(SYSTEM, "Would have gone to %s but LaunchBrowser is not implemented on this platform", url); #elif defined(_WIN32) std::wstring wurl = ConvertUTF8ToWString(url); ShellExecute(NULL, L"open", wurl.c_str(), NULL, NULL, SW_SHOWNORMAL); @@ -217,7 +216,7 @@ void LaunchBrowser(const char *url) { std::string command = std::string("xdg-open ") + url; int err = system(command.c_str()); if (err) { - ILOG("Would have gone to %s but xdg-utils seems not to be installed", url) + INFO_LOG(SYSTEM, "Would have gone to %s but xdg-utils seems not to be installed", url); } #endif } @@ -229,7 +228,7 @@ void LaunchMarket(const char *url) { webWifiCreate(&conf, NULL, url, uuid, 0); webWifiShow(&conf, NULL); #elif defined(MOBILE_DEVICE) - ILOG("Would have gone to %s but LaunchMarket is not implemented on this platform", url); + INFO_LOG(SYSTEM, "Would have gone to %s but LaunchMarket is not implemented on this platform", url); #elif defined(_WIN32) std::wstring wurl = ConvertUTF8ToWString(url); ShellExecute(NULL, L"open", wurl.c_str(), NULL, NULL, SW_SHOWNORMAL); @@ -240,14 +239,14 @@ void LaunchMarket(const char *url) { std::string command = std::string("xdg-open ") + url; int err = system(command.c_str()); if (err) { - ILOG("Would have gone to %s but xdg-utils seems not to be installed", url) + INFO_LOG(SYSTEM, "Would have gone to %s but xdg-utils seems not to be installed", url); } #endif } void LaunchEmail(const char *email_address) { #if defined(MOBILE_DEVICE) - ILOG("Would have opened your email client for %s but LaunchEmail is not implemented on this platform", email_address); + INFO_LOG(SYSTEM, "Would have opened your email client for %s but LaunchEmail is not implemented on this platform", email_address); #elif defined(_WIN32) std::wstring mailto = std::wstring(L"mailto:") + ConvertUTF8ToWString(email_address); ShellExecute(NULL, L"open", mailto.c_str(), NULL, NULL, SW_SHOWNORMAL); @@ -258,7 +257,7 @@ void LaunchEmail(const char *email_address) { std::string command = std::string("xdg-email ") + email_address; int err = system(command.c_str()); if (err) { - ILOG("Would have gone to %s but xdg-utils seems not to be installed", email_address) + INFO_LOG(SYSTEM, "Would have gone to %s but xdg-utils seems not to be installed", email_address); } #endif } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 919d7ce2f6..4c3559d030 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -237,7 +237,7 @@ void QtHost::ShutdownSound() { } std::string NativeQueryConfig(std::string query) { char temp[128]; if (query == "screenRotation") { - ILOG("g_Config.screenRotation = %d", g_Config.iScreenRotation); + INFO_LOG(G3D, "g_Config.screenRotation = %d", g_Config.iScreenRotation); snprintf(temp, sizeof(temp), "%d", g_Config.iScreenRotation); return std::string(temp); } else if (query == "immersiveMode") { @@ -357,7 +357,7 @@ static void PostLoadConfig() { void CreateDirectoriesAndroid() { // On Android, create a PSP directory tree in the external_dir, // to hopefully reduce confusion a bit. - ILOG("Creating %s", (g_Config.memStickDirectory + "PSP").c_str()); + INFO_LOG(IO, "Creating %s", (g_Config.memStickDirectory + "PSP").c_str()); File::CreateFullPath(g_Config.memStickDirectory + "PSP"); File::CreateFullPath(GetSysDirectory(DIRECTORY_SAVEDATA)); File::CreateFullPath(GetSysDirectory(DIRECTORY_SAVESTATE)); @@ -608,21 +608,21 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch // don't already have one. if (!gotBootFilename) { gotBootFilename = true; - ILOG("Boot filename found in args: '%s'", argv[i]); + INFO_LOG(SYSTEM, "Boot filename found in args: '%s'", argv[i]); bool okToLoad = true; bool okToCheck = true; if (System_GetPropertyBool(SYSPROP_SUPPORTS_PERMISSIONS)) { PermissionStatus status = System_GetPermissionStatus(SYSTEM_PERMISSION_STORAGE); if (status == PERMISSION_STATUS_DENIED) { - ELOG("Storage permission denied. Launching without argument."); + ERROR_LOG(IO, "Storage permission denied. Launching without argument."); okToLoad = false; okToCheck = false; } else if (status != PERMISSION_STATUS_GRANTED) { - ELOG("Storage permission not granted. Launching without argument check."); + ERROR_LOG(IO, "Storage permission not granted. Launching without argument check."); okToCheck = false; } else { - ILOG("Storage permission granted."); + INFO_LOG(IO, "Storage permission granted."); } } if (okToLoad) { @@ -812,7 +812,7 @@ void RenderOverlays(UIContext *dc, void *userdata); bool CreateGlobalPipelines(); bool NativeInitGraphics(GraphicsContext *graphicsContext) { - ILOG("NativeInitGraphics"); + INFO_LOG(SYSTEM, "NativeInitGraphics"); // We set this now so any resize during init is processed later. resized = false; @@ -881,7 +881,7 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { gpu->DeviceRestore(); } - ILOG("NativeInitGraphics completed"); + INFO_LOG(SYSTEM, "NativeInitGraphics completed"); return true; } @@ -931,7 +931,7 @@ void NativeShutdownGraphics() { if (gpu) gpu->DeviceLost(); - ILOG("NativeShutdownGraphics"); + INFO_LOG(SYSTEM, "NativeShutdownGraphics"); #if PPSSPP_PLATFORM(WINDOWS) delete winAudioBackend; @@ -973,7 +973,7 @@ void NativeShutdownGraphics() { texColorPipeline = nullptr; } - ILOG("NativeShutdownGraphics done"); + INFO_LOG(SYSTEM, "NativeShutdownGraphics done"); } void TakeScreenshot() { @@ -1090,7 +1090,7 @@ void NativeRender(GraphicsContext *graphicsContext) { } if (resized) { - ILOG("Resized flag set - recalculating bounds"); + INFO_LOG(G3D, "Resized flag set - recalculating bounds"); resized = false; if (uiContext) { @@ -1119,7 +1119,7 @@ void NativeRender(GraphicsContext *graphicsContext) { NativeMessageReceived("gpu_resized", ""); #endif } else { - // ILOG("Polling graphics context"); + // INFO_LOG(G3D, "Polling graphics context"); graphicsContext->Poll(); } @@ -1179,7 +1179,7 @@ void HandleGlobalMessage(const std::string &msg, const std::string &value) { // Ideally we should simply reinitialize graphics to the mode from the config, but there are potential issues // and I can't risk it before 1.9.0. int gpuBackend = g_Config.iGPUBackend; - ILOG("Reloading config after storage permission grant."); + INFO_LOG(IO, "Reloading config after storage permission grant."); g_Config.Reload(); PostLoadConfig(); g_Config.iGPUBackend = gpuBackend; @@ -1218,16 +1218,16 @@ void NativeUpdate() { bool NativeIsAtTopLevel() { // This might need some synchronization? if (!screenManager) { - ELOG("No screen manager active"); + ERROR_LOG(SYSTEM, "No screen manager active"); return false; } Screen *currentScreen = screenManager->topScreen(); if (currentScreen) { bool top = currentScreen->isTopLevel(); - ILOG("Screen toplevel: %i", (int)top); + INFO_LOG(SYSTEM, "Screen toplevel: %i", (int)top); return currentScreen->isTopLevel(); } else { - ELOG("No current screen"); + ERROR_LOG(SYSTEM, "No current screen"); return false; } } @@ -1246,7 +1246,7 @@ bool NativeTouch(const TouchInput &touch) { } bool NativeKey(const KeyInput &key) { - // ILOG("Key code: %i flags: %i", key.keyCode, key.flags); + // INFO_LOG(SYSTEM, "Key code: %i flags: %i", key.keyCode, key.flags); #if !defined(MOBILE_DEVICE) if (g_Config.bPauseExitsEmulator) { static std::vector pspKeys; @@ -1364,7 +1364,7 @@ void NativeInputBoxReceived(std::function cb, b void NativeResized() { // NativeResized can come from any thread so we just set a flag, then process it later. - ILOG("NativeResized - setting flag"); + INFO_LOG(G3D, "NativeResized - setting flag"); resized = true; } @@ -1398,7 +1398,7 @@ void NativeShutdown() { moncleanup(); #endif - ILOG("NativeShutdown called"); + INFO_LOG(SYSTEM, "NativeShutdown called"); ShutdownWebServer(); diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 24f3b964d1..07a136c69f 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -505,7 +505,7 @@ std::string GetCPUBrandString() { } catch (const std::exception & e) { const char* what = e.what(); - ILOG("%s", what); + INFO_LOG(SYSTEM, "%s", what); } if (cpu_id != nullptr) { @@ -527,7 +527,7 @@ std::string GetCPUBrandString() { } catch (const std::exception & e) { const char* what = e.what(); - ILOG("%s", what); + INFO_LOG(SYSTEM, "%s", what); } } diff --git a/UWP/StorageFileLoader.cpp b/UWP/StorageFileLoader.cpp index 0c52448a58..da0f6af19e 100644 --- a/UWP/StorageFileLoader.cpp +++ b/UWP/StorageFileLoader.cpp @@ -43,7 +43,7 @@ void StorageFileLoader::threadfunc() { operationFailed_ = true; // TODO: What do we do? const char *what = e.what(); - ILOG("%s", what); + INFO_LOG(SYSTEM, "%s", what); } catch (Platform::COMException ^e) { @@ -57,11 +57,11 @@ void StorageFileLoader::threadfunc() { } catch (const std::exception& e) { const char *what = e.what(); - ILOG("%s", what); + INFO_LOG(SYSTEM, "%s", what); } catch (Platform::COMException ^e) { std::string what = FromPlatformString(e->ToString()); - ILOG("%s", what.c_str()); + INFO_LOG(SYSTEM, "%s", what.c_str()); } initMutex.unlock(); @@ -85,7 +85,7 @@ void StorageFileLoader::threadfunc() { } catch (const std::exception& e) { operationFailed_ = true; const char *what = e.what(); - ILOG("%s", what); + INFO_LOG(SYSTEM, "%s", what); } operationRequested_ = false; std::unique_lock lock(mutexResponse_); diff --git a/android/jni/Arm64EmitterTest.cpp b/android/jni/Arm64EmitterTest.cpp index e14c98532d..3a04f6fb18 100644 --- a/android/jni/Arm64EmitterTest.cpp +++ b/android/jni/Arm64EmitterTest.cpp @@ -1,8 +1,7 @@ -#include "base/logging.h" - #include "Common/Arm64Emitter.h" #include "Common/BitSet.h" #include "Common/CPUDetect.h" +#include "Common/Log.h" static bool functionWasCalled; @@ -67,11 +66,11 @@ void Arm64EmitterTest() { return; for (int i = 0; i < 6; i++) { - ILOG("---------------------------"); + INFO_LOG(SYSTEM, "---------------------------"); } - ILOG("---------------------------"); - ILOG("Running ARM64 emitter test!"); - ILOG("---------------------------"); + INFO_LOG(SYSTEM, "---------------------------"); + INFO_LOG(SYSTEM, "Running ARM64 emitter test!"); + INFO_LOG(SYSTEM, "---------------------------"); TestCode gen; gen.ReserveCodeSpace(0x1000); @@ -79,15 +78,15 @@ void Arm64EmitterTest() { gen.Generate(); u32 retval = CallPtr(gen.testCodePtr); - ILOG("Returned %d", retval); - // ILOG("ARM emitter test 1 passed if %f == 3.0! retval = %08x", abc[32 + 31], retval); + INFO_LOG(SYSTEM, "Returned %d", retval); + // INFO_LOG(SYSTEM, "ARM emitter test 1 passed if %f == 3.0! retval = %08x", abc[32 + 31], retval); /* - ILOG("x: %08x %08x %08x %08x", x[0], x[1], x[2], x[3]); - ILOG("y: %08x %08x %08x %08x", y[0], y[1], y[2], y[3]); - ILOG("z: %08x %08x %08x %08x", z[0], z[1], z[2], z[3]); - ILOG("c: %f %f %f %f", c[0], c[1], c[2], c[3]);*/ + INFO_LOG(SYSTEM, "x: %08x %08x %08x %08x", x[0], x[1], x[2], x[3]); + INFO_LOG(SYSTEM, "y: %08x %08x %08x %08x", y[0], y[1], y[2], y[3]); + INFO_LOG(SYSTEM, "z: %08x %08x %08x %08x", z[0], z[1], z[2], z[3]); + INFO_LOG(SYSTEM, "c: %f %f %f %f", c[0], c[1], c[2], c[3]);*/ for (int i = 0; i < 6; i++) { - ILOG("--------------------------"); + INFO_LOG(SYSTEM, "--------------------------"); } // DisassembleArm(codeStart, gen.GetCodePtr()-codeStart); } diff --git a/android/jni/ArmEmitterTest.cpp b/android/jni/ArmEmitterTest.cpp index 8090c1e94c..5af9643f07 100644 --- a/android/jni/ArmEmitterTest.cpp +++ b/android/jni/ArmEmitterTest.cpp @@ -1,4 +1,3 @@ -#include "base/logging.h" #include "ArmEmitterTest.h" #include "Common/ArmEmitter.h" @@ -70,7 +69,7 @@ void TestCode::Generate() VST1(I_32, D6, R3, 2); PLD(R1, 32); u32 word = *(u32 *)(GetCodePtr() - 4); - ILOG("Instruction Word: %08x", word); + INFO_LOG(SYSTEM, "Instruction Word: %08x", word); // This works! @@ -122,11 +121,11 @@ void ArmEmitterTest() return; for (int i = 0; i < 6; i++) { - ILOG("--------------------------"); + INFO_LOG(SYSTEM, "--------------------------"); } - ILOG("--------------------------"); - ILOG("Running ARM emitter test!"); - ILOG("--------------------------"); + INFO_LOG(SYSTEM, "--------------------------"); + INFO_LOG(SYSTEM, "Running ARM emitter test!"); + INFO_LOG(SYSTEM, "--------------------------"); TestCode gen; gen.ReserveCodeSpace(0x1000); @@ -134,13 +133,13 @@ void ArmEmitterTest() gen.Generate(); u32 retval = CallPtr(gen.testCodePtr); - // ILOG("ARM emitter test 1 passed if %f == 3.0! retval = %08x", abc[32 + 31], retval); - ILOG("x: %08x %08x %08x %08x", x[0], x[1], x[2], x[3]); - ILOG("y: %08x %08x %08x %08x", y[0], y[1], y[2], y[3]); - ILOG("z: %08x %08x %08x %08x", z[0], z[1], z[2], z[3]); - ILOG("c: %f %f %f %f", c[0], c[1], c[2], c[3]); + // INFO_LOG(SYSTEM, "ARM emitter test 1 passed if %f == 3.0! retval = %08x", abc[32 + 31], retval); + INFO_LOG(SYSTEM, "x: %08x %08x %08x %08x", x[0], x[1], x[2], x[3]); + INFO_LOG(SYSTEM, "y: %08x %08x %08x %08x", y[0], y[1], y[2], y[3]); + INFO_LOG(SYSTEM, "z: %08x %08x %08x %08x", z[0], z[1], z[2], z[3]); + INFO_LOG(SYSTEM, "c: %f %f %f %f", c[0], c[1], c[2], c[3]); for (int i = 0; i < 6; i++) { - ILOG("--------------------------"); + INFO_LOG(SYSTEM, "--------------------------"); } // DisassembleArm(codeStart, gen.GetCodePtr()-codeStart); } diff --git a/android/jni/TestRunner.cpp b/android/jni/TestRunner.cpp index 2a24811289..f3db153a6e 100644 --- a/android/jni/TestRunner.cpp +++ b/android/jni/TestRunner.cpp @@ -28,9 +28,9 @@ #include "ppsspp_config.h" #include "base/basictypes.h" #include "base/display.h" -#include "base/logging.h" #include "Common/FileUtil.h" +#include "Common/Log.h" #include "Core/Core.h" #include "Core/System.h" #include "Core/Config.h" @@ -112,11 +112,11 @@ bool RunTests() { coreParam.fileToStart = baseDirectory + "pspautotests/tests/" + testName + ".prx"; std::string expectedFile = baseDirectory + "pspautotests/tests/" + testName + ".expected"; - ILOG("Preparing to execute '%s'", testName); + INFO_LOG(SYSTEM, "Preparing to execute '%s'", testName); std::string error_string; output = ""; if (!PSP_Init(coreParam, &error_string)) { - ELOG("Failed to init unittest %s : %s", testsToRun[i], error_string.c_str()); + ERROR_LOG(SYSTEM, "Failed to init unittest %s : %s", testsToRun[i], error_string.c_str()); PSP_CoreParameter().pixelWidth = pixel_xres; PSP_CoreParameter().pixelHeight = pixel_yres; return false; @@ -125,7 +125,7 @@ bool RunTests() { PSP_BeginHostFrame(); // Run the emu until the test exits - ILOG("Test: Entering runloop."); + INFO_LOG(SYSTEM, "Test: Entering runloop."); while (true) { int blockTicks = usToCycles(1000000 / 10); while (coreState == CORE_RUNNING) { @@ -136,7 +136,7 @@ bool RunTests() { // set back to running for the next frame coreState = CORE_RUNNING; } else if (coreState == CORE_POWERDOWN) { - ILOG("Finished running test %s", testName); + INFO_LOG(SYSTEM, "Finished running test %s", testName); break; } } @@ -144,7 +144,7 @@ bool RunTests() { std::ifstream expected(expectedFile.c_str(), std::ios_base::in); if (!expected) { - ELOG("Error opening expectedFile %s", expectedFile.c_str()); + ERROR_LOG(SYSTEM, "Error opening expectedFile %s", expectedFile.c_str()); break; } @@ -160,9 +160,9 @@ bool RunTests() { e = TrimNewlines(e); o = TrimNewlines(o); if (e != o) { - ELOG("DIFF on line %i!", line); - ELOG("O: %s", o.c_str()); - ELOG("E: %s", e.c_str()); + ERROR_LOG(SYSTEM, "DIFF on line %i!", line); + ERROR_LOG(SYSTEM, "O: %s", o.c_str()); + ERROR_LOG(SYSTEM, "E: %s", e.c_str()); } if (expected.eof()) { break; diff --git a/ext/native/base/logging.cpp b/ext/native/base/logging.cpp index b4f40fa8c7..812219d11f 100644 --- a/ext/native/base/logging.cpp +++ b/ext/native/base/logging.cpp @@ -1,4 +1,4 @@ -#include "base/logging.h" +#include const char *GetFn(const char *fn) { const char *p = strrchr(fn, '\\'); diff --git a/ext/native/file/zip_read.cpp b/ext/native/file/zip_read.cpp index b6e997877b..7efcab7255 100644 --- a/ext/native/file/zip_read.cpp +++ b/ext/native/file/zip_read.cpp @@ -301,7 +301,7 @@ uint8_t *VFSReadFile(const char *filename, size_t *size) { if (prefix_len >= fn_len) continue; if (0 == memcmp(filename, entries[i].prefix, prefix_len)) { fileSystemFound = true; - // ILOG("Prefix match: %s (%s) -> %s", entries[i].prefix, filename, filename + prefix_len); + // INFO_LOG(IO, "Prefix match: %s (%s) -> %s", entries[i].prefix, filename, filename + prefix_len); uint8_t *data = entries[i].reader->ReadAsset(filename + prefix_len, size); if (data) return data; @@ -319,7 +319,7 @@ uint8_t *VFSReadFile(const char *filename, size_t *size) { bool VFSGetFileListing(const char *path, std::vector *listing, const char *filter) { if (IsLocalPath(path)) { // Local path, not VFS. - // ILOG("Not a VFS path: %s . Reading local directory.", path); + // INFO_LOG(IO, "Not a VFS path: %s . Reading local directory.", path); getFilesInDir(path, listing, filter); return true; } @@ -346,7 +346,7 @@ bool VFSGetFileListing(const char *path, std::vector *listing, const c bool VFSGetFileInfo(const char *path, FileInfo *info) { if (IsLocalPath(path)) { // Local path, not VFS. - // ILOG("Not a VFS path: %s . Getting local file info.", path); + // INFO_LOG(IO, "Not a VFS path: %s . Getting local file info.", path); return getFileInfo(path, info); } diff --git a/ext/native/gfx_es2/draw_text_qt.cpp b/ext/native/gfx_es2/draw_text_qt.cpp index 12929e25cf..39b4ac95eb 100644 --- a/ext/native/gfx_es2/draw_text_qt.cpp +++ b/ext/native/gfx_es2/draw_text_qt.cpp @@ -134,7 +134,7 @@ void TextDrawerQt::DrawStringBitmap(std::vector &bitmapData, TextString } } } else { - _assert_msg_("Bad TextDrawer format"); + _assert_msg_(false, "Bad TextDrawer format"); } } diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index a8c67d211b..9c3d9c21be 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -91,15 +91,15 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n // Create D2D Device and DeviceContext. // TODO: We have one sitting right in DX::DeviceResource, there might be a way to use that instead. hr = m_d2dFactory->CreateDevice(dxgiDevice, &m_d2dDevice); - if (FAILED(hr)) FLOG("D2D CreateDevice failed"); + if (FAILED(hr)) _assert_msg_(false, "D2D CreateDevice failed"); hr = m_d2dDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &m_d2dContext); - if (FAILED(hr)) FLOG("D2D CreateDeviceContext failed"); + if (FAILED(hr)) _assert_msg_(false, "D2D CreateDeviceContext failed"); // Load the Roboto font hr = m_dwriteFactory->CreateFontFileReference(L"Content/Roboto-Condensed.ttf", nullptr, &m_fontFile); - if (FAILED(hr)) ELOG("CreateFontFileReference failed"); + if (FAILED(hr)) ERROR_LOG(SYSTEM, "CreateFontFileReference failed"); hr = m_dwriteFactory->CreateFontSetBuilder(&m_fontSetBuilder); - if (FAILED(hr)) ELOG("CreateFontSetBuilder failed"); + if (FAILED(hr)) ERROR_LOG(SYSTEM, "CreateFontSetBuilder failed"); hr = m_fontSetBuilder->AddFontFile(m_fontFile); hr = m_fontSetBuilder->CreateFontSet(&m_fontSet); hr = m_dwriteFactory->CreateFontCollectionFromFontSet(m_fontSet, &m_fontCollection); diff --git a/ext/native/tools/audiotool.cpp b/ext/native/tools/audiotool.cpp deleted file mode 100644 index 68cfee7ae3..0000000000 --- a/ext/native/tools/audiotool.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// TODO - -#include - -#include "audio/wav_load.h" -#include "base/logging.h" - - -struct AudioClip { - int length; - -}; - - -int main(int argc, char **argv) { - CHECK(argc == 3); -} diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 4f6f9a4db3..4741c4373e 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -30,6 +30,7 @@ #include "Core/HLE/sceUsbCam.h" #include "Core/HLE/sceUsbGps.h" #include "Common/GraphicsContext.h" +#include "Common/Log.h" #include #include @@ -244,7 +245,7 @@ static LocationHelper *locationHelper; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ NativeInitGraphics(graphicsContext); - ILOG("Emulation thread starting\n"); + INFO_LOG(SYSTEM, "Emulation thread starting\n"); while (threadEnabled) { NativeUpdate(); NativeRender(graphicsContext); @@ -252,11 +253,11 @@ static LocationHelper *locationHelper; } - ILOG("Emulation thread shutting down\n"); + INFO_LOG(SYSTEM, "Emulation thread shutting down\n"); NativeShutdownGraphics(); // Also ask the main thread to stop, so it doesn't hang waiting for a new frame. - ILOG("Emulation thread stopping\n"); + INFO_LOG(SYSTEM, "Emulation thread stopping\n"); graphicsContext->StopThread(); threadStopped = true; diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index e2b94af96a..b8af6ae8bb 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -32,7 +32,6 @@ #include #include "base/NativeApp.h" -#include "base/logging.h" #include "input/input_state.h" #include "ext/disarm.h" #include "math/math_util.h" @@ -41,6 +40,7 @@ #include "Common/ArmEmitter.h" #include "Common/BitScan.h" #include "Common/CPUDetect.h" +#include "Common/Log.h" #include "Core/Config.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/MemMap.h" @@ -326,7 +326,7 @@ bool TestMatrixTranspose() { } void TestGetMatrix(int matrix, MatrixSize sz) { - ILOG("Testing matrix %s", GetMatrixNotation(matrix, sz)); + INFO_LOG(SYSTEM, "Testing matrix %s", GetMatrixNotation(matrix, sz)); u8 fullMatrix[16]; u8 cols[4]; @@ -344,8 +344,8 @@ void TestGetMatrix(int matrix, MatrixSize sz) { // int rowName = GetRowName(matrix, sz, i, 0); int colName = cols[i]; int rowName = rows[i]; - ILOG("Column %i: %s", i, GetVectorNotation(colName, vsz)); - ILOG("Row %i: %s", i, GetVectorNotation(rowName, vsz)); + INFO_LOG(SYSTEM, "Column %i: %s", i, GetVectorNotation(colName, vsz)); + INFO_LOG(SYSTEM, "Row %i: %s", i, GetVectorNotation(rowName, vsz)); u8 colRegs[4]; u8 rowRegs[4]; @@ -366,12 +366,12 @@ void TestGetMatrix(int matrix, MatrixSize sz) { c << (int)fullMatrix[j * 4 + i] << " "; d << (int)rowRegs[j] << " "; } - ILOG("Col: %s vs %s", a.str().c_str(), b.str().c_str()); + INFO_LOG(SYSTEM, "Col: %s vs %s", a.str().c_str(), b.str().c_str()); if (a.str() != b.str()) - ILOG("WRONG!"); - ILOG("Row: %s vs %s", c.str().c_str(), d.str().c_str()); + INFO_LOG(SYSTEM, "WRONG!"); + INFO_LOG(SYSTEM, "Row: %s vs %s", c.str().c_str(), d.str().c_str()); if (c.str() != d.str()) - ILOG("WRONG!"); + INFO_LOG(SYSTEM, "WRONG!"); } } From 3c412ea21e93afa29ac5ee54021291970ca99673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 18:40:50 +0200 Subject: [PATCH 506/848] Fix build of ZimTool/AtlasTool. Had to break the ugly backwards dependency from LogManager to g_Config. --- Common/LogManager.cpp | 26 +++++++++++--------- Common/LogManager.h | 5 ++-- UI/NativeApp.cpp | 2 +- UWP/PPSSPP_UWPMain.cpp | 3 ++- Windows/main.cpp | 2 +- ext/native/base/logging.h | 11 --------- ext/native/tools/atlastool/atlastool.vcxproj | 5 ++-- ext/native/tools/zimtool/zimtool.vcxproj | 2 ++ headless/Headless.cpp | 2 +- libretro/libretro.cpp | 2 +- 10 files changed, 29 insertions(+), 31 deletions(-) diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index c1eef5d2fb..89dee6720e 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -21,16 +21,18 @@ #include #include "util/text/utf8.h" -#include "LogManager.h" -#include "ConsoleListener.h" -#include "Timer.h" -#include "FileUtil.h" -#include "StringUtils.h" -#include "Core/Config.h" + +#include "Common/LogManager.h" +#include "Common/ConsoleListener.h" +#include "Common/Timer.h" +#include "Common/FileUtil.h" +#include "Common/StringUtils.h" // Don't need to savestate this. const char *hleCurrentThreadName = nullptr; +bool *g_bLogEnabledSetting = nullptr; + static const char level_to_char[8] = "-NEWIDV"; #if PPSSPP_PLATFORM(UWP) && defined(_DEBUG) @@ -40,7 +42,7 @@ static const char level_to_char[8] = "-NEWIDV"; #endif void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char *file, int line, const char* fmt, ...) { - if (!g_Config.bEnableLogging) + if (g_bLogEnabledSetting && !(*g_bLogEnabledSetting)) return; va_list args; va_start(args, fmt); @@ -56,7 +58,7 @@ void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type) { if (LogManager::GetInstance()) - return g_Config.bEnableLogging && LogManager::GetInstance()->IsEnabled(level, type); + return (*g_bLogEnabledSetting) && LogManager::GetInstance()->IsEnabled(level, type); return false; } @@ -116,7 +118,9 @@ static const LogNameTableEntry logTable[] = { {LogTypes::SCEMISC, "SCEMISC"}, }; -LogManager::LogManager() { +LogManager::LogManager(bool *enabledSetting) { + g_bLogEnabledSetting = enabledSetting; + for (size_t i = 0; i < ARRAY_SIZE(logTable); i++) { _assert_msg_(i == logTable[i].logType, "Bad logtable at %i", (int)i); truncate_cpy(log_[logTable[i].logType].m_shortName, logTable[i].name); @@ -271,8 +275,8 @@ bool LogManager::IsEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type) return true; } -void LogManager::Init() { - logManager_ = new LogManager(); +void LogManager::Init(bool *enabledSetting) { + logManager_ = new LogManager(enabledSetting); } void LogManager::Shutdown() { diff --git a/Common/LogManager.h b/Common/LogManager.h index a9d5a568e9..6aaa69b462 100644 --- a/Common/LogManager.h +++ b/Common/LogManager.h @@ -105,7 +105,7 @@ class ConsoleListener; class LogManager { private: - LogManager(); + LogManager(bool *enabledSetting); ~LogManager(); // Prevent copies. @@ -122,6 +122,7 @@ private: std::mutex log_lock_; std::mutex listeners_lock_; std::vector listeners_; + public: void AddListener(LogListener *listener); void RemoveListener(LogListener *listener); @@ -175,7 +176,7 @@ public: logManager_ = logManager; } - static void Init(); + static void Init(bool *enabledSetting); static void Shutdown(); void ChangeFileLog(const char *filename); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 4c3559d030..00d37db957 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -531,7 +531,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch } if (!LogManager::GetInstance()) - LogManager::Init(); + LogManager::Init(&g_Config.bEnableLogging); #ifndef _WIN32 g_Config.AddSearchPath(user_data_path); diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 07a136c69f..5711ae0b29 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -10,6 +10,7 @@ #include "Common/LogManager.h" #include "Core/System.h" #include "Core/Loaders.h" +#include "Core/Config.h" #include "base/NativeApp.h" #include "base/timeutil.h" #include "input/input_state.h" @@ -100,7 +101,7 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptr (b)); -#define CHECK_GE(a, b) CHECK((a) >= (b)); -#define CHECK_LT(a, b) CHECK((a) < (b)); -#define CHECK_LE(a, b) CHECK((a) <= (b)); diff --git a/ext/native/tools/atlastool/atlastool.vcxproj b/ext/native/tools/atlastool/atlastool.vcxproj index 60613f1c54..805700c863 100644 --- a/ext/native/tools/atlastool/atlastool.vcxproj +++ b/ext/native/tools/atlastool/atlastool.vcxproj @@ -81,7 +81,7 @@ Console true ../prebuilt/win64 - freetype.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winmm.lib;freetype.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) @@ -97,6 +97,7 @@ true ../../../../;../../ext;../../;../../../../ext;../prebuilt MultiThreaded + false Console @@ -104,7 +105,7 @@ true true ../prebuilt/win64 - freetype.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + winmm.lib;freetype.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) diff --git a/ext/native/tools/zimtool/zimtool.vcxproj b/ext/native/tools/zimtool/zimtool.vcxproj index 3c9e0d3c2d..1eecf94c3f 100644 --- a/ext/native/tools/zimtool/zimtool.vcxproj +++ b/ext/native/tools/zimtool/zimtool.vcxproj @@ -84,6 +84,7 @@ true true true + winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) @@ -101,6 +102,7 @@ Console true + winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 77af343446..4e0cee7457 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -335,7 +335,7 @@ int main(int argc, const char* argv[]) GraphicsContext *graphicsContext = nullptr; bool glWorking = host->InitGraphics(&error_string, &graphicsContext); - LogManager::Init(); + LogManager::Init(&g_Config.bEnableLogging); LogManager *logman = LogManager::GetInstance(); PrintfLogger *printfLogger = new PrintfLogger(); diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 497cbae28d..2b61b9f550 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -358,7 +358,7 @@ void retro_init(void) g_Config.iFirmwareVersion = PSP_DEFAULT_FIRMWARE; g_Config.iPSPModel = PSP_MODEL_SLIM; - LogManager::Init(); + LogManager::Init(&g_Config.bEnableLogging); host = new LibretroHost; From f0d2f24658dcf0011c3fa4338f0174d8eff37b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 19:01:16 +0200 Subject: [PATCH 507/848] Finally delete base/logging.cpp/h. Carefully preserve behaviour on Android. There's more cleanup to do ... --- CMakeLists.txt | 2 - UI/NativeApp.cpp | 35 +++++---- UWP/NativeUWP/NativeUWP.vcxproj | 2 - Windows/main.cpp | 3 +- android/jni/app-android.cpp | 40 +++++++++++ android/jni/app-android.h | 7 ++ ext/native/base/logging.cpp | 9 --- ext/native/base/logging.h | 124 -------------------------------- ext/native/native.vcxproj | 4 +- libretro/Makefile.common | 1 - 10 files changed, 66 insertions(+), 161 deletions(-) delete mode 100644 ext/native/base/logging.cpp delete mode 100644 ext/native/base/logging.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0137d06d5a..1b8a4e8706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -822,7 +822,6 @@ elseif(WIN32) else() link_directories(dx9sdk/Lib/x86) endif() - set(nativeExtra ${nativeExtra} ext/native/base/logging.cpp) elseif(TARGET SDL2::SDL2) set(TargetBin PPSSPPSDL) # Require SDL @@ -934,7 +933,6 @@ add_library(native STATIC ext/native/base/display.cpp ext/native/base/display.h ext/native/base/linked_ptr.h - ext/native/base/logging.h ext/native/base/stringutil.cpp ext/native/base/stringutil.h ext/native/base/timeutil.cpp diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 00d37db957..db07804eb8 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -44,9 +44,6 @@ #endif #include "base/display.h" - -#include "base/logging.h" // For "AndroidLogger". TODO: Remove. - #include "base/stringutil.h" #include "base/timeutil.h" #include "base/NativeApp.h" @@ -70,12 +67,16 @@ #include "ui/view.h" #include "util/text/utf8.h" +#include "android/jni/app-android.h" + #include "Common/CPUDetect.h" #include "Common/FileUtil.h" +#include "Common/KeyMap.h" #include "Common/LogManager.h" #include "Common/MemArena.h" #include "Common/GraphicsContext.h" #include "Common/OSVersion.h" + #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Core.h" @@ -93,8 +94,8 @@ #include "Core/Util/GameManager.h" #include "Core/Util/AudioFormat.h" #include "Core/WebServer.h" -#include "GPU/GPUInterface.h" +#include "GPU/GPUInterface.h" #include "UI/BackgroundAudio.h" #include "UI/ControlMappingScreen.h" #include "UI/DiscordIntegration.h" @@ -108,10 +109,6 @@ #include "UI/TiltEventProcessor.h" #include "UI/TextureUtil.h" -#if !defined(MOBILE_DEVICE) -#include "Common/KeyMap.h" -#endif - #if !defined(MOBILE_DEVICE) && defined(USING_QT_UI) #include "Qt/QtHost.h" #endif @@ -183,7 +180,7 @@ WindowsAudioBackend *winAudioBackend; std::thread *graphicsLoadThread; -class AndroidLogger : public LogListener { +class PrintfLogger : public LogListener { public: void Log(const LogMessage &message) override { // Log with simplified headers as Android already provides timestamp etc. @@ -191,17 +188,17 @@ public: case LogTypes::LVERBOSE: case LogTypes::LDEBUG: case LogTypes::LINFO: - ILOG("[%s] %s", message.log, message.msg.c_str()); + printf("INFO [%s] %s", message.log, message.msg.c_str()); break; case LogTypes::LERROR: - ELOG("[%s] %s", message.log, message.msg.c_str()); + printf("ERR [%s] %s", message.log, message.msg.c_str()); break; case LogTypes::LWARNING: - WLOG("[%s] %s", message.log, message.msg.c_str()); + printf("WARN [%s] %s", message.log, message.msg.c_str()); break; case LogTypes::LNOTICE: default: - ILOG("[%s] !!! %s", message.log, message.msg.c_str()); + printf("NOTE [%s] !!! %s", message.log, message.msg.c_str()); break; } } @@ -214,7 +211,7 @@ int Win32Mix(short *buffer, int numSamples, int bits, int rate, int channels) { #endif // globals -static AndroidLogger *logger = nullptr; +static LogListener *logger = nullptr; std::string boot_filename = ""; void NativeHost::InitSound() { @@ -661,10 +658,13 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch PostLoadConfig(); -#if defined(__ANDROID__) || (defined(MOBILE_DEVICE) && !defined(_DEBUG)) +#if PPSSPP_PLATFORM(ANDROID) + logger = new AndroidLogger(); + logman->AddListener(logger); +#elif (defined(MOBILE_DEVICE) && !defined(_DEBUG)) // Enable basic logging for any kind of mobile device, since LogManager doesn't. // The MOBILE_DEVICE/_DEBUG condition matches LogManager.cpp. - logger = new AndroidLogger(); + logger = new PrintfLogger(); logman->AddListener(logger); #endif @@ -1408,9 +1408,6 @@ void NativeShutdown() { g_Discord.Shutdown(); - delete logger; - logger = nullptr; - // Previously we did exit() here on Android but that makes it hard to do things like restart on backend change. // I think we handle most globals correctly or correct-enough now. } diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index a25e4fbd1a..cce36088aa 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -385,7 +385,6 @@ - @@ -479,7 +478,6 @@ - diff --git a/Windows/main.cpp b/Windows/main.cpp index 6193e9e96f..693d57c8db 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -610,8 +610,9 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin // - It should be possible to log to a file without showing the console. LogManager::GetInstance()->GetConsoleListener()->Init(showLog, 150, 120, "PPSSPP Debug Console"); - if (debugLogLevel) + if (debugLogLevel) { LogManager::GetInstance()->SetAllLogLevels(LogTypes::LDEBUG); + } timeBeginPeriod(1); // TODO: Evaluate if this makes sense to keep. diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index aad11b14f1..a0c5c6a5af 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -16,6 +16,8 @@ #ifndef _MSC_VER #include #include +#include + #elif !defined(JNIEXPORT) // Just for better highlighting in MSVC if opening this file. // Not having types makes it get confused and say everything is wrong. @@ -173,6 +175,44 @@ static std::map permissions; AndroidGraphicsContext *graphicsContext; +#ifndef LOG_APP_NAME +#define LOG_APP_NAME "PPSSPP" +#endif + +#ifdef _DEBUG +#define DLOG(...) __android_log_print(ANDROID_LOG_INFO, LOG_APP_NAME, __VA_ARGS__); +#else +#define DLOG(...) +#endif + +#define ILOG(...) __android_log_print(ANDROID_LOG_INFO, LOG_APP_NAME, __VA_ARGS__); +#define WLOG(...) __android_log_print(ANDROID_LOG_WARN, LOG_APP_NAME, __VA_ARGS__); +#define ELOG(...) __android_log_print(ANDROID_LOG_ERROR, LOG_APP_NAME, __VA_ARGS__); +#define FLOG(...) __android_log_print(ANDROID_LOG_FATAL, LOG_APP_NAME, __VA_ARGS__); + +#define MessageBox(a, b, c, d) __android_log_print(ANDROID_LOG_INFO, APP_NAME, "%s %s", (b), (c)); + +void AndroidLogger::Log(const LogMessage &message) { + // Log with simplified headers as Android already provides timestamp etc. + switch (message.level) { + case LogTypes::LVERBOSE: + case LogTypes::LDEBUG: + case LogTypes::LINFO: + ILOG("[%s] %s", message.log, message.msg.c_str()); + break; + case LogTypes::LERROR: + ELOG("[%s] %s", message.log, message.msg.c_str()); + break; + case LogTypes::LWARNING: + WLOG("[%s] %s", message.log, message.msg.c_str()); + break; + case LogTypes::LNOTICE: + default: + ILOG("[%s] !!! %s", message.log, message.msg.c_str()); + break; + } +} + JNIEnv* getEnv() { JNIEnv *env; int status = gJvm->GetEnv((void**)&env, JNI_VERSION_1_6); diff --git a/android/jni/app-android.h b/android/jni/app-android.h index 49d0dab435..aa21dd9ade 100644 --- a/android/jni/app-android.h +++ b/android/jni/app-android.h @@ -2,6 +2,8 @@ #include "ppsspp_config.h" +#include "Common/LogManager.h" + #if PPSSPP_PLATFORM(ANDROID) #include @@ -10,3 +12,8 @@ jclass findClass(const char* name); JNIEnv* getEnv(); #endif + +class AndroidLogger : public LogListener { +public: + void Log(const LogMessage &message) override; +}; diff --git a/ext/native/base/logging.cpp b/ext/native/base/logging.cpp deleted file mode 100644 index 812219d11f..0000000000 --- a/ext/native/base/logging.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include - -const char *GetFn(const char *fn) { - const char *p = strrchr(fn, '\\'); - if (p) - return p + 1; - else - return fn; -} diff --git a/ext/native/base/logging.h b/ext/native/base/logging.h deleted file mode 100644 index 1ba560b602..0000000000 --- a/ext/native/base/logging.h +++ /dev/null @@ -1,124 +0,0 @@ -#pragma once - -#include - -#include "ppsspp_config.h" -#include "base/backtrace.h" - -// Simple wrapper around Android's logging interface that also allows other -// implementations, and also some misc utilities. - -#ifdef _MSC_VER -// Disable annoying warnings in VS -#pragma warning (disable:4996) //strcpy may be dangerous, etc. -#endif - -#undef Crash - -#include -// Logging -#ifdef _WIN32 - -#ifdef _M_X64 -inline void Crash() { int *x = (int *)1337; *x = 1; } -#elif defined(_M_IX86) -inline void Crash() { __asm { int 3 }; } -#elif defined(_M_ARM) -inline void Crash() { int *x = (int *)1337; *x = 1; } -#elif defined(_M_ARM64) -inline void Crash() { int* x = (int*)1337; *x = 1; } -#endif - -#else - -#if defined(_M_IX86) || defined(_M_X64) -inline void Crash() { - PrintBacktraceToStderr(); - asm("int $0x3"); -} -#else -inline void Crash() { - PrintBacktraceToStderr(); - char *p = (char *)1337; - *p = 1; -} -#endif - -#endif - -#if defined(__ANDROID__) - -#include - -// Must only be used for logging -#ifndef APP_NAME -#define APP_NAME "PPSSPP" -#endif - -#ifdef _DEBUG -#define DLOG(...) __android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__); -#else -#define DLOG(...) -#endif - -#define ILOG(...) __android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__); -#define WLOG(...) __android_log_print(ANDROID_LOG_WARN, APP_NAME, __VA_ARGS__); -#define ELOG(...) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__); -#define FLOG(...) __android_log_print(ANDROID_LOG_FATAL, APP_NAME, __VA_ARGS__); - -#define MessageBox(a, b, c, d) __android_log_print(ANDROID_LOG_INFO, APP_NAME, "%s %s", (b), (c)); - -#else - -#ifdef _WIN32 - -const char *GetFn(const char *fn); - -#define XLOG_IMPL(type, ...) do {\ - char temp[512]; \ - char *p = temp; \ - int len = snprintf(p, sizeof(temp), type ": %s:%i: ", GetFn(__FILE__), __LINE__); \ - if (len < sizeof(temp)) { \ - p += len; \ - p += snprintf(p, sizeof(temp) - len - 3, type ": " __VA_ARGS__); \ - if (p > temp + sizeof(temp) - 3) \ - p = temp + sizeof(temp) - 3; \ - p += sprintf(p, "\n"); \ - OutputDebugStringUTF8(temp); \ - } \ -} while (false) - -#define DUMPLOG(x) OutputDebugStringUTF8(x) - -#ifdef _DEBUG -#define DLOG(...) XLOG_IMPL("D", __VA_ARGS__) -#else -#define DLOG(...) -#endif - -#define ILOG(...) XLOG_IMPL("I", __VA_ARGS__) -#define WLOG(...) XLOG_IMPL("W", __VA_ARGS__) -#define ELOG(...) XLOG_IMPL("E", __VA_ARGS__) -#define FLOG(...) do {XLOG_IMPL("F", __VA_ARGS__); Crash();} while (false) - -#else - -#include - -inline const char *removePath(const char *str) { - const char *slash = strrchr(str, '/'); - return slash ? (slash + 1) : str; -} - -#ifdef _DEBUG -#define DLOG(...) {printf("D: %s:%i: ", removePath(__FILE__), __LINE__); printf("D: " __VA_ARGS__); printf("\n");} -#else -#define DLOG(...) -#endif -#define ILOG(...) {printf("I: %s:%i: ", removePath(__FILE__), __LINE__); printf(__VA_ARGS__); printf("\n");} -#define WLOG(...) {printf("W: %s:%i: ", removePath(__FILE__), __LINE__); printf(__VA_ARGS__); printf("\n");} -#define ELOG(...) {printf("E: %s:%i: ", removePath(__FILE__), __LINE__); printf(__VA_ARGS__); printf("\n");} -#define FLOG(...) {printf("F: %s:%i: ", removePath(__FILE__), __LINE__); printf(__VA_ARGS__); printf("\n"); Crash();} - -#endif -#endif diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index d13049e3e9..afb7f0ffed 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -387,7 +387,6 @@ - @@ -496,7 +495,6 @@ - true true @@ -1217,4 +1215,4 @@ - \ No newline at end of file + diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 1a347a8acb..c4ac5d2f4e 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -215,7 +215,6 @@ SOURCES_CXX += \ $(EXTDIR)/native/base/buffer.cpp \ $(EXTDIR)/native/base/colorutil.cpp \ $(EXTDIR)/native/base/display.cpp \ - $(EXTDIR)/native/base/logging.cpp \ $(EXTDIR)/native/base/stringutil.cpp \ $(EXTDIR)/native/base/timeutil.cpp \ $(EXTDIR)/native/data/compression.cpp \ From d35b4131054520b5e8b0f93e255d4b93ef94b703 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 15 Aug 2020 10:12:14 -0700 Subject: [PATCH 508/848] Debugger: Oops, fix comment typos. --- Core/Debugger/WebSocket/GPUBufferSubscriber.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp b/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp index aff77aae30..ec9a226508 100644 --- a/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp +++ b/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp @@ -344,7 +344,7 @@ void WebSocketGPUBufferRenderStencil(DebuggerRequest &req) { }); } -// Retrieve current stencil texture (gpu.buffer.texture) +// Retrieve current texture (gpu.buffer.texture) // // Parameters: // - type: either 'uri' or 'base64'. @@ -372,7 +372,7 @@ void WebSocketGPUBufferTexture(DebuggerRequest &req) { }); } -// Retrieve current stencil texture (gpu.buffer.texture) +// Retrieve current CLUT (gpu.buffer.clut) // // Parameters: // - type: either 'uri' or 'base64'. From 1e2f87a6d2d745eed0d3cbdc7adcdca3c4c0079a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 15 Aug 2020 10:12:34 -0700 Subject: [PATCH 509/848] Vulkan: Fix tex upscaling 4444 swizzling. --- GPU/Vulkan/TextureCacheVulkan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 1dc8630082..202c8a839c 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -111,7 +111,7 @@ uint readColoru(uvec2 p) { uint a = ((data >> 15) & 0x01) == 0 ? 0x00 : 0xFF; return (a << 24) | (b << 16) | (g << 8) | r; } else if (params.fmt == 4) { - uint r = (data & 0x0F) | ((data << 4) & 0x0F); + uint r = (data & 0x0F) | ((data << 4) & 0xF0); uint g = (data & 0xF0) | ((data >> 4) & 0x0F); uint b = ((data >> 8) & 0x0F) | ((data >> 4) & 0xF0); uint a = ((data >> 12) & 0x0F) | ((data >> 8) & 0xF0); @@ -188,7 +188,7 @@ uint readColoru(uvec2 p) { uint a = ((data >> 15) & 0x01) == 0 ? 0x00 : 0xFF; return (a << 24) | (b << 16) | (g << 8) | r; } else if (params.fmt == 4) { - uint r = (data & 0x0F) | ((data << 4) & 0x0F); + uint r = (data & 0x0F) | ((data << 4) & 0xF0); uint g = (data & 0xF0) | ((data >> 4) & 0x0F); uint b = ((data >> 8) & 0x0F) | ((data >> 4) & 0xF0); uint a = ((data >> 12) & 0x0F) | ((data >> 8) & 0xF0); From 004119fd32f63f0edba9a9226517e694b9f36192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 19:47:04 +0200 Subject: [PATCH 510/848] UWP buildfix --- UWP/StorageFileLoader.cpp | 1 + ext/native/gfx_es2/draw_text_uwp.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/UWP/StorageFileLoader.cpp b/UWP/StorageFileLoader.cpp index da0f6af19e..dcdbdcff76 100644 --- a/UWP/StorageFileLoader.cpp +++ b/UWP/StorageFileLoader.cpp @@ -3,6 +3,7 @@ #include "file/file_util.h" #include "thread/threadutil.h" #include "StorageFileLoader.h" +#include "Common/Log.h" #include "UWPUtil.h" using namespace Concurrency; diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index 9c3d9c21be..0e741b0077 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -7,6 +7,7 @@ #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_text_uwp.h" +#include "Common/Log.h" #if PPSSPP_PLATFORM(UWP) @@ -70,7 +71,7 @@ TextDrawerUWP::TextDrawerUWP(Draw::DrawContext *draw) : TextDrawer(draw), ctx_(n IDXGIDevice* dxgiDevice; hr = d3ddevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); - if (FAILED(hr)) FLOG("ID3DDevice QueryInterface IDXGIDevice failed"); + if (FAILED(hr)) _assert_msg_(false, "ID3DDevice QueryInterface IDXGIDevice failed"); // Initialize the Direct2D Factory. D2D1_FACTORY_OPTIONS options = {}; From 99a5a9aac5c02646097dac909054c529543e65a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 20:02:07 +0200 Subject: [PATCH 511/848] Address feedback --- Common/LogManager.cpp | 2 +- Core/TextureReplacer.cpp | 1 + UI/NativeApp.cpp | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 89dee6720e..8adf305dd6 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -98,7 +98,7 @@ static const LogNameTableEntry logTable[] = { {LogTypes::MEMMAP, "MEMMAP"}, {LogTypes::SASMIX, "SASMIX"}, {LogTypes::SAVESTATE, "SAVESTATE"}, - {LogTypes::FRAMEBUF, "FRAMEBUF"}, + {LogTypes::FRAMEBUF, "FRAMEBUF"}, {LogTypes::AUDIO, "AUDIO"}, {LogTypes::IO, "IO"}, diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index ad1de50dd4..16f0374fc4 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -385,6 +385,7 @@ static bool WriteTextureToPNG(png_imagep image, const std::string &filename, int } if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, row_stride, colormap)) { + fclose(fp); return true; } else { ERROR_LOG(SYSTEM, "Texture PNG encode failed."); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index db07804eb8..445d007269 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1408,6 +1408,11 @@ void NativeShutdown() { g_Discord.Shutdown(); + if (logger) { + delete logger; + logger = nullptr; + } + // Previously we did exit() here on Android but that makes it hard to do things like restart on backend change. // I think we handle most globals correctly or correct-enough now. } From ccc033127952e938849bb514c1a257622a77a202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 20:53:08 +0200 Subject: [PATCH 512/848] Move timeutil to Common. (Experiment to see how much work it is to move these). --- CMakeLists.txt | 4 ++-- Common/Common.vcxproj | 2 ++ .../base/timeutil.cpp => Common/TimeUtil.cpp | 2 +- .../base/timeutil.h => Common/TimeUtil.h | 0 Common/Vulkan/VulkanMemory.cpp | 2 +- Core/Core.cpp | 2 +- Core/FileLoaders/CachingFileLoader.cpp | 2 +- Core/FileLoaders/RamCachingFileLoader.cpp | 2 +- Core/HLE/HLE.cpp | 2 +- Core/HLE/proAdhoc.cpp | 7 +++++-- Core/HLE/proAdhoc.h | 1 - Core/HLE/proAdhocServer.cpp | 6 ++++-- Core/HLE/sceDisplay.cpp | 2 +- Core/HLE/sceFont.cpp | 2 +- Core/HLE/sceNetAdhoc.cpp | 1 + Core/HLE/sceRtc.cpp | 2 +- Core/HW/StereoResampler.cpp | 4 ++-- Core/MIPS/MIPSAnalyst.cpp | 2 +- Core/SaveState.cpp | 2 +- Core/System.cpp | 2 +- Core/Util/PortManager.cpp | 2 +- Core/WebServer.cpp | 2 +- GPU/Common/PresentationCommon.cpp | 2 +- GPU/Common/TextureScalerCommon.cpp | 2 +- GPU/D3D11/DrawEngineD3D11.cpp | 3 +-- GPU/Directx9/DrawEngineDX9.cpp | 3 +-- GPU/GLES/DrawEngineGLES.cpp | 3 +-- GPU/GLES/ShaderManagerGLES.cpp | 2 +- GPU/GPU.cpp | 2 +- GPU/GPUCommon.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 2 +- GPU/Vulkan/GPU_Vulkan.cpp | 4 ++-- Qt/QtMain.h | 2 +- SDL/SDLMain.cpp | 2 +- UI/BackgroundAudio.cpp | 4 ++-- UI/ComboKeyMappingScreen.cpp | 6 ++++-- UI/EmuScreen.cpp | 2 +- UI/GameInfoCache.cpp | 2 +- UI/GameSettingsScreen.cpp | 2 +- UI/GamepadEmu.cpp | 16 +++++++------- UI/MainScreen.cpp | 2 +- UI/MiscScreens.cpp | 20 ++++++++++-------- UI/NativeApp.cpp | 2 +- UI/OnScreenDisplay.cpp | 3 ++- UI/RemoteISOScreen.cpp | 2 +- UI/SavedataScreen.cpp | 2 +- UI/TextureUtil.cpp | 3 ++- UWP/CommonUWP/CommonUWP.vcxproj | 2 ++ UWP/CommonUWP/CommonUWP.vcxproj.filters | 2 ++ UWP/NativeUWP/NativeUWP.vcxproj | 2 -- UWP/NativeUWP/NativeUWP.vcxproj.filters | 6 ------ UWP/PPSSPP_UWPMain.cpp | 17 ++++++++------- Windows/EmuThread.cpp | 2 +- Windows/MainWindow.cpp | 2 +- android/jni/app-android.cpp | 2 +- ext/native/Android.mk | 1 - ext/native/base/CMakeLists.txt | 7 ------- ext/native/base/buffer.cpp | 2 +- ext/native/file/path.cpp | 2 +- ext/native/input/gesture_detector.cpp | 2 +- ext/native/native.vcxproj | 2 -- ext/native/native.vcxproj.filters | 6 ------ ext/native/net/http_client.cpp | 2 +- ext/native/net/http_server.cpp | 2 +- ext/native/net/resolve.cpp | 2 +- ext/native/profiler/profiler.cpp | 2 +- ext/native/thin3d/VulkanQueueRunner.cpp | 2 +- ext/native/thread/prioritizedworkqueue.cpp | 2 +- ext/native/ui/root.cpp | 2 +- ext/native/ui/screen.cpp | 2 +- ext/native/ui/ui_tween.h | 2 +- ext/native/ui/view.cpp | 3 ++- ext/native/ui/viewgroup.cpp | 5 ++--- headless/Headless.cpp | 5 +++-- headless/SDLHeadlessHost.cpp | 21 +++++++++---------- headless/WindowsHeadlessHost.cpp | 14 ++++++------- ios/PPSSPPUIApplication.mm | 2 +- ios/ViewController.mm | 2 +- libretro/Makefile.common | 2 +- libretro/libretro.cpp | 2 +- unittest/JitHarness.cpp | 2 +- unittest/TestVertexJit.cpp | 2 +- 82 files changed, 139 insertions(+), 144 deletions(-) rename ext/native/base/timeutil.cpp => Common/TimeUtil.cpp (98%) rename ext/native/base/timeutil.h => Common/TimeUtil.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b8a4e8706..a723ae2626 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -460,6 +460,8 @@ add_library(Common STATIC Common/ThreadSafeList.h Common/Timer.cpp Common/Timer.h + Common/TimeUtil.cpp + Common/TimeUtil.h ) add_subdirectory(ext) @@ -935,8 +937,6 @@ add_library(native STATIC ext/native/base/linked_ptr.h ext/native/base/stringutil.cpp ext/native/base/stringutil.h - ext/native/base/timeutil.cpp - ext/native/base/timeutil.h ext/native/data/base64.cpp ext/native/data/base64.h ext/native/data/compression.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 40a9f61a06..cfe40b4cf4 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -417,6 +417,7 @@ + @@ -513,6 +514,7 @@ + diff --git a/ext/native/base/timeutil.cpp b/Common/TimeUtil.cpp similarity index 98% rename from ext/native/base/timeutil.cpp rename to Common/TimeUtil.cpp index c2446c3989..54832e853e 100644 --- a/ext/native/base/timeutil.cpp +++ b/Common/TimeUtil.cpp @@ -1,7 +1,7 @@ #include #include "base/basictypes.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #ifdef _WIN32 #include diff --git a/ext/native/base/timeutil.h b/Common/TimeUtil.h similarity index 100% rename from ext/native/base/timeutil.h rename to Common/TimeUtil.h diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 062472c377..5a5cec031b 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -18,10 +18,10 @@ // Additionally, Common/Vulkan/* , including this file, are also licensed // under the public domain. -#include "base/timeutil.h" #include "math/math_util.h" #include "Common/Log.h" +#include "Common/TimeUtil.h" #include "Common/Vulkan/VulkanMemory.h" VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryPropertyMask) diff --git a/Core/Core.cpp b/Core/Core.cpp index acb1ad44c6..6c1952d47e 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -24,7 +24,7 @@ #include "base/NativeApp.h" #include "base/display.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "thread/threadutil.h" #include "profiler/profiler.h" diff --git a/Core/FileLoaders/CachingFileLoader.cpp b/Core/FileLoaders/CachingFileLoader.cpp index f161574916..4902af5a33 100644 --- a/Core/FileLoaders/CachingFileLoader.cpp +++ b/Core/FileLoaders/CachingFileLoader.cpp @@ -20,7 +20,7 @@ #include #include "thread/threadutil.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "Core/FileLoaders/CachingFileLoader.h" // Takes ownership of backend. diff --git a/Core/FileLoaders/RamCachingFileLoader.cpp b/Core/FileLoaders/RamCachingFileLoader.cpp index bc99ad80f0..e575b21b72 100644 --- a/Core/FileLoaders/RamCachingFileLoader.cpp +++ b/Core/FileLoaders/RamCachingFileLoader.cpp @@ -20,8 +20,8 @@ #include #include -#include "base/timeutil.h" #include "thread/threadutil.h" +#include "Common/TimeUtil.h" #include "Core/FileLoaders/RamCachingFileLoader.h" #include "Common/Log.h" diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index d83c9e3fe5..b0b29575bb 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -20,11 +20,11 @@ #include #include -#include "base/timeutil.h" #include "profiler/profiler.h" #include "Common/Log.h" #include "Common/Serialize/SerializeFuncs.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/Core.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 681e11e493..3a803c6d0a 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -31,9 +31,13 @@ #endif #include -#include "util/text/parsers.h" + +#include "i18n/i18n.h" #include "thread/threadutil.h" +#include "util/text/parsers.h" + #include "Common/Serialize/SerializeFuncs.h" +#include "Common/TimeUtil.h" #include "Core/Core.h" #include "Core/Host.h" #include "Core/HLE/sceKernelInterrupt.h" @@ -41,7 +45,6 @@ #include "Core/HLE/sceKernelMemory.h" #include "Core/Instance.h" #include "proAdhoc.h" -#include "i18n/i18n.h" uint16_t portOffset; uint32_t minSocketTimeoutUS; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index e5d39745ee..74aa597446 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -41,7 +41,6 @@ #include #include -#include "base/timeutil.h" #include "net/resolve.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 85d4f2d56a..ef507310ab 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -43,14 +43,16 @@ #include #include //#include + +#include "i18n/i18n.h" #include "thread/threadutil.h" + #include "Common/FileUtil.h" +#include "Common/TimeUtil.h" #include "Core/Util/PortManager.h" #include "Core/Core.h" #include "Core/Host.h" #include "Core/HLE/proAdhocServer.h" -#include "i18n/i18n.h" - // User Count uint32_t _db_user_count = 0; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 406c757635..01c07a5182 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -26,7 +26,6 @@ #include #endif -#include "base/timeutil.h" #include "i18n/i18n.h" #include "profiler/profiler.h" @@ -35,6 +34,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeMap.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/CoreTiming.h" #include "Core/CoreParameter.h" diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 4577aa5d83..dbf0bebf34 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1,6 +1,6 @@ #include "sceFont.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include #include diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 05e5e663c0..8c559e689a 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -31,6 +31,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeMap.h" +#include "Common/TimeUtil.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/Util/PortManager.h" diff --git a/Core/HLE/sceRtc.cpp b/Core/HLE/sceRtc.cpp index f9ad48aa7e..5fc8d372ce 100644 --- a/Core/HLE/sceRtc.cpp +++ b/Core/HLE/sceRtc.cpp @@ -24,10 +24,10 @@ #endif #include -#include "base/timeutil.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" +#include "Common/TimeUtil.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index 5075465589..d130079033 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -35,11 +35,11 @@ #include #include -#include "base/timeutil.h" #include "base/NativeApp.h" -#include "Common/Serialize/Serializer.h" #include "Common/MathUtil.h" +#include "Common/Serialize/Serializer.h" #include "Common/Log.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/HW/StereoResampler.h" diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index d52c2ffebd..10b9720281 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -21,9 +21,9 @@ #include #include -#include "base/timeutil.h" #include "ext/cityhash/city.h" #include "Common/FileUtil.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/MemMap.h" #include "Core/System.h" diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 42ec9b289b..8c5fb1fd0c 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -20,7 +20,6 @@ #include #include -#include "base/timeutil.h" #include "base/stringutil.h" #include "i18n/i18n.h" #include "thread/threadutil.h" @@ -29,6 +28,7 @@ #include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" +#include "Common/TimeUtil.h" #include "Core/SaveState.h" #include "Core/Config.h" diff --git a/Core/System.cpp b/Core/System.cpp index f64754e22d..29fc5e0a30 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -32,13 +32,13 @@ #include #include -#include "base/timeutil.h" #include "base/NativeApp.h" #include "math/math_util.h" #include "thread/threadutil.h" #include "util/text/utf8.h" #include "Common/FileUtil.h" +#include "Common/TimeUtil.h" #include "Common/GraphicsContext.h" #include "Core/MemFault.h" #include "Core/HDRemaster.h" diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index f1ed937836..75218d13f1 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -29,7 +29,7 @@ #include #include #include -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "i18n/i18n.h" #include "net/resolve.h" #include "thread/threadutil.h" diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index eab106add0..4697de3de0 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -20,13 +20,13 @@ #include #include #include "base/stringutil.h" -#include "base/timeutil.h" #include "file/fd_util.h" #include "net/http_client.h" #include "net/http_server.h" #include "net/sinks.h" #include "thread/threadutil.h" #include "Common/FileUtil.h" +#include "Common/TimeUtil.h" #include "Common/Log.h" #include "Core/Config.h" #include "Core/Debugger/WebSocket.h" diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 9ef488ffda..a1fd204c6a 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -21,11 +21,11 @@ #include #include "base/display.h" -#include "base/timeutil.h" #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" #include "thin3d/thin3d.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Host.h" diff --git a/GPU/Common/TextureScalerCommon.cpp b/GPU/Common/TextureScalerCommon.cpp index ca40ba50c9..4b9bf8f307 100644 --- a/GPU/Common/TextureScalerCommon.cpp +++ b/GPU/Common/TextureScalerCommon.cpp @@ -47,7 +47,7 @@ //#define DEBUG_SCALER_OUTPUT #ifdef SCALING_MEASURE_TIME -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #endif /////////////////////////////////////// Helper Functions (mostly math for parallelization) diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index a4780b0b80..0e5b8444a7 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -17,10 +17,9 @@ #include -#include "base/timeutil.h" - #include "Common/Log.h" #include "Common/MemoryUtil.h" +#include "Common/TimeUtil.h" #include "Core/MemMap.h" #include "Core/System.h" #include "Core/Reporting.h" diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index a10a6fca2d..376339c7d4 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -15,10 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/timeutil.h" - #include "Common/Log.h" #include "Common/MemoryUtil.h" +#include "Common/TimeUtil.h" #include "Core/MemMap.h" #include "Core/System.h" #include "Core/Reporting.h" diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index e245fe3112..215d80c07a 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -15,9 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/timeutil.h" - #include "Common/MemoryUtil.h" +#include "Common/TimeUtil.h" #include "Core/MemMap.h" #include "Core/System.h" #include "Core/Reporting.h" diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 58001193b8..58a344b55e 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -24,7 +24,6 @@ #include #include "math/dataconv.h" -#include "base/timeutil.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/gpu_features.h" #include "i18n/i18n.h" @@ -36,6 +35,7 @@ #include "Common/Log.h" #include "Common/FileUtil.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/Host.h" #include "Core/Reporting.h" diff --git a/GPU/GPU.cpp b/GPU/GPU.cpp index 2a0bee4842..f731ee6cbb 100644 --- a/GPU/GPU.cpp +++ b/GPU/GPU.cpp @@ -17,7 +17,7 @@ #include "ppsspp_config.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "Common/GraphicsContext.h" #include "Core/Core.h" diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 4b8d995983..32bcb5ec66 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -2,7 +2,6 @@ #include #include -#include "base/timeutil.h" #include "profiler/profiler.h" #include "Common/ColorConv.h" @@ -10,6 +9,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeList.h" +#include "Common/TimeUtil.h" #include "Core/Reporting.h" #include "GPU/GeDisasm.h" #include "GPU/GPU.h" diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 963fa0f0a6..b241affff0 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -17,13 +17,13 @@ #include -#include "base/timeutil.h" #include "math/dataconv.h" #include "profiler/profiler.h" #include "thin3d/VulkanRenderManager.h" #include "Common/Log.h" #include "Common/MemoryUtil.h" +#include "Common/TimeUtil.h" #include "Core/MemMap.h" #include "Core/System.h" #include "Core/Reporting.h" diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index c2ba043348..93488cfc55 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -18,13 +18,13 @@ #include -#include "base/timeutil.h" #include "profiler/profiler.h" #include "Common/Log.h" -#include "Common/Serialize/Serializer.h" #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" +#include "Common/Serialize/Serializer.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/Debugger/Breakpoints.h" diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 9a69162919..50e0396734 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -23,7 +23,7 @@ QTM_USE_NAMESPACE #include #include "base/display.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "file/zip_read.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 6c882b5681..878d2da2ce 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -22,7 +22,7 @@ SDLJoystick *joystick = NULL; #include #include "base/display.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "ext/glslang/glslang/Public/ShaderLang.h" #include "image/png_load.h" #include "input/input_state.h" diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index a061af2056..8337d13576 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -1,14 +1,14 @@ #include #include -#include "base/timeutil.h" #include "file/chunk_file.h" #include "file/vfs.h" #include "ui/root.h" +#include "Common/CommonTypes.h" #include "Common/Log.h" #include "Common/Serialize/SerializeFuncs.h" -#include "Common/CommonTypes.h" +#include "Common/TimeUtil.h" #include "Common/FixedSizeQueue.h" #include "Core/HW/SimpleAudioDec.h" #include "Core/HLE/__sceAudio.h" diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index e309ba35b3..8741168179 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -16,12 +16,12 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "TouchControlVisibilityScreen.h" +#include "UI/ComboKeyMappingScreen.h" + #include "Core/Config.h" #include "i18n/i18n.h" -#include "ComboKeyMappingScreen.h" #include "base/colorutil.h" #include "base/display.h" -#include "base/timeutil.h" #include "file/path.h" #include "gfx_es2/draw_buffer.h" #include "gfx/texture_atlas.h" @@ -31,6 +31,8 @@ #include "ui/view.h" #include "ui/viewgroup.h" +#include "Common/TimeUtil.h" + void ComboKeyScreen::CreateViews() { using namespace UI; auto co = GetI18NCategory("Controls"); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 1d44551622..a6d5b600e1 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -20,7 +20,6 @@ #include #include "base/display.h" -#include "base/timeutil.h" #include "profiler/profiler.h" #include "gfx/texture_atlas.h" @@ -38,6 +37,7 @@ #include "Common/KeyMap.h" #include "Common/Log.h" +#include "Common/TimeUtil.h" #ifndef MOBILE_DEVICE #include "Core/AVIDump.h" diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 1fa929f5a4..a88130091a 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -22,7 +22,6 @@ #include #include -#include "base/timeutil.h" #include "base/stringutil.h" #include "file/file_util.h" #include "file/zip_read.h" @@ -31,6 +30,7 @@ #include "Common/FileUtil.h" #include "Common/StringUtils.h" +#include "Common/TimeUtil.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/FileSystems/DirectoryFileSystem.h" #include "Core/FileSystems/VirtualDiscFileSystem.h" diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index bcb0a293c5..7b2a2b8793 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -21,7 +21,7 @@ #include "base/colorutil.h" #include "base/stringutil.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "math/curves.h" #include "net/resolve.h" #include "gfx_es2/gpu_features.h" diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index ef3a1ad2be..59b3bd4ba7 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -16,19 +16,21 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + +#include "base/colorutil.h" +#include "base/display.h" +#include "base/NativeApp.h" +#include "gfx/texture_atlas.h" +#include "math/math_util.h" +#include "ui/ui_context.h" + #include "Common/Log.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/Core.h" #include "Core/System.h" #include "Core/HLE/sceCtrl.h" #include "UI/GamepadEmu.h" -#include "base/colorutil.h" -#include "base/display.h" -#include "base/NativeApp.h" -#include "base/timeutil.h" -#include "gfx/texture_atlas.h" -#include "math/math_util.h" -#include "ui/ui_context.h" static u32 GetButtonColor() { return g_Config.iTouchButtonStyle != 0 ? 0xFFFFFF : 0xc0b080; diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index c444568214..ac90e768f2 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -21,7 +21,6 @@ #include "ppsspp_config.h" #include "base/colorutil.h" #include "base/display.h" -#include "base/timeutil.h" #include "file/path.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" @@ -34,6 +33,7 @@ #include "util/text/utf8.h" #include "Common/FileUtil.h" +#include "Common/TimeUtil.h" #include "Core/System.h" #include "Core/Host.h" #include "Core/Reporting.h" diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index e88e244829..5a01b65735 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -22,7 +22,6 @@ #include "base/colorutil.h" #include "base/display.h" -#include "base/timeutil.h" #include "gfx_es2/draw_buffer.h" #include "math/curves.h" #include "i18n/i18n.h" @@ -32,6 +31,17 @@ #include "ui/ui.h" #include "util/random/rng.h" #include "file/vfs.h" + +#include "Common/TimeUtil.h" +#include "Common/FileUtil.h" +#include "Core/Config.h" +#include "Core/Host.h" +#include "Core/System.h" +#include "Core/MIPS/JitCommon/JitCommon.h" +#include "Core/HLE/sceUtility.h" +#include "GPU/GPUState.h" +#include "GPU/Common/PostShader.h" + #include "UI/ControlMappingScreen.h" #include "UI/DisplayLayoutScreen.h" #include "UI/EmuScreen.h" @@ -39,14 +49,6 @@ #include "UI/GameSettingsScreen.h" #include "UI/MainScreen.h" #include "UI/MiscScreens.h" -#include "Core/Config.h" -#include "Core/Host.h" -#include "Core/System.h" -#include "Core/MIPS/JitCommon/JitCommon.h" -#include "Core/HLE/sceUtility.h" -#include "Common/FileUtil.h" -#include "GPU/GPUState.h" -#include "GPU/Common/PostShader.h" #ifdef _MSC_VER #pragma execution_character_set("utf-8") diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 445d007269..91d0b7c86e 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -45,7 +45,7 @@ #include "base/display.h" #include "base/stringutil.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index 66517ad1c0..f45fb125d8 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -1,12 +1,13 @@ #include "UI/OnScreenDisplay.h" #include "base/colorutil.h" -#include "base/timeutil.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" #include "ui/ui_context.h" +#include "Common/TimeUtil.h" + OnScreenMessages osm; void OnScreenMessagesView::Draw(UIContext &dc) { diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 8029c39671..93e8410232 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -26,7 +26,6 @@ #endif #include "base/stringutil.h" -#include "base/timeutil.h" #include "file/path.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" @@ -36,6 +35,7 @@ #include "net/resolve.h" #include "net/url.h" #include "Common/Common.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/WebServer.h" #include "UI/RemoteISOScreen.h" diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 0f3ce2a45f..59d227a60f 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -20,7 +20,6 @@ #include "base/colorutil.h" #include "base/stringutil.h" -#include "base/timeutil.h" #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" #include "math/curves.h" @@ -35,6 +34,7 @@ #include "UI/PauseScreen.h" #include "Common/FileUtil.h" +#include "Common/TimeUtil.h" #include "Core/Host.h" #include "Core/Config.h" #include "Core/Loaders.h" diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index dc0cfa2355..284a9b019d 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -1,7 +1,6 @@ #include #include "base/colorutil.h" -#include "base/timeutil.h" #include "thin3d/thin3d.h" #include "image/zim_load.h" #include "image/png_load.h" @@ -12,7 +11,9 @@ #include "ui/view.h" #include "ui/ui_context.h" #include "gfx_es2/draw_buffer.h" + #include "Common/Log.h" +#include "Common/TimeUtil.h" #include "UI/TextureUtil.h" #include "UI/GameInfoCache.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index d07e29c0a5..3405d3666f 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -423,6 +423,7 @@ + @@ -460,6 +461,7 @@ + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 5a670fd890..57775b7f87 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -35,6 +35,7 @@ + @@ -91,6 +92,7 @@ + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index cce36088aa..0fba453b04 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -389,7 +389,6 @@ - @@ -479,7 +478,6 @@ - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 5e8aaecb8d..8835c898dd 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -79,9 +79,6 @@ base - - base - thin3d @@ -505,9 +502,6 @@ base - - base - thin3d diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 5711ae0b29..373f164eaf 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -5,14 +5,7 @@ #include #include "base/basictypes.h" -#include "Common/FileUtil.h" -#include "Common/Log.h" -#include "Common/LogManager.h" -#include "Core/System.h" -#include "Core/Loaders.h" -#include "Core/Config.h" #include "base/NativeApp.h" -#include "base/timeutil.h" #include "input/input_state.h" #include "file/vfs.h" #include "file/zip_read.h" @@ -23,7 +16,17 @@ #include "thread/threadutil.h" #include "thin3d/thin3d_create.h" #include "util/text/utf8.h" + #include "Common/DirectXHelper.h" +#include "Common/FileUtil.h" +#include "Common/Log.h" +#include "Common/LogManager.h" +#include "Common/TimeUtil.h" + +#include "Core/System.h" +#include "Core/Loaders.h" +#include "Core/Config.h" + #include "NKCodeFromWindowsSystem.h" #include "XAudioSoundStream.h" #include "UWPHost.h" diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 83ce9471f7..2e314b0f14 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -2,7 +2,6 @@ #include #include -#include "base/timeutil.h" #include "base/NativeApp.h" #include "i18n/i18n.h" #include "input/input_state.h" @@ -11,6 +10,7 @@ #include "Common/Log.h" #include "Common/StringUtils.h" #include "Common/GraphicsContext.h" +#include "Common/TimeUtil.h" #include "Windows/EmuThread.h" #include "Windows/W32Util/Misc.h" #include "Windows/MainWindow.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 59f6820aa5..c802848273 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -35,7 +35,7 @@ #include "base/display.h" #include "base/NativeApp.h" #include "base/stringutil.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "i18n/i18n.h" #include "input/input_state.h" #include "input/keycodes.h" diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index a0c5c6a5af..e6531bdd31 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -53,7 +53,6 @@ struct JNIEnv {}; #include "base/stringutil.h" #include "base/display.h" #include "base/NativeApp.h" -#include "base/timeutil.h" #include "thread/threadutil.h" #include "file/zip_read.h" #include "input/input_state.h" @@ -68,6 +67,7 @@ struct JNIEnv {}; #include "Common/Log.h" #include "Common/GraphicsContext.h" +#include "Common/TimeUtil.h" #include "AndroidGraphicsContext.h" #include "AndroidVulkanContext.h" #include "AndroidEGLContext.h" diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 0373665117..2699df0ff8 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -10,7 +10,6 @@ LOCAL_SRC_FILES :=\ base/backtrace.cpp \ base/buffer.cpp \ base/display.cpp \ - base/timeutil.cpp \ base/colorutil.cpp \ base/stringutil.cpp \ data/base64.cpp \ diff --git a/ext/native/base/CMakeLists.txt b/ext/native/base/CMakeLists.txt index 9915f73bec..7044873bbe 100644 --- a/ext/native/base/CMakeLists.txt +++ b/ext/native/base/CMakeLists.txt @@ -1,6 +1,5 @@ set(SRCS colorutil.cpp - timeutil.cpp ../thread/threadutil.cpp display.cpp buffer.cpp @@ -11,9 +10,3 @@ add_library(base STATIC ${SRCS}) if(UNIX) add_definitions(-fPIC) endif(UNIX) - -add_library(timeutil STATIC timeutil.cpp) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/base/buffer.cpp b/ext/native/base/buffer.cpp index e603ff059f..86ccd22480 100644 --- a/ext/native/base/buffer.cpp +++ b/ext/native/base/buffer.cpp @@ -18,7 +18,7 @@ #define MSG_NOSIGNAL 0x00 #endif -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "file/fd_util.h" #include "Common/Log.h" diff --git a/ext/native/file/path.cpp b/ext/native/file/path.cpp index 2bcb7e1cdb..8025878c02 100644 --- a/ext/native/file/path.cpp +++ b/ext/native/file/path.cpp @@ -2,7 +2,7 @@ #include #include #include "base/stringutil.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "file/path.h" #include "net/http_client.h" #include "net/url.h" diff --git a/ext/native/input/gesture_detector.cpp b/ext/native/input/gesture_detector.cpp index 40bbb3c784..d73f4f9090 100644 --- a/ext/native/input/gesture_detector.cpp +++ b/ext/native/input/gesture_detector.cpp @@ -2,7 +2,7 @@ // TODO: // Zoom gesture a la http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-6-implementing-the-pinch-zoom-gesture/1847 -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "input/gesture_detector.h" const float estimatedInertiaDamping = 0.75f; diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index afb7f0ffed..338f014265 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -389,7 +389,6 @@ - @@ -516,7 +515,6 @@ true - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 91a926358b..6f6f940372 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -80,9 +80,6 @@ math - - base - input @@ -397,9 +394,6 @@ gfx - - base - input diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index 7ff05ec99e..a8658b2ad2 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -1,5 +1,5 @@ #include "net/http_client.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #ifndef _WIN32 #include diff --git a/ext/native/net/http_server.cpp b/ext/native/net/http_server.cpp index 1520b05873..e509ee7c0b 100644 --- a/ext/native/net/http_server.cpp +++ b/ext/native/net/http_server.cpp @@ -1,4 +1,4 @@ -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "ppsspp_config.h" #ifdef _WIN32 diff --git a/ext/native/net/resolve.cpp b/ext/native/net/resolve.cpp index e1479541a5..a6e07c0635 100644 --- a/ext/native/net/resolve.cpp +++ b/ext/native/net/resolve.cpp @@ -24,7 +24,7 @@ #include #endif -#include "base/timeutil.h" +#include "Common/TimeUtil.h" namespace net { diff --git a/ext/native/profiler/profiler.cpp b/ext/native/profiler/profiler.cpp index 60dffd5154..2538dbba2e 100644 --- a/ext/native/profiler/profiler.cpp +++ b/ext/native/profiler/profiler.cpp @@ -8,7 +8,7 @@ #include -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "gfx_es2/draw_buffer.h" #include "ppsspp_config.h" #include "profiler/profiler.h" diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 6ce2eb4249..91767c164d 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -1,8 +1,8 @@ #include -#include "base/timeutil.h" #include "DataFormat.h" #include "Common/Log.h" +#include "Common/TimeUtil.h" #include "VulkanQueueRunner.h" #include "VulkanRenderManager.h" diff --git a/ext/native/thread/prioritizedworkqueue.cpp b/ext/native/thread/prioritizedworkqueue.cpp index dcb233f38c..24a51c7c70 100644 --- a/ext/native/thread/prioritizedworkqueue.cpp +++ b/ext/native/thread/prioritizedworkqueue.cpp @@ -1,7 +1,7 @@ #include #include -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "thread/prioritizedworkqueue.h" #include "Common/Log.h" diff --git a/ext/native/ui/root.cpp b/ext/native/ui/root.cpp index 928d34dbfe..394ee2aa28 100644 --- a/ext/native/ui/root.cpp +++ b/ext/native/ui/root.cpp @@ -3,11 +3,11 @@ #include "ppsspp_config.h" -#include "base/timeutil.h" #include "ui/root.h" #include "ui/viewgroup.h" #include "Common/Log.h" +#include "Common/TimeUtil.h" namespace UI { diff --git a/ext/native/ui/screen.cpp b/ext/native/ui/screen.cpp index 32a26196cc..696d1986b6 100644 --- a/ext/native/ui/screen.cpp +++ b/ext/native/ui/screen.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/timeutil.h" #include "input/input_state.h" #include "ui/root.h" #include "ui/screen.h" @@ -7,6 +6,7 @@ #include "ui/view.h" #include "Common/Log.h" +#include "Common/TimeUtil.h" ScreenManager::ScreenManager() { uiContext_ = 0; diff --git a/ext/native/ui/ui_tween.h b/ext/native/ui/ui_tween.h index aad4fbfa5d..57e9f69116 100644 --- a/ext/native/ui/ui_tween.h +++ b/ext/native/ui/ui_tween.h @@ -3,7 +3,7 @@ #include #include #include -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "ui/view.h" namespace UI { diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 577fd91e1c..f457a6b73c 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -2,7 +2,6 @@ #include #include "base/stringutil.h" -#include "base/timeutil.h" #include "input/input_state.h" #include "input/keycodes.h" #include "gfx_es2/draw_buffer.h" @@ -16,6 +15,8 @@ #include "thin3d/thin3d.h" #include "base/NativeApp.h" +#include "Common/TimeUtil.h" + namespace UI { const float ITEM_HEIGHT = 64.f; diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index cf96bc8db3..1a13ac27e9 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -1,9 +1,9 @@ +#include #include #include #include #include "base/stringutil.h" -#include "base/timeutil.h" #include "input/keycodes.h" #include "math/curves.h" #include "ui/ui_context.h" @@ -14,8 +14,7 @@ #include "gfx_es2/draw_buffer.h" #include "Common/Log.h" - -#include +#include "Common/TimeUtil.h" namespace UI { diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 4e0cee7457..bfa385b6a3 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -9,10 +9,13 @@ #include #endif +#include "base/NativeApp.h" #include "file/zip_read.h" #include "profiler/profiler.h" + #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Core.h" @@ -24,8 +27,6 @@ #include "GPU/Common/FramebufferManagerCommon.h" #include "Log.h" #include "LogManager.h" -#include "base/NativeApp.h" -#include "base/timeutil.h" #include "Compare.h" #include "StubHost.h" diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index b81b47a51e..75b39e9c78 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -22,17 +22,6 @@ #include #include "headless/SDLHeadlessHost.h" - -#include "Common/FileUtil.h" -#include "Common/GraphicsContext.h" - -#include "Core/CoreParameter.h" -#include "Core/ConfigValues.h" -#include "Core/System.h" -#include "GPU/Common/GPUDebugInterface.h" -#include "GPU/GPUState.h" - -#include "base/timeutil.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" #include "file/vfs.h" @@ -40,6 +29,16 @@ #include "thin3d/thin3d_create.h" #include "thin3d/GLRenderManager.h" +#include "Common/FileUtil.h" +#include "Common/GraphicsContext.h" +#include "Common/TimeUtil.h" + +#include "Core/CoreParameter.h" +#include "Core/ConfigValues.h" +#include "Core/System.h" +#include "GPU/Common/GPUDebugInterface.h" +#include "GPU/GPUState.h" + const bool WINDOW_VISIBLE = false; const int WINDOW_WIDTH = 480; const int WINDOW_HEIGHT = 272; diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index 18b90d72bf..5d5e79dfc7 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -19,9 +19,15 @@ #include "headless/WindowsHeadlessHost.h" +#include "gfx/gl_common.h" +#include "gfx_es2/gpu_features.h" +#include "file/vfs.h" +#include "file/zip_read.h" + +#include "Common/CommonWindows.h" #include "Common/Log.h" #include "Common/FileUtil.h" -#include "Common/CommonWindows.h" +#include "Common/TimeUtil.h" #include "Core/CoreParameter.h" #include "Core/System.h" @@ -34,12 +40,6 @@ #include "Windows/GPU/D3D11Context.h" #include "Windows/GPU/WindowsVulkanContext.h" -#include "base/timeutil.h" -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" -#include "file/vfs.h" -#include "file/zip_read.h" - const bool WINDOW_VISIBLE = false; const int WINDOW_WIDTH = 480; const int WINDOW_HEIGHT = 272; diff --git a/ios/PPSSPPUIApplication.mm b/ios/PPSSPPUIApplication.mm index d07e7a26e0..c410c8156d 100644 --- a/ios/PPSSPPUIApplication.mm +++ b/ios/PPSSPPUIApplication.mm @@ -13,7 +13,7 @@ #import #include "base/display.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "file/zip_read.h" #include "input/input_state.h" #include "net/resolve.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 4741c4373e..4d748b0a88 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -13,7 +13,7 @@ #include #include "base/display.h" -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "file/zip_read.h" #include "input/input_state.h" #include "net/resolve.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index c4ac5d2f4e..d9e90898eb 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -153,6 +153,7 @@ SOURCES_CXX += \ $(COMMONDIR)/MsgHandler.cpp \ $(COMMONDIR)/StringUtils.cpp \ $(COMMONDIR)/Timer.cpp \ + $(COMMONDIR)/TimeUtil.cpp \ $(COMMONDIR)/ThreadPools.cpp @@ -216,7 +217,6 @@ SOURCES_CXX += \ $(EXTDIR)/native/base/colorutil.cpp \ $(EXTDIR)/native/base/display.cpp \ $(EXTDIR)/native/base/stringutil.cpp \ - $(EXTDIR)/native/base/timeutil.cpp \ $(EXTDIR)/native/data/compression.cpp \ $(EXTDIR)/native/json/json_reader.cpp \ $(EXTDIR)/glslang/OGLCompilersDLL/InitializeDll.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 2b61b9f550..13f4f2c8a4 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -5,7 +5,7 @@ #include #include -#include "base/timeutil.h" +#include "Common/TimeUtil.h" #include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" #include "Core/Config.h" diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index 1569048b18..6ab64de21e 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -17,8 +17,8 @@ #include -#include "base/timeutil.h" #include "base/NativeApp.h" +#include "Common/TimeUtil.h" #include "Core/ConfigValues.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" diff --git a/unittest/TestVertexJit.cpp b/unittest/TestVertexJit.cpp index 75e5985888..ac00dfd532 100644 --- a/unittest/TestVertexJit.cpp +++ b/unittest/TestVertexJit.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/timeutil.h" #include "Common/Common.h" +#include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "GPU/Common/VertexDecoderCommon.h" From abd2a1542c274ec02628367739714fbfa35b6490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 21:36:42 +0200 Subject: [PATCH 513/848] Update .editorconfig to match the encoding of the resource files. --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 965fbcf1ee..332927531a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -27,7 +27,7 @@ charset = utf-8-bom charset = utf-8-bom [Windows/{aboutbox.rc,version.rc}] -charset = utf-16le +charset = utf-8 [libretro/**.{cpp,h}] indent_style = space From d3d90a11cf3e5f91c09d3046fc99835e50e3ae1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 15 Aug 2020 22:18:54 +0200 Subject: [PATCH 514/848] Android.mk fix --- android/jni/Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 4f7d7c2899..cd30bde35c 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -220,6 +220,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/StringUtils.cpp \ $(SRC)/Common/ThreadPools.cpp \ $(SRC)/Common/Timer.cpp \ + $(SRC)/Common/TimeUtil.cpp \ $(SRC)/Common/Misc.cpp \ $(SRC)/GPU/Math3D.cpp \ $(SRC)/GPU/GPU.cpp \ From 7aacf3df370bd26225c87740c3ba8f749d5c2c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 00:13:19 +0200 Subject: [PATCH 515/848] Remove time_now() - time_now_d() is the replacement. Absolute time values can't be stored reliably in floats. --- Common/TimeUtil.cpp | 14 -------------- Common/TimeUtil.h | 1 - Common/Vulkan/VulkanMemory.cpp | 6 +++--- Core/SaveState.cpp | 6 +++--- GPU/Common/PresentationCommon.cpp | 2 +- UI/GamepadEmu.cpp | 6 +++--- UI/GamepadEmu.h | 4 ++-- UI/MainScreen.cpp | 2 +- UI/MiscScreens.cpp | 4 ++-- UI/SavedataScreen.cpp | 2 +- ext/native/ui/ui_tween.h | 20 ++++++++++---------- ext/native/ui/view.cpp | 4 ++-- 12 files changed, 28 insertions(+), 43 deletions(-) diff --git a/Common/TimeUtil.cpp b/Common/TimeUtil.cpp index 54832e853e..7a3f3b6c46 100644 --- a/Common/TimeUtil.cpp +++ b/Common/TimeUtil.cpp @@ -17,7 +17,6 @@ #include "Common/Log.h" static double curtime = 0; -static float curtime_f = 0; #ifdef _WIN32 @@ -58,19 +57,6 @@ double real_time_now() { void time_update() { curtime = real_time_now(); - curtime_f = (float)curtime; - - //printf("curtime: %f %f\n", curtime, curtime_f); - // also smooth time. - //curtime+=float((double) (time-_starttime) / (double) _frequency); - //curtime*=0.5f; - //curtime+=1.0f/60.0f; - //lastTime=curtime; - //curtime_f = (float)curtime; -} - -float time_now() { - return curtime_f; } double time_now_d() { diff --git a/Common/TimeUtil.h b/Common/TimeUtil.h index 8ba68ca8ad..c7c38ed6f0 100644 --- a/Common/TimeUtil.h +++ b/Common/TimeUtil.h @@ -8,7 +8,6 @@ void time_update(); // Seconds. -float time_now(); double time_now_d(); // Uncached time. Slower than the above cached time functions. Does not update cached time, call time_update for that. diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 5a5cec031b..ab5660b389 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -278,7 +278,7 @@ bool VulkanDeviceAllocator::AllocateFromSlab(Slab &slab, size_t &start, size_t b // Remember the size so we can free. slab.allocSizes[start] = blocks; - slab.tags[start] = { tag, time_now(), 0.0f }; + slab.tags[start] = { tag, (float)time_now_d(), 0.0f }; slab.totalUsage += blocks; return true; } @@ -312,7 +312,7 @@ void VulkanDeviceAllocator::DoTouch(VkDeviceMemory deviceMemory, size_t offset) auto it = slab.tags.find(start); if (it != slab.tags.end()) { - it->second.touched = time_now(); + it->second.touched = time_now_d(); found = true; } } @@ -436,7 +436,7 @@ bool VulkanDeviceAllocator::AllocateSlab(VkDeviceSize minBytes, int memoryTypeIn } void VulkanDeviceAllocator::ReportOldUsage() { - float now = time_now(); + float now = time_now_d(); static const float OLD_AGE = 10.0f; for (size_t i = 0; i < slabs_.size(); ++i) { const auto &slab = slabs_[i]; diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 8c5fb1fd0c..442475876e 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -263,7 +263,7 @@ namespace SaveState static StateRingbuffer rewindStates(REWIND_NUM_STATES); // TODO: Any reason for this to be configurable? const static float rewindMaxWallFrequency = 1.0f; - static float rewindLastTime = 0.0f; + static double rewindLastTime = 0.0f; const int StateRingbuffer::BLOCK_SIZE = 8192; const int StateRingbuffer::BASE_USAGE_INTERVAL = 15; @@ -671,11 +671,11 @@ namespace SaveState // For fast-forwarding, otherwise they may be useless and too close. time_update(); - float diff = time_now() - rewindLastTime; + float diff = time_now_d() - rewindLastTime; if (diff < rewindMaxWallFrequency) return; - rewindLastTime = time_now(); + rewindLastTime = time_now_d(); DEBUG_LOG(BOOT, "saving rewind state"); rewindStates.Save(); } diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index a1fd204c6a..653a2de946 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -178,7 +178,7 @@ void PresentationCommon::CalculatePostShaderUniforms(int bufferWidth, int buffer float v_pixel_delta = 1.0f / targetHeight; int flipCount = __DisplayGetFlipCount(); int vCount = __DisplayGetVCount(); - float time[4] = { time_now(), (vCount % 60) * 1.0f / 60.0f, (float)vCount, (float)(flipCount % 60) }; + float time[4] = { (float)time_now_d(), (vCount % 60) * 1.0f / 60.0f, (float)vCount, (float)(flipCount % 60) }; uniforms->texelDelta[0] = u_delta; uniforms->texelDelta[1] = v_delta; diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 59b3bd4ba7..ade3f154a1 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -36,7 +36,7 @@ static u32 GetButtonColor() { return g_Config.iTouchButtonStyle != 0 ? 0xFFFFFF : 0xc0b080; } -GamepadView::GamepadView(UI::LayoutParams *layoutParams) : UI::View(layoutParams), secondsWithoutTouch_(0) { +GamepadView::GamepadView(UI::LayoutParams *layoutParams) : UI::View(layoutParams) { lastFrameTime_ = time_now_d(); } @@ -45,7 +45,7 @@ void GamepadView::Touch(const TouchInput &input) { } void GamepadView::Update() { - const float now = time_now(); + const double now = time_now_d(); float delta = now - lastFrameTime_; if (delta > 0) { secondsWithoutTouch_ += delta; @@ -195,7 +195,7 @@ void AnalogRotationButton::Touch(const TouchInput &input) { } void AnalogRotationButton::Update() { - const float now = time_now(); + const float now = time_now_d(); float delta = now - lastFrameTime_; if (delta > 0) { secondsWithoutTouch_ += delta; diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 9f2fbc2a1f..57c2c41ecb 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -37,8 +37,8 @@ public: protected: virtual float GetButtonOpacity(); - float lastFrameTime_; - float secondsWithoutTouch_; + double lastFrameTime_; + float secondsWithoutTouch_ = 0.0; }; class MultiTouchButton : public GamepadView { diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index ac90e768f2..ca03869cd8 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -317,7 +317,7 @@ void GameButton::Draw(UIContext &dc) { if (HasFocus()) { dc.Draw()->Flush(); dc.RebindTexture(); - float pulse = sinf(time_now() * 7.0f) * 0.25 + 0.8; + float pulse = sin(time_now_d() * 7.0) * 0.25 + 0.8; dc.Draw()->DrawImage4Grid(dc.theme->dropShadow4Grid, x - dropsize*1.5f, y - dropsize*1.5f, x + w + dropsize*1.5f, y + h + dropsize*1.5f, alphaMul(color, pulse), 1.0f); dc.Draw()->Flush(); } else { diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 5a01b65735..a5e2952483 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -123,11 +123,11 @@ void DrawBackground(UIContext &dc, float alpha) { ui_draw2d.DrawImageStretch(img, dc.GetBounds(), bgColor); } - float t = time_now(); + double t = time_now_d(); for (int i = 0; i < 100; i++) { float x = xbase[i] + dc.GetBounds().x; float y = ybase[i] + dc.GetBounds().y + 40 * cosf(i * 7.2f + t * 1.3f); - float angle = sinf(i + t); + float angle = (float)sin(i + t); int n = i & 3; ui_draw2d.DrawImageRotated(symbols[n], x, y, 1.0f, angle, colorAlpha(colors[n], alpha * 0.1f)); } diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 59d227a60f..45e951c419 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -248,7 +248,7 @@ void SavedataButton::Draw(UIContext &dc) { if (HasFocus()) { dc.Draw()->Flush(); dc.RebindTexture(); - float pulse = sinf(time_now() * 7.0f) * 0.25 + 0.8; + float pulse = sin(time_now_d() * 7.0) * 0.25 + 0.8; dc.Draw()->DrawImage4Grid(dc.theme->dropShadow4Grid, x - dropsize*1.5f, y - dropsize*1.5f, x + w + dropsize*1.5f, y + h + dropsize*1.5f, alphaMul(color, pulse), 1.0f); dc.Draw()->Flush(); } else { diff --git a/ext/native/ui/ui_tween.h b/ext/native/ui/ui_tween.h index 57e9f69116..67d353d074 100644 --- a/ext/native/ui/ui_tween.h +++ b/ext/native/ui/ui_tween.h @@ -12,7 +12,7 @@ namespace UI { class Tween { public: explicit Tween(float duration, float (*curve)(float)) : duration_(duration), curve_(curve) { - start_ = time_now(); + start_ = time_now_d(); } virtual ~Tween() { } @@ -21,7 +21,7 @@ public: void Apply(View *view); bool Finished() { - return finishApplied_ && time_now() >= start_ + delay_ + duration_; + return finishApplied_ && time_now_d() >= start_ + delay_ + duration_; } void Persist() { @@ -41,7 +41,7 @@ public: protected: float DurationOffset() { - return time_now() - start_ - delay_; + return (time_now_d() - start_) - delay_; } float Position() { @@ -50,7 +50,7 @@ protected: virtual void DoApply(View *view, float pos) = 0; - float start_; + double start_; float duration_; float delay_ = 0.0f; bool finishApplied_ = false; @@ -78,7 +78,7 @@ public: const Value newFrom = valid_ ? Current(Position()) : newTo; // Are we already part way through another transition? - if (time_now() < start_ + delay_ + duration_ && valid_) { + if (time_now_d() < start_ + delay_ + duration_ && valid_) { if (newTo == to_) { // Already on course. Don't change. return; @@ -88,17 +88,17 @@ public: if (newDuration >= 0.0f) { newOffset *= newDuration / duration_; } - start_ = time_now() - newOffset - delay_; - } else if (time_now() <= start_ + delay_) { + start_ = time_now_d() - newOffset - delay_; + } else if (time_now_d() <= start_ + delay_) { // Start the delay over again. - start_ = time_now(); + start_ = time_now_d(); } else { // Since we've partially animated to the other value, skip delay. - start_ = time_now() - delay_; + start_ = time_now_d() - delay_; } } else { // Already finished, so restart. - start_ = time_now(); + start_ = time_now_d(); finishApplied_ = false; } diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index f457a6b73c..252dd60b79 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -201,12 +201,12 @@ Clickable::Clickable(LayoutParams *layoutParams) void Clickable::DrawBG(UIContext &dc, const Style &style) { if (style.background.type == DRAW_SOLID_COLOR) { - if (time_now() - bgColorLast_ >= 0.25f) { + if (time_now_d() - bgColorLast_ >= 0.25f) { bgColor_->Reset(style.background.color); } else { bgColor_->Divert(style.background.color, down_ ? 0.05f : 0.1f); } - bgColorLast_ = time_now(); + bgColorLast_ = time_now_d(); dc.FillRect(Drawable(bgColor_->CurrentValue()), bounds_); } else { From c8a06d40c906392bb54f1ce693e20261d7868904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 10:00:26 +0200 Subject: [PATCH 516/848] Buildfix --- Common/TimeUtil.h | 5 +++-- headless/Headless.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Common/TimeUtil.h b/Common/TimeUtil.h index c7c38ed6f0..7fa7b1966b 100644 --- a/Common/TimeUtil.h +++ b/Common/TimeUtil.h @@ -2,8 +2,9 @@ // http://linux.die.net/man/3/clock_gettime -// This time implementation caches the time for max performance (call time_now() as much as you like). +// This time implementation caches the time for max performance (call time_now_d() as much as you like). // You need to call time_update() once per frame (or whenever you need the correct time right now). +// Or you can use real_time_now() directly. void time_update(); @@ -33,4 +34,4 @@ private: bool endCalled_; double totalTime_; double endTime_; -}; \ No newline at end of file +}; diff --git a/headless/Headless.cpp b/headless/Headless.cpp index bfa385b6a3..7f5e5fdcf4 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -175,7 +175,7 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool // TODO: We must have some kind of stack overflow or we're not following the ABI right. // This gets trashed if it's not static. static double deadline; - deadline = time_now() + timeout; + deadline = time_now_d() + timeout; Core_UpdateDebugStats(g_Config.bShowDebugStats || g_Config.bLogFrameDrops); From c5147c01a09dbcbb1a57511f32824b5e0cf2a7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 00:38:31 +0200 Subject: [PATCH 517/848] Fix newlines in logging before the manager is initialized. --- Common/LogManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 8adf305dd6..84a91f6530 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -52,6 +52,7 @@ void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const char } else { // Fall back to printf if we're before the log manager has been initialized. vprintf(fmt, args); + printf("\n"); } va_end(args); } From 5d64fc5ff1640a7dfc1b6cf7caed72bd40738257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 00:38:55 +0200 Subject: [PATCH 518/848] Switch to PPSSPP's assert functions (don't use the system's) --- Common/Common.h | 7 ---- Common/Log.h | 21 +++++----- Common/Vulkan/VulkanContext.h | 1 - Common/Vulkan/VulkanDebug.cpp | 1 - Common/Vulkan/VulkanImage.cpp | 2 +- Common/Vulkan/VulkanMemory.h | 10 +++-- Core/CwCheat.cpp | 7 ++-- .../WebSocket/GPUBufferSubscriber.cpp | 4 +- Core/Debugger/WebSocket/WebSocketUtils.h | 1 - Core/HLE/sceIo.cpp | 4 +- Core/HLE/sceKernelThread.cpp | 2 +- Core/Util/PPGeDraw.cpp | 8 ++-- GPU/Common/FramebufferManagerCommon.cpp | 5 +-- GPU/Common/PresentationCommon.cpp | 5 +-- GPU/Common/TextureScalerCommon.cpp | 1 - GPU/D3D11/TextureCacheD3D11.cpp | 1 - GPU/Directx9/TextureCacheDX9.cpp | 1 - GPU/Vulkan/DepalettizeShaderVulkan.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 10 ++--- GPU/Vulkan/FramebufferManagerVulkan.cpp | 8 ++-- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 6 +-- GPU/Vulkan/TextureCacheVulkan.cpp | 6 +-- GPU/Vulkan/VulkanUtil.cpp | 20 +++++----- SDL/SDLGLGraphicsContext.cpp | 2 +- SDL/SDLMain.cpp | 1 - SDL/SDLVulkanGraphicsContext.cpp | 2 +- UI/DiscordIntegration.cpp | 5 +-- UWP/PPSSPP_UWPMain.cpp | 3 +- Windows/Debugger/Debugger_Disasm.cpp | 6 --- Windows/EmuThread.cpp | 1 - Windows/GPU/D3D11Context.cpp | 1 - Windows/GPU/WindowsGLContext.cpp | 1 - Windows/GPU/WindowsVulkanContext.cpp | 1 - Windows/WASAPIStream.cpp | 11 +++--- android/jni/AndroidEGLContext.cpp | 2 - android/jni/AndroidJavaGLContext.cpp | 2 - android/jni/AndroidJavaGLContext.h | 1 + android/jni/AndroidVulkanContext.cpp | 2 - ext/native/gfx_es2/draw_text_android.cpp | 5 +-- ext/native/net/websocket_server.cpp | 39 ++++++++++--------- ext/native/thin3d/GLQueueRunner.cpp | 12 +++--- ext/native/thin3d/GLRenderManager.cpp | 24 ++++++------ ext/native/thin3d/VulkanRenderManager.cpp | 24 ++++++------ ext/native/thin3d/VulkanRenderManager.h | 6 +-- ext/native/thin3d/thin3d_d3d11.cpp | 11 +++--- ext/native/thin3d/thin3d_vulkan.cpp | 9 ++--- ext/native/thin3d/vulkan_utils.cpp | 10 ++--- headless/SDLHeadlessHost.cpp | 6 +-- 49 files changed, 142 insertions(+), 180 deletions(-) diff --git a/Common/Common.h b/Common/Common.h index 9894771c53..471bef4bdf 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -26,13 +26,6 @@ #pragma warning (disable:4100) #endif -// Force enable logging in the right modes. For some reason, something had changed -// so that debugfast no longer logged. -#if defined(_DEBUG) || defined(DEBUGFAST) -#undef LOGGING -#define LOGGING 1 -#endif - #include "Log.h" #include "CommonTypes.h" #include "CommonFuncs.h" diff --git a/Common/Log.h b/Common/Log.h index 8dc232319c..3bd39e5c10 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -17,16 +17,11 @@ #pragma once -#include #include #include "CommonFuncs.h" #include "Common/MsgHandler.h" -#if defined(__ANDROID__) -#include -#endif - #define NOTICE_LEVEL 1 // VERY important information that is NOT errors. Like startup and debugprintfs from the game itself. #define ERROR_LEVEL 2 // Important errors. #define WARNING_LEVEL 3 // Something is suspicious. @@ -34,7 +29,6 @@ #define DEBUG_LEVEL 5 // Detailed debugging - might make things slow. #define VERBOSE_LEVEL 6 // Noisy debugging - sometimes needed but usually unimportant. - namespace LogTypes { enum LOG_TYPE { @@ -92,15 +86,20 @@ void GenericLog(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, ; bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); -#if defined(LOGGING) || defined(_DEBUG) || defined(DEBUGFAST) || defined(_WIN32) +#if defined(_DEBUG) || defined(_WIN32) + #define MAX_LOGLEVEL DEBUG_LEVEL + #else + #ifndef MAX_LOGLEVEL #define MAX_LOGLEVEL INFO_LEVEL #endif // loglevel + #endif // logging -// Let the compiler optimize this out +// Let the compiler optimize this out. +// TODO: Compute a dynamic max level as well that can be checked here. #define GENERIC_LOG(t, v, ...) { \ if (v <= MAX_LOGLEVEL) \ GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ @@ -121,7 +120,9 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * #endif +// If we're in "debug" assert mode #if MAX_LOGLEVEL >= DEBUG_LEVEL + #define _dbg_assert_(_a_) \ if (!(_a_)) {\ printf(#_a_ "\n\nError...\n\n Line: %d\n File: %s\n\n", \ @@ -151,15 +152,13 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * #endif // __ANDROID__ -#define _dbg_update_() ; //Host_UpdateLogDisplay(); - #else // not debug -#define _dbg_update_() ; #ifndef _dbg_assert_ #define _dbg_assert_(_a_) {} #define _dbg_assert_msg_(_a_, _desc_, ...) {} #endif // dbg_assert + #endif // MAX_LOGLEVEL DEBUG #if defined(__ANDROID__) diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index b1c998b8b5..17509f6c72 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index 687070640f..47a82b63a7 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -16,7 +16,6 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include #include #include "Common/Log.h" diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 82d07cd264..1b856dcff2 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -243,7 +243,7 @@ VkImageView VulkanTexture::CreateViewForMip(int mip) { view_info.subresourceRange.layerCount = 1; VkImageView view; VkResult res = vkCreateImageView(vulkan_->GetDevice(), &view_info, NULL, &view); - assert(res == VK_SUCCESS); + _assert_(res == VK_SUCCESS); return view; } diff --git a/Common/Vulkan/VulkanMemory.h b/Common/Vulkan/VulkanMemory.h index 5c4cec8b1e..d2f41e2d12 100644 --- a/Common/Vulkan/VulkanMemory.h +++ b/Common/Vulkan/VulkanMemory.h @@ -2,6 +2,8 @@ #include #include + +#include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" // VulkanMemory @@ -73,14 +75,14 @@ public: // Returns the offset that should be used when binding this buffer to get this data. size_t Push(const void *data, size_t size, VkBuffer *vkbuf) { - assert(writePtr_); + _dbg_assert_(writePtr_); size_t off = Allocate(size, vkbuf); memcpy(writePtr_ + off, data, size); return off; } uint32_t PushAligned(const void *data, size_t size, int align, VkBuffer *vkbuf) { - assert(writePtr_); + _dbg_assert_(writePtr_); offset_ = (offset_ + align - 1) & ~(align - 1); size_t off = Allocate(size, vkbuf); memcpy(writePtr_ + off, data, size); @@ -94,13 +96,13 @@ public: // "Zero-copy" variant - you can write the data directly as you compute it. // Recommended. void *Push(size_t size, uint32_t *bindOffset, VkBuffer *vkbuf) { - assert(writePtr_); + _dbg_assert_(writePtr_); size_t off = Allocate(size, vkbuf); *bindOffset = (uint32_t)off; return writePtr_ + off; } void *PushAligned(size_t size, uint32_t *bindOffset, VkBuffer *vkbuf, int align) { - assert(writePtr_); + _dbg_assert_(writePtr_); offset_ = (offset_ + align - 1) & ~(align - 1); size_t off = Allocate(size, vkbuf); *bindOffset = (uint32_t)off; diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 131c739ce1..7ed008f886 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include "i18n/i18n.h" @@ -777,7 +776,7 @@ CheatOperation CWCheatEngine::InterpretNextCwCheat(const CheatCode &cheat, size_ CheatOperation CWCheatEngine::InterpretNextTempAR(const CheatCode &cheat, size_t &i) { // TODO - assert(false); + _assert_(false); return { CheatOp::Invalid }; } @@ -787,7 +786,7 @@ CheatOperation CWCheatEngine::InterpretNextOp(const CheatCode &cheat, size_t &i) else if (cheat.fmt == CheatCodeFormat::TEMPAR) return InterpretNextTempAR(cheat, i); else - assert(false); + _assert_(false); return { CheatOp::Invalid }; } @@ -1178,7 +1177,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, break; default: - assert(false); + _assert_(false); } } diff --git a/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp b/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp index ec9a226508..7e6d03966e 100644 --- a/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp +++ b/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp @@ -113,7 +113,7 @@ static bool StreamBufferToDataURI(DebuggerRequest &req, const GPUDebugBuffer &bu req.ws->AddFragment(false, Base64Encode(ctx->buf, ctx->bufSize)); ctx->bufSize = 0; } - assert(ctx->bufSize == 0 || length == 0); + _assert_(ctx->bufSize == 0 || length == 0); // Save bytes that would result in padding for next time. size_t toBuffer = length % 3; @@ -241,7 +241,7 @@ static void GenericStreamBuffer(DebuggerRequest &req, std::function #include #include "json/json_reader.h" diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 16206298f2..9316bae16f 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1483,7 +1483,7 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { int error; FileNode *f = __IoOpen(error, filename, flags, mode); if (!f) { - assert(error != 0); + _assert_(error != 0); if (error == (int)SCE_KERNEL_ERROR_NOCWD) { // TODO: Timing is not accurate. return hleLogError(SCEIO, hleDelayResult(error, "file opened", 10000), "no current working directory"); @@ -2063,7 +2063,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) { // We have to return an fd here, which may have been destroyed when we reach Wait if it failed. if (f == nullptr) { - assert(error != 0); + _assert_(error != 0); if (error == SCE_KERNEL_ERROR_NODEV) return hleLogError(SCEIO, error, "device not found"); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index c11bf8b2ad..e995528d02 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1529,7 +1529,7 @@ void __KernelWaitCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 time } PSPThread *thread = __GetCurrentThread(); - assert(thread != nullptr); + _assert_(thread != nullptr); thread->nt.waitID = waitID; thread->nt.waitType = type; __KernelChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->nt.status & THREADSTATUS_SUSPEND))); diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 356bd4ef90..05484bd8af 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -142,7 +142,7 @@ void PPGeSetTexture(u32 dataAddr, int width, int height); static void WriteCmd(u8 cmd, u32 data) { Memory::Write_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr); dlWritePtr += 4; - assert(dlWritePtr <= dlPtr + dlSize); + _dbg_assert_(dlWritePtr <= dlPtr + dlSize); } static void WriteCmdAddrWithBase(u8 cmd, u32 addr) { @@ -181,7 +181,7 @@ static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color Memory::WriteStruct(dataWritePtr, &vtx); dataWritePtr += sizeof(vtx); } - assert(dataWritePtr <= dataPtr + dataSize); + _dbg_assert_(dataWritePtr <= dataPtr + dataSize); vertexCount++; } @@ -420,8 +420,8 @@ void PPGeEnd() } void PPGeScissor(int x1, int y1, int x2, int y2) { - assert(x1 >= 0 && x1 <= 480 && x2 >= 0 && x2 <= 480); - assert(y1 >= 0 && y1 <= 272 && y2 >= 0 && y2 <= 272); + _dbg_assert_(x1 >= 0 && x1 <= 480 && x2 >= 0 && x2 <= 480); + _dbg_assert_(y1 >= 0 && y1 <= 272 && y2 >= 0 && y2 <= 272); WriteCmd(GE_CMD_SCISSOR1, (y1 << 10) | x1); WriteCmd(GE_CMD_SCISSOR2, ((y2 - 1) << 10) | (x2 - 1)); } diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 864cf678e6..be46d3d620 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include "ext/native/thin3d/thin3d.h" @@ -1025,8 +1024,8 @@ void FramebufferManagerCommon::DecimateFBOs() { } void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, int h, bool force, bool skipCopy) { - assert(w > 0); - assert(h > 0); + _dbg_assert_(w > 0); + _dbg_assert_(h > 0); VirtualFramebuffer old = *vfb; int oldWidth = vfb->bufferWidth; diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index a1fd204c6a..f78bc00d68 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include #include #include #include @@ -407,7 +406,7 @@ Draw::Pipeline *PresentationCommon::CreatePipeline(std::vectorCreateBuffer(sizeof(Vertex) * 8, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA); @@ -531,7 +530,7 @@ void PresentationCommon::BindSource(int binding) { } else if (srcFramebuffer_) { draw_->BindFramebufferAsTexture(srcFramebuffer_, binding, Draw::FB_COLOR_BIT, 0); } else { - assert(false); + _assert_(false); } } diff --git a/GPU/Common/TextureScalerCommon.cpp b/GPU/Common/TextureScalerCommon.cpp index 4b9bf8f307..63b972403e 100644 --- a/GPU/Common/TextureScalerCommon.cpp +++ b/GPU/Common/TextureScalerCommon.cpp @@ -21,7 +21,6 @@ #endif #include -#include #include #include #include diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 70fee76b59..538c0d46be 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index fcafb02685..50006f3505 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include "Core/MemMap.h" diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.cpp b/GPU/Vulkan/DepalettizeShaderVulkan.cpp index e1cc53fd09..f0ab47eb1c 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.cpp +++ b/GPU/Vulkan/DepalettizeShaderVulkan.cpp @@ -84,7 +84,7 @@ void DepalShaderCacheVulkan::DeviceRestore(Draw::DrawContext *draw, VulkanContex vulkan_ = vulkan; std::string errors; vshader_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, depal_vs, &errors); - assert(vshader_ != VK_NULL_HANDLE); + _assert_(vshader_ != VK_NULL_HANDLE); } DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat) { diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index b241affff0..db98dcca5c 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -15,8 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include - #include "math/dataconv.h" #include "profiler/profiler.h" #include "thin3d/VulkanRenderManager.h" @@ -142,7 +140,7 @@ void DrawEngineVulkan::InitDeviceObjects() { dsl.bindingCount = ARRAY_SIZE(bindings); dsl.pBindings = bindings; VkResult res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_); - assert(VK_SUCCESS == res); + _dbg_assert_(VK_SUCCESS == res); // We are going to use one-shot descriptors in the initial implementation. Might look into caching them // if creating and updating them turns out to be expensive. @@ -164,7 +162,7 @@ void DrawEngineVulkan::InitDeviceObjects() { pl.pSetLayouts = &descriptorSetLayout_; pl.flags = 0; res = vkCreatePipelineLayout(device, &pl, nullptr, &pipelineLayout_); - assert(VK_SUCCESS == res); + _dbg_assert_(VK_SUCCESS == res); VkSamplerCreateInfo samp{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; @@ -176,7 +174,7 @@ void DrawEngineVulkan::InitDeviceObjects() { samp.minFilter = VK_FILTER_NEAREST; res = vkCreateSampler(device, &samp, nullptr, &samplerSecondary_); res = vkCreateSampler(device, &samp, nullptr, &nullSampler_); - assert(VK_SUCCESS == res); + _dbg_assert_(VK_SUCCESS == res); vertexCache_ = new VulkanPushBuffer(vulkan_, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); @@ -407,7 +405,7 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView if (!frame.descPool || frame.descPoolSize < frame.descCount + 1) { VkResult res = RecreateDescriptorPool(frame, frame.descPoolSize * 2); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); } // Didn't find one in the frame descriptor set cache, let's make a new one. diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 5c4d0f0b51..17ad7045d0 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -107,8 +107,8 @@ void FramebufferManagerVulkan::InitDeviceObjects() { std::string fs_errors, vs_errors; fsBasicTex_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_FRAGMENT_BIT, tex_fs, &fs_errors); vsBasicTex_ = CompileShaderModule(vulkan_, VK_SHADER_STAGE_VERTEX_BIT, tex_vs, &vs_errors); - assert(fsBasicTex_ != VK_NULL_HANDLE); - assert(vsBasicTex_ != VK_NULL_HANDLE); + _assert_(fsBasicTex_ != VK_NULL_HANDLE); + _assert_(vsBasicTex_ != VK_NULL_HANDLE); VkSamplerCreateInfo samp = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; @@ -117,11 +117,11 @@ void FramebufferManagerVulkan::InitDeviceObjects() { samp.magFilter = VK_FILTER_NEAREST; samp.minFilter = VK_FILTER_NEAREST; VkResult res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &nearestSampler_); - assert(res == VK_SUCCESS); + _assert_(res == VK_SUCCESS); samp.magFilter = VK_FILTER_LINEAR; samp.minFilter = VK_FILTER_LINEAR; res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &linearSampler_); - assert(res == VK_SUCCESS); + _assert_(res == VK_SUCCESS); } void FramebufferManagerVulkan::DestroyDeviceObjects() { diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 93488cfc55..97b1f82ecc 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -474,7 +474,7 @@ void GPU_Vulkan::InitDeviceObjects() { INFO_LOG(G3D, "GPU_Vulkan::InitDeviceObjects"); // Initialize framedata for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { - assert(!frameData_[i].push_); + _assert_(!frameData_[i].push_); 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); } diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 9986f1a523..520ea6305b 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -77,8 +77,8 @@ static const DeclTypeInfo VComp[] = { }; static void VertexAttribSetup(VkVertexInputAttributeDescription *attr, int fmt, int offset, PspAttributeLocation location) { - assert(fmt != DEC_NONE); - assert(fmt < ARRAY_SIZE(VComp)); + _assert_(fmt != DEC_NONE); + _assert_(fmt < ARRAY_SIZE(VComp)); attr->location = (uint32_t)location; attr->binding = 0; attr->format = VComp[fmt].type; @@ -332,7 +332,7 @@ VulkanPipeline *PipelineManagerVulkan::GetOrCreatePipeline(VkPipelineLayout layo if (!pipelineCache_) { VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); } VulkanPipelineKey key{}; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 202c8a839c..d0fc324a25 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -254,7 +254,7 @@ VkSampler SamplerCache::GetOrCreateSampler(const SamplerCacheKey &key) { samp.mipLodBias = (float)(int32_t)key.lodBias * (1.0f / 256.0f); VkResult res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &sampler); - assert(res == VK_SUCCESS); + _assert_(res == VK_SUCCESS); cache_.Insert(key, sampler); return sampler; } @@ -351,7 +351,7 @@ void TextureCacheVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext vulkan_ = vulkan; draw_ = draw; - assert(!allocator_); + _assert_(!allocator_); allocator_ = new VulkanDeviceAllocator(vulkan_, TEXCACHE_MIN_SLAB_SIZE, TEXCACHE_MAX_SLAB_SIZE); samplerCache_.DeviceRestore(vulkan); @@ -1124,7 +1124,7 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePt dstFmt = (VkFormat)fmt; // We always end up at 8888. Other parts assume this. - assert(dstFmt == VULKAN_8888_FORMAT); + _assert_(dstFmt == VULKAN_8888_FORMAT); bpp = sizeof(u32); decPitch = w * bpp; diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index 0e653be2b1..9a617645d1 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -65,7 +65,7 @@ void Vulkan2D::DestroyDeviceObjects() { void Vulkan2D::InitDeviceObjects() { VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); VkDescriptorSetLayoutBinding bindings[2] = {}; // Texture. @@ -85,7 +85,7 @@ void Vulkan2D::InitDeviceObjects() { dsl.bindingCount = 2; dsl.pBindings = bindings; res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); VkDescriptorPoolSize dpTypes[1]; dpTypes[0].descriptorCount = 3000; @@ -98,7 +98,7 @@ void Vulkan2D::InitDeviceObjects() { dp.poolSizeCount = ARRAY_SIZE(dpTypes); for (int i = 0; i < vulkan_->GetInflightFrames(); i++) { VkResult res = vkCreateDescriptorPool(vulkan_->GetDevice(), &dp, nullptr, &frameData_[i].descPool); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); } VkPushConstantRange push = {}; @@ -113,7 +113,7 @@ void Vulkan2D::InitDeviceObjects() { pl.pSetLayouts = &descriptorSetLayout_; pl.flags = 0; res = vkCreatePipelineLayout(device, &pl, nullptr, &pipelineLayout_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); } void Vulkan2D::DeviceLost() { @@ -188,7 +188,7 @@ VkDescriptorSet Vulkan2D::GetDescriptorSet(VkImageView tex1, VkSampler sampler1, descAlloc.descriptorPool = frame->descPool; descAlloc.descriptorSetCount = 1; VkResult result = vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc); - assert(result == VK_SUCCESS); + _assert_(result == VK_SUCCESS); // We just don't write to the slots we don't care about. VkWriteDescriptorSet writes[2]{}; @@ -406,7 +406,7 @@ VulkanComputeShaderManager::~VulkanComputeShaderManager() {} void VulkanComputeShaderManager::InitDeviceObjects() { VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; VkResult res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); VkDescriptorSetLayoutBinding bindings[3] = {}; bindings[0].descriptorCount = 1; @@ -428,7 +428,7 @@ void VulkanComputeShaderManager::InitDeviceObjects() { dsl.bindingCount = ARRAY_SIZE(bindings); dsl.pBindings = bindings; res = vkCreateDescriptorSetLayout(device, &dsl, nullptr, &descriptorSetLayout_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); VkDescriptorPoolSize dpTypes[2]; dpTypes[0].descriptorCount = 8192; @@ -443,7 +443,7 @@ void VulkanComputeShaderManager::InitDeviceObjects() { dp.poolSizeCount = ARRAY_SIZE(dpTypes); for (int i = 0; i < ARRAY_SIZE(frameData_); i++) { VkResult res = vkCreateDescriptorPool(vulkan_->GetDevice(), &dp, nullptr, &frameData_[i].descPool); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); } VkPushConstantRange push = {}; @@ -458,7 +458,7 @@ void VulkanComputeShaderManager::InitDeviceObjects() { pl.pSetLayouts = &descriptorSetLayout_; pl.flags = 0; res = vkCreatePipelineLayout(device, &pl, nullptr, &pipelineLayout_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); } void VulkanComputeShaderManager::DestroyDeviceObjects() { @@ -491,7 +491,7 @@ VkDescriptorSet VulkanComputeShaderManager::GetDescriptorSet(VkImageView image, descAlloc.descriptorPool = frameData.descPool; descAlloc.descriptorSetCount = 1; VkResult result = vkAllocateDescriptorSets(vulkan_->GetDevice(), &descAlloc, &desc); - assert(result == VK_SUCCESS); + _assert_(result == VK_SUCCESS); VkWriteDescriptorSet writes[2]{}; int n = 0; diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index e99c15ed75..b5650590b7 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -412,7 +412,7 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std: renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); SetGPUBackend(GPUBackend::OPENGL); bool success = draw_->CreatePresets(); - assert(success); + _assert_(success); renderManager_->SetSwapFunction([&]() { #ifdef USING_EGL if (useEGLSwap) diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 878d2da2ce..119ea7419b 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -16,7 +16,6 @@ SDLJoystick *joystick = NULL; #include #include -#include #include #include #include diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 06f253c6d5..76361240ce 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -117,7 +117,7 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, draw_ = Draw::T3DCreateVulkanContext(vulkan_, false); SetGPUBackend(GPUBackend::VULKAN); bool success = draw_->CreatePresets(); - assert(success); + _assert_(success); draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight()); renderManager_ = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); diff --git a/UI/DiscordIntegration.cpp b/UI/DiscordIntegration.cpp index b872b21e01..ccc2a16e7a 100644 --- a/UI/DiscordIntegration.cpp +++ b/UI/DiscordIntegration.cpp @@ -1,6 +1,5 @@ #include -#include #include "ppsspp_config.h" #include "Common/Log.h" @@ -50,8 +49,8 @@ bool Discord::IsEnabled() const { } void Discord::Init() { - assert(IsEnabled()); - assert(!initialized_); + _assert_(IsEnabled()); + _assert_(!initialized_); #ifdef ENABLE_DISCORD DiscordEventHandlers eventHandlers{}; diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 373f164eaf..0b9d191aa0 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -1,7 +1,6 @@ #include "pch.h" #include "PPSSPP_UWPMain.h" -#include #include #include "base/basictypes.h" @@ -324,7 +323,7 @@ UWPGraphicsContext::UWPGraphicsContext(std::shared_ptr reso draw_ = Draw::T3DCreateD3D11Context( resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetDeviceFeatureLevel(), 0, adapterNames); bool success = draw_->CreatePresets(); - assert(success); + _assert_(success); } void UWPGraphicsContext::Shutdown() { diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 112f854ab1..d519dffa7c 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -238,7 +238,6 @@ void CDisasm::stepInto() Sleep(1); } - _dbg_update_(); ptr->gotoPC(); UpdateDialog(); vfpudlg->Update(); @@ -292,7 +291,6 @@ void CDisasm::stepOver() SetDebugMode(false, true); CBreakPoints::AddBreakPoint(breakpointAddress,true); - _dbg_update_(); Core_EnableStepping(false); Sleep(1); ptr->gotoAddr(breakpointAddress); @@ -331,7 +329,6 @@ void CDisasm::stepOut() SetDebugMode(false, true); CBreakPoints::AddBreakPoint(breakpointAddress,true); - _dbg_update_(); Core_EnableStepping(false); Sleep(1); ptr->gotoAddr(breakpointAddress); @@ -351,7 +348,6 @@ void CDisasm::runToLine() ptr->setDontRedraw(true); SetDebugMode(false, true); CBreakPoints::AddBreakPoint(pos,true); - _dbg_update_(); Core_EnableStepping(false); } @@ -533,7 +529,6 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) ptr->setDontRedraw(false); SetDebugMode(true, true); Core_EnableStepping(true); - _dbg_update_(); Sleep(1); //let cpu catch up ptr->gotoPC(); UpdateDialog(); @@ -573,7 +568,6 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) hleDebugBreak(); SetDebugMode(false, true); - _dbg_update_(); Core_EnableStepping(false); } break; diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 2e314b0f14..32af670d4a 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -230,7 +230,6 @@ void MainThreadFunc() { } INFO_LOG(BOOT, "Done."); - _dbg_update_(); if (coreState == CORE_POWERDOWN) { INFO_LOG(BOOT, "Exit before core loop."); diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 19fdd64dd1..7ed3969444 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -3,7 +3,6 @@ #include "Common/CommonWindows.h" #include #include -#include #include "Common/Log.h" #include "base/display.h" diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index 9646cf25e9..dc9037a783 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include #include "Common/Log.h" #include "Common/CommonWindows.h" #include "gfx/gl_common.h" diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index c74fa27024..7b10b5e7c8 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -46,7 +46,6 @@ // and use the same render pass configuration (clear to black). However, we can later change this so we switch // to a non-clearing render pass in buffered mode, which might be a tiny bit faster. -#include #include #include diff --git a/Windows/WASAPIStream.cpp b/Windows/WASAPIStream.cpp index 9662bf2891..17be143334 100644 --- a/Windows/WASAPIStream.cpp +++ b/Windows/WASAPIStream.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" + #include "WindowsAudio.h" #include "WASAPIStream.h" #include "Common/Log.h" @@ -234,12 +235,12 @@ WASAPIAudioThread::~WASAPIAudioThread() { } bool WASAPIAudioThread::ActivateDefaultDevice() { - assert(device_ == nullptr); + _assert_(device_ == nullptr); HRESULT hresult = deviceEnumerator_->GetDefaultAudioEndpoint(eRender, eMultimedia, &device_); if (FAILED(hresult) || device_ == nullptr) return false; - assert(audioInterface_ == nullptr); + _assert_(audioInterface_ == nullptr); hresult = device_->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, (void **)&audioInterface_); if (FAILED(hresult) || audioInterface_ == nullptr) return false; @@ -249,7 +250,7 @@ bool WASAPIAudioThread::ActivateDefaultDevice() { bool WASAPIAudioThread::InitAudioDevice() { REFERENCE_TIME hnsBufferDuration = REFTIMES_PER_SEC; - assert(deviceFormat_ == nullptr); + _assert_(deviceFormat_ == nullptr); HRESULT hresult = audioInterface_->GetMixFormat((WAVEFORMATEX **)&deviceFormat_); if (FAILED(hresult) || !deviceFormat_) return false; @@ -262,7 +263,7 @@ bool WASAPIAudioThread::InitAudioDevice() { hresult = audioInterface_->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, hnsBufferDuration, 0, &deviceFormat_->Format, nullptr); if (FAILED(hresult)) return false; - assert(renderClient_ == nullptr); + _assert_(renderClient_ == nullptr); hresult = audioInterface_->GetService(IID_IAudioRenderClient, (void **)&renderClient_); if (FAILED(hresult) || !renderClient_) return false; @@ -389,7 +390,7 @@ bool WASAPIAudioThread::PrepareFormat() { void WASAPIAudioThread::Run() { // Adapted from http://msdn.microsoft.com/en-us/library/windows/desktop/dd316756(v=vs.85).aspx - assert(deviceEnumerator_ == nullptr); + _assert_(deviceEnumerator_ == nullptr); HRESULT hresult = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, /* Object is not created as the part of the aggregate */ CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&deviceEnumerator_); diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index 97b4ecd55a..c84a79db01 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -1,5 +1,3 @@ -#include - #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "thin3d/thin3d_create.h" diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index 36a2259f43..ffd5564494 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -1,5 +1,3 @@ -#include - #include "AndroidJavaGLContext.h" #include "base/display.h" #include "base/NativeApp.h" diff --git a/android/jni/AndroidJavaGLContext.h b/android/jni/AndroidJavaGLContext.h index 05d3966896..9e4b07dd1b 100644 --- a/android/jni/AndroidJavaGLContext.h +++ b/android/jni/AndroidJavaGLContext.h @@ -29,6 +29,7 @@ public: void SwapBuffers() override {} void SwapInterval(int interval) override {} void Resize() override {} + Draw::DrawContext *GetDrawContext() override { return draw_; } diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index b61ad99b84..c3d490e3b1 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -1,5 +1,3 @@ -#include - #include "AndroidVulkanContext.h" #include "base/NativeApp.h" #include "base/display.h" diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index 91298f6de4..34e4295bd3 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -192,7 +192,7 @@ void TextDrawerAndroid::DrawStringBitmap(std::vector &bitmapData, TextS entry.lastUsedFrame = frameCount_; jint *jimage = env->GetIntArrayElements(imageData, nullptr); - assert(env->GetArrayLength(imageData) == imageWidth * imageHeight); + _assert_(env->GetArrayLength(imageData) == imageWidth * imageHeight); if (texFormat == Draw::DataFormat::B4G4R4A4_UNORM_PACK16 || texFormat == Draw::DataFormat::R4G4B4A4_UNORM_PACK16) { bitmapData.resize(entry.bmWidth * entry.bmHeight * sizeof(uint16_t)); uint16_t *bitmapData16 = (uint16_t *)&bitmapData[0]; @@ -213,8 +213,7 @@ void TextDrawerAndroid::DrawStringBitmap(std::vector &bitmapData, TextS } } } else { - ERROR_LOG(G3D, "Bad TextDrawer format"); - assert(false); + _assert_msg_(false, "Bad TextDrawer format"); } env->ReleaseIntArrayElements(imageData, jimage, 0); env->DeleteLocalRef(imageData); diff --git a/ext/native/net/websocket_server.cpp b/ext/native/net/websocket_server.cpp index dc9b361884..c45b266222 100644 --- a/ext/native/net/websocket_server.cpp +++ b/ext/native/net/websocket_server.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -15,13 +14,15 @@ #include #include #endif + #include "base/stringutil.h" #include "data/base64.h" #include "net/http_server.h" #include "net/sinks.h" #include "net/websocket_server.h" -// TODO: Not a great cross dependency. + #include "Common/Crypto/sha1.h" +#include "Common/Log.h" static const char *const WEBSOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; @@ -125,28 +126,28 @@ WebSocketServer *WebSocketServer::CreateAsUpgrade(const http::Request &request, } void WebSocketServer::Send(const std::string &str) { - assert(open_); - assert(fragmentOpcode_ == -1); + _assert_(open_); + _assert_(fragmentOpcode_ == -1); SendHeader(true, (int)Opcode::TEXT, str.size()); SendBytes(str.c_str(), str.size()); } void WebSocketServer::Send(const std::vector &payload) { - assert(open_); - assert(fragmentOpcode_ == -1); + _assert_(open_); + _assert_(fragmentOpcode_ == -1); SendHeader(true, (int)Opcode::BINARY, payload.size()); SendBytes((const char *)&payload[0], payload.size()); } void WebSocketServer::AddFragment(bool finish, const std::string &str) { - assert(open_); + _assert_(open_); if (fragmentOpcode_ == -1) { SendHeader(finish, (int)Opcode::TEXT, str.size()); fragmentOpcode_ = (int)Opcode::TEXT; } else if (fragmentOpcode_ == (int)Opcode::TEXT) { SendHeader(finish, (int)Opcode::CONTINUE, str.size()); } else { - assert(fragmentOpcode_ == (int)Opcode::TEXT || fragmentOpcode_ == -1); + _assert_(fragmentOpcode_ == (int)Opcode::TEXT || fragmentOpcode_ == -1); } SendBytes(str.c_str(), str.size()); if (finish) { @@ -155,14 +156,14 @@ void WebSocketServer::AddFragment(bool finish, const std::string &str) { } void WebSocketServer::AddFragment(bool finish, const std::vector &payload) { - assert(open_); + _assert_(open_); if (fragmentOpcode_ == -1) { SendHeader(finish, (int)Opcode::BINARY, payload.size()); fragmentOpcode_ = (int)Opcode::BINARY; } else if (fragmentOpcode_ == (int)Opcode::BINARY) { SendHeader(finish, (int)Opcode::CONTINUE, payload.size()); } else { - assert(fragmentOpcode_ == (int)Opcode::BINARY || fragmentOpcode_ == -1); + _assert_(fragmentOpcode_ == (int)Opcode::BINARY || fragmentOpcode_ == -1); } SendBytes((const char *)&payload[0], payload.size()); if (finish) { @@ -171,15 +172,15 @@ void WebSocketServer::AddFragment(bool finish, const std::vector &paylo } void WebSocketServer::Ping(const std::vector &payload) { - assert(open_); - assert(payload.size() <= 125); + _assert_(open_); + _assert_(payload.size() <= 125); SendHeader(true, (int)Opcode::PING, payload.size()); SendBytes((const char *)&payload[0], payload.size()); } void WebSocketServer::Pong(const std::vector &payload) { - assert(open_); - assert(payload.size() <= 125); + _assert_(open_); + _assert_(payload.size() <= 125); SendHeader(true, (int)Opcode::PONG, payload.size()); SendBytes((const char *)&payload[0], payload.size()); } @@ -275,7 +276,7 @@ bool WebSocketServer::ReadFrames() { } bool WebSocketServer::ReadFrame() { - assert(pendingLeft_ == 0); + _assert_(pendingLeft_ == 0); // TODO: For now blocking on header trickle, shouldn't be common. auto readExact = [&](void *p, size_t sz) { @@ -408,7 +409,7 @@ bool WebSocketServer::ReadPending() { binary_(pendingBuf_); } } else { - assert(false); + _assert_(false); } // All done, clear it out. @@ -455,14 +456,14 @@ bool WebSocketServer::ReadControlFrame(int opcode, size_t sz) { // Don't read anything more. return false; } else { - assert(false); + _assert_(false); } return true; } void WebSocketServer::SendHeader(bool fin, int opcode, size_t sz) { - assert((opcode & 0x0F) == opcode); + _assert_((opcode & 0x0F) == opcode); uint8_t frameHeader = (fin ? 0x80 : 0x00) | opcode; SendBytes(&frameHeader, 1); @@ -479,7 +480,7 @@ void WebSocketServer::SendHeader(bool fin, int opcode, size_t sz) { SendBytes(frameSize, sizeof(frameSize)); } else { uint64_t sz64 = sz; - assert((sz64 & 0x8000000000000000ULL) == 0); + _assert_((sz64 & 0x8000000000000000ULL) == 0); uint8_t frameSize[] = { 127, (uint8_t)((sz64 >> 56) & 0xFF), diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 49698384bd..9c380ee622 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -248,7 +248,7 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski // Query all the uniforms. for (size_t j = 0; j < program->queries_.size(); j++) { auto &x = program->queries_[j]; - assert(x.name); + _dbg_assert_(x.name); *x.dest = glGetUniformLocation(program->program, x.name); } @@ -984,7 +984,7 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last } case GLRRenderCommand::UNIFORM4I: { - assert(curProgram); + _dbg_assert_(curProgram); int loc = c.uniform4.loc ? *c.uniform4.loc : -1; if (c.uniform4.name) { loc = curProgram->GetUniformLoc(c.uniform4.name); @@ -1010,7 +1010,7 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last } case GLRRenderCommand::UNIFORMMATRIX: { - assert(curProgram); + _dbg_assert_(curProgram); int loc = c.uniformMatrix4.loc ? *c.uniformMatrix4.loc : -1; if (c.uniformMatrix4.name) { loc = curProgram->GetUniformLoc(c.uniformMatrix4.name); @@ -1076,7 +1076,7 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last // TODO: Add fast path for glBindVertexBuffer GLRInputLayout *layout = c.bindVertexBuffer.inputLayout; GLuint buf = c.bindVertexBuffer.buffer ? c.bindVertexBuffer.buffer->buffer_ : 0; - assert(!c.bindVertexBuffer.buffer->Mapped()); + _dbg_assert_(!c.bindVertexBuffer.buffer->Mapped()); if (buf != curArrayBuffer) { glBindBuffer(GL_ARRAY_BUFFER, buf); curArrayBuffer = buf; @@ -1105,14 +1105,14 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last Crash(); } else if (c.bind_buffer.target == GL_ELEMENT_ARRAY_BUFFER) { GLuint buf = c.bind_buffer.buffer ? c.bind_buffer.buffer->buffer_ : 0; - assert(!c.bind_buffer.buffer->Mapped()); + _dbg_assert_(!c.bind_buffer.buffer->Mapped()); if (buf != curElemArrayBuffer) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf); curElemArrayBuffer = buf; } } else { GLuint buf = c.bind_buffer.buffer ? c.bind_buffer.buffer->buffer_ : 0; - assert(!c.bind_buffer.buffer->Mapped()); + _dbg_assert_(!c.bind_buffer.buffer->Mapped()); glBindBuffer(c.bind_buffer.target, buf); } CHECK_GL_ERROR_IF_DEBUG(); diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 19a3ac0053..bc2e9a9a3c 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -1,5 +1,3 @@ -#include - #include "GLRenderManager.h" #include "gfx_es2/gpu_features.h" #include "thin3d/thin3d.h" @@ -213,7 +211,7 @@ bool GLRenderManager::ThreadFrame() { // Only increment next time if we're done. nextFrame = frameData.type == GLRRunType::END; - assert(frameData.type == GLRRunType::END || frameData.type == GLRRunType::SYNC); + _assert_(frameData.type == GLRRunType::END || frameData.type == GLRRunType::SYNC); } VLOG("PULL: Running frame %d", threadFrame_); if (firstFrame) { @@ -279,7 +277,7 @@ void GLRenderManager::StopThread() { } void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag) { - assert(insideFrame_); + _assert_(insideFrame_); #ifdef _DEBUG curProgram_ = nullptr; #endif @@ -509,7 +507,7 @@ void GLRenderManager::Submit(int frame, bool triggerFence) { VLOG("PULL: Frame %d.readyForFence = true", frame); std::unique_lock lock(frameData.push_mutex); - assert(frameData.readyForSubmit); + _assert_(frameData.readyForSubmit); frameData.readyForFence = true; frameData.readyForSubmit = false; frameData.push_condVar.notify_all(); @@ -577,7 +575,7 @@ void GLRenderManager::Run(int frame) { break; default: - assert(false); + _assert_(false); } VLOG("PULL: Finished running frame %d", frame); @@ -597,7 +595,7 @@ void GLRenderManager::FlushSync() { frameData.steps = std::move(steps_); steps_.clear(); frameData.readyForRun = true; - assert(frameData.readyForFence == false); + _assert_(frameData.readyForFence == false); frameData.type = GLRRunType::SYNC; frameData.pull_condVar.notify_all(); } @@ -666,7 +664,7 @@ GLPushBuffer::~GLPushBuffer() { } void GLPushBuffer::Map() { - assert(!writePtr_); + _assert_(!writePtr_); auto &info = buffers_[buf_]; writePtr_ = info.deviceMemory ? info.deviceMemory : info.localMemory; info.flushOffset = 0; @@ -676,11 +674,11 @@ void GLPushBuffer::Map() { offset_++; info.flushOffset++; } - assert(writePtr_); + _assert_(writePtr_); } void GLPushBuffer::Unmap() { - assert(writePtr_); + _assert_(writePtr_); if (!buffers_[buf_].deviceMemory) { // Here we simply upload the data to the last buffer. // Might be worth trying with size_ instead of offset_, so the driver can replace @@ -700,7 +698,7 @@ void GLPushBuffer::Flush() { if (!buffers_[buf_].deviceMemory && writePtr_) { auto &info = buffers_[buf_]; if (info.flushOffset != 0) { - assert(info.buffer->buffer_); + _assert_(info.buffer->buffer_); glBindBuffer(target_, info.buffer->buffer_); glBufferSubData(target_, 0, info.flushOffset, info.localMemory); } @@ -766,7 +764,7 @@ void GLPushBuffer::NextBuffer(size_t minSize) { } bool res = AddBuffer(); - assert(res); + _assert_(res); if (!res) { // Let's try not to crash at least? buf_ = 0; @@ -857,7 +855,7 @@ void GLPushBuffer::UnmapDevice() { } void *GLRBuffer::Map(GLBufferStrategy strategy) { - assert(buffer_ != 0); + _assert_(buffer_ != 0); GLbitfield access = GL_MAP_WRITE_BIT; if ((strategy & GLBufferStrategy::MASK_FLUSH) != 0) { diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 4756b4bd09..1ba685ee70 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -74,7 +74,7 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int ivci.subresourceRange.layerCount = 1; ivci.subresourceRange.levelCount = 1; res = vkCreateImageView(vulkan->GetDevice(), &ivci, nullptr, &img.imageView); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); VkPipelineStageFlags dstStage; VkAccessFlagBits dstAccessMask; @@ -109,9 +109,9 @@ VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan VkSemaphoreCreateInfo semaphoreCreateInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; semaphoreCreateInfo.flags = 0; VkResult res = vkCreateSemaphore(vulkan_->GetDevice(), &semaphoreCreateInfo, nullptr, &acquireSemaphore_); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); res = vkCreateSemaphore(vulkan_->GetDevice(), &semaphoreCreateInfo, nullptr, &renderingCompleteSemaphore_); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); inflightFramesAtStart_ = vulkan_->GetInflightFrames(); for (int i = 0; i < inflightFramesAtStart_; i++) { @@ -119,9 +119,9 @@ VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan cmd_pool_info.queueFamilyIndex = vulkan_->GetGraphicsQueueFamilyIndex(); cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; VkResult res = vkCreateCommandPool(vulkan_->GetDevice(), &cmd_pool_info, nullptr, &frameData_[i].cmdPoolInit); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); res = vkCreateCommandPool(vulkan_->GetDevice(), &cmd_pool_info, nullptr, &frameData_[i].cmdPoolMain); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); VkCommandBufferAllocateInfo cmd_alloc = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; cmd_alloc.commandPool = frameData_[i].cmdPoolInit; @@ -129,10 +129,10 @@ VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan cmd_alloc.commandBufferCount = 1; res = vkAllocateCommandBuffers(vulkan_->GetDevice(), &cmd_alloc, &frameData_[i].initCmd); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); cmd_alloc.commandPool = frameData_[i].cmdPoolMain; res = vkAllocateCommandBuffers(vulkan_->GetDevice(), &cmd_alloc, &frameData_[i].mainCmd); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); // Creating the frame fence with true so they can be instantly waited on the first frame frameData_[i].fence = vulkan_->CreateFence(true); @@ -156,7 +156,7 @@ VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan void VulkanRenderManager::CreateBackbuffers() { VkResult res = vkGetSwapchainImagesKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), &swapchainImageCount_, nullptr); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); VkImage *swapchainImages = new VkImage[swapchainImageCount_]; res = vkGetSwapchainImagesKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), &swapchainImageCount_, swapchainImages); @@ -193,7 +193,7 @@ void VulkanRenderManager::CreateBackbuffers() { res = vkCreateImageView(vulkan_->GetDevice(), &color_image_view, nullptr, &sc_buffer.view); swapchainImages_.push_back(sc_buffer); - assert(res == VK_SUCCESS); + _dbg_assert_(res == VK_SUCCESS); } delete[] swapchainImages; @@ -289,7 +289,7 @@ void VulkanRenderManager::DestroyBackbuffers() { vulkan_->Delete().QueueDeleteImage(depth_.image); vulkan_->Delete().QueueDeleteDeviceMemory(depth_.mem); for (uint32_t i = 0; i < framebuffers_.size(); i++) { - assert(framebuffers_[i] != VK_NULL_HANDLE); + _dbg_assert_(framebuffers_[i] != VK_NULL_HANDLE); vulkan_->Delete().QueueDeleteFramebuffer(framebuffers_[i]); } framebuffers_.clear(); @@ -347,7 +347,7 @@ void VulkanRenderManager::ThreadFunc() { // Only increment next time if we're done. nextFrame = frameData.type == VKRRunType::END; - assert(frameData.type == VKRRunType::END || frameData.type == VKRRunType::SYNC); + _dbg_assert_(frameData.type == VKRRunType::END || frameData.type == VKRRunType::SYNC); } VLOG("PULL: Running frame %d", threadFrame); if (firstFrame) { @@ -511,7 +511,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR // More redundant bind elimination. if (curRenderStep_ && curRenderStep_->commands.size() == 0 && curRenderStep_->render.color != VKRRenderPassAction::CLEAR && curRenderStep_->render.depth != VKRRenderPassAction::CLEAR && curRenderStep_->render.stencil != VKRRenderPassAction::CLEAR) { // Can trivially kill the last empty render step. - assert(steps_.back() == curRenderStep_); + _dbg_assert_(steps_.back() == curRenderStep_); delete steps_.back(); steps_.pop_back(); curRenderStep_ = nullptr; diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index c1607354f4..f5ff60e3ad 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -192,7 +192,7 @@ public: void PushConstants(VkPipelineLayout pipelineLayout, VkShaderStageFlags stages, int offset, int size, void *constants) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); - assert(size + offset < 40); + _dbg_assert_(size + offset < 40); VkRenderData data{ VKRRenderCommand::PUSH_CONSTANTS }; data.push.pipelineLayout = pipelineLayout; data.push.stages = stages; @@ -214,7 +214,7 @@ public: data.draw.vbuffer = vbuffer; data.draw.voffset = voffset; data.draw.numUboOffsets = numUboOffsets; - assert(numUboOffsets <= ARRAY_SIZE(data.draw.uboOffsets)); + _dbg_assert_(numUboOffsets <= ARRAY_SIZE(data.draw.uboOffsets)); for (int i = 0; i < numUboOffsets; i++) data.draw.uboOffsets[i] = uboOffsets[i]; curRenderStep_->commands.push_back(data); @@ -233,7 +233,7 @@ public: data.drawIndexed.ibuffer = ibuffer; data.drawIndexed.ioffset = ioffset; data.drawIndexed.numUboOffsets = numUboOffsets; - assert(numUboOffsets <= ARRAY_SIZE(data.drawIndexed.uboOffsets)); + _dbg_assert_(numUboOffsets <= ARRAY_SIZE(data.drawIndexed.uboOffsets)); for (int i = 0; i < numUboOffsets; i++) data.drawIndexed.uboOffsets[i] = uboOffsets[i]; data.drawIndexed.indexType = indexType; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 9c371678e0..1f589e3856 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -12,7 +12,6 @@ #include "Common/ColorConv.h" -#include #include #include #include @@ -288,7 +287,7 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de packDesc.SampleDesc.Count = 1; packDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; hr = device_->CreateTexture2D(&packDesc, nullptr, &packTexture_); - assert(SUCCEEDED(hr)); + _assert_(SUCCEEDED(hr)); } D3D11DrawContext::~D3D11DrawContext() { @@ -1420,7 +1419,7 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel D3D11Framebuffer *fb = (D3D11Framebuffer *)src; if (fb) { - assert(fb->colorFormat == DXGI_FORMAT_R8G8B8A8_UNORM); + _assert_(fb->colorFormat == DXGI_FORMAT_R8G8B8A8_UNORM); // TODO: Figure out where the badness really comes from. if (bx + bw > fb->width) { @@ -1461,7 +1460,7 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel packDesc.Format = fb->depthStencilFormat; break; default: - assert(false); + _assert_(false); } device_->CreateTexture2D(&packDesc, nullptr, &packTex); } else { @@ -1484,11 +1483,11 @@ bool D3D11DrawContext::CopyFramebufferToMemorySync(Framebuffer *src, int channel case FB_DEPTH_BIT: case FB_STENCIL_BIT: // For depth/stencil buffers, we can't reliably copy subrectangles, so just copy the whole resource. - assert(fb); // Can't copy depth/stencil from backbuffer. Shouldn't happen thanks to checks above. + _assert_(fb); // Can't copy depth/stencil from backbuffer. Shouldn't happen thanks to checks above. context_->CopyResource(packTex, fb->depthStencilTex); break; default: - assert(false); + _assert_(false); break; } diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index f6c4dc18b9..d31620e655 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include "base/display.h" #include "base/stringutil.h" @@ -858,7 +857,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) dsl.bindingCount = ARRAY_SIZE(bindings); dsl.pBindings = bindings; VkResult res = vkCreateDescriptorSetLayout(device_, &dsl, nullptr, &descriptorSetLayout_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); VkPipelineLayoutCreateInfo pl = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; pl.pPushConstantRanges = nullptr; @@ -866,11 +865,11 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) pl.setLayoutCount = 1; pl.pSetLayouts = &descriptorSetLayout_; res = vkCreatePipelineLayout(device_, &pl, nullptr, &pipelineLayout_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); VkPipelineCacheCreateInfo pc{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; res = vkCreatePipelineCache(vulkan_->GetDevice(), &pc, nullptr, &pipelineCache_); - assert(VK_SUCCESS == res); + _assert_(VK_SUCCESS == res); renderManager_.SetSplitSubmit(splitSubmit); @@ -1580,7 +1579,7 @@ void VKContext::HandleEvent(Event ev, int width, int height, void *param1, void renderManager_.CreateBackbuffers(); break; default: - assert(false); + _assert_(false); break; } } diff --git a/ext/native/thin3d/vulkan_utils.cpp b/ext/native/thin3d/vulkan_utils.cpp index ec46b011a9..80f7086c7f 100644 --- a/ext/native/thin3d/vulkan_utils.cpp +++ b/ext/native/thin3d/vulkan_utils.cpp @@ -65,7 +65,7 @@ void VulkanImage::Create2D(VulkanContext *vulkan, VkFormat format, VkFlags requi VkMemoryRequirements mem_reqs; VkResult err = vkCreateImage(device, &i, nullptr, &image_); - assert(!err); + _assert_(!err); vkGetImageMemoryRequirements(device, image_, &mem_reqs); @@ -75,13 +75,13 @@ void VulkanImage::Create2D(VulkanContext *vulkan, VkFormat format, VkFlags requi mem_alloc_.memoryTypeIndex = 0; bool res = vulkan->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, required_props, &mem_alloc_.memoryTypeIndex); - assert(res); + _assert_(res); err = vkAllocateMemory(device, &mem_alloc_, nullptr, &memory_); - assert(!err); + _assert_(!err); err = vkBindImageMemory(device, image_, memory_, 0); // at offset 0. - assert(!err); + _assert_(!err); } void VulkanImage::SetImageData2D(VkDevice device, const uint8_t *data, int width, int height, int pitch) { @@ -95,7 +95,7 @@ void VulkanImage::SetImageData2D(VkDevice device, const uint8_t *data, int width vkGetImageSubresourceLayout(device, image_, &subres, &layout); VkResult err = vkMapMemory(device, memory_, 0, mem_alloc_.allocationSize, 0, &destData); - assert(!err); + _assert_(!err); uint8_t *writePtr = (uint8_t *)destData + layout.offset; int bpp = 4; // TODO diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index 75b39e9c78..56e6ddc9d2 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -17,9 +17,8 @@ #ifdef SDL -#include +#include #include -#include #include "headless/SDLHeadlessHost.h" #include "gfx/gl_common.h" @@ -29,6 +28,7 @@ #include "thin3d/thin3d_create.h" #include "thin3d/GLRenderManager.h" +#include "Common/Log.h" #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" #include "Common/TimeUtil.h" @@ -156,7 +156,7 @@ bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) { renderManager_->SetInflightFrames(g_Config.iInflightFrames); SetGPUBackend(GPUBackend::OPENGL); bool success = draw_->CreatePresets(); - assert(success); + _assert_(success); renderManager_->SetSwapFunction([&]() { SDL_GL_SwapWindow(screen_); }); From 449f80b74feade4a88d0503c3784cd551ccb0bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 10:15:17 +0200 Subject: [PATCH 519/848] Address feedback. --- Common/Vulkan/VulkanMemory.cpp | 12 ++++++------ Common/Vulkan/VulkanMemory.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index ab5660b389..6698c73e2a 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -278,7 +278,7 @@ bool VulkanDeviceAllocator::AllocateFromSlab(Slab &slab, size_t &start, size_t b // Remember the size so we can free. slab.allocSizes[start] = blocks; - slab.tags[start] = { tag, (float)time_now_d(), 0.0f }; + slab.tags[start] = { tag, time_now_d(), 0.0 }; slab.totalUsage += blocks; return true; } @@ -436,15 +436,15 @@ bool VulkanDeviceAllocator::AllocateSlab(VkDeviceSize minBytes, int memoryTypeIn } void VulkanDeviceAllocator::ReportOldUsage() { - float now = time_now_d(); - static const float OLD_AGE = 10.0f; + double now = time_now_d(); + static const double OLD_AGE = 10.0; for (size_t i = 0; i < slabs_.size(); ++i) { const auto &slab = slabs_[i]; bool hasOldAllocs = false; for (auto it : slab.tags) { const auto info = it.second; - float touchedAge = now - info.touched; + double touchedAge = now - info.touched; if (touchedAge >= OLD_AGE) { hasOldAllocs = true; break; @@ -456,8 +456,8 @@ void VulkanDeviceAllocator::ReportOldUsage() { for (auto it : slab.tags) { const auto info = it.second; - float createAge = now - info.created; - float touchedAge = now - info.touched; + double createAge = now - info.created; + double touchedAge = now - info.touched; NOTICE_LOG(G3D, " * %s (created %fs ago, used %fs ago)", info.tag.c_str(), createAge, touchedAge); } } diff --git a/Common/Vulkan/VulkanMemory.h b/Common/Vulkan/VulkanMemory.h index 5c4cec8b1e..ba16245007 100644 --- a/Common/Vulkan/VulkanMemory.h +++ b/Common/Vulkan/VulkanMemory.h @@ -176,8 +176,8 @@ private: struct UsageInfo { std::string tag; - float created; - float touched; + double created; + double touched; }; struct Slab { From 8db6599e772517b3835f4477fc5e81a60be65d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 12:48:09 +0200 Subject: [PATCH 520/848] Buildfixes --- Common/LogManager.cpp | 4 ++++ GPU/D3D11/TextureCacheD3D11.cpp | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- libretro/LibretroGraphicsContext.cpp | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 84a91f6530..af8a33437e 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -28,6 +28,10 @@ #include "Common/FileUtil.h" #include "Common/StringUtils.h" +#if PPSSPP_PLATFORM(ANDROID) +#include +#endif + // Don't need to savestate this. const char *hleCurrentThreadName = nullptr; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 538c0d46be..17cc43472e 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -729,7 +729,7 @@ void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture & pixelData = (u32 *)mapData; // We always end up at 8888. Other parts assume this. - assert(scaleFmt == DXGI_FORMAT_B8G8R8A8_UNORM); + _assert_(scaleFmt == DXGI_FORMAT_B8G8R8A8_UNORM); bpp = sizeof(u32); decPitch = w * bpp; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 50006f3505..6fd3cadd69 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -738,7 +738,7 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &re pixelData = (u32 *)rect.pBits; // We always end up at 8888. Other parts assume this. - assert(dstFmt == D3DFMT_A8R8G8B8); + _assert_(dstFmt == D3DFMT_A8R8G8B8); bpp = sizeof(u32); decPitch = w * bpp; diff --git a/libretro/LibretroGraphicsContext.cpp b/libretro/LibretroGraphicsContext.cpp index b88e6893b2..4facea7683 100644 --- a/libretro/LibretroGraphicsContext.cpp +++ b/libretro/LibretroGraphicsContext.cpp @@ -51,7 +51,7 @@ void LibretroHWRenderContext::ContextReset() { if (!draw_) { CreateDrawContext(); bool success = draw_->CreatePresets(); - assert(success); + _assert_(success); } GotBackbuffer(); From fce0fdb6dc6d594d77a07a88815c7c1624718fd2 Mon Sep 17 00:00:00 2001 From: sorgts Date: Sun, 16 Aug 2020 14:01:23 +0200 Subject: [PATCH 521/848] Fix undesired re-builds after runnning CMake --- CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f9eae3205..398bad57e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,6 +240,18 @@ endif() if(ARM64) message("Generating for ARMv8, ${CMAKE_BUILD_TYPE}") endif() + +# It looks like the flags for the selected build type are written to the cache after each run, which causes some of the operations +# below to keep expanding them with the same flags over and over on every run, leading to a rebuild of the majority of the files. +# To work around this, remember the initial state of the variables from the first run and reset the variables to that. +# TODO: Setting the attributes per target would probably be a better solution. +foreach (LANGUAGE C CXX) + foreach (BUILD_TYPE DEBUG MINSIZEREL RELEASE RELWITHDEBINFO) + set(_CMAKE_${LANGUAGE}_FLAGS_${BUILD_TYPE}_INITIAL ${CMAKE_${LANGUAGE}_FLAGS_${BUILD_TYPE}} CACHE STRING "") + set(CMAKE_${LANGUAGE}_FLAGS_${BUILD_TYPE} ${_CMAKE_${LANGUAGE}_FLAGS_${BUILD_TYPE}_INITIAL}) + endforeach() +endforeach() + if(NOT MSVC) if(ANDROID) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") From e8a9845d93e9ddbe2d1412d4fd6db4db82b9a51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 13:27:28 +0200 Subject: [PATCH 522/848] First step of cleaning up Log.h. Plus a few other bits and bobs. --- Common/ArmEmitter.h | 1 - Common/ExceptionHandlerSetup.cpp | 1 - Common/Log.h | 17 +++++----- Common/MipsEmitter.h | 1 - Common/MsgHandler.cpp | 53 +++++++++----------------------- Common/MsgHandler.h | 16 ++-------- Common/x64Emitter.cpp | 1 - Core/AVIDump.cpp | 1 - Core/CoreTiming.cpp | 21 ++++--------- Core/WaveFile.cpp | 3 +- Core/WaveFile.h | 8 ++--- 11 files changed, 37 insertions(+), 86 deletions(-) diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index 19dab7c135..e100eff197 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -23,7 +23,6 @@ #include "Common.h" #include "ArmCommon.h" #include "CodeBlock.h" -#include "MsgHandler.h" // VCVT flags #define TO_FLOAT 0 diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index f886a5b6da..794c849946 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -15,7 +15,6 @@ #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" -#include "Common/MsgHandler.h" #include "Common/Log.h" #include "ext/native/thread/threadutil.h" diff --git a/Common/Log.h b/Common/Log.h index 3bd39e5c10..01358058d9 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -20,7 +20,7 @@ #include #include "CommonFuncs.h" -#include "Common/MsgHandler.h" +#include "MsgHandler.h" // For ShowAssertDialog #define NOTICE_LEVEL 1 // VERY important information that is NOT errors. Like startup and debugprintfs from the game itself. #define ERROR_LEVEL 2 // Important errors. @@ -129,7 +129,7 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * __LINE__, __FILE__); \ ERROR_LOG(SYSTEM, #_a_ "\n\nError...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \ __LINE__, __FILE__); \ - if (!PanicYesNo("*** Assertion ***\n")) { Crash(); } \ + if (!ShowAssertDialog(__FILE__, __LINE__, "*** Assertion ***\n")) { Crash(); } \ } #if defined(__ANDROID__) @@ -138,7 +138,7 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * if (!(_a_)) {\ printf(__VA_ARGS__); \ ERROR_LOG(SYSTEM, __VA_ARGS__); \ - if (!PanicYesNo(__VA_ARGS__)) AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ + if (!ShowAssertDialog(__FILE__, __LINE__, __VA_ARGS__)) AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ } #else // !defined(__ANDROID__) @@ -147,7 +147,7 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * if (!(_a_)) {\ printf(__VA_ARGS__); \ ERROR_LOG(SYSTEM, __VA_ARGS__); \ - if (!PanicYesNo(__VA_ARGS__)) { Crash();} \ + if (!ShowAssertDialog(__FILE__, __LINE__, __VA_ARGS__)) { Crash();} \ } #endif // __ANDROID__ @@ -169,7 +169,7 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * } #define _assert_msg_(_a_, ...) \ - if (!(_a_) && !PanicYesNo(__VA_ARGS__)) { \ + if (!(_a_) && !ShowAssertDialog(__FILENAME__, __LINE__, __VA_ARGS__)) { \ AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ } @@ -177,13 +177,12 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * #define _assert_(_a_) \ if (!(_a_)) {\ - ERROR_LOG(SYSTEM, "Error...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \ - __LINE__, __FILE__); \ - if (!PanicYesNo("*** Assertion ***\n")) { Crash(); } \ + ERROR_LOG(SYSTEM, "Error...\n\n Line: %d\n File: %s\n\nIgnore and continue?", __LINE__, __FILE__); \ + if (!ShowAssertDialog(__FILE__, __LINE__, "*** Assertion ***\n")) { Crash(); } \ } #define _assert_msg_(_a_, ...) \ - if (!(_a_) && !PanicYesNo(__VA_ARGS__)) { \ + if (!(_a_) && !ShowAssertDialog(__FILE__, __LINE__, __VA_ARGS__)) { \ Crash(); \ } diff --git a/Common/MipsEmitter.h b/Common/MipsEmitter.h index 582e1eb4b4..19913ec2e2 100644 --- a/Common/MipsEmitter.h +++ b/Common/MipsEmitter.h @@ -22,7 +22,6 @@ #include #include "Common.h" -#include "MsgHandler.h" namespace MIPSGen { diff --git a/Common/MsgHandler.cpp b/Common/MsgHandler.cpp index 428790d0df..eb34978a20 100644 --- a/Common/MsgHandler.cpp +++ b/Common/MsgHandler.cpp @@ -24,52 +24,29 @@ #include "StringUtils.h" #include "util/text/utf8.h" -bool MsgHandler(const char *caption, const char *text, const char *file, int line, bool yes_no, int Style); - -bool MsgAlert(bool yes_no, int Style, const char *file, int line, const char* format, ...) { - // Read message and write it to the log - char buffer[2048]; - static const char *captions[] = { - "Information", - "Question", - "Warning", - "Critical" - }; - - const char *caption = captions[Style]; - va_list args; - va_start(args, format); - CharArrayFromFormatV(buffer, sizeof(buffer)-1, format, args); - va_end(args); - // Normal logging (will also log to Android log) - ERROR_LOG(SYSTEM, "(%s:%d) %s: %s", file, line, caption, buffer); - // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored - if (Style == QUESTION || Style == CRITICAL) - return MsgHandler(caption, buffer, file, line, yes_no, Style); - return true; -} - -#ifdef _WIN32 +#ifdef PPSSPP_PLATFORM(WINDOWS) #include "CommonWindows.h" #endif -// Default non library dependent panic alert -bool MsgHandler(const char* caption, const char* text, const char *file, int line, bool yes_no, int Style) { -#if defined(USING_WIN_UI) - int msgBoxStyle = MB_ICONINFORMATION; - if (Style == QUESTION) msgBoxStyle = MB_ICONQUESTION; - if (Style == WARNING) msgBoxStyle = MB_ICONWARNING; +bool ShowAssertDialog(const char *file, int line, const char* format, ...) { + // Read message and write it to the log + char text[2048]; + const char *caption = "Critical"; + va_list args; + va_start(args, format); + CharArrayFromFormatV(text, sizeof(text)-1, format, args); + va_end(args); + // Normal logging (will also log to Android log) + ERROR_LOG(SYSTEM, "(%s:%d) %s: %s", file, line, caption, text); +#if defined(USING_WIN_UI) + int msgBoxStyle = MB_ICONINFORMATION | MB_YESNO; std::wstring wtext = ConvertUTF8ToWString(text) + L"\n\nTry to continue?"; std::wstring wcaption = ConvertUTF8ToWString(caption); OutputDebugString(wtext.c_str()); - return IDYES == MessageBox(0, wtext.c_str(), wcaption.c_str(), msgBoxStyle | (yes_no ? MB_YESNO : MB_OK)); -#elif PPSSPP_PLATFORM(UWP) - OutputDebugStringUTF8(text); - return false; + return IDYES == MessageBox(0, wtext.c_str(), wcaption.c_str(), msgBoxStyle); #else - // Will use android-log if available, printf if not. - ERROR_LOG(SYSTEM, "(%s:%d) %s", file, line, text); + OutputDebugStringUTF8(text); return false; #endif } diff --git a/Common/MsgHandler.h b/Common/MsgHandler.h index a940366255..22bbc0aa19 100644 --- a/Common/MsgHandler.h +++ b/Common/MsgHandler.h @@ -17,19 +17,9 @@ #pragma once -// Message alerts -enum MSG_TYPE { - INFORMATION, - QUESTION, - WARNING, - CRITICAL -}; - -bool MsgAlert(bool yes_no, int Style, const char *file, int line, const char* format, ...) +// Currently only actually shows a dialog box on Windows. +bool ShowAssertDialog(const char *file, int line, const char* format, ...) #ifdef __GNUC__ - __attribute__((format(printf, 5, 6))) + __attribute__((format(printf, 3, 4))) #endif ; - -// Used only for asserts. -#define PanicYesNo(...) MsgAlert(true, CRITICAL, __FILE__, __LINE__, __VA_ARGS__) diff --git a/Common/x64Emitter.cpp b/Common/x64Emitter.cpp index eac312914b..82c790c36f 100644 --- a/Common/x64Emitter.cpp +++ b/Common/x64Emitter.cpp @@ -21,7 +21,6 @@ #include "ABI.h" #include "CPUDetect.h" #include "MemoryUtil.h" -#include "MsgHandler.h" #define PRIx64 "llx" diff --git a/Core/AVIDump.cpp b/Core/AVIDump.cpp index 1786eede35..fd25806e51 100644 --- a/Core/AVIDump.cpp +++ b/Core/AVIDump.cpp @@ -24,7 +24,6 @@ extern "C" { #endif #include "Common/FileUtil.h" -#include "Common/MsgHandler.h" #include "Common/ColorConv.h" #include "Core/Config.h" diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 62fb2afca3..81a7b3444d 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -22,7 +22,6 @@ #include "profiler/profiler.h" -#include "Common/MsgHandler.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeList.h" #include "Core/CoreTiming.h" @@ -43,25 +42,17 @@ int CPU_HZ = 222000000; namespace CoreTiming { -struct EventType -{ - EventType() {} - - EventType(TimedCallback cb, const char *n) - : callback(cb), name(n) {} - +struct EventType { TimedCallback callback; const char *name; }; std::vector event_types; -struct BaseEvent -{ +struct BaseEvent { s64 time; u64 userdata; int type; -// Event *next; }; typedef LinkedListItem Event; @@ -171,7 +162,7 @@ void FreeTsEvent(Event* ev) int RegisterEvent(const char *name, TimedCallback callback) { - event_types.push_back(EventType(callback, name)); + event_types.push_back(EventType{ callback, name }); return (int)event_types.size() - 1; } @@ -185,9 +176,9 @@ void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callba { _assert_msg_(event_type >= 0, "Invalid event type %d", event_type) if (event_type >= (int) event_types.size()) - event_types.resize(event_type + 1, EventType(AntiCrashCallback, "INVALID EVENT")); + event_types.resize(event_type + 1, EventType{ AntiCrashCallback, "INVALID EVENT" }); - event_types[event_type] = EventType(callback, name); + event_types[event_type] = EventType{ callback, name }; } void UnregisterAllEvents() @@ -692,7 +683,7 @@ void DoState(PointerWrap &p) int n = (int) event_types.size(); Do(p, n); // These (should) be filled in later by the modules. - event_types.resize(n, EventType(AntiCrashCallback, "INVALID EVENT")); + event_types.resize(n, EventType{ AntiCrashCallback, "INVALID EVENT" }); if (s >= 3) { DoLinkedList(p, first, (Event **) NULL); diff --git a/Core/WaveFile.cpp b/Core/WaveFile.cpp index b1c56b002c..20f98a766f 100644 --- a/Core/WaveFile.cpp +++ b/Core/WaveFile.cpp @@ -5,8 +5,7 @@ #include #include "Core/WaveFile.h" -#include "Common/CommonTypes.h" -#include "Common/MsgHandler.h" +#include "Common/Log.h" #include "Core/Config.h" constexpr size_t WaveFileWriter::BUFFER_SIZE; diff --git a/Core/WaveFile.h b/Core/WaveFile.h index c2ba17d802..b9dcad5f1e 100644 --- a/Core/WaveFile.h +++ b/Core/WaveFile.h @@ -14,7 +14,7 @@ #include #include -#include "Common/CommonTypes.h" + #include "Common/FileUtil.h" class WaveFileWriter @@ -27,14 +27,14 @@ public: void Stop(); void SetSkipSilence(bool skip) { skip_silence = skip; } - void AddStereoSamples(const short* sample_data, u32 count); - u32 GetAudioSize() const { return audio_size; } + void AddStereoSamples(const short* sample_data, uint32_t count); + uint32_t GetAudioSize() const { return audio_size; } private: static constexpr size_t BUFFER_SIZE = 32 * 1024; File::IOFile file; bool skip_silence = false; - u32 audio_size = 0; + uint32_t audio_size = 0; std::array conv_buffer{}; void Write(u32 value); void Write4(const char* ptr); From 5704ebfb61924e0935b8ea5c49d19fc722e6c6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 13:41:16 +0200 Subject: [PATCH 523/848] More cleanup of Log.h, move AndroidAssert into MsgHandler.cpp/h. --- Common/Log.h | 33 ++++++++------------------------- Common/LogManager.cpp | 19 ------------------- Common/MsgHandler.cpp | 27 ++++++++++++++++++++++++--- Common/MsgHandler.h | 12 ++++++++++-- Common/StringUtils.cpp | 1 + 5 files changed, 43 insertions(+), 49 deletions(-) diff --git a/Common/Log.h b/Common/Log.h index 01358058d9..4638865639 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -112,42 +112,26 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); #define DEBUG_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LDEBUG, __VA_ARGS__) } while (false) #define VERBOSE_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LVERBOSE, __VA_ARGS__) } while (false) -#if defined(__ANDROID__) - -// Tricky macro to get the basename, that also works if *built* on Win32. -#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : (__builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)) -void AndroidAssertLog(const char *func, const char *file, int line, const char *condition, const char *fmt, ...); - -#endif - // If we're in "debug" assert mode #if MAX_LOGLEVEL >= DEBUG_LEVEL #define _dbg_assert_(_a_) \ if (!(_a_)) {\ - printf(#_a_ "\n\nError...\n\n Line: %d\n File: %s\n\n", \ - __LINE__, __FILE__); \ - ERROR_LOG(SYSTEM, #_a_ "\n\nError...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \ - __LINE__, __FILE__); \ - if (!ShowAssertDialog(__FILE__, __LINE__, "*** Assertion ***\n")) { Crash(); } \ + if (!ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, "*** Assertion ***\n")) { Crash(); } \ } #if defined(__ANDROID__) #define _dbg_assert_msg_(_a_, ...)\ if (!(_a_)) {\ - printf(__VA_ARGS__); \ - ERROR_LOG(SYSTEM, __VA_ARGS__); \ - if (!ShowAssertDialog(__FILE__, __LINE__, __VA_ARGS__)) AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ + if (!ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, __VA_ARGS__)) AndroidAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ } #else // !defined(__ANDROID__) #define _dbg_assert_msg_(_a_, ...)\ if (!(_a_)) {\ - printf(__VA_ARGS__); \ - ERROR_LOG(SYSTEM, __VA_ARGS__); \ - if (!ShowAssertDialog(__FILE__, __LINE__, __VA_ARGS__)) { Crash();} \ + if (!ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, __VA_ARGS__)) { Crash();} \ } #endif // __ANDROID__ @@ -165,24 +149,23 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char * #define _assert_(_a_) \ if (!(_a_)) {\ - AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "Assertion failed!"); \ + AndroidAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "Assertion failed!"); \ } #define _assert_msg_(_a_, ...) \ - if (!(_a_) && !ShowAssertDialog(__FILENAME__, __LINE__, __VA_ARGS__)) { \ - AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ + if (!(_a_) && !ShowAssertDialog(__FUNCTION__,__FILENAME__, __LINE__, #_a_, __VA_ARGS__)) { \ + AndroidAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ } #else // __ANDROID__ #define _assert_(_a_) \ if (!(_a_)) {\ - ERROR_LOG(SYSTEM, "Error...\n\n Line: %d\n File: %s\n\nIgnore and continue?", __LINE__, __FILE__); \ - if (!ShowAssertDialog(__FILE__, __LINE__, "*** Assertion ***\n")) { Crash(); } \ + if (!ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, "*** Assertion ***\n")) { Crash(); } \ } #define _assert_msg_(_a_, ...) \ - if (!(_a_) && !ShowAssertDialog(__FILE__, __LINE__, __VA_ARGS__)) { \ + if (!(_a_) && !ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, __VA_ARGS__)) { \ Crash(); \ } diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index af8a33437e..aa090315ac 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -28,10 +28,6 @@ #include "Common/FileUtil.h" #include "Common/StringUtils.h" -#if PPSSPP_PLATFORM(ANDROID) -#include -#endif - // Don't need to savestate this. const char *hleCurrentThreadName = nullptr; @@ -67,21 +63,6 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type) { return false; } -#if defined(__ANDROID__) - -#define LOG_BUF_SIZE 1024 - -void AndroidAssertLog(const char *func, const char *file, int line, const char *condition, const char *fmt, ...) { - char buf[LOG_BUF_SIZE]; - va_list args; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - __android_log_assert(condition, "PPSSPP", "%s:%d (%s): [%s] %s", file, line, func, condition, buf); - va_end(args); -} - -#endif - LogManager *LogManager::logManager_ = NULL; struct LogNameTableEntry { diff --git a/Common/MsgHandler.cpp b/Common/MsgHandler.cpp index eb34978a20..9df5f14538 100644 --- a/Common/MsgHandler.cpp +++ b/Common/MsgHandler.cpp @@ -24,20 +24,25 @@ #include "StringUtils.h" #include "util/text/utf8.h" -#ifdef PPSSPP_PLATFORM(WINDOWS) +#if PPSSPP_PLATFORM(ANDROID) +#include +#elif PPSSPP_PLATFORM(WINDOWS) #include "CommonWindows.h" #endif -bool ShowAssertDialog(const char *file, int line, const char* format, ...) { +bool ShowAssertDialog(const char *function, const char *file, int line, const char *expression, const char* format, ...) { // Read message and write it to the log char text[2048]; const char *caption = "Critical"; va_list args; va_start(args, format); - CharArrayFromFormatV(text, sizeof(text)-1, format, args); + vsnprintf(text, sizeof(text), format, args); va_end(args); + // Normal logging (will also log to Android log) ERROR_LOG(SYSTEM, "(%s:%d) %s: %s", file, line, caption, text); + // Also do a simple printf for good measure, in case logging of SYSTEM is disabled (should we disallow that?) + printf("(%s: %d) %s: %s\n", file, line, caption, text); #if defined(USING_WIN_UI) int msgBoxStyle = MB_ICONINFORMATION | MB_YESNO; @@ -50,3 +55,19 @@ bool ShowAssertDialog(const char *file, int line, const char* format, ...) { return false; #endif } + + +#if defined(__ANDROID__) + +#define LOG_BUF_SIZE 1024 + +void AndroidAssert(const char *func, const char *file, int line, const char *condition, const char *fmt, ...) { + char buf[LOG_BUF_SIZE]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + __android_log_assert(condition, "PPSSPP", "%s:%d (%s): [%s] %s", file, line, func, condition, buf); + va_end(args); +} + +#endif diff --git a/Common/MsgHandler.h b/Common/MsgHandler.h index 22bbc0aa19..5f16e105d3 100644 --- a/Common/MsgHandler.h +++ b/Common/MsgHandler.h @@ -18,8 +18,16 @@ #pragma once // Currently only actually shows a dialog box on Windows. -bool ShowAssertDialog(const char *file, int line, const char* format, ...) +bool ShowAssertDialog(const char *function, const char *file, int line, const char *expression, const char* format, ...) #ifdef __GNUC__ - __attribute__((format(printf, 3, 4))) + __attribute__((format(printf, 5, 6))) #endif ; + +#if defined(__ANDROID__) + +// Tricky macro to get the basename, that also works if *built* on Win32. +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : (__builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)) +void AndroidAssert(const char *func, const char *file, int line, const char *condition, const char *fmt, ...); + +#endif diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index 0bd5da6962..58d721a1e4 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -39,6 +39,7 @@ long parseHexLong(std::string s) { value = strtoul(s.c_str(),0, 0); return value; } + long parseLong(std::string s) { long value = 0; if (s.substr(0,2) == "0x") { From 9561a4f80a861bfbd61bb36be49a23d89cdc872c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 13:48:31 +0200 Subject: [PATCH 524/848] Move MsgHandler into Log.cpp/h --- CMakeLists.txt | 4 ++-- Common/Common.vcxproj | 4 ++-- Common/Common.vcxproj.filters | 6 +++-- Common/FakeEmitter.h | 1 - Common/{MsgHandler.cpp => Log.cpp} | 31 ++++++++++++------------- Common/Log.h | 24 +++++++++++++++---- GPU/Common/TextureScalerCommon.cpp | 1 - UWP/CommonUWP/CommonUWP.vcxproj | 3 +-- UWP/CommonUWP/CommonUWP.vcxproj.filters | 3 +-- android/jni/Android.mk | 2 +- libretro/Makefile.common | 2 +- 11 files changed, 46 insertions(+), 35 deletions(-) rename Common/{MsgHandler.cpp => Log.cpp} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f9eae3205..7651d67276 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -440,6 +440,8 @@ add_library(Common STATIC Common/KeyMap.cpp Common/KeyMap.h Common/Hashmaps.h + Common/Log.h + Common/Log.cpp Common/LogManager.cpp Common/LogManager.h Common/MakeUnique.h @@ -451,8 +453,6 @@ add_library(Common STATIC Common/MemoryUtil.cpp Common/MemoryUtil.h Common/Misc.cpp - Common/MsgHandler.cpp - Common/MsgHandler.h Common/OSVersion.cpp Common/OSVersion.h Common/StringUtils.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index cfe40b4cf4..62f72077cd 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -354,6 +354,7 @@ + @@ -407,7 +408,6 @@ - @@ -450,6 +450,7 @@ false false + @@ -498,7 +499,6 @@ - Create diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 92551a3e85..6cd39fb4f3 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -14,7 +14,6 @@ - @@ -93,6 +92,8 @@ Serialize + + @@ -103,7 +104,6 @@ - @@ -159,6 +159,8 @@ Serialize + + diff --git a/Common/FakeEmitter.h b/Common/FakeEmitter.h index 25ef39b419..6b827655c8 100644 --- a/Common/FakeEmitter.h +++ b/Common/FakeEmitter.h @@ -24,7 +24,6 @@ #include #include "Common.h" -#include "MsgHandler.h" // VCVT flags #define TO_FLOAT 0 diff --git a/Common/MsgHandler.cpp b/Common/Log.cpp similarity index 99% rename from Common/MsgHandler.cpp rename to Common/Log.cpp index 9df5f14538..4aff42ce37 100644 --- a/Common/MsgHandler.cpp +++ b/Common/Log.cpp @@ -30,6 +30,21 @@ #include "CommonWindows.h" #endif +#if defined(__ANDROID__) + +#define LOG_BUF_SIZE 1024 + +void AndroidAssert(const char *func, const char *file, int line, const char *condition, const char *fmt, ...) { + char buf[LOG_BUF_SIZE]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + __android_log_assert(condition, "PPSSPP", "%s:%d (%s): [%s] %s", file, line, func, condition, buf); + va_end(args); +} + +#endif + bool ShowAssertDialog(const char *function, const char *file, int line, const char *expression, const char* format, ...) { // Read message and write it to the log char text[2048]; @@ -55,19 +70,3 @@ bool ShowAssertDialog(const char *function, const char *file, int line, const ch return false; #endif } - - -#if defined(__ANDROID__) - -#define LOG_BUF_SIZE 1024 - -void AndroidAssert(const char *func, const char *file, int line, const char *condition, const char *fmt, ...) { - char buf[LOG_BUF_SIZE]; - va_list args; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - __android_log_assert(condition, "PPSSPP", "%s:%d (%s): [%s] %s", file, line, func, condition, buf); - va_end(args); -} - -#endif diff --git a/Common/Log.h b/Common/Log.h index 4638865639..74dec3fc65 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -20,7 +20,6 @@ #include #include "CommonFuncs.h" -#include "MsgHandler.h" // For ShowAssertDialog #define NOTICE_LEVEL 1 // VERY important information that is NOT errors. Like startup and debugprintfs from the game itself. #define ERROR_LEVEL 2 // Important errors. @@ -105,11 +104,11 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); GenericLog(v, t, __FILE__, __LINE__, __VA_ARGS__); \ } -#define ERROR_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LERROR, __VA_ARGS__) } while (false) +#define ERROR_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LERROR, __VA_ARGS__) } while (false) #define WARN_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LWARNING, __VA_ARGS__) } while (false) -#define NOTICE_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LNOTICE, __VA_ARGS__) } while (false) -#define INFO_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LINFO, __VA_ARGS__) } while (false) -#define DEBUG_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LDEBUG, __VA_ARGS__) } while (false) +#define NOTICE_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LNOTICE, __VA_ARGS__) } while (false) +#define INFO_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LINFO, __VA_ARGS__) } while (false) +#define DEBUG_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LDEBUG, __VA_ARGS__) } while (false) #define VERBOSE_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LVERBOSE, __VA_ARGS__) } while (false) // If we're in "debug" assert mode @@ -173,3 +172,18 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); // Just INFO_LOGs on nonWindows. On Windows it outputs to the VS output console. void OutputDebugStringUTF8(const char *p); + +// Currently only actually shows a dialog box on Windows. +bool ShowAssertDialog(const char *function, const char *file, int line, const char *expression, const char* format, ...) +#ifdef __GNUC__ +__attribute__((format(printf, 5, 6))) +#endif +; + +#if defined(__ANDROID__) + +// Tricky macro to get the basename, that also works if *built* on Win32. +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : (__builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)) +void AndroidAssert(const char *func, const char *file, int line, const char *condition, const char *fmt, ...); + +#endif diff --git a/GPU/Common/TextureScalerCommon.cpp b/GPU/Common/TextureScalerCommon.cpp index 63b972403e..6f4c2d3fc4 100644 --- a/GPU/Common/TextureScalerCommon.cpp +++ b/GPU/Common/TextureScalerCommon.cpp @@ -30,7 +30,6 @@ #include "Core/Config.h" #include "Common/Common.h" #include "Common/Log.h" -#include "Common/MsgHandler.h" #include "Common/CommonFuncs.h" #include "Common/ThreadPools.h" #include "Common/CPUDetect.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 3405d3666f..b6a8a7b933 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -414,7 +414,6 @@ - @@ -445,6 +444,7 @@ + @@ -454,7 +454,6 @@ - diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 57775b7f87..50626b680e 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -19,6 +19,7 @@ + @@ -28,7 +29,6 @@ - @@ -83,7 +83,6 @@ - diff --git a/android/jni/Android.mk b/android/jni/Android.mk index cd30bde35c..36a29682f0 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -209,13 +209,13 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/ColorConv.cpp \ $(SRC)/Common/ExceptionHandlerSetup.cpp \ $(SRC)/Common/KeyMap.cpp \ + $(SRC)/Common/Log.cpp \ $(SRC)/Common/LogManager.cpp \ $(SRC)/Common/MemArenaAndroid.cpp \ $(SRC)/Common/MemArenaDarwin.cpp \ $(SRC)/Common/MemArenaWin32.cpp \ $(SRC)/Common/MemArenaPosix.cpp \ $(SRC)/Common/MemoryUtil.cpp \ - $(SRC)/Common/MsgHandler.cpp \ $(SRC)/Common/FileUtil.cpp \ $(SRC)/Common/StringUtils.cpp \ $(SRC)/Common/ThreadPools.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index d9e90898eb..d92fd54468 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -146,11 +146,11 @@ SOURCES_CXX += \ $(COMMONDIR)/ExceptionHandlerSetup.cpp \ $(COMMONDIR)/FileUtil.cpp \ $(COMMONDIR)/KeyMap.cpp \ + $(COMMONDIR)/Log.cpp \ $(COMMONDIR)/LogManager.cpp \ $(COMMONDIR)/OSVersion.cpp \ $(COMMONDIR)/MemoryUtil.cpp \ $(COMMONDIR)/Misc.cpp \ - $(COMMONDIR)/MsgHandler.cpp \ $(COMMONDIR)/StringUtils.cpp \ $(COMMONDIR)/Timer.cpp \ $(COMMONDIR)/TimeUtil.cpp \ From 0bf6bd9175d34d4b6b1805064a3f7166d338c201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 14:11:56 +0200 Subject: [PATCH 525/848] More Log.h cleanup. --- Common/CommonFuncs.h | 1 - Common/ConsoleListener.cpp | 4 +- Common/ConsoleListener.h | 4 +- Common/Log.cpp | 39 ++++++++++---------- Common/Log.h | 75 ++++++++++++-------------------------- Common/LogManager.h | 1 + GPU/D3D11/D3D11Util.cpp | 4 +- GPU/GeDisasm.cpp | 5 ++- UI/NativeApp.cpp | 2 + UI/TextureUtil.cpp | 4 +- 10 files changed, 55 insertions(+), 84 deletions(-) diff --git a/Common/CommonFuncs.h b/Common/CommonFuncs.h index d9b4ea6d74..4e5adc8beb 100644 --- a/Common/CommonFuncs.h +++ b/Common/CommonFuncs.h @@ -25,7 +25,6 @@ #if !defined(_WIN32) - #include #include diff --git a/Common/ConsoleListener.cpp b/Common/ConsoleListener.cpp index 5b7217827a..7eab9980c9 100644 --- a/Common/ConsoleListener.cpp +++ b/Common/ConsoleListener.cpp @@ -49,8 +49,8 @@ HANDLE ConsoleListener::hTriggerEvent = NULL; CRITICAL_SECTION ConsoleListener::criticalSection; char *ConsoleListener::logPending = NULL; -std::atomic ConsoleListener::logPendingReadPos; -std::atomic ConsoleListener::logPendingWritePos; +std::atomic ConsoleListener::logPendingReadPos; +std::atomic ConsoleListener::logPendingWritePos; #endif ConsoleListener::ConsoleListener() : bHidden(true) diff --git a/Common/ConsoleListener.h b/Common/ConsoleListener.h index 66a612a849..976e7531cd 100644 --- a/Common/ConsoleListener.h +++ b/Common/ConsoleListener.h @@ -63,8 +63,8 @@ private: static CRITICAL_SECTION criticalSection; static char *logPending; - static std::atomic logPendingReadPos; - static std::atomic logPendingWritePos; + static std::atomic logPendingReadPos; + static std::atomic logPendingWritePos; int openWidth_; int openHeight_; diff --git a/Common/Log.cpp b/Common/Log.cpp index 4aff42ce37..dd0802ad86 100644 --- a/Common/Log.cpp +++ b/Common/Log.cpp @@ -30,41 +30,40 @@ #include "CommonWindows.h" #endif -#if defined(__ANDROID__) +#define LOG_BUF_SIZE 2048 -#define LOG_BUF_SIZE 1024 - -void AndroidAssert(const char *func, const char *file, int line, const char *condition, const char *fmt, ...) { - char buf[LOG_BUF_SIZE]; - va_list args; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - __android_log_assert(condition, "PPSSPP", "%s:%d (%s): [%s] %s", file, line, func, condition, buf); - va_end(args); -} - -#endif - -bool ShowAssertDialog(const char *function, const char *file, int line, const char *expression, const char* format, ...) { +bool HandleAssert(const char *function, const char *file, int line, const char *expression, const char* format, ...) { // Read message and write it to the log - char text[2048]; + char text[LOG_BUF_SIZE]; const char *caption = "Critical"; va_list args; va_start(args, format); vsnprintf(text, sizeof(text), format, args); va_end(args); + // Secondary formatting. Wonder if this can be combined into the vsnprintf somehow. + char formatted[LOG_BUF_SIZE]; + snprintf(formatted, sizeof(formatted), "(%s:%s:%d) %s: [%s] %s", file, function, line, caption, expression, text); + // Normal logging (will also log to Android log) - ERROR_LOG(SYSTEM, "(%s:%d) %s: %s", file, line, caption, text); + ERROR_LOG(SYSTEM, "%s", formatted); // Also do a simple printf for good measure, in case logging of SYSTEM is disabled (should we disallow that?) - printf("(%s: %d) %s: %s\n", file, line, caption, text); + printf("%s\n", formatted); #if defined(USING_WIN_UI) int msgBoxStyle = MB_ICONINFORMATION | MB_YESNO; - std::wstring wtext = ConvertUTF8ToWString(text) + L"\n\nTry to continue?"; + std::wstring wtext = ConvertUTF8ToWString(formatted) + L"\n\nTry to continue?"; std::wstring wcaption = ConvertUTF8ToWString(caption); OutputDebugString(wtext.c_str()); - return IDYES == MessageBox(0, wtext.c_str(), wcaption.c_str(), msgBoxStyle); + if (IDYES != MessageBox(0, wtext.c_str(), wcaption.c_str(), msgBoxStyle)) { + return false; + } else { + return true; + } +#elif PPSSPP_PLATFORM(ANDROID) + __android_log_assert(expression, "PPSSPP", "%s", formatted); + // Doesn't matter what we return here. + return false; #else OutputDebugStringUTF8(text); return false; diff --git a/Common/Log.h b/Common/Log.h index 74dec3fc65..f8a56730a6 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -17,8 +17,6 @@ #pragma once -#include - #include "CommonFuncs.h" #define NOTICE_LEVEL 1 // VERY important information that is NOT errors. Like startup and debugprintfs from the game itself. @@ -111,30 +109,34 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); #define DEBUG_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LDEBUG, __VA_ARGS__) } while (false) #define VERBOSE_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LVERBOSE, __VA_ARGS__) } while (false) +// Currently only actually shows a dialog box on Windows. +bool HandleAssert(const char *function, const char *file, int line, const char *expression, const char* format, ...) +#ifdef __GNUC__ +__attribute__((format(printf, 5, 6))) +#endif +; + +#if defined(__ANDROID__) +// Tricky macro to get the basename, that also works if *built* on Win32. +// Doesn't mean this macro can be used on Win32 though. +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : (__builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)) +#else +#define __FILENAME__ __FILE__ +#endif + // If we're in "debug" assert mode #if MAX_LOGLEVEL >= DEBUG_LEVEL #define _dbg_assert_(_a_) \ if (!(_a_)) {\ - if (!ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, "*** Assertion ***\n")) { Crash(); } \ + if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "*** Assertion ***\n")) Crash(); \ } -#if defined(__ANDROID__) - -#define _dbg_assert_msg_(_a_, ...)\ - if (!(_a_)) {\ - if (!ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, __VA_ARGS__)) AndroidAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ +#define _dbg_assert_msg_(_a_, ...) \ + if (!(_a_)) { \ + if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__)) Crash(); \ } -#else // !defined(__ANDROID__) - -#define _dbg_assert_msg_(_a_, ...)\ - if (!(_a_)) {\ - if (!ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, __VA_ARGS__)) { Crash();} \ - } - -#endif // __ANDROID__ - #else // not debug #ifndef _dbg_assert_ @@ -144,46 +146,15 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); #endif // MAX_LOGLEVEL DEBUG -#if defined(__ANDROID__) - #define _assert_(_a_) \ if (!(_a_)) {\ - AndroidAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "Assertion failed!"); \ + if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, "*** Assertion ***\n")) Crash(); \ } -#define _assert_msg_(_a_, ...) \ - if (!(_a_) && !ShowAssertDialog(__FUNCTION__,__FILENAME__, __LINE__, #_a_, __VA_ARGS__)) { \ - AndroidAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ +#define _assert_msg_(_a_, ...) \ + if (!(_a_)) { \ + if (!HandleAssert(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__)) Crash(); \ } -#else // __ANDROID__ - -#define _assert_(_a_) \ - if (!(_a_)) {\ - if (!ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, "*** Assertion ***\n")) { Crash(); } \ - } - -#define _assert_msg_(_a_, ...) \ - if (!(_a_) && !ShowAssertDialog(__FUNCTION__, __FILE__, __LINE__, #_a_, __VA_ARGS__)) { \ - Crash(); \ - } - -#endif // __ANDROID__ - // Just INFO_LOGs on nonWindows. On Windows it outputs to the VS output console. void OutputDebugStringUTF8(const char *p); - -// Currently only actually shows a dialog box on Windows. -bool ShowAssertDialog(const char *function, const char *file, int line, const char *expression, const char* format, ...) -#ifdef __GNUC__ -__attribute__((format(printf, 5, 6))) -#endif -; - -#if defined(__ANDROID__) - -// Tricky macro to get the basename, that also works if *built* on Win32. -#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : (__builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)) -void AndroidAssert(const char *func, const char *file, int line, const char *condition, const char *fmt, ...); - -#endif diff --git a/Common/LogManager.h b/Common/LogManager.h index 6aaa69b462..346561430f 100644 --- a/Common/LogManager.h +++ b/Common/LogManager.h @@ -24,6 +24,7 @@ #include #include "file/ini_file.h" +#include "Common/CommonFuncs.h" #include "Common/Log.h" #define MAX_MESSAGES 8000 diff --git a/GPU/D3D11/D3D11Util.cpp b/GPU/D3D11/D3D11Util.cpp index 7a7b0aac25..add974eb75 100644 --- a/GPU/D3D11/D3D11Util.cpp +++ b/GPU/D3D11/D3D11Util.cpp @@ -6,7 +6,6 @@ #include #include - #if PPSSPP_PLATFORM(UWP) #define ptr_D3DCompile D3DCompile #else @@ -15,8 +14,9 @@ #include "base/stringutil.h" -#include "D3D11Util.h" +#include "Common/CommonFuncs.h" #include "Common/Log.h" +#include "D3D11Util.h" static std::vector CompileShaderToBytecode(const char *code, size_t codeSize, const char *target, UINT flags) { ID3DBlob *compiledCode = nullptr; diff --git a/GPU/GeDisasm.cpp b/GPU/GeDisasm.cpp index fda2d77890..ef04d7c606 100644 --- a/GPU/GeDisasm.cpp +++ b/GPU/GeDisasm.cpp @@ -15,9 +15,10 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Core/MemMap.h" +#include -#include "ge_constants.h" +#include "Core/MemMap.h" +#include "GPU/ge_constants.h" #include "GPU/GPU.h" #include "GPU/GPUState.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 91d0b7c86e..22b6ca4cad 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -762,6 +762,8 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch // Must be done restarting by now. restarting = false; + + _assert_msg_(false, "assert test"); } static UI::Style MakeStyle(uint32_t fg, uint32_t bg) { diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index 284a9b019d..eaf2b82faf 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -107,9 +107,7 @@ bool ManagedTexture::LoadFromFileData(const uint8_t *data, size_t dataSize, Imag return false; } - if (!image[0]) { - Crash(); - } + _assert_(image[0] != nullptr); if (num_levels < 0 || num_levels >= 16) { ERROR_LOG(IO, "Invalid num_levels: %d. Falling back to one. Image: %dx%d", num_levels, width[0], height[0]); From 1ee70c1bcf847ac09a61d12b65e8b3e04268280a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 15:05:44 +0200 Subject: [PATCH 526/848] Buildfix --- Core/HLE/HLE.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/HLE/HLE.h b/Core/HLE/HLE.h index 9fa4c16451..7a89618015 100644 --- a/Core/HLE/HLE.h +++ b/Core/HLE/HLE.h @@ -17,8 +17,10 @@ #pragma once +#include #include #include + #include "Common/CommonTypes.h" #include "Common/Log.h" #include "Core/MIPS/MIPS.h" From 20eef073b410066a8c6e75f317bce2c8cfbcdf43 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 16 Aug 2020 10:54:47 -0700 Subject: [PATCH 527/848] Global: Unbreak build. --- UI/NativeApp.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 22b6ca4cad..91d0b7c86e 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -762,8 +762,6 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch // Must be done restarting by now. restarting = false; - - _assert_msg_(false, "assert test"); } static UI::Style MakeStyle(uint32_t fg, uint32_t bg) { From 2e06386cf680084e84be054772af203085c64c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 21:38:07 +0200 Subject: [PATCH 528/848] Software renderer clipper: Don't clip on the sides. Fixes #4845 and should fix #7124 for the SW renderer. --- GPU/Software/Clipper.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/GPU/Software/Clipper.cpp b/GPU/Software/Clipper.cpp index 2aa3ff69eb..86142582b9 100644 --- a/GPU/Software/Clipper.cpp +++ b/GPU/Software/Clipper.cpp @@ -324,10 +324,11 @@ void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2, const Verte indices[1] = SKIP_FLAG; indices[2] = SKIP_FLAG; - POLY_CLIP(CLIP_POS_X_BIT, -1, 0, 0, 1); - POLY_CLIP(CLIP_NEG_X_BIT, 1, 0, 0, 1); - POLY_CLIP(CLIP_POS_Y_BIT, 0, -1, 0, 1); - POLY_CLIP(CLIP_NEG_Y_BIT, 0, 1, 0, 1); + // The PSP doesn't clip on the sides (so, commented out) but it does appear to have a Z clipper. + // POLY_CLIP(CLIP_POS_X_BIT, -1, 0, 0, 1); + // POLY_CLIP(CLIP_NEG_X_BIT, 1, 0, 0, 1); + // POLY_CLIP(CLIP_POS_Y_BIT, 0, -1, 0, 1); + // POLY_CLIP(CLIP_NEG_Y_BIT, 0, 1, 0, 1); POLY_CLIP(CLIP_POS_Z_BIT, 0, 0, 0, 1); POLY_CLIP(CLIP_NEG_Z_BIT, 0, 0, 1, 1); From 479dedf0ba768976e7f4d6b2616e4fdd69868163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 22:22:58 +0200 Subject: [PATCH 529/848] Some logging improvements. Show more coordinates for block transfers, etc. --- Common/Vulkan/VulkanLoader.cpp | 6 +++--- GPU/Common/FramebufferManagerCommon.cpp | 22 ++++++++++++++++------ UI/NativeApp.cpp | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index 4fff74c28d..4a6ef8a249 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -476,7 +476,7 @@ bool VulkanLoad() { LOAD_GLOBAL_FUNC(vkEnumerateInstanceLayerProperties); if (vkCreateInstance && vkGetInstanceProcAddr && vkGetDeviceProcAddr && vkEnumerateInstanceExtensionProperties && vkEnumerateInstanceLayerProperties) { - WARN_LOG(G3D, "VulkanLoad: Base functions loaded."); + INFO_LOG(G3D, "VulkanLoad: Base functions loaded."); return true; } else { ERROR_LOG(G3D, "VulkanLoad: Failed to load Vulkan base functions."); @@ -549,14 +549,14 @@ void VulkanLoadInstanceFunctions(VkInstance instance, const VulkanExtensions &en LOAD_INSTANCE_FUNC(instance, vkSetDebugUtilsObjectTagEXT); } - WARN_LOG(G3D, "Vulkan instance functions loaded."); + INFO_LOG(G3D, "Vulkan instance functions loaded."); } // On some implementations, loading functions (that have Device as their first parameter) via vkGetDeviceProcAddr may // increase performance - but then these function pointers will only work on that specific device. Thus, this loader is not very // good for multi-device - not likely we'll ever try that anyway though. void VulkanLoadDeviceFunctions(VkDevice device, const VulkanExtensions &enabledExtensions) { - WARN_LOG(G3D, "Vulkan device functions loaded."); + INFO_LOG(G3D, "Vulkan device functions loaded."); LOAD_DEVICE_FUNC(device, vkQueueSubmit); LOAD_DEVICE_FUNC(device, vkQueueWaitIdle); diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index be46d3d620..795a570648 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1086,7 +1086,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } if (!vfb->fbo) { - ERROR_LOG(FRAMEBUF, "Error creating FBO! %i x %i", vfb->renderWidth, vfb->renderHeight); + ERROR_LOG(FRAMEBUF, "Error creating FBO during resize! %d x %d", vfb->renderWidth, vfb->renderHeight); vfb->last_frame_failed = gpuStats.numFlips; } } @@ -1431,7 +1431,7 @@ bool FramebufferManagerCommon::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb snprintf(name, sizeof(name), "download_temp"); nvfb->fbo = draw_->CreateFramebuffer({ nvfb->bufferWidth, nvfb->bufferHeight, 1, 1, false, (Draw::FBColorDepth)nvfb->colorDepth, name }); if (!nvfb->fbo) { - ERROR_LOG(FRAMEBUF, "Error creating GL FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight); + ERROR_LOG(FRAMEBUF, "Error creating FBO! %d x %d", nvfb->renderWidth, nvfb->renderHeight); return false; } return true; @@ -1566,7 +1566,10 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst if (dstBuffer && srcBuffer) { if (srcBuffer == dstBuffer) { if (srcX != dstX || srcY != dstY) { - WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x -> %08x (%dx%d %dbpp)", srcBasePtr, dstBasePtr, width, height, bpp); + WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", + srcBasePtr, srcX, srcY, srcStride, + dstBasePtr, dstX, dstY, dstStride, + width, height, bpp); FlushBeforeCopy(); BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); RebindFramebuffer("rebind after intra block transfer"); @@ -1577,7 +1580,10 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst return true; } } else { - WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x -> %08x (%dx%d %dbpp)", srcBasePtr, dstBasePtr, width, height, bpp); + WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", + srcBasePtr, srcX, srcY, srcStride, + dstBasePtr, dstX, dstY, dstStride, + width, height, bpp); // Just do the blit! FlushBeforeCopy(); BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); @@ -1590,7 +1596,10 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst // Here we should just draw the pixels into the buffer. Copy first. return false; } else if (srcBuffer) { - WARN_LOG_ONCE(btd, G3D, "Block transfer download %08x -> %08x (%dx%d %dbpp)", srcBasePtr, dstBasePtr, width, height, bpp); + WARN_LOG_ONCE(btd, G3D, "Block transfer readback %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", + srcBasePtr, srcX, srcY, srcStride, + dstBasePtr, dstX, dstY, dstStride, + width, height, bpp); FlushBeforeCopy(); if (g_Config.bBlockTransferGPU && !srcBuffer->memoryUpdated) { const int srcBpp = srcBuffer->format == GE_FORMAT_8888 ? 4 : 2; @@ -1599,8 +1608,9 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst if (srcHeight <= 0 || (tooTall && srcY != 0)) { WARN_LOG_ONCE(btdheight, G3D, "Block transfer download %08x -> %08x skipped, %d+%d is taller than %d", srcBasePtr, dstBasePtr, srcY, srcHeight, srcBuffer->bufferHeight); } else { - if (tooTall) + if (tooTall) { WARN_LOG_ONCE(btdheight, G3D, "Block transfer download %08x -> %08x dangerous, %d+%d is taller than %d", srcBasePtr, dstBasePtr, srcY, srcHeight, srcBuffer->bufferHeight); + } ReadFramebufferToMemory(srcBuffer, static_cast(srcX * srcXFactor), srcY, static_cast(srcWidth * srcXFactor), srcHeight); srcBuffer->usageFlags = (srcBuffer->usageFlags | FB_USAGE_DOWNLOAD) & ~FB_USAGE_DOWNLOAD_CLEAR; } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 91d0b7c86e..663bc30e5b 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -373,7 +373,7 @@ void CreateDirectoriesAndroid() { static void CheckFailedGPUBackends() { #ifdef _DEBUG // If you're in debug mode, you probably don't want a fallback. If you're in release mode, use IGNORE below. - WARN_LOG(LOADER, "Not checking for failed graphics backends in debug mode"); + NOTICE_LOG(LOADER, "Not checking for failed graphics backends in debug mode"); return; #endif From c0dffd56aa24ddc096b823116542c7ddaa54bb32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 16 Aug 2020 22:38:15 +0200 Subject: [PATCH 530/848] Log the first 100 block transfers instead of just the first one. Should make it easier to spot interesting things without hacking the log code. --- Core/HLE/HLE.cpp | 2 +- Core/Reporting.cpp | 17 +++++++++++--- Core/Reporting.h | 30 +++++++++++++++---------- GPU/Common/FramebufferManagerCommon.cpp | 6 ++--- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index b0b29575bb..1634895a40 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -875,7 +875,7 @@ void hleDoLogInternal(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u64 res, if (reportTag != nullptr) { // A blank string means always log, not just once. - if (reportTag[0] == '\0' || Reporting::ShouldLogOnce(reportTag)) { + if (reportTag[0] == '\0' || Reporting::ShouldLogNTimes(reportTag, 1)) { // Here we want the original key, so that different args, etc. group together. std::string key = std::string(kernelFlag) + std::string("%08x=") + funcName + "(%s)"; if (reason != nullptr) diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 0447d6adb9..28c9609b01 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -63,7 +63,7 @@ namespace Reporting // Temporarily stores a reference to the hostname. static std::string lastHostname; // Keeps track of report-only-once identifiers. Since they're always constants, a pointer is okay. - static std::set logOnceUsed; + static std::map logOnceUsed; // Keeps track of whether a harmful setting was ever used. static bool everUnsupported = false; // Support is cached here to avoid checking it on every single request. @@ -347,10 +347,21 @@ namespace Reporting everUnsupported = true; } - bool ShouldLogOnce(const char *identifier) + bool ShouldLogNTimes(const char *identifier, int count) { // True if it wasn't there already -> so yes, log. - return logOnceUsed.insert(identifier).second; + auto iter = logOnceUsed.find(identifier); + if (iter == logOnceUsed.end()) { + logOnceUsed.insert(std::pair(identifier, 1)); + return true; + } else { + if (iter->second >= count) { + return false; + } else { + iter->second++; + return true; + } + } } std::string CurrentGameID() diff --git a/Core/Reporting.h b/Core/Reporting.h index c34f815119..1d168cb88c 100644 --- a/Core/Reporting.h +++ b/Core/Reporting.h @@ -17,27 +17,33 @@ #pragma once -#include "Common/CommonTypes.h" -#include "Common/Log.h" #include #include +#include "Common/CommonTypes.h" +#include "Common/Log.h" + #define DEBUG_LOG_REPORT(t,...) do { DEBUG_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } while (false) #define ERROR_LOG_REPORT(t,...) do { ERROR_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } while (false) #define WARN_LOG_REPORT(t,...) do { WARN_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } while (false) #define NOTICE_LOG_REPORT(t,...) do { NOTICE_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } while (false) #define INFO_LOG_REPORT(t,...) do { INFO_LOG(t, __VA_ARGS__); Reporting::ReportMessage(__VA_ARGS__); } while (false) -#define DEBUG_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { DEBUG_LOG_REPORT(t, __VA_ARGS__); } } while (false) -#define ERROR_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { ERROR_LOG_REPORT(t, __VA_ARGS__); } } while (false) -#define WARN_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { WARN_LOG_REPORT(t, __VA_ARGS__); } } while (false) -#define NOTICE_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { NOTICE_LOG_REPORT(t, __VA_ARGS__); } } while (false) -#define INFO_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { INFO_LOG_REPORT(t, __VA_ARGS__); } } while (false) +#define DEBUG_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { DEBUG_LOG_REPORT(t, __VA_ARGS__); } } while (false) +#define ERROR_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { ERROR_LOG_REPORT(t, __VA_ARGS__); } } while (false) +#define WARN_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { WARN_LOG_REPORT(t, __VA_ARGS__); } } while (false) +#define NOTICE_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { NOTICE_LOG_REPORT(t, __VA_ARGS__); } } while (false) +#define INFO_LOG_REPORT_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { INFO_LOG_REPORT(t, __VA_ARGS__); } } while (false) -#define ERROR_LOG_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { ERROR_LOG(t, __VA_ARGS__); } } while (false) -#define WARN_LOG_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { WARN_LOG(t, __VA_ARGS__); } } while (false) -#define NOTICE_LOG_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { NOTICE_LOG(t, __VA_ARGS__); } } while (false) -#define INFO_LOG_ONCE(n,t,...) do { if (Reporting::ShouldLogOnce(#n)) { INFO_LOG(t, __VA_ARGS__); } } while (false) +#define ERROR_LOG_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { ERROR_LOG(t, __VA_ARGS__); } } while (false) +#define WARN_LOG_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { WARN_LOG(t, __VA_ARGS__); } } while (false) +#define NOTICE_LOG_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { NOTICE_LOG(t, __VA_ARGS__); } } while (false) +#define INFO_LOG_ONCE(n,t,...) do { if (Reporting::ShouldLogNTimes(#n, 1)) { INFO_LOG(t, __VA_ARGS__); } } while (false) + +#define ERROR_LOG_N_TIMES(s,n,t,...) do { if (Reporting::ShouldLogNTimes(#s, n)) { ERROR_LOG(t, __VA_ARGS__); } } while (false) +#define WARN_LOG_N_TIMES(s,n,t,...) do { if (Reporting::ShouldLogNTimes(#s, n)) { WARN_LOG(t, __VA_ARGS__); } } while (false) +#define NOTICE_LOG_N_TIMES(s,n,t,...) do { if (Reporting::ShouldLogNTimes(#s, n)) { NOTICE_LOG(t, __VA_ARGS__); } } while (false) +#define INFO_LOG_N_TIMES(s,n,t,...) do { if (Reporting::ShouldLogNTimes(#s, n)) { INFO_LOG(t, __VA_ARGS__); } } while (false) class PointerWrap; @@ -79,7 +85,7 @@ namespace Reporting std::vector CompatibilitySuggestions(); // Returns true if that identifier has not been logged yet. - bool ShouldLogOnce(const char *identifier); + bool ShouldLogNTimes(const char *identifier, int n); enum class ReportStatus { WORKING, diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 795a570648..8f1e56b3b2 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1566,7 +1566,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst if (dstBuffer && srcBuffer) { if (srcBuffer == dstBuffer) { if (srcX != dstX || srcY != dstY) { - WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", + WARN_LOG_N_TIMES(dstsrc, 100, G3D, "Intra-buffer block transfer %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", srcBasePtr, srcX, srcY, srcStride, dstBasePtr, dstX, dstY, dstStride, width, height, bpp); @@ -1580,7 +1580,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst return true; } } else { - WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", + WARN_LOG_N_TIMES(dstnotsrc, 100, G3D, "Inter-buffer block transfer %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", srcBasePtr, srcX, srcY, srcStride, dstBasePtr, dstX, dstY, dstStride, width, height, bpp); @@ -1596,7 +1596,7 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst // Here we should just draw the pixels into the buffer. Copy first. return false; } else if (srcBuffer) { - WARN_LOG_ONCE(btd, G3D, "Block transfer readback %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", + WARN_LOG_N_TIMES(btd, 100, G3D, "Block transfer readback %08x (x:%d y:%d stride:%d) -> %08x (x:%d y:%d stride:%d) (%dx%d %dbpp)", srcBasePtr, srcX, srcY, srcStride, dstBasePtr, dstX, dstY, dstStride, width, height, bpp); From ea376ef886241772595bec5b59cef789291d7a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 17 Aug 2020 15:39:06 +0200 Subject: [PATCH 531/848] Add support for the 8Bitdo SF30/SN30 Pro controllers on SDL. See #13034 --- assets/gamecontrollerdb.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/gamecontrollerdb.txt b/assets/gamecontrollerdb.txt index 76ba6498a5..8913052eaa 100644 --- a/assets/gamecontrollerdb.txt +++ b/assets/gamecontrollerdb.txt @@ -195,3 +195,4 @@ bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,b 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, 03000000ad1b000003f5000033050000,Hori Fighting Stick VX,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,-leftx:h0.8,+leftx:h0.2,-lefty:h0.1,+lefty:h0.4,lefttrigger:b6,righttrigger:b7, +03000000c82d00000260000011010000,8Bitdo SF30 Pro 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, From df1f126715063b671e771d779dae613fab5795dc Mon Sep 17 00:00:00 2001 From: sum2012 Date: Mon, 17 Aug 2020 23:16:15 +0800 Subject: [PATCH 532/848] Fix sceKernelExitThread fix #13297 fix #9523 According from https://github.com/jpcsp/jpcsp/blob/master/src/jpcsp/HLE/modules/ThreadManForUser.java#L3924 --- Core/HLE/sceKernel.cpp | 4 ++-- Core/HLE/sceKernelThread.cpp | 10 +++++++++- Core/HLE/sceKernelThread.h | 4 +++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 6521f3e79c..ec58221d72 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -744,7 +744,7 @@ const HLEFunction ThreadManForUser[] = {0X1181E963, &WrapI_U, "sceKernelDelaySysClockThreadCB", 'i', "P", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0XCEADEB47, &WrapI_U, "sceKernelDelayThread", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X68DA9E36, &WrapI_U, "sceKernelDelayThreadCB", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, - {0XAA73C935, &WrapV_I, "sceKernelExitThread", 'v', "i" }, + {0XAA73C935, &WrapI_I, "sceKernelExitThread", 'i', "i" }, {0X809CE29B, &WrapV_I, "sceKernelExitDeleteThread", 'v', "i" }, {0x94aa61ee, &WrapI_V, "sceKernelGetThreadCurrentPriority", 'i', "" }, {0X293B45B8, &WrapI_V, "sceKernelGetThreadId", 'i', "", HLE_NOT_IN_INTERRUPT }, @@ -887,7 +887,7 @@ const HLEFunction ThreadManForKernel[] = {0x446D8DE6, &WrapI_CUUIUU, "sceKernelCreateThread", 'i', "sxxixx", HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL }, {0xF475845D, &WrapI_IIU, "sceKernelStartThread", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL }, {0X9FA03CD3, &WrapI_I, "sceKernelDeleteThread", 'i', "i", HLE_KERNEL_SYSCALL }, - {0XAA73C935, &WrapV_I, "sceKernelExitThread", 'v', "i", HLE_KERNEL_SYSCALL }, + {0XAA73C935, &WrapI_I, "sceKernelExitThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0X809CE29B, &WrapV_I, "sceKernelExitDeleteThread", 'v', "i", HLE_KERNEL_SYSCALL }, {0X9944F31F, &WrapI_I, "sceKernelSuspendThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0X75156E8F, &WrapI_I, "sceKernelResumeThread", 'i', "i", HLE_KERNEL_SYSCALL }, diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index e995528d02..ea397162d1 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -49,6 +49,8 @@ #include "Core/HLE/KernelWaitHelpers.h" #include "Core/HLE/ThreadQueueList.h" + + typedef struct { WaitType type; @@ -2148,11 +2150,16 @@ void __KernelReturnFromThread() // The stack will be deallocated when the thread is deleted. } -void sceKernelExitThread(int exitStatus) { +int sceKernelExitThread(int exitStatus) { + if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() > 0x0307FFFF) + return ERROR_KERNEL_WAIT_CAN_NOT_WAIT; PSPThread *thread = __GetCurrentThread(); _dbg_assert_msg_(thread != NULL, "Exited from a NULL thread."); INFO_LOG(SCEKERNEL, "sceKernelExitThread(%d)", exitStatus); + if (exitStatus < 0) { + exitStatus = ERROR_KERNEL_ILLEGAL_ARGUMENT; + } __KernelStopThread(currentThread, exitStatus, "thread exited"); hleReSchedule("thread exited"); @@ -2161,6 +2168,7 @@ void sceKernelExitThread(int exitStatus) { __KernelThreadTriggerEvent((thread->nt.attr & PSP_THREAD_ATTR_KERNEL) != 0, thread->GetUID(), THREADEVENT_EXIT); // The stack will be deallocated when the thread is deleted. + return 0; } void _sceKernelExitThread(int exitStatus) { diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 5c85ba661b..37d1065a20 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -41,7 +41,7 @@ void __KernelStopThread(SceUID threadID, int exitStatus, const char *reason); u32 __KernelDeleteThread(SceUID threadID, int exitStatus, const char *reason); int sceKernelDeleteThread(int threadHandle); void sceKernelExitDeleteThread(int exitStatus); -void sceKernelExitThread(int exitStatus); +int sceKernelExitThread(int exitStatus); void _sceKernelExitThread(int exitStatus); SceUID sceKernelGetThreadId(); int sceKernelGetThreadCurrentPriority(); @@ -77,6 +77,8 @@ struct SceKernelSysClock { u32_le hi; }; +static const int ERROR_KERNEL_WAIT_CAN_NOT_WAIT = 0x800201a7; +static const int ERROR_KERNEL_ILLEGAL_ARGUMENT = 0x800200d2; // TODO: Map these to PSP wait types. Most of these are wrong. // remember to update the waitTypeNames array in sceKernelThread.cpp when changing these From dfad6cd4794c04d3512dad9ed6b1f06e37b11e33 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Mon, 17 Aug 2020 23:18:12 +0800 Subject: [PATCH 533/848] oop --- Core/HLE/sceKernelThread.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index ea397162d1..52ff9688a7 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -49,8 +49,6 @@ #include "Core/HLE/KernelWaitHelpers.h" #include "Core/HLE/ThreadQueueList.h" - - typedef struct { WaitType type; From 35c05ef06493eaed69ac734f380e330b88e6871a Mon Sep 17 00:00:00 2001 From: sum2012 Date: Tue, 18 Aug 2020 06:42:55 +0800 Subject: [PATCH 534/848] Use ppsspp error name --- Core/HLE/sceKernelThread.cpp | 4 ++-- Core/HLE/sceKernelThread.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 52ff9688a7..7e719c05e3 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2150,13 +2150,13 @@ void __KernelReturnFromThread() int sceKernelExitThread(int exitStatus) { if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() > 0x0307FFFF) - return ERROR_KERNEL_WAIT_CAN_NOT_WAIT; + return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_CAN_NOT_WAIT); PSPThread *thread = __GetCurrentThread(); _dbg_assert_msg_(thread != NULL, "Exited from a NULL thread."); INFO_LOG(SCEKERNEL, "sceKernelExitThread(%d)", exitStatus); if (exitStatus < 0) { - exitStatus = ERROR_KERNEL_ILLEGAL_ARGUMENT; + exitStatus = SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT; } __KernelStopThread(currentThread, exitStatus, "thread exited"); diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 37d1065a20..4c11a613fe 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -77,8 +77,6 @@ struct SceKernelSysClock { u32_le hi; }; -static const int ERROR_KERNEL_WAIT_CAN_NOT_WAIT = 0x800201a7; -static const int ERROR_KERNEL_ILLEGAL_ARGUMENT = 0x800200d2; // TODO: Map these to PSP wait types. Most of these are wrong. // remember to update the waitTypeNames array in sceKernelThread.cpp when changing these From a89840f309229da7a1860d3941984e1faa3bca58 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 17 Aug 2020 23:08:35 -0700 Subject: [PATCH 535/848] Net: Cut down on local IP aliasing. --- Core/HLE/proAdhoc.cpp | 22 +++++++++++----------- Core/HLE/proAdhoc.h | 7 ++++++- Core/HLE/proAdhocServer.cpp | 2 +- Core/HLE/sceNet.cpp | 12 ++++++------ 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 681e11e493..6b9621c72a 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -76,7 +76,7 @@ bool updateChatScreen = false; int newChat = 0; bool isOriPort = false; bool isLocalServer = false; -sockaddr LocalhostIP; +SockAddrIN4 g_localhostIP; sockaddr LocalIP; int defaultWlanChannel = PSP_SYSTEMPARAM_ADHOC_CHANNEL_1; // Don't put 0(Auto) here, it needed to be a valid/actual channel number @@ -1535,7 +1535,7 @@ int getLocalIp(sockaddr_in* SocketAddress) { socklen_t addrLen = sizeof(localAddr); if (SOCKET_ERROR != getsockname(metasocket, (struct sockaddr*) & localAddr, &addrLen)) { if (isLocalServer) { - localAddr.sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; + localAddr.sin_addr = g_localhostIP.in.sin_addr; } SocketAddress->sin_addr = localAddr.sin_addr; return 0; @@ -1556,7 +1556,7 @@ int getLocalIp(sockaddr_in* SocketAddress) { if (pHost) { memcpy(&SocketAddress->sin_addr, pHost->h_addr_list[0], pHost->h_length); if (isLocalServer) { - SocketAddress->sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; + SocketAddress->sin_addr = g_localhostIP.in.sin_addr; } return 0; } @@ -1580,7 +1580,7 @@ int getLocalIp(sockaddr_in* SocketAddress) { } freeifaddrs(ifAddrStruct); if (isLocalServer) { - SocketAddress->sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; + SocketAddress->sin_addr = g_localhostIP.in.sin_addr; } return 0; } @@ -1606,7 +1606,7 @@ int getLocalIp(sockaddr_in* SocketAddress) { SocketAddress->sin_addr = name.sin_addr; // May be we should cache this so it doesn't need to use connect all the time, or even better cache it when connecting to adhoc server to get an accurate IP closesocket(sock); if (isLocalServer) { - SocketAddress->sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; + SocketAddress->sin_addr = g_localhostIP.in.sin_addr; } return 0; } @@ -1623,7 +1623,7 @@ uint32_t getLocalIp(int sock) { socklen_t addrLen = sizeof(localAddr); getsockname(sock, (struct sockaddr*)&localAddr, &addrLen); if (isLocalServer) { - localAddr.sin_addr = ((sockaddr_in*)&LocalhostIP)->sin_addr; + localAddr.sin_addr = g_localhostIP.in.sin_addr; } return localAddr.sin_addr.s_addr; } @@ -1843,12 +1843,12 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ setsockopt(metasocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); setsockopt(metasocket, SOL_SOCKET, SO_DONTROUTE, (const char*)&on, sizeof(on)); - ((struct sockaddr_in*) & LocalhostIP)->sin_port = 0; + g_localhostIP.in.sin_port = 0; // Bind Local Address to Socket - iResult = bind(metasocket, (struct sockaddr*) & LocalhostIP, sizeof(sockaddr)); + iResult = bind(metasocket, &g_localhostIP.addr, sizeof(sockaddr)); if (iResult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "Bind to alternate localhost[%s] failed(%i).", inet_ntoa(((struct sockaddr_in*) & LocalhostIP)->sin_addr), iResult); - host->NotifyUserMessage(std::string(n->T("Failed to Bind Localhost IP")) + " " + inet_ntoa(((struct sockaddr_in*) & LocalhostIP)->sin_addr), 2.0, 0x0000ff); + ERROR_LOG(SCENET, "Bind to alternate localhost[%s] failed(%i).", inet_ntoa(g_localhostIP.in.sin_addr), iResult); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Localhost IP")) + " " + inet_ntoa(g_localhostIP.in.sin_addr), 2.0, 0x0000ff); } } @@ -1917,7 +1917,7 @@ bool resolveIP(uint32_t ip, SceNetEtherAddr * mac) { getLocalIp(&addr); uint32_t localIp = addr.sin_addr.s_addr; - if (ip == localIp || ip == ((sockaddr_in*)&LocalhostIP)->sin_addr.s_addr){ + if (ip == localIp || ip == g_localhostIP.in.sin_addr.s_addr) { getLocalMac(mac); return true; } diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index e5d39745ee..4657700fbe 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -829,11 +829,16 @@ extern std::recursive_mutex peerlock; extern SceNetAdhocPdpStat * pdp[255]; extern SceNetAdhocPtpStat * ptp[255]; +union SockAddrIN4 { + sockaddr addr; + sockaddr_in in; +}; + extern uint16_t portOffset; extern uint32_t minSocketTimeoutUS; extern bool isOriPort; extern bool isLocalServer; -extern sockaddr LocalhostIP; // Used to differentiate localhost IP on multiple-instance +extern SockAddrIN4 g_localhostIP; // Used to differentiate localhost IP on multiple-instance extern sockaddr LocalIP; // IP of Network Adapter used to connect to Adhoc Server (LAN/WAN) extern int defaultWlanChannel; // Default WLAN Channel for Auto, JPCSP uses 11 diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 85d4f2d56a..07ddaf29eb 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -1826,7 +1826,7 @@ int create_listen_socket(uint16_t port) //Should only bind to specific IP for the 2nd or more instance of PPSSPP to prevent communication interference issue when sharing the same port. Doesn't work well when PPSSPP_ID reseted everytime emulation restarted. /* if (PPSSPP_ID > 1) { - local.sin_addr = ((sockaddr_in *)&LocalhostIP)->sin_addr; + local.sin_addr = g_localhostIP.in.sin_addr; } */ diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 1b3f900aeb..1b848df461 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -123,19 +123,19 @@ static int InitLocalhostIP() { if (iResult != 0) { ERROR_LOG(SCENET, "DNS Error (%s) result: %d\n", ipstr, iResult); //osm.Show("DNS Error, can't resolve client bind " + ipstr, 8.0f); - ((sockaddr_in*)&LocalhostIP)->sin_family = AF_INET; - ((sockaddr_in*)&LocalhostIP)->sin_addr.s_addr = inet_addr(ipstr); //"127.0.0.1" - ((sockaddr_in*)&LocalhostIP)->sin_port = 0; + g_localhostIP.in.sin_family = AF_INET; + g_localhostIP.in.sin_addr.s_addr = inet_addr(ipstr); //"127.0.0.1" + g_localhostIP.in.sin_port = 0; return iResult; } for (ptr = localAddr; ptr != NULL; ptr = ptr->ai_next) { switch (ptr->ai_family) { case AF_INET: - memcpy(&LocalhostIP, ptr->ai_addr, sizeof(sockaddr)); + memcpy(&g_localhostIP.addr, ptr->ai_addr, sizeof(sockaddr)); break; } } - ((sockaddr_in*)&LocalhostIP)->sin_port = 0; + g_localhostIP.in.sin_port = 0; freeaddrinfo(localAddr); // Resolve server dns @@ -198,7 +198,7 @@ void __NetInit() { SceNetEtherAddr mac; getLocalMac(&mac); - INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(((sockaddr_in*)&LocalhostIP)->sin_addr), mac2str(&mac).c_str()); + INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(g_localhostIP.in.sin_addr), mac2str(&mac).c_str()); // TODO: May be we should initialize & cleanup somewhere else than here for PortManager to be used as general purpose for whatever port forwarding PPSSPP needed __UPnPInit(); From 4d307be2b2cfe31f14f080f9c25c0b070b659b20 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 17 Aug 2020 23:33:27 -0700 Subject: [PATCH 536/848] Net: Simplify local IP lookup. --- Core/HLE/sceNet.cpp | 54 ++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 1b848df461..63bd62c093 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -114,49 +114,27 @@ void AfterApctlMipsCall::SetData(int HandlerID, int OldState, int NewState, int } static int InitLocalhostIP() { - // find local IP - addrinfo* localAddr; - addrinfo* ptr; - char ipstr[256]; - sprintf(ipstr, "127.0.0.%u", PPSSPP_ID); - int iResult = getaddrinfo(ipstr, 0, NULL, &localAddr); - if (iResult != 0) { - ERROR_LOG(SCENET, "DNS Error (%s) result: %d\n", ipstr, iResult); - //osm.Show("DNS Error, can't resolve client bind " + ipstr, 8.0f); - g_localhostIP.in.sin_family = AF_INET; - g_localhostIP.in.sin_addr.s_addr = inet_addr(ipstr); //"127.0.0.1" - g_localhostIP.in.sin_port = 0; - return iResult; - } - for (ptr = localAddr; ptr != NULL; ptr = ptr->ai_next) { - switch (ptr->ai_family) { - case AF_INET: - memcpy(&g_localhostIP.addr, ptr->ai_addr, sizeof(sockaddr)); - break; - } - } + // The entire 127.*.*.* is reserved for loopback. + uint32_t localIP = 0x7F000001 + PPSSPP_ID - 1; + + g_localhostIP.in.sin_family = AF_INET; + g_localhostIP.in.sin_addr.s_addr = htonl(localIP); g_localhostIP.in.sin_port = 0; - freeaddrinfo(localAddr); - // Resolve server dns - addrinfo* resultAddr; - in_addr serverIp; - serverIp.s_addr = INADDR_NONE; + // If lookup fails, we'll assume it's not local. + isLocalServer = false; - iResult = getaddrinfo(g_Config.proAdhocServer.c_str(), 0, NULL, &resultAddr); - if (iResult != 0) { - ERROR_LOG(SCENET, "DNS Error (%s)\n", g_Config.proAdhocServer.c_str()); - return iResult; - } - for (ptr = resultAddr; ptr != NULL; ptr = ptr->ai_next) { - switch (ptr->ai_family) { - case AF_INET: - serverIp = ((sockaddr_in*)ptr->ai_addr)->sin_addr; - break; + addrinfo *resultAddr = nullptr; + std::string error; + if (net::DNSResolve(g_Config.proAdhocServer, "", &resultAddr, error, net::DNSType::IPV4)) { + for (addrinfo *ptr = resultAddr; ptr != nullptr; ptr = ptr->ai_next) { + auto addr4 = ((sockaddr_in *)ptr->ai_addr)->sin_addr.s_addr; + isLocalServer = (ntohl(addr4) & 0x7F000000) == 0x7F000000; } + + net::DNSResolveFree(resultAddr); + resultAddr = nullptr; } - freeaddrinfo(resultAddr); - isLocalServer = (((uint8_t*)&serverIp.s_addr)[0] == 0x7f); return 0; } From 5313fc5b368b8d7c92d47b0560563ae613461188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 18 Aug 2020 09:18:24 +0200 Subject: [PATCH 537/848] More work on GL state leaks. Some things really need a redesign. --- Core/HLE/sceKernel.cpp | 1 + Core/HLE/sceKernelModule.cpp | 2 +- Core/System.cpp | 6 +++--- GPU/GLES/DrawEngineGLES.cpp | 1 + UI/EmuScreen.cpp | 1 - ext/native/thin3d/GLQueueRunner.h | 1 + ext/native/thin3d/thin3d_gl.cpp | 23 +++++++++++++++++++---- 7 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 6521f3e79c..51aed70022 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -107,6 +107,7 @@ void __KernelInit() ERROR_LOG(SCEKERNEL, "Can't init kernel when kernel is running"); return; } + INFO_LOG(SCEKERNEL, "Initializing kernel..."); __KernelTimeInit(); __InterruptsInit(); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 0173045ce2..486bd06bd0 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1654,7 +1654,7 @@ void __KernelLoadReset() { bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string) { SceKernelLoadExecParam param; - PSP_SetLoading("Loading game..."); + PSP_SetLoading("Loading exec..."); if (paramPtr) Memory::ReadStruct(paramPtr, ¶m); diff --git a/Core/System.cpp b/Core/System.cpp index 29fc5e0a30..6f9b58ad7b 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -108,9 +108,9 @@ static GPUBackend gpuBackend; static std::string gpuBackendDevice; // Ugly! -static bool pspIsInited = false; -static bool pspIsIniting = false; -static bool pspIsQuitting = false; +static volatile bool pspIsInited = false; +static volatile bool pspIsIniting = false; +static volatile bool pspIsQuitting = false; void ResetUIState() { globalUIState = UISTATE_MENU; diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 215d80c07a..b07e819d43 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -314,6 +314,7 @@ void DrawEngineGLES::DoFlush() { if (lastRenderStepId_ != curRenderStepId) { // Dirty everything that has dynamic state that will need re-recording. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); + textureCache_->ForgetLastTexture(); lastRenderStepId_ = curRenderStepId; } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index a6d5b600e1..b3557c076b 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1090,7 +1090,6 @@ void EmuScreen::CreateViews() { loadingSpinner->SetTag("LoadingSpinner"); // Don't really need this, and it creates a lot of strings to translate... - // Maybe just show "Loading game..." only? loadingTextView->SetVisibility(V_GONE); loadingTextView->SetShadow(true); diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index 2c0d49fbe8..031c17b06f 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -416,6 +416,7 @@ private: GLuint currentReadHandle_ = 0; GLuint AllocTextureName(); + // Texture name cache. Ripped straight from TextureCacheGLES. std::vector nameCache_; std::unordered_map glStrings_; diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index c42b186b54..d6a2a8ee8b 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -483,14 +483,16 @@ public: private: void ApplySamplers(); + void Unbind(); GLRenderManager renderManager_; - OpenGLSamplerState *boundSamplers_[MAX_TEXTURE_SLOTS]{}; - OpenGLTexture *boundTextures_[MAX_TEXTURE_SLOTS]{}; DeviceCaps caps_{}; // Bound state + OpenGLSamplerState *boundSamplers_[MAX_TEXTURE_SLOTS]{}; + OpenGLTexture *boundTextures_[MAX_TEXTURE_SLOTS]{}; + OpenGLPipeline *curPipeline_ = nullptr; OpenGLBuffer *curVBuffers_[4]{}; int curVBufferOffsets_[4]{}; @@ -610,10 +612,14 @@ void OpenGLContext::BeginFrame() { } void OpenGLContext::EndFrame() { + Unbind(); + FrameData &frameData = frameData_[renderManager_.GetCurFrame()]; renderManager_.EndPushBuffer(frameData.push); // upload the data! renderManager_.Finish(); +} +void OpenGLContext::Unbind() { // Unbind stuff. for (auto &texture : boundTextures_) { texture = nullptr; @@ -621,6 +627,9 @@ void OpenGLContext::EndFrame() { for (auto &sampler : boundSamplers_) { sampler = nullptr; } + for (int i = 0; i < ARRAY_SIZE(boundTextures_); i++) { + renderManager_.BindTexture(i, nullptr); + } curPipeline_ = nullptr; } @@ -679,7 +688,6 @@ private: OpenGLTexture::OpenGLTexture(GLRenderManager *render, const TextureDesc &desc) : render_(render) { generatedMips_ = false; - canWrap_ = true; width_ = desc.width; height_ = desc.height; depth_ = desc.depth; @@ -1022,7 +1030,9 @@ void OpenGLContext::ApplySamplers() { for (int i = 0; i < MAX_TEXTURE_SLOTS; i++) { const OpenGLSamplerState *samp = boundSamplers_[i]; const OpenGLTexture *tex = boundTextures_[i]; - if (!samp || !tex) { + if (tex) { + _assert_(samp); + } else { continue; } GLenum wrapS; @@ -1037,6 +1047,8 @@ void OpenGLContext::ApplySamplers() { GLenum magFilt = samp->magFilt; GLenum minFilt = tex->HasMips() ? samp->mipMinFilt : samp->minFilt; renderManager_.SetTextureSampler(i, wrapS, wrapT, magFilt, minFilt, 0.0f); + // TODO: Improve this to allow mipmaps. We don't care about those right now though for thin3d stuff. + renderManager_.SetTextureLod(i, 0.0, 0.0, 0.0); } } @@ -1098,6 +1110,9 @@ void OpenGLContext::BindPipeline(Pipeline *pipeline) { curPipeline_->depthStencil->Apply(&renderManager_, stencilRef_); curPipeline_->raster->Apply(&renderManager_); renderManager_.BindProgram(curPipeline_->program_); + } else { + // Wipe bound textures and samplers. + Unbind(); } } From 06ab2159e919a08d1fb78856ccfe51491f7c5d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 18 Aug 2020 09:18:50 +0200 Subject: [PATCH 538/848] Windows: Auto-enable GL validation (debug messages) in debug builds --- Windows/GPU/WindowsGLContext.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index dc9037a783..01933b2701 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -131,8 +131,13 @@ void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenu void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) { // Ignore buffer mapping messages from NVIDIA - if (source == GL_DEBUG_SOURCE_API_ARB && type == GL_DEBUG_TYPE_OTHER_ARB && id == 131185) + if (source == GL_DEBUG_SOURCE_API_ARB && type == GL_DEBUG_TYPE_OTHER_ARB && id == 131185) { return; + } + // Ignore application messages + if (source == GL_DEBUG_SOURCE_APPLICATION) { + return; + } (void)length; FILE *outFile = (FILE *)userParam; @@ -366,7 +371,14 @@ bool WindowsGLContext::InitFromRenderThread(std::string *error_message) { hRC = m_hrc; - if (g_Config.bGfxDebugOutput) { + bool validation = g_Config.bGfxDebugOutput; + + // Always run OpenGL validation in debug mode, just like we do with Vulkan if debug layers are installed. +#ifdef _DEBUG + validation = true; +#endif + + if (validation) { if (wglewIsSupported("GL_KHR_debug") == 1) { glGetError(); glDebugMessageCallback((GLDEBUGPROC)&DebugCallbackARB, nullptr); From 495996e58bcc65807bf1b34bfd6c7c737f6b014c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 18 Aug 2020 00:47:22 -0700 Subject: [PATCH 539/848] Windows: Make the instance counter go by 1, 2, 3. --- Core/Config.cpp | 12 +++++++++--- Core/Config.h | 3 ++- Windows/main.cpp | 27 ++++++++++++++++----------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index f7fd8e9af9..0a2355e5fc 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1117,12 +1117,13 @@ static void IterateSettings(IniFile &iniFile, std::function> GetLangValuesMapping() { @@ -1173,6 +1174,11 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { const bool useIniFilename = iniFileName != nullptr && strlen(iniFileName) > 0; iniFilename_ = FindConfigFile(useIniFilename ? iniFileName : "ppsspp.ini"); + if (!bUpdatedInstanceCounter) { + InitInstanceCounter(); + bUpdatedInstanceCounter = true; + } + const bool useControllerIniFilename = controllerIniFilename != nullptr && strlen(controllerIniFilename) > 0; controllerIniFilename_ = FindConfigFile(useControllerIniFilename ? controllerIniFilename : "controls.ini"); diff --git a/Core/Config.h b/Core/Config.h index 71fa93e357..3072efdbc3 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -61,7 +61,8 @@ public: // Whether to save the config on close. bool bSaveSettings; bool bFirstRun; - bool bGameSpecific; + bool bGameSpecific = false; + bool bUpdatedInstanceCounter = false; int iRunCount; // To be used to for example check for updates every 10 runs and things like that. diff --git a/Windows/main.cpp b/Windows/main.cpp index 50cd28534b..7ee603d783 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -516,6 +516,22 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin g_Config.internalDataDirectory = W32Util::UserDocumentsPath(); InitSysDirectories(); + // Check for the Vulkan workaround before any serious init. + for (size_t i = 1; i < wideArgs.size(); ++i) { + if (wideArgs[i][0] == L'-') { + // This should only be called by DetectVulkanInExternalProcess(). + if (wideArgs[i] == L"--vulkan-available-check") { + // Just call it, this way it will crash here if it doesn't work. + // (this is an external process.) + bool result = VulkanMayBeAvailable(); + + LogManager::Shutdown(); + WinMainCleanup(); + return result ? EXIT_CODE_VULKAN_WORKS : EXIT_FAILURE; + } + } + } + // Load config up here, because those changes below would be overwritten // if it's not loaded here first. g_Config.AddSearchPath(""); @@ -574,17 +590,6 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin g_Config.bSoftwareRendering = true; } } - - // This should only be called by DetectVulkanInExternalProcess(). - if (wideArgs[i] == L"--vulkan-available-check") { - // Just call it, this way it will crash here if it doesn't work. - // (this is an external process.) - bool result = VulkanMayBeAvailable(); - - LogManager::Shutdown(); - WinMainCleanup(); - return result ? EXIT_CODE_VULKAN_WORKS : EXIT_FAILURE; - } } } #ifdef _DEBUG From 06a528927e61e1bf5a14945202a85766fb3952f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 18 Aug 2020 12:57:33 +0200 Subject: [PATCH 540/848] GL: Re-enable mipmaps for thin3d textures. --- ext/native/thin3d/thin3d_gl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index d6a2a8ee8b..3a7c0f958c 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -672,6 +672,9 @@ public: void Bind(int stage) { render_->BindTexture(stage, tex_); } + int NumMipmaps() const { + return mipLevels_; + } private: void SetImageData(int x, int y, int z, int width, int height, int depth, int level, int stride, const uint8_t *data, TextureCallback callback); @@ -1047,8 +1050,7 @@ void OpenGLContext::ApplySamplers() { GLenum magFilt = samp->magFilt; GLenum minFilt = tex->HasMips() ? samp->mipMinFilt : samp->minFilt; renderManager_.SetTextureSampler(i, wrapS, wrapT, magFilt, minFilt, 0.0f); - // TODO: Improve this to allow mipmaps. We don't care about those right now though for thin3d stuff. - renderManager_.SetTextureLod(i, 0.0, 0.0, 0.0); + renderManager_.SetTextureLod(i, 0.0, (float)(tex->NumMipmaps() - 1), 0.0); } } From 80283d32307736aed06c78dbb550a1b46afa2416 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Tue, 18 Aug 2020 21:03:45 +0800 Subject: [PATCH 541/848] Add a check in sceKernelExitDeleteThread --- Core/HLE/sceKernel.cpp | 4 ++-- Core/HLE/sceKernelThread.cpp | 5 ++++- Core/HLE/sceKernelThread.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 189337c0c1..42acf6f118 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -746,7 +746,7 @@ const HLEFunction ThreadManForUser[] = {0XCEADEB47, &WrapI_U, "sceKernelDelayThread", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X68DA9E36, &WrapI_U, "sceKernelDelayThreadCB", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0XAA73C935, &WrapI_I, "sceKernelExitThread", 'i', "i" }, - {0X809CE29B, &WrapV_I, "sceKernelExitDeleteThread", 'v', "i" }, + {0X809CE29B, &WrapI_I, "sceKernelExitDeleteThread", 'v', "i" }, {0x94aa61ee, &WrapI_V, "sceKernelGetThreadCurrentPriority", 'i', "" }, {0X293B45B8, &WrapI_V, "sceKernelGetThreadId", 'i', "", HLE_NOT_IN_INTERRUPT }, {0X3B183E26, &WrapI_I, "sceKernelGetThreadExitStatus", 'i', "i" }, @@ -889,7 +889,7 @@ const HLEFunction ThreadManForKernel[] = {0xF475845D, &WrapI_IIU, "sceKernelStartThread", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL }, {0X9FA03CD3, &WrapI_I, "sceKernelDeleteThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0XAA73C935, &WrapI_I, "sceKernelExitThread", 'i', "i", HLE_KERNEL_SYSCALL }, - {0X809CE29B, &WrapV_I, "sceKernelExitDeleteThread", 'v', "i", HLE_KERNEL_SYSCALL }, + {0X809CE29B, &WrapI_I, "sceKernelExitDeleteThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0X9944F31F, &WrapI_I, "sceKernelSuspendThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0X75156E8F, &WrapI_I, "sceKernelResumeThread", 'i', "i", HLE_KERNEL_SYSCALL }, {0X94416130, &WrapU_UUUU, "sceKernelGetThreadmanIdList", 'x', "xxxx", HLE_KERNEL_SYSCALL }, diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 7e719c05e3..c8f1c4216f 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2184,7 +2184,9 @@ void _sceKernelExitThread(int exitStatus) { // The stack will be deallocated when the thread is deleted. } -void sceKernelExitDeleteThread(int exitStatus) { +int sceKernelExitDeleteThread(int exitStatus) { + if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() > 0x0307FFFF) + return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_CAN_NOT_WAIT); PSPThread *thread = __GetCurrentThread(); if (thread) { @@ -2202,6 +2204,7 @@ void sceKernelExitDeleteThread(int exitStatus) { } else ERROR_LOG_REPORT(SCEKERNEL, "sceKernelExitDeleteThread(%d) ERROR - could not find myself!", exitStatus); + return 0; } u32 sceKernelSuspendDispatchThread() diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 4c11a613fe..d36e12c986 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -40,7 +40,7 @@ int sceKernelDelaySysClockThreadCB(u32 sysclockAddr); void __KernelStopThread(SceUID threadID, int exitStatus, const char *reason); u32 __KernelDeleteThread(SceUID threadID, int exitStatus, const char *reason); int sceKernelDeleteThread(int threadHandle); -void sceKernelExitDeleteThread(int exitStatus); +int sceKernelExitDeleteThread(int exitStatus); int sceKernelExitThread(int exitStatus); void _sceKernelExitThread(int exitStatus); SceUID sceKernelGetThreadId(); From 3f6c80fb074e246fbf5cc0a6243f4906c882ad18 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Tue, 18 Aug 2020 21:22:12 +0800 Subject: [PATCH 542/848] Small mistake in sceKernelExitDeleteThread oop --- Core/HLE/sceKernel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 42acf6f118..971a9c728b 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -746,7 +746,7 @@ const HLEFunction ThreadManForUser[] = {0XCEADEB47, &WrapI_U, "sceKernelDelayThread", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X68DA9E36, &WrapI_U, "sceKernelDelayThreadCB", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0XAA73C935, &WrapI_I, "sceKernelExitThread", 'i', "i" }, - {0X809CE29B, &WrapI_I, "sceKernelExitDeleteThread", 'v', "i" }, + {0X809CE29B, &WrapI_I, "sceKernelExitDeleteThread", 'i', "i" }, {0x94aa61ee, &WrapI_V, "sceKernelGetThreadCurrentPriority", 'i', "" }, {0X293B45B8, &WrapI_V, "sceKernelGetThreadId", 'i', "", HLE_NOT_IN_INTERRUPT }, {0X3B183E26, &WrapI_I, "sceKernelGetThreadExitStatus", 'i', "i" }, From 60801e066fa0aa1e8fd3d0ffd66c18a0c7c282ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 18 Aug 2020 15:31:16 +0200 Subject: [PATCH 543/848] Improve JPEG file detection (mainly for background image use) --- UI/TextureUtil.cpp | 5 ++++- Windows/MainWindowMenu.cpp | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index eaf2b82faf..7fac93cc5c 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -25,13 +25,16 @@ static Draw::DataFormat ZimToT3DFormat(int zim) { } static ImageFileType DetectImageFileType(const uint8_t *data, size_t size) { + if (size < 4) { + return TYPE_UNKNOWN; + } if (!memcmp(data, "ZIMG", 4)) { return ZIM; } else if (!memcmp(data, "\x89\x50\x4E\x47", 4)) { return PNG; } - else if (!memcmp(data, "\xff\xd8\xff\xe0", 4)) { + else if (!memcmp(data, "\xff\xd8\xff\xe0", 4) || !memcmp(data, "\xff\xd8\xff\xe1", 4)) { return JPEG; } else { diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index fcc1b2528d..858a4e919f 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -399,14 +399,14 @@ namespace MainWindow { } void BrowseBackground() { - static std::wstring filter = L"All supported images (*.jpg *.png)|*.jpg;*.png|All files (*.*)|*.*||"; + static std::wstring filter = L"All supported images (*.jpg *.jpeg *.png)|*.jpg;*.jpeg;*.png|All files (*.*)|*.*||"; for (size_t i = 0; i < filter.length(); i++) { if (filter[i] == '|') filter[i] = '\0'; } W32Util::MakeTopMost(GetHWND(), false); - browseImageDialog = new W32Util::AsyncBrowseDialog(W32Util::AsyncBrowseDialog::OPEN, GetHWND(), WM_USER_BROWSE_BG_DONE, L"LoadFile", L"", filter, L"*.jpg;*.png;"); + browseImageDialog = new W32Util::AsyncBrowseDialog(W32Util::AsyncBrowseDialog::OPEN, GetHWND(), WM_USER_BROWSE_BG_DONE, L"LoadFile", L"", filter, L"*.jpg;*.jpeg;*.png;"); } void BrowseBackgroundDone() { @@ -414,7 +414,7 @@ namespace MainWindow { if (browseImageDialog->GetResult(filename)) { std::wstring src = ConvertUTF8ToWString(filename); std::wstring dest; - if (filename.size() >= 4 && filename.substr(filename.size() - 4) == ".jpg") { + if (filename.size() >= 5 && (filename.substr(filename.size() - 4) == ".jpg" || filename.substr(filename.size() - 5) == ".jpeg")) { dest = ConvertUTF8ToWString(GetSysDirectory(DIRECTORY_SYSTEM) + "background.jpg"); } else { dest = ConvertUTF8ToWString(GetSysDirectory(DIRECTORY_SYSTEM) + "background.png"); From 09a3d1f7cb74924272a2ec29c3c99df438deed2c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 18 Aug 2020 00:48:24 -0700 Subject: [PATCH 544/848] Net: Use locking consistently for instance counter. --- Core/Instance.cpp | 144 +++++++++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 58 deletions(-) diff --git a/Core/Instance.cpp b/Core/Instance.cpp index 8d8554629a..58673a6483 100644 --- a/Core/Instance.cpp +++ b/Core/Instance.cpp @@ -37,14 +37,74 @@ uint8_t PPSSPP_ID = 0; #if PPSSPP_PLATFORM(WINDOWS) -static HANDLE hIDMapFile = NULL; +static HANDLE hIDMapFile = nullptr; +static HANDLE mapLock = nullptr; #else -static int hIDMapFile = 0; +static int hIDMapFile = -1; +static long BUF_SIZE = 4096; #endif -static int32_t* pIDBuf = NULL; +struct InstanceInfo { + uint8_t pad[2]; + uint8_t next; + uint8_t total; +}; + #define ID_SHM_NAME "/PPSSPP_ID" +static bool UpdateInstanceCounter(void (*callback)(volatile InstanceInfo *)) { +#if PPSSPP_PLATFORM(WINDOWS) + if (!hIDMapFile) { + return false; + } + InstanceInfo *buf = (InstanceInfo *)MapViewOfFile(hIDMapFile, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + sizeof(InstanceInfo)); + + if (!buf) { + ERROR_LOG(SCENET, "Could not map view of file %s (%d).", ID_SHM_NAME, GetLastError()); + return false; + } + + bool result = false; + if (!mapLock || WaitForSingleObject(mapLock, INFINITE) == 0) { + callback(buf); + if (mapLock) { + ReleaseMutex(mapLock); + } + result = true; + } + UnmapViewOfFile(buf); + + return result; +#elif PPSSPP_PLATFORM(ANDROID) || defined(__LIBRETRO__) + // TODO: replace shm_open & shm_unlink with ashmem or android-shmem + return false; +#else + if (hIDMapFile < 0) { + return false; + } + + InstanceInfo *buf = (InstanceInfo *)mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hIDMapFile, 0); + if (buf == MAP_FAILED) { + ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME); + return false; + } + + bool result = false; + if (mlock(buf, BUF_SIZE) == 0) { + callback(buf); + munlock(buf, BUF_SIZE); + result = true; + } + + munmap(buf, BUF_SIZE); + return result; +#endif +} + // Get current number of instance of PPSSPP running. // Must be called only once during init. void InitInstanceCounter() { @@ -56,6 +116,8 @@ void InitInstanceCounter() { int gran = sysInfo.dwAllocationGranularity ? sysInfo.dwAllocationGranularity : 0x10000; BUF_SIZE = (BUF_SIZE + gran - 1) & ~(gran - 1); + mapLock = CreateMutex(nullptr, FALSE, L"PPSSPP_ID_mutex"); + hIDMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file NULL, // default security @@ -65,89 +127,55 @@ void InitInstanceCounter() { TEXT(ID_SHM_NAME)); // name of mapping object DWORD lasterr = GetLastError(); - if (hIDMapFile == NULL) - { + if (!hIDMapFile) { ERROR_LOG(SCENET, "Could not create %s file mapping object (%d).", ID_SHM_NAME, lasterr); PPSSPP_ID = 1; return; } - - pIDBuf = (int32_t*)MapViewOfFile(hIDMapFile, // handle to map object - FILE_MAP_ALL_ACCESS, // read/write permission - 0, - 0, - sizeof(int32_t)); //BUF_SIZE - - if (pIDBuf == NULL) { - ERROR_LOG(SCENET, "Could not map view of file %s (%d).", ID_SHM_NAME, GetLastError()); - //CloseHandle(hIDMapFile); - PPSSPP_ID = 1; - return; - } - - (*pIDBuf)++; - int id = *pIDBuf; - UnmapViewOfFile(pIDBuf); - //CloseHandle(hIDMapFile); //Should be called when program exits - //hIDMapFile = NULL; - - PPSSPP_ID = id; #elif PPSSPP_PLATFORM(ANDROID) || defined(__LIBRETRO__) // TODO : replace shm_open & shm_unlink with ashmem or android-shmem - PPSSPP_ID = 1; #else - long BUF_SIZE = 4096; - //caddr_t pIDBuf; - int status; - - // Create shared memory object - + // Create shared memory object hIDMapFile = shm_open(ID_SHM_NAME, O_CREAT | O_RDWR, 0); BUF_SIZE = (BUF_SIZE < sysconf(_SC_PAGE_SIZE)) ? sysconf(_SC_PAGE_SIZE) : BUF_SIZE; - if ((ftruncate(hIDMapFile, BUF_SIZE)) == -1) { // Set the size + if (hIDMapFile < 0 || (ftruncate(hIDMapFile, BUF_SIZE)) == -1) { // Set the size ERROR_LOG(SCENET, "ftruncate(%s) failure.", ID_SHM_NAME); PPSSPP_ID = 1; return; } - - pIDBuf = (int32_t*)mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hIDMapFile, 0); - if (pIDBuf == MAP_FAILED) { // Set the size - ERROR_LOG(SCENET, "mmap(%s) failure.", ID_SHM_NAME); - pIDBuf = NULL; - PPSSPP_ID = 1; - return; - } - - int id = 1; - if (mlock(pIDBuf, BUF_SIZE) == 0) { - (*pIDBuf)++; - id = *pIDBuf; - munlock(pIDBuf, BUF_SIZE); - } - - status = munmap(pIDBuf, BUF_SIZE); // Unmap the page - //status = close(hIDMapFile); // Close file, should be called when program exits? - //status = shm_unlink(ID_SHM_NAME); // Unlink [& delete] shared-memory object, should be called when program exits - - PPSSPP_ID = id; #endif + + bool success = UpdateInstanceCounter([](volatile InstanceInfo *buf) { + PPSSPP_ID = ++buf->next; + buf->total++; + }); + if (!success) { + PPSSPP_ID = 1; + } } void ShutdownInstanceCounter() { + UpdateInstanceCounter([](volatile InstanceInfo *buf) { + buf->total--; + }); + #if PPSSPP_PLATFORM(WINDOWS) if (hIDMapFile) { CloseHandle(hIDMapFile); // If program exited(or crashed?) or the last handle reference closed the shared memory object will be deleted. hIDMapFile = nullptr; } + if (mapLock) { + CloseHandle(mapLock); + mapLock = nullptr; + } #elif PPSSPP_PLATFORM(ANDROID) || defined(__LIBRETRO__) // Do nothing #else - // TODO : This unlink should be called when program exits instead of everytime the game reset. - if (hIDMapFile != 0) { + if (hIDMapFile >= 0) { close(hIDMapFile); shm_unlink(ID_SHM_NAME); // If program exited or crashed before unlinked the shared memory object and it's contents will persist. - hIDMapFile = 0; + hIDMapFile = -1; } #endif } From b0ca6354147c61fcb75345549b4eaa65b57d9dbe Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 18 Aug 2020 01:07:12 -0700 Subject: [PATCH 545/848] Windows: Show instance counter only with peers. --- Core/Instance.cpp | 8 ++++++++ Core/Instance.h | 1 + Windows/MainWindow.cpp | 12 +++++++++++- Windows/WindowsHost.cpp | 10 +++++++--- Windows/WindowsHost.h | 2 ++ 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Core/Instance.cpp b/Core/Instance.cpp index 58673a6483..8084c2ff25 100644 --- a/Core/Instance.cpp +++ b/Core/Instance.cpp @@ -105,6 +105,14 @@ static bool UpdateInstanceCounter(void (*callback)(volatile InstanceInfo *)) { #endif } +int GetInstancePeerCount() { + static int c = 0; + UpdateInstanceCounter([](volatile InstanceInfo *buf) { + c = buf->total; + }); + return c; +} + // Get current number of instance of PPSSPP running. // Must be called only once during init. void InitInstanceCounter() { diff --git a/Core/Instance.h b/Core/Instance.h index 5fdfd8106c..12f6518f10 100644 --- a/Core/Instance.h +++ b/Core/Instance.h @@ -25,6 +25,7 @@ extern uint8_t PPSSPP_ID; void InitInstanceCounter(); void ShutdownInstanceCounter(); +int GetInstancePeerCount(); inline bool IsFirstInstance() { return PPSSPP_ID == 1; diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 59f6820aa5..a6ba627622 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -46,6 +46,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Debugger/SymbolMap.h" +#include "Core/Instance.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Windows/InputBox.h" @@ -466,7 +467,11 @@ namespace MainWindow void UpdateWindowTitle() { // Seems to be fine to call now since we use a UNICODE build... - SetWindowText(hwndMain, windowTitle.c_str()); + std::wstring title = windowTitle; + if (PPSSPP_ID >= 1 && GetInstancePeerCount() > 1) { + title.append(ConvertUTF8ToWString(StringFromFormat(" (instance: %d)", (int)PPSSPP_ID))); + } + SetWindowText(hwndMain, title.c_str()); } void SetWindowTitle(const wchar_t *title) { @@ -708,6 +713,7 @@ namespace MainWindow case WM_ACTIVATE: { + UpdateWindowTitle(); bool pause = true; if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) { WindowsRawInput::GainFocus(); @@ -741,6 +747,10 @@ namespace MainWindow } break; + case WM_SETFOCUS: + UpdateWindowTitle(); + break; + case WM_ERASEBKGND: // This window is always covered by DisplayWindow. No reason to erase. return 1; diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index f0735eb202..e197877ce7 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -170,9 +170,7 @@ void WindowsHost::SetWindowTitle(const char *message) { #ifdef _DEBUG winTitle.append(L" (debug)"); #endif - if (PPSSPP_ID >= 1) { - winTitle.append(ConvertUTF8ToWString(StringFromFormat(" (instance: %d)", (int)PPSSPP_ID))); - } + lastTitle_ = winTitle; MainWindow::SetWindowTitle(winTitle.c_str()); PostMessage(mainWindow_, MainWindow::WM_USER_WINDOW_TITLE_CHANGED, 0, 0); @@ -194,6 +192,12 @@ void WindowsHost::ShutdownSound() { void WindowsHost::UpdateUI() { PostMessage(mainWindow_, MainWindow::WM_USER_UPDATE_UI, 0, 0); + + int peers = GetInstancePeerCount(); + if (PPSSPP_ID >= 1 && peers != lastNumInstances_) { + lastNumInstances_ = peers; + PostMessage(mainWindow_, MainWindow::WM_USER_WINDOW_TITLE_CHANGED, 0, 0); + } } void WindowsHost::UpdateMemView() { diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h index 3aadb76dc8..7c96fe6631 100644 --- a/Windows/WindowsHost.h +++ b/Windows/WindowsHost.h @@ -73,6 +73,8 @@ private: HWND mainWindow_; GraphicsContext *gfx_ = nullptr; size_t numDinputDevices_ = 0; + std::wstring lastTitle_; + int lastNumInstances_ = 0; std::list> input; }; From 31830dd4df457b0099bfcb80b9f1d7ad6f69e32b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 18 Aug 2020 01:07:51 -0700 Subject: [PATCH 546/848] native: Minor header cleanup. --- ext/native/net/resolve.h | 4 ---- ext/native/ui/ui_context.cpp | 1 + ext/native/ui/ui_context.h | 6 +++++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ext/native/net/resolve.h b/ext/native/net/resolve.h index 8cc9756392..882ed5c0d5 100644 --- a/ext/native/net/resolve.h +++ b/ext/native/net/resolve.h @@ -11,10 +11,6 @@ namespace net { void Init(); void Shutdown(); -// use free() to free the returned string. -char *DNSResolveTry(const char *host, const char **err); -char *DNSResolve(const char *host); - enum class DNSType { ANY = 0, IPV4 = 1, diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index 22cc79c24b..be30e861ca 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -12,6 +12,7 @@ #include "gfx_es2/draw_text.h" #include "Common/Log.h" +#include "UI/TextureUtil.h" UIContext::UIContext() { fontStyle_ = new UI::FontStyle(); diff --git a/ext/native/ui/ui_context.h b/ext/native/ui/ui_context.h index effc248136..b6d9dd3e43 100644 --- a/ext/native/ui/ui_context.h +++ b/ext/native/ui/ui_context.h @@ -1,12 +1,12 @@ #pragma once +#include #include #include "base/basictypes.h" #include "math/geom2d.h" #include "math/lin/vec3.h" #include "gfx/texture_atlas.h" -#include "UI/TextureUtil.h" // Everything you need to draw a UI collected into a single unit that can be passed around. // Everything forward declared so this header is safe everywhere. @@ -22,13 +22,17 @@ namespace Draw { } class Texture; +class ManagedTexture; class DrawBuffer; class TextDrawer; namespace UI { struct Drawable; + struct EventParams; struct Theme; struct FontStyle; + class Event; + class View; } class DrawBuffer; From 1e2a904fb77341cb31f8d0e6caf3a745b6df3923 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 18 Aug 2020 07:21:11 -0700 Subject: [PATCH 547/848] Audiocodec: Fix warning on older clang. --- Core/HLE/sceAudiocodec.cpp | 5 +++-- Core/HLE/sceNet.h | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index d21be884b8..21d643e1fc 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -184,7 +184,8 @@ void __sceAudiocodecDoState(PointerWrap &p){ // These sizeof(pointers) are wrong, but kept to avoid breaking on old saves. // They're not used in new savestates. #ifdef __clang__ -#pragma diagnostic push +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma clang diagnostic ignored "-Wsizeof-pointer-div" #endif DoArray(p, codec_, s >= 2 ? count : (int)ARRAY_SIZE(codec_)); @@ -195,7 +196,7 @@ void __sceAudiocodecDoState(PointerWrap &p){ audioList[ctxPtr_[i]] = decoder; } #ifdef __clang__ -#pragma diagnostic pop +#pragma clang diagnostic pop #endif delete[] codec_; delete[] ctxPtr_; diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index a4a2f52788..8374a878ff 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -240,4 +240,3 @@ int sceNetApctlConnect(int connIndex); int sceNetInetPoll(void *fds, u32 nfds, int timeout); int sceNetInetTerm(); int sceNetApctlTerm(); -static u32 sceNetTerm(); From 0298f59fd501ae4d2d58139d61f94643150b95f2 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 19 Aug 2020 12:33:20 +0700 Subject: [PATCH 548/848] Avoid using getaddrinfo during initialization as it could blocked the thread if there is no network --- Core/HLE/sceNet.cpp | 20 +++----------------- UI/GameSettingsScreen.cpp | 2 +- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 63bd62c093..0b4d7ffd29 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -113,7 +113,7 @@ void AfterApctlMipsCall::SetData(int HandlerID, int OldState, int NewState, int argsAddr = ArgsAddr; } -static int InitLocalhostIP() { +void InitLocalhostIP() { // The entire 127.*.*.* is reserved for loopback. uint32_t localIP = 0x7F000001 + PPSSPP_ID - 1; @@ -121,22 +121,8 @@ static int InitLocalhostIP() { g_localhostIP.in.sin_addr.s_addr = htonl(localIP); g_localhostIP.in.sin_port = 0; - // If lookup fails, we'll assume it's not local. - isLocalServer = false; - - addrinfo *resultAddr = nullptr; - std::string error; - if (net::DNSResolve(g_Config.proAdhocServer, "", &resultAddr, error, net::DNSType::IPV4)) { - for (addrinfo *ptr = resultAddr; ptr != nullptr; ptr = ptr->ai_next) { - auto addr4 = ((sockaddr_in *)ptr->ai_addr)->sin_addr.s_addr; - isLocalServer = (ntohl(addr4) & 0x7F000000) == 0x7F000000; - } - - net::DNSResolveFree(resultAddr); - resultAddr = nullptr; - } - - return 0; + std::string serverStr = StripSpaces(g_Config.proAdhocServer); + isLocalServer = (!strcasecmp(serverStr.c_str(), "localhost") || serverStr.find("127.") == 0); } void __NetApctlInit() { diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 7b2a2b8793..57a20f7ab7 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -1930,7 +1930,7 @@ bool HostnameSelectScreen::CanComplete(DialogResult result) { void HostnameSelectScreen::OnCompleted(DialogResult result) { if (result == DR_OK) - *value_ = addrView_->GetText(); + *value_ = StripSpaces(addrView_->GetText()); } SettingInfoMessage::SettingInfoMessage(int align, UI::AnchorLayoutParams *lp) From d7fa5928d4f7ff7d8b62d4619c987aa1808f5007 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 19 Aug 2020 20:56:05 -0700 Subject: [PATCH 549/848] Kernel: Avoid two different Heap structs. --- Core/HLE/sceHeap.cpp | 4 ++-- Core/HLE/sceKernelHeap.cpp | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Core/HLE/sceHeap.cpp b/Core/HLE/sceHeap.cpp index 0de98e1443..e1c802b149 100644 --- a/Core/HLE/sceHeap.cpp +++ b/Core/HLE/sceHeap.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeMap.h" @@ -25,7 +26,6 @@ #include "Core/HLE/sceKernelMemory.h" #include "Core/HLE/sceHeap.h" #include "Core/Util/BlockAllocator.h" -#include struct Heap { Heap() : alloc(4) {} @@ -43,7 +43,7 @@ struct Heap { } }; -std::map heapList; +static std::map heapList; static Heap *getHeap(u32 addr) { auto found = heapList.find(addr); diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index 0399f3a0a6..af2cbdff1d 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -9,10 +9,14 @@ #include "Core/HLE/sceKernelMemory.h" #include "Core/Util/BlockAllocator.h" -static const u32 HEAP_BLOCK_HEADER_SIZE = 8; +static const u32 KERNEL_HEAP_BLOCK_HEADER_SIZE = 8; static const bool g_fromBottom = false; -struct Heap : public KernelObject { +// This object and the functions here are available for kernel code only, not game code. +// This differs from code like sceKernelMutex, which is available for games. +// This exists in PPSSPP mainly because certain game patches use these kernel modules. + +struct KernelHeap : public KernelObject { int uid = 0; int partitionId = 0; u32 size = 0; @@ -48,7 +52,7 @@ static int sceKernelCreateHeap(int partitionId, int size, int flags, const char return SCE_KERNEL_ERROR_NO_MEMORY; // Blind guess } - Heap *heap = new Heap(); + KernelHeap *heap = new KernelHeap(); SceUID uid = kernelObjects.Create(heap); heap->partitionId = partitionId; @@ -63,10 +67,10 @@ static int sceKernelCreateHeap(int partitionId, int size, int flags, const char static int sceKernelAllocHeapMemory(int heapId, int size) { u32 error; - Heap *heap = kernelObjects.Get(heapId, error); + KernelHeap *heap = kernelObjects.Get(heapId, error); if (heap) { // There's 8 bytes at the end of every block, reserved. - u32 memSize = HEAP_BLOCK_HEADER_SIZE + size; + u32 memSize = KERNEL_HEAP_BLOCK_HEADER_SIZE + size; u32 addr = heap->alloc.Alloc(memSize, true); return hleLogSuccessInfoX(SCEKERNEL, addr); } else { @@ -76,10 +80,10 @@ static int sceKernelAllocHeapMemory(int heapId, int size) { static int sceKernelDeleteHeap(int heapId) { u32 error; - Heap *heap = kernelObjects.Get(heapId, error); + KernelHeap *heap = kernelObjects.Get(heapId, error); if (heap) { userMemory.Free(heap->address); - kernelObjects.Destroy(heap->uid); + kernelObjects.Destroy(heap->uid); return hleLogSuccessInfoX(SCEKERNEL, 0); } else { return hleLogError(SCEKERNEL, error, "sceKernelDeleteHeap(%d): invalid heapId", heapId); From 3055deeba6de432d6b4f7cda160b5143d83d33a0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 19 Aug 2020 21:18:44 -0700 Subject: [PATCH 550/848] GPU: Fix some case warnings. Better to avoid the warnings. --- GPU/Common/FramebufferManagerCommon.cpp | 1 + GPU/Common/GPUStateUtils.cpp | 1 + GPU/GLES/StencilBufferGLES.cpp | 4 +++- GPU/Software/Rasterizer.cpp | 3 +++ GPU/Vulkan/StencilBufferVulkan.cpp | 4 +++- 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 8f1e56b3b2..4ebc279948 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -754,6 +754,7 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G break; case GE_FORMAT_INVALID: + case GE_FORMAT_DEPTH16: _dbg_assert_msg_(false, "Invalid pixelFormat passed to DrawPixels()."); break; } diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 2f629b1b89..62cd71757a 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -226,6 +226,7 @@ StencilValueType ReplaceAlphaWithStencilType() { case GE_FORMAT_4444: case GE_FORMAT_8888: case GE_FORMAT_INVALID: + case GE_FORMAT_DEPTH16: switch (gstate.getStencilOpZPass()) { case GE_STENCILOP_REPLACE: // TODO: Could detect zero here and force ZERO - less uniform updates? diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index ab843c5059..8ca12e5c09 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -109,7 +109,9 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo values = 256; break; case GE_FORMAT_INVALID: - // Impossible. + case GE_FORMAT_DEPTH16: + // Inconceivable. + _assert_(false); break; } diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index f7897008f2..9933fac43e 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -268,6 +268,7 @@ static inline u32 GetPixelColor(int x, int y) return fb.Get32(x, y, gstate.FrameBufStride()); case GE_FORMAT_INVALID: + case GE_FORMAT_DEPTH16: _dbg_assert_msg_(false, "Software: invalid framebuf format."); } return 0; @@ -293,6 +294,7 @@ static inline void SetPixelColor(int x, int y, u32 value) break; case GE_FORMAT_INVALID: + case GE_FORMAT_DEPTH16: _dbg_assert_msg_(false, "Software: invalid framebuf format."); } } @@ -1498,6 +1500,7 @@ void ClearRectangle(const VertexData &v0, const VertexData &v1) break; case GE_FORMAT_INVALID: + case GE_FORMAT_DEPTH16: _dbg_assert_msg_(false, "Software: invalid framebuf format."); break; } diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index e655780476..5862ece18f 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -140,7 +140,9 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp values = 256; break; case GE_FORMAT_INVALID: - // Impossible. + case GE_FORMAT_DEPTH16: + // Inconceivable. + _assert_(false); break; } From 631924f3e0e9a34e99ac7aa94231adb0b86efdf6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 19 Aug 2020 21:35:31 -0700 Subject: [PATCH 551/848] UI: Split chat lines using Unicode. --- UI/ChatScreen.cpp | 71 +++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index aa5478befe..9f498d8c8f 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -1,18 +1,16 @@ +#include #include "ppsspp_config.h" +#include "i18n/i18n.h" #include "ui/root.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "ui/ui.h" -#include "ChatScreen.h" -#include "Core/Config.h" -#include "Core/Host.h" -#include "Core/System.h" -#include "Common/LogManager.h" -#include "Core/HLE/proAdhoc.h" -#include "i18n/i18n.h" -#include #include "util/text/utf8.h" +#include "Core/Config.h" +#include "Core/System.h" +#include "Core/HLE/proAdhoc.h" +#include "UI/ChatScreen.h" void ChatMenu::CreatePopupContents(UI::ViewGroup *parent) { using namespace UI; @@ -167,29 +165,43 @@ UI::EventReturn ChatMenu::OnQuickChat5(UI::EventParams &e) { */ std::vector Split(const std::string& str) { - std::vector ret; - int counter = 0; - int firstSentenceEnd = 0; - int secondSentenceEnd = 0; - int spliton = 45; + static const int spliton = 45; - for (int i = 0; i<(int)str.length(); i++) { - if (isspace(str[i])) { - if (i < spliton) { - if(str[i-1]!=':') - firstSentenceEnd = i+1; + int firstSentenceEnd = 0; + int splitCharStart = 0; + + uint32_t lastc = -1; + int i = 0; + if ((int)str.length() > spliton) { + for (UTF8 utf(str.c_str()); utf.byteIndex() < (int)str.length(); ++i) { + uint32_t c = utf.next(); + if (isspace(c)) { + if (i < spliton) { + if (lastc != ':') + firstSentenceEnd = utf.byteIndex(); + } else if (i > spliton) { + firstSentenceEnd = splitCharStart; + } } - else if (i > spliton) { - firstSentenceEnd = spliton; + if (i == spliton) { + splitCharStart = utf.byteIndex(); } + lastc = c; } } if (firstSentenceEnd == 0) { - firstSentenceEnd = spliton; + if (i <= spliton) { + firstSentenceEnd = (int)str.length(); + } else { + firstSentenceEnd = splitCharStart; + } } + + std::vector ret; ret.push_back(str.substr(0, firstSentenceEnd)); - ret.push_back(str.substr(firstSentenceEnd)); + if (firstSentenceEnd < (int)str.length()) + ret.push_back(str.substr(firstSentenceEnd)); return ret; } @@ -219,17 +231,10 @@ void ChatMenu::UpdateChat() { LinearLayout *line = chatVert_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, FILL_PARENT))); TextView *nameView = line->Add(new TextView(displayname, FLAG_DYNAMIC_ASCII, true)); nameView->SetTextColor(0xFF000000 | namecolor); - if (chattext.length() > 45) { - std::vector splitted = Split(chattext); - std::string one = splitted[0]; - std::string two = splitted[1]; - TextView *oneview = line->Add(new TextView(one, FLAG_DYNAMIC_ASCII, true)); - oneview->SetTextColor(0xFF000000 | textcolor); - TextView *twoview = chatVert_->Add(new TextView(two, FLAG_DYNAMIC_ASCII, true)); - twoview->SetTextColor(0xFF000000 | textcolor); - } - else { - TextView *chatView = line->Add(new TextView(chattext, FLAG_DYNAMIC_ASCII, true)); + + std::vector splitMessage = Split(chattext); + for (const std::string &msg : splitMessage) { + TextView *chatView = line->Add(new TextView(msg, FLAG_DYNAMIC_ASCII, true)); chatView->SetTextColor(0xFF000000 | textcolor); } } From aa14fef19d5ac484045178721f26a8141294eb92 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 19 Aug 2020 21:38:11 -0700 Subject: [PATCH 552/848] UI: Allow text to use native fonts. Yes, it changes, but we want to show characters outside our atlas. It's not just ASCII. --- UI/ChatScreen.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 9f498d8c8f..215d69dae1 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -225,16 +225,16 @@ void ChatMenu::UpdateChat() { } if (i.length() <= displayname.length() || i[displayname.length()] != ':') { - TextView *v = chatVert_->Add(new TextView(i, FLAG_DYNAMIC_ASCII, true)); + TextView *v = chatVert_->Add(new TextView(i, ALIGN_LEFT | FLAG_WRAP_TEXT, true, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); v->SetTextColor(0xFF000000 | infocolor); } else { LinearLayout *line = chatVert_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, FILL_PARENT))); - TextView *nameView = line->Add(new TextView(displayname, FLAG_DYNAMIC_ASCII, true)); + TextView *nameView = line->Add(new TextView(displayname, ALIGN_LEFT | FLAG_WRAP_TEXT, true, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); nameView->SetTextColor(0xFF000000 | namecolor); std::vector splitMessage = Split(chattext); for (const std::string &msg : splitMessage) { - TextView *chatView = line->Add(new TextView(msg, FLAG_DYNAMIC_ASCII, true)); + TextView *chatView = line->Add(new TextView(msg, ALIGN_LEFT | FLAG_WRAP_TEXT, true, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); chatView->SetTextColor(0xFF000000 | textcolor); } } From 3c5d82d30e863ccca5dff553850fb6be8f12128e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 19 Aug 2020 21:58:11 -0700 Subject: [PATCH 553/848] UI: Use standard text wrapping for chat messages. This way they will actually wrap in a width-aware way, regardless of screen size. They should also better take into account non-Unicode. --- UI/ChatScreen.cpp | 59 ++++------------------------------------------- 1 file changed, 4 insertions(+), 55 deletions(-) diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 215d69dae1..5430945518 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -157,61 +157,12 @@ UI::EventReturn ChatMenu::OnQuickChat5(UI::EventParams &e) { return UI::EVENT_DONE; } -/* - maximum chat length in one message from server is only 64 character - need to split the chat to fit the static chat screen size - if the chat screen size become dynamic from device resolution - we need to change split function logic also. -*/ -std::vector Split(const std::string& str) -{ - static const int spliton = 45; - - int firstSentenceEnd = 0; - int splitCharStart = 0; - - uint32_t lastc = -1; - int i = 0; - if ((int)str.length() > spliton) { - for (UTF8 utf(str.c_str()); utf.byteIndex() < (int)str.length(); ++i) { - uint32_t c = utf.next(); - if (isspace(c)) { - if (i < spliton) { - if (lastc != ':') - firstSentenceEnd = utf.byteIndex(); - } else if (i > spliton) { - firstSentenceEnd = splitCharStart; - } - } - if (i == spliton) { - splitCharStart = utf.byteIndex(); - } - lastc = c; - } - } - - if (firstSentenceEnd == 0) { - if (i <= spliton) { - firstSentenceEnd = (int)str.length(); - } else { - firstSentenceEnd = splitCharStart; - } - } - - std::vector ret; - ret.push_back(str.substr(0, firstSentenceEnd)); - if (firstSentenceEnd < (int)str.length()) - ret.push_back(str.substr(firstSentenceEnd)); - return ret; -} - void ChatMenu::UpdateChat() { using namespace UI; if (chatVert_ != nullptr) { chatVert_->Clear(); //read Access violation is proadhoc.cpp use NULL_->Clear() pointer? std::vector chatLog = getChatLog(); for (auto i : chatLog) { - //split long text uint32_t namecolor = 0x29B6F6; uint32_t textcolor = 0xFFFFFF; uint32_t infocolor = 0xFDD835; @@ -229,14 +180,12 @@ void ChatMenu::UpdateChat() { v->SetTextColor(0xFF000000 | infocolor); } else { LinearLayout *line = chatVert_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, FILL_PARENT))); - TextView *nameView = line->Add(new TextView(displayname, ALIGN_LEFT | FLAG_WRAP_TEXT, true, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); + line->SetSpacing(0.0f); + TextView *nameView = line->Add(new TextView(displayname, ALIGN_LEFT, true, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, 0.0f))); nameView->SetTextColor(0xFF000000 | namecolor); - std::vector splitMessage = Split(chattext); - for (const std::string &msg : splitMessage) { - TextView *chatView = line->Add(new TextView(msg, ALIGN_LEFT | FLAG_WRAP_TEXT, true, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); - chatView->SetTextColor(0xFF000000 | textcolor); - } + TextView *chatView = line->Add(new TextView(chattext, ALIGN_LEFT | FLAG_WRAP_TEXT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f))); + chatView->SetTextColor(0xFF000000 | textcolor); } } toBottom_ = true; From 506a86300da4e0207c37e280be5f289cfde27c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 22 Aug 2020 00:30:29 +0200 Subject: [PATCH 554/848] More explicit invalidation of any cached state in Thin3D. Fixes #13307 --- GPU/Common/PresentationCommon.cpp | 4 ++-- GPU/D3D11/GPU_D3D11.cpp | 5 ++--- GPU/D3D11/TextureCacheD3D11.cpp | 4 +++- ext/native/thin3d/thin3d.h | 6 +++++- ext/native/thin3d/thin3d_d3d11.cpp | 27 +++++++++++++++------------ ext/native/thin3d/thin3d_d3d9.cpp | 6 ++++++ ext/native/thin3d/thin3d_gl.cpp | 26 +++++++++++--------------- ext/native/thin3d/thin3d_vulkan.cpp | 11 ++++------- 8 files changed, 48 insertions(+), 41 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 2064f6ef17..d11bf72b95 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -539,8 +539,7 @@ void PresentationCommon::UpdateUniforms(bool hasVideo) { } void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u0, float v0, float u1, float v1) { - // Make sure Direct3D 11 clears state, since we set shaders outside Draw. - draw_->BindPipeline(nullptr); + draw_->InvalidateCachedState(); // TODO: If shader objects have been created by now, we might have received errors. // GLES can have the shader fail later, shader->failed / shader->error. @@ -649,6 +648,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u Draw::Framebuffer *postShaderFramebuffer = postShaderFramebuffers_[i]; draw_->BindFramebufferAsRenderTarget(postShaderFramebuffer, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "PostShader"); + if (usePostShaderOutput) { draw_->BindFramebufferAsTexture(postShaderFramebuffers_[i - 1], 0, Draw::FB_COLOR_BIT, 0); } else { diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index fcd1fa0d8d..3d8a463838 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -119,7 +119,6 @@ GPU_D3D11::~GPU_D3D11() { shaderManagerD3D11_->ClearShaders(); delete shaderManagerD3D11_; delete textureCacheD3D11_; - draw_->BindPipeline(nullptr); stockD3D11.Destroy(); } @@ -233,8 +232,8 @@ void GPU_D3D11::ReapplyGfxState() { } void GPU_D3D11::EndHostFrame() { - // Tell the DrawContext that it's time to reset everything. - draw_->BindPipeline(nullptr); + // Probably not really necessary. + draw_->InvalidateCachedState(); } void GPU_D3D11::BeginFrame() { diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 17cc43472e..47a1a95535 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -389,7 +389,9 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra Draw::Framebuffer *depalFBO = framebufferManagerD3D11_->GetTempFBO(TempFBO::DEPAL, framebuffer->renderWidth, framebuffer->renderHeight, Draw::FBO_8888); shaderManager_->DirtyLastShader(); - draw_->BindPipeline(nullptr); + + // Not sure why or if we need this here - we're not about to actually draw using draw_, just use its framebuffer binds. + draw_->InvalidateCachedState(); float xoff = -0.5f / framebuffer->renderWidth; float yoff = 0.5f / framebuffer->renderHeight; diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 88001c4aa3..e3f6390afe 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -646,7 +646,11 @@ public: BindTextures(stage, 1, textures); } // from sampler 0 and upwards - // Call this with nullptr to signal that you're done with the stuff you've bound, like textures and samplers and stuff. + // Clear state cached within thin3d. Must be called after directly calling API functions. + // Note that framebuffer state (which framebuffer is bounds) may not be cached. + // Must not actually perform any API calls itself since this can be called when no framebuffer is bound for rendering. + virtual void InvalidateCachedState() = 0; + virtual void BindPipeline(Pipeline *pipeline) = 0; virtual void Draw(int vertexCount, int offset) = 0; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 1f589e3856..1457e79af1 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -77,6 +77,8 @@ public: void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) override; + void InvalidateCachedState() override; + void BindTextures(int start, int count, Texture **textures) override; void BindSamplerStates(int start, int count, SamplerState **states) override; void BindVertexBuffers(int start, int count, Buffer **buffers, int *offsets) override; @@ -1019,19 +1021,20 @@ void D3D11DrawContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { context_->Unmap(curPipeline_->dynamicUniforms, 0); } -void D3D11DrawContext::BindPipeline(Pipeline *pipeline) { - if (pipeline == nullptr) { - // This is a signal to forget all our caching. - curBlend_ = nullptr; - curDepth_ = nullptr; - curRaster_ = nullptr; - curPS_ = nullptr; - curVS_ = nullptr; - curGS_ = nullptr; - curInputLayout_ = nullptr; - curTopology_ = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - } +void D3D11DrawContext::InvalidateCachedState() { + // This is a signal to forget all our state caching. + curBlend_ = nullptr; + curDepth_ = nullptr; + curRaster_ = nullptr; + curPS_ = nullptr; + curVS_ = nullptr; + curGS_ = nullptr; + curInputLayout_ = nullptr; + curTopology_ = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + curPipeline_ = nullptr; +} +void D3D11DrawContext::BindPipeline(Pipeline *pipeline) { D3D11Pipeline *dPipeline = (D3D11Pipeline *)pipeline; if (curPipeline_ == dPipeline) return; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 2b629149a8..9843af9358 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -606,6 +606,8 @@ public: return stepId_; } + void InvalidateCachedState() override; + private: LPDIRECT3D9 d3d_; LPDIRECT3D9EX d3dEx_; @@ -631,6 +633,10 @@ private: bool supportsINTZ = false; }; +void D3D9Context::InvalidateCachedState() { + curPipeline_ = nullptr; +} + #define FB_DIV 1 #define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))) diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 3a7c0f958c..abcf53dc3e 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -481,9 +481,10 @@ public: return renderManager_.GetCurrentStepId(); } + void InvalidateCachedState() override; + private: void ApplySamplers(); - void Unbind(); GLRenderManager renderManager_; @@ -612,14 +613,14 @@ void OpenGLContext::BeginFrame() { } void OpenGLContext::EndFrame() { - Unbind(); - FrameData &frameData = frameData_[renderManager_.GetCurFrame()]; renderManager_.EndPushBuffer(frameData.push); // upload the data! renderManager_.Finish(); + + InvalidateCachedState(); } -void OpenGLContext::Unbind() { +void OpenGLContext::InvalidateCachedState() { // Unbind stuff. for (auto &texture : boundTextures_) { texture = nullptr; @@ -627,9 +628,6 @@ void OpenGLContext::Unbind() { for (auto &sampler : boundSamplers_) { sampler = nullptr; } - for (int i = 0; i < ARRAY_SIZE(boundTextures_); i++) { - renderManager_.BindTexture(i, nullptr); - } curPipeline_ = nullptr; } @@ -1107,15 +1105,13 @@ bool OpenGLPipeline::LinkShaders() { void OpenGLContext::BindPipeline(Pipeline *pipeline) { curPipeline_ = (OpenGLPipeline *)pipeline; - if (curPipeline_) { - curPipeline_->blend->Apply(&renderManager_); - curPipeline_->depthStencil->Apply(&renderManager_, stencilRef_); - curPipeline_->raster->Apply(&renderManager_); - renderManager_.BindProgram(curPipeline_->program_); - } else { - // Wipe bound textures and samplers. - Unbind(); + if (!curPipeline_) { + return; } + curPipeline_->blend->Apply(&renderManager_); + curPipeline_->depthStencil->Apply(&renderManager_, stencilRef_); + curPipeline_->raster->Apply(&renderManager_); + renderManager_.BindProgram(curPipeline_->program_); } void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index d31620e655..e74f5f1615 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -408,10 +408,6 @@ public: void BindPipeline(Pipeline *pipeline) override { curPipeline_ = (VKPipeline *)pipeline; - - if (!pipeline) { - UnbindBoundState(); - } } // TODO: Make VKBuffers proper buffers, and do a proper binding model. This is just silly. @@ -497,8 +493,9 @@ public: return renderManager_.GetCurrentStepId(); } + void InvalidateCachedState() override; + private: - void UnbindBoundState(); VulkanTexture *GetNullTexture(); VulkanContext *vulkan_ = nullptr; @@ -923,10 +920,10 @@ void VKContext::EndFrame() { push_ = nullptr; // Unbind stuff, to avoid accidentally relying on it across frames (and provide some protection against forgotten unbinds of deleted things). - UnbindBoundState(); + InvalidateCachedState(); } -void VKContext::UnbindBoundState() { +void VKContext::InvalidateCachedState() { curPipeline_ = nullptr; for (auto &view : boundImageView_) { From 26ba65f385f1e2b6a0092fdc363d3b72d01a6825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 22 Aug 2020 00:32:51 +0200 Subject: [PATCH 555/848] Some minor logging improvements that get to tag along the previous commit --- Core/FileSystems/ISOFileSystem.cpp | 24 +++++++++++++++--------- Core/HLE/sceOpenPSID.cpp | 4 ++-- libretro/.gitignore | 1 + 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index 04c52f14c6..4484ac8110 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -324,7 +324,7 @@ ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(const std::string &path, bo return entry; } else { if (catchError) - ERROR_LOG(FILESYS,"File %s not found", path.c_str()); + ERROR_LOG(FILESYS, "File '%s' not found", path.c_str()); return 0; } @@ -337,7 +337,7 @@ int ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char entry.isBlockSectorMode = false; if (access & FILEACCESS_WRITE) { - ERROR_LOG(FILESYS, "Can't open file %s with write access on an ISO partition", filename.c_str()); + ERROR_LOG(FILESYS, "Can't open file '%s' with write access on an ISO partition", filename.c_str()); return SCE_KERNEL_ERROR_ERRNO_INVALID_FLAG; } @@ -346,7 +346,7 @@ int ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF; parseLBN(filename, §orStart, &readSize); if (sectorStart > blockDevice->GetNumBlocks()) { - WARN_LOG(FILESYS, "Unable to open raw sector, out of range: %s, sector %08x, max %08x", filename.c_str(), sectorStart, blockDevice->GetNumBlocks()); + WARN_LOG(FILESYS, "Unable to open raw sector, out of range: '%s', sector %08x, max %08x", filename.c_str(), sectorStart, blockDevice->GetNumBlocks()); return SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND; } else if (sectorStart == blockDevice->GetNumBlocks()) @@ -354,7 +354,7 @@ int ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char ERROR_LOG(FILESYS, "Should not be able to open the block after the last on disc! %08x", sectorStart); } - DEBUG_LOG(FILESYS, "Got a raw sector open: %s, sector %08x, size %08x", filename.c_str(), sectorStart, readSize); + DEBUG_LOG(FILESYS, "Got a raw sector open: '%s', sector %08x, size %08x", filename.c_str(), sectorStart, readSize); u32 newHandle = hAlloc->GetNewHandle(); entry.seekPos = 0; entry.file = 0; @@ -363,16 +363,16 @@ int ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char entry.openSize = readSize; // when open as "umd1:/sce_lbn0x0_size0x6B49D200", that mean open umd1 as a block device. // the param in sceIoLseek and sceIoRead is lba mode. we must mark it. - if (strncmp(devicename, "umd0:", 5)==0 || strncmp(devicename, "umd1:", 5)==0) + if (strncmp(devicename, "umd0:", 5) == 0 || strncmp(devicename, "umd1:", 5) == 0) entry.isBlockSectorMode = true; entries[newHandle] = entry; return newHandle; } - // May return entireISO for "umd0:" - entry.file = GetFromPath(filename); - if (!entry.file){ + // May return entireISO for "umd0:". + entry.file = GetFromPath(filename, false); + if (!entry.file) { return SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND; } @@ -524,7 +524,13 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) { if ((s64)e.seekPos + size > fileSize) { // Clamp to the remaining size, but read what we can. const s64 newSize = fileSize - (s64)e.seekPos; - WARN_LOG(FILESYS, "Reading beyond end of file, clamping size %lld to %lld", size, newSize); + // Reading beyond the file is really quite normal behavior (if return value handled correctly), so + // not doing WARN here. Still, can potentially be useful to see so leaving at INFO. + if (newSize == 0) { + INFO_LOG(FILESYS, "Attempted read at end of file, 0-size read simulated"); + } else { + INFO_LOG(FILESYS, "Reading beyond end of file from seekPos %d, clamping size %lld to %lld", e.seekPos, size, newSize); + } size = newSize; } diff --git a/Core/HLE/sceOpenPSID.cpp b/Core/HLE/sceOpenPSID.cpp index 46d3a7890d..d20e349307 100644 --- a/Core/HLE/sceOpenPSID.cpp +++ b/Core/HLE/sceOpenPSID.cpp @@ -25,7 +25,7 @@ u8 dummyOpenPSID[16] = { 0x10, 0x02, 0xA3, 0x44, 0x13, 0xF5, 0x93, 0xB0, 0xCC, 0 static int sceOpenPSIDGetOpenPSID(u32 OpenPSIDPtr) { - ERROR_LOG(HLE, "UNTESTED sceOpenPSIDGetOpenPSID(%d)", OpenPSIDPtr); + WARN_LOG(HLE, "UNTESTED sceOpenPSIDGetOpenPSID(%d)", OpenPSIDPtr); getLocalMac((SceNetEtherAddr*)&dummyOpenPSID); if (Memory::IsValidAddress(OpenPSIDPtr)) @@ -40,7 +40,7 @@ static int sceOpenPSIDGetOpenPSID(u32 OpenPSIDPtr) static int sceOpenPSID_driver_0x19D579F0(u32 OpenPSIDPtr,u32 unknown) { - ERROR_LOG(HLE, "UNTESTED sceOpenPSID_driver_0x19D579F0(%d,%d)", OpenPSIDPtr,unknown); + WARN_LOG(HLE, "UNTESTED sceOpenPSID_driver_0x19D579F0(%d,%d)", OpenPSIDPtr,unknown); getLocalMac((SceNetEtherAddr*)&dummyOpenPSID); if (Memory::IsValidAddress(OpenPSIDPtr)) diff --git a/libretro/.gitignore b/libretro/.gitignore index b791c99ede..de1b540422 100644 --- a/libretro/.gitignore +++ b/libretro/.gitignore @@ -2,3 +2,4 @@ *.so *.dll *.dylib +*.manifest From d465ce5123d8a7f4cbe8595f39cd3564483e775b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 22 Aug 2020 10:50:39 +0200 Subject: [PATCH 556/848] Quick Vulkan crashfix --- GPU/Common/FramebufferManagerCommon.cpp | 1 + GPU/Vulkan/GPU_Vulkan.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 4ebc279948..1fb3581e50 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -682,6 +682,7 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int DrawActiveTexture(dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags); gpuStats.numUploads++; pixelsTex->Release(); + draw_->InvalidateCachedState(); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 97b1f82ecc..b3d39f7289 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -332,6 +332,8 @@ void GPU_Vulkan::EndHostFrame() { drawEngine_.EndFrame(); framebufferManagerVulkan_->EndFrame(); textureCacheVulkan_->EndFrame(); + + draw_->InvalidateCachedState(); } // Needs to be called on GPU thread, not reporting thread. From 5ade93a091f65f849c7748b72c1fa213d50150ca Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Aug 2020 08:22:15 -0700 Subject: [PATCH 557/848] GPU: Properly detect clears. The check was reversed before, oops. Detected masked draws. Must've gotten this backwards debugging Mana Khemia. --- GPU/Common/SoftwareTransformCommon.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index c7e18fff21..92d570019a 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -445,7 +445,7 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt int scissorX2 = gstate.getScissorX2() + 1; int scissorY2 = gstate.getScissorY2() + 1; reallyAClear = IsReallyAClear(transformed, maxIndex, scissorX2, scissorY2); - if (reallyAClear && gstate.getColorMask() != 0 && gstate.getClearModeColorMask() != 0) { + if (reallyAClear && gstate.getColorMask() != 0xFFFFFFFF && (gstate.isClearModeColorMask() || gstate.isClearModeAlphaMask())) { result->setSafeSize = true; result->safeWidth = scissorX2; result->safeHeight = scissorY2; @@ -469,8 +469,8 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt // Detect full screen "clears" that might not be so obvious, to set the safe size if possible. if (!result->setSafeSize && prim == GE_PRIM_RECTANGLES && maxIndex == 2) { - bool clearingColor = gstate.isModeClear() && gstate.getClearModeColorMask() != 0; - bool writingColor = gstate.getColorMask() != 0; + bool clearingColor = gstate.isModeClear() && (gstate.isClearModeColorMask() || gstate.isClearModeAlphaMask()); + bool writingColor = gstate.getColorMask() != 0xFFFFFFFF; bool startsZeroX = transformed[0].x <= 0.0f && transformed[1].x > transformed[0].x; bool startsZeroY = transformed[0].y <= 0.0f && transformed[1].y > transformed[0].y; From 3b11b096213584d63a5ed7b627c84e3b731fcfee Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Aug 2020 08:24:46 -0700 Subject: [PATCH 558/848] Debugger: Check for no texture before debug bind. This means a framebuffer texture that is somehow not attached, but better to avoid the crash. --- GPU/GLES/TextureCacheGLES.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 9428cdf5d7..5f0a9d9068 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -634,7 +634,6 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) { } } - // glBindTexture(GL_TEXTURE_2D, entry->textureName); lastBoundTexture = entry->textureName; // GLES2 doesn't have support for a "Max lod" which is critical as PSP games often @@ -859,12 +858,15 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) gstate = saved; } - buffer.Allocate(w, h, GE_FORMAT_8888, false); - renderManager->CopyImageToMemorySync(entry->textureName, level, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, (uint8_t *)buffer.GetData(), w, "GetCurrentTextureDebug"); + bool result = entry->textureName != nullptr; + if (result) { + buffer.Allocate(w, h, GE_FORMAT_8888, false); + renderManager->CopyImageToMemorySync(entry->textureName, level, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, (uint8_t *)buffer.GetData(), w, "GetCurrentTextureDebug"); + } gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); - return true; + return result; #else return false; #endif From 35c5308c306c7fd75e1518f0b84ee04b6d3d75b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 23 Aug 2020 22:11:18 +0200 Subject: [PATCH 559/848] Framebuffer matching: Don't try to match depth buffers with color if the swizzle bits don't indicate it. Fixes God of War issue reported in a comment of #13317. --- GPU/Common/TextureCacheCommon.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index cd7a725349..5613f9bb11 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -763,9 +763,33 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi AttachedFramebufferInfo fbInfo = { 0 }; const u32 mirrorMask = 0x00600000; + u32 addr = address & 0x3FFFFFFF; u32 texaddr = entry->addr + texaddrOffset; - if (entry->addr & 0x04000000) { + if (Memory::IsVRAMAddress(entry->addr)) { + // This bit controls swizzle. The swizzles at 0x00200000 and 0x00600000 are designed + // to perfectly match reading depth as color (which one to use I think might be related + // to the bpp of the color format used when rendering to it). + // It's fairly unlikely that games would screw this up since the result will be garbage so + // we use it to filter out unlikely matches. + switch (entry->addr & mirrorMask) { + case 0x00000000: + case 0x00400000: + // Don't match the depth channel with these addresses when texturing. + if (channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH) { + // God of War: If we actively detach here, the shadows disappear. + return false; + } + break; + case 0x00200000: + case 0x00600000: + // Don't match the color channel with these addresses when texturing. + if (channel == FramebufferNotificationChannel::NOTIFY_FB_COLOR) { + return false; + } + break; + } + addr &= ~mirrorMask; texaddr &= ~mirrorMask; } From 055588c1a1db85c7b422044354dcf4e72cde7021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 22 Aug 2020 10:36:02 +0200 Subject: [PATCH 560/848] Framebuffer manager refactor step 1: Split ApplyFramebuffer into Match and Apply steps. This should have no change in behavior, but prepares the ground for the next steps. Want this merged separately. --- GPU/Common/TextureCacheCommon.cpp | 118 +++++++++++++++++++----------- GPU/Common/TextureCacheCommon.h | 39 +++++++--- 2 files changed, 105 insertions(+), 52 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 5613f9bb11..3fa66ba8e9 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -530,7 +530,9 @@ void TextureCacheCommon::SetTexture(bool force) { entry->framebuffer = nullptr; for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { auto framebuffer = fbCache_[i]; - AttachFramebuffer(entry, framebuffer->fb_address, framebuffer, 0, (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR); + auto notificationChannel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; + FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer->fb_address, framebuffer, 0, notificationChannel); + ApplyFramebufferMatch(match, entry, framebuffer->fb_address, framebuffer, notificationChannel); } // If we ended up with a framebuffer, attach it - no texture decoding needed. @@ -662,15 +664,22 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram if (std::find(fbCache_.begin(), fbCache_.end(), framebuffer) == fbCache_.end()) { fbCache_.push_back(framebuffer); } + + // TODO: Rework this to not try to "apply" all matches, only the best one. for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { - AttachFramebuffer(it->second.get(), addr, framebuffer, 0, channel); + TexCacheEntry *entry = it->second.get(); + FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); + ApplyFramebufferMatch(match, entry, addr, framebuffer, channel); } // Let's assume anything in mirrors is fair game to check. + // TODO: Only do this for depth? for (auto it = cache_.lower_bound(mirrorCacheKey), end = cache_.upper_bound(mirrorCacheKeyEnd); it != end; ++it) { const u64 mirrorlessKey = it->first & ~0x0060000000000000ULL; // Let's still make sure it's in the cache range. if (mirrorlessKey >= cacheKey && mirrorlessKey <= cacheKeyEnd) { - AttachFramebuffer(it->second.get(), addr, framebuffer, 0, channel); + TexCacheEntry *entry = it->second.get(); + FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); + ApplyFramebufferMatch(match, entry, addr, framebuffer, channel); } } break; @@ -691,7 +700,8 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram } } -void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo, FramebufferNotificationChannel channel) { +void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel) { + _dbg_assert_((fbInfo.match == FramebufferMatch::VALID) || (fbInfo.match == FramebufferMatch::VALID_DEPAL)); const u64 cachekey = entry->CacheKey(); const bool hasInvalidFramebuffer = entry->framebuffer == nullptr || entry->invalidHint == -1; const bool hasOlderFramebuffer = entry->framebuffer != nullptr && entry->framebuffer->last_frame_render < framebuffer->last_frame_render; @@ -725,7 +735,8 @@ void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFra } } -void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo, FramebufferNotificationChannel channel) { +void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel) { + _dbg_assert_(fbInfo.match == FramebufferMatch::INVALID); const u64 cachekey = entry->CacheKey(); if (entry->framebuffer == nullptr || entry->framebuffer == framebuffer) { @@ -757,10 +768,32 @@ void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, Vi } } -bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) { - static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32; +bool TextureCacheCommon::ApplyFramebufferMatch(FramebufferMatchInfo match, TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel) { + // There were five possible outcomes of the old ApplyFramebuffer, these have been + // mapped to the FramebufferMatch enum, and we handle them the same old ways here. + switch (match.match) { + case FramebufferMatch::VALID: + AttachFramebufferValid(entry, framebuffer, match, channel); + return true; + case FramebufferMatch::VALID_DEPAL: + AttachFramebufferValid(entry, framebuffer, match, channel); + entry->status |= TexCacheEntry::STATUS_DEPALETTIZE; + return true; + case FramebufferMatch::INVALID: + AttachFramebufferInvalid(entry, framebuffer, match, channel); + return true; + case FramebufferMatch::NO_MATCH: + DetachFramebuffer(entry, address, framebuffer, channel); + return false; + case FramebufferMatch::IGNORE: + // The purpose of this seems to be to delay a decision to the next frame. + default: + return false; + } +} - AttachedFramebufferInfo fbInfo = { 0 }; +FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const { + static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32; const u32 mirrorMask = 0x00600000; @@ -778,14 +811,14 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // Don't match the depth channel with these addresses when texturing. if (channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH) { // God of War: If we actively detach here, the shadows disappear. - return false; + return FramebufferMatchInfo{ FramebufferMatch::IGNORE }; } break; case 0x00200000: case 0x00600000: // Don't match the color channel with these addresses when texturing. if (channel == FramebufferNotificationChannel::NOTIFY_FB_COLOR) { - return false; + return FramebufferMatchInfo{ FramebufferMatch::IGNORE }; } break; } @@ -811,16 +844,21 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. // However, some games use a different format to clear the buffer. if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) { - DetachFramebuffer(entry, address, framebuffer, channel); + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; + } else { + // TODO: This is a weird outcome. The purpose seems to be to delay + // a decision to the next frame. + // Should really try to map it to something else. + return FramebufferMatchInfo{ FramebufferMatch::IGNORE }; } } else { - AttachFramebufferValid(entry, framebuffer, fbInfo, channel); - return true; + return FramebufferMatchInfo{ FramebufferMatch::VALID }; } } else { // Apply to buffered mode only. - if (!framebufferManager_->UseBufferedRendering()) - return false; + if (!framebufferManager_->UseBufferedRendering()) { + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; + } // Check works for D16 too (???) const bool matchingClutFormat = @@ -832,55 +870,53 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi const u32 bitOffset = (texaddr - addr) * 8; const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry->format]); + + // To avoid ruining git blame, kept the same name as the old struct. + FramebufferMatchInfo fbInfo{ FramebufferMatch::VALID }; + fbInfo.yOffset = entry->bufw == 0 ? 0 : pixelOffset / entry->bufw; fbInfo.xOffset = entry->bufw == 0 ? 0 : pixelOffset % entry->bufw; if (framebuffer->fb_stride != entry->bufw) { if (noOffset) { - // Not actually sure why we even try here. There's no way it'll go well if the strides are different. WARN_LOG_ONCE(diffStrides2, G3D, "Texturing from framebuffer (matching_clut=%s) different strides %d != %d", matchingClutFormat ? "yes" : "no", entry->bufw, framebuffer->fb_stride); + // Continue on with other checks. + // Not actually sure why we even try here. There's no way it'll go well if the strides are different. } else { // Assume any render-to-tex with different bufw + offset is a render from ram. - DetachFramebuffer(entry, address, framebuffer, channel); - return false; + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } } // Check if it's in bufferWidth (which might be higher than width and may indicate the framebuffer includes the data.) if (fbInfo.xOffset >= framebuffer->bufferWidth && fbInfo.xOffset + w <= (u32)framebuffer->fb_stride) { // This happens in Brave Story, see #10045 - the texture is in the space between strides, with matching stride. - DetachFramebuffer(entry, address, framebuffer, channel); - return false; + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } if (fbInfo.yOffset + minSubareaHeight >= framebuffer->height) { // Can't be inside the framebuffer then, ram. Detach to be safe. - DetachFramebuffer(entry, address, framebuffer, channel); - return false; + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } // Trying to play it safe. Below 0x04110000 is almost always framebuffers. // TODO: Maybe we can reduce this check and find a better way above 0x04110000? if (fbInfo.yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 0x04110000) { WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); - DetachFramebuffer(entry, address, framebuffer, channel); - return false; + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } // Check for CLUT. The framebuffer is always RGB, but it can be interpreted as a CLUT texture. // 3rd Birthday (and a bunch of other games) render to a 16 bit clut texture. if (matchingClutFormat) { if (!noOffset) { - WARN_LOG_REPORT_ONCE(subareaClut, G3D, "Texturing from framebuffer using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); + WARN_LOG_ONCE(subareaClut, G3D, "Texturing from framebuffer using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); } - AttachFramebufferValid(entry, framebuffer, fbInfo, channel); - entry->status |= TexCacheEntry::STATUS_DEPALETTIZE; - // We'll validate it compiles later. - return true; + fbInfo.match = FramebufferMatch::VALID_DEPAL; + return fbInfo; } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) { WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffer of format %s", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format)); - DetachFramebuffer(entry, address, framebuffer, channel); - return false; + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } // This is either normal or we failed to generate a shader to depalettize @@ -888,23 +924,19 @@ bool TextureCacheCommon::AttachFramebuffer(TexCacheEntry *entry, u32 address, Vi if (framebuffer->format != entry->format) { WARN_LOG_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); - AttachFramebufferValid(entry, framebuffer, fbInfo, channel); - return true; + return fbInfo; // Valid! } else { WARN_LOG_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); - // If "AttachFramebufferValid" , God of War Ghost of Sparta/Chains of Olympus will be missing special effect. - AttachFramebufferInvalid(entry, framebuffer, fbInfo, channel); - return true; + // If we return VALID here, God of War Ghost of Sparta/Chains of Olympus will be missing some special effect according to an old comment. + fbInfo.match = FramebufferMatch::INVALID; + return fbInfo; } } else { - WARN_LOG_REPORT_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", + WARN_LOG_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); - DetachFramebuffer(entry, address, framebuffer, channel); - return false; + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } } - - return false; } void TextureCacheCommon::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) { @@ -976,7 +1008,9 @@ bool TextureCacheCommon::SetOffsetTexture(u32 yOffset) { bool success = false; for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { auto framebuffer = fbCache_[i]; - if (AttachFramebuffer(entry, framebuffer->fb_address, framebuffer, texaddrOffset, (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR)) { + FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; + FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer->fb_address, framebuffer, texaddrOffset, channel); + if (ApplyFramebufferMatch(match, entry, framebuffer->fb_address, framebuffer, channel)) { success = true; } } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 4962856342..72895a7188 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -185,6 +185,27 @@ class FramebufferManagerCommon; // Would really like to replace this with DenseHashMap but can't as long as we need lower_bound. typedef std::map> TexCache; +// Urgh. +#ifdef IGNORE +#undef IGNORE +#endif + +// TODO: Try to get rid of IGNORE, it doesn't match what we want to do +enum class FramebufferMatch { + VALID = 0, + VALID_DEPAL, + INVALID, + NO_MATCH, + IGNORE, +}; + +// Separate to keep main texture cache size down. +struct FramebufferMatchInfo { + FramebufferMatch match; + u32 xOffset; + u32 yOffset; +}; + class TextureCacheCommon { public: TextureCacheCommon(Draw::DrawContext *draw); @@ -236,12 +257,6 @@ protected: virtual void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) = 0; bool CheckFullHash(TexCacheEntry *entry, bool &doDelete); - // Separate to keep main texture cache size down. - struct AttachedFramebufferInfo { - u32 xOffset; - u32 yOffset; - }; - void DecodeTextureLevel(u8 *out, int outPitch, GETextureFormat format, GEPaletteFormat clutformat, uint32_t texaddr, int level, int bufw, bool reverseColors, bool useBGRA, bool expandTo32Bit); void UnswizzleFromMem(u32 *dest, u32 destPitch, const u8 *texptr, u32 bufw, u32 height, u32 bytesPerPixel); void ReadIndexedTex(u8 *out, int outPitch, int level, const u8 *texptr, int bytesPerIndex, int bufw, bool expandTo32Bit); @@ -256,9 +271,13 @@ protected: void UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key); // Used by D3D11 and Vulkan. void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode); - bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel); - void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo, FramebufferNotificationChannel channel); - void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo, FramebufferNotificationChannel channel); + FramebufferMatchInfo MatchFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; + + // Temporary utility during conversion + bool ApplyFramebufferMatch(FramebufferMatchInfo match, TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel); + + void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); + void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel); void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer); @@ -306,7 +325,7 @@ protected: u32 secondCacheSizeEstimate_; std::vector fbCache_; - std::map fbTexInfo_; + std::map fbTexInfo_; std::map videos_; From f44717c4f55b2ecadbfb3561470cca318be40bec Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Aug 2020 21:29:15 -0700 Subject: [PATCH 561/848] TexCache: Force recreate texture on detach. We could have multiple detaches, and we delete the texture on attach, so we really must make sure we recreate. Fixes #13320. --- GPU/Common/TextureCacheCommon.cpp | 11 +++++++++-- GPU/Common/TextureCacheCommon.h | 1 + GPU/GLES/TextureCacheGLES.cpp | 8 +++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index cd7a725349..d6bdf6fa66 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -407,6 +407,12 @@ void TextureCacheCommon::SetTexture(bool force) { rehash = false; } + // Do we need to recreate? + if (entry->status & TexCacheEntry::STATUS_FORCE_REBUILD) { + match = false; + entry->status &= ~TexCacheEntry::STATUS_FORCE_REBUILD; + } + if (match) { if (entry->lastFrame != gpuStats.numFlips) { u32 diff = gpuStats.numFlips - entry->lastFrame; @@ -749,11 +755,12 @@ void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, Vi const u64 cachekey = entry->CacheKey(); cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); entry->framebuffer = nullptr; - // Force the hash to change in case we had one before. + // Force recreate the texture in case we had one before and the hash matches. // Otherwise we never recreate the texture. - entry->hash ^= 1; + entry->status |= TexCacheEntry::STATUS_FORCE_REBUILD; fbTexInfo_.erase(cachekey); GPUDebug::NotifyTextureAttachment(entry->addr); + InvalidateLastTexture(entry); } } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 4962856342..76cd264b70 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -126,6 +126,7 @@ struct TexCacheEntry { STATUS_BAD_MIPS = 0x400, // Has bad or unusable mipmap levels. STATUS_DEPTH = 0x800, + STATUS_FORCE_REBUILD = 0x1000, }; // Status, but int so we can zero initialize. diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 5f0a9d9068..aa8c4b0d41 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -825,8 +825,10 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) } SetTexture(true); - if (!nextTexture_) + if (!nextTexture_) { + ERROR_LOG(G3D, "Failed to get debug texture: no texture set"); return false; + } // Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer. TexCacheEntry *entry = nextTexture_; @@ -844,6 +846,8 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); // We may have blitted to a temp FBO. framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); + if (!retval) + ERROR_LOG(G3D, "Failed to get debug texture: copy to memory failed"); return retval; } @@ -862,6 +866,8 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) if (result) { buffer.Allocate(w, h, GE_FORMAT_8888, false); renderManager->CopyImageToMemorySync(entry->textureName, level, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, (uint8_t *)buffer.GetData(), w, "GetCurrentTextureDebug"); + } else { + ERROR_LOG(G3D, "Failed to get debug texture: texture is null"); } gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); From c98d96c78f142fc86dbf1824806dd40304c6bc42 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Aug 2020 21:32:06 -0700 Subject: [PATCH 562/848] http: Avoid logging errors for would block. It's not an error, this case is expected. --- ext/native/net/sinks.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ext/native/net/sinks.cpp b/ext/native/net/sinks.cpp index 8c4434b31d..dbfa8643df 100644 --- a/ext/native/net/sinks.cpp +++ b/ext/native/net/sinks.cpp @@ -21,6 +21,7 @@ #endif #include +#include #include #include "net/sinks.h" @@ -185,6 +186,14 @@ bool InputSink::Block() { void InputSink::AccountFill(int bytes) { if (bytes < 0) { +#if PPSSPP_PLATFORM(WINDOWS) + int err = WSAGetLastError(); + if (err == WSAEWOULDBLOCK) + return; +#else + if (errno == EWOULDBLOCK || errno == EAGAIN) + return; +#endif ERROR_LOG(IO, "Error reading from socket"); return; } From 3574a352dff074a3685f34be1d337b35c96f8b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 25 Aug 2020 12:19:01 +0200 Subject: [PATCH 563/848] Update lang submodule --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index 1c64b8fbd3..d5a2a51942 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 1c64b8fbd3cb6bd87935eb53f302f7de6f86e209 +Subproject commit d5a2a51942377820764604d9bb424fa9a879c4bd From b652f62d19c66b3f643ce7a85aa2fbe018651a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 26 Aug 2020 22:17:42 +0200 Subject: [PATCH 564/848] SavedataParam: Be careful with const char* to string. Might help #13187 --- Core/Dialog/SavedataParam.cpp | 6 +++++- Core/ELF/ParamSFO.cpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index d14f3395e3..37776d489e 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -263,7 +263,11 @@ std::string SavedataParam::GetSaveFilePath(const SceUtilitySavedataParam *param, inline static std::string FixedToString(const char *str, size_t n) { - return std::string(str, strnlen(str, n)); + if (!str) { + return std::string(""); + } else { + return std::string(str, strnlen(str, n)); + } } std::string SavedataParam::GetGameName(const SceUtilitySavedataParam *param) const diff --git a/Core/ELF/ParamSFO.cpp b/Core/ELF/ParamSFO.cpp index 6c164db355..b12b508942 100644 --- a/Core/ELF/ParamSFO.cpp +++ b/Core/ELF/ParamSFO.cpp @@ -155,7 +155,7 @@ int ParamSFOData::GetDataOffset(const u8 *paramsfo, std::string dataName) { for (u32 i = 0; i < header->index_table_entries; i++) { const char *key = (const char *)(key_start + indexTables[i].key_table_offset); - if(std::string(key) == dataName) + if (!strcmp(key, dataName.c_str())) { return data_start + indexTables[i].data_table_offset; } From 90344fdee5bd293f31c091dc002b359117196c76 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 26 Aug 2020 21:44:38 -0700 Subject: [PATCH 565/848] Exception: Don't trust sigaltstack(). Let's just track our allocation separately and free it, always. --- Common/ExceptionHandlerSetup.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 794c849946..0b8f8ac7f0 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -21,6 +21,7 @@ #include "Common/MachineContext.h" static BadAccessHandler g_badAccessHandler; +static void *altStack = nullptr; #ifdef MACHINE_CONTEXT_SUPPORTED @@ -287,10 +288,11 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { g_badAccessHandler = badAccessHandler; stack_t signal_stack{}; + altStack = malloc(SIGSTKSZ); #ifdef __FreeBSD__ - signal_stack.ss_sp = (char*)malloc(SIGSTKSZ); + signal_stack.ss_sp = (char*)altStack; #else - signal_stack.ss_sp = malloc(SIGSTKSZ); + signal_stack.ss_sp = altStack; #endif signal_stack.ss_size = SIGSTKSZ; signal_stack.ss_flags = 0; @@ -300,7 +302,7 @@ void InstallExceptionHandler(BadAccessHandler badAccessHandler) { struct sigaction sa{}; sa.sa_handler = nullptr; sa.sa_sigaction = &sigsegv_handler; - sa.sa_flags = SA_SIGINFO; + sa.sa_flags = SA_SIGINFO | SA_ONSTACK; sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, &old_sa_segv); #ifdef __APPLE__ @@ -313,10 +315,13 @@ void UninstallExceptionHandler() { return; } stack_t signal_stack{}; - stack_t old_stack{}; signal_stack.ss_flags = SS_DISABLE; - if (0 == sigaltstack(&signal_stack, &old_stack) && !(old_stack.ss_flags & SS_DISABLE)) { - free(old_stack.ss_sp); + if (0 != sigaltstack(&signal_stack, nullptr)) { + ERROR_LOG(SYSTEM, "Could not remove signal altstack"); + } + if (altStack) { + free(altStack); + altStack = nullptr; } sigaction(SIGSEGV, &old_sa_segv, nullptr); #ifdef __APPLE__ From 3be729bfc5f1e552ed29ac12dfb99b7638d16c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 00:30:53 +0200 Subject: [PATCH 566/848] Vulkan: Silly typo fix in barrier --- ext/native/thin3d/VulkanQueueRunner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 91767c164d..9cf1309535 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -1070,13 +1070,13 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c if (step.render.framebuffer->depth.layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) { barriers[n].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barriers[n].oldLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; - barriers[n].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barriers[n].newLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; barriers[n].subresourceRange.layerCount = 1; barriers[n].subresourceRange.levelCount = 1; barriers[n].image = step.render.framebuffer->depth.image; barriers[n].srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; barriers[n].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - barriers[n].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barriers[n].subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; barriers[n].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barriers[n].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; stage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; From de4778358e86380336663e4d9d79aba59c0187c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 15:22:00 +0200 Subject: [PATCH 567/848] AspectMask fix --- ext/native/thin3d/VulkanQueueRunner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 9cf1309535..3a02d1ebc9 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -314,7 +314,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; break; default: - _dbg_assert_msg_(false, "PerformBindRT: Unexpected depth layout %d", (int)key.prevDepthLayout); + _dbg_assert_msg_(false, "GetRenderPass: Unexpected depth layout %d", (int)key.prevDepthLayout); break; } @@ -1076,7 +1076,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c barriers[n].image = step.render.framebuffer->depth.image; barriers[n].srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; barriers[n].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - barriers[n].subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + barriers[n].subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; barriers[n].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barriers[n].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; stage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; From b323397c540622d8e2099a614b5d0a5dbe1f8a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 16:29:38 +0200 Subject: [PATCH 568/848] Vulkan: Minor fix for depth/stencil pretransitions. Used DEPTH_ATTACHMENT_OPTIMAL by mistake in barrier. --- ext/native/thin3d/VulkanQueueRunner.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 3a02d1ebc9..373e514a4b 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -997,7 +997,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; vkCmdPipelineBarrier(cmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); iter.fb->color.layout = barrier.newLayout; - } else if (iter.aspect == VK_IMAGE_ASPECT_DEPTH_BIT && iter.fb->depth.layout != iter.targetLayout) { + } else if ((iter.aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && iter.fb->depth.layout != iter.targetLayout) { VkImageMemoryBarrier barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; barrier.oldLayout = iter.fb->depth.layout; barrier.subresourceRange.layerCount = 1; @@ -1067,10 +1067,10 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c stage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; n++; } - if (step.render.framebuffer->depth.layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) { + if (step.render.framebuffer->depth.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { barriers[n].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barriers[n].oldLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; - barriers[n].newLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + barriers[n].oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + barriers[n].newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; barriers[n].subresourceRange.layerCount = 1; barriers[n].subresourceRange.levelCount = 1; barriers[n].image = step.render.framebuffer->depth.image; @@ -1283,7 +1283,7 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step step.render.finalColorLayout, step.render.finalDepthStencilLayout); - // We now do any layout pretransitions as part of the render pass. + // We now do any layout transitions of the framebuffer as part of the render pass. fb->color.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; fb->depth.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; From d54e0b32318a891791106e1f28c4993e28174b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 21:23:41 +0200 Subject: [PATCH 569/848] Fix longstanding depth/stencil view issue in Vulkan. Cleans up validation. We didn't specify DEPTH|STENCIL as aspects for views we rendered to, only DEPTH. Who knows how many of the driver bugs we "found" are this. DEPTH|STENCIL views can't be sampled though, so we create a separate DEPTH view for that. This keeps Katamari working. --- ext/native/thin3d/VulkanRenderManager.cpp | 27 ++++++++++++++--------- ext/native/thin3d/VulkanRenderManager.h | 3 +++ ext/native/thin3d/thin3d_vulkan.cpp | 20 +++++++++++------ 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 1ba685ee70..cc4d3a1497 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -62,7 +62,6 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int res = vkBindImageMemory(vulkan->GetDevice(), img.image, img.memory, 0); _dbg_assert_(res == VK_SUCCESS); - VkImageAspectFlags viewAspects = color ? VK_IMAGE_ASPECT_COLOR_BIT : VK_IMAGE_ASPECT_DEPTH_BIT; VkImageAspectFlags aspects = color ? VK_IMAGE_ASPECT_COLOR_BIT : (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); VkImageViewCreateInfo ivci{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; @@ -70,12 +69,21 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int ivci.format = ici.format; ivci.image = img.image; ivci.viewType = VK_IMAGE_VIEW_TYPE_2D; - ivci.subresourceRange.aspectMask = viewAspects; + ivci.subresourceRange.aspectMask = aspects; ivci.subresourceRange.layerCount = 1; ivci.subresourceRange.levelCount = 1; res = vkCreateImageView(vulkan->GetDevice(), &ivci, nullptr, &img.imageView); _dbg_assert_(res == VK_SUCCESS); + // Separate view for texture sampling that only exposes depth. + if (!color) { + ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + res = vkCreateImageView(vulkan->GetDevice(), &ivci, nullptr, &img.depthSampleView); + _dbg_assert_(res == VK_SUCCESS); + } else { + img.depthSampleView = VK_NULL_HANDLE; + } + VkPipelineStageFlags dstStage; VkAccessFlagBits dstAccessMask; switch (initialLayout) { @@ -985,7 +993,7 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == fb) { - if (aspectBit & VK_IMAGE_ASPECT_COLOR_BIT) { + if (aspectBit == VK_IMAGE_ASPECT_COLOR_BIT) { // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -994,8 +1002,7 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in _assert_msg_(false, "Unexpected color layout %d", (int)steps_[i]->render.finalColorLayout); // May need to shadow the framebuffer if we re-order passes later. } - } - if (aspectBit & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + } else if (aspectBit == VK_IMAGE_ASPECT_DEPTH_BIT) { // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. if (steps_[i]->render.finalDepthStencilLayout == VK_IMAGE_LAYOUT_UNDEFINED) { steps_[i]->render.finalDepthStencilLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -1004,7 +1011,7 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in _assert_msg_(false, "Unexpected depth layout %d", (int)steps_[i]->render.finalDepthStencilLayout); // May need to shadow the framebuffer if we re-order passes later. } - } + } // We don't (yet?) support texturing from stencil images. steps_[i]->render.numReads++; break; } @@ -1014,13 +1021,13 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in curRenderStep_->dependencies.insert(fb); if (!curRenderStep_->preTransitions.empty() && - curRenderStep_->preTransitions.back().fb == fb && - curRenderStep_->preTransitions.back().targetLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + curRenderStep_->preTransitions.back().fb == fb && + curRenderStep_->preTransitions.back().targetLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { // We're done. - return aspectBit == VK_IMAGE_ASPECT_COLOR_BIT ? fb->color.imageView : fb->depth.imageView; + return aspectBit == VK_IMAGE_ASPECT_COLOR_BIT ? fb->color.imageView : fb->depth.depthSampleView; } else { curRenderStep_->preTransitions.push_back({ aspectBit, fb, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }); - return aspectBit == VK_IMAGE_ASPECT_COLOR_BIT ? fb->color.imageView : fb->depth.imageView; + return aspectBit == VK_IMAGE_ASPECT_COLOR_BIT ? fb->color.imageView : fb->depth.depthSampleView; } } diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index f5ff60e3ad..9bac655676 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -23,6 +23,7 @@ struct VKRImage { VkImage image; VkImageView imageView; + VkImageView depthSampleView; VkDeviceMemory memory; VkImageLayout layout; VkFormat format; @@ -67,6 +68,8 @@ public: vulkan_->Delete().QueueDeleteImageView(color.imageView); if (depth.imageView) vulkan_->Delete().QueueDeleteImageView(depth.imageView); + if (depth.depthSampleView) + vulkan_->Delete().QueueDeleteImageView(depth.depthSampleView); if (color.memory) vulkan_->Delete().QueueDeleteDeviceMemory(color.memory); if (depth.memory) diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index e74f5f1615..7e4b504515 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1525,15 +1525,21 @@ void VKContext::BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPass void VKContext::BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) { VKFramebuffer *fb = (VKFramebuffer *)fbo; - if (fb == curFramebuffer_) { - Crash(); - } + // TODO: There are cases where this is okay, actually. + _assert_(fb != curFramebuffer_); int aspect = 0; - if (channelBit & FBChannel::FB_COLOR_BIT) aspect |= VK_IMAGE_ASPECT_COLOR_BIT; - if (channelBit & FBChannel::FB_DEPTH_BIT) aspect |= VK_IMAGE_ASPECT_DEPTH_BIT; - if (channelBit & FBChannel::FB_STENCIL_BIT) aspect |= VK_IMAGE_ASPECT_STENCIL_BIT; - + switch (channelBit) { + case FBChannel::FB_COLOR_BIT: + aspect = VK_IMAGE_ASPECT_COLOR_BIT; + break; + case FBChannel::FB_DEPTH_BIT: + aspect = VK_IMAGE_ASPECT_DEPTH_BIT; + break; + default: + _assert_(false); + break; + } boundTextures_[binding] = nullptr; boundImageView_[binding] = renderManager_.BindFramebufferAsTexture(fb->GetFB(), binding, aspect, attachment); } From 6e9d5ffbd71d0ba3ff239ef48125be1e3e851354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 10:02:50 +0200 Subject: [PATCH 570/848] VulkanRenderManager: Improve logging. LogSteps output is much better. More logging improvements --- GPU/Common/FramebufferManagerCommon.cpp | 14 ++-- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 2 + ext/native/thin3d/VulkanQueueRunner.cpp | 92 ++++++++++++++++------- ext/native/thin3d/VulkanQueueRunner.h | 6 +- ext/native/thin3d/VulkanRenderManager.cpp | 52 ++++++++++++- ext/native/thin3d/VulkanRenderManager.h | 58 +++----------- 7 files changed, 140 insertions(+), 86 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 1fb3581e50..29470e8ce9 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -516,8 +516,10 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe textureCache_->ForgetLastTexture(); shaderManager_->DirtyLastShader(); - // Copy depth pixel value from the read framebuffer to the draw framebuffer if (prevVfb) { + // Copy depth value from the previously bound framebuffer to the current one. + // TODO: We should only do this if they are actually pointing to the same depth buffer address, surely.. + bool hasNewerDepth = prevVfb->last_frame_depth_render != 0 && prevVfb->last_frame_depth_render >= vfb->last_frame_depth_updated; if (!prevVfb->fbo || !vfb->fbo || !useBufferedRendering_ || !hasNewerDepth || isClearingDepth) { // If depth wasn't updated, then we're at least "two degrees" away from the data. @@ -1068,11 +1070,11 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } shaderManager_->DirtyLastShader(); - char name[256]; - snprintf(name, sizeof(name), "%08x_%08x", vfb->fb_address, vfb->z_address); - vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, name }); + char tag[256]; + snprintf(tag, sizeof(tag), "%08x_%08x_%dx%d", vfb->fb_address, vfb->z_address, w, h); + vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, tag }); if (old.fbo) { - INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %d x %d x %d", vfb->fb_address, w, h, vfb->format); + INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %dx%dx%s", vfb->fb_address, w, h, GeBufferFormatToString(vfb->format)); if (vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); if (!skipCopy) { @@ -1088,7 +1090,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, } if (!vfb->fbo) { - ERROR_LOG(FRAMEBUF, "Error creating FBO during resize! %d x %d", vfb->renderWidth, vfb->renderHeight); + ERROR_LOG(FRAMEBUF, "Error creating FBO during resize! %dx%d", vfb->renderWidth, vfb->renderHeight); vfb->last_frame_failed = gpuStats.numFlips; } } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index b3d39f7289..6a5d2415f9 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -141,7 +141,7 @@ void GPU_Vulkan::LoadCache(std::string filename) { } fclose(f); if (!result) { - WARN_LOG(G3D, "Bad Vulkan pipeline cache"); + WARN_LOG(G3D, "Incompatible Vulkan pipeline cache - rebuilding."); // Bad cache file for this GPU/Driver/etc. Delete it. File::Delete(filename); } else { diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 520ea6305b..df8446b6bb 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -583,6 +583,8 @@ struct StoredVulkanPipelineKey { } }; +// If you're looking for how to invalidate the cache, it's done in ShaderManagerVulkan, look for CACHE_VERSION and increment it. +// (Header of the same file this is stored in). void PipelineManagerVulkan::SaveCache(FILE *file, bool saveRawPipelineCache, ShaderManagerVulkan *shaderManager, Draw::DrawContext *drawContext) { VulkanRenderManager *rm = (VulkanRenderManager *)drawContext->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); VulkanQueueRunner *queueRunner = rm->GetQueueRunner(); diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 373e514a4b..79547ef39b 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -238,7 +238,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { attachments[1].initialLayout = VK_IMAGE_LAYOUT_GENERAL; attachments[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL; #else - attachments[1].initialLayout = key.prevDepthLayout; + attachments[1].initialLayout = key.prevDepthStencilLayout; attachments[1].finalLayout = key.finalDepthStencilLayout; #endif attachments[1].flags = 0; @@ -294,7 +294,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { break; } - switch (key.prevDepthLayout) { + switch (key.prevDepthStencilLayout) { case VK_IMAGE_LAYOUT_UNDEFINED: // No need to specify stage or access. break; @@ -314,7 +314,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { deps[numDeps].srcStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; break; default: - _dbg_assert_msg_(false, "GetRenderPass: Unexpected depth layout %d", (int)key.prevDepthLayout); + _dbg_assert_msg_(false, "GetRenderPass: Unexpected depth layout %d", (int)key.prevDepthStencilLayout); break; } @@ -730,6 +730,16 @@ void VulkanQueueRunner::ApplySonicHack(std::vector &steps) { } } +const char *AspectToString(VkImageAspectFlags aspect) { + switch (aspect) { + case VK_IMAGE_ASPECT_COLOR_BIT: return "COLOR"; + case VK_IMAGE_ASPECT_DEPTH_BIT: return "DEPTH"; + case VK_IMAGE_ASPECT_STENCIL_BIT: return "STENCIL"; + case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: return "DEPTHSTENCIL"; + default: return "UNUSUAL"; + } +} + std::string VulkanQueueRunner::StepToString(const VKRStep &step) const { char buffer[256]; switch (step.stepType) { @@ -737,23 +747,23 @@ std::string VulkanQueueRunner::StepToString(const VKRStep &step) const { { int w = step.render.framebuffer ? step.render.framebuffer->width : vulkan_->GetBackbufferWidth(); int h = step.render.framebuffer ? step.render.framebuffer->height : vulkan_->GetBackbufferHeight(); - snprintf(buffer, sizeof(buffer), "RenderPass %s (draws: %d, %dx%d, fb: %p, )", step.tag, step.render.numDraws, w, h, step.render.framebuffer); + snprintf(buffer, sizeof(buffer), "RENDER %s (draws: %d, %dx%d, fb: %p, )", step.tag, step.render.numDraws, w, h, step.render.framebuffer); break; } case VKRStepType::COPY: - snprintf(buffer, sizeof(buffer), "Copy '%s' (%dx%d)", step.tag, step.copy.srcRect.extent.width, step.copy.srcRect.extent.height); + snprintf(buffer, sizeof(buffer), "COPY '%s' %s -> %s (%dx%d, %s)", step.tag, step.copy.src->tag.c_str(), step.copy.dst->tag.c_str(), step.copy.srcRect.extent.width, step.copy.srcRect.extent.height, AspectToString(step.copy.aspectMask)); break; case VKRStepType::BLIT: - snprintf(buffer, sizeof(buffer), "Blit '%s' (%dx%d->%dx%d)", step.tag, step.blit.srcRect.extent.width, step.blit.srcRect.extent.height, step.blit.dstRect.extent.width, step.blit.dstRect.extent.height); + snprintf(buffer, sizeof(buffer), "BLIT '%s' %s -> %s (%dx%d->%dx%d, %s)", step.tag, step.copy.src->tag.c_str(), step.copy.dst->tag.c_str(), step.blit.srcRect.extent.width, step.blit.srcRect.extent.height, step.blit.dstRect.extent.width, step.blit.dstRect.extent.height, AspectToString(step.blit.aspectMask)); break; case VKRStepType::READBACK: - snprintf(buffer, sizeof(buffer), "Readback '%s' (%dx%d, fb: %p)", step.tag, step.readback.srcRect.extent.width, step.readback.srcRect.extent.height, step.readback.src); + snprintf(buffer, sizeof(buffer), "READBACK '%s' %s (%dx%d, %s)", step.tag, step.readback.src->tag.c_str(), step.readback.srcRect.extent.width, step.readback.srcRect.extent.height, AspectToString(step.readback.aspectMask)); break; case VKRStepType::READBACK_IMAGE: - snprintf(buffer, sizeof(buffer), "ReadbackImage '%s' (%dx%d)", step.tag, step.readback_image.srcRect.extent.width, step.readback_image.srcRect.extent.height); + snprintf(buffer, sizeof(buffer), "READBACK_IMAGE '%s' (%dx%d)", step.tag, step.readback_image.srcRect.extent.width, step.readback_image.srcRect.extent.height); break; case VKRStepType::RENDER_SKIP: - snprintf(buffer, sizeof(buffer), "(SKIPPED RenderPass) %s", step.tag); + snprintf(buffer, sizeof(buffer), "(RENDER_SKIP) %s", step.tag); break; default: buffer[0] = 0; @@ -849,14 +859,13 @@ void VulkanQueueRunner::ApplyRenderPassMerge(std::vector &steps) { } } -void VulkanQueueRunner::LogSteps(const std::vector &steps) { - INFO_LOG(G3D, "======================================="); +void VulkanQueueRunner::LogSteps(const std::vector &steps, bool verbose) { + INFO_LOG(G3D, "=================== FRAME ===================="); for (size_t i = 0; i < steps.size(); i++) { const VKRStep &step = *steps[i]; - INFO_LOG(G3D, "%s", StepToString(step).c_str()); switch (step.stepType) { case VKRStepType::RENDER: - LogRenderPass(step); + LogRenderPass(step, verbose); break; case VKRStepType::COPY: LogCopy(step); @@ -875,6 +884,7 @@ void VulkanQueueRunner::LogSteps(const std::vector &steps) { break; } } + INFO_LOG(G3D, "------------------- SUBMIT ------------------"); } const char *RenderPassActionName(VKRRenderPassAction a) { @@ -889,10 +899,37 @@ const char *RenderPassActionName(VKRRenderPassAction a) { return "?"; } -void VulkanQueueRunner::LogRenderPass(const VKRStep &pass) { +const char *ImageLayoutToString(VkImageLayout layout) { + switch (layout) { + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return "COLOR_ATTACHMENT"; + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "DEPTH_STENCIL_ATTACHMENT"; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return "SHADER_READ_ONLY"; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return "TRANSFER_SRC"; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return "TRANSFER_DST"; + case VK_IMAGE_LAYOUT_GENERAL: return "GENERAL"; + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: return "PRESENT_SRC_KHR"; + case VK_IMAGE_LAYOUT_UNDEFINED: return "UNDEFINED"; + default: return "(unknown)"; + } +} + +void VulkanQueueRunner::LogRenderPass(const VKRStep &pass, bool verbose) { const auto &r = pass.render; - int fb = (int)(intptr_t)(r.framebuffer ? r.framebuffer->framebuf : 0); - INFO_LOG(G3D, "RenderPass Begin(%x, %s, %s, %s)", fb, RenderPassActionName(r.color), RenderPassActionName(r.depth), RenderPassActionName(r.stencil)); + const char *framebuf = r.framebuffer ? r.framebuffer->tag.c_str() : "backbuffer"; + int w = r.framebuffer ? r.framebuffer->width : vulkan_->GetBackbufferWidth(); + int h = r.framebuffer ? r.framebuffer->height : vulkan_->GetBackbufferHeight(); + + INFO_LOG(G3D, "RENDER Begin(%s, draws: %d, %dx%d, %s, %s, %s)", framebuf, r.numDraws, w, h, RenderPassActionName(r.color), RenderPassActionName(r.depth), RenderPassActionName(r.stencil)); + // TODO: Log these in detail. + for (int i = 0; i < pass.preTransitions.size(); i++) { + INFO_LOG(G3D, " PRETRANSITION: %s %s -> %s", pass.preTransitions[i].fb->tag.c_str(), AspectToString(pass.preTransitions[i].aspect), ImageLayoutToString(pass.preTransitions[i].targetLayout)); + } + + if (!verbose) { + INFO_LOG(G3D, "RENDER End(%s) - %d commands executed", framebuf, (int)pass.commands.size()); + return; + } + for (auto &cmd : pass.commands) { switch (cmd.cmd) { case VKRRenderCommand::REMOVED: @@ -931,7 +968,7 @@ void VulkanQueueRunner::LogRenderPass(const VKRStep &pass) { break; } } - INFO_LOG(G3D, "RenderPass End(%x)", fb); + INFO_LOG(G3D, "RENDER End(%s)", framebuf); } void VulkanQueueRunner::LogCopy(const VKRStep &step) { @@ -952,6 +989,7 @@ void VulkanQueueRunner::LogReadbackImage(const VKRStep &step) { void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer cmd) { // TODO: If there are multiple, we can transition them together. + for (const auto &iter : step.preTransitions) { if (iter.aspect == VK_IMAGE_ASPECT_COLOR_BIT && iter.fb->color.layout != iter.targetLayout) { VkImageMemoryBarrier barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; @@ -1044,6 +1082,10 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c // Don't execute empty renderpasses that keep the contents. if (step.commands.empty() && step.render.color == VKRRenderPassAction::KEEP && step.render.depth == VKRRenderPassAction::KEEP && step.render.stencil == VKRRenderPassAction::KEEP) { // Nothing to do. + + // TODO: Though - a later step might have used this step's finalColorLayout etc to get things in a layout it expects. + // Should we just do a barrier? Or just let the later step deal with not having things in its preferred layout, like now? + return; } @@ -1084,10 +1126,12 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c } if (stage) { vkCmdPipelineBarrier(cmd, stage, stage, 0, 0, nullptr, 0, nullptr, n, barriers); + // No need to modify the image layouts here - it's just an execution barrier. } } // This is supposed to bind a vulkan render pass to the command buffer. + // This reads the layout of the color and depth images, and chooses a render pass using them. PerformBindFramebufferAsRenderTarget(step, cmd); int curWidth = step.render.framebuffer ? step.render.framebuffer->width : vulkan_->GetBackbufferWidth(); @@ -1355,7 +1399,7 @@ void VulkanQueueRunner::PerformCopy(const VKRStep &step, VkCommandBuffer cmd) { } } - // We can't copy only depth or only stencil unfortunately. + // We can't copy only depth or only stencil unfortunately - or can we?. if (step.copy.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { if (src->depth.layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) { SetupTransitionToTransferSrc(src->depth, srcBarriers[srcCount++], srcStage, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); @@ -1378,16 +1422,8 @@ void VulkanQueueRunner::PerformCopy(const VKRStep &step, VkCommandBuffer cmd) { vkCmdCopyImage(cmd, src->color.image, src->color.layout, dst->color.image, dst->color.layout, 1, ©); } if (step.copy.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - copy.srcSubresource.aspectMask = 0; - copy.dstSubresource.aspectMask = 0; - if (step.copy.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) { - copy.srcSubresource.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; - copy.dstSubresource.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; - } - if (step.copy.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { - copy.srcSubresource.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - copy.dstSubresource.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - } + copy.srcSubresource.aspectMask = step.copy.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + copy.dstSubresource.aspectMask = step.copy.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); vkCmdCopyImage(cmd, src->depth.image, src->depth.layout, dst->depth.image, dst->depth.layout, 1, ©); } } diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index a89951af3b..660d406da9 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -182,7 +182,7 @@ public: // RunSteps can modify steps but will leave it in a valid state. void RunSteps(VkCommandBuffer cmd, std::vector &steps, QueueProfileContext *profile); - void LogSteps(const std::vector &steps); + void LogSteps(const std::vector &steps, bool verbose); std::string StepToString(const VKRStep &step) const; @@ -210,7 +210,7 @@ public: VKRRenderPassAction depthLoadAction; VKRRenderPassAction stencilLoadAction; VkImageLayout prevColorLayout; - VkImageLayout prevDepthLayout; + VkImageLayout prevDepthStencilLayout; VkImageLayout finalColorLayout; VkImageLayout finalDepthStencilLayout; }; @@ -250,7 +250,7 @@ private: void PerformReadback(const VKRStep &pass, VkCommandBuffer cmd); void PerformReadbackImage(const VKRStep &pass, VkCommandBuffer cmd); - void LogRenderPass(const VKRStep &pass); + void LogRenderPass(const VKRStep &pass, bool verbose); void LogCopy(const VKRStep &pass); void LogBlit(const VKRStep &pass); void LogReadback(const VKRStep &pass); diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index cc4d3a1497..4960b5c045 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -19,8 +19,57 @@ #define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL #endif +VKRFramebuffer::VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height, const char *tag) : vulkan_(vk) { + width = _width; + height = _height; -void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int width, int height, VkFormat format, VkImageLayout initialLayout, bool color) { + CreateImage(vulkan_, initCmd, color, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true, tag); + CreateImage(vulkan_, initCmd, depth, width, height, vulkan_->GetDeviceInfo().preferredDepthStencilFormat, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false, tag); + + VkFramebufferCreateInfo fbci{ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; + VkImageView views[2]{}; + + fbci.renderPass = renderPass; + fbci.attachmentCount = 2; + fbci.pAttachments = views; + views[0] = color.imageView; + views[1] = depth.imageView; + fbci.width = width; + fbci.height = height; + fbci.layers = 1; + + vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf); + if (vk->Extensions().EXT_debug_utils) { + vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_color_%s", tag).c_str()); + vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_depth_%s", tag).c_str()); + vk->SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, StringFromFormat("fb_%s", tag).c_str()); + } + + if (tag) { + this->tag = tag; + } +} + +VKRFramebuffer::~VKRFramebuffer() { + if (color.image) + vulkan_->Delete().QueueDeleteImage(color.image); + if (depth.image) + vulkan_->Delete().QueueDeleteImage(depth.image); + if (color.imageView) + vulkan_->Delete().QueueDeleteImageView(color.imageView); + if (depth.imageView) + vulkan_->Delete().QueueDeleteImageView(depth.imageView); + if (depth.depthSampleView) + vulkan_->Delete().QueueDeleteImageView(depth.depthSampleView); + if (color.memory) + vulkan_->Delete().QueueDeleteDeviceMemory(color.memory); + if (depth.memory) + vulkan_->Delete().QueueDeleteDeviceMemory(depth.memory); + if (framebuf) + vulkan_->Delete().QueueDeleteFramebuffer(framebuf); +} + +void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int width, int height, VkFormat format, VkImageLayout initialLayout, bool color, const char *tag) { VkImageCreateInfo ici{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; ici.arrayLayers = 1; ici.mipLevels = 1; @@ -111,6 +160,7 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int img.layout = initialLayout; img.format = format; + img.tag = tag ? tag : "N/A"; } VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan) : vulkan_(vulkan), queueRunner_(vulkan) { diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 9bac655676..50657051ef 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -21,62 +21,25 @@ // Simple independent framebuffer image. Gets its own allocation, we don't have that many framebuffers so it's fine // to let them have individual non-pooled allocations. Until it's not fine. We'll see. struct VKRImage { + // These four are "immutable". VkImage image; VkImageView imageView; VkImageView depthSampleView; VkDeviceMemory memory; - VkImageLayout layout; VkFormat format; + + // This one is used by QueueRunner's Perform functions to keep track. CANNOT be used anywhere else due to sync issues. + VkImageLayout layout; + + // For debugging. + std::string tag; }; -void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int width, int height, VkFormat format, VkImageLayout initialLayout, bool color); +void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int width, int height, VkFormat format, VkImageLayout initialLayout, bool color, const char *tag); class VKRFramebuffer { public: - VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height, const char *tag) : vulkan_(vk) { - width = _width; - height = _height; - - CreateImage(vulkan_, initCmd, color, width, height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); - CreateImage(vulkan_, initCmd, depth, width, height, vulkan_->GetDeviceInfo().preferredDepthStencilFormat, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false); - - VkFramebufferCreateInfo fbci{ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; - VkImageView views[2]{}; - - fbci.renderPass = renderPass; - fbci.attachmentCount = 2; - fbci.pAttachments = views; - views[0] = color.imageView; - views[1] = depth.imageView; - fbci.width = width; - fbci.height = height; - fbci.layers = 1; - - vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf); - if (vk->Extensions().EXT_debug_utils) { - vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_color_%s", tag).c_str()); - vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_depth_%s", tag).c_str()); - vk->SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, StringFromFormat("fb_%s", tag).c_str()); - } - } - - ~VKRFramebuffer() { - if (color.image) - vulkan_->Delete().QueueDeleteImage(color.image); - if (depth.image) - vulkan_->Delete().QueueDeleteImage(depth.image); - if (color.imageView) - vulkan_->Delete().QueueDeleteImageView(color.imageView); - if (depth.imageView) - vulkan_->Delete().QueueDeleteImageView(depth.imageView); - if (depth.depthSampleView) - vulkan_->Delete().QueueDeleteImageView(depth.depthSampleView); - if (color.memory) - vulkan_->Delete().QueueDeleteDeviceMemory(color.memory); - if (depth.memory) - vulkan_->Delete().QueueDeleteDeviceMemory(depth.memory); - if (framebuf) - vulkan_->Delete().QueueDeleteFramebuffer(framebuf); - } + VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRenderPass renderPass, int _width, int _height, const char *tag); + ~VKRFramebuffer(); int numShadows = 1; // TODO: Support this. @@ -87,6 +50,7 @@ public: int height = 0; VulkanContext *vulkan_; + std::string tag; }; enum class VKRRunType { From 4e841ca3a62d9abb7d8d18393915f8b69273cf41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 16:51:39 +0200 Subject: [PATCH 571/848] Naming fix, better names for temp fbos --- GPU/Common/FramebufferManagerCommon.cpp | 14 ++++++++------ ext/native/thin3d/thin3d_vulkan.cpp | 2 ++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 29470e8ce9..b3348cbc36 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1760,8 +1760,8 @@ void FramebufferManagerCommon::DestroyAllFBOs() { tempFBOs_.clear(); } -Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u16 h, Draw::FBColorDepth depth) { - u64 key = ((u64)reason << 48) | ((u64)depth << 32) | ((u32)w << 16) | h; +Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u16 h, Draw::FBColorDepth color_depth) { + u64 key = ((u64)reason << 48) | ((u64)color_depth << 32) | ((u32)w << 16) | h; auto it = tempFBOs_.find(key); if (it != tempFBOs_.end()) { it->second.last_frame_used = gpuStats.numFlips; @@ -1770,10 +1770,12 @@ Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u textureCache_->ForgetLastTexture(); bool z_stencil = reason == TempFBO::STENCIL; - const char *name = "temp_fbo"; - Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, z_stencil, depth, name }); - if (!fbo) - return fbo; + char name[128]; + snprintf(name, sizeof(name), "temp_fbo_%dx%d%s", w, h, z_stencil ? "_depth" : ""); + Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, z_stencil, color_depth, name }); + if (!fbo) { + return nullptr; + } const TempFBOInfo info = { fbo, gpuStats.numFlips }; tempFBOs_[key] = info; diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 7e4b504515..3308c7f657 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1460,6 +1460,8 @@ private: Framebuffer *VKContext::CreateFramebuffer(const FramebufferDesc &desc) { VkCommandBuffer cmd = renderManager_.GetInitCmd(); + // TODO: We always create with depth here, even when it's not needed (such as color temp FBOs). + // Should optimize those away. VKRFramebuffer *vkrfb = new VKRFramebuffer(vulkan_, cmd, renderManager_.GetFramebufferRenderPass(), desc.width, desc.height, desc.tag); return new VKFramebuffer(vkrfb); } From 95a4cd37fc64524532a2172b5387adcbd19b7fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 16:53:26 +0200 Subject: [PATCH 572/848] Improve LogSteps further. Break out PreprocessSteps. --- ext/native/thin3d/VulkanQueueRunner.cpp | 91 ++++++++++++----------- ext/native/thin3d/VulkanQueueRunner.h | 2 +- ext/native/thin3d/VulkanRenderManager.cpp | 3 +- 3 files changed, 50 insertions(+), 46 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 79547ef39b..94e816051d 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -378,9 +378,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { return pass; } -void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &steps, QueueProfileContext *profile) { - if (profile) - profile->cpuStartTime = real_time_now(); +void VulkanQueueRunner::PreprocessSteps(std::vector &steps) { // Optimizes renderpasses, then sequences them. // Planned optimizations: // * Create copies of render target that are rendered to multiple times and textured from in sequence, and push those render passes @@ -450,6 +448,11 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &st ApplyRenderPassMerge(steps); } } +} + +void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &steps, QueueProfileContext *profile) { + if (profile) + profile->cpuStartTime = real_time_now(); bool emitLabels = vulkan_->Extensions().EXT_debug_utils; for (size_t i = 0; i < steps.size(); i++) { @@ -919,56 +922,55 @@ void VulkanQueueRunner::LogRenderPass(const VKRStep &pass, bool verbose) { int w = r.framebuffer ? r.framebuffer->width : vulkan_->GetBackbufferWidth(); int h = r.framebuffer ? r.framebuffer->height : vulkan_->GetBackbufferHeight(); - INFO_LOG(G3D, "RENDER Begin(%s, draws: %d, %dx%d, %s, %s, %s)", framebuf, r.numDraws, w, h, RenderPassActionName(r.color), RenderPassActionName(r.depth), RenderPassActionName(r.stencil)); + INFO_LOG(G3D, "RENDER %s Begin(%s, draws: %d, %dx%d, %s, %s, %s)", pass.tag, framebuf, r.numDraws, w, h, RenderPassActionName(r.color), RenderPassActionName(r.depth), RenderPassActionName(r.stencil)); // TODO: Log these in detail. for (int i = 0; i < pass.preTransitions.size(); i++) { INFO_LOG(G3D, " PRETRANSITION: %s %s -> %s", pass.preTransitions[i].fb->tag.c_str(), AspectToString(pass.preTransitions[i].aspect), ImageLayoutToString(pass.preTransitions[i].targetLayout)); } - if (!verbose) { - INFO_LOG(G3D, "RENDER End(%s) - %d commands executed", framebuf, (int)pass.commands.size()); - return; - } + if (verbose) { + for (auto &cmd : pass.commands) { + switch (cmd.cmd) { + case VKRRenderCommand::REMOVED: + INFO_LOG(G3D, " (Removed)"); + break; - for (auto &cmd : pass.commands) { - switch (cmd.cmd) { - case VKRRenderCommand::REMOVED: - INFO_LOG(G3D, " (Removed)"); - break; + case VKRRenderCommand::BIND_PIPELINE: + INFO_LOG(G3D, " BindPipeline(%x)", (int)(intptr_t)cmd.pipeline.pipeline); + break; + case VKRRenderCommand::BLEND: + INFO_LOG(G3D, " BlendColor(%08x)", cmd.blendColor.color); + break; + case VKRRenderCommand::CLEAR: + INFO_LOG(G3D, " Clear"); + break; + case VKRRenderCommand::DRAW: + INFO_LOG(G3D, " Draw(%d)", cmd.draw.count); + break; + case VKRRenderCommand::DRAW_INDEXED: + INFO_LOG(G3D, " DrawIndexed(%d)", cmd.drawIndexed.count); + break; + case VKRRenderCommand::SCISSOR: + INFO_LOG(G3D, " Scissor(%d, %d, %d, %d)", (int)cmd.scissor.scissor.offset.x, (int)cmd.scissor.scissor.offset.y, (int)cmd.scissor.scissor.extent.width, (int)cmd.scissor.scissor.extent.height); + break; + case VKRRenderCommand::STENCIL: + INFO_LOG(G3D, " Stencil(ref=%d, compare=%d, write=%d)", cmd.stencil.stencilRef, cmd.stencil.stencilCompareMask, cmd.stencil.stencilWriteMask); + break; + case VKRRenderCommand::VIEWPORT: + INFO_LOG(G3D, " Viewport(%f, %f, %f, %f, %f, %f)", cmd.viewport.vp.x, cmd.viewport.vp.y, cmd.viewport.vp.width, cmd.viewport.vp.height, cmd.viewport.vp.minDepth, cmd.viewport.vp.maxDepth); + break; + case VKRRenderCommand::PUSH_CONSTANTS: + INFO_LOG(G3D, " PushConstants(%d)", cmd.push.size); + break; - case VKRRenderCommand::BIND_PIPELINE: - INFO_LOG(G3D, " BindPipeline(%x)", (int)(intptr_t)cmd.pipeline.pipeline); - break; - case VKRRenderCommand::BLEND: - INFO_LOG(G3D, " BlendColor(%08x)", cmd.blendColor.color); - break; - case VKRRenderCommand::CLEAR: - INFO_LOG(G3D, " Clear"); - break; - case VKRRenderCommand::DRAW: - INFO_LOG(G3D, " Draw(%d)", cmd.draw.count); - break; - case VKRRenderCommand::DRAW_INDEXED: - INFO_LOG(G3D, " DrawIndexed(%d)", cmd.drawIndexed.count); - break; - case VKRRenderCommand::SCISSOR: - INFO_LOG(G3D, " Scissor(%d, %d, %d, %d)", (int)cmd.scissor.scissor.offset.x, (int)cmd.scissor.scissor.offset.y, (int)cmd.scissor.scissor.extent.width, (int)cmd.scissor.scissor.extent.height); - break; - case VKRRenderCommand::STENCIL: - INFO_LOG(G3D, " Stencil(ref=%d, compare=%d, write=%d)", cmd.stencil.stencilRef, cmd.stencil.stencilCompareMask, cmd.stencil.stencilWriteMask); - break; - case VKRRenderCommand::VIEWPORT: - INFO_LOG(G3D, " Viewport(%f, %f, %f, %f, %f, %f)", cmd.viewport.vp.x, cmd.viewport.vp.y, cmd.viewport.vp.width, cmd.viewport.vp.height, cmd.viewport.vp.minDepth, cmd.viewport.vp.maxDepth); - break; - case VKRRenderCommand::PUSH_CONSTANTS: - INFO_LOG(G3D, " PushConstants(%d)", cmd.push.size); - break; - - case VKRRenderCommand::NUM_RENDER_COMMANDS: - break; + case VKRRenderCommand::NUM_RENDER_COMMANDS: + break; + } } } - INFO_LOG(G3D, "RENDER End(%s)", framebuf); + + INFO_LOG(G3D, " Final: %s %s", ImageLayoutToString(pass.render.finalColorLayout), ImageLayoutToString(pass.render.finalDepthStencilLayout)); + INFO_LOG(G3D, "RENDER End(%s) - %d commands executed", framebuf, (int)pass.commands.size()); } void VulkanQueueRunner::LogCopy(const VKRStep &step) { @@ -1406,6 +1408,7 @@ void VulkanQueueRunner::PerformCopy(const VKRStep &step, VkCommandBuffer cmd) { } if (dst->depth.layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { SetupTransitionToTransferDst(dst->depth, dstBarriers[dstCount++], dstStage, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + _dbg_assert_(dst->depth.layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); } } diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index 660d406da9..c73c1acecd 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -180,7 +180,7 @@ public: backbufferImage_ = img; } - // RunSteps can modify steps but will leave it in a valid state. + void PreprocessSteps(std::vector &steps); void RunSteps(VkCommandBuffer cmd, std::vector &steps, QueueProfileContext *profile); void LogSteps(const std::vector &steps, bool verbose); diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 4960b5c045..9530b2b41d 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -1256,7 +1256,8 @@ void VulkanRenderManager::Run(int frame) { FrameData &frameData = frameData_[frame]; auto &stepsOnThread = frameData_[frame].steps; VkCommandBuffer cmd = frameData.mainCmd; - // queueRunner_.LogSteps(stepsOnThread); + queueRunner_.PreprocessSteps(stepsOnThread); + //queueRunner_.LogSteps(stepsOnThread, false); queueRunner_.RunSteps(cmd, stepsOnThread, frameData.profilingEnabled_ ? &frameData.profile : nullptr); stepsOnThread.clear(); From 3607f0ab3286d6260ab74f7918aa120398fb924b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 21:07:54 +0200 Subject: [PATCH 573/848] Log validation errors normally as well as using OutputDebugString. --- Common/Vulkan/VulkanDebug.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp index 47a82b63a7..5567586822 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/Vulkan/VulkanDebug.cpp @@ -75,14 +75,13 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( DebugBreak(); } } -#else - // TODO: Improve. +#endif + if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { ERROR_LOG(G3D, "VKDEBUG: %s", msg.c_str()); } else { WARN_LOG(G3D, "VKDEBUG: %s", msg.c_str()); } -#endif // false indicates that layer should not bail-out of an // API call that had validation failures. This may mean that the From b58f5e46aee7b9687826ce60a0133f87530a765c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 11:48:43 +0200 Subject: [PATCH 574/848] Correctly update image layout to the final one after a render pass. --- ext/native/thin3d/VulkanQueueRunner.cpp | 10 +++++----- ext/native/thin3d/VulkanQueueRunner.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 94e816051d..7a88ac8b1d 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -1132,8 +1132,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c } } - // This is supposed to bind a vulkan render pass to the command buffer. - // This reads the layout of the color and depth images, and chooses a render pass using them. + // This reads the layout of the color and depth images, and chooses a render pass using them that + // will transition to the desired final layout. PerformBindFramebufferAsRenderTarget(step, cmd); int curWidth = step.render.framebuffer ? step.render.framebuffer->width : vulkan_->GetBackbufferWidth(); @@ -1329,9 +1329,9 @@ void VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKRStep &step step.render.finalColorLayout, step.render.finalDepthStencilLayout); - // We now do any layout transitions of the framebuffer as part of the render pass. - fb->color.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - fb->depth.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + // We now do any layout pretransitions as part of the render pass. + fb->color.layout = step.render.finalColorLayout; + fb->depth.layout = step.render.finalDepthStencilLayout; if (step.render.color == VKRRenderPassAction::CLEAR) { Uint8x4ToFloat4(clearVal[0].color.float32, step.render.clearColor); diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index c73c1acecd..e8daa6d599 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -218,8 +218,8 @@ public: // Only call this from the render thread! Also ok during initialization (LoadCache). VkRenderPass GetRenderPass( VKRRenderPassAction colorLoadAction, VKRRenderPassAction depthLoadAction, VKRRenderPassAction stencilLoadAction, - VkImageLayout prevColorLayout, VkImageLayout prevDepthLayout, VkImageLayout finalColorLayout, VkImageLayout finalDepthStencilLayout) { - RPKey key{ colorLoadAction, depthLoadAction, stencilLoadAction, prevColorLayout, prevDepthLayout, finalColorLayout, finalDepthStencilLayout }; + VkImageLayout prevColorLayout, VkImageLayout prevDepthStencilLayout, VkImageLayout finalColorLayout, VkImageLayout finalDepthStencilLayout) { + RPKey key{ colorLoadAction, depthLoadAction, stencilLoadAction, prevColorLayout, prevDepthStencilLayout, finalColorLayout, finalDepthStencilLayout }; return GetRenderPass(key); } From f64d36664ec067478310b071072831e9f7c49d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 15:22:09 +0200 Subject: [PATCH 575/848] Fix final subpass dependency for depth --- ext/native/thin3d/VulkanQueueRunner.cpp | 26 +++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 7a88ac8b1d..655002ead0 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -351,12 +351,34 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) { break; } + switch (key.finalDepthStencilLayout) { + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + deps[numDeps].dstAccessMask |= VK_ACCESS_SHADER_READ_BIT; + deps[numDeps].dstStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + deps[numDeps].dstAccessMask |= VK_ACCESS_TRANSFER_READ_BIT; + deps[numDeps].dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + deps[numDeps].dstAccessMask |= VK_ACCESS_TRANSFER_READ_BIT; + deps[numDeps].dstStageMask |= VK_PIPELINE_STAGE_TRANSFER_BIT; + break; + case VK_IMAGE_LAYOUT_UNDEFINED: + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + // Nothing to do. + break; + default: + _dbg_assert_msg_(false, "GetRenderPass: Unexpected final depth layout %d", (int)key.finalDepthStencilLayout); + break; + } + if (deps[numDeps].dstAccessMask) { deps[numDeps].srcSubpass = 0; deps[numDeps].dstSubpass = VK_SUBPASS_EXTERNAL; deps[numDeps].dependencyFlags = 0; - deps[numDeps].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - deps[numDeps].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + deps[numDeps].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + deps[numDeps].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; numDeps++; } From 0b8e377872ba999c2431aec590902a99ceb75a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 22:59:27 +0200 Subject: [PATCH 576/848] Address feedback from #13341. --- GPU/Common/FramebufferManagerCommon.cpp | 2 +- ext/native/thin3d/VulkanRenderManager.cpp | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index b3348cbc36..3b49bad205 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -518,7 +518,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe if (prevVfb) { // Copy depth value from the previously bound framebuffer to the current one. - // TODO: We should only do this if they are actually pointing to the same depth buffer address, surely.. + // We check that the address is the same within BlitFramebufferDepth before actually blitting. bool hasNewerDepth = prevVfb->last_frame_depth_render != 0 && prevVfb->last_frame_depth_render >= vfb->last_frame_depth_updated; if (!prevVfb->fbo || !vfb->fbo || !useBufferedRendering_ || !hasNewerDepth || isClearingDepth) { diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 9530b2b41d..3c6810cc3f 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -39,13 +39,10 @@ VKRFramebuffer::VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRen fbci.layers = 1; vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf); - if (vk->Extensions().EXT_debug_utils) { + if (tag && vk->Extensions().EXT_debug_utils) { vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_color_%s", tag).c_str()); vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_depth_%s", tag).c_str()); vk->SetDebugName(framebuf, VK_OBJECT_TYPE_FRAMEBUFFER, StringFromFormat("fb_%s", tag).c_str()); - } - - if (tag) { this->tag = tag; } } From 924329321c201360c85ec9b71fbdc669d1d25a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 27 Aug 2020 23:02:17 +0200 Subject: [PATCH 577/848] Throw in a minor simplification in depal. --- GPU/Common/DepalettizeShaderCommon.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index 3e9cd383ab..e95691cc8e 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -73,11 +73,7 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang WRITE(p, " float4 color = tex.Sample(texSamp, v_texcoord0);\n"); } else { WRITE(p, "void main() {\n"); - if (pixelFormat == GE_FORMAT_DEPTH16) { - WRITE(p, " float color = texture(tex, v_texcoord0).r;\n"); - } else { - WRITE(p, " vec4 color = texture(tex, v_texcoord0);\n"); - } + WRITE(p, " vec4 color = texture(tex, v_texcoord0);\n"); } int mask = gstate.getClutIndexMask(); @@ -119,7 +115,7 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang break; case GE_FORMAT_DEPTH16: // Remap depth buffer. - WRITE(p, " float depth = (color - z_offset) * z_scale;\n"); + WRITE(p, " float depth = (color.x - z_offset) * z_scale;\n"); WRITE(p, " int index = int(clamp(depth, 0.0, 65535.0));\n"); break; default: From 1371ef298b92bdc8fa195962bcbd6690812980ae Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 27 Aug 2020 19:23:23 -0700 Subject: [PATCH 578/848] Net: Reduce PortManager log noise. Shows up when running unit tests, etc. --- Core/Util/PortManager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index 75218d13f1..bc6b18ace2 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -65,7 +65,7 @@ PortManager::~PortManager() { } void PortManager::Terminate() { - INFO_LOG(SCENET, "PortManager::Terminate()"); + VERBOSE_LOG(SCENET, "PortManager::Terminate()"); if (urls) { FreeUPNPUrls(urls); free(urls); @@ -96,7 +96,7 @@ bool PortManager::Initialize(const unsigned int timeout) { unsigned char ttl = 2; // defaulting to 2 int error = 0; - INFO_LOG(SCENET, "PortManager::Initialize(%d)", timeout); + VERBOSE_LOG(SCENET, "PortManager::Initialize(%d)", timeout); if (!g_Config.bEnableUPnP) { ERROR_LOG(SCENET, "PortManager::Initialize - UPnP is Disabled on Networking Settings"); return false; @@ -265,7 +265,7 @@ bool PortManager::Remove(const char* protocol, unsigned short port) { bool PortManager::Restore() { int r; - INFO_LOG(SCENET, "PortManager::Restore()"); + VERBOSE_LOG(SCENET, "PortManager::Restore()"); if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') { if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Remove - the init was not done !"); @@ -318,7 +318,7 @@ bool PortManager::Clear() { char rHost[64]; char duration[16]; - INFO_LOG(SCENET, "PortManager::Clear()"); + VERBOSE_LOG(SCENET, "PortManager::Clear()"); if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0') { if (g_Config.bEnableUPnP) WARN_LOG(SCENET, "PortManager::Clear - the init was not done !"); From 9b27cbd4504c596db5b6776aca4d2a58c81323f6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 27 Aug 2020 20:01:04 -0700 Subject: [PATCH 579/848] Common: Update to latest xxhash. --- ext/xxhash.c | 975 +--------- ext/xxhash.h | 4796 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 4739 insertions(+), 1032 deletions(-) diff --git a/ext/xxhash.c b/ext/xxhash.c index 5149945e44..7807719256 100644 --- a/ext/xxhash.c +++ b/ext/xxhash.c @@ -1,944 +1,43 @@ /* -xxHash - Fast Hash algorithm -Copyright (C) 2012-2014, Yann Collet. -BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -You can contact the author at : -- xxHash source repository : http://code.google.com/p/xxhash/ -- public discussion board : https://groups.google.com/forum/#!forum/lz4c -*/ + * xxHash - Extremely Fast Hash algorithm + * Copyright (C) 2012-2020 Yann Collet + * + * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You can contact the author at: + * - xxHash homepage: https://www.xxhash.com + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ -//************************************** -// Tuning parameters -//************************************** -// Unaligned memory access is automatically enabled for "common" CPU, such as x86. -// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected. -// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance. -// You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32). + /* + * xxhash.c instantiates functions defined in xxhash.h + */ -#include "ppsspp_config.h" +#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */ +#define XXH_IMPLEMENTATION /* access definitions */ -// ector NOTE: For whatever reason ARM is unhappy about this on Android. -#if !defined(IOS) && !defined(ANDROID) && (defined(ARM) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)) -# define XXH_USE_UNALIGNED_ACCESS 1 -#endif - -// XXH_ACCEPT_NULL_INPUT_POINTER : -// If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. -// When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. -// This option has a very small performance cost (only measurable on small inputs). -// By default, this option is disabled. To enable it, uncomment below define : -//#define XXH_ACCEPT_NULL_INPUT_POINTER 1 - -// XXH_FORCE_NATIVE_FORMAT : -// By default, xxHash library provides endian-independant Hash values, based on little-endian convention. -// Results are therefore identical for little-endian and big-endian CPU. -// This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. -// Should endian-independance be of no importance for your application, you may set the #define below to 1. -// It will improve speed for Big-endian CPU. -// This option has no impact on Little_Endian CPU. -#define XXH_FORCE_NATIVE_FORMAT 1 - - -//************************************** -// Compiler Specific Options -//************************************** -// Disable some Visual warning messages -#ifdef _MSC_VER // Visual Studio -# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant -#endif - -#ifdef _MSC_VER // Visual Studio -# define FORCE_INLINE static __forceinline -#else -# ifdef __GNUC__ -# define FORCE_INLINE static inline __attribute__((always_inline)) -# else -# define FORCE_INLINE static inline -# endif -#endif - -//************************************** -// Includes & Memory related functions -//************************************** #include "xxhash.h" -// Modify the local functions below should you wish to use some other memory routines -// for malloc(), free() -#include -FORCE_INLINE void* XXH_malloc(size_t s) -{ - return malloc(s); -} -FORCE_INLINE void XXH_free (void* p) -{ - free(p); -} -// for memcpy() -#include -FORCE_INLINE void* XXH_memcpy(void* dest, const void* src, size_t size) -{ - return memcpy(dest,src,size); -} - - -//************************************** -// Basic Types -//************************************** -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 -# include -typedef uint8_t BYTE; -typedef uint16_t U16; -typedef uint32_t U32; -typedef int32_t S32; -typedef uint64_t U64; -#else -typedef unsigned char BYTE; -typedef unsigned short U16; -typedef unsigned int U32; -typedef signed int S32; -typedef unsigned long long U64; -#endif - -#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS) -# define _PACKED __attribute__ ((packed)) -#else -# define _PACKED -#endif - -#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) -# ifdef __IBMC__ -# pragma pack(1) -# else -# pragma pack(push, 1) -# endif -#endif - -typedef struct _U32_S -{ - U32 v; -} _PACKED U32_S; -typedef struct _U64_S -{ - U64 v; -} _PACKED U64_S; - -#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) -# pragma pack(pop) -#endif - -#define A32(x) (((U32_S *)(x))->v) -#define A64(x) (((U64_S *)(x))->v) - - -//*************************************** -// Compiler-specific Functions and Macros -//*************************************** -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -// Note : although _rotl exists for minGW (GCC under windows), performance seems poor -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -# define XXH_rotl64(x,r) _rotl64(x,r) -#else -# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) -# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) -#endif - -#if defined(_MSC_VER) // Visual Studio -# define XXH_swap32 _byteswap_ulong -# define XXH_swap64 _byteswap_uint64 -#elif GCC_VERSION >= 403 -# define XXH_swap32 __builtin_bswap32 -# define XXH_swap64 __builtin_bswap64 -#else -static inline U32 XXH_swap32 (U32 x) -{ - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} -static inline U64 XXH_swap64 (U64 x) -{ - return ((x << 56) & 0xff00000000000000ULL) | - ((x << 40) & 0x00ff000000000000ULL) | - ((x << 24) & 0x0000ff0000000000ULL) | - ((x << 8) & 0x000000ff00000000ULL) | - ((x >> 8) & 0x00000000ff000000ULL) | - ((x >> 24) & 0x0000000000ff0000ULL) | - ((x >> 40) & 0x000000000000ff00ULL) | - ((x >> 56) & 0x00000000000000ffULL); -} -#endif - - -//************************************** -// Constants -//************************************** -#define PRIME32_1 2654435761U -#define PRIME32_2 2246822519U -#define PRIME32_3 3266489917U -#define PRIME32_4 668265263U -#define PRIME32_5 374761393U - -#define PRIME64_1 11400714785074694791ULL -#define PRIME64_2 14029467366897019727ULL -#define PRIME64_3 1609587929392839161ULL -#define PRIME64_4 9650029242287828579ULL -#define PRIME64_5 2870177450012600261ULL - -//************************************** -// Architecture Macros -//************************************** -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; -#ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch -static const int one = 1; -# define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one)) -#endif - - -//************************************** -// Macros -//************************************** -#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations - - -//**************************** -// Memory reads -//**************************** -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; - -FORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr)); - else - return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr); -} - -FORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) -{ - return XXH_readLE32_align(ptr, endian, XXH_unaligned); -} - -FORCE_INLINE U64 XXH_readLE64_align(const U64* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? A64(ptr) : XXH_swap64(A64(ptr)); - else - return endian==XXH_littleEndian ? *ptr : XXH_swap64(*ptr); -} - -FORCE_INLINE U64 XXH_readLE64(const U64* ptr, XXH_endianess endian) -{ - return XXH_readLE64_align(ptr, endian, XXH_unaligned); -} - - -//**************************** -// Simple Hash Functions -//**************************** -FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U32 h32; -#define XXH_get32bits(p) XXH_readLE32_align((const U32*)p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) - { - len=0; - bEnd=p=(const BYTE*)(size_t)16; - } -#endif - - if (len>=16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - do - { -#if defined(ARM) && defined(__GNUC__) - __builtin_prefetch(p + 0xc0, 0, 0); -#endif - v1 += XXH_get32bits(p) * PRIME32_2; - v1 = XXH_rotl32(v1, 13); - v1 *= PRIME32_1; - p+=4; - v2 += XXH_get32bits(p) * PRIME32_2; - v2 = XXH_rotl32(v2, 13); - v2 *= PRIME32_1; - p+=4; - v3 += XXH_get32bits(p) * PRIME32_2; - v3 = XXH_rotl32(v3, 13); - v3 *= PRIME32_1; - p+=4; - v4 += XXH_get32bits(p) * PRIME32_2; - v4 = XXH_rotl32(v4, 13); - v4 *= PRIME32_1; - p+=4; - } - while (p<=limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } - else - { - h32 = seed + PRIME32_5; - } - - h32 += (U32) len; - - while (p+4<=bEnd) - { - h32 += XXH_get32bits(p) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -unsigned int XXH32 (const void* input, size_t len, unsigned seed) -{ -#if 0 - // Simple version, good for code maintenance, but unfortunately slow for small inputs - XXH32_state_t state; - XXH32_reset(&state, seed); - XXH32_update(&state, input, len); - return XXH32_digest(&state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - -# if !defined(XXH_USE_UNALIGNED_ACCESS) - if ((((size_t)input) & 3) == 0) // Input is aligned, let's leverage the speed advantage - { - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - -FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U64 h64; -#define XXH_get64bits(p) XXH_readLE64_align((const U64*)p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) - { - len=0; - bEnd=p=(const BYTE*)(size_t)32; - } -#endif - - if (len>=32) - { - const BYTE* const limit = bEnd - 32; - U64 v1 = seed + PRIME64_1 + PRIME64_2; - U64 v2 = seed + PRIME64_2; - U64 v3 = seed + 0; - U64 v4 = seed - PRIME64_1; - - do - { -#if defined(ARM) && defined(__GNUC__) - // TODO: Validate that this helps as it does with XXH32. - __builtin_prefetch(p + 0xc0, 0, 0); -#endif - v1 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - v2 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - v3 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - v4 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - } - while (p<=limit); - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - - v1 *= PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - h64 ^= v1; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v2 *= PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - h64 ^= v2; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v3 *= PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - h64 ^= v3; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v4 *= PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - h64 ^= v4; - h64 = h64 * PRIME64_1 + PRIME64_4; - } - else - { - h64 = seed + PRIME64_5; - } - - h64 += (U64) len; - - while (p+8<=bEnd) - { - U64 k1 = XXH_get64bits(p); - k1 *= PRIME64_2; - k1 = XXH_rotl64(k1,31); - k1 *= PRIME64_1; - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) - { - h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) -{ -#if 0 - // Simple version, good for code maintenance, but unfortunately slow for small inputs - XXH64_state_t state; - XXH64_reset(&state, seed); - XXH64_update(&state, input, len); - return XXH64_digest(&state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - -# if !defined(XXH_USE_UNALIGNED_ACCESS) - if ((((size_t)input) & 7)==0) // Input is aligned, let's leverage the speed advantage - { - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - -/**************************************************** - * Advanced Hash Functions -****************************************************/ - -/*** Allocation ***/ -typedef struct -{ - U64 total_len; - U32 seed; - U32 v1; - U32 v2; - U32 v3; - U32 v4; - U32 memsize; - char memory[16]; -} XXH_istate32_t; - -typedef struct -{ - U64 total_len; - U64 seed; - U64 v1; - U64 v2; - U64 v3; - U64 v4; - U32 memsize; - char memory[32]; -} XXH_istate64_t; - - -XXH32_state_t* XXH32_createState(void) -{ - XXH_STATIC_ASSERT(sizeof(XXH32_state_t) >= sizeof(XXH_istate32_t)); // A compilation error here means XXH32_state_t is not large enough - return (XXH32_state_t*)malloc(sizeof(XXH32_state_t)); -} -XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) -{ - free(statePtr); - return XXH_OK; -}; - -XXH64_state_t* XXH64_createState(void) -{ - XXH_STATIC_ASSERT(sizeof(XXH64_state_t) >= sizeof(XXH_istate64_t)); // A compilation error here means XXH64_state_t is not large enough - return (XXH64_state_t*)malloc(sizeof(XXH64_state_t)); -} -XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) -{ - free(statePtr); - return XXH_OK; -}; - - -/*** Hash feed ***/ - -XXH_errorcode XXH32_reset(XXH32_state_t* state_in, U32 seed) -{ - XXH_istate32_t* state = (XXH_istate32_t*) state_in; - state->seed = seed; - state->v1 = seed + PRIME32_1 + PRIME32_2; - state->v2 = seed + PRIME32_2; - state->v3 = seed + 0; - state->v4 = seed - PRIME32_1; - state->total_len = 0; - state->memsize = 0; - return XXH_OK; -} - -XXH_errorcode XXH64_reset(XXH64_state_t* state_in, unsigned long long seed) -{ - XXH_istate64_t* state = (XXH_istate64_t*) state_in; - state->seed = seed; - state->v1 = seed + PRIME64_1 + PRIME64_2; - state->v2 = seed + PRIME64_2; - state->v3 = seed + 0; - state->v4 = seed - PRIME64_1; - state->total_len = 0; - state->memsize = 0; - return XXH_OK; -} - - -FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state_in, const void* input, size_t len, XXH_endianess endian) -{ - XXH_istate32_t* state = (XXH_istate32_t *) state_in; - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 16) // fill in tmp buffer - { - XXH_memcpy(state->memory + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) // some data left from previous update - { - XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize); - { - const U32* p32 = (const U32*)state->memory; - state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v1 = XXH_rotl32(state->v1, 13); - state->v1 *= PRIME32_1; - p32++; - state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v2 = XXH_rotl32(state->v2, 13); - state->v2 *= PRIME32_1; - p32++; - state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v3 = XXH_rotl32(state->v3, 13); - state->v3 *= PRIME32_1; - p32++; - state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v4 = XXH_rotl32(state->v4, 13); - state->v4 *= PRIME32_1; - p32++; - } - p += 16-state->memsize; - state->memsize = 0; - } - - if (p <= bEnd-16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = state->v1; - U32 v2 = state->v2; - U32 v3 = state->v3; - U32 v4 = state->v4; - - do - { - v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; - v1 = XXH_rotl32(v1, 13); - v1 *= PRIME32_1; - p+=4; - v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; - v2 = XXH_rotl32(v2, 13); - v2 *= PRIME32_1; - p+=4; - v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; - v3 = XXH_rotl32(v3, 13); - v3 *= PRIME32_1; - p+=4; - v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; - v4 = XXH_rotl32(v4, 13); - v4 *= PRIME32_1; - p+=4; - } - while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) - { - XXH_memcpy(state->memory, p, bEnd-p); - state->memsize = (int)(bEnd-p); - } - - return XXH_OK; -} - -XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH32_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endianess endian) -{ - XXH_istate32_t* state = (XXH_istate32_t*) state_in; - const BYTE * p = (const BYTE*)state->memory; - BYTE* bEnd = (BYTE*)state->memory + state->memsize; - U32 h32; - - if (state->total_len >= 16) - { - h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); - } - else - { - h32 = state->seed + PRIME32_5; - } - - h32 += (U32) state->total_len; - - while (p+4<=bEnd) - { - h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -U32 XXH32_digest (const XXH32_state_t* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_digest_endian(state_in, XXH_littleEndian); - else - return XXH32_digest_endian(state_in, XXH_bigEndian); -} - - -FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state_in, const void* input, size_t len, XXH_endianess endian) -{ - XXH_istate64_t * state = (XXH_istate64_t *) state_in; - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 32) // fill in tmp buffer - { - XXH_memcpy(state->memory + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) // some data left from previous update - { - XXH_memcpy(state->memory + state->memsize, input, 32-state->memsize); - { - const U64* p64 = (const U64*)state->memory; - state->v1 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v1 = XXH_rotl64(state->v1, 31); - state->v1 *= PRIME64_1; - p64++; - state->v2 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v2 = XXH_rotl64(state->v2, 31); - state->v2 *= PRIME64_1; - p64++; - state->v3 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v3 = XXH_rotl64(state->v3, 31); - state->v3 *= PRIME64_1; - p64++; - state->v4 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v4 = XXH_rotl64(state->v4, 31); - state->v4 *= PRIME64_1; - p64++; - } - p += 32-state->memsize; - state->memsize = 0; - } - - if (p+32 <= bEnd) - { - const BYTE* const limit = bEnd - 32; - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - do - { - v1 += XXH_readLE64((const U64*)p, endian) * PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - p+=8; - v2 += XXH_readLE64((const U64*)p, endian) * PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - p+=8; - v3 += XXH_readLE64((const U64*)p, endian) * PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - p+=8; - v4 += XXH_readLE64((const U64*)p, endian) * PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - p+=8; - } - while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) - { - XXH_memcpy(state->memory, p, bEnd-p); - state->memsize = (int)(bEnd-p); - } - - return XXH_OK; -} - -XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH64_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state_in, XXH_endianess endian) -{ - XXH_istate64_t * state = (XXH_istate64_t *) state_in; - const BYTE * p = (const BYTE*)state->memory; - BYTE* bEnd = (BYTE*)state->memory + state->memsize; - U64 h64; - - if (state->total_len >= 32) - { - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - - v1 *= PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - h64 ^= v1; - h64 = h64*PRIME64_1 + PRIME64_4; - - v2 *= PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - h64 ^= v2; - h64 = h64*PRIME64_1 + PRIME64_4; - - v3 *= PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - h64 ^= v3; - h64 = h64*PRIME64_1 + PRIME64_4; - - v4 *= PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - h64 ^= v4; - h64 = h64*PRIME64_1 + PRIME64_4; - } - else - { - h64 = state->seed + PRIME64_5; - } - - h64 += (U64) state->total_len; - - while (p+8<=bEnd) - { - U64 k1 = XXH_readLE64((const U64*)p, endian); - k1 *= PRIME64_2; - k1 = XXH_rotl64(k1,31); - k1 *= PRIME64_1; - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) - { - h64 ^= (U64)(XXH_readLE32((const U32*)p, endian)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -unsigned long long XXH64_digest (const XXH64_state_t* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_digest_endian(state_in, XXH_littleEndian); - else - return XXH64_digest_endian(state_in, XXH_bigEndian); -} diff --git a/ext/xxhash.h b/ext/xxhash.h index 55b45015a4..7fe59d9a3e 100644 --- a/ext/xxhash.h +++ b/ext/xxhash.h @@ -1,39 +1,42 @@ /* - xxHash - Extremely Fast Hash algorithm - Header File - Copyright (C) 2012-2014, Yann Collet. - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + * xxHash - Extremely Fast Hash algorithm + * Header File + * Copyright (C) 2012-2020 Yann Collet + * + * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You can contact the author at: + * - xxHash homepage: https://www.xxhash.com + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: +/* TODO: update */ +/* Notice extracted from xxHash homepage: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - You can contact the author at : - - xxHash source repository : http://code.google.com/p/xxhash/ -*/ - -/* Notice extracted from xxHash homepage : - -xxHash is an extremely fast Hash algorithm, running at RAM speed limits. +xxHash is an extremely fast hash algorithm, running at RAM speed limits. It also successfully passes all tests from the SMHasher suite. Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) @@ -55,100 +58,4705 @@ SHA1-32 0.28 GB/s 10 Q.Score is a measure of quality of the hash function. It depends on successfully passing SMHasher test set. 10 is a perfect score. -*/ -#pragma once +Note: SMHasher's CRC32 implementation is not the fastest one. +Other speed-oriented implementations can be faster, +especially in combination with PCLMUL instruction: +https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735 + +A 64-bit version, named XXH64, is available since r35. +It offers much better speed, but for 64-bit applications only. +Name Speed on 64 bits Speed on 32 bits +XXH64 13.8 GB/s 1.9 GB/s +XXH32 6.8 GB/s 6.0 GB/s +*/ #if defined (__cplusplus) extern "C" { #endif +/* **************************** + * INLINE mode + ******************************/ +/*! + * XXH_INLINE_ALL (and XXH_PRIVATE_API) + * Use these build macros to inline xxhash into the target unit. + * Inlining improves performance on small inputs, especially when the length is + * expressed as a compile-time constant: + * + * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html + * + * It also keeps xxHash symbols private to the unit, so they are not exported. + * + * Usage: + * #define XXH_INLINE_ALL + * #include "xxhash.h" + * + * Do not compile and link xxhash.o as a separate object, as it is not useful. + */ +#if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \ + && !defined(XXH_INLINE_ALL_31684351384) + /* this section should be traversed only once */ +# define XXH_INLINE_ALL_31684351384 + /* give access to the advanced API, required to compile implementations */ +# undef XXH_STATIC_LINKING_ONLY /* avoid macro redef */ +# define XXH_STATIC_LINKING_ONLY + /* make all functions private */ +# undef XXH_PUBLIC_API +# if defined(__GNUC__) +# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define XXH_PUBLIC_API static inline +# elif defined(_MSC_VER) +# define XXH_PUBLIC_API static __inline +# else + /* note: this version may generate warnings for unused static functions */ +# define XXH_PUBLIC_API static +# endif -/***************************** - Includes -*****************************/ + /* + * This part deals with the special case where a unit wants to inline xxHash, + * but "xxhash.h" has previously been included without XXH_INLINE_ALL, such + * as part of some previously included *.h header file. + * Without further action, the new include would just be ignored, + * and functions would effectively _not_ be inlined (silent failure). + * The following macros solve this situation by prefixing all inlined names, + * avoiding naming collision with previous inclusions. + */ +# ifdef XXH_NAMESPACE +# error "XXH_INLINE_ALL with XXH_NAMESPACE is not supported" + /* + * Note: Alternative: #undef all symbols (it's a pretty large list). + * Without #error: it compiles, but functions are actually not inlined. + */ +# endif +# define XXH_NAMESPACE XXH_INLINE_ + /* + * Some identifiers (enums, type names) are not symbols, but they must + * still be renamed to avoid redeclaration. + * Alternative solution: do not redeclare them. + * However, this requires some #ifdefs, and is a more dispersed action. + * Meanwhile, renaming can be achieved in a single block + */ +# define XXH_IPREF(Id) XXH_INLINE_ ## Id +# define XXH_OK XXH_IPREF(XXH_OK) +# define XXH_ERROR XXH_IPREF(XXH_ERROR) +# define XXH_errorcode XXH_IPREF(XXH_errorcode) +# define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t) +# define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t) +# define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t) +# define XXH32_state_s XXH_IPREF(XXH32_state_s) +# define XXH32_state_t XXH_IPREF(XXH32_state_t) +# define XXH64_state_s XXH_IPREF(XXH64_state_s) +# define XXH64_state_t XXH_IPREF(XXH64_state_t) +# define XXH3_state_s XXH_IPREF(XXH3_state_s) +# define XXH3_state_t XXH_IPREF(XXH3_state_t) +# define XXH128_hash_t XXH_IPREF(XXH128_hash_t) + /* Ensure the header is parsed again, even if it was previously included */ +# undef XXHASH_H_5627135585666179 +# undef XXHASH_H_STATIC_13879238742 +#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ + + + +/* **************************************************************** + * Stable API + *****************************************************************/ +#ifndef XXHASH_H_5627135585666179 +#define XXHASH_H_5627135585666179 1 + +/* specific declaration modes for Windows */ +#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) +# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# ifdef XXH_EXPORT +# define XXH_PUBLIC_API __declspec(dllexport) +# elif XXH_IMPORT +# define XXH_PUBLIC_API __declspec(dllimport) +# endif +# else +# define XXH_PUBLIC_API /* do nothing */ +# endif +#endif + +/*! + * XXH_NAMESPACE, aka Namespace Emulation: + * + * If you want to include _and expose_ xxHash functions from within your own + * library, but also want to avoid symbol collisions with other libraries which + * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix + * any public symbol from xxhash library with the value of XXH_NAMESPACE + * (therefore, avoid empty or numeric values). + * + * Note that no change is required within the calling program as long as it + * includes `xxhash.h`: Regular symbol names will be automatically translated + * by this header. + */ +#ifdef XXH_NAMESPACE +# define XXH_CAT(A,B) A##B +# define XXH_NAME2(A,B) XXH_CAT(A,B) +# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) +/* XXH32 */ +# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) +# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) +# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) +# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) +# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) +# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) +# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) +# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) +# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) +/* XXH64 */ +# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) +# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) +# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) +# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) +# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) +# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) +# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) +# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) +# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) +/* XXH3_64bits */ +# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits) +# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret) +# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed) +# define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState) +# define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState) +# define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState) +# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset) +# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed) +# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret) +# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update) +# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest) +# define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret) +/* XXH3_128bits */ +# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128) +# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits) +# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed) +# define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret) +# define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset) +# define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed) +# define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret) +# define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update) +# define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest) +# define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual) +# define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp) +# define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash) +# define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical) +#endif + + +/* ************************************* +* Version +***************************************/ +#define XXH_VERSION_MAJOR 0 +#define XXH_VERSION_MINOR 8 +#define XXH_VERSION_RELEASE 0 +#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) +XXH_PUBLIC_API unsigned XXH_versionNumber (void); + + +/* **************************** +* Definitions +******************************/ #include /* size_t */ - - -/***************************** - Type -*****************************/ typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; +/*-********************************************************************** +* 32-bit hash +************************************************************************/ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint32_t XXH32_hash_t; +#else +# include +# if UINT_MAX == 0xFFFFFFFFUL + typedef unsigned int XXH32_hash_t; +# else +# if ULONG_MAX == 0xFFFFFFFFUL + typedef unsigned long XXH32_hash_t; +# else +# error "unsupported platform: need a 32-bit type" +# endif +# endif +#endif -/***************************** - Simple Hash Functions +/*! + * XXH32(): + * Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input". + * The memory between input & input+length must be valid (allocated and read-accessible). + * "seed" can be used to alter the result predictably. + * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s + * + * Note: XXH3 provides competitive speed for both 32-bit and 64-bit systems, + * and offers true 64/128 bit hash results. It provides a superior level of + * dispersion, and greatly reduces the risks of collisions. + */ +XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); + +/******* Streaming *******/ + +/* + * Streaming functions generate the xxHash value from an incrememtal input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + */ + +typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state); + +XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); +XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); + +/******* Canonical representation *******/ + +/* + * The default return values from XXH functions are unsigned 32 and 64 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + */ + +typedef struct { unsigned char digest[4]; } XXH32_canonical_t; +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); + + +#ifndef XXH_NO_LONG_LONG +/*-********************************************************************** +* 64-bit hash +************************************************************************/ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint64_t XXH64_hash_t; +#else + /* the following type must have a width of 64-bit */ + typedef unsigned long long XXH64_hash_t; +#endif + +/*! + * XXH64(): + * Returns the 64-bit hash of sequence of length @length stored at memory + * address @input. + * @seed can be used to alter the result predictably. + * + * This function usually runs faster on 64-bit systems, but slower on 32-bit + * systems (see benchmark). + * + * Note: XXH3 provides competitive speed for both 32-bit and 64-bit systems, + * and offers true 64/128 bit hash results. It provides a superior level of + * dispersion, and greatly reduces the risks of collisions. + */ +XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, XXH64_hash_t seed); + +/******* Streaming *******/ +typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); + +XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); + +/******* Canonical representation *******/ +typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t; +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); + + +/*-********************************************************************** +* XXH3 64-bit variant +************************************************************************/ + +/* ************************************************************************ + * XXH3 is a new hash algorithm featuring: + * - Improved speed for both small and large inputs + * - True 64-bit and 128-bit outputs + * - SIMD acceleration + * - Improved 32-bit viability + * + * Speed analysis methodology is explained here: + * + * https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html + * + * In general, expect XXH3 to run about ~2x faster on large inputs and >3x + * faster on small ones compared to XXH64, though exact differences depend on + * the platform. + * + * The algorithm is portable: Like XXH32 and XXH64, it generates the same hash + * on all platforms. + * + * It benefits greatly from SIMD and 64-bit arithmetic, but does not require it. + * + * Almost all 32-bit and 64-bit targets that can run XXH32 smoothly can run + * XXH3 at competitive speeds, even if XXH64 runs slowly. Further details are + * explained in the implementation. + * + * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8, + * ZVector and scalar targets. This can be controlled with the XXH_VECTOR macro. + * + * XXH3 offers 2 variants, _64bits and _128bits. + * When only 64 bits are needed, prefer calling the _64bits variant, as it + * reduces the amount of mixing, resulting in faster speed on small inputs. + * + * It's also generally simpler to manipulate a scalar return type than a struct. + * + * The 128-bit version adds additional strength, but it is slightly slower. + * + * Return values of XXH3 and XXH128 are officially finalized starting + * with v0.8.0 and will no longer change in future versions. + * Avoid storing values from before that release in long-term storage. + * + * Results produced by v0.7.x are not comparable with results from v0.7.y. + * However, the API is completely stable, and it can safely be used for + * ephemeral data (local sessions). + * + * The API supports one-shot hashing, streaming mode, and custom secrets. + */ + +/* XXH3_64bits(): + * default 64-bit variant, using default secret and default seed of 0. + * It's the fastest variant. */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len); + +/* + * XXH3_64bits_withSeed(): + * This variant generates a custom secret on the fly + * based on default secret altered using the `seed` value. + * While this operation is decently fast, note that it's not completely free. + * Note: seed==0 produces the same results as XXH3_64bits(). + */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); + +/* + * XXH3_64bits_withSecret(): + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * However, the quality of produced hash values depends on secret's entropy. + * Technically, the secret must look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever unsure about the "randomness" of the blob of bytes, + * consider relabelling it as a "custom seed" instead, + * and employ "XXH3_generateSecret()" (see below) + * to generate a high entropy secret derived from the custom seed. + */ +#define XXH3_SECRET_SIZE_MIN 136 +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); + + +/******* Streaming *******/ +/* + * Streaming requires state maintenance. + * This operation costs memory and CPU. + * As a consequence, streaming is slower than one-shot hashing. + * For better performance, prefer one-shot functions whenever applicable. + */ +typedef struct XXH3_state_s XXH3_state_t; +XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr); +XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state); + +/* + * XXH3_64bits_reset(): + * Initialize with default parameters. + * digest will be equivalent to `XXH3_64bits()`. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr); +/* + * XXH3_64bits_reset_withSeed(): + * Generate a custom secret from `seed`, and store it into `statePtr`. + * digest will be equivalent to `XXH3_64bits_withSeed()`. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); +/* + * XXH3_64bits_reset_withSecret(): + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); + +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr); + +/* note : canonical representation of XXH3 is the same as XXH64 + * since they both produce XXH64_hash_t values */ + + +/*-********************************************************************** +* XXH3 128-bit variant +************************************************************************/ + +typedef struct { + XXH64_hash_t low64; + XXH64_hash_t high64; +} XXH128_hash_t; + +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len); +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); + +/******* Streaming *******/ +/* + * Streaming requires state maintenance. + * This operation costs memory and CPU. + * As a consequence, streaming is slower than one-shot hashing. + * For better performance, prefer one-shot functions whenever applicable. + * + * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits(). + * Use already declared XXH3_createState() and XXH3_freeState(). + * + * All reset and streaming functions have same meaning as their 64-bit counterpart. + */ + +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr); +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); + +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr); + +/* Following helper functions make it possible to compare XXH128_hast_t values. + * Since XXH128_hash_t is a structure, this capability is not offered by the language. + * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ + +/*! + * XXH128_isEqual(): + * Return: 1 if `h1` and `h2` are equal, 0 if they are not. + */ +XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); + +/*! + * XXH128_cmp(): + * + * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. + * + * return: >0 if *h128_1 > *h128_2 + * =0 if *h128_1 == *h128_2 + * <0 if *h128_1 < *h128_2 + */ +XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2); + + +/******* Canonical representation *******/ +typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t; +XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash); +XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src); + + +#endif /* XXH_NO_LONG_LONG */ + +#endif /* XXHASH_H_5627135585666179 */ + + + +#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) +#define XXHASH_H_STATIC_13879238742 +/* **************************************************************************** + * This section contains declarations which are not guaranteed to remain stable. + * They may change in future versions, becoming incompatible with a different + * version of the library. + * These declarations should only be used with static linking. + * Never use them in association with dynamic linking! + ***************************************************************************** */ + +/* + * These definitions are only present to allow static allocation + * of XXH states, on stack or in a struct, for example. + * Never **ever** access their members directly. + */ + +struct XXH32_state_s { + XXH32_hash_t total_len_32; + XXH32_hash_t large_len; + XXH32_hash_t v1; + XXH32_hash_t v2; + XXH32_hash_t v3; + XXH32_hash_t v4; + XXH32_hash_t mem32[4]; + XXH32_hash_t memsize; + XXH32_hash_t reserved; /* never read nor write, might be removed in a future version */ +}; /* typedef'd to XXH32_state_t */ + + +#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */ + +struct XXH64_state_s { + XXH64_hash_t total_len; + XXH64_hash_t v1; + XXH64_hash_t v2; + XXH64_hash_t v3; + XXH64_hash_t v4; + XXH64_hash_t mem64[4]; + XXH32_hash_t memsize; + XXH32_hash_t reserved32; /* required for padding anyway */ + XXH64_hash_t reserved64; /* never read nor write, might be removed in a future version */ +}; /* typedef'd to XXH64_state_t */ + +#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11+ */ +# include +# define XXH_ALIGN(n) alignas(n) +#elif defined(__GNUC__) +# define XXH_ALIGN(n) __attribute__ ((aligned(n))) +#elif defined(_MSC_VER) +# define XXH_ALIGN(n) __declspec(align(n)) +#else +# define XXH_ALIGN(n) /* disabled */ +#endif + +/* Old GCC versions only accept the attribute after the type in structures. */ +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \ + && defined(__GNUC__) +# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align) +#else +# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type +#endif + +#define XXH3_INTERNALBUFFER_SIZE 256 +#define XXH3_SECRET_DEFAULT_SIZE 192 +struct XXH3_state_s { + XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]); + /* used to store a custom secret generated from a seed */ + XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]); + XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]); + XXH32_hash_t bufferedSize; + XXH32_hash_t reserved32; + size_t nbStripesSoFar; + XXH64_hash_t totalLen; + size_t nbStripesPerBlock; + size_t secretLimit; + XXH64_hash_t seed; + XXH64_hash_t reserved64; + const unsigned char* extSecret; /* reference to external secret; + * if == NULL, use .customSecret instead */ + /* note: there may be some padding at the end due to alignment on 64 bytes */ +}; /* typedef'd to XXH3_state_t */ + +#undef XXH_ALIGN_MEMBER + +/* When the XXH3_state_t structure is merely emplaced on stack, + * it should be initialized with XXH3_INITSTATE() or a memset() + * in case its first reset uses XXH3_NNbits_reset_withSeed(). + * This init can be omitted if the first reset uses default or _withSecret mode. + * This operation isn't necessary when the state is created with XXH3_createState(). + * Note that this doesn't prepare the state for a streaming operation, + * it's still necessary to use XXH3_NNbits_reset*() afterwards. + */ +#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; } + + +/* === Experimental API === */ +/* Symbols defined below must be considered tied to a specific library version. */ + +/* + * XXH3_generateSecret(): + * + * Derive a high-entropy secret from any user-defined content, named customSeed. + * The generated secret can be used in combination with `*_withSecret()` functions. + * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed, + * as it becomes much more difficult for an external actor to guess how to impact the calculation logic. + * + * The function accepts as input a custom seed of any length and any content, + * and derives from it a high-entropy secret of length XXH3_SECRET_DEFAULT_SIZE + * into an already allocated buffer secretBuffer. + * The generated secret is _always_ XXH_SECRET_DEFAULT_SIZE bytes long. + * + * The generated secret can then be used with any `*_withSecret()` variant. + * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`, + * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()` + * are part of this list. They all accept a `secret` parameter + * which must be very long for implementation reasons (>= XXH3_SECRET_SIZE_MIN) + * _and_ feature very high entropy (consist of random-looking bytes). + * These conditions can be a high bar to meet, so + * this function can be used to generate a secret of proper quality. + * + * customSeed can be anything. It can have any size, even small ones, + * and its content can be anything, even stupidly "low entropy" source such as a bunch of zeroes. + * The resulting `secret` will nonetheless provide all expected qualities. + * + * Supplying NULL as the customSeed copies the default secret into `secretBuffer`. + * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior. + */ +XXH_PUBLIC_API void XXH3_generateSecret(void* secretBuffer, const void* customSeed, size_t customSeedSize); + + +/* simple short-cut to pre-selected XXH3_128bits variant */ +XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed); + + +#endif /* XXH_NO_LONG_LONG */ + + +#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) +# define XXH_IMPLEMENTATION +#endif + +#endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */ + + +/* ======================================================================== */ +/* ======================================================================== */ +/* ======================================================================== */ + + +/*-********************************************************************** + * xxHash implementation + *-********************************************************************** + * xxHash's implementation used to be hosted inside xxhash.c. + * + * However, inlining requires implementation to be visible to the compiler, + * hence be included alongside the header. + * Previously, implementation was hosted inside xxhash.c, + * which was then #included when inlining was activated. + * This construction created issues with a few build and install systems, + * as it required xxhash.c to be stored in /include directory. + * + * xxHash implementation is now directly integrated within xxhash.h. + * As a consequence, xxhash.c is no longer needed in /include. + * + * xxhash.c is still available and is still useful. + * In a "normal" setup, when xxhash is not inlined, + * xxhash.h only exposes the prototypes and public symbols, + * while xxhash.c can be built into an object file xxhash.o + * which can then be linked into the final binary. + ************************************************************************/ + +#if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \ + || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387) +# define XXH_IMPLEM_13a8737387 + +/* ************************************* +* Tuning parameters +***************************************/ +/*! + * XXH_FORCE_MEMORY_ACCESS: + * By default, access to unaligned memory is controlled by `memcpy()`, which is + * safe and portable. + * + * Unfortunately, on some target/compiler combinations, the generated assembly + * is sub-optimal. + * + * The below switch allow selection of a different access method + * in the search for improved performance. + * Method 0 (default): + * Use `memcpy()`. Safe and portable. Default. + * Method 1: + * `__attribute__((packed))` statement. It depends on compiler extensions + * and is therefore not portable. + * This method is safe if your compiler supports it, and *generally* as + * fast or faster than `memcpy`. + * Method 2: + * Direct access via cast. This method doesn't depend on the compiler but + * violates the C standard. + * It can generate buggy code on targets which do not support unaligned + * memory accesses. + * But in some circumstances, it's the only known way to get the most + * performance (example: GCC + ARMv6) + * Method 3: + * Byteshift. This can generate the best code on old compilers which don't + * inline small `memcpy()` calls, and it might also be faster on big-endian + * systems which lack a native byteswap instruction. + * See https://stackoverflow.com/a/32095106/646947 for details. + * Prefer these methods in priority order (0 > 1 > 2 > 3) + */ +#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# if !defined(__clang__) && defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED) && defined(__ARM_ARCH) && (__ARM_ARCH == 6) +# define XXH_FORCE_MEMORY_ACCESS 2 +# elif !defined(__clang__) && ((defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ + (defined(__GNUC__) && (defined(__ARM_ARCH) && __ARM_ARCH >= 7))) +# define XXH_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +/*! + * XXH_ACCEPT_NULL_INPUT_POINTER: + * If the input pointer is NULL, xxHash's default behavior is to dereference it, + * triggering a segfault. + * When this macro is enabled, xxHash actively checks the input for a null pointer. + * If it is, the result for null input pointers is the same as a zero-length input. + */ +#ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */ +# define XXH_ACCEPT_NULL_INPUT_POINTER 0 +#endif + +/*! + * XXH_FORCE_ALIGN_CHECK: + * This is an important performance trick + * for architectures without decent unaligned memory access performance. + * It checks for input alignment, and when conditions are met, + * uses a "fast path" employing direct 32-bit/64-bit read, + * resulting in _dramatically faster_ read speed. + * + * The check costs one initial branch per hash, which is generally negligible, but not zero. + * Moreover, it's not useful to generate binary for an additional code path + * if memory access uses same instruction for both aligned and unaligned adresses. + * + * In these cases, the alignment check can be removed by setting this macro to 0. + * Then the code will always use unaligned memory access. + * Align check is automatically disabled on x86, x64 & arm64, + * which are platforms known to offer good unaligned memory accesses performance. + * + * This option does not affect XXH3 (only XXH32 and XXH64). + */ +#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ +# if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \ + || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */ +# define XXH_FORCE_ALIGN_CHECK 0 +# else +# define XXH_FORCE_ALIGN_CHECK 1 +# endif +#endif + +/*! + * XXH_NO_INLINE_HINTS: + * + * By default, xxHash tries to force the compiler to inline almost all internal + * functions. + * + * This can usually improve performance due to reduced jumping and improved + * constant folding, but significantly increases the size of the binary which + * might not be favorable. + * + * Additionally, sometimes the forced inlining can be detrimental to performance, + * depending on the architecture. + * + * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the + * compiler full control on whether to inline or not. + * + * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using + * -fno-inline with GCC or Clang, this will automatically be defined. + */ +#ifndef XXH_NO_INLINE_HINTS +# if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \ + || defined(__NO_INLINE__) /* -O0, -fno-inline */ +# define XXH_NO_INLINE_HINTS 1 +# else +# define XXH_NO_INLINE_HINTS 0 +# endif +#endif + +/*! + * XXH_REROLL: + * Whether to reroll XXH32_finalize, and XXH64_finalize, + * instead of using an unrolled jump table/if statement loop. + * + * This is automatically defined on -Os/-Oz on GCC and Clang. + */ +#ifndef XXH_REROLL +# if defined(__OPTIMIZE_SIZE__) +# define XXH_REROLL 1 +# else +# define XXH_REROLL 0 +# endif +#endif + + +/* ************************************* +* Includes & Memory related functions +***************************************/ +/*! + * Modify the local functions below should you wish to use + * different memory routines for malloc() and free() + */ +#include + +static void* XXH_malloc(size_t s) { return malloc(s); } +static void XXH_free(void* p) { free(p); } + +/*! and for memcpy() */ +#include +static void* XXH_memcpy(void* dest, const void* src, size_t size) +{ + return memcpy(dest,src,size); +} + +#include /* ULLONG_MAX */ + + +/* ************************************* +* Compiler Specific Options +***************************************/ +#ifdef _MSC_VER /* Visual Studio warning fix */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#endif + +#if XXH_NO_INLINE_HINTS /* disable inlining hints */ +# if defined(__GNUC__) +# define XXH_FORCE_INLINE static __attribute__((unused)) +# else +# define XXH_FORCE_INLINE static +# endif +# define XXH_NO_INLINE static +/* enable inlining hints */ +#elif defined(_MSC_VER) /* Visual Studio */ +# define XXH_FORCE_INLINE static __forceinline +# define XXH_NO_INLINE static __declspec(noinline) +#elif defined(__GNUC__) +# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) +# define XXH_NO_INLINE static __attribute__((noinline)) +#elif defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */ +# define XXH_FORCE_INLINE static inline +# define XXH_NO_INLINE static +#else +# define XXH_FORCE_INLINE static +# define XXH_NO_INLINE static +#endif + + + +/* ************************************* +* Debug +***************************************/ +/* + * XXH_DEBUGLEVEL is expected to be defined externally, typically via the + * compiler's command line options. The value must be a number. + */ +#ifndef XXH_DEBUGLEVEL +# ifdef DEBUGLEVEL /* backwards compat */ +# define XXH_DEBUGLEVEL DEBUGLEVEL +# else +# define XXH_DEBUGLEVEL 0 +# endif +#endif + +#if (XXH_DEBUGLEVEL>=1) +# include /* note: can still be disabled with NDEBUG */ +# define XXH_ASSERT(c) assert(c) +#else +# define XXH_ASSERT(c) ((void)0) +#endif + +/* note: use after variable declarations */ +#define XXH_STATIC_ASSERT(c) do { enum { XXH_sa = 1/(int)(!!(c)) }; } while (0) + + +/* ************************************* +* Basic Types +***************************************/ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint8_t xxh_u8; +#else + typedef unsigned char xxh_u8; +#endif +typedef XXH32_hash_t xxh_u32; + +#ifdef XXH_OLD_NAMES +# define BYTE xxh_u8 +# define U8 xxh_u8 +# define U32 xxh_u32 +#endif + +/* *** Memory access *** */ + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) +/* + * Manual byteshift. Best for old compilers which don't inline memcpy. + * We actually directly use XXH_readLE32 and XXH_readBE32. + */ +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* + * Force direct memory access. Only works on CPU which support unaligned memory + * access in hardware. + */ +static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* + * __pack instructions are safer but compiler specific, hence potentially + * problematic for some compilers. + * + * Currently only defined for GCC and ICC. + */ +#ifdef XXH_OLD_NAMES +typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; +#endif +static xxh_u32 XXH_read32(const void* ptr) +{ + typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign; + return ((const xxh_unalign*)ptr)->u32; +} + +#else + +/* + * Portable and safe solution. Generally efficient. + * see: https://stackoverflow.com/a/32095106/646947 + */ +static xxh_u32 XXH_read32(const void* memPtr) +{ + xxh_u32 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + + +/* *** Endianess *** */ +typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; + +/*! + * XXH_CPU_LITTLE_ENDIAN: + * Defined to 1 if the target is little endian, or 0 if it is big endian. + * It can be defined externally, for example on the compiler command line. + * + * If it is not defined, a runtime check (which is usually constant folded) + * is used instead. + */ +#ifndef XXH_CPU_LITTLE_ENDIAN +/* + * Try to detect endianness automatically, to avoid the nonstandard behavior + * in `XXH_isLittleEndian()` + */ +# if defined(_WIN32) /* Windows is always little endian */ \ + || defined(__LITTLE_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +# define XXH_CPU_LITTLE_ENDIAN 1 +# elif defined(__BIG_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define XXH_CPU_LITTLE_ENDIAN 0 +# else +/* + * runtime test, presumed to simplify to a constant by compiler + */ +static int XXH_isLittleEndian(void) +{ + /* + * Portable and well-defined behavior. + * Don't use static: it is detrimental to performance. + */ + const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 }; + return one.c[0]; +} +# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian() +# endif +#endif + + + + +/* **************************************** +* Compiler-specific Functions and Macros +******************************************/ +#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +#ifdef __has_builtin +# define XXH_HAS_BUILTIN(x) __has_builtin(x) +#else +# define XXH_HAS_BUILTIN(x) 0 +#endif + +#if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \ + && XXH_HAS_BUILTIN(__builtin_rotateleft64) +# define XXH_rotl32 __builtin_rotateleft32 +# define XXH_rotl64 __builtin_rotateleft64 +/* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ +#elif defined(_MSC_VER) +# define XXH_rotl32(x,r) _rotl(x,r) +# define XXH_rotl64(x,r) _rotl64(x,r) +#else +# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r)))) +#endif + +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap32 _byteswap_ulong +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap32 __builtin_bswap32 +#else +static xxh_u32 XXH_swap32 (xxh_u32 x) +{ + return ((x << 24) & 0xff000000 ) | + ((x << 8) & 0x00ff0000 ) | + ((x >> 8) & 0x0000ff00 ) | + ((x >> 24) & 0x000000ff ); +} +#endif + + +/* *************************** +* Memory reads *****************************/ - -unsigned int XXH32 (const void* input, size_t length, unsigned seed); -unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed); +typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; /* -XXH32() : - Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". - The memory between input & input+length must be valid (allocated and read-accessible). - "seed" can be used to alter the result predictably. - This function successfully passes all SMHasher tests. - Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s -XXH64() : - Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". -*/ + * XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. + * + * This is ideal for older compilers which don't inline memcpy. + */ +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) + +XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[0] + | ((xxh_u32)bytePtr[1] << 8) + | ((xxh_u32)bytePtr[2] << 16) + | ((xxh_u32)bytePtr[3] << 24); +} + +XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[3] + | ((xxh_u32)bytePtr[2] << 8) + | ((xxh_u32)bytePtr[1] << 16) + | ((xxh_u32)bytePtr[0] << 24); +} + +#else +XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); +} + +static xxh_u32 XXH_readBE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); +} +#endif + +XXH_FORCE_INLINE xxh_u32 +XXH_readLE32_align(const void* ptr, XXH_alignment align) +{ + if (align==XXH_unaligned) { + return XXH_readLE32(ptr); + } else { + return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr); + } +} + + +/* ************************************* +* Misc +***************************************/ +XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } + + +/* ******************************************************************* +* 32-bit hash functions +*********************************************************************/ +static const xxh_u32 XXH_PRIME32_1 = 0x9E3779B1U; /* 0b10011110001101110111100110110001 */ +static const xxh_u32 XXH_PRIME32_2 = 0x85EBCA77U; /* 0b10000101111010111100101001110111 */ +static const xxh_u32 XXH_PRIME32_3 = 0xC2B2AE3DU; /* 0b11000010101100101010111000111101 */ +static const xxh_u32 XXH_PRIME32_4 = 0x27D4EB2FU; /* 0b00100111110101001110101100101111 */ +static const xxh_u32 XXH_PRIME32_5 = 0x165667B1U; /* 0b00010110010101100110011110110001 */ + +#ifdef XXH_OLD_NAMES +# define PRIME32_1 XXH_PRIME32_1 +# define PRIME32_2 XXH_PRIME32_2 +# define PRIME32_3 XXH_PRIME32_3 +# define PRIME32_4 XXH_PRIME32_4 +# define PRIME32_5 XXH_PRIME32_5 +#endif + +static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) +{ + acc += input * XXH_PRIME32_2; + acc = XXH_rotl32(acc, 13); + acc *= XXH_PRIME32_1; +#if defined(__GNUC__) && defined(__SSE4_1__) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * UGLY HACK: + * This inline assembly hack forces acc into a normal register. This is the + * only thing that prevents GCC and Clang from autovectorizing the XXH32 + * loop (pragmas and attributes don't work for some resason) without globally + * disabling SSE4.1. + * + * The reason we want to avoid vectorization is because despite working on + * 4 integers at a time, there are multiple factors slowing XXH32 down on + * SSE4: + * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on + * newer chips!) making it slightly slower to multiply four integers at + * once compared to four integers independently. Even when pmulld was + * fastest, Sandy/Ivy Bridge, it is still not worth it to go into SSE + * just to multiply unless doing a long operation. + * + * - Four instructions are required to rotate, + * movqda tmp, v // not required with VEX encoding + * pslld tmp, 13 // tmp <<= 13 + * psrld v, 19 // x >>= 19 + * por v, tmp // x |= tmp + * compared to one for scalar: + * roll v, 13 // reliably fast across the board + * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason + * + * - Instruction level parallelism is actually more beneficial here because + * the SIMD actually serializes this operation: While v1 is rotating, v2 + * can load data, while v3 can multiply. SSE forces them to operate + * together. + * + * How this hack works: + * __asm__("" // Declare an assembly block but don't declare any instructions + * : // However, as an Input/Output Operand, + * "+r" // constrain a read/write operand (+) as a general purpose register (r). + * (acc) // and set acc as the operand + * ); + * + * Because of the 'r', the compiler has promised that seed will be in a + * general purpose register and the '+' says that it will be 'read/write', + * so it has to assume it has changed. It is like volatile without all the + * loads and stores. + * + * Since the argument has to be in a normal register (not an SSE register), + * each time XXH32_round is called, it is impossible to vectorize. + */ + __asm__("" : "+r" (acc)); +#endif + return acc; +} + +/* mix all bits */ +static xxh_u32 XXH32_avalanche(xxh_u32 h32) +{ + h32 ^= h32 >> 15; + h32 *= XXH_PRIME32_2; + h32 ^= h32 >> 13; + h32 *= XXH_PRIME32_3; + h32 ^= h32 >> 16; + return(h32); +} + +#define XXH_get32bits(p) XXH_readLE32_align(p, align) + +static xxh_u32 +XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) +{ +#define XXH_PROCESS1 do { \ + h32 += (*ptr++) * XXH_PRIME32_5; \ + h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \ +} while (0) + +#define XXH_PROCESS4 do { \ + h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \ + ptr += 4; \ + h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \ +} while (0) + + /* Compact rerolled version */ + if (XXH_REROLL) { + len &= 15; + while (len >= 4) { + XXH_PROCESS4; + len -= 4; + } + while (len > 0) { + XXH_PROCESS1; + --len; + } + return XXH32_avalanche(h32); + } else { + switch(len&15) /* or switch(bEnd - p) */ { + case 12: XXH_PROCESS4; + /* fallthrough */ + case 8: XXH_PROCESS4; + /* fallthrough */ + case 4: XXH_PROCESS4; + return XXH32_avalanche(h32); + + case 13: XXH_PROCESS4; + /* fallthrough */ + case 9: XXH_PROCESS4; + /* fallthrough */ + case 5: XXH_PROCESS4; + XXH_PROCESS1; + return XXH32_avalanche(h32); + + case 14: XXH_PROCESS4; + /* fallthrough */ + case 10: XXH_PROCESS4; + /* fallthrough */ + case 6: XXH_PROCESS4; + XXH_PROCESS1; + XXH_PROCESS1; + return XXH32_avalanche(h32); + + case 15: XXH_PROCESS4; + /* fallthrough */ + case 11: XXH_PROCESS4; + /* fallthrough */ + case 7: XXH_PROCESS4; + /* fallthrough */ + case 3: XXH_PROCESS1; + /* fallthrough */ + case 2: XXH_PROCESS1; + /* fallthrough */ + case 1: XXH_PROCESS1; + /* fallthrough */ + case 0: return XXH32_avalanche(h32); + } + XXH_ASSERT(0); + return h32; /* reaching this point is deemed impossible */ + } +} + +#ifdef XXH_OLD_NAMES +# define PROCESS1 XXH_PROCESS1 +# define PROCESS4 XXH_PROCESS4 +#else +# undef XXH_PROCESS1 +# undef XXH_PROCESS4 +#endif + +XXH_FORCE_INLINE xxh_u32 +XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align) +{ + const xxh_u8* bEnd = input + len; + xxh_u32 h32; + +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + if (input==NULL) { + len=0; + bEnd=input=(const xxh_u8*)(size_t)16; + } +#endif + + if (len>=16) { + const xxh_u8* const limit = bEnd - 15; + xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + xxh_u32 v2 = seed + XXH_PRIME32_2; + xxh_u32 v3 = seed + 0; + xxh_u32 v4 = seed - XXH_PRIME32_1; + + do { +#if defined(ARM) && defined(__GNUC__) + __builtin_prefetch(input + 0xc0, 0, 0); +#endif + v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; + v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; + v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; + v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; + } while (input < limit); + + h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + } else { + h32 = seed + XXH_PRIME32_5; + } + + h32 += (xxh_u32)len; + + return XXH32_finalize(h32, input, len&15, align); +} + + +XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH32_state_t state; + XXH32_reset(&state, seed); + XXH32_update(&state, (const xxh_u8*)input, len); + return XXH32_digest(&state); + +#else + + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ + return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned); + } } + + return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned); +#endif +} -/***************************** - Advanced Hash Functions -*****************************/ -typedef struct { long long ll[ 6]; } XXH32_state_t; -typedef struct { long long ll[11]; } XXH64_state_t; +/******* Hash streaming *******/ + +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) +{ + return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); +} +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + +XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed) +{ + XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ + memset(&state, 0, sizeof(state)); + state.v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + state.v2 = seed + XXH_PRIME32_2; + state.v3 = seed + 0; + state.v4 = seed - XXH_PRIME32_1; + /* do not write into reserved, planned to be removed in a future version */ + memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); + return XXH_OK; +} + + +XXH_PUBLIC_API XXH_errorcode +XXH32_update(XXH32_state_t* state, const void* input, size_t len) +{ + if (input==NULL) +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + return XXH_OK; +#else + return XXH_ERROR; +#endif + + { const xxh_u8* p = (const xxh_u8*)input; + const xxh_u8* const bEnd = p + len; + + state->total_len_32 += (XXH32_hash_t)len; + state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); + + if (state->memsize + len < 16) { /* fill in tmp buffer */ + XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); + state->memsize += (XXH32_hash_t)len; + return XXH_OK; + } + + if (state->memsize) { /* some data left from previous update */ + XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); + { const xxh_u32* p32 = state->mem32; + state->v1 = XXH32_round(state->v1, XXH_readLE32(p32)); p32++; + state->v2 = XXH32_round(state->v2, XXH_readLE32(p32)); p32++; + state->v3 = XXH32_round(state->v3, XXH_readLE32(p32)); p32++; + state->v4 = XXH32_round(state->v4, XXH_readLE32(p32)); + } + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= bEnd-16) { + const xxh_u8* const limit = bEnd - 16; + xxh_u32 v1 = state->v1; + xxh_u32 v2 = state->v2; + xxh_u32 v3 = state->v3; + xxh_u32 v4 = state->v4; + + do { + v1 = XXH32_round(v1, XXH_readLE32(p)); p+=4; + v2 = XXH32_round(v2, XXH_readLE32(p)); p+=4; + v3 = XXH32_round(v3, XXH_readLE32(p)); p+=4; + v4 = XXH32_round(v4, XXH_readLE32(p)); p+=4; + } while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) { + XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + } + + return XXH_OK; +} + + +XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* state) +{ + xxh_u32 h32; + + if (state->large_len) { + h32 = XXH_rotl32(state->v1, 1) + + XXH_rotl32(state->v2, 7) + + XXH_rotl32(state->v3, 12) + + XXH_rotl32(state->v4, 18); + } else { + h32 = state->v3 /* == seed */ + XXH_PRIME32_5; + } + + h32 += state->total_len_32; + + return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); +} + + +/******* Canonical representation *******/ /* -These structures allow static allocation of XXH states. -States must then be initialized using XXHnn_reset() before first use. + * The default return values from XXH functions are unsigned 32 and 64 bit + * integers. + * + * The canonical representation uses big endian convention, the same convention + * as human-readable numbers (large digits first). + * + * This way, hash values can be written into a file or buffer, remaining + * comparable across different systems. + * + * The following functions allow transformation of hash values to and from their + * canonical format. + */ +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); + memcpy(dst, &hash, sizeof(*dst)); +} -If you prefer dynamic allocation, please refer to functions below. -*/ +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) +{ + return XXH_readBE32(src); +} -XXH32_state_t* XXH32_createState(void); -XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); -XXH64_state_t* XXH64_createState(void); -XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); +#ifndef XXH_NO_LONG_LONG + +/* ******************************************************************* +* 64-bit hash functions +*********************************************************************/ + +/******* Memory access *******/ + +typedef XXH64_hash_t xxh_u64; + +#ifdef XXH_OLD_NAMES +# define U64 xxh_u64 +#endif + +/*! + * XXH_REROLL_XXH64: + * Whether to reroll the XXH64_finalize() loop. + * + * Just like XXH32, we can unroll the XXH64_finalize() loop. This can be a + * performance gain on 64-bit hosts, as only one jump is required. + * + * However, on 32-bit hosts, because arithmetic needs to be done with two 32-bit + * registers, and 64-bit arithmetic needs to be simulated, it isn't beneficial + * to unroll. The code becomes ridiculously large (the largest function in the + * binary on i386!), and rerolling it saves anywhere from 3kB to 20kB. It is + * also slightly faster because it fits into cache better and is more likely + * to be inlined by the compiler. + * + * If XXH_REROLL is defined, this is ignored and the loop is always rerolled. + */ +#ifndef XXH_REROLL_XXH64 +# if (defined(__ILP32__) || defined(_ILP32)) /* ILP32 is often defined on 32-bit GCC family */ \ + || !(defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) /* x86-64 */ \ + || defined(_M_ARM64) || defined(__aarch64__) || defined(__arm64__) /* aarch64 */ \ + || defined(__PPC64__) || defined(__PPC64LE__) || defined(__ppc64__) || defined(__powerpc64__) /* ppc64 */ \ + || defined(__mips64__) || defined(__mips64)) /* mips64 */ \ + || (!defined(SIZE_MAX) || SIZE_MAX < ULLONG_MAX) /* check limits */ +# define XXH_REROLL_XXH64 1 +# else +# define XXH_REROLL_XXH64 0 +# endif +#endif /* !defined(XXH_REROLL_XXH64) */ + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) +/* + * Manual byteshift. Best for old compilers which don't inline memcpy. + * We actually directly use XXH_readLE64 and XXH_readBE64. + */ +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static xxh_u64 XXH_read64(const void* memPtr) { return *(const xxh_u64*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* -These functions create and release memory for XXH state. -States must then be initialized using XXHnn_reset() before first use. -*/ + * __pack instructions are safer, but compiler specific, hence potentially + * problematic for some compilers. + * + * Currently only defined for GCC and ICC. + */ +#ifdef XXH_OLD_NAMES +typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; +#endif +static xxh_u64 XXH_read64(const void* ptr) +{ + typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64; + return ((const xxh_unalign64*)ptr)->u64; +} - -XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed); -XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); -unsigned int XXH32_digest (const XXH32_state_t* statePtr); - -XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); -XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); -unsigned long long XXH64_digest (const XXH64_state_t* statePtr); +#else /* -These functions calculate the xxHash of an input provided in multiple smaller packets, -as opposed to an input provided as a single block. + * Portable and safe solution. Generally efficient. + * see: https://stackoverflow.com/a/32095106/646947 + */ +static xxh_u64 XXH_read64(const void* memPtr) +{ + xxh_u64 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} -XXH state space must first be allocated, using either static or dynamic method provided above. +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ -Start a new hash by initializing state with a seed, using XXHnn_reset(). +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap64 _byteswap_uint64 +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap64 __builtin_bswap64 +#else +static xxh_u64 XXH_swap64 (xxh_u64 x) +{ + return ((x << 56) & 0xff00000000000000ULL) | + ((x << 40) & 0x00ff000000000000ULL) | + ((x << 24) & 0x0000ff0000000000ULL) | + ((x << 8) & 0x000000ff00000000ULL) | + ((x >> 8) & 0x00000000ff000000ULL) | + ((x >> 24) & 0x0000000000ff0000ULL) | + ((x >> 40) & 0x000000000000ff00ULL) | + ((x >> 56) & 0x00000000000000ffULL); +} +#endif -Then, feed the hash state by calling XXHnn_update() as many times as necessary. -Obviously, input must be valid, meaning allocated and read accessible. -The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. -Finally, you can produce a hash anytime, by using XXHnn_digest(). -This function returns the final nn-bits hash. -You can nonetheless continue feeding the hash state with more input, -and therefore get some new hashes, by calling again XXHnn_digest(). +/* XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. */ +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) -When you are done, don't forget to free XXH state space, using typically XXHnn_freeState(). -*/ +XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[0] + | ((xxh_u64)bytePtr[1] << 8) + | ((xxh_u64)bytePtr[2] << 16) + | ((xxh_u64)bytePtr[3] << 24) + | ((xxh_u64)bytePtr[4] << 32) + | ((xxh_u64)bytePtr[5] << 40) + | ((xxh_u64)bytePtr[6] << 48) + | ((xxh_u64)bytePtr[7] << 56); +} + +XXH_FORCE_INLINE xxh_u64 XXH_readBE64(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[7] + | ((xxh_u64)bytePtr[6] << 8) + | ((xxh_u64)bytePtr[5] << 16) + | ((xxh_u64)bytePtr[4] << 24) + | ((xxh_u64)bytePtr[3] << 32) + | ((xxh_u64)bytePtr[2] << 40) + | ((xxh_u64)bytePtr[1] << 48) + | ((xxh_u64)bytePtr[0] << 56); +} + +#else +XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); +} + +static xxh_u64 XXH_readBE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); +} +#endif + +XXH_FORCE_INLINE xxh_u64 +XXH_readLE64_align(const void* ptr, XXH_alignment align) +{ + if (align==XXH_unaligned) + return XXH_readLE64(ptr); + else + return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr); +} + + +/******* xxh64 *******/ + +static const xxh_u64 XXH_PRIME64_1 = 0x9E3779B185EBCA87ULL; /* 0b1001111000110111011110011011000110000101111010111100101010000111 */ +static const xxh_u64 XXH_PRIME64_2 = 0xC2B2AE3D27D4EB4FULL; /* 0b1100001010110010101011100011110100100111110101001110101101001111 */ +static const xxh_u64 XXH_PRIME64_3 = 0x165667B19E3779F9ULL; /* 0b0001011001010110011001111011000110011110001101110111100111111001 */ +static const xxh_u64 XXH_PRIME64_4 = 0x85EBCA77C2B2AE63ULL; /* 0b1000010111101011110010100111011111000010101100101010111001100011 */ +static const xxh_u64 XXH_PRIME64_5 = 0x27D4EB2F165667C5ULL; /* 0b0010011111010100111010110010111100010110010101100110011111000101 */ + +#ifdef XXH_OLD_NAMES +# define PRIME64_1 XXH_PRIME64_1 +# define PRIME64_2 XXH_PRIME64_2 +# define PRIME64_3 XXH_PRIME64_3 +# define PRIME64_4 XXH_PRIME64_4 +# define PRIME64_5 XXH_PRIME64_5 +#endif + +static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) +{ + acc += input * XXH_PRIME64_2; + acc = XXH_rotl64(acc, 31); + acc *= XXH_PRIME64_1; + return acc; +} + +static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val) +{ + val = XXH64_round(0, val); + acc ^= val; + acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4; + return acc; +} + +static xxh_u64 XXH64_avalanche(xxh_u64 h64) +{ + h64 ^= h64 >> 33; + h64 *= XXH_PRIME64_2; + h64 ^= h64 >> 29; + h64 *= XXH_PRIME64_3; + h64 ^= h64 >> 32; + return h64; +} + + +#define XXH_get64bits(p) XXH_readLE64_align(p, align) + +static xxh_u64 +XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) +{ +#define XXH_PROCESS1_64 do { \ + h64 ^= (*ptr++) * XXH_PRIME64_5; \ + h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1; \ +} while (0) + +#define XXH_PROCESS4_64 do { \ + h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1; \ + ptr += 4; \ + h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3; \ +} while (0) + +#define XXH_PROCESS8_64 do { \ + xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr)); \ + ptr += 8; \ + h64 ^= k1; \ + h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4; \ +} while (0) + + /* Rerolled version for 32-bit targets is faster and much smaller. */ + if (XXH_REROLL || XXH_REROLL_XXH64) { + len &= 31; + while (len >= 8) { + XXH_PROCESS8_64; + len -= 8; + } + if (len >= 4) { + XXH_PROCESS4_64; + len -= 4; + } + while (len > 0) { + XXH_PROCESS1_64; + --len; + } + return XXH64_avalanche(h64); + } else { + switch(len & 31) { + case 24: XXH_PROCESS8_64; + /* fallthrough */ + case 16: XXH_PROCESS8_64; + /* fallthrough */ + case 8: XXH_PROCESS8_64; + return XXH64_avalanche(h64); + + case 28: XXH_PROCESS8_64; + /* fallthrough */ + case 20: XXH_PROCESS8_64; + /* fallthrough */ + case 12: XXH_PROCESS8_64; + /* fallthrough */ + case 4: XXH_PROCESS4_64; + return XXH64_avalanche(h64); + + case 25: XXH_PROCESS8_64; + /* fallthrough */ + case 17: XXH_PROCESS8_64; + /* fallthrough */ + case 9: XXH_PROCESS8_64; + XXH_PROCESS1_64; + return XXH64_avalanche(h64); + + case 29: XXH_PROCESS8_64; + /* fallthrough */ + case 21: XXH_PROCESS8_64; + /* fallthrough */ + case 13: XXH_PROCESS8_64; + /* fallthrough */ + case 5: XXH_PROCESS4_64; + XXH_PROCESS1_64; + return XXH64_avalanche(h64); + + case 26: XXH_PROCESS8_64; + /* fallthrough */ + case 18: XXH_PROCESS8_64; + /* fallthrough */ + case 10: XXH_PROCESS8_64; + XXH_PROCESS1_64; + XXH_PROCESS1_64; + return XXH64_avalanche(h64); + + case 30: XXH_PROCESS8_64; + /* fallthrough */ + case 22: XXH_PROCESS8_64; + /* fallthrough */ + case 14: XXH_PROCESS8_64; + /* fallthrough */ + case 6: XXH_PROCESS4_64; + XXH_PROCESS1_64; + XXH_PROCESS1_64; + return XXH64_avalanche(h64); + + case 27: XXH_PROCESS8_64; + /* fallthrough */ + case 19: XXH_PROCESS8_64; + /* fallthrough */ + case 11: XXH_PROCESS8_64; + XXH_PROCESS1_64; + XXH_PROCESS1_64; + XXH_PROCESS1_64; + return XXH64_avalanche(h64); + + case 31: XXH_PROCESS8_64; + /* fallthrough */ + case 23: XXH_PROCESS8_64; + /* fallthrough */ + case 15: XXH_PROCESS8_64; + /* fallthrough */ + case 7: XXH_PROCESS4_64; + /* fallthrough */ + case 3: XXH_PROCESS1_64; + /* fallthrough */ + case 2: XXH_PROCESS1_64; + /* fallthrough */ + case 1: XXH_PROCESS1_64; + /* fallthrough */ + case 0: return XXH64_avalanche(h64); + } + } + /* impossible to reach */ + XXH_ASSERT(0); + return 0; /* unreachable, but some compilers complain without it */ +} + +#ifdef XXH_OLD_NAMES +# define PROCESS1_64 XXH_PROCESS1_64 +# define PROCESS4_64 XXH_PROCESS4_64 +# define PROCESS8_64 XXH_PROCESS8_64 +#else +# undef XXH_PROCESS1_64 +# undef XXH_PROCESS4_64 +# undef XXH_PROCESS8_64 +#endif + +XXH_FORCE_INLINE xxh_u64 +XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align) +{ + const xxh_u8* bEnd = input + len; + xxh_u64 h64; + +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + if (input==NULL) { + len=0; + bEnd=input=(const xxh_u8*)(size_t)32; + } +#endif + + if (len>=32) { + const xxh_u8* const limit = bEnd - 32; + xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + xxh_u64 v2 = seed + XXH_PRIME64_2; + xxh_u64 v3 = seed + 0; + xxh_u64 v4 = seed - XXH_PRIME64_1; + + do { + v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; + v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; + v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; + v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; + } while (input<=limit); + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + + } else { + h64 = seed + XXH_PRIME64_5; + } + + h64 += (xxh_u64) len; + + return XXH64_finalize(h64, input, len, align); +} + + +XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH64_state_t state; + XXH64_reset(&state, seed); + XXH64_update(&state, (const xxh_u8*)input, len); + return XXH64_digest(&state); + +#else + + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ + return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_aligned); + } } + + return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned); + +#endif +} + +/******* Hash Streaming *******/ + +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) +{ + return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); +} +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + +XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed) +{ + XXH64_state_t state; /* use a local state to memcpy() in order to avoid strict-aliasing warnings */ + memset(&state, 0, sizeof(state)); + state.v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + state.v2 = seed + XXH_PRIME64_2; + state.v3 = seed + 0; + state.v4 = seed - XXH_PRIME64_1; + /* do not write into reserved64, might be removed in a future version */ + memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved64)); + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH64_update (XXH64_state_t* state, const void* input, size_t len) +{ + if (input==NULL) +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + return XXH_OK; +#else + return XXH_ERROR; +#endif + + { const xxh_u8* p = (const xxh_u8*)input; + const xxh_u8* const bEnd = p + len; + + state->total_len += len; + + if (state->memsize + len < 32) { /* fill in tmp buffer */ + XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); + state->memsize += (xxh_u32)len; + return XXH_OK; + } + + if (state->memsize) { /* tmp buffer is full */ + XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); + state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0)); + state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1)); + state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2)); + state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3)); + p += 32-state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) { + const xxh_u8* const limit = bEnd - 32; + xxh_u64 v1 = state->v1; + xxh_u64 v2 = state->v2; + xxh_u64 v3 = state->v3; + xxh_u64 v4 = state->v4; + + do { + v1 = XXH64_round(v1, XXH_readLE64(p)); p+=8; + v2 = XXH64_round(v2, XXH_readLE64(p)); p+=8; + v3 = XXH64_round(v3, XXH_readLE64(p)); p+=8; + v4 = XXH64_round(v4, XXH_readLE64(p)); p+=8; + } while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) { + XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + } + + return XXH_OK; +} + + +XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* state) +{ + xxh_u64 h64; + + if (state->total_len >= 32) { + xxh_u64 const v1 = state->v1; + xxh_u64 const v2 = state->v2; + xxh_u64 const v3 = state->v3; + xxh_u64 const v4 = state->v4; + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + } else { + h64 = state->v3 /*seed*/ + XXH_PRIME64_5; + } + + h64 += (xxh_u64) state->total_len; + + return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); +} + + +/******* Canonical representation *******/ + +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); + memcpy(dst, &hash, sizeof(*dst)); +} + +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) +{ + return XXH_readBE64(src); +} + + + +/* ********************************************************************* +* XXH3 +* New generation hash designed for speed on small keys and vectorization +************************************************************************ */ + +/* === Compiler specifics === */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#else +/* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */ +# define XXH_RESTRICT /* disable */ +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 3)) \ + || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ + || defined(__clang__) +# define XXH_likely(x) __builtin_expect(x, 1) +# define XXH_unlikely(x) __builtin_expect(x, 0) +#else +# define XXH_likely(x) (x) +# define XXH_unlikely(x) (x) +#endif + +#if defined(__GNUC__) +# if defined(__AVX2__) +# include +# elif defined(__SSE2__) +# include +# elif defined(__ARM_NEON__) || defined(__ARM_NEON) +# define inline __inline__ /* circumvent a clang bug */ +# include +# undef inline +# endif +#elif defined(_MSC_VER) +# include +#endif + +/* + * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while + * remaining a true 64-bit/128-bit hash function. + * + * This is done by prioritizing a subset of 64-bit operations that can be + * emulated without too many steps on the average 32-bit machine. + * + * For example, these two lines seem similar, and run equally fast on 64-bit: + * + * xxh_u64 x; + * x ^= (x >> 47); // good + * x ^= (x >> 13); // bad + * + * However, to a 32-bit machine, there is a major difference. + * + * x ^= (x >> 47) looks like this: + * + * x.lo ^= (x.hi >> (47 - 32)); + * + * while x ^= (x >> 13) looks like this: + * + * // note: funnel shifts are not usually cheap. + * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13)); + * x.hi ^= (x.hi >> 13); + * + * The first one is significantly faster than the second, simply because the + * shift is larger than 32. This means: + * - All the bits we need are in the upper 32 bits, so we can ignore the lower + * 32 bits in the shift. + * - The shift result will always fit in the lower 32 bits, and therefore, + * we can ignore the upper 32 bits in the xor. + * + * Thanks to this optimization, XXH3 only requires these features to be efficient: + * + * - Usable unaligned access + * - A 32-bit or 64-bit ALU + * - If 32-bit, a decent ADC instruction + * - A 32 or 64-bit multiply with a 64-bit result + * - For the 128-bit variant, a decent byteswap helps short inputs. + * + * The first two are already required by XXH32, and almost all 32-bit and 64-bit + * platforms which can run XXH32 can run XXH3 efficiently. + * + * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one + * notable exception. + * + * First of all, Thumb-1 lacks support for the UMULL instruction which + * performs the important long multiply. This means numerous __aeabi_lmul + * calls. + * + * Second of all, the 8 functional registers are just not enough. + * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need + * Lo registers, and this shuffling results in thousands more MOVs than A32. + * + * A32 and T32 don't have this limitation. They can access all 14 registers, + * do a 32->64 multiply with UMULL, and the flexible operand allowing free + * shifts is helpful, too. + * + * Therefore, we do a quick sanity check. + * + * If compiling Thumb-1 for a target which supports ARM instructions, we will + * emit a warning, as it is not a "sane" platform to compile for. + * + * Usually, if this happens, it is because of an accident and you probably need + * to specify -march, as you likely meant to compile for a newer architecture. + * + * Credit: large sections of the vectorial and asm source code paths + * have been contributed by @easyaspi314 + */ +#if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM) +# warning "XXH3 is highly inefficient without ARM or Thumb-2." +#endif + +/* ========================================== + * Vectorization detection + * ========================================== */ +#define XXH_SCALAR 0 /* Portable scalar version */ +#define XXH_SSE2 1 /* SSE2 for Pentium 4 and all x86_64 */ +#define XXH_AVX2 2 /* AVX2 for Haswell and Bulldozer */ +#define XXH_AVX512 3 /* AVX512 for Skylake and Icelake */ +#define XXH_NEON 4 /* NEON for most ARMv7-A and all AArch64 */ +#define XXH_VSX 5 /* VSX and ZVector for POWER8/z13 */ + +#ifndef XXH_VECTOR /* can be defined on command line */ +# if defined(__AVX512F__) +# define XXH_VECTOR XXH_AVX512 +# elif defined(__AVX2__) +# define XXH_VECTOR XXH_AVX2 +# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) +# define XXH_VECTOR XXH_SSE2 +# elif defined(__GNUC__) /* msvc support maybe later */ \ + && (defined(__ARM_NEON__) || defined(__ARM_NEON)) \ + && (defined(__LITTLE_ENDIAN__) /* We only support little endian NEON */ \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) +# define XXH_VECTOR XXH_NEON +# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \ + || (defined(__s390x__) && defined(__VEC__)) \ + && defined(__GNUC__) /* TODO: IBM XL */ +# define XXH_VECTOR XXH_VSX +# else +# define XXH_VECTOR XXH_SCALAR +# endif +#endif + +/* + * Controls the alignment of the accumulator, + * for compatibility with aligned vector loads, which are usually faster. + */ +#ifndef XXH_ACC_ALIGN +# if defined(XXH_X86DISPATCH) +# define XXH_ACC_ALIGN 64 /* for compatibility with avx512 */ +# elif XXH_VECTOR == XXH_SCALAR /* scalar */ +# define XXH_ACC_ALIGN 8 +# elif XXH_VECTOR == XXH_SSE2 /* sse2 */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_AVX2 /* avx2 */ +# define XXH_ACC_ALIGN 32 +# elif XXH_VECTOR == XXH_NEON /* neon */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_VSX /* vsx */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_AVX512 /* avx512 */ +# define XXH_ACC_ALIGN 64 +# endif +#endif + +#if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \ + || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512 +# define XXH_SEC_ALIGN XXH_ACC_ALIGN +#else +# define XXH_SEC_ALIGN 8 +#endif + +/* + * UGLY HACK: + * GCC usually generates the best code with -O3 for xxHash. + * + * However, when targeting AVX2, it is overzealous in its unrolling resulting + * in code roughly 3/4 the speed of Clang. + * + * There are other issues, such as GCC splitting _mm256_loadu_si256 into + * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which + * only applies to Sandy and Ivy Bridge... which don't even support AVX2. + * + * That is why when compiling the AVX2 version, it is recommended to use either + * -O2 -mavx2 -march=haswell + * or + * -O2 -mavx2 -mno-avx256-split-unaligned-load + * for decent performance, or to use Clang instead. + * + * Fortunately, we can control the first one with a pragma that forces GCC into + * -O2, but the other one we can't control without "failed to inline always + * inline function due to target mismatch" warnings. + */ +#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ + && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ +# pragma GCC push_options +# pragma GCC optimize("-O2") +#endif + + +#if XXH_VECTOR == XXH_NEON +/* + * NEON's setup for vmlal_u32 is a little more complicated than it is on + * SSE2, AVX2, and VSX. + * + * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast. + * + * To do the same operation, the 128-bit 'Q' register needs to be split into + * two 64-bit 'D' registers, performing this operation:: + * + * [ a | b ] + * | '---------. .--------' | + * | x | + * | .---------' '--------. | + * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ] + * + * Due to significant changes in aarch64, the fastest method for aarch64 is + * completely different than the fastest method for ARMv7-A. + * + * ARMv7-A treats D registers as unions overlaying Q registers, so modifying + * D11 will modify the high half of Q5. This is similar to how modifying AH + * will only affect bits 8-15 of AX on x86. + * + * VZIP takes two registers, and puts even lanes in one register and odd lanes + * in the other. + * + * On ARMv7-A, this strangely modifies both parameters in place instead of + * taking the usual 3-operand form. + * + * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the + * lower and upper halves of the Q register to end up with the high and low + * halves where we want - all in one instruction. + * + * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] } + * + * Unfortunately we need inline assembly for this: Instructions modifying two + * registers at once is not possible in GCC or Clang's IR, and they have to + * create a copy. + * + * aarch64 requires a different approach. + * + * In order to make it easier to write a decent compiler for aarch64, many + * quirks were removed, such as conditional execution. + * + * NEON was also affected by this. + * + * aarch64 cannot access the high bits of a Q-form register, and writes to a + * D-form register zero the high bits, similar to how writes to W-form scalar + * registers (or DWORD registers on x86_64) work. + * + * The formerly free vget_high intrinsics now require a vext (with a few + * exceptions) + * + * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent + * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one + * operand. + * + * The equivalent of the VZIP.32 on the lower and upper halves would be this + * mess: + * + * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] } + * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] } + * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] } + * + * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN): + * + * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32); + * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF); + * + * This is available on ARMv7-A, but is less efficient than a single VZIP.32. + */ + +/* + * Function-like macro: + * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi) + * { + * outLo = (uint32x2_t)(in & 0xFFFFFFFF); + * outHi = (uint32x2_t)(in >> 32); + * in = UNDEFINED; + * } + */ +# if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \ + && defined(__GNUC__) \ + && !defined(__aarch64__) && !defined(__arm64__) +# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ + do { \ + /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \ + /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \ + /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \ + __asm__("vzip.32 %e0, %f0" : "+w" (in)); \ + (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \ + (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \ + } while (0) +# else +# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ + do { \ + (outLo) = vmovn_u64 (in); \ + (outHi) = vshrn_n_u64 ((in), 32); \ + } while (0) +# endif +#endif /* XXH_VECTOR == XXH_NEON */ + +/* + * VSX and Z Vector helpers. + * + * This is very messy, and any pull requests to clean this up are welcome. + * + * There are a lot of problems with supporting VSX and s390x, due to + * inconsistent intrinsics, spotty coverage, and multiple endiannesses. + */ +#if XXH_VECTOR == XXH_VSX +# if defined(__s390x__) +# include +# else +/* gcc's altivec.h can have the unwanted consequence to unconditionally + * #define bool, vector, and pixel keywords, + * with bad consequences for programs already using these keywords for other purposes. + * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined. + * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler, + * but it seems that, in some cases, it isn't. + * Force the build macro to be defined, so that keywords are not altered. + */ +# if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__) +# define __APPLE_ALTIVEC__ +# endif +# include +# endif + +typedef __vector unsigned long long xxh_u64x2; +typedef __vector unsigned char xxh_u8x16; +typedef __vector unsigned xxh_u32x4; + +# ifndef XXH_VSX_BE +# if defined(__BIG_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define XXH_VSX_BE 1 +# elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__ +# warning "-maltivec=be is not recommended. Please use native endianness." +# define XXH_VSX_BE 1 +# else +# define XXH_VSX_BE 0 +# endif +# endif /* !defined(XXH_VSX_BE) */ + +# if XXH_VSX_BE +/* A wrapper for POWER9's vec_revb. */ +# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__)) +# define XXH_vec_revb vec_revb +# else +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val) +{ + xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 }; + return vec_perm(val, val, vByteSwap); +} +# endif +# endif /* XXH_VSX_BE */ + +/* + * Performs an unaligned load and byte swaps it on big endian. + */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr) +{ + xxh_u64x2 ret; + memcpy(&ret, ptr, sizeof(xxh_u64x2)); +# if XXH_VSX_BE + ret = XXH_vec_revb(ret); +# endif + return ret; +} + +/* + * vec_mulo and vec_mule are very problematic intrinsics on PowerPC + * + * These intrinsics weren't added until GCC 8, despite existing for a while, + * and they are endian dependent. Also, their meaning swap depending on version. + * */ +# if defined(__s390x__) + /* s390x is always big endian, no issue on this platform */ +# define XXH_vec_mulo vec_mulo +# define XXH_vec_mule vec_mule +# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) +/* Clang has a better way to control this, we can just use the builtin which doesn't swap. */ +# define XXH_vec_mulo __builtin_altivec_vmulouw +# define XXH_vec_mule __builtin_altivec_vmuleuw +# else +/* gcc needs inline assembly */ +/* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b) +{ + xxh_u64x2 result; + __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); + return result; +} +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b) +{ + xxh_u64x2 result; + __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); + return result; +} +# endif /* XXH_vec_mulo, XXH_vec_mule */ +#endif /* XXH_VECTOR == XXH_VSX */ + + +/* prefetch + * can be disabled, by declaring XXH_NO_PREFETCH build macro */ +#if defined(XXH_NO_PREFETCH) +# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ +#else +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) +# else +# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ +# endif +#endif /* XXH_NO_PREFETCH */ + + +/* ========================================== + * XXH3 default settings + * ========================================== */ + +#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */ + +#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN) +# error "default keyset is not large enough" +#endif + +/* Pseudorandom secret taken directly from FARSH */ +XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = { + 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, + 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, + 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, + 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, + 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, + 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, + 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, + 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, + 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, + 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, + 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, + 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, +}; + + +#ifdef XXH_OLD_NAMES +# define kSecret XXH3_kSecret +#endif + +/* + * Calculates a 32-bit to 64-bit long multiply. + * + * Wraps __emulu on MSVC x86 because it tends to call __allmul when it doesn't + * need to (but it shouldn't need to anyways, it is about 7 instructions to do + * a 64x64 multiply...). Since we know that this will _always_ emit MULL, we + * use that instead of the normal method. + * + * If you are compiling for platforms like Thumb-1 and don't have a better option, + * you may also want to write your own long multiply routine here. + * + * XXH_FORCE_INLINE xxh_u64 XXH_mult32to64(xxh_u64 x, xxh_u64 y) + * { + * return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF); + * } + */ +#if defined(_MSC_VER) && defined(_M_IX86) +# include +# define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y)) +#else +/* + * Downcast + upcast is usually better than masking on older compilers like + * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers. + * + * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands + * and perform a full 64x64 multiply -- entirely redundant on 32-bit. + */ +# define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y)) +#endif + +/* + * Calculates a 64->128-bit long multiply. + * + * Uses __uint128_t and _umul128 if available, otherwise uses a scalar version. + */ +static XXH128_hash_t +XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs) +{ + /* + * GCC/Clang __uint128_t method. + * + * On most 64-bit targets, GCC and Clang define a __uint128_t type. + * This is usually the best way as it usually uses a native long 64-bit + * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64. + * + * Usually. + * + * Despite being a 32-bit platform, Clang (and emscripten) define this type + * despite not having the arithmetic for it. This results in a laggy + * compiler builtin call which calculates a full 128-bit multiply. + * In that case it is best to use the portable one. + * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677 + */ +#if defined(__GNUC__) && !defined(__wasm__) \ + && defined(__SIZEOF_INT128__) \ + || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) + + __uint128_t const product = (__uint128_t)lhs * (__uint128_t)rhs; + XXH128_hash_t r128; + r128.low64 = (xxh_u64)(product); + r128.high64 = (xxh_u64)(product >> 64); + return r128; + + /* + * MSVC for x64's _umul128 method. + * + * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct); + * + * This compiles to single operand MUL on x64. + */ +#elif defined(_M_X64) || defined(_M_IA64) + +#ifndef _MSC_VER +# pragma intrinsic(_umul128) +#endif + xxh_u64 product_high; + xxh_u64 const product_low = _umul128(lhs, rhs, &product_high); + XXH128_hash_t r128; + r128.low64 = product_low; + r128.high64 = product_high; + return r128; + +#else + /* + * Portable scalar method. Optimized for 32-bit and 64-bit ALUs. + * + * This is a fast and simple grade school multiply, which is shown below + * with base 10 arithmetic instead of base 0x100000000. + * + * 9 3 // D2 lhs = 93 + * x 7 5 // D2 rhs = 75 + * ---------- + * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15 + * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45 + * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21 + * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63 + * --------- + * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27 + * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67 + * --------- + * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975 + * + * The reasons for adding the products like this are: + * 1. It avoids manual carry tracking. Just like how + * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX. + * This avoids a lot of complexity. + * + * 2. It hints for, and on Clang, compiles to, the powerful UMAAL + * instruction available in ARM's Digital Signal Processing extension + * in 32-bit ARMv6 and later, which is shown below: + * + * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm) + * { + * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm; + * *RdLo = (xxh_u32)(product & 0xFFFFFFFF); + * *RdHi = (xxh_u32)(product >> 32); + * } + * + * This instruction was designed for efficient long multiplication, and + * allows this to be calculated in only 4 instructions at speeds + * comparable to some 64-bit ALUs. + * + * 3. It isn't terrible on other platforms. Usually this will be a couple + * of 32-bit ADD/ADCs. + */ + + /* First calculate all of the cross products. */ + xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF); + xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF); + xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32); + xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32); + + /* Now add the products together. These will never overflow. */ + xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi; + xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi; + xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF); + + XXH128_hash_t r128; + r128.low64 = lower; + r128.high64 = upper; + return r128; +#endif +} + +/* + * Does a 64-bit to 128-bit multiply, then XOR folds it. + * + * The reason for the separate function is to prevent passing too many structs + * around by value. This will hopefully inline the multiply, but we don't force it. + */ +static xxh_u64 +XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs) +{ + XXH128_hash_t product = XXH_mult64to128(lhs, rhs); + return product.low64 ^ product.high64; +} + +/* Seems to produce slightly better code on GCC for some reason. */ +XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) +{ + XXH_ASSERT(0 <= shift && shift < 64); + return v64 ^ (v64 >> shift); +} + +/* + * This is a fast avalanche stage, + * suitable when input bits are already partially mixed + */ +static XXH64_hash_t XXH3_avalanche(xxh_u64 h64) +{ + h64 = XXH_xorshift64(h64, 37); + h64 *= 0x165667919E3779F9ULL; + h64 = XXH_xorshift64(h64, 32); + return h64; +} + +/* + * This is a stronger avalanche, + * inspired by Pelle Evensen's rrmxmx + * preferable when input has not been previously mixed + */ +static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len) +{ + /* this mix is inspired by Pelle Evensen's rrmxmx */ + h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24); + h64 *= 0x9FB21C651E98DF25ULL; + h64 ^= (h64 >> 35) + len ; + h64 *= 0x9FB21C651E98DF25ULL; + return XXH_xorshift64(h64, 28); +} + + +/* ========================================== + * Short keys + * ========================================== + * One of the shortcomings of XXH32 and XXH64 was that their performance was + * sub-optimal on short lengths. It used an iterative algorithm which strongly + * favored lengths that were a multiple of 4 or 8. + * + * Instead of iterating over individual inputs, we use a set of single shot + * functions which piece together a range of lengths and operate in constant time. + * + * Additionally, the number of multiplies has been significantly reduced. This + * reduces latency, especially when emulating 64-bit multiplies on 32-bit. + * + * Depending on the platform, this may or may not be faster than XXH32, but it + * is almost guaranteed to be faster than XXH64. + */ + +/* + * At very short lengths, there isn't enough input to fully hide secrets, or use + * the entire secret. + * + * There is also only a limited amount of mixing we can do before significantly + * impacting performance. + * + * Therefore, we use different sections of the secret and always mix two secret + * samples with an XOR. This should have no effect on performance on the + * seedless or withSeed variants because everything _should_ be constant folded + * by modern compilers. + * + * The XOR mixing hides individual parts of the secret and increases entropy. + * + * This adds an extra layer of strength for custom secrets. + */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(1 <= len && len <= 3); + XXH_ASSERT(secret != NULL); + /* + * len = 1: combined = { input[0], 0x01, input[0], input[0] } + * len = 2: combined = { input[1], 0x02, input[0], input[1] } + * len = 3: combined = { input[2], 0x03, input[0], input[1] } + */ + { xxh_u8 const c1 = input[0]; + xxh_u8 const c2 = input[len >> 1]; + xxh_u8 const c3 = input[len - 1]; + xxh_u32 const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24) + | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8); + xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; + xxh_u64 const keyed = (xxh_u64)combined ^ bitflip; + return XXH64_avalanche(keyed); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(4 <= len && len < 8); + seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; + { xxh_u32 const input1 = XXH_readLE32(input); + xxh_u32 const input2 = XXH_readLE32(input + len - 4); + xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed; + xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32); + xxh_u64 const keyed = input64 ^ bitflip; + return XXH3_rrmxmx(keyed, len); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(8 <= len && len <= 16); + { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed; + xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed; + xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1; + xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2; + xxh_u64 const acc = len + + XXH_swap64(input_lo) + input_hi + + XXH3_mul128_fold64(input_lo, input_hi); + return XXH3_avalanche(acc); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(len <= 16); + { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed); + if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed); + if (len) return XXH3_len_1to3_64b(input, len, secret, seed); + return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64))); + } +} + +/* + * DISCLAIMER: There are known *seed-dependent* multicollisions here due to + * multiplication by zero, affecting hashes of lengths 17 to 240. + * + * However, they are very unlikely. + * + * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all + * unseeded non-cryptographic hashes, it does not attempt to defend itself + * against specially crafted inputs, only random inputs. + * + * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes + * cancelling out the secret is taken an arbitrary number of times (addressed + * in XXH3_accumulate_512), this collision is very unlikely with random inputs + * and/or proper seeding: + * + * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a + * function that is only called up to 16 times per hash with up to 240 bytes of + * input. + * + * This is not too bad for a non-cryptographic hash function, especially with + * only 64 bit outputs. + * + * The 128-bit variant (which trades some speed for strength) is NOT affected + * by this, although it is always a good idea to use a proper seed if you care + * about strength. + */ +XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64) +{ +#if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */ + /* + * UGLY HACK: + * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in + * slower code. + * + * By forcing seed64 into a register, we disrupt the cost model and + * cause it to scalarize. See `XXH32_round()` + * + * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600, + * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on + * GCC 9.2, despite both emitting scalar code. + * + * GCC generates much better scalar code than Clang for the rest of XXH3, + * which is why finding a more optimal codepath is an interest. + */ + __asm__ ("" : "+r" (seed64)); +#endif + { xxh_u64 const input_lo = XXH_readLE64(input); + xxh_u64 const input_hi = XXH_readLE64(input+8); + return XXH3_mul128_fold64( + input_lo ^ (XXH_readLE64(secret) + seed64), + input_hi ^ (XXH_readLE64(secret+8) - seed64) + ); + } +} + +/* For mid range keys, XXH3 uses a Mum-hash variant. */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(16 < len && len <= 128); + + { xxh_u64 acc = len * XXH_PRIME64_1; + if (len > 32) { + if (len > 64) { + if (len > 96) { + acc += XXH3_mix16B(input+48, secret+96, seed); + acc += XXH3_mix16B(input+len-64, secret+112, seed); + } + acc += XXH3_mix16B(input+32, secret+64, seed); + acc += XXH3_mix16B(input+len-48, secret+80, seed); + } + acc += XXH3_mix16B(input+16, secret+32, seed); + acc += XXH3_mix16B(input+len-32, secret+48, seed); + } + acc += XXH3_mix16B(input+0, secret+0, seed); + acc += XXH3_mix16B(input+len-16, secret+16, seed); + + return XXH3_avalanche(acc); + } +} + +#define XXH3_MIDSIZE_MAX 240 + +XXH_NO_INLINE XXH64_hash_t +XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + + #define XXH3_MIDSIZE_STARTOFFSET 3 + #define XXH3_MIDSIZE_LASTOFFSET 17 + + { xxh_u64 acc = len * XXH_PRIME64_1; + int const nbRounds = (int)len / 16; + int i; + for (i=0; i<8; i++) { + acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed); + } + acc = XXH3_avalanche(acc); + XXH_ASSERT(nbRounds >= 8); +#if defined(__clang__) /* Clang */ \ + && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ + /* + * UGLY HACK: + * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86. + * In everywhere else, it uses scalar code. + * + * For 64->128-bit multiplies, even if the NEON was 100% optimal, it + * would still be slower than UMAAL (see XXH_mult64to128). + * + * Unfortunately, Clang doesn't handle the long multiplies properly and + * converts them to the nonexistent "vmulq_u64" intrinsic, which is then + * scalarized into an ugly mess of VMOV.32 instructions. + * + * This mess is difficult to avoid without turning autovectorization + * off completely, but they are usually relatively minor and/or not + * worth it to fix. + * + * This loop is the easiest to fix, as unlike XXH32, this pragma + * _actually works_ because it is a loop vectorization instead of an + * SLP vectorization. + */ + #pragma clang loop vectorize(disable) +#endif + for (i=8 ; i < nbRounds; i++) { + acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); + } + /* last bytes */ + acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); + return XXH3_avalanche(acc); + } +} + + +/* ======= Long Keys ======= */ + +#define XXH_STRIPE_LEN 64 +#define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */ +#define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64)) + +#ifdef XXH_OLD_NAMES +# define STRIPE_LEN XXH_STRIPE_LEN +# define ACC_NB XXH_ACC_NB +#endif + +XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64) +{ + if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64); + memcpy(dst, &v64, sizeof(v64)); +} + +/* Several intrinsic functions below are supposed to accept __int64 as argument, + * as documented in https://software.intel.com/sites/landingpage/IntrinsicsGuide/ . + * However, several environments do not define __int64 type, + * requiring a workaround. + */ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) + typedef int64_t xxh_i64; +#else + /* the following type must have a width of 64-bit */ + typedef long long xxh_i64; +#endif + +/* + * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized. + * + * It is a hardened version of UMAC, based off of FARSH's implementation. + * + * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD + * implementations, and it is ridiculously fast. + * + * We harden it by mixing the original input to the accumulators as well as the product. + * + * This means that in the (relatively likely) case of a multiply by zero, the + * original input is preserved. + * + * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve + * cross-pollination, as otherwise the upper and lower halves would be + * essentially independent. + * + * This doesn't matter on 64-bit hashes since they all get merged together in + * the end, so we skip the extra step. + * + * Both XXH3_64bits and XXH3_128bits use this subroutine. + */ + +#if (XXH_VECTOR == XXH_AVX512) || defined(XXH_X86DISPATCH) + +#ifndef XXH_TARGET_AVX512 +# define XXH_TARGET_AVX512 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ALIGN(64) __m512i* const xacc = (__m512i *) acc; + XXH_ASSERT((((size_t)acc) & 63) == 0); + XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i)); + + { + /* data_vec = input[0]; */ + __m512i const data_vec = _mm512_loadu_si512 (input); + /* key_vec = secret[0]; */ + __m512i const key_vec = _mm512_loadu_si512 (secret); + /* data_key = data_vec ^ key_vec; */ + __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo); + /* xacc[0] += swap(data_vec); */ + __m512i const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2)); + __m512i const sum = _mm512_add_epi64(*xacc, data_swap); + /* xacc[0] += product; */ + *xacc = _mm512_add_epi64(product, sum); + } +} + +/* + * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing. + * + * Multiplication isn't perfect, as explained by Google in HighwayHash: + * + * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to + * // varying degrees. In descending order of goodness, bytes + * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32. + * // As expected, the upper and lower bytes are much worse. + * + * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291 + * + * Since our algorithm uses a pseudorandom secret to add some variance into the + * mix, we don't need to (or want to) mix as often or as much as HighwayHash does. + * + * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid + * extraction. + * + * Both XXH3_64bits and XXH3_128bits use this subroutine. + */ + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 63) == 0); + XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i)); + { XXH_ALIGN(64) __m512i* const xacc = (__m512i*) acc; + const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1); + + /* xacc[0] ^= (xacc[0] >> 47) */ + __m512i const acc_vec = *xacc; + __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47); + __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted); + /* xacc[0] ^= secret; */ + __m512i const key_vec = _mm512_loadu_si512 (secret); + __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + + /* xacc[0] *= XXH_PRIME32_1; */ + __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32); + __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32); + *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32)); + } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0); + XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64); + XXH_ASSERT(((size_t)customSecret & 63) == 0); + (void)(&XXH_writeLE64); + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i); + __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, -(xxh_i64)seed64); + + XXH_ALIGN(64) const __m512i* const src = (const __m512i*) XXH3_kSecret; + XXH_ALIGN(64) __m512i* const dest = ( __m512i*) customSecret; + int i; + for (i=0; i < nbRounds; ++i) { + /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*', + * this will warn "discards ‘const’ qualifier". */ + union { + XXH_ALIGN(64) const __m512i* cp; + XXH_ALIGN(64) void* p; + } remote_const_void; + remote_const_void.cp = src + i; + dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_AVX2) || defined(XXH_X86DISPATCH) + +#ifndef XXH_TARGET_AVX2 +# define XXH_TARGET_AVX2 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void +XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 31) == 0); + { XXH_ALIGN(32) __m256i* const xacc = (__m256i *) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xinput = (const __m256i *) input; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xsecret = (const __m256i *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) { + /* data_vec = xinput[i]; */ + __m256i const data_vec = _mm256_loadu_si256 (xinput+i); + /* key_vec = xsecret[i]; */ + __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); + /* data_key = data_vec ^ key_vec; */ + __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2)); + __m256i const sum = _mm256_add_epi64(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = _mm256_add_epi64(product, sum); + } } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void +XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 31) == 0); + { XXH_ALIGN(32) __m256i* const xacc = (__m256i*) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xsecret = (const __m256i *) secret; + const __m256i prime32 = _mm256_set1_epi32((int)XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m256i const acc_vec = xacc[i]; + __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47); + __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted); + /* xacc[i] ^= xsecret; */ + __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); + __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32); + __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32); + xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32)); + } + } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0); + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE / sizeof(__m256i)) == 6); + XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64); + (void)(&XXH_writeLE64); + XXH_PREFETCH(customSecret); + { __m256i const seed = _mm256_set_epi64x(-(xxh_i64)seed64, (xxh_i64)seed64, -(xxh_i64)seed64, (xxh_i64)seed64); + + XXH_ALIGN(64) const __m256i* const src = (const __m256i*) XXH3_kSecret; + XXH_ALIGN(64) __m256i* dest = ( __m256i*) customSecret; + +# if defined(__GNUC__) || defined(__clang__) + /* + * On GCC & Clang, marking 'dest' as modified will cause the compiler: + * - do not extract the secret from sse registers in the internal loop + * - use less common registers, and avoid pushing these reg into stack + * The asm hack causes Clang to assume that XXH3_kSecretPtr aliases with + * customSecret, and on aarch64, this prevented LDP from merging two + * loads together for free. Putting the loads together before the stores + * properly generates LDP. + */ + __asm__("" : "+r" (dest)); +# endif + + /* GCC -O2 need unroll loop manually */ + dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed); + dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed); + dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed); + dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed); + dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed); + dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed); + } +} + +#endif + +#if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH) + +#ifndef XXH_TARGET_SSE2 +# define XXH_TARGET_SSE2 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void +XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + /* SSE2 is just a half-scale version of the AVX2 version. */ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { XXH_ALIGN(16) __m128i* const xacc = (__m128i *) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xinput = (const __m128i *) input; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xsecret = (const __m128i *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = _mm_loadu_si128 (xinput+i); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = _mm_loadu_si128 (xsecret+i); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = _mm_mul_epu32 (data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2)); + __m128i const sum = _mm_add_epi64(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = _mm_add_epi64(product, sum); + } } +} + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void +XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { XXH_ALIGN(16) __m128i* const xacc = (__m128i*) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = _mm_set1_epi32((int)XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = _mm_srli_epi64 (acc_vec, 47); + __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = _mm_loadu_si128 (xsecret+i); + __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32); + __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32); + xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32)); + } + } +} + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); + (void)(&XXH_writeLE64); + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i); + +# if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900 + // MSVC 32bit mode does not support _mm_set_epi64x before 2015 + XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, -(xxh_i64)seed64 }; + __m128i const seed = _mm_load_si128((__m128i const*)seed64x2); +# else + __m128i const seed = _mm_set_epi64x(-(xxh_i64)seed64, (xxh_i64)seed64); +# endif + int i; + + XXH_ALIGN(64) const float* const src = (float const*) XXH3_kSecret; + XXH_ALIGN(XXH_SEC_ALIGN) __m128i* dest = (__m128i*) customSecret; +# if defined(__GNUC__) || defined(__clang__) + /* + * On GCC & Clang, marking 'dest' as modified will cause the compiler: + * - do not extract the secret from sse registers in the internal loop + * - use less common registers, and avoid pushing these reg into stack + */ + __asm__("" : "+r" (dest)); +# endif + + for (i=0; i < nbRounds; ++i) { + dest[i] = _mm_add_epi64(_mm_castps_si128(_mm_load_ps(src+i*4)), seed); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_NEON) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_neon( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + XXH_ALIGN(16) uint64x2_t* const xacc = (uint64x2_t *) acc; + /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */ + uint8_t const* const xinput = (const uint8_t *) input; + uint8_t const* const xsecret = (const uint8_t *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN / sizeof(uint64x2_t); i++) { + /* data_vec = xinput[i]; */ + uint8x16_t data_vec = vld1q_u8(xinput + (i * 16)); + /* key_vec = xsecret[i]; */ + uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); + uint64x2_t data_key; + uint32x2_t data_key_lo, data_key_hi; + /* xacc[i] += swap(data_vec); */ + uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec); + uint64x2_t const swapped = vextq_u64(data64, data64, 1); + xacc[i] = vaddq_u64 (xacc[i], swapped); + /* data_key = data_vec ^ key_vec; */ + data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec)); + /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF); + * data_key_hi = (uint32x2_t) (data_key >> 32); + * data_key = UNDEFINED; */ + XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); + /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */ + xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi); + + } + } +} + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + + { uint64x2_t* xacc = (uint64x2_t*) acc; + uint8_t const* xsecret = (uint8_t const*) secret; + uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(uint64x2_t); i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + uint64x2_t acc_vec = xacc[i]; + uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47); + uint64x2_t data_vec = veorq_u64 (acc_vec, shifted); + + /* xacc[i] ^= xsecret[i]; */ + uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); + uint64x2_t data_key = veorq_u64(data_vec, vreinterpretq_u64_u8(key_vec)); + + /* xacc[i] *= XXH_PRIME32_1 */ + uint32x2_t data_key_lo, data_key_hi; + /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF); + * data_key_hi = (uint32x2_t) (xacc[i] >> 32); + * xacc[i] = UNDEFINED; */ + XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); + { /* + * prod_hi = (data_key >> 32) * XXH_PRIME32_1; + * + * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will + * incorrectly "optimize" this: + * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b)); + * shifted = vshll_n_u32(tmp, 32); + * to this: + * tmp = "vmulq_u64"(a, b); // no such thing! + * shifted = vshlq_n_u64(tmp, 32); + * + * However, unlike SSE, Clang lacks a 64-bit multiply routine + * for NEON, and it scalarizes two 64-bit multiplies instead. + * + * vmull_u32 has the same timing as vmul_u32, and it avoids + * this bug completely. + * See https://bugs.llvm.org/show_bug.cgi?id=39967 + */ + uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime); + /* xacc[i] = prod_hi << 32; */ + xacc[i] = vshlq_n_u64(prod_hi, 32); + /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */ + xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime); + } + } } +} + +#endif + +#if (XXH_VECTOR == XXH_VSX) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + xxh_u64x2* const xacc = (xxh_u64x2*) acc; /* presumed aligned */ + xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */ + xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */ + xxh_u64x2 const v32 = { 32, 32 }; + size_t i; + for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { + /* data_vec = xinput[i]; */ + xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i); + /* key_vec = xsecret[i]; */ + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const data_key = data_vec ^ key_vec; + /* shuffled = (data_key << 32) | (data_key >> 32); */ + xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32); + /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */ + xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled); + xacc[i] += product; + + /* swap high and low halves */ +#ifdef __s390x__ + xacc[i] += vec_permi(data_vec, data_vec, 2); +#else + xacc[i] += vec_xxpermdi(data_vec, data_vec, 2); +#endif + } +} + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + + { xxh_u64x2* const xacc = (xxh_u64x2*) acc; + const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret; + /* constants */ + xxh_u64x2 const v32 = { 32, 32 }; + xxh_u64x2 const v47 = { 47, 47 }; + xxh_u32x4 const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 }; + size_t i; + for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + xxh_u64x2 const acc_vec = xacc[i]; + xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47); + + /* xacc[i] ^= xsecret[i]; */ + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const data_key = data_vec ^ key_vec; + + /* xacc[i] *= XXH_PRIME32_1 */ + /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */ + xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime); + /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */ + xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime); + xacc[i] = prod_odd + (prod_even << v32); + } } +} + +#endif + +/* scalar variants - universal */ + +XXH_FORCE_INLINE void +XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ + const xxh_u8* const xinput = (const xxh_u8*) input; /* no alignment restriction */ + const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ + size_t i; + XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0); + for (i=0; i < XXH_ACC_NB; i++) { + xxh_u64 const data_val = XXH_readLE64(xinput + 8*i); + xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + i*8); + xacc[i ^ 1] += data_val; /* swap adjacent lanes */ + xacc[i] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32); + } +} + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ + const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ + size_t i; + XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0); + for (i=0; i < XXH_ACC_NB; i++) { + xxh_u64 const key64 = XXH_readLE64(xsecret + 8*i); + xxh_u64 acc64 = xacc[i]; + acc64 = XXH_xorshift64(acc64, 47); + acc64 ^= key64; + acc64 *= XXH_PRIME32_1; + xacc[i] = acc64; + } +} + +XXH_FORCE_INLINE void +XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + /* + * We need a separate pointer for the hack below, + * which requires a non-const pointer. + * Any decent compiler will optimize this out otherwise. + */ + const xxh_u8* kSecretPtr = XXH3_kSecret; + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); + +#if defined(__clang__) && defined(__aarch64__) + /* + * UGLY HACK: + * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are + * placed sequentially, in order, at the top of the unrolled loop. + * + * While MOVK is great for generating constants (2 cycles for a 64-bit + * constant compared to 4 cycles for LDR), long MOVK chains stall the + * integer pipelines: + * I L S + * MOVK + * MOVK + * MOVK + * MOVK + * ADD + * SUB STR + * STR + * By forcing loads from memory (as the asm line causes Clang to assume + * that XXH3_kSecretPtr has been changed), the pipelines are used more + * efficiently: + * I L S + * LDR + * ADD LDR + * SUB STR + * STR + * XXH3_64bits_withSeed, len == 256, Snapdragon 835 + * without hack: 2654.4 MB/s + * with hack: 3202.9 MB/s + */ + __asm__("" : "+r" (kSecretPtr)); +#endif + /* + * Note: in debug mode, this overrides the asm optimization + * and Clang will emit MOVK chains again. + */ + XXH_ASSERT(kSecretPtr == XXH3_kSecret); + + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16; + int i; + for (i=0; i < nbRounds; i++) { + /* + * The asm hack causes Clang to assume that kSecretPtr aliases with + * customSecret, and on aarch64, this prevented LDP from merging two + * loads together for free. Putting the loads together before the stores + * properly generates LDP. + */ + xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64; + xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64; + XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo); + XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi); + } } +} + + +typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*); +typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*); +typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); + + +#if (XXH_VECTOR == XXH_AVX512) + +#define XXH3_accumulate_512 XXH3_accumulate_512_avx512 +#define XXH3_scrambleAcc XXH3_scrambleAcc_avx512 +#define XXH3_initCustomSecret XXH3_initCustomSecret_avx512 + +#elif (XXH_VECTOR == XXH_AVX2) + +#define XXH3_accumulate_512 XXH3_accumulate_512_avx2 +#define XXH3_scrambleAcc XXH3_scrambleAcc_avx2 +#define XXH3_initCustomSecret XXH3_initCustomSecret_avx2 + +#elif (XXH_VECTOR == XXH_SSE2) + +#define XXH3_accumulate_512 XXH3_accumulate_512_sse2 +#define XXH3_scrambleAcc XXH3_scrambleAcc_sse2 +#define XXH3_initCustomSecret XXH3_initCustomSecret_sse2 + +#elif (XXH_VECTOR == XXH_NEON) + +#define XXH3_accumulate_512 XXH3_accumulate_512_neon +#define XXH3_scrambleAcc XXH3_scrambleAcc_neon +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#elif (XXH_VECTOR == XXH_VSX) + +#define XXH3_accumulate_512 XXH3_accumulate_512_vsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_vsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#else /* scalar */ + +#define XXH3_accumulate_512 XXH3_accumulate_512_scalar +#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#endif + + + +#ifndef XXH_PREFETCH_DIST +# ifdef __clang__ +# define XXH_PREFETCH_DIST 320 +# else +# if (XXH_VECTOR == XXH_AVX512) +# define XXH_PREFETCH_DIST 512 +# else +# define XXH_PREFETCH_DIST 384 +# endif +# endif /* __clang__ */ +#endif /* XXH_PREFETCH_DIST */ + +/* + * XXH3_accumulate() + * Loops over XXH3_accumulate_512(). + * Assumption: nbStripes will not overflow the secret size + */ +XXH_FORCE_INLINE void +XXH3_accumulate( xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, + size_t nbStripes, + XXH3_f_accumulate_512 f_acc512) +{ + size_t n; + for (n = 0; n < nbStripes; n++ ) { + const xxh_u8* const in = input + n*XXH_STRIPE_LEN; + XXH_PREFETCH(in + XXH_PREFETCH_DIST); + f_acc512(acc, + in, + secret + n*XXH_SECRET_CONSUME_RATE); + } +} + +XXH_FORCE_INLINE void +XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; + size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock; + size_t const nb_blocks = (len - 1) / block_len; + + size_t n; + + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); + + for (n = 0; n < nb_blocks; n++) { + XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512); + f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN); + } + + /* last partial block */ + XXH_ASSERT(len > XXH_STRIPE_LEN); + { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN; + XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE)); + XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512); + + /* last stripe */ + { const xxh_u8* const p = input + len - XXH_STRIPE_LEN; +#define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */ + f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); + } } +} + +XXH_FORCE_INLINE xxh_u64 +XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret) +{ + return XXH3_mul128_fold64( + acc[0] ^ XXH_readLE64(secret), + acc[1] ^ XXH_readLE64(secret+8) ); +} + +static XXH64_hash_t +XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) +{ + xxh_u64 result64 = start; + size_t i = 0; + + for (i = 0; i < 4; i++) { + result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i); +#if defined(__clang__) /* Clang */ \ + && (defined(__arm__) || defined(__thumb__)) /* ARMv7 */ \ + && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ + /* + * UGLY HACK: + * Prevent autovectorization on Clang ARMv7-a. Exact same problem as + * the one in XXH3_len_129to240_64b. Speeds up shorter keys > 240b. + * XXH3_64bits, len == 256, Snapdragon 835: + * without hack: 2063.7 MB/s + * with hack: 2560.7 MB/s + */ + __asm__("" : "+r" (result64)); +#endif + } + + return XXH3_avalanche(result64); +} + +#define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ + XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, + const void* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; + + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble); + + /* converge into final hash */ + XXH_STATIC_ASSERT(sizeof(acc) == 64); + /* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; + return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + * Since the function is not inlined, the compiler may not be able to understand that, + * in some scenarios, its `secret` argument is actually a compile time constant. + * This variant enforces that the compiler can detect that, + * and uses this opportunity to streamline the generated code for better performance. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; (void)secret; (void)secretLen; + return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * XXH3_hashLong_64b_withSeed(): + * Generate a custom key based on alteration of default XXH3_kSecret with the seed, + * and then use this key for long mode hashing. + * + * This operation is decently fast but nonetheless costs a little bit of time. + * Try to avoid it whenever possible (typically when seed==0). + * + * It's important for performance that XXH3_hashLong is not inlined. Not sure + * why (uop cache maybe?), but the difference is large and easily measurable. + */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len, + XXH64_hash_t seed, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble, + XXH3_f_initCustomSecret f_initSec) +{ + if (seed == 0) + return XXH3_hashLong_64b_internal(input, len, + XXH3_kSecret, sizeof(XXH3_kSecret), + f_acc512, f_scramble); + { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; + f_initSec(secret, seed); + return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret), + f_acc512, f_scramble); + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSeed(const void* input, size_t len, + XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen) +{ + (void)secret; (void)secretLen; + return XXH3_hashLong_64b_withSeed_internal(input, len, seed, + XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); +} + + +typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t, + XXH64_hash_t, const xxh_u8* XXH_RESTRICT, size_t); + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen, + XXH3_hashLong64_f f_hashLong) +{ + XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN); + /* + * If an action is to be taken if `secretLen` condition is not respected, + * it should be done here. + * For now, it's a contract pre-condition. + * Adding a check and a branch here would cost performance at every hash. + * Also, note that function signature doesn't offer room to return an error. + */ + if (len <= 16) + return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64); + if (len <= 128) + return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + return f_hashLong(input, len, seed64, (const xxh_u8*)secret, secretLen); +} + + +/* === Public entry point === */ + +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len) +{ + return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default); +} + +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +{ + return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret); +} + +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed); +} + + +/* === XXH3 streaming === */ + +/* + * Malloc's a pointer that is always aligned to align. + * + * This must be freed with `XXH_alignedFree()`. + * + * malloc typically guarantees 16 byte alignment on 64-bit systems and 8 byte + * alignment on 32-bit. This isn't enough for the 32 byte aligned loads in AVX2 + * or on 32-bit, the 16 byte aligned loads in SSE2 and NEON. + * + * This underalignment previously caused a rather obvious crash which went + * completely unnoticed due to XXH3_createState() not actually being tested. + * Credit to RedSpah for noticing this bug. + * + * The alignment is done manually: Functions like posix_memalign or _mm_malloc + * are avoided: To maintain portability, we would have to write a fallback + * like this anyways, and besides, testing for the existence of library + * functions without relying on external build tools is impossible. + * + * The method is simple: Overallocate, manually align, and store the offset + * to the original behind the returned pointer. + * + * Align must be a power of 2 and 8 <= align <= 128. + */ +static void* XXH_alignedMalloc(size_t s, size_t align) +{ + XXH_ASSERT(align <= 128 && align >= 8); /* range check */ + XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */ + XXH_ASSERT(s != 0 && s < (s + align)); /* empty/overflow */ + { /* Overallocate to make room for manual realignment and an offset byte */ + xxh_u8* base = (xxh_u8*)XXH_malloc(s + align); + if (base != NULL) { + /* + * Get the offset needed to align this pointer. + * + * Even if the returned pointer is aligned, there will always be + * at least one byte to store the offset to the original pointer. + */ + size_t offset = align - ((size_t)base & (align - 1)); /* base % align */ + /* Add the offset for the now-aligned pointer */ + xxh_u8* ptr = base + offset; + + XXH_ASSERT((size_t)ptr % align == 0); + + /* Store the offset immediately before the returned pointer. */ + ptr[-1] = (xxh_u8)offset; + return ptr; + } + return NULL; + } +} +/* + * Frees an aligned pointer allocated by XXH_alignedMalloc(). Don't pass + * normal malloc'd pointers, XXH_alignedMalloc has a specific data layout. + */ +static void XXH_alignedFree(void* p) +{ + if (p != NULL) { + xxh_u8* ptr = (xxh_u8*)p; + /* Get the offset byte we added in XXH_malloc. */ + xxh_u8 offset = ptr[-1]; + /* Free the original malloc'd pointer */ + xxh_u8* base = ptr - offset; + XXH_free(base); + } +} +XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) +{ + XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64); + if (state==NULL) return NULL; + XXH3_INITSTATE(state); + return state; +} + +XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) +{ + XXH_alignedFree(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API void +XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state) +{ + memcpy(dst_state, src_state, sizeof(*dst_state)); +} + +static void +XXH3_64bits_reset_internal(XXH3_state_t* statePtr, + XXH64_hash_t seed, + const void* secret, size_t secretSize) +{ + size_t const initStart = offsetof(XXH3_state_t, bufferedSize); + size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart; + XXH_ASSERT(offsetof(XXH3_state_t, nbStripesPerBlock) > initStart); + XXH_ASSERT(statePtr != NULL); + /* set members from bufferedSize to nbStripesPerBlock (excluded) to 0 */ + memset((char*)statePtr + initStart, 0, initLength); + statePtr->acc[0] = XXH_PRIME32_3; + statePtr->acc[1] = XXH_PRIME64_1; + statePtr->acc[2] = XXH_PRIME64_2; + statePtr->acc[3] = XXH_PRIME64_3; + statePtr->acc[4] = XXH_PRIME64_4; + statePtr->acc[5] = XXH_PRIME32_2; + statePtr->acc[6] = XXH_PRIME64_5; + statePtr->acc[7] = XXH_PRIME32_1; + statePtr->seed = seed; + statePtr->extSecret = (const unsigned char*)secret; + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); + statePtr->secretLimit = secretSize - XXH_STRIPE_LEN; + statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset(XXH3_state_t* statePtr) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_64bits_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_64bits_reset_internal(statePtr, 0, secret, secretSize); + if (secret == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +{ + if (statePtr == NULL) return XXH_ERROR; + if (seed==0) return XXH3_64bits_reset(statePtr); + if (seed != statePtr->seed) XXH3_initCustomSecret(statePtr->customSecret, seed); + XXH3_64bits_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +/* Note : when XXH3_consumeStripes() is invoked, + * there must be a guarantee that at least one more byte must be consumed from input + * so that the function can blindly consume all stripes using the "normal" secret segment */ +XXH_FORCE_INLINE void +XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc, + size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock, + const xxh_u8* XXH_RESTRICT input, size_t nbStripes, + const xxh_u8* XXH_RESTRICT secret, size_t secretLimit, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */ + XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock); + if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) { + /* need a scrambling operation */ + size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr; + size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock; + XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512); + f_scramble(acc, secret + secretLimit); + XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512); + *nbStripesSoFarPtr = nbStripesAfterBlock; + } else { + XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512); + *nbStripesSoFarPtr += nbStripes; + } +} + +/* + * Both XXH3_64bits_update and XXH3_128bits_update use this routine. + */ +XXH_FORCE_INLINE XXH_errorcode +XXH3_update(XXH3_state_t* state, + const xxh_u8* input, size_t len, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + if (input==NULL) +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + return XXH_OK; +#else + return XXH_ERROR; +#endif + + { const xxh_u8* const bEnd = input + len; + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + + state->totalLen += len; + + if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } + /* total input is now > XXH3_INTERNALBUFFER_SIZE */ + + #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN) + XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */ + + /* + * Internal buffer is partially filled (always, except at beginning) + * Complete it, then consume it. + */ + if (state->bufferedSize) { + size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize; + XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize); + input += loadSize; + XXH3_consumeStripes(state->acc, + &state->nbStripesSoFar, state->nbStripesPerBlock, + state->buffer, XXH3_INTERNALBUFFER_STRIPES, + secret, state->secretLimit, + f_acc512, f_scramble); + state->bufferedSize = 0; + } + XXH_ASSERT(input < bEnd); + + /* Consume input by a multiple of internal buffer size */ + if (input+XXH3_INTERNALBUFFER_SIZE < bEnd) { + const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE; + do { + XXH3_consumeStripes(state->acc, + &state->nbStripesSoFar, state->nbStripesPerBlock, + input, XXH3_INTERNALBUFFER_STRIPES, + secret, state->secretLimit, + f_acc512, f_scramble); + input += XXH3_INTERNALBUFFER_SIZE; + } while (inputbuffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); + } + XXH_ASSERT(input < bEnd); + + /* Some remaining input (always) : buffer it */ + XXH_memcpy(state->buffer, input, (size_t)(bEnd-input)); + state->bufferedSize = (XXH32_hash_t)(bEnd-input); + } + + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len) +{ + return XXH3_update(state, (const xxh_u8*)input, len, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + + +XXH_FORCE_INLINE void +XXH3_digest_long (XXH64_hash_t* acc, + const XXH3_state_t* state, + const unsigned char* secret) +{ + /* + * Digest on a local copy. This way, the state remains unaltered, and it can + * continue ingesting more input afterwards. + */ + memcpy(acc, state->acc, sizeof(state->acc)); + if (state->bufferedSize >= XXH_STRIPE_LEN) { + size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN; + size_t nbStripesSoFar = state->nbStripesSoFar; + XXH3_consumeStripes(acc, + &nbStripesSoFar, state->nbStripesPerBlock, + state->buffer, nbStripes, + secret, state->secretLimit, + XXH3_accumulate_512, XXH3_scrambleAcc); + /* last stripe */ + XXH3_accumulate_512(acc, + state->buffer + state->bufferedSize - XXH_STRIPE_LEN, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); + } else { /* bufferedSize < XXH_STRIPE_LEN */ + xxh_u8 lastStripe[XXH_STRIPE_LEN]; + size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize; + XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */ + memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize); + memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize); + XXH3_accumulate_512(acc, + lastStripe, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); + } +} + +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) +{ + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + if (state->totalLen > XXH3_MIDSIZE_MAX) { + XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; + XXH3_digest_long(acc, state, secret); + return XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)state->totalLen * XXH_PRIME64_1); + } + /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ + if (state->seed) + return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); + return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), + secret, state->secretLimit + XXH_STRIPE_LEN); +} + + +#define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x)) + +XXH_PUBLIC_API void +XXH3_generateSecret(void* secretBuffer, const void* customSeed, size_t customSeedSize) +{ + XXH_ASSERT(secretBuffer != NULL); + if (customSeedSize == 0) { + memcpy(secretBuffer, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); + return; + } + XXH_ASSERT(customSeed != NULL); + + { size_t const segmentSize = sizeof(XXH128_hash_t); + size_t const nbSegments = XXH_SECRET_DEFAULT_SIZE / segmentSize; + XXH128_canonical_t scrambler; + XXH64_hash_t seeds[12]; + size_t segnb; + XXH_ASSERT(nbSegments == 12); + XXH_ASSERT(segmentSize * nbSegments == XXH_SECRET_DEFAULT_SIZE); /* exact multiple */ + XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0)); + + /* + * Copy customSeed to seeds[], truncating or repeating as necessary. + */ + { size_t toFill = XXH_MIN(customSeedSize, sizeof(seeds)); + size_t filled = toFill; + memcpy(seeds, customSeed, toFill); + while (filled < sizeof(seeds)) { + toFill = XXH_MIN(filled, sizeof(seeds) - filled); + memcpy((char*)seeds + filled, seeds, toFill); + filled += toFill; + } } + + /* generate secret */ + memcpy(secretBuffer, &scrambler, sizeof(scrambler)); + for (segnb=1; segnb < nbSegments; segnb++) { + size_t const segmentStart = segnb * segmentSize; + XXH128_canonical_t segment; + XXH128_canonicalFromHash(&segment, + XXH128(&scrambler, sizeof(scrambler), XXH_readLE64(seeds + segnb) + segnb) ); + memcpy((char*)secretBuffer + segmentStart, &segment, sizeof(segment)); + } } +} + + +/* ========================================== + * XXH3 128 bits (a.k.a XXH128) + * ========================================== + * XXH3's 128-bit variant has better mixing and strength than the 64-bit variant, + * even without counting the significantly larger output size. + * + * For example, extra steps are taken to avoid the seed-dependent collisions + * in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B). + * + * This strength naturally comes at the cost of some speed, especially on short + * lengths. Note that longer hashes are about as fast as the 64-bit version + * due to it using only a slight modification of the 64-bit loop. + * + * XXH128 is also more oriented towards 64-bit machines. It is still extremely + * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64). + */ + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + /* A doubled version of 1to3_64b with different constants. */ + XXH_ASSERT(input != NULL); + XXH_ASSERT(1 <= len && len <= 3); + XXH_ASSERT(secret != NULL); + /* + * len = 1: combinedl = { input[0], 0x01, input[0], input[0] } + * len = 2: combinedl = { input[1], 0x02, input[0], input[1] } + * len = 3: combinedl = { input[2], 0x03, input[0], input[1] } + */ + { xxh_u8 const c1 = input[0]; + xxh_u8 const c2 = input[len >> 1]; + xxh_u8 const c3 = input[len - 1]; + xxh_u32 const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24) + | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8); + xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13); + xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; + xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed; + xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl; + xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph; + XXH128_hash_t h128; + h128.low64 = XXH64_avalanche(keyed_lo); + h128.high64 = XXH64_avalanche(keyed_hi); + return h128; + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(4 <= len && len <= 8); + seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; + { xxh_u32 const input_lo = XXH_readLE32(input); + xxh_u32 const input_hi = XXH_readLE32(input + len - 4); + xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32); + xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed; + xxh_u64 const keyed = input_64 ^ bitflip; + + /* Shift len to the left to ensure it is even, this avoids even multiplies. */ + XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2)); + + m128.high64 += (m128.low64 << 1); + m128.low64 ^= (m128.high64 >> 3); + + m128.low64 = XXH_xorshift64(m128.low64, 35); + m128.low64 *= 0x9FB21C651E98DF25ULL; + m128.low64 = XXH_xorshift64(m128.low64, 28); + m128.high64 = XXH3_avalanche(m128.high64); + return m128; + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(9 <= len && len <= 16); + { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed; + xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed; + xxh_u64 const input_lo = XXH_readLE64(input); + xxh_u64 input_hi = XXH_readLE64(input + len - 8); + XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1); + /* + * Put len in the middle of m128 to ensure that the length gets mixed to + * both the low and high bits in the 128x64 multiply below. + */ + m128.low64 += (xxh_u64)(len - 1) << 54; + input_hi ^= bitfliph; + /* + * Add the high 32 bits of input_hi to the high 32 bits of m128, then + * add the long product of the low 32 bits of input_hi and XXH_PRIME32_2 to + * the high 64 bits of m128. + * + * The best approach to this operation is different on 32-bit and 64-bit. + */ + if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */ + /* + * 32-bit optimized version, which is more readable. + * + * On 32-bit, it removes an ADC and delays a dependency between the two + * halves of m128.high64, but it generates an extra mask on 64-bit. + */ + m128.high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2); + } else { + /* + * 64-bit optimized (albeit more confusing) version. + * + * Uses some properties of addition and multiplication to remove the mask: + * + * Let: + * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF) + * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000) + * c = XXH_PRIME32_2 + * + * a + (b * c) + * Inverse Property: x + y - x == y + * a + (b * (1 + c - 1)) + * Distributive Property: x * (y + z) == (x * y) + (x * z) + * a + (b * 1) + (b * (c - 1)) + * Identity Property: x * 1 == x + * a + b + (b * (c - 1)) + * + * Substitute a, b, and c: + * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1)) + * + * Since input_hi.hi + input_hi.lo == input_hi, we get this: + * input_hi + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1)) + */ + m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1); + } + /* m128 ^= XXH_swap64(m128 >> 64); */ + m128.low64 ^= XXH_swap64(m128.high64); + + { /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */ + XXH128_hash_t h128 = XXH_mult64to128(m128.low64, XXH_PRIME64_2); + h128.high64 += m128.high64 * XXH_PRIME64_2; + + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = XXH3_avalanche(h128.high64); + return h128; + } } +} + +/* + * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN + */ +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(len <= 16); + { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed); + if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed); + if (len) return XXH3_len_1to3_128b(input, len, secret, seed); + { XXH128_hash_t h128; + xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72); + xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88); + h128.low64 = XXH64_avalanche(seed ^ bitflipl); + h128.high64 = XXH64_avalanche( seed ^ bitfliph); + return h128; + } } +} + +/* + * A bit slower than XXH3_mix16B, but handles multiply by zero better. + */ +XXH_FORCE_INLINE XXH128_hash_t +XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2, + const xxh_u8* secret, XXH64_hash_t seed) +{ + acc.low64 += XXH3_mix16B (input_1, secret+0, seed); + acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8); + acc.high64 += XXH3_mix16B (input_2, secret+16, seed); + acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8); + return acc; +} + + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(16 < len && len <= 128); + + { XXH128_hash_t acc; + acc.low64 = len * XXH_PRIME64_1; + acc.high64 = 0; + if (len > 32) { + if (len > 64) { + if (len > 96) { + acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed); + } + acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed); + } + acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed); + } + acc = XXH128_mix32B(acc, input, input+len-16, secret, seed); + { XXH128_hash_t h128; + h128.low64 = acc.low64 + acc.high64; + h128.high64 = (acc.low64 * XXH_PRIME64_1) + + (acc.high64 * XXH_PRIME64_4) + + ((len - seed) * XXH_PRIME64_2); + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64); + return h128; + } + } +} + +XXH_NO_INLINE XXH128_hash_t +XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + + { XXH128_hash_t acc; + int const nbRounds = (int)len / 32; + int i; + acc.low64 = len * XXH_PRIME64_1; + acc.high64 = 0; + for (i=0; i<4; i++) { + acc = XXH128_mix32B(acc, + input + (32 * i), + input + (32 * i) + 16, + secret + (32 * i), + seed); + } + acc.low64 = XXH3_avalanche(acc.low64); + acc.high64 = XXH3_avalanche(acc.high64); + XXH_ASSERT(nbRounds >= 4); + for (i=4 ; i < nbRounds; i++) { + acc = XXH128_mix32B(acc, + input + (32 * i), + input + (32 * i) + 16, + secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)), + seed); + } + /* last bytes */ + acc = XXH128_mix32B(acc, + input + len - 16, + input + len - 32, + secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16, + 0ULL - seed); + + { XXH128_hash_t h128; + h128.low64 = acc.low64 + acc.high64; + h128.high64 = (acc.low64 * XXH_PRIME64_1) + + (acc.high64 * XXH_PRIME64_4) + + ((len - seed) * XXH_PRIME64_2); + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64); + return h128; + } + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; + + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble); + + /* converge into final hash */ + XXH_STATIC_ASSERT(sizeof(acc) == 64); + XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + { XXH128_hash_t h128; + h128.low64 = XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)len * XXH_PRIME64_1); + h128.high64 = XXH3_mergeAccs(acc, + secret + secretSize + - sizeof(acc) - XXH_SECRET_MERGEACCS_START, + ~((xxh_u64)len * XXH_PRIME64_2)); + return h128; + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; (void)secret; (void)secretLen; + return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; + return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble, + XXH3_f_initCustomSecret f_initSec) +{ + if (seed64 == 0) + return XXH3_hashLong_128b_internal(input, len, + XXH3_kSecret, sizeof(XXH3_kSecret), + f_acc512, f_scramble); + { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; + f_initSec(secret, seed64); + return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret), + f_acc512, f_scramble); + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSeed(const void* input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)secret; (void)secretLen; + return XXH3_hashLong_128b_withSeed_internal(input, len, seed64, + XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); +} + +typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t, + XXH64_hash_t, const void* XXH_RESTRICT, size_t); + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_128bits_internal(const void* input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen, + XXH3_hashLong128_f f_hl128) +{ + XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN); + /* + * If an action is to be taken if `secret` conditions are not respected, + * it should be done here. + * For now, it's a contract pre-condition. + * Adding a check and a branch here would cost performance at every hash. + */ + if (len <= 16) + return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64); + if (len <= 128) + return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + return f_hl128(input, len, seed64, secret, secretLen); +} + + +/* === Public XXH128 API === */ + +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len) +{ + return XXH3_128bits_internal(input, len, 0, + XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_hashLong_128b_default); +} + +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +{ + return XXH3_128bits_internal(input, len, 0, + (const xxh_u8*)secret, secretSize, + XXH3_hashLong_128b_withSecret); +} + +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_128bits_internal(input, len, seed, + XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_hashLong_128b_withSeed); +} + +XXH_PUBLIC_API XXH128_hash_t +XXH128(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_128bits_withSeed(input, len, seed); +} + + +/* === XXH3 128-bit streaming === */ + +/* + * All the functions are actually the same as for 64-bit streaming variant. + * The only difference is the finalizatiom routine. + */ + +static void +XXH3_128bits_reset_internal(XXH3_state_t* statePtr, + XXH64_hash_t seed, + const void* secret, size_t secretSize) +{ + XXH3_64bits_reset_internal(statePtr, seed, secret, secretSize); +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset(XXH3_state_t* statePtr) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_128bits_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_128bits_reset_internal(statePtr, 0, secret, secretSize); + if (secret == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +{ + if (statePtr == NULL) return XXH_ERROR; + if (seed==0) return XXH3_128bits_reset(statePtr); + if (seed != statePtr->seed) XXH3_initCustomSecret(statePtr->customSecret, seed); + XXH3_128bits_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len) +{ + return XXH3_update(state, (const xxh_u8*)input, len, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state) +{ + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + if (state->totalLen > XXH3_MIDSIZE_MAX) { + XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; + XXH3_digest_long(acc, state, secret); + XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + { XXH128_hash_t h128; + h128.low64 = XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)state->totalLen * XXH_PRIME64_1); + h128.high64 = XXH3_mergeAccs(acc, + secret + state->secretLimit + XXH_STRIPE_LEN + - sizeof(acc) - XXH_SECRET_MERGEACCS_START, + ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); + return h128; + } + } + /* len <= XXH3_MIDSIZE_MAX : short code */ + if (state->seed) + return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); + return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), + secret, state->secretLimit + XXH_STRIPE_LEN); +} + +/* 128-bit utility functions */ + +#include /* memcmp, memcpy */ + +/* return : 1 is equal, 0 if different */ +XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) +{ + /* note : XXH128_hash_t is compact, it has no padding byte */ + return !(memcmp(&h1, &h2, sizeof(h1))); +} + +/* This prototype is compatible with stdlib's qsort(). + * return : >0 if *h128_1 > *h128_2 + * <0 if *h128_1 < *h128_2 + * =0 if *h128_1 == *h128_2 */ +XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2) +{ + XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1; + XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2; + int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64); + /* note : bets that, in most cases, hash values are different */ + if (hcmp) return hcmp; + return (h1.low64 > h2.low64) - (h2.low64 > h1.low64); +} + + +/*====== Canonical representation ======*/ +XXH_PUBLIC_API void +XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) { + hash.high64 = XXH_swap64(hash.high64); + hash.low64 = XXH_swap64(hash.low64); + } + memcpy(dst, &hash.high64, sizeof(hash.high64)); + memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64)); +} + +XXH_PUBLIC_API XXH128_hash_t +XXH128_hashFromCanonical(const XXH128_canonical_t* src) +{ + XXH128_hash_t h; + h.high64 = XXH_readBE64(src); + h.low64 = XXH_readBE64(src->digest + 8); + return h; +} + +/* Pop our optimization override from above */ +#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ + && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ +# pragma GCC pop_options +#endif + +#endif /* XXH_NO_LONG_LONG */ + + +#endif /* XXH_IMPLEMENTATION */ #if defined (__cplusplus) From 3b0f7e109dacaccf46d0ad05f2122fd995a53722 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 27 Aug 2020 20:01:37 -0700 Subject: [PATCH 580/848] unittest: Fix build on Android. --- unittest/UnitTest.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index b8af6ae8bb..25ad953392 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -24,12 +24,14 @@ // TODO: Make a test of nice unittest asserts and count successes etc. // Or just integrate with an existing testing framework. - #include #include #include #include #include +#if defined(ANDROID) +#include +#endif #include "base/NativeApp.h" #include "input/input_state.h" @@ -62,6 +64,16 @@ bool System_GetPropertyBool(SystemProperty prop) { return false; } +#if defined(ANDROID) +JNIEnv *getEnv() { + return nullptr; +} + +jclass findClass(const char *name) { + return nullptr; +} +#endif + #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923 #endif From 184d4a1fc03fb8a7ed70689cb47f1129aa676ea6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 27 Aug 2020 20:01:59 -0700 Subject: [PATCH 581/848] Vulkan: Type comparison warning fix. --- ext/native/thin3d/VulkanQueueRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 91767c164d..a5beef1613 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -589,7 +589,7 @@ void VulkanQueueRunner::ApplyMGSHack(std::vector &steps) { VKRFramebuffer *depalFramebuffer = steps[i]->render.framebuffer; VKRFramebuffer *targetFramebuffer = steps[i + 1]->render.framebuffer; // OK, found the start of a post-process sequence. Let's scan until we find the end. - for (int j = i; j < steps.size() - 3; j++) { + for (int j = i; j < (int)steps.size() - 3; j++) { if (((j - i) & 1) == 0) { // This should be a depal draw. if (steps[j]->render.numDraws != 1) From 30625225b0ea1a79f8efdbc485ed18731a3d7140 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 27 Aug 2020 20:31:09 -0700 Subject: [PATCH 582/848] GPU: Remove neon xxhash implementation. It's typically around the same speed now with modern compilers, and much slower than XXH3. --- Core/TextureReplacer.h | 1 - GPU/Common/TextureDecoder.cpp | 6 -- GPU/Common/TextureDecoder.h | 12 ++-- GPU/Common/TextureDecoderNEON.cpp | 101 ------------------------------ GPU/Common/TextureDecoderNEON.h | 1 - 5 files changed, 5 insertions(+), 116 deletions(-) diff --git a/Core/TextureReplacer.h b/Core/TextureReplacer.h index a79d7b6c31..d90f373c4e 100644 --- a/Core/TextureReplacer.h +++ b/Core/TextureReplacer.h @@ -48,7 +48,6 @@ enum class ReplacedTextureAlpha { // For forward comatibility, we specify the hash. enum class ReplacedTextureHash { - // TODO: Maybe only support crc32c for now? QUICK, XXH32, XXH64, diff --git a/GPU/Common/TextureDecoder.cpp b/GPU/Common/TextureDecoder.cpp index 0aca26ec84..f02094bfcd 100644 --- a/GPU/Common/TextureDecoder.cpp +++ b/GPU/Common/TextureDecoder.cpp @@ -311,8 +311,6 @@ void DoUnswizzleTex16Basic(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 QuickTexHashFunc DoQuickTexHash = &QuickTexHashBasic; QuickTexHashFunc StableQuickTexHash = &QuickTexHashNonSSE; UnswizzleTex16Func DoUnswizzleTex16 = &DoUnswizzleTex16Basic; -ReliableHash32Func DoReliableHash32 = &XXH32; -ReliableHash64Func DoReliableHash64 = &XXH64; #endif // This has to be done after CPUDetect has done its magic. @@ -322,10 +320,6 @@ void SetupTextureDecoder() { DoQuickTexHash = &QuickTexHashNEON; StableQuickTexHash = &QuickTexHashNEON; DoUnswizzleTex16 = &DoUnswizzleTex16NEON; -#if !PPSSPP_PLATFORM(IOS) - // Not sure if this is safe on iOS, it's had issues with xxhash. - DoReliableHash32 = &ReliableHash32NEON; -#endif } #endif } diff --git a/GPU/Common/TextureDecoder.h b/GPU/Common/TextureDecoder.h index 35ffa8400f..dd01b65bce 100644 --- a/GPU/Common/TextureDecoder.h +++ b/GPU/Common/TextureDecoder.h @@ -62,9 +62,9 @@ typedef u32 ReliableHashType; #define DoQuickTexHash QuickTexHashNEON #define StableQuickTexHash QuickTexHashNEON #define DoUnswizzleTex16 DoUnswizzleTex16NEON -#define DoReliableHash32 ReliableHash32NEON #include "ext/xxhash.h" +#define DoReliableHash32 XXH32 #define DoReliableHash64 XXH64 #define DoReliableHash XXH64 @@ -78,13 +78,11 @@ extern QuickTexHashFunc StableQuickTexHash; typedef void (*UnswizzleTex16Func)(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 pitch); extern UnswizzleTex16Func DoUnswizzleTex16; -typedef u32 (*ReliableHash32Func)(const void *input, size_t len, u32 seed); -extern ReliableHash32Func DoReliableHash32; +#include "ext/xxhash.h" +#define DoReliableHash32 XXH32 +#define DoReliableHash64 XXH64 -typedef u64 (*ReliableHash64Func)(const void *input, size_t len, u64 seed); -extern ReliableHash64Func DoReliableHash64; - -#define DoReliableHash DoReliableHash32 +#define DoReliableHash XXH32 typedef u32 ReliableHashType; #endif diff --git a/GPU/Common/TextureDecoderNEON.cpp b/GPU/Common/TextureDecoderNEON.cpp index af56567a45..36f40b3b76 100644 --- a/GPU/Common/TextureDecoderNEON.cpp +++ b/GPU/Common/TextureDecoderNEON.cpp @@ -162,107 +162,6 @@ void DoUnswizzleTex16NEON(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 p } } -// NOTE: This is just a NEON version of xxhash. -// GCC sucks at making things NEON and can't seem to handle it. - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; -#else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; - typedef signed int S32; - typedef unsigned long long U64; -#endif - -#define PRIME32_1 2654435761U -#define PRIME32_2 2246822519U -#define PRIME32_3 3266489917U -#define PRIME32_4 668265263U -#define PRIME32_5 374761393U - -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -#else -# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) -#endif - -u32 ReliableHash32NEON(const void *input, size_t len, u32 seed) { - if (((uintptr_t)input & 3) != 0) { - // Cannot handle misaligned data. Fall back to XXH32. - return XXH32(input, len, seed); - } - - const u8 *p = (const u8 *)input; - const u8 *const bEnd = p + len; - U32 h32; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) { len=0; p=(const BYTE*)(size_t)16; } -#endif - - if (len>=16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - uint32x4_t prime32_1q = vdupq_n_u32(PRIME32_1); - uint32x4_t prime32_2q = vdupq_n_u32(PRIME32_2); - uint32x4_t vq = vcombine_u32(vcreate_u32(v1 | ((U64)v2 << 32)), vcreate_u32(v3 | ((U64)v4 << 32))); - - do { - __builtin_prefetch(p + 0xc0, 0, 0); - vq = vmlaq_u32(vq, vld1q_u32((const U32*)p), prime32_2q); - vq = vorrq_u32(vshlq_n_u32(vq, 13), vshrq_n_u32(vq, 32 - 13)); - p += 16; - vq = vmulq_u32(vq, prime32_1q); - } while (p<=limit); - - v1 = vgetq_lane_u32(vq, 0); - v2 = vgetq_lane_u32(vq, 1); - v3 = vgetq_lane_u32(vq, 2); - v4 = vgetq_lane_u32(vq, 3); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } - else - { - h32 = seed + PRIME32_5; - } - - h32 += (U32) len; - - while (p<=bEnd-4) - { - h32 += *(const U32*)p * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - static inline bool VectorIsNonZeroNEON(const uint32x4_t &v) { u64 low = vgetq_lane_u64(vreinterpretq_u64_u32(v), 0); u64 high = vgetq_lane_u64(vreinterpretq_u64_u32(v), 1); diff --git a/GPU/Common/TextureDecoderNEON.h b/GPU/Common/TextureDecoderNEON.h index 02c3a8ec70..6d3b5cf45a 100644 --- a/GPU/Common/TextureDecoderNEON.h +++ b/GPU/Common/TextureDecoderNEON.h @@ -19,7 +19,6 @@ u32 QuickTexHashNEON(const void *checkp, u32 size); void DoUnswizzleTex16NEON(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 pitch); -u32 ReliableHash32NEON(const void *input, size_t len, u32 seed); CheckAlphaResult CheckAlphaRGBA8888NEON(const u32 *pixelData, int stride, int w, int h); CheckAlphaResult CheckAlphaABGR4444NEON(const u32 *pixelData, int stride, int w, int h); From 15c25be42bd8c7526487a10a9f400f19cf17fadd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 27 Aug 2020 20:37:49 -0700 Subject: [PATCH 583/848] GPU: Switch vertex/lookup hashes to XXH3. This is faster pretty much everywhere. --- Common/Hashmaps.h | 5 +---- GPU/Common/DrawEngineCommon.cpp | 17 ++++++++--------- GPU/Common/DrawEngineCommon.h | 9 +-------- GPU/D3D11/DrawEngineD3D11.cpp | 4 ++-- GPU/D3D11/DrawEngineD3D11.h | 2 +- GPU/Directx9/DrawEngineDX9.cpp | 4 ++-- GPU/Directx9/DrawEngineDX9.h | 2 +- GPU/GLES/DrawEngineGLES.cpp | 4 ++-- GPU/GLES/DrawEngineGLES.h | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 5 ++--- GPU/Vulkan/DrawEngineVulkan.h | 9 +-------- 11 files changed, 22 insertions(+), 41 deletions(-) diff --git a/Common/Hashmaps.h b/Common/Hashmaps.h index 04d88067bd..4c6664277c 100644 --- a/Common/Hashmaps.h +++ b/Common/Hashmaps.h @@ -8,14 +8,11 @@ #include "Common/CommonFuncs.h" #include "Common/Log.h" -// Whatever random value. -const uint32_t hashmapSeed = 0x23B58532; - // TODO: Try hardware CRC. Unfortunately not available on older Intels or ARM32. // Seems to be ubiquitous on ARM64 though. template inline uint32_t HashKey(const K &k) { - return XXH32(&k, sizeof(k), hashmapSeed); + return XXH3_64bits(&k, sizeof(k)) & 0xFFFFFFFF; } template inline bool KeyEquals(const K &a, const K &b) { diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index bcd8a41e29..8285191699 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -23,7 +23,6 @@ #include "GPU/Common/DrawEngineCommon.h" #include "GPU/Common/SplineCommon.h" #include "GPU/Common/VertexDecoderCommon.h" -#include "GPU/Common/TextureDecoder.h" // for ReliableHash #include "GPU/ge_constants.h" #include "GPU/GPUState.h" @@ -607,7 +606,7 @@ inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) { size_t step = sz / 4; u32 hash = 0; for (size_t i = 0; i < sz; i += step) { - hash += DoReliableHash32(p + i, 100, 0x3A44B9C4); + hash += XXH3_64bits(p + i, 100); } return hash; } else { @@ -642,8 +641,8 @@ u32 DrawEngineCommon::ComputeMiniHash() { return fullhash; } -ReliableHashType DrawEngineCommon::ComputeHash() { - ReliableHashType fullhash = 0; +uint64_t DrawEngineCommon::ComputeHash() { + uint64_t fullhash = 0; const int vertexSize = dec_->GetDecVtxFmt().stride; const int indexSize = IndexSize(dec_->VertexType()); @@ -652,7 +651,7 @@ ReliableHashType DrawEngineCommon::ComputeHash() { for (int i = 0; i < numDrawCalls; i++) { const DeferredDrawCall &dc = drawCalls[i]; if (!dc.inds) { - fullhash += DoReliableHash((const char *)dc.verts, vertexSize * dc.vertexCount, 0x1DE8CAC4); + fullhash += XXH3_64bits((const char *)dc.verts, vertexSize * dc.vertexCount); } else { int indexLowerBound = dc.indexLowerBound, indexUpperBound = dc.indexUpperBound; int j = i + 1; @@ -667,15 +666,15 @@ ReliableHashType DrawEngineCommon::ComputeHash() { } // This could get seriously expensive with sparse indices. Need to combine hashing ranges the same way // we do when drawing. - fullhash += DoReliableHash((const char *)dc.verts + vertexSize * indexLowerBound, - vertexSize * (indexUpperBound - indexLowerBound), 0x029F3EE1); + fullhash += XXH3_64bits((const char *)dc.verts + vertexSize * indexLowerBound, + vertexSize * (indexUpperBound - indexLowerBound)); // Hm, we will miss some indices when combining above, but meh, it should be fine. - fullhash += DoReliableHash((const char *)dc.inds, indexSize * dc.vertexCount, 0x955FD1CA); + fullhash += XXH3_64bits((const char *)dc.inds, indexSize * dc.vertexCount); i = lastMatch; } } - fullhash += DoReliableHash(&drawCalls[0].uvScale, sizeof(drawCalls[0].uvScale) * numDrawCalls, 0x0123e658); + fullhash += XXH3_64bits(&drawCalls[0].uvScale, sizeof(drawCalls[0].uvScale) * numDrawCalls); return fullhash; } diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index 6bc34f10ac..0aa5f36b42 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -36,13 +36,6 @@ enum { DECODED_INDEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 16, }; -// Avoiding the full include of TextureDecoder.h. -#if (defined(_M_SSE) && defined(_M_X64)) || defined(ARM64) -typedef u64 ReliableHashType; -#else -typedef u32 ReliableHashType; -#endif - inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) { // As the decoder depends on the UVGenMode when we use UV prescale, we simply mash it // into the top of the verttype where there are unused bits. @@ -115,7 +108,7 @@ protected: // Utility for vertex caching u32 ComputeMiniHash(); - ReliableHashType ComputeHash(); + uint64_t ComputeHash(); // Vertex decoding void DecodeVertsStep(u8 *dest, int &i, int &decodedVerts); diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 0e5b8444a7..0c08c49ae0 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -371,7 +371,7 @@ void DrawEngineD3D11::DoFlush() { case VertexArrayInfoD3D11::VAI_NEW: { // Haven't seen this one before. - ReliableHashType dataHash = ComputeHash(); + uint64_t dataHash = ComputeHash(); vai->hash = dataHash; vai->minihash = ComputeMiniHash(); vai->status = VertexArrayInfoD3D11::VAI_HASHING; @@ -395,7 +395,7 @@ void DrawEngineD3D11::DoFlush() { if (vai->drawsUntilNextFullHash == 0) { // Let's try to skip a full hash if mini would fail. const u32 newMiniHash = ComputeMiniHash(); - ReliableHashType newHash = vai->hash; + uint64_t newHash = vai->hash; if (newMiniHash == vai->minihash) { newHash = ComputeHash(); } diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index 3511f760f5..88d27c6bc1 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -79,7 +79,7 @@ public: VAI_UNRELIABLE, // never cache }; - ReliableHashType hash; + uint64_t hash; u32 minihash; ID3D11Buffer *vbo; diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 376339c7d4..66f269ff58 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -350,7 +350,7 @@ void DrawEngineDX9::DoFlush() { case VertexArrayInfoDX9::VAI_NEW: { // Haven't seen this one before. - ReliableHashType dataHash = ComputeHash(); + uint64_t dataHash = ComputeHash(); vai->hash = dataHash; vai->minihash = ComputeMiniHash(); vai->status = VertexArrayInfoDX9::VAI_HASHING; @@ -375,7 +375,7 @@ void DrawEngineDX9::DoFlush() { if (vai->drawsUntilNextFullHash == 0) { // Let's try to skip a full hash if mini would fail. const u32 newMiniHash = ComputeMiniHash(); - ReliableHashType newHash = vai->hash; + uint64_t newHash = vai->hash; if (newMiniHash == vai->minihash) { newHash = ComputeHash(); } diff --git a/GPU/Directx9/DrawEngineDX9.h b/GPU/Directx9/DrawEngineDX9.h index 2d01617b40..22cb6a7a4e 100644 --- a/GPU/Directx9/DrawEngineDX9.h +++ b/GPU/Directx9/DrawEngineDX9.h @@ -77,7 +77,7 @@ public: VAI_UNRELIABLE, // never cache }; - ReliableHashType hash; + uint64_t hash; u32 minihash; LPDIRECT3DVERTEXBUFFER9 vbo; diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index b07e819d43..cd8a7910a9 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -365,7 +365,7 @@ void DrawEngineGLES::DoFlush() { case VertexArrayInfo::VAI_NEW: { // Haven't seen this one before. - ReliableHashType dataHash = ComputeHash(); + uint64_t dataHash = ComputeHash(); vai->hash = dataHash; vai->minihash = ComputeMiniHash(); vai->status = VertexArrayInfo::VAI_HASHING; @@ -385,7 +385,7 @@ void DrawEngineGLES::DoFlush() { if (vai->drawsUntilNextFullHash == 0) { // Let's try to skip a full hash if mini would fail. const u32 newMiniHash = ComputeMiniHash(); - ReliableHashType newHash = vai->hash; + uint64_t newHash = vai->hash; if (newMiniHash == vai->minihash) { newHash = ComputeHash(); } diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 70159d7e2e..f484034e11 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -90,7 +90,7 @@ public: VAI_UNRELIABLE, // never cache }; - ReliableHashType hash; + uint64_t hash; u32 minihash; GLRBuffer *vbo; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index db98dcca5c..4a9b9a29fb 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -35,7 +35,6 @@ #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanMemory.h" -#include "GPU/Common/TextureDecoder.h" #include "GPU/Common/SplineCommon.h" #include "GPU/Common/TransformCommon.h" #include "GPU/Common/VertexDecoderCommon.h" @@ -653,7 +652,7 @@ void DrawEngineVulkan::DoFlush() { case VertexArrayInfoVulkan::VAI_NEW: { // Haven't seen this one before. We don't actually upload the vertex data yet. - ReliableHashType dataHash = ComputeHash(); + uint64_t dataHash = ComputeHash(); vai->hash = dataHash; vai->minihash = ComputeMiniHash(); vai->status = VertexArrayInfoVulkan::VAI_HASHING; @@ -678,7 +677,7 @@ void DrawEngineVulkan::DoFlush() { if (vai->drawsUntilNextFullHash == 0) { // Let's try to skip a full hash if mini would fail. const u32 newMiniHash = ComputeMiniHash(); - ReliableHashType newHash = vai->hash; + uint64_t newHash = vai->hash; if (newMiniHash == vai->minihash) { newHash = ComputeHash(); } diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 8ea60dec73..0cb4a5bdcd 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -55,13 +55,6 @@ class PipelineManagerVulkan; class TextureCacheVulkan; class FramebufferManagerVulkan; -// Avoiding the full include of TextureDecoder.h. -#if (defined(_M_SSE) && defined(_M_X64)) || defined(ARM64) -typedef u64 ReliableHashType; -#else -typedef u32 ReliableHashType; -#endif - class VulkanContext; class VulkanPushBuffer; struct VulkanPipeline; @@ -91,7 +84,7 @@ public: VAI_UNRELIABLE, // never cache }; - ReliableHashType hash; + uint64_t hash; u32 minihash; // These will probably always be the same, but whatever. From 53d9c10b22dfda9236e33960c49fb5ab59b86f59 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 27 Aug 2020 20:40:55 -0700 Subject: [PATCH 584/848] irjit: Switch to XXH3. --- Core/Debugger/DisassemblyManager.cpp | 6 +++--- Core/MIPS/IR/IRJit.cpp | 2 +- UI/CwCheatScreen.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Core/Debugger/DisassemblyManager.cpp b/Core/Debugger/DisassemblyManager.cpp index b04c40cc16..d05a0984b6 100644 --- a/Core/Debugger/DisassemblyManager.cpp +++ b/Core/Debugger/DisassemblyManager.cpp @@ -41,12 +41,12 @@ bool isInInterval(u32 start, u32 size, u32 value) } -static u32 computeHash(u32 address, u32 size) +static HashType computeHash(u32 address, u32 size) { #ifdef _M_X64 - return XXH64(Memory::GetPointer(address), size, 0xBACD7814BACD7814LL); + return XXH3_64bits(Memory::GetPointer(address), size); #else - return XXH32(Memory::GetPointer(address), size, 0xBACD7814); + return XXH3_64bits(Memory::GetPointer(address), size) & 0xFFFFFFFF; #endif } diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index ec279776cd..4324d3ba8f 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -481,7 +481,7 @@ u64 IRBlock::CalculateHash() const { buffer[pos++] = instr.encoding; } - return XXH64(&buffer[0], origSize_, 0x9A5C33B8); + return XXH3_64bits(&buffer[0], origSize_); } return 0; diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index dad1ac5861..a5c040d029 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "base/stringutil.h" -#include "ext/cityhash/city.h" +#include "ext/xxhash.h" #include "i18n/i18n.h" #include "ui/ui.h" #include "util/text/utf8.h" @@ -62,7 +62,7 @@ void CwCheatScreen::LoadCheatInfo() { // We won't parse this, just using it to detect changes to the file. std::string str; if (readFileToString(true, engine_->CheatFilename().c_str(), str)) { - fileCheckHash_ = CityHash64(str.c_str(), str.size()); + fileCheckHash_ = XXH3_64bits(str.c_str(), str.size()); } fileCheckCounter_ = 0; @@ -119,7 +119,7 @@ void CwCheatScreen::update() { // Check if the file has changed. If it has, we'll reload. std::string str; if (readFileToString(true, engine_->CheatFilename().c_str(), str)) { - uint64_t newHash = CityHash64(str.c_str(), str.size()); + uint64_t newHash = XXH3_64bits(str.c_str(), str.size()); if (newHash != fileCheckHash_) { // This will update the hash. RecreateViews(); From 7f812a5d9ab00f18af7cfe452168b5a9f7288ca6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 27 Aug 2020 20:46:39 -0700 Subject: [PATCH 585/848] GPU: Hash CLUT using XXH3 with replacements off. It's faster, but if texture replacements are enabled, we want the hash to stay the same. --- GPU/D3D11/TextureCacheD3D11.cpp | 5 ++++- GPU/Directx9/TextureCacheDX9.cpp | 5 ++++- GPU/GLES/TextureCacheGLES.cpp | 5 ++++- GPU/Vulkan/TextureCacheVulkan.cpp | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 47a1a95535..0b59f6daed 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -208,7 +208,10 @@ void TextureCacheD3D11::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBa // Adding clutBaseBytes may just be mitigating this for some usage patterns. const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); - clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + if (replacer_.Enabled()) + clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + else + clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; clutBuf_ = clutBufRaw_; // Special optimization: fonts typically draw clut4 with just alpha values in a single color. diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 6fd3cadd69..4c0d6c4c9a 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -250,7 +250,10 @@ void TextureCacheDX9::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase // Adding clutBaseBytes may just be mitigating this for some usage patterns. const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); - clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + if (replacer_.Enabled()) + clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + else + clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; clutBuf_ = clutBufRaw_; // Special optimization: fonts typically draw clut4 with just alpha values in a single color. diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 5f0a9d9068..ee9db82361 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -249,7 +249,10 @@ void TextureCacheGLES::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBas // Adding clutBaseBytes may just be mitigating this for some usage patterns. const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); - clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + if (replacer_.Enabled()) + clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + else + clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; // Avoid a copy when we don't need to convert colors. if (clutFormat != GE_CMODE_32BIT_ABGR8888) { diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index d0fc324a25..6f0bc779b4 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -507,7 +507,10 @@ void TextureCacheVulkan::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutB // Adding clutBaseBytes may just be mitigating this for some usage patterns. const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); - clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + if (replacer_.Enabled()) + clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + else + clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; clutBuf_ = clutBufRaw_; // Special optimization: fonts typically draw clut4 with just alpha values in a single color. From e32524c5445eb40045f7a015e0072fa53f3ab516 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Aug 2020 01:15:22 -0700 Subject: [PATCH 586/848] GPU: Remove ReliableHash aliases. Let's just use XXH32/XXH64 directly in texture replacements, clearer anyway. --- Core/TextureReplacer.cpp | 8 ++++---- GPU/Common/TextureDecoder.h | 27 --------------------------- GPU/D3D11/TextureCacheD3D11.cpp | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 2 +- 6 files changed, 8 insertions(+), 35 deletions(-) diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 16f0374fc4..7cdb34c23a 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -246,9 +246,9 @@ u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, GETextureForm case ReplacedTextureHash::QUICK: return StableQuickTexHash(checkp, sizeInRAM); case ReplacedTextureHash::XXH32: - return DoReliableHash32(checkp, sizeInRAM, 0xBACD7814); + return XXH32(checkp, sizeInRAM, 0xBACD7814); case ReplacedTextureHash::XXH64: - return DoReliableHash64(checkp, sizeInRAM, 0xBACD7814); + return XXH64(checkp, sizeInRAM, 0xBACD7814); default: return 0; } @@ -269,7 +269,7 @@ u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, GETextureForm case ReplacedTextureHash::XXH32: for (int y = 0; y < h; ++y) { - u32 rowHash = DoReliableHash32(checkp, bytesPerLine, 0xBACD7814); + u32 rowHash = XXH32(checkp, bytesPerLine, 0xBACD7814); result = (result * 11) ^ rowHash; checkp += stride; } @@ -277,7 +277,7 @@ u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, GETextureForm case ReplacedTextureHash::XXH64: for (int y = 0; y < h; ++y) { - u32 rowHash = DoReliableHash64(checkp, bytesPerLine, 0xBACD7814); + u32 rowHash = XXH64(checkp, bytesPerLine, 0xBACD7814); result = (result * 11) ^ rowHash; checkp += stride; } diff --git a/GPU/Common/TextureDecoder.h b/GPU/Common/TextureDecoder.h index dd01b65bce..803c6c3929 100644 --- a/GPU/Common/TextureDecoder.h +++ b/GPU/Common/TextureDecoder.h @@ -45,31 +45,11 @@ u32 QuickTexHashSSE2(const void *checkp, u32 size); void DoUnswizzleTex16Basic(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 pitch); #define DoUnswizzleTex16 DoUnswizzleTex16Basic -#include "ext/xxhash.h" -#define DoReliableHash32 XXH32 -#define DoReliableHash64 XXH64 - -#if defined(_M_X64) || defined(ARM64) -#define DoReliableHash XXH64 -typedef u64 ReliableHashType; -#else -#define DoReliableHash XXH32 -typedef u32 ReliableHashType; -#endif - // For ARM64, NEON is mandatory, so we also statically link. #elif PPSSPP_ARCH(ARM64) || defined(ARM64) #define DoQuickTexHash QuickTexHashNEON #define StableQuickTexHash QuickTexHashNEON #define DoUnswizzleTex16 DoUnswizzleTex16NEON - -#include "ext/xxhash.h" -#define DoReliableHash32 XXH32 -#define DoReliableHash64 XXH64 - -#define DoReliableHash XXH64 -typedef u64 ReliableHashType; - #else typedef u32 (*QuickTexHashFunc)(const void *checkp, u32 size); extern QuickTexHashFunc DoQuickTexHash; @@ -77,13 +57,6 @@ extern QuickTexHashFunc StableQuickTexHash; typedef void (*UnswizzleTex16Func)(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 pitch); extern UnswizzleTex16Func DoUnswizzleTex16; - -#include "ext/xxhash.h" -#define DoReliableHash32 XXH32 -#define DoReliableHash64 XXH64 - -#define DoReliableHash XXH32 -typedef u32 ReliableHashType; #endif CheckAlphaResult CheckAlphaRGBA8888Basic(const u32 *pixelData, int stride, int w, int h); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 0b59f6daed..9b6ad9b70c 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -209,7 +209,7 @@ void TextureCacheD3D11::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBa const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); if (replacer_.Enabled()) - clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); else clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; clutBuf_ = clutBufRaw_; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 4c0d6c4c9a..c5e70491ef 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -251,7 +251,7 @@ void TextureCacheDX9::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); if (replacer_.Enabled()) - clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); else clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; clutBuf_ = clutBufRaw_; diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index ee9db82361..17c2acd6f5 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -250,7 +250,7 @@ void TextureCacheGLES::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBas const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); if (replacer_.Enabled()) - clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); else clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 6f0bc779b4..bf51e1f74e 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -508,7 +508,7 @@ void TextureCacheVulkan::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutB const u32 clutExtendedBytes = std::min(clutTotalBytes_ + clutBaseBytes, clutMaxBytes_); if (replacer_.Enabled()) - clutHash_ = DoReliableHash32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); + clutHash_ = XXH32((const char *)clutBufRaw_, clutExtendedBytes, 0xC0108888); else clutHash_ = XXH3_64bits((const char *)clutBufRaw_, clutExtendedBytes) & 0xFFFFFFFF; clutBuf_ = clutBufRaw_; From 41fe6f9e12f5d6ba50a86ffe556e9b19a6c24141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 28 Aug 2020 10:38:00 +0200 Subject: [PATCH 587/848] Delete an unused buffer, saving 0.5MB of RAM. --- GPU/Common/TextureCacheCommon.cpp | 1 - GPU/Common/TextureCacheCommon.h | 1 - 2 files changed, 2 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 246e2ae9ec..9f40e00d92 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -115,7 +115,6 @@ TextureCacheCommon::TextureCacheCommon(Draw::DrawContext *draw) // These buffers will grow if necessary, but most won't need more than this. tmpTexBuf32_.resize(512 * 512); // 1MB - tmpTexBuf16_.resize(512 * 512); // 0.5MB tmpTexBufRearrange_.resize(512 * 512); // 1MB replacer_.Init(); diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 0f10f4e070..452236cd44 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -331,7 +331,6 @@ protected: std::map videos_; SimpleBuf tmpTexBuf32_; - SimpleBuf tmpTexBuf16_; SimpleBuf tmpTexBufRearrange_; TexCacheEntry *nextTexture_; From df82673116ef8a5a74e7af0d0be8490202597c00 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sat, 29 Aug 2020 15:26:44 +0800 Subject: [PATCH 588/848] Actually clear memory when initializating. --- Core/Util/BlockAllocator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index c302d8e91b..53a0631232 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -23,6 +23,7 @@ #include "Common/StringUtils.h" #include "Core/Util/BlockAllocator.h" #include "Core/Reporting.h" +#include "Core/MemMapHelpers.h" // Slow freaking thing but works (eventually) :) @@ -43,6 +44,7 @@ void BlockAllocator::Init(u32 rangeStart, u32 rangeSize) //Initial block, covering everything top_ = new Block(rangeStart_, rangeSize_, false, NULL, NULL); bottom_ = top_; + Memory::Memset(rangeStart_, 0, rangeSize_); } void BlockAllocator::Shutdown() From 8618cc7ab5f793475275554b2a3dd020717822ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 29 Aug 2020 12:42:36 +0200 Subject: [PATCH 589/848] Virtual framebuffer copies: Make a more informed guess on appropriate pixel format. This is the first part of the Test Drive fix, which I want in separately. --- GPU/Common/FramebufferManagerCommon.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 3b49bad205..ab95f7de01 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1293,9 +1293,19 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst } if (!dstBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) { - GEBufferFormat ramFormat = bpp == 4 ? GE_FORMAT_8888 : GE_FORMAT_5551; - // TODO: We don't really know the 16-bit format here.. at all. Can only guess when it gets used later! - // But actually, the format of the source buffer is probably not a bad guess.. + GEBufferFormat ramFormat; + // Try to guess the appropriate format. We only know the bpp from the block transfer command (16 or 32 bit). + if (bpp == 4) { + // Only one possibility unless it's doing split pixel tricks (which we could detect through stride maybe). + ramFormat = GE_FORMAT_8888; + } else if (srcBuffer->format != GE_FORMAT_8888) { + // We guess that the game will interpret the data the same as it was in the source of the copy. + // Seems like a likely good guess, and works in Test Drive Unlimited. + ramFormat = srcBuffer->format; + } else { + // No info left - just fall back to something. But this is definitely split pixel tricks. + ramFormat = GE_FORMAT_5551; + } dstBuffer = CreateRAMFramebuffer(dstBasePtr, dstWidth, dstHeight, dstStride, ramFormat); } From 0f45e17f09ffd506c11041e326bcb4cff27ec7d3 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sat, 29 Aug 2020 19:51:11 +0800 Subject: [PATCH 590/848] Only clear when initializating kernelMemory and userMemory. --- Core/HLE/sceKernelMemory.cpp | 6 ++++-- Core/Util/BlockAllocator.cpp | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 7da8bc4ef2..8ceb699fad 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -426,8 +426,10 @@ void __KernelFplEndCallback(SceUID threadID, SceUID prevCallbackId); void __KernelMemoryInit() { - kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd()-PSP_GetKernelMemoryBase()); - userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd()-PSP_GetUserMemoryBase()); + kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase()); + userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase()); + Memory::Memset(PSP_GetKernelMemoryBase(), 0, PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase()); + Memory::Memset(PSP_GetUserMemoryBase(), 0, PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase()); INFO_LOG(SCEKERNEL, "Kernel and user memory pools initialized"); vplWaitTimer = CoreTiming::RegisterEvent("VplTimeout", __KernelVplTimeout); diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index 53a0631232..c302d8e91b 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -23,7 +23,6 @@ #include "Common/StringUtils.h" #include "Core/Util/BlockAllocator.h" #include "Core/Reporting.h" -#include "Core/MemMapHelpers.h" // Slow freaking thing but works (eventually) :) @@ -44,7 +43,6 @@ void BlockAllocator::Init(u32 rangeStart, u32 rangeSize) //Initial block, covering everything top_ = new Block(rangeStart_, rangeSize_, false, NULL, NULL); bottom_ = top_; - Memory::Memset(rangeStart_, 0, rangeSize_); } void BlockAllocator::Shutdown() From 364aabe84f1d9750f9a2c7c7b55383d5a863956c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 29 Aug 2020 08:03:58 -0700 Subject: [PATCH 591/848] TexCache: Improve quicktexhash by ~1-4% on NEON. Improvement is greater on 64-bit (4.3%) than 32-bit (1.6%.) --- GPU/Common/TextureDecoderNEON.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GPU/Common/TextureDecoderNEON.cpp b/GPU/Common/TextureDecoderNEON.cpp index 36f40b3b76..32a9c53d60 100644 --- a/GPU/Common/TextureDecoderNEON.cpp +++ b/GPU/Common/TextureDecoderNEON.cpp @@ -47,7 +47,8 @@ u32 QuickTexHashNEON(const void *checkp, u32 size) { uint16x8_t update = vdupq_n_u16(0x2455U); const u32 *p = (const u32 *)checkp; - for (u32 i = 0; i < size / 16; i += 4) { + const u32 *pend = p + size / 4; + while (p < pend) { cursor = vreinterpretq_u32_u16(vmlaq_u16(vreinterpretq_u16_u32(cursor), vreinterpretq_u16_u32(vld1q_u32(&p[4 * 0])), cursor2)); cursor = veorq_u32(cursor, vld1q_u32(&p[4 * 1])); cursor = vaddq_u32(cursor, vld1q_u32(&p[4 * 2])); @@ -58,7 +59,8 @@ u32 QuickTexHashNEON(const void *checkp, u32 size) { } cursor = vaddq_u32(cursor, vreinterpretq_u32_u16(cursor2)); - check = vgetq_lane_u32(cursor, 0) + vgetq_lane_u32(cursor, 1) + vgetq_lane_u32(cursor, 2) + vgetq_lane_u32(cursor, 3); + uint32x2_t mixed = vadd_u32(vget_high_u32(cursor), vget_low_u32(cursor)); + check = vget_lane_u32(mixed, 0) + vget_lane_u32(mixed, 1); #else // TODO: Why does this crash on iOS, but only certain devices? // It's faster than the above, but I guess it sucks to be using an iPhone. From 7426e2a8f82d10f17f375a2b55a5764c3e6fc7aa Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 29 Aug 2020 08:16:23 -0700 Subject: [PATCH 592/848] TexCache: Try to avoid wrong texcache usage. Now that the speed is closer, disable on non-ARMV7 so we can avoid wrong compilations more often. --- GPU/Common/TextureDecoderNEON.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GPU/Common/TextureDecoderNEON.cpp b/GPU/Common/TextureDecoderNEON.cpp index 32a9c53d60..8e96223877 100644 --- a/GPU/Common/TextureDecoderNEON.cpp +++ b/GPU/Common/TextureDecoderNEON.cpp @@ -41,7 +41,7 @@ u32 QuickTexHashNEON(const void *checkp, u32 size) { __builtin_prefetch(checkp, 0, 0); if (((intptr_t)checkp & 0xf) == 0 && (size & 0x3f) == 0) { -#if defined(IOS) || PPSSPP_ARCH(ARM64) || defined(_MSC_VER) +#if defined(IOS) || PPSSPP_ARCH(ARM64) || defined(_MSC_VER) || !PPSSPP_ARCH(ARMV7) uint32x4_t cursor = vdupq_n_u32(0); uint16x8_t cursor2 = vld1q_u16(QuickTexHashInitial); uint16x8_t update = vdupq_n_u16(0x2455U); @@ -64,6 +64,7 @@ u32 QuickTexHashNEON(const void *checkp, u32 size) { #else // TODO: Why does this crash on iOS, but only certain devices? // It's faster than the above, but I guess it sucks to be using an iPhone. + // As of 2020 clang, it's still faster by ~1.4%. // d0/d1 (q0) - cursor // d2/d3 (q1) - cursor2 From 2be8f8628642e860e7ace9c560c387f243a1a3fb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 29 Aug 2020 08:18:54 -0700 Subject: [PATCH 593/848] GPU: Avoid compile error if ARM64=1 specified. If it's specified, but incorrect, we would compile incorrectly. We're moving away from it anyway. --- GPU/Common/TextureDecoder.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GPU/Common/TextureDecoder.h b/GPU/Common/TextureDecoder.h index 803c6c3929..02e7939cdc 100644 --- a/GPU/Common/TextureDecoder.h +++ b/GPU/Common/TextureDecoder.h @@ -23,6 +23,7 @@ enum CheckAlphaResult { CHECKALPHA_ANY = 4, }; +#include "ppsspp_config.h" #include "Common/Common.h" #include "Common/Swap.h" #include "Core/MemMap.h" @@ -46,7 +47,7 @@ void DoUnswizzleTex16Basic(const u8 *texptr, u32 *ydestp, int bxc, int byc, u32 #define DoUnswizzleTex16 DoUnswizzleTex16Basic // For ARM64, NEON is mandatory, so we also statically link. -#elif PPSSPP_ARCH(ARM64) || defined(ARM64) +#elif PPSSPP_ARCH(ARM64) #define DoQuickTexHash QuickTexHashNEON #define StableQuickTexHash QuickTexHashNEON #define DoUnswizzleTex16 DoUnswizzleTex16NEON From 6b8f7294b3f2a8d39c3344e0e917eb1c0545070e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 29 Aug 2020 08:45:50 -0700 Subject: [PATCH 594/848] Global: Remove ARM64 define. Was barely used anymore, and some users are specifying it when it's not the case, so better to detect consistently. --- CMakeLists.txt | 1 - Core/Config.cpp | 5 +++-- Core/MIPS/ARM64/Arm64Jit.cpp | 2 +- Core/MIPS/JitCommon/JitBlockCache.cpp | 12 ++++++------ Core/MIPS/JitCommon/JitBlockCache.h | 3 ++- GPU/Common/VertexDecoderArm64.cpp | 5 ----- GPU/Common/VertexDecoderCommon.cpp | 7 ++++--- UI/DevScreens.cpp | 3 ++- UI/NativeApp.cpp | 8 ++++---- Windows/GPU/D3D11Context.cpp | 2 +- android/jni/Locals.mk | 4 +--- ext/glslang-build/Android.mk | 2 -- ext/miniupnp-build/Android.mk | 2 -- ext/native/Android.mk | 2 -- ext/native/gfx/gl_common.h | 4 +++- ppsspp_config.h | 4 ---- unittest/JitHarness.cpp | 5 +++-- unittest/UnitTest.cpp | 7 ++++--- 18 files changed, 34 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58ae6384d3..8ac7149764 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,6 @@ if(CMAKE_SYSTEM_PROCESSOR) endif() elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^aarch64") set(ARM64 ON) - add_definitions(-DARM64) elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^amd64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^x86_64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "^AMD64") set(X86_DEVICE ON) set(X86_64_DEVICE ON) diff --git a/Core/Config.cpp b/Core/Config.cpp index f4149c8870..1a8fc70027 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -22,6 +22,7 @@ #include #include +#include "ppsspp_config.h" #include "base/display.h" #include "base/NativeApp.h" #include "file/ini_file.h" @@ -393,7 +394,7 @@ static int DefaultNumWorkers() { } static int DefaultCpuCore() { -#if defined(ARM) || defined(ARM64) || defined(_M_IX86) || defined(_M_X64) +#if PPSSPP_ARCH(ARM) || PPSSPP_ARCH(ARM64) || PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) return (int)CPUCore::JIT; #else return (int)CPUCore::INTERPRETER; @@ -401,7 +402,7 @@ static int DefaultCpuCore() { } static bool DefaultCodeGen() { -#if defined(ARM) || defined(ARM64) || defined(_M_IX86) || defined(_M_X64) +#if PPSSPP_ARCH(ARM) || PPSSPP_ARCH(ARM64) || PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) return true; #else return false; diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index e626599019..582cb7191e 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -472,7 +472,7 @@ void Arm64Jit::UnlinkBlock(u8 *checkedEntry, u32 originalAddress) { } bool Arm64Jit::ReplaceJalTo(u32 dest) { -#ifdef ARM64 +#if PPSSPP_ARCH(ARM64) const ReplacementTableEntry *entry = nullptr; u32 funcSize = 0; if (!CanReplaceJalTo(dest, &entry, &funcSize)) { diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 7761646993..9807ce9551 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -601,12 +601,12 @@ void JitBlockCache::InvalidateChangedBlocks() { } int JitBlockCache::GetBlockExitSize() { -#if defined(ARM) +#if PPSSPP_ARCH(ARM) // Will depend on the sequence found to encode the destination address. return 0; -#elif defined(_M_IX86) || defined(_M_X64) +#elif PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) return 15; -#elif defined(ARM64) +#elif PPSSPP_ARCH(ARM64) // Will depend on the sequence found to encode the destination address. return 0; #else @@ -654,11 +654,11 @@ JitBlockDebugInfo JitBlockCache::GetBlockDebugInfo(int blockNum) const { debugInfo.origDisasm.push_back(mipsDis); } -#if defined(ARM) +#if PPSSPP_ARCH(ARM) debugInfo.targetDisasm = DisassembleArm2(block->normalEntry, block->codeSize); -#elif defined(ARM64) +#elif PPSSPP_ARCH(ARM64) debugInfo.targetDisasm = DisassembleArm64(block->normalEntry, block->codeSize); -#elif defined(_M_IX86) || defined(_M_X64) +#elif PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) debugInfo.targetDisasm = DisassembleX86(block->normalEntry, block->codeSize); #endif diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 3c51a67f66..0b26138fb2 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -22,12 +22,13 @@ #include #include +#include "ppsspp_config.h" #include "Common/CommonTypes.h" #include "Common/CodeBlock.h" #include "Core/MIPS/MIPSAnalyst.h" #include "Core/MIPS/MIPS.h" -#if defined(ARM) || defined(ARM64) +#if PPSSPP_ARCH(ARM) || PPSSPP_ARCH(ARM64) const int MAX_JIT_BLOCK_EXITS = 2; #else const int MAX_JIT_BLOCK_EXITS = 8; diff --git a/GPU/Common/VertexDecoderArm64.cpp b/GPU/Common/VertexDecoderArm64.cpp index 7ba612affa..c1ec8770bc 100644 --- a/GPU/Common/VertexDecoderArm64.cpp +++ b/GPU/Common/VertexDecoderArm64.cpp @@ -18,11 +18,6 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM64) -// This allows highlighting to work. Yay. -#ifdef __INTELLISENSE__ -#define ARM64 -#endif - #include "Common/CPUDetect.h" #include "Common/Log.h" #include "Core/Config.h" diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index 87b8114303..0491105465 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -18,6 +18,7 @@ #include #include +#include "ppsspp_config.h" #include "base/basictypes.h" #include "Common/Log.h" @@ -1345,11 +1346,11 @@ std::string VertexDecoder::GetString(DebugShaderStringType stringType) { if (!jitted_) return "Not compiled"; std::vector lines; -#if defined(ARM64) +#if PPSSPP_ARCH(ARM64) lines = DisassembleArm64((const u8 *)jitted_, jittedSize_); -#elif defined(ARM) +#elif PPSSPP_ARCH(ARM) lines = DisassembleArm2((const u8 *)jitted_, jittedSize_); -#elif defined(MIPS) +#elif PPSSPP_ARCH(MIPS) || PPSSPP_ARCH(MIPS64) // No MIPS disassembler defined #else lines = DisassembleX86((const u8 *)jitted_, jittedSize_); diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 9c0d6cdf99..86d6c9b71a 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -17,6 +17,7 @@ #include +#include "ppsspp_config.h" #include "base/display.h" #include "base/stringutil.h" #include "gfx_es2/gpu_features.h" @@ -458,7 +459,7 @@ void SystemInfoScreen::CreateViews() { deviceSpecs->Add(new ItemHeader(si->T("CPU Information"))); deviceSpecs->Add(new InfoItem(si->T("CPU Name", "Name"), cpu_info.brand_string)); -#if defined(ARM) || defined(ARM64) || defined(MIPS) +#if PPSSPP_ARCH(ARM) || PPSSPP_ARCH(ARM64) || PPSSPP_ARCH(MIPS) || PPSSPP_ARCH(MIPS64) deviceSpecs->Add(new InfoItem(si->T("Cores"), StringFromInt(cpu_info.num_cores))); #else int totalThreads = cpu_info.num_cores * cpu_info.logical_cpu_count; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 663bc30e5b..0471116650 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -125,9 +125,9 @@ static UI::Theme ui_theme; Atlas g_ui_atlas; -#if defined(ARM) && defined(__ANDROID__) +#if PPSSPP_ARCH(ARM) && defined(__ANDROID__) #include "../../android/jni/ArmEmitterTest.h" -#elif defined(ARM64) && defined(__ANDROID__) +#elif PPSSPP_ARCH(ARM64) && defined(__ANDROID__) #include "../../android/jni/Arm64EmitterTest.h" #endif @@ -291,9 +291,9 @@ void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name, boo *landscape = true; *version = PPSSPP_GIT_VERSION; -#if defined(ARM) && defined(__ANDROID__) +#if PPSSPP_ARCH(ARM) && defined(__ANDROID__) ArmEmitterTest(); -#elif defined(ARM64) && defined(__ANDROID__) +#elif PPSSPP_ARCH(ARM64) && defined(__ANDROID__) Arm64EmitterTest(); #endif } diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 7ed3969444..74f3b9b67b 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -54,7 +54,7 @@ HRESULT D3D11Context::CreateTheDevice(IDXGIAdapter *adapter) { // D3D11 has no need for display rotation. g_display_rotation = DisplayRotation::ROTATE_0; g_display_rot_matrix.setIdentity(); -#if defined(_DEBUG) && !defined(_M_ARM) && !defined(_M_ARM64) +#if defined(_DEBUG) && !PPSSPP_ARCH(ARM) && !PPSSPP_ARCH(ARM64) UINT createDeviceFlags = D3D11_CREATE_DEVICE_DEBUG; #else UINT createDeviceFlags = 0; diff --git a/android/jni/Locals.mk b/android/jni/Locals.mk index 8493c67b05..6e851d5d13 100644 --- a/android/jni/Locals.mk +++ b/android/jni/Locals.mk @@ -70,7 +70,7 @@ ifeq ($(TARGET_ARCH_ABI),x86_64) LOCAL_LDLIBS += $(LOCAL_PATH)/../../ffmpeg/android/x86_64/lib/libavutil.a LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../ffmpeg/android/x86_64/include - LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_ARCH_64 -D_M_X64 -fomit-frame-pointer -mtune=atom -mfpmath=sse -mssse3 -mstackrealign + LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_X64 -fomit-frame-pointer -mtune=atom -mfpmath=sse -mssse3 -mstackrealign endif ifeq ($(TARGET_ARCH_ABI),arm64-v8a) @@ -80,8 +80,6 @@ ifeq ($(TARGET_ARCH_ABI),arm64-v8a) LOCAL_LDLIBS += $(LOCAL_PATH)/../../ffmpeg/android/arm64/lib/libswscale.a LOCAL_LDLIBS += $(LOCAL_PATH)/../../ffmpeg/android/arm64/lib/libavutil.a LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../ffmpeg/android/arm64/include - - LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_ARCH_64 -DARM64 endif # Compile with profiling. diff --git a/ext/glslang-build/Android.mk b/ext/glslang-build/Android.mk index 48b9ec9a42..8125efa02b 100644 --- a/ext/glslang-build/Android.mk +++ b/ext/glslang-build/Android.mk @@ -64,8 +64,6 @@ ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A else ifeq ($(TARGET_ARCH_ABI),armeabi) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 -else ifeq ($(TARGET_ARCH_ABI),arm64-v8a) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_ARCH_64 -DARM64 else ifeq ($(TARGET_ARCH_ABI),x86) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86 else ifeq ($(TARGET_ARCH_ABI),x86_64) diff --git a/ext/miniupnp-build/Android.mk b/ext/miniupnp-build/Android.mk index e2d7fd1c28..6675d326a5 100644 --- a/ext/miniupnp-build/Android.mk +++ b/ext/miniupnp-build/Android.mk @@ -31,8 +31,6 @@ ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A else ifeq ($(TARGET_ARCH_ABI),armeabi) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 -else ifeq ($(TARGET_ARCH_ABI),arm64-v8a) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_ARCH_64 -DARM64 else ifeq ($(TARGET_ARCH_ABI),x86) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86 else ifeq ($(TARGET_ARCH_ABI),x86_64) diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 2699df0ff8..d95685387d 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -118,8 +118,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ else ifeq ($(TARGET_ARCH_ABI),armeabi) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 -else ifeq ($(TARGET_ARCH_ABI),arm64-v8a) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_ARCH_64 -DARM64 else ifeq ($(TARGET_ARCH_ABI),x86) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86 LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ diff --git a/ext/native/gfx/gl_common.h b/ext/native/gfx/gl_common.h index fd8711b647..011caa19e7 100644 --- a/ext/native/gfx/gl_common.h +++ b/ext/native/gfx/gl_common.h @@ -1,5 +1,7 @@ #pragma once +#include "ppsspp_config.h" + #ifdef IOS #include #include @@ -51,7 +53,7 @@ extern PFNGLMAPBUFFERPROC glMapBuffer; typedef void (EGLAPIENTRYP PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); extern PFNGLDRAWTEXTURENVPROC glDrawTextureNV; -#ifndef ARM64 +#if !PPSSPP_ARCH(ARM64) typedef void (EGLAPIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) ( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, diff --git a/ppsspp_config.h b/ppsspp_config.h index 8743e2290e..655e744f14 100644 --- a/ppsspp_config.h +++ b/ppsspp_config.h @@ -58,10 +58,6 @@ #define PPSSPP_ARCH_ARM64 1 #define PPSSPP_ARCH_64BIT 1 #define PPSSPP_ARCH_ARM_NEON 1 - //TODO: Remove this compat define - #ifndef ARM64 - #define ARM64 1 - #endif #endif #if defined(__mips64__) diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index 6ab64de21e..e2cecf0f88 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -17,6 +17,7 @@ #include +#include "ppsspp_config.h" #include "base/NativeApp.h" #include "Common/TimeUtil.h" #include "Core/ConfigValues.h" @@ -172,9 +173,9 @@ bool TestJit() { // Disassemble JitBlockCache *cache = MIPSComp::jit->GetBlockCache(); JitBlock *block = cache->GetBlock(0); // Should only be one block. -#if defined(ARM) +#if PPSSPP_ARCH(ARM) std::vector lines = DisassembleArm2(block->normalEntry, block->codeSize); -#elif defined(ARM64) +#elif PPSSPP_ARCH(ARM64) std::vector lines = DisassembleArm64(block->normalEntry, block->codeSize); #else std::vector lines = DisassembleX86(block->normalEntry, block->codeSize); diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 25ad953392..57225020da 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -33,6 +33,7 @@ #include #endif +#include "ppsspp_config.h" #include "base/NativeApp.h" #include "input/input_state.h" #include "ext/disarm.h" @@ -559,13 +560,13 @@ bool TestArm64Emitter(); bool TestX64Emitter(); TestItem availableTests[] = { -#if defined(ARM64) || defined(_M_X64) || defined(_M_IX86) +#if PPSSPP_ARCH(ARM64) || PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) TEST_ITEM(Arm64Emitter), #endif -#if defined(ARM) || defined(_M_X64) || defined(_M_IX86) +#if PPSSPP_ARCH(ARM) || PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) TEST_ITEM(ArmEmitter), #endif -#if defined(_M_X64) || defined(_M_IX86) +#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86) TEST_ITEM(X64Emitter), #endif TEST_ITEM(VertexJit), From c5738ca19e4c7bc85dbd178b84cc7a17d1aff4d8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 29 Aug 2020 08:49:19 -0700 Subject: [PATCH 595/848] cmake: Remove outdated ARMV7 define. Was not used anymore, but was defined incorrectly in some armv8 files. --- cmake/Toolchains/beagleboard.cmake | 1 - cmake/Toolchains/generic.armv7.cmake | 2 -- cmake/Toolchains/raspberry.armv7.cmake | 1 - cmake/Toolchains/raspberry.armv8.cmake | 1 - cmake/Toolchains/vero4k.armv8.cmake | 1 - 5 files changed, 6 deletions(-) diff --git a/cmake/Toolchains/beagleboard.cmake b/cmake/Toolchains/beagleboard.cmake index 310d13f071..a8648f26f6 100644 --- a/cmake/Toolchains/beagleboard.cmake +++ b/cmake/Toolchains/beagleboard.cmake @@ -1,4 +1,3 @@ -set(ARMV7 ON) set(USING_FBDEV ON) set(ARCH_FLAGS "-march=armv7-a -mfpu=neon -mcpu=cortex-a8") diff --git a/cmake/Toolchains/generic.armv7.cmake b/cmake/Toolchains/generic.armv7.cmake index 65a60943f4..a87da96179 100644 --- a/cmake/Toolchains/generic.armv7.cmake +++ b/cmake/Toolchains/generic.armv7.cmake @@ -1,5 +1,3 @@ -set(ARMV7 ON) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfpu=neon -mcpu=cortex-a9") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfpu=neon -mcpu=cortex-a9") set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=armv7-a -mfpu=neon -mcpu=cortex-a9") diff --git a/cmake/Toolchains/raspberry.armv7.cmake b/cmake/Toolchains/raspberry.armv7.cmake index b9a8b46a65..8fa4dc6888 100644 --- a/cmake/Toolchains/raspberry.armv7.cmake +++ b/cmake/Toolchains/raspberry.armv7.cmake @@ -38,5 +38,4 @@ if(NOT PPSSPP_PI_MODEL4) set(USING_FBDEV ON) endif() set(USING_GLES2 ON) -set(ARMV7 ON) set(USE_WAYLAND_WSI OFF) diff --git a/cmake/Toolchains/raspberry.armv8.cmake b/cmake/Toolchains/raspberry.armv8.cmake index c1c8f5fd02..1bac90de9f 100644 --- a/cmake/Toolchains/raspberry.armv8.cmake +++ b/cmake/Toolchains/raspberry.armv8.cmake @@ -38,5 +38,4 @@ if(NOT PPSSPP_PI_MODEL4) set(USING_FBDEV ON) endif() set(USING_GLES2 ON) -set(ARMV7 ON) set(USE_WAYLAND_WSI OFF) diff --git a/cmake/Toolchains/vero4k.armv8.cmake b/cmake/Toolchains/vero4k.armv8.cmake index 28720127b3..9ce852199a 100644 --- a/cmake/Toolchains/vero4k.armv8.cmake +++ b/cmake/Toolchains/vero4k.armv8.cmake @@ -17,6 +17,5 @@ set(EGL_LIBRARIES /opt/vero3/lib/libEGL.so) set(USING_GLES2 ON) set(USING_EGL ON) set(USING_FBDEV ON) -set(ARMV7 ON) set(FORCED_CPU armv7) set(USING_X11_VULKAN OFF CACHE BOOL "" FORCE) From b86d26da422b5c731902bb27c514b8eca2f36797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 30 Aug 2020 10:13:16 +0200 Subject: [PATCH 596/848] Remove wrong assert. Should fix #13354 --- ext/native/thin3d/VulkanRenderManager.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 3c6810cc3f..6f439134a3 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -1038,25 +1038,20 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in _dbg_assert_(curRenderStep_ != nullptr); // Mark the dependency, check for required transitions, and return the image. + // Optimization: If possible, use final*Layout to put the texture into the correct layout "early". for (int i = (int)steps_.size() - 1; i >= 0; i--) { if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == fb) { if (aspectBit == VK_IMAGE_ASPECT_COLOR_BIT) { // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) { steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - break; - } else if (steps_[i]->render.finalColorLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - _assert_msg_(false, "Unexpected color layout %d", (int)steps_[i]->render.finalColorLayout); - // May need to shadow the framebuffer if we re-order passes later. } + // If we find some other layout, a copy after this is likely involved. It's fine though, + // we'll just transition it right as we need it and lose a tiny optimization. } else if (aspectBit == VK_IMAGE_ASPECT_DEPTH_BIT) { // If this framebuffer was rendered to earlier in this frame, make sure to pre-transition it to the correct layout. if (steps_[i]->render.finalDepthStencilLayout == VK_IMAGE_LAYOUT_UNDEFINED) { steps_[i]->render.finalDepthStencilLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - break; - } else if (steps_[i]->render.finalDepthStencilLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - _assert_msg_(false, "Unexpected depth layout %d", (int)steps_[i]->render.finalDepthStencilLayout); - // May need to shadow the framebuffer if we re-order passes later. } } // We don't (yet?) support texturing from stencil images. steps_[i]->render.numReads++; From 000c20ee44b6214aa005bb6c45138e7fe5cb7002 Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sun, 30 Aug 2020 17:44:17 +0800 Subject: [PATCH 597/848] Add a check in sceKernelTerminateDeleteThread https://github.com/jpcsp/jpcsp/blob/master/src/jpcsp/HLE/modules/ThreadManForUser.java#L3998 --- Core/HLE/sceKernelThread.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index c8f1c4216f..5d5d4af02c 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2304,6 +2304,8 @@ int sceKernelTerminateDeleteThread(int threadID) ERROR_LOG(SCEKERNEL, "sceKernelTerminateDeleteThread(%i): cannot terminate current thread", threadID); return SCE_KERNEL_ERROR_ILLEGAL_THID; } + if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() > 0x0307FFFF) + return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_CAN_NOT_WAIT); u32 error; PSPThread *t = kernelObjects.Get(threadID, error); From b0365bd6ee3dc0b755edbc215f1e91e2c85de1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 30 Aug 2020 11:48:58 +0200 Subject: [PATCH 598/848] GE dump loading: Try to use the correct GameID so compat.ini flags apply. --- Core/ELF/ParamSFO.h | 5 ++++- Core/System.cpp | 27 ++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Core/ELF/ParamSFO.h b/Core/ELF/ParamSFO.h index dca5d1b23e..aac91f12e7 100644 --- a/Core/ELF/ParamSFO.h +++ b/Core/ELF/ParamSFO.h @@ -22,6 +22,7 @@ #include #include "Common/CommonTypes.h" +#include "Common/Log.h" class ParamSFOData { @@ -40,7 +41,9 @@ public: std::string GetDiscID() { const std::string discID = GetValueString("DISC_ID"); if (discID.empty()) { - return GenerateFakeID(); + std::string fakeID = GenerateFakeID(); + WARN_LOG(LOADER, "No DiscID found - generating a fake one: %s", fakeID.c_str()); + return fakeID; } return discID; } diff --git a/Core/System.cpp b/Core/System.cpp index 6f9b58ad7b..cc77f58f97 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -185,6 +185,17 @@ bool CPU_HasPendingAction() { void CPU_Shutdown(); +bool DiscIDFromGEDumpPath(const std::string &path, std::string *id) { + std::string filename = File::GetFilename(path); + // Could be more discerning, but hey.. + if (filename.size() > 10 && filename[0] == 'U' && filename[9] == '_') { + *id = filename.substr(0, 9); + return true; + } else { + return false; + } +} + bool CPU_Init() { coreState = CORE_POWERUP; currentMIPS = &mipsr4k; @@ -216,32 +227,46 @@ bool CPU_Init() { MIPSAnalyst::Reset(); Replacement_Init(); + std::string discID; + switch (type) { case IdentifiedFileType::PSP_ISO: case IdentifiedFileType::PSP_ISO_NP: case IdentifiedFileType::PSP_DISC_DIRECTORY: InitMemoryForGameISO(loadedFile); + discID = g_paramSFO.GetDiscID(); break; case IdentifiedFileType::PSP_PBP: case IdentifiedFileType::PSP_PBP_DIRECTORY: // This is normal for homebrew. // ERROR_LOG(LOADER, "PBP directory resolution failed."); InitMemoryForGamePBP(loadedFile); + discID = g_paramSFO.GetDiscID(); break; case IdentifiedFileType::PSP_ELF: if (Memory::g_PSPModel != PSP_MODEL_FAT) { INFO_LOG(LOADER, "ELF, using full PSP-2000 memory access"); Memory::g_MemorySize = Memory::RAM_DOUBLE_SIZE; } + discID = g_paramSFO.GetDiscID(); + break; + case IdentifiedFileType::PPSSPP_GE_DUMP: + // Try to grab the disc ID from the filename, since unfortunately, we don't store + // it in the GE dump. This should probably be fixed, but as long as you don't rename the dumps, + // this will do the trick. + if (!DiscIDFromGEDumpPath(filename, &discID)) { + // Failed? Let the param SFO autogen a fake disc ID. + discID = g_paramSFO.GetDiscID(); + } break; default: + discID = g_paramSFO.GetDiscID(); break; } // Here we have read the PARAM.SFO, let's see if we need any compatibility overrides. // Homebrew usually has an empty discID, and even if they do have a disc id, it's not // likely to collide with any commercial ones. - std::string discID = g_paramSFO.GetDiscID(); coreParameter.compat.Load(discID); if (!Memory::Init()) { From e9ff037e914270f981e410c1bb5b72252494e4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 26 Aug 2020 22:16:48 +0200 Subject: [PATCH 599/848] Extract AttachFramebufferToEntry function --- GPU/Common/TextureCacheCommon.cpp | 37 ++++++++++++++++++------------- GPU/Common/TextureCacheCommon.h | 2 ++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 9f40e00d92..3498f8c577 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -533,12 +533,8 @@ void TextureCacheCommon::SetTexture(bool force) { // Before we go reading the texture from memory, let's check for render-to-texture. // We must do this early so we have the right w/h. entry->framebuffer = nullptr; - for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { - auto framebuffer = fbCache_[i]; - auto notificationChannel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; - FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer->fb_address, framebuffer, 0, notificationChannel); - ApplyFramebufferMatch(match, entry, framebuffer->fb_address, framebuffer, notificationChannel); - } + + AttachFramebufferToEntry(entry, 0); // If we ended up with a framebuffer, attach it - no texture decoding needed. if (entry->framebuffer) { @@ -551,6 +547,20 @@ void TextureCacheCommon::SetTexture(bool force) { nextNeedsRebuild_ = true; } +bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texAddrOffset) { + bool success = false; + for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { + auto framebuffer = fbCache_[i]; + FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; + FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer->fb_address, framebuffer, texAddrOffset, channel); + if (ApplyFramebufferMatch(match, entry, framebuffer->fb_address, framebuffer, channel)) { + success = true; + } + } + return success; +} + + // Removes old textures. void TextureCacheCommon::Decimate(bool forcePressure) { if (--decimationCounter_ <= 0) { @@ -665,8 +675,12 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram switch (msg) { case NOTIFY_FB_CREATED: case NOTIFY_FB_UPDATED: + // Try to match the new framebuffer to existing textures. + // Backwards from the "usual" texturing case so can't share a utility function. + // Ensure it's in the framebuffer cache. if (std::find(fbCache_.begin(), fbCache_.end(), framebuffer) == fbCache_.end()) { + ERROR_LOG(G3D, "Shouldn't happen: NotifyFramebuffer with framebuffer not in fbCache_"); fbCache_.push_back(framebuffer); } @@ -676,6 +690,7 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); ApplyFramebufferMatch(match, entry, addr, framebuffer, channel); } + // Let's assume anything in mirrors is fair game to check. // TODO: Only do this for depth? for (auto it = cache_.lower_bound(mirrorCacheKey), end = cache_.upper_bound(mirrorCacheKeyEnd); it != end; ++it) { @@ -1011,15 +1026,7 @@ bool TextureCacheCommon::SetOffsetTexture(u32 yOffset) { } TexCacheEntry *entry = iter->second.get(); - bool success = false; - for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { - auto framebuffer = fbCache_[i]; - FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; - FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer->fb_address, framebuffer, texaddrOffset, channel); - if (ApplyFramebufferMatch(match, entry, framebuffer->fb_address, framebuffer, channel)) { - success = true; - } - } + bool success = AttachFramebufferToEntry(entry, texaddrOffset); if (success && entry->framebuffer) { // This will not apply the texture immediately. diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 452236cd44..f699e55026 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -274,6 +274,8 @@ protected: FramebufferMatchInfo MatchFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; + bool AttachFramebufferToEntry(TexCacheEntry *entry, u32 texAddrOffset); + // Temporary utility during conversion bool ApplyFramebufferMatch(FramebufferMatchInfo match, TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel); From a70ea98475281c47d2e054a79be5d2c085246a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 29 Aug 2020 22:15:33 +0200 Subject: [PATCH 600/848] Switch framebuffer matching to a scoring model. --- GPU/Common/TextureCacheCommon.cpp | 88 ++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 7 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 3498f8c577..9fcfd3ce12 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -549,15 +549,77 @@ void TextureCacheCommon::SetTexture(bool force) { bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texAddrOffset) { bool success = false; + + struct AttachCandidate { + FramebufferMatchInfo match; + TexCacheEntry *entry; + VirtualFramebuffer *fb; + }; + + std::vector candidates; + + bool anyIgnores = false; + + FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { auto framebuffer = fbCache_[i]; - FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer->fb_address, framebuffer, texAddrOffset, channel); - if (ApplyFramebufferMatch(match, entry, framebuffer->fb_address, framebuffer, channel)) { - success = true; + if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { + candidates.push_back(AttachCandidate{ match, entry, framebuffer }); + } else if (match.match == FramebufferMatch::IGNORE) { + anyIgnores = true; } } - return success; + + if (!candidates.size()) { + // No candidates at all. + if (anyIgnores) { + // We want to defer the decision, apparently. + return false; + } + + // Actively detach the current framebuffer. + if (entry->framebuffer) { + DetachFramebuffer(entry, entry->addr, entry->framebuffer, channel); + } + return false; + } + + if (candidates.size() == 1) { + VirtualFramebuffer *framebuffer = candidates[0].fb; + return ApplyFramebufferMatch(candidates[0].match, entry, framebuffer->fb_address, framebuffer, channel); + } + + // OK, multiple possible candidates. Will need to figure out which one is the most relevant. + int bestRelevancy = -1; + int bestIndex = -1; + + for (int i = 0; i < (int)candidates.size(); i++) { + const AttachCandidate &candidate = candidates[i]; + int relevancy = 0; + switch (candidate.match.match) { + case FramebufferMatch::VALID: + case FramebufferMatch::VALID_DEPAL: + relevancy += 1000; + break; + case FramebufferMatch::INVALID: + relevancy += 100; + break; + } + + // Bonus point for matching stride. + if (channel == NOTIFY_FB_COLOR && candidate.fb->fb_stride == candidate.entry->bufw) { + relevancy += 10; + } + + if (relevancy >= bestRelevancy) { + bestRelevancy = relevancy; + bestIndex = i; + } + } + + VirtualFramebuffer *framebuffer = candidates[bestIndex].fb; + return ApplyFramebufferMatch(candidates[bestIndex].match, candidates[bestIndex].entry, framebuffer->fb_address, framebuffer, channel); } @@ -680,7 +742,9 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram // Ensure it's in the framebuffer cache. if (std::find(fbCache_.begin(), fbCache_.end(), framebuffer) == fbCache_.end()) { - ERROR_LOG(G3D, "Shouldn't happen: NotifyFramebuffer with framebuffer not in fbCache_"); + // TODO: This is kind of silly. We should probably simply share this list of framebuffers + // with the framebuffer manager. + WARN_LOG(G3D, "TextureCache got info about new framebuffer, at %08x", address); fbCache_.push_back(framebuffer); } @@ -768,8 +832,9 @@ void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualF entry->invalidHint = -1; entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; entry->maxLevel = 0; - if (channel == NOTIFY_FB_DEPTH) + if (channel == NOTIFY_FB_DEPTH) { entry->status |= TexCacheEntry::STATUS_DEPTH; + } fbTexInfo_[cachekey] = fbInfo; GPUDebug::NotifyTextureAttachment(entry->addr); } @@ -820,7 +885,16 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, u32 addr = address & 0x3FFFFFFF; u32 texaddr = entry->addr + texaddrOffset; - if (Memory::IsVRAMAddress(entry->addr)) { + + bool texInVRAM = Memory::IsVRAMAddress(texaddr); + bool fbInVRAM = Memory::IsVRAMAddress(framebuffer->fb_address); + + if (texInVRAM != fbInVRAM) { + // Shortcut. Cannot possibly be a match. + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; + } + + if (texInVRAM) { // This bit controls swizzle. The swizzles at 0x00200000 and 0x00600000 are designed // to perfectly match reading depth as color (which one to use I think might be related // to the bpp of the color format used when rendering to it). From 4252036d8920bff98aa831920136efe074b334d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 29 Aug 2020 22:25:50 +0200 Subject: [PATCH 601/848] Apply the scoring model when creating/updating framebuffers too. Reuses the same mechanism. This is the second part of the Test Drive fix. --- GPU/Common/TextureCacheCommon.cpp | 38 +++++++++++++++++++------------ GPU/Common/TextureCacheCommon.h | 8 +++++++ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 9fcfd3ce12..bad64c09bf 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -550,12 +550,6 @@ void TextureCacheCommon::SetTexture(bool force) { bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texAddrOffset) { bool success = false; - struct AttachCandidate { - FramebufferMatchInfo match; - TexCacheEntry *entry; - VirtualFramebuffer *fb; - }; - std::vector candidates; bool anyIgnores = false; @@ -565,7 +559,7 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA auto framebuffer = fbCache_[i]; FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer->fb_address, framebuffer, texAddrOffset, channel); if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { - candidates.push_back(AttachCandidate{ match, entry, framebuffer }); + candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); } else if (match.match == FramebufferMatch::IGNORE) { anyIgnores = true; } @@ -585,9 +579,15 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA return false; } + return AttachBestCandidate(candidates); +} + +bool TextureCacheCommon::AttachBestCandidate(const std::vector &candidates) { + _dbg_assert_(!candidates.empty()); + if (candidates.size() == 1) { VirtualFramebuffer *framebuffer = candidates[0].fb; - return ApplyFramebufferMatch(candidates[0].match, entry, framebuffer->fb_address, framebuffer, channel); + return ApplyFramebufferMatch(candidates[0].match, candidates[0].entry, framebuffer->fb_address, framebuffer, candidates[0].channel); } // OK, multiple possible candidates. Will need to figure out which one is the most relevant. @@ -608,7 +608,7 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA } // Bonus point for matching stride. - if (channel == NOTIFY_FB_COLOR && candidate.fb->fb_stride == candidate.entry->bufw) { + if (candidate.channel == NOTIFY_FB_COLOR && candidate.fb->fb_stride == candidate.entry->bufw) { relevancy += 10; } @@ -619,10 +619,9 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA } VirtualFramebuffer *framebuffer = candidates[bestIndex].fb; - return ApplyFramebufferMatch(candidates[bestIndex].match, candidates[bestIndex].entry, framebuffer->fb_address, framebuffer, channel); + return ApplyFramebufferMatch(candidates[bestIndex].match, candidates[bestIndex].entry, framebuffer->fb_address, framebuffer, candidates[bestIndex].channel); } - // Removes old textures. void TextureCacheCommon::Decimate(bool forcePressure) { if (--decimationCounter_ <= 0) { @@ -737,6 +736,7 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram switch (msg) { case NOTIFY_FB_CREATED: case NOTIFY_FB_UPDATED: + { // Try to match the new framebuffer to existing textures. // Backwards from the "usual" texturing case so can't share a utility function. @@ -748,11 +748,15 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram fbCache_.push_back(framebuffer); } + std::vector candidates; + // TODO: Rework this to not try to "apply" all matches, only the best one. for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { TexCacheEntry *entry = it->second.get(); FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); - ApplyFramebufferMatch(match, entry, addr, framebuffer, channel); + if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { + candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); + } } // Let's assume anything in mirrors is fair game to check. @@ -763,11 +767,17 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram if (mirrorlessKey >= cacheKey && mirrorlessKey <= cacheKeyEnd) { TexCacheEntry *entry = it->second.get(); FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); - ApplyFramebufferMatch(match, entry, addr, framebuffer, channel); + if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { + candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); + } } } - break; + if (!candidates.empty()) { + AttachBestCandidate(candidates); + } + break; + } case NOTIFY_FB_DESTROYED: fbCache_.erase(std::remove(fbCache_.begin(), fbCache_.end(), framebuffer), fbCache_.end()); diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index f699e55026..630ef43fa9 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -207,6 +207,13 @@ struct FramebufferMatchInfo { u32 yOffset; }; +struct AttachCandidate { + FramebufferMatchInfo match; + TexCacheEntry *entry; + VirtualFramebuffer *fb; + FramebufferNotificationChannel channel; +}; + class TextureCacheCommon { public: TextureCacheCommon(Draw::DrawContext *draw); @@ -278,6 +285,7 @@ protected: // Temporary utility during conversion bool ApplyFramebufferMatch(FramebufferMatchInfo match, TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel); + bool AttachBestCandidate(const std::vector &candidates); void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); From eda4bb2341a1571bc9afa9f35e06827d27cb6d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 29 Aug 2020 22:36:07 +0200 Subject: [PATCH 602/848] Test Drive: Allow virtual framebuffer copies. This eliminates the hyper expensive readbacks. Write some comments in Depal about how we could get rid of the banding. --- GPU/Common/DepalettizeShaderCommon.cpp | 14 ++++++++++++-- assets/compat.ini | 6 ++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index e95691cc8e..d435d6ca28 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -80,10 +80,20 @@ void GenerateDepalShader300(char *buffer, GEBufferFormat pixelFormat, ShaderLang int shift = gstate.getClutIndexShift(); int offset = gstate.getClutIndexStartPos(); GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); - // Unfortunately sampling turned our texture into floating point. To avoid this, might be able + + // Sampling turns our texture into floating point. To avoid this, might be able // to declare them as isampler2D objects, but these require integer textures, which needs more work. - // Anyhow, we simply work around this by converting back to integer. Hopefully there will be no loss of precision. + // Anyhow, we simply work around this by converting back to integer, which is fine. // Use the mask to skip reading some components. + + // TODO: Since we actually have higher precision color data here, we might want to apply a dithering pattern here + // in the 5551, 565 and 4444 modes. This would benefit Test Drive which renders at 16-bit on the real hardware + // and dithers immediately, while we render at higher color depth and thus don't dither resulting in banding + // when we sample it at low color depth like this. + + // An alternative would be to have a special mode where we keep some extra precision here and sample the CLUT linearly - works for ramps such + // as those that Test Drive uses for its color remapping. But would need game specific flagging. + int shiftedMask = mask << shift; switch (pixelFormat) { case GE_FORMAT_8888: diff --git a/assets/compat.ini b/assets/compat.ini index 7826197a67..b07222ea85 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -538,6 +538,12 @@ ULJM05049 = true ULKS46027 = true ULAS42019 = true +# Test Drive Unlimited +ULET00386 = true +ULUS10249 = true +ULES00637 = true +ULKS46126 = true + # Note! This whole flag is disabled temporarily by appending "Disabled" to its name). See 7914 [YugiohSaveFixDisabled] # The cause of Yu-gi-oh series 's bad save (cannot save) are load "save status" and use cwcheat, From cdf11dffd1caee2461e18a114e350986661aac47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 30 Aug 2020 17:50:42 +0200 Subject: [PATCH 603/848] Shrink the "Cardboard VR Off" button. Got a complaint through email that it was so large it could be visible with the cardboard on, despite its location. --- UI/EmuScreen.cpp | 1 + UI/GameSettingsScreen.cpp | 7 ++++++- ext/native/ui/view.cpp | 11 ++++++++++- ext/native/ui/view.h | 6 ++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index b3557c076b..ba3cd45976 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1028,6 +1028,7 @@ void EmuScreen::CreateViews() { cardboardDisableButton_ = root_->Add(new Button(sc->T("Cardboard VR OFF"), new AnchorLayoutParams(bounds.centerX(), NONE, NONE, 30, true))); cardboardDisableButton_->OnClick.Handle(this, &EmuScreen::OnDisableCardboard); cardboardDisableButton_->SetVisibility(V_GONE); + cardboardDisableButton_->SetScale(0.65f); // make it smaller - this button can be in the way otherwise. if (g_Config.bEnableNetworkChat) { switch (g_Config.iChatButtonPosition) { diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 57a20f7ab7..d914255fa4 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -510,6 +510,12 @@ void GameSettingsScreen::CreateViews() { graphicsSettings->Add(new PopupMultiChoice(&g_Config.iBufFilter, gr->T("Screen Scaling Filter"), bufFilters, 1, ARRAY_SIZE(bufFilters), gr->GetName(), screenManager())); #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) + bool showCardboardSettings = true; +#else + // If you enabled it through the ini, you can see this. Useful for testing. + bool showCardboardSettings = g_Config.bEnableCardboardVR; +#endif + graphicsSettings->Add(new ItemHeader(gr->T("Cardboard VR Settings", "Cardboard VR Settings"))); graphicsSettings->Add(new CheckBox(&g_Config.bEnableCardboardVR, gr->T("Enable Cardboard VR", "Enable Cardboard VR"))); PopupSliderChoice *cardboardScreenSize = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardScreenSize, 30, 100, gr->T("Cardboard Screen Size", "Screen Size (in % of the viewport)"), 1, screenManager(), gr->T("% of viewport"))); @@ -518,7 +524,6 @@ void GameSettingsScreen::CreateViews() { cardboardXShift->SetEnabledPtr(&g_Config.bEnableCardboardVR); PopupSliderChoice *cardboardYShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardYShift, -100, 100, gr->T("Cardboard Screen Y Shift", "Y Shift (in % of the void)"), 1, screenManager(), gr->T("% of the void"))); cardboardYShift->SetEnabledPtr(&g_Config.bEnableCardboardVR); -#endif std::vector cameraList = Camera::getDeviceList(); if (cameraList.size() >= 1) { diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 252dd60b79..849ec8947a 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -702,6 +702,9 @@ void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const // Add some internal padding to not look totally ugly w += paddingW_; h += paddingH_; + + w *= scale_; + h *= scale_; } void Button::Click() { @@ -720,12 +723,16 @@ void Button::Draw(UIContext &dc) { DrawBG(dc, style); float tw, th; dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, text_.c_str(), &tw, &th); + tw *= scale_; + th *= scale_; + if (tw > bounds_.w || imageID_.isValid()) { dc.PushScissor(bounds_); } dc.SetFontStyle(dc.theme->uiFont); + dc.SetFontScale(scale_, scale_); if (imageID_.isValid() && text_.empty()) { - dc.Draw()->DrawImage(imageID_, bounds_.centerX(), bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); + dc.Draw()->DrawImage(imageID_, bounds_.centerX(), bounds_.centerY(), scale_, 0xFFFFFFFF, ALIGN_CENTER); } else if (!text_.empty()) { dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER); if (imageID_.isValid()) { @@ -735,6 +742,8 @@ void Button::Draw(UIContext &dc) { } } } + dc.SetFontScale(1.0f, 1.0f); + if (tw > bounds_.w || imageID_.isValid()) { dc.PopScissor(); } diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index 0f0976b12f..b21d82076d 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -527,12 +527,18 @@ public: paddingH_ = h; } + // Needed an extra small button... + void SetScale(float f) { + scale_ = f; + } + private: Style style_; std::string text_; ImageID imageID_; int paddingW_ = 16; int paddingH_ = 8; + float scale_ = 1.0f; }; class Slider : public Clickable { From e0d797a9be8b2231bc10cf6e9d71616cc071269e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 30 Aug 2020 22:43:13 +0200 Subject: [PATCH 604/848] Forgot the if, oops. --- UI/GameSettingsScreen.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index d914255fa4..0e248c2981 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -515,15 +515,16 @@ void GameSettingsScreen::CreateViews() { // If you enabled it through the ini, you can see this. Useful for testing. bool showCardboardSettings = g_Config.bEnableCardboardVR; #endif - - graphicsSettings->Add(new ItemHeader(gr->T("Cardboard VR Settings", "Cardboard VR Settings"))); - graphicsSettings->Add(new CheckBox(&g_Config.bEnableCardboardVR, gr->T("Enable Cardboard VR", "Enable Cardboard VR"))); - PopupSliderChoice *cardboardScreenSize = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardScreenSize, 30, 100, gr->T("Cardboard Screen Size", "Screen Size (in % of the viewport)"), 1, screenManager(), gr->T("% of viewport"))); - cardboardScreenSize->SetEnabledPtr(&g_Config.bEnableCardboardVR); - PopupSliderChoice *cardboardXShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardXShift, -100, 100, gr->T("Cardboard Screen X Shift", "X Shift (in % of the void)"), 1, screenManager(), gr->T("% of the void"))); - cardboardXShift->SetEnabledPtr(&g_Config.bEnableCardboardVR); - PopupSliderChoice *cardboardYShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardYShift, -100, 100, gr->T("Cardboard Screen Y Shift", "Y Shift (in % of the void)"), 1, screenManager(), gr->T("% of the void"))); - cardboardYShift->SetEnabledPtr(&g_Config.bEnableCardboardVR); + if (showCardboardSettings) { + graphicsSettings->Add(new ItemHeader(gr->T("Cardboard VR Settings", "Cardboard VR Settings"))); + graphicsSettings->Add(new CheckBox(&g_Config.bEnableCardboardVR, gr->T("Enable Cardboard VR", "Enable Cardboard VR"))); + PopupSliderChoice *cardboardScreenSize = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardScreenSize, 30, 100, gr->T("Cardboard Screen Size", "Screen Size (in % of the viewport)"), 1, screenManager(), gr->T("% of viewport"))); + cardboardScreenSize->SetEnabledPtr(&g_Config.bEnableCardboardVR); + PopupSliderChoice *cardboardXShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardXShift, -100, 100, gr->T("Cardboard Screen X Shift", "X Shift (in % of the void)"), 1, screenManager(), gr->T("% of the void"))); + cardboardXShift->SetEnabledPtr(&g_Config.bEnableCardboardVR); + PopupSliderChoice *cardboardYShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardYShift, -100, 100, gr->T("Cardboard Screen Y Shift", "Y Shift (in % of the void)"), 1, screenManager(), gr->T("% of the void"))); + cardboardYShift->SetEnabledPtr(&g_Config.bEnableCardboardVR); + } std::vector cameraList = Camera::getDeviceList(); if (cameraList.size() >= 1) { From 064f2b6d01788fe74327b033748efe8aa97e7657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 31 Aug 2020 09:42:15 +0200 Subject: [PATCH 605/848] Add some ONCE-reporting of multiple candidate situations --- GPU/Common/TextureCacheCommon.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index bad64c09bf..6f37473836 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -86,6 +86,15 @@ // GL_UNSIGNED_BYTE/RGBA: AAAAAAAABBBBBBBBGGGGGGGGRRRRRRRR (match) // These are Data::Format:: B4G4R4A4_PACK16, B5G6R6_PACK16, B5G5R5A1_PACK16, R8G8B8A8 +// Allow the extra bits from the remasters for the purposes of this. +inline int dimWidth(u16 dim) { + return 1 << (dim & 0xFF); +} + +inline int dimHeight(u16 dim) { + return 1 << ((dim >> 8) & 0xFF); +} + // Vulkan color formats: // TODO TextureCacheCommon::TextureCacheCommon(Draw::DrawContext *draw) @@ -579,9 +588,16 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA return false; } + if (candidates.size() > 1) { + bool depth = channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH; + WARN_LOG_REPORT_ONCE(multifbcandidate, G3D, "AttachFramebufferToEntry(%s): Multiple (%d) candidate framebuffers. texaddr: %08x offset: %d (%dx%d stride %d, %s)", + depth ? "DEPTH" : "COLOR", entry->addr, texAddrOffset, dimWidth(entry->dim), dimHeight(entry->dim), entry->bufw, GeTextureFormatToString((GETextureFormat)entry->format)); + } + return AttachBestCandidate(candidates); } +// reason is just used for reporting/logging. bool TextureCacheCommon::AttachBestCandidate(const std::vector &candidates) { _dbg_assert_(!candidates.empty()); @@ -774,6 +790,12 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram } if (!candidates.empty()) { + if (candidates.size() > 1) { + bool depth = channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH; + WARN_LOG_REPORT_ONCE(multitexcandidate, G3D, "NotifyFramebuffer(%s): Multiple (%d) candidate textures. fb addr: %08x (%dx%d stride %d, %s)", + depth ? "DEPTH" : "COLOR", (int)candidates.size(), addr, framebuffer->width, framebuffer->height, depth ? framebuffer->z_stride : framebuffer->fb_stride, GeBufferFormatToString(framebuffer->format)); + } + AttachBestCandidate(candidates); } break; From 5043f05687f0301a48e7e23bd2297120c15e4705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 31 Aug 2020 10:37:28 +0200 Subject: [PATCH 606/848] Oops, crashfix for late change --- GPU/Common/TextureCacheCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 6f37473836..efa80c93e0 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -591,7 +591,7 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA if (candidates.size() > 1) { bool depth = channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH; WARN_LOG_REPORT_ONCE(multifbcandidate, G3D, "AttachFramebufferToEntry(%s): Multiple (%d) candidate framebuffers. texaddr: %08x offset: %d (%dx%d stride %d, %s)", - depth ? "DEPTH" : "COLOR", entry->addr, texAddrOffset, dimWidth(entry->dim), dimHeight(entry->dim), entry->bufw, GeTextureFormatToString((GETextureFormat)entry->format)); + depth ? "DEPTH" : "COLOR", (int)candidates.size(), entry->addr, texAddrOffset, dimWidth(entry->dim), dimHeight(entry->dim), entry->bufw, GeTextureFormatToString((GETextureFormat)entry->format)); } return AttachBestCandidate(candidates); From 8b5530e626480855fb23b0ad230ef8bbdc68245d Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Tue, 1 Sep 2020 19:10:57 +0800 Subject: [PATCH 607/848] Reschedule after resuming thread from suspend. --- Core/HLE/sceKernelThread.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 5d5d4af02c..566d526d40 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2802,6 +2802,7 @@ int sceKernelResumeThread(SceUID threadID) // If it was dormant, waiting, etc. before we don't flip its ready state. if (t->nt.status == 0) __KernelChangeReadyState(t, threadID, true); + hleReSchedule("resume thread from suspend"); return 0; } else From a22181df1cc2761371f440229417b47c4e484a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 1 Sep 2020 00:05:37 +0200 Subject: [PATCH 608/848] Partially fix Katamari (flicker due to choice of the wrong depth buffer still happening). --- Common/Vulkan/VulkanImage.cpp | 14 +++++++ Common/Vulkan/VulkanImage.h | 1 + Core/MemMap.h | 7 +++- Core/MemMapFunctions.cpp | 4 -- GPU/Common/FramebufferManagerCommon.cpp | 2 +- GPU/Common/TextureCacheCommon.cpp | 54 +++++++++++++++---------- GPU/Vulkan/TextureCacheVulkan.cpp | 13 ++++-- 7 files changed, 65 insertions(+), 30 deletions(-) diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 1b856dcff2..2165221668 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -181,6 +181,20 @@ void VulkanTexture::UploadMip(VkCommandBuffer cmd, int mip, int mipWidth, int mi vkCmdCopyBufferToImage(cmd, buffer, image_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©_region); } +void VulkanTexture::ClearMip(VkCommandBuffer cmd, int mip, uint32_t value) { + // Must be in TRANSFER_DST mode. + VkClearColorValue clearVal; + for (int i = 0; i < 4; i++) { + clearVal.float32[i] = ((value >> (i * 8)) & 0xFF) / 255.0f; + } + VkImageSubresourceRange range{}; + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + range.layerCount = 1; + range.baseMipLevel = mip; + range.levelCount = 1; + vkCmdClearColorImage(cmd, image_, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearVal, 1, &range); +} + void VulkanTexture::GenerateMip(VkCommandBuffer cmd, int mip) { _assert_msg_(mip != 0, "Cannot generate the first level"); _assert_msg_(mip < numMips_, "Cannot generate mipmaps past the maximum created (%d vs %d)", mip, numMips_); diff --git a/Common/Vulkan/VulkanImage.h b/Common/Vulkan/VulkanImage.h index 2c809b2bdb..91e36dc977 100644 --- a/Common/Vulkan/VulkanImage.h +++ b/Common/Vulkan/VulkanImage.h @@ -19,6 +19,7 @@ public: // 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, 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 ClearMip(VkCommandBuffer cmd, int mip, uint32_t value); 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, VkImageLayout layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); diff --git a/Core/MemMap.h b/Core/MemMap.h index 40a6820698..d0cac9f082 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -255,7 +255,12 @@ inline void Write_Float(float f, u32 address) u8* GetPointer(const u32 address); bool IsRAMAddress(const u32 address); -bool IsVRAMAddress(const u32 address); +inline bool IsVRAMAddress(const u32 address) { + return ((address & 0x3F800000) == 0x04000000); +} +inline bool IsDepthTexVRAMAddress(const u32 address) { + return ((address & 0x3FE00000) == 0x04200000) || ((address & 0x3FE00000) == 0x04600000); +} bool IsScratchpadAddress(const u32 address); // Used for auto-converted char * parameters, which can sometimes legitimately be null - diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index 07f912b198..36903cdabb 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -112,10 +112,6 @@ bool IsRAMAddress(const u32 address) { } } -bool IsVRAMAddress(const u32 address) { - return ((address & 0x3F800000) == 0x04000000); -} - bool IsScratchpadAddress(const u32 address) { return (address & 0xBFFF0000) == 0x00010000 && (address & 0x0000FFFF) < SCRATCHPAD_SIZE; } diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index ab95f7de01..240b75f28e 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -489,7 +489,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged) { if (vfbFormatChanged) { textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb->z_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); if (vfb->drawnFormat != vfb->format) { ReformatFramebufferFrom(vfb, vfb->drawnFormat); } diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index efa80c93e0..7a4fc786eb 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -542,6 +542,9 @@ void TextureCacheCommon::SetTexture(bool force) { // Before we go reading the texture from memory, let's check for render-to-texture. // We must do this early so we have the right w/h. entry->framebuffer = nullptr; + if (Memory::IsDepthTexVRAMAddress(texaddr)) { + entry->status |= TexCacheEntry::STATUS_DEPTH; + } AttachFramebufferToEntry(entry, 0); @@ -566,7 +569,8 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { auto framebuffer = fbCache_[i]; - FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer->fb_address, framebuffer, texAddrOffset, channel); + uint32_t fb_addr = channel == NOTIFY_FB_DEPTH ? framebuffer->z_address : framebuffer->fb_address; + FramebufferMatchInfo match = MatchFramebuffer(entry, fb_addr, framebuffer, texAddrOffset, channel); if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); } else if (match.match == FramebufferMatch::IGNORE) { @@ -597,7 +601,6 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA return AttachBestCandidate(candidates); } -// reason is just used for reporting/logging. bool TextureCacheCommon::AttachBestCandidate(const std::vector &candidates) { _dbg_assert_(!candidates.empty()); @@ -628,7 +631,12 @@ bool TextureCacheCommon::AttachBestCandidate(const std::vector relevancy += 10; } - if (relevancy >= bestRelevancy) { + // Bonus points for no offset. + if (candidate.match.xOffset == 0 && candidate.match.yOffset == 0) { + relevancy += 9; + } + + if (relevancy > bestRelevancy) { bestRelevancy = relevancy; bestIndex = i; } @@ -825,6 +833,7 @@ void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFra if (!hasInvalidFramebuffer && !hasOlderFramebuffer) { // If it's valid, but the offset is greater, then we still win. + // TODO: This check should probably be moved to MatchFramebuffer somehow. if (fbTexInfo_[cachekey].yOffset == fbInfo.yOffset) hasFartherFramebuffer = fbTexInfo_[cachekey].xOffset > fbInfo.xOffset; else @@ -910,16 +919,16 @@ bool TextureCacheCommon::ApplyFramebufferMatch(FramebufferMatchInfo match, TexCa } } -FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const { +FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, u32 fb_address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const { static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32; const u32 mirrorMask = 0x00600000; - u32 addr = address & 0x3FFFFFFF; + u32 addr = fb_address & 0x3FFFFFFF; u32 texaddr = entry->addr + texaddrOffset; bool texInVRAM = Memory::IsVRAMAddress(texaddr); - bool fbInVRAM = Memory::IsVRAMAddress(framebuffer->fb_address); + bool fbInVRAM = Memory::IsVRAMAddress(fb_address); if (texInVRAM != fbInVRAM) { // Shortcut. Cannot possibly be a match. @@ -953,6 +962,7 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, addr &= ~mirrorMask; texaddr &= ~mirrorMask; } + const bool noOffset = texaddr == addr; const bool exactMatch = noOffset && entry->format < 4 && channel == NOTIFY_FB_COLOR; const u32 w = 1 << ((entry->dim >> 0) & 0xf); @@ -995,14 +1005,21 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, const bool clutFormat = IsClutFormat((GETextureFormat)(entry->format)); - const u32 bitOffset = (texaddr - addr) * 8; - const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry->format]); - // To avoid ruining git blame, kept the same name as the old struct. FramebufferMatchInfo fbInfo{ FramebufferMatch::VALID }; - fbInfo.yOffset = entry->bufw == 0 ? 0 : pixelOffset / entry->bufw; - fbInfo.xOffset = entry->bufw == 0 ? 0 : pixelOffset % entry->bufw; + const u32 bitOffset = (texaddr - addr) * 8; + if (bitOffset != 0) { + const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry->format]); + + fbInfo.yOffset = entry->bufw == 0 ? 0 : pixelOffset / entry->bufw; + fbInfo.xOffset = entry->bufw == 0 ? 0 : pixelOffset % entry->bufw; + } + + if (fbInfo.yOffset + minSubareaHeight >= framebuffer->height) { + // Can't be inside the framebuffer. + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; + } if (framebuffer->fb_stride != entry->bufw) { if (noOffset) { @@ -1021,15 +1038,10 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } - if (fbInfo.yOffset + minSubareaHeight >= framebuffer->height) { - // Can't be inside the framebuffer then, ram. Detach to be safe. - return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; - } - // Trying to play it safe. Below 0x04110000 is almost always framebuffers. // TODO: Maybe we can reduce this check and find a better way above 0x04110000? if (fbInfo.yOffset > MAX_SUBAREA_Y_OFFSET_SAFE && addr > 0x04110000) { - WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); + WARN_LOG_REPORT_ONCE(subareaIgnored, G3D, "Ignoring possible texturing from framebuffer at %08x +%dx%d / %dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset, framebuffer->width, framebuffer->height); return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } @@ -1037,7 +1049,7 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, // 3rd Birthday (and a bunch of other games) render to a 16 bit clut texture. if (matchingClutFormat) { if (!noOffset) { - WARN_LOG_ONCE(subareaClut, G3D, "Texturing from framebuffer using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); + WARN_LOG_ONCE(subareaClut, G3D, "Texturing from framebuffer using CLUT with offset at %08x +%dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset); } fbInfo.match = FramebufferMatch::VALID_DEPAL; return fbInfo; @@ -1050,17 +1062,17 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, if (framebuffer->format == entry->format || matchingClutFormat) { if (framebuffer->format != entry->format) { WARN_LOG_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", - GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); + GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), fb_address); return fbInfo; // Valid! } else { - WARN_LOG_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset); + WARN_LOG_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset); // If we return VALID here, God of War Ghost of Sparta/Chains of Olympus will be missing some special effect according to an old comment. fbInfo.match = FramebufferMatch::INVALID; return fbInfo; } } else { WARN_LOG_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", - GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), address); + GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), fb_address); return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } } diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index bf51e1f74e..93e39d87fd 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -1007,9 +1007,16 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { entry->vkTex->UploadMip(cmdInit, i, mipWidth, mipHeight, localBuf, localOffset, stride / bpp); } else { - data = drawEngine_->GetPushBufferForTextureData()->PushAligned(size, &bufferOffset, &texBuf, pushAlignment); - LoadTextureLevel(*entry, (uint8_t *)data, stride, i, scaleFactor, dstFmt); - entry->vkTex->UploadMip(cmdInit, i, mipWidth, mipHeight, texBuf, bufferOffset, stride / bpp); + // Don't even try to read depth data. + if (entry->status & TexCacheEntry::STATUS_DEPTH) { + // Clear with a warning value (hot pink). This should not be seen - means we missed matching a framebuffer + // that a game rendered depth to. + entry->vkTex->ClearMip(cmdInit, i, 0xFFFF00FF); + } else { + data = drawEngine_->GetPushBufferForTextureData()->PushAligned(size, &bufferOffset, &texBuf, pushAlignment); + LoadTextureLevel(*entry, (uint8_t *)data, stride, i, scaleFactor, dstFmt); + entry->vkTex->UploadMip(cmdInit, i, mipWidth, mipHeight, texBuf, bufferOffset, stride / bpp); + } } } if (replacer_.Enabled()) { From a1e5f1b052443b234534a4aa9d5a9db852760164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 1 Sep 2020 01:14:20 +0200 Subject: [PATCH 609/848] When going the other way, there can be multiple textures that need updating. --- GPU/Common/TextureCacheCommon.cpp | 13 ++++++------- GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp | 3 ++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 7a4fc786eb..d8c26f3243 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -804,7 +804,11 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram depth ? "DEPTH" : "COLOR", (int)candidates.size(), addr, framebuffer->width, framebuffer->height, depth ? framebuffer->z_stride : framebuffer->fb_stride, GeBufferFormatToString(framebuffer->format)); } - AttachBestCandidate(candidates); + // There can actually be multiple ones to update here! This can be the case where two textures point to different framebuffers that share depth buffers. + // So we have no choice but to run all the candidate matches. + for (int i = 0; i < (int)candidates.size(); i++) { + ApplyFramebufferMatch(candidates[i].match, candidates[i].entry, framebuffer->fb_address, framebuffer, candidates[i].channel); + } } break; } @@ -845,13 +849,11 @@ void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFra cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry); } ReleaseTexture(entry, true); + entry->framebuffer = framebuffer; entry->invalidHint = 0; entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; entry->maxLevel = 0; - if (channel == NOTIFY_FB_DEPTH) { - entry->status |= TexCacheEntry::STATUS_DEPTH; - } fbTexInfo_[cachekey] = fbInfo; framebuffer->last_frame_attached = gpuStats.numFlips; GPUDebug::NotifyTextureAttachment(entry->addr); @@ -873,9 +875,6 @@ void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualF entry->invalidHint = -1; entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; entry->maxLevel = 0; - if (channel == NOTIFY_FB_DEPTH) { - entry->status |= TexCacheEntry::STATUS_DEPTH; - } fbTexInfo_[cachekey] = fbInfo; GPUDebug::NotifyTextureAttachment(entry->addr); } diff --git a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp index 87920c52a7..05fdf3a4a9 100644 --- a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp @@ -195,7 +195,8 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer, uint32_ } } else { if (doTextureProjection) { - // We don't use textureProj because we need better control and it's probably not much of a savings anyway. + // We don't use textureProj because we need to manually offset from the divided coordinate to do filtering here. + // On older hardware it has the advantage of higher resolution math, but such old hardware can't run Vulkan. 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); From 5697b6a9c582914357c94e764ae3620dfa6658a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 1 Sep 2020 23:04:16 +0200 Subject: [PATCH 610/848] Look in the mirrors or not depending on whether the texture's address is in the mirrors (detected as a depth texture). Also removes reporting that no longer makes sense. --- GPU/Common/TextureCacheCommon.cpp | 38 ++++++++++++++----------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index d8c26f3243..73c8a5b918 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -775,37 +775,33 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram std::vector candidates; // TODO: Rework this to not try to "apply" all matches, only the best one. - for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { - TexCacheEntry *entry = it->second.get(); - FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); - if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { - candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); - } - } - - // Let's assume anything in mirrors is fair game to check. - // TODO: Only do this for depth? - for (auto it = cache_.lower_bound(mirrorCacheKey), end = cache_.upper_bound(mirrorCacheKeyEnd); it != end; ++it) { - const u64 mirrorlessKey = it->first & ~0x0060000000000000ULL; - // Let's still make sure it's in the cache range. - if (mirrorlessKey >= cacheKey && mirrorlessKey <= cacheKeyEnd) { + if (channel == FramebufferNotificationChannel::NOTIFY_FB_COLOR) { + // Color - no need to look in the mirrors. + for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { TexCacheEntry *entry = it->second.get(); FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); } } + } else { + // Depth. Just look in the mirrors. + for (auto it = cache_.lower_bound(mirrorCacheKey), end = cache_.upper_bound(mirrorCacheKeyEnd); it != end; ++it) { + const u64 mirrorlessKey = it->first & ~0x0060000000000000ULL; + // Let's still make sure it's in the cache range. + if (mirrorlessKey >= cacheKey && mirrorlessKey <= cacheKeyEnd) { + TexCacheEntry *entry = it->second.get(); + FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); + if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { + candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); + } + } + } } if (!candidates.empty()) { - if (candidates.size() > 1) { - bool depth = channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH; - WARN_LOG_REPORT_ONCE(multitexcandidate, G3D, "NotifyFramebuffer(%s): Multiple (%d) candidate textures. fb addr: %08x (%dx%d stride %d, %s)", - depth ? "DEPTH" : "COLOR", (int)candidates.size(), addr, framebuffer->width, framebuffer->height, depth ? framebuffer->z_stride : framebuffer->fb_stride, GeBufferFormatToString(framebuffer->format)); - } - // There can actually be multiple ones to update here! This can be the case where two textures point to different framebuffers that share depth buffers. - // So we have no choice but to run all the candidate matches. + // So we have no choice but to run all the matches. for (int i = 0; i < (int)candidates.size(); i++) { ApplyFramebufferMatch(candidates[i].match, candidates[i].entry, framebuffer->fb_address, framebuffer, candidates[i].channel); } From f13c69a0e18ce3da5eb2a2f36d662ff150a8a7ba Mon Sep 17 00:00:00 2001 From: sum2012 Date: Wed, 2 Sep 2020 20:26:45 +0800 Subject: [PATCH 611/848] Add a check in sceKernelTerminateThread https://github.com/jpcsp/jpcsp/blob/master/src/jpcsp/HLE/modules/ThreadManForUser.java#L3971 --- Core/HLE/sceKernelThread.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 566d526d40..c0b249f810 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2337,6 +2337,8 @@ int sceKernelTerminateThread(SceUID threadID) { if (__IsInInterrupt() && sceKernelGetCompiledSdkVersion() >= 0x03080000) { return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_CONTEXT, "in interrupt"); } + if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() >= 0x03080000) + return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_CAN_NOT_WAIT); if (threadID == 0 || threadID == currentThread) { return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_THID, "cannot terminate current thread"); } From f5937d0c6a3b69ed212bf77a6e289b6954e79ecc Mon Sep 17 00:00:00 2001 From: sum2012 Date: Wed, 2 Sep 2020 20:31:06 +0800 Subject: [PATCH 612/848] Use >= 0x03080000 instead of 0x0307FFFF --- Core/HLE/sceKernelThread.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index c0b249f810..59b3ec3c7e 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2149,7 +2149,7 @@ void __KernelReturnFromThread() } int sceKernelExitThread(int exitStatus) { - if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() > 0x0307FFFF) + if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() >= 0x03080000) return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_CAN_NOT_WAIT); PSPThread *thread = __GetCurrentThread(); _dbg_assert_msg_(thread != NULL, "Exited from a NULL thread."); @@ -2185,7 +2185,7 @@ void _sceKernelExitThread(int exitStatus) { } int sceKernelExitDeleteThread(int exitStatus) { - if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() > 0x0307FFFF) + if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() >= 0x03080000) return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_CAN_NOT_WAIT); PSPThread *thread = __GetCurrentThread(); if (thread) @@ -2304,7 +2304,7 @@ int sceKernelTerminateDeleteThread(int threadID) ERROR_LOG(SCEKERNEL, "sceKernelTerminateDeleteThread(%i): cannot terminate current thread", threadID); return SCE_KERNEL_ERROR_ILLEGAL_THID; } - if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() > 0x0307FFFF) + if (!__KernelIsDispatchEnabled() && sceKernelGetCompiledSdkVersion() >= 0x03080000) return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_CAN_NOT_WAIT); u32 error; From a76a5bdf5659ef771fae04b7f72106722c92e0a8 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 2 Sep 2020 00:21:44 +0700 Subject: [PATCH 613/848] Ignores the 1st byte of MAC address when comparing, since there might be games (ie. Gran Turismo) that tries to tamper/change the 1st byte during multiplayer upon use. --- Core/HLE/proAdhoc.cpp | 17 +++++++++++------ Core/HLE/proAdhoc.h | 9 ++++++++- Core/HLE/sceNetAdhoc.cpp | 6 +++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index ec348035e8..bab95ae287 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -83,11 +83,16 @@ SockAddrIN4 g_localhostIP; sockaddr LocalIP; int defaultWlanChannel = PSP_SYSTEMPARAM_ADHOC_CHANNEL_1; // Don't put 0(Auto) here, it needed to be a valid/actual channel number +bool isMacMatch(const SceNetEtherAddr* addr1, const SceNetEtherAddr* addr2) { + // Ignoring the 1st byte since there are games (ie. Gran Turismo) who tamper with the 1st byte (as some kind of protection?). Using only the last 4-bytes might be sufficient tho, since the first 3-bytes are manufacturer Id. + return (memcmp(((const char*)addr1)+1, ((const char*)addr2)+1, ETHER_ADDR_LEN-1) == 0); +} + bool isLocalMAC(const SceNetEtherAddr * addr) { SceNetEtherAddr saddr; getLocalMac(&saddr); - return (memcmp((const void*)addr, (const void*)&saddr, ETHER_ADDR_LEN) == 0); + return isMacMatch(addr, &saddr); } bool isPDPPortInUse(uint16_t port) { @@ -193,7 +198,7 @@ SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC) { // Iterate Friends for (; peer != NULL; peer = peer->next) { - if (IsMatch(peer->mac_addr, *MAC)) break; + if (isMacMatch(&peer->mac_addr, MAC)) break; } // Return found friend @@ -262,7 +267,7 @@ SceNetAdhocctlScanInfo * findGroup(SceNetEtherAddr * MAC) { // Iterate Groups for (; group != NULL; group = group->next) { - if (IsMatch(group->bssid.mac_addr, *MAC)) break; + if (isMacMatch(&group->bssid.mac_addr, MAC)) break; } // Return found group @@ -533,7 +538,7 @@ SceNetAdhocMatchingMemberInternal * findPeer(SceNetAdhocMatchingContext * contex for (; peer != NULL; peer = peer->next) { // Found Peer in List - if (memcmp(&peer->mac, mac, sizeof(SceNetEtherAddr)) == 0) + if (isMacMatch(&peer->mac, mac)) { // Return Peer Pointer return peer; @@ -1958,7 +1963,7 @@ bool resolveMAC(SceNetEtherAddr * mac, uint32_t * ip) { SceNetEtherAddr localMac; getLocalMac(&localMac); // Local MAC Requested - if (memcmp(&localMac, mac, sizeof(SceNetEtherAddr)) == 0) { + if (isMacMatch(&localMac, mac)) { // Get Local IP Address sockaddr_in sockAddr; getLocalIp(&sockAddr); @@ -1975,7 +1980,7 @@ bool resolveMAC(SceNetEtherAddr * mac, uint32_t * ip) { // Iterate Peers for (; peer != NULL; peer = peer->next) { // Found Matching Peer - if (memcmp(&peer->mac_addr, mac, sizeof(SceNetEtherAddr)) == 0) { + if (isMacMatch(&peer->mac_addr, mac)) { // Copy Data *ip = peer->ip_addr; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 7866f8a20e..26020f1ae1 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -857,10 +857,17 @@ bool SetMatchingInCallback(SceNetAdhocMatchingContext* context, bool IsInCB); int IsAdhocctlInCallback(); int SetAdhocctlInCallback(bool IsInCB); +/** + * Compare MAC Addresses + * @param addr1 & addr2 To-be-compared MAC Address + * @return True if both matched + */ +bool isMacMatch(const SceNetEtherAddr* addr1, const SceNetEtherAddr* addr2); + /** * Local MAC Check * @param saddr To-be-checked MAC Address - * @return 1 if valid or... 0 + * @return True if it's local mac */ bool isLocalMAC(const SceNetEtherAddr * addr); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 8c559e689a..33679ef822 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1381,7 +1381,7 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { getLocalMac(&localmac); // Local MAC Matches - if (memcmp(&localmac, mac, sizeof(SceNetEtherAddr)) == 0) + if (isMacMatch(&localmac, (const SceNetEtherAddr*)mac)) { // Write Data *nickname = parameter.nickname; @@ -1402,7 +1402,7 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { for (; peer != NULL; peer = peer->next) { // Match found - if (memcmp(&peer->mac_addr, mac, sizeof(SceNetEtherAddr)) == 0) + if (isMacMatch(&peer->mac_addr, (const SceNetEtherAddr*)mac)) { // Write Data *nickname = peer->nickname; @@ -3800,7 +3800,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) } int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u32 dataAddr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x)", matchingId, mac2str((SceNetEtherAddr*)mac).c_str(), dataLen, dataAddr); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)mac).c_str(), dataLen, dataAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) return -1; From 9c5f02fbf5c4d467718989662709c106f40e325e Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 2 Sep 2020 03:33:06 +0700 Subject: [PATCH 614/848] Default to P2P/Parent's MAC address if the target MAC on sceNetAdhocMatchingSendData is 00:00:00:00:00:00 (need to confirm whether this is correct or an error should be returned instead) --- Core/HLE/proAdhoc.cpp | 6 +++- Core/HLE/proAdhoc.h | 7 ++++ Core/HLE/sceNetAdhoc.cpp | 72 +++++++++++++++++++++++++++++----------- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index bab95ae287..34f9c5510a 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -84,7 +84,7 @@ sockaddr LocalIP; int defaultWlanChannel = PSP_SYSTEMPARAM_ADHOC_CHANNEL_1; // Don't put 0(Auto) here, it needed to be a valid/actual channel number bool isMacMatch(const SceNetEtherAddr* addr1, const SceNetEtherAddr* addr2) { - // Ignoring the 1st byte since there are games (ie. Gran Turismo) who tamper with the 1st byte (as some kind of protection?). Using only the last 4-bytes might be sufficient tho, since the first 3-bytes are manufacturer Id. + // Ignoring the 1st byte since there are games (ie. Gran Turismo) who tamper with the 1st byte of OUI to change the unicast/multicast bit return (memcmp(((const char*)addr1)+1, ((const char*)addr2)+1, ETHER_ADDR_LEN-1) == 0); } @@ -1916,6 +1916,10 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ } } +bool isZeroMAC(const SceNetEtherAddr* addr) { + return (memcmp(addr->data, "\x00\x00\x00\x00\x00\x00", ETHER_ADDR_LEN) == 0); +} + bool isBroadcastMAC(const SceNetEtherAddr * addr) { return (memcmp(addr->data, "\xFF\xFF\xFF\xFF\xFF\xFF", ETHER_ADDR_LEN) == 0); } diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 26020f1ae1..3f6fd7af59 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -1253,6 +1253,13 @@ int getPTPSocketCount(); */ int initNetwork(SceNetAdhocctlAdhocId *adhocid); +/** + * Zero MAC Check + * @param addr To-be-checked MAC Address + * @return true if MAC is all zeroes + */ +bool isZeroMAC(const SceNetEtherAddr* addr); + /** * Broadcast MAC Check * @param addr To-be-checked MAC Address diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 33679ef822..887f2aac3d 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -3799,6 +3799,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ID, "adhocmatching invalid id"); } +// Gran Turismo may replace the 1st bit of the 1st byte of MAC address's OUI with 0 (unicast bit), or replace the whole 6-bytes of MAC address with all 00 (invalid mac) for unknown reason int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u32 dataAddr) { WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)mac).c_str(), dataLen, dataAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) @@ -3819,23 +3820,59 @@ int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u3 // Running Context if (context->running) { - // Find Target Peer - SceNetAdhocMatchingMemberInternal * peer = findPeer(context, (SceNetEtherAddr *)mac); + // Invalid Data Length + if (dataLen <=0 || dataAddr == 0) + // Invalid Data Length + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_DATALEN, "invalid datalen"); - // Found Peer - if (peer != NULL) - { - void * data = NULL; - if (Memory::IsValidAddress(dataAddr)) data = Memory::GetPointer(dataAddr); + void* data = NULL; + if (Memory::IsValidAddress(dataAddr)) data = Memory::GetPointer(dataAddr); - // Valid Data Length - if (dataLen > 0 && data != NULL) + // FIXME: If the target MAC is 00:00:00:00:00:00 (invalid mac) Should we default to P2P/Parent's MAC or return an Error? + if (isZeroMAC((const SceNetEtherAddr*)mac)) { + int sent = 0; + peerlock.lock(); + // Iterate Peer List for Matching Target + SceNetAdhocMatchingMemberInternal* peer = context->peerlist; + for (; peer != NULL; peer = peer->next) + { + // Valid Peer Connection State + if (peer->state == PSP_ADHOC_MATCHING_PEER_PARENT || peer->state == PSP_ADHOC_MATCHING_PEER_P2P) + { + // Skip Busy peers + if (peer->sending) + continue; + + // Mark Peer as Sending + peer->sending = 1; + + // Send Data to Peer + sendBulkData(context, peer, dataLen, data); + sent++; + break; + } + } + peerlock.unlock(); + + if (sent == 0) + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET, "invalid target"); + + // Return Success + return 0; + } + else { + // Find Target Peer + SceNetAdhocMatchingMemberInternal* peer = findPeer(context, (SceNetEtherAddr*)mac); + + // Found Peer + if (peer != NULL) { // Valid Peer Connection State if (peer->state == PSP_ADHOC_MATCHING_PEER_PARENT || peer->state == PSP_ADHOC_MATCHING_PEER_CHILD || peer->state == PSP_ADHOC_MATCHING_PEER_P2P) { // Send in Progress - if (peer->sending) return ERROR_NET_ADHOC_MATCHING_DATA_BUSY; + if (peer->sending) + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_DATA_BUSY, "data busy"); // Mark Peer as Sending peer->sending = 1; @@ -3848,31 +3885,28 @@ int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u3 } // Not connected / accepted - return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_ESTABLISHED, "adhocmatching not established"); + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_ESTABLISHED, "not established"); } - - // Invalid Data Length - return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_DATALEN, "adhocmatching invalid datalen"); } // Peer not found - return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET, "adhocmatching unknown target"); + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_UNKNOWN_TARGET, "unknown target"); } // Context not running - return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_RUNNING, "adhocmatching not running"); + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_RUNNING, "not running"); } // Invalid Matching ID - return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ID, "adhocmatching invalid id"); + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ID, "invalid id"); } // Invalid Arguments - return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "adhocmatching invalid arg"); + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_INVALID_ARG, "invalid arg"); } // Uninitialized Library - return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED, "adhocmatching not initialized"); + return hleLogError(SCENET, ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED, "not initialized"); } int sceNetAdhocMatchingAbortSendData(int matchingId, const char *mac) { From ca059bc9626e0dfd208305f3d5472545f0f0f30b Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 2 Sep 2020 21:42:16 +0700 Subject: [PATCH 615/848] Making sure the 1st 2-bits on the 1st byte of MAC address' OUI are zero to prevent issue with some games (ie. Gran Turismo) --- Core/Config.cpp | 4 ++++ Core/HLE/proAdhoc.cpp | 3 +++ Core/HLE/sceNet.cpp | 2 ++ 3 files changed, 9 insertions(+) diff --git a/Core/Config.cpp b/Core/Config.cpp index 1a8fc70027..3164c9af9b 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -378,6 +378,10 @@ std::string CreateRandMAC() { srand(time(nullptr)); for (int i = 0; i < 6; i++) { u32 value = rand() % 256; + if (i == 0) { + // Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo) + value &= 0xfc; + } if (value <= 15) randStream << '0' << std::hex << value; else diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 34f9c5510a..b5f3a76662 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1668,10 +1668,13 @@ void getLocalMac(SceNetEtherAddr * addr){ uint8_t mac[ETHER_ADDR_LEN] = {0}; if (PPSSPP_ID > 1) { memset(&mac, PPSSPP_ID, sizeof(mac)); + // Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo) + mac[0] &= 0xfc; } else if (!ParseMacAddress(g_Config.sMACAddress.c_str(), mac)) { ERROR_LOG(SCENET, "Error parsing mac address %s", g_Config.sMACAddress.c_str()); + memset(&mac, 0, sizeof(mac)); } memcpy(addr, mac, ETHER_ADDR_LEN); } diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 0b4d7ffd29..42c70cecec 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -609,6 +609,8 @@ static u32 sceWlanGetEtherAddr(u32 addrAddr) { u8 *addr = Memory::GetPointer(addrAddr); if (PPSSPP_ID > 1) { Memory::Memset(addrAddr, PPSSPP_ID, 6); + // Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo) + addr[0] &= 0xfc; } else // Read MAC Address from config From 577209752e12e1fb19f8e7726541b7ac8c8377a7 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 2 Sep 2020 06:25:47 +0700 Subject: [PATCH 616/848] An attempt to fix sceNetAdhocPollSocket to works properly. This fixes one of the multiplayer mode on Bleach Heat the Soul 7 --- Core/HLE/sceNetAdhoc.cpp | 49 +++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 887f2aac3d..36375b5174 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -851,7 +851,7 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Flags seems to be bitmasks of ADHOC_F_ALERT... int sceNetAdhocSetSocketAlert(int id, int flag) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocSetSocketAlert(%d, %08x)", id, flag); + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocSetSocketAlert(%d, %08x) at %08x", id, flag, currentMIPS->pc); return 0; //Dummy Result } @@ -872,7 +872,8 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb for (int i = 0; i < count; i++) { // Invalid Socket - if (sds[i].id < 1 || sds[i].id > 255 || (pdp[sds[i].id - 1] == NULL && ptp[sds[i].id - 1] == NULL)) return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + if (sds[i].id < 1 || sds[i].id > 255 || (pdp[sds[i].id - 1] == NULL && ptp[sds[i].id - 1] == NULL)) + return hleLogDebug(SCENET, ERROR_NET_ADHOC_INVALID_SOCKET_ID, "invalid socket id"); } // Nonblocking Mode @@ -894,6 +895,7 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb //WSAPoll only available for Vista or newer, so we'll use an alternative way for XP since Windows doesn't have poll function like *NIX fd_set readfds, writefds, exceptfds; int fd; + int maxfd = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); // TODO: PDP and PTP should share the same indexing to prevent identical PDP & PTP socket id for (int i = 0; i < count; i++) { @@ -908,15 +910,17 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb else { fd = pdp[sds[i].id - 1]->id; } + if (fd > maxfd) maxfd = fd; if (sds[i].events & ADHOC_EV_RECV) FD_SET(fd, &readfds); - if (sds[i].events & ADHOC_EV_SEND) FD_SET(fd, &writefds); + //if (sds[i].events & ADHOC_EV_SEND) + FD_SET(fd, &writefds); // Data can always be sent regardless of events bitmask? //if (sds[i].events & ADHOC_EV_ALERT) - FD_SET(fd, &exceptfds); + FD_SET(fd, &exceptfds); // can be raised on revents regardless of events bitmask? } timeval tmout; tmout.tv_sec = timeout / 1000000; // seconds tmout.tv_usec = (timeout % 1000000); // microseconds - affectedsockets = select(count, &readfds, &writefds, &exceptfds, &tmout); + affectedsockets = select(maxfd + 1, &readfds, &writefds, &exceptfds, &tmout); if (affectedsockets > 0) { affectedsockets = 0; for (int i = 0; i < count; i++) { @@ -926,38 +930,37 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb else { fd = pdp[sds[i].id - 1]->id; } - if (FD_ISSET(fd, &readfds)) sds[i].revents |= ADHOC_EV_RECV; - if (FD_ISSET(fd, &writefds)) sds[i].revents |= ADHOC_EV_SEND; // Data can always be sent ? + if (FD_ISSET(fd, &readfds)) + sds[i].revents |= ADHOC_EV_RECV; sds[i].revents &= sds[i].events; - if (FD_ISSET(fd, &exceptfds)) sds[i].revents |= ADHOC_EV_ALERT; // can be raised on revents regardless of events bitmask? + if (FD_ISSET(fd, &writefds)) + sds[i].revents |= ADHOC_EV_SEND; // Data can always be sent regardless of events bitmask? + if (FD_ISSET(fd, &exceptfds)) + sds[i].revents |= ADHOC_EV_ALERT; // can be raised on revents regardless of events bitmask? if (sds[i].revents) affectedsockets++; } } // Free Network Lock //freeNetworkLock(); - // Blocking Mode (Nonblocking Mode returns 0, even on Success) - if (!nonblock) - { - // Success - if (affectedsockets >= 0) return affectedsockets; // (affectedsockets > 0) - - // Timeout - return ERROR_NET_ADHOC_TIMEOUT; - } - // No Events generated - if (affectedsockets >= 0) return 0; + // Non-blocking mode + // Bleach 7 seems to use nonblocking and check the return value > 0, or 0x80410709 (ERROR_NET_ADHOC_WOULD_BLOCK), also 0x80410717 (ERROR_NET_ADHOC_EXCEPTION_EVENT) + if (affectedsockets > 0) + return hleLogDebug(SCENET, affectedsockets, "success"); - return ERROR_NET_ADHOC_WOULD_BLOCK; // Bleach 7 seems to use nonblocking and check the return value against 0 and 0x80410709 (also 0x80410717 ?) + else if (affectedsockets == 0) + return hleLogDebug(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block"); + + return hleLogDebug(SCENET, ERROR_NET_ADHOC_EXCEPTION_EVENT, "exception event"); } // Invalid Argument - return ERROR_NET_ADHOC_INVALID_ARG; + return hleLogDebug(SCENET, ERROR_NET_ADHOC_INVALID_ARG, "invalid arg"); } // Library is uninitialized - return ERROR_NET_ADHOC_NOT_INITIALIZED; + return hleLogDebug(SCENET, ERROR_NET_ADHOC_NOT_INITIALIZED, "adhoc not initialized"); } int NetAdhocPdp_Delete(int id, int unknown) { @@ -2859,7 +2862,7 @@ static int sceNetAdhocGameModeDeleteReplica(int id) { } int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGetSocketAlert(%i, %08x)", id, flagPtr); + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGetSocketAlert(%i, %08x) at %08x", id, flagPtr, currentMIPS->pc); // Dummy Value if (Memory::IsValidAddress(flagPtr)) { From 405863c579c5f49f702aa6b5565f65b7e2c2e5d6 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 2 Sep 2020 16:19:10 +0700 Subject: [PATCH 617/848] An attempt to make PDP and PTP ID to be unique so they can be polled properly together without getting conflicted ID. This fixes Gran Turismo. --- Core/HLE/sceNetAdhoc.cpp | 54 +++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 36375b5174..498f8205d3 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -394,7 +394,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u UPnP_Add(IP_PROTOCOL_UDP, isOriPort ? port : port + portOffset, port + portOffset); // g_PortManager.Add(IP_PROTOCOL_UDP, isOriPort ? port : port + portOffset, port + portOffset); // Success - return i + 1; + return i + 256; } // Free Memory for Internal Data @@ -497,9 +497,9 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Valid Data Length if (len >= 0) { // should we allow 0 size packet (for ping) ? // Valid Socket ID - if (id > 0 && id <= 255 && pdp[id - 1] != NULL) { + if (id > 255 && id <= 510 && pdp[id - 256] != NULL) { // Cast Socket - SceNetAdhocPdpStat * socket = pdp[id - 1]; + SceNetAdhocPdpStat * socket = pdp[id - 256]; // Valid Data Buffer if (data != NULL) { @@ -675,9 +675,9 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * int * len = (int *)dataLength; if (netAdhocInited) { // Valid Socket ID - if (id > 0 && id <= 255 && pdp[id - 1] != NULL) { + if (id > 255 && id <= 510 && pdp[id - 256] != NULL) { // Cast Socket - SceNetAdhocPdpStat * socket = pdp[id - 1]; + SceNetAdhocPdpStat * socket = pdp[id - 256]; // Valid Arguments if (saddr != NULL && port != NULL && buf != NULL && len != NULL && *len > 0) { @@ -857,8 +857,6 @@ int sceNetAdhocSetSocketAlert(int id, int flag) { } int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonblock) { // timeout in microseconds - DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocPollSocket(%08x, %i, %i, %i) at %08x", socketStructAddr, count, timeout, nonblock, currentMIPS->pc); - // Library is initialized if (netAdhocInited) { @@ -872,7 +870,7 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb for (int i = 0; i < count; i++) { // Invalid Socket - if (sds[i].id < 1 || sds[i].id > 255 || (pdp[sds[i].id - 1] == NULL && ptp[sds[i].id - 1] == NULL)) + if (sds[i].id < 1 || sds[i].id > 510 || (pdp[sds[i].id - 256] == NULL && ptp[sds[i].id - 1] == NULL)) return hleLogDebug(SCENET, ERROR_NET_ADHOC_INVALID_SOCKET_ID, "invalid socket id"); } @@ -901,21 +899,20 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb for (int i = 0; i < count; i++) { sds[i].revents = 0; // Fill in Socket ID - if (ptp[sds[i].id - 1] != NULL) { + if (sds[i].id <= 255 && ptp[sds[i].id - 1] != NULL) { fd = ptp[sds[i].id - 1]->id; if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_LISTEN) sds[i].revents |= ADHOC_EV_ACCEPT; else if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_CLOSED) sds[i].revents |= ADHOC_EV_CONNECT; } else { - fd = pdp[sds[i].id - 1]->id; + fd = pdp[sds[i].id - 256]->id; } if (fd > maxfd) maxfd = fd; if (sds[i].events & ADHOC_EV_RECV) FD_SET(fd, &readfds); - //if (sds[i].events & ADHOC_EV_SEND) - FD_SET(fd, &writefds); // Data can always be sent regardless of events bitmask? + if (sds[i].events & ADHOC_EV_SEND) FD_SET(fd, &writefds); // Does Data can always be sent regardless of events bitmask? //if (sds[i].events & ADHOC_EV_ALERT) - FD_SET(fd, &exceptfds); // can be raised on revents regardless of events bitmask? + FD_SET(fd, &exceptfds); // Does Alert can be raised on revents regardless of events bitmask? } timeval tmout; tmout.tv_sec = timeout / 1000000; // seconds @@ -924,19 +921,19 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb if (affectedsockets > 0) { affectedsockets = 0; for (int i = 0; i < count; i++) { - if (ptp[sds[i].id - 1] != NULL) { + if (sds[i].id <= 255 && ptp[sds[i].id - 1] != NULL) { fd = ptp[sds[i].id - 1]->id; } else { - fd = pdp[sds[i].id - 1]->id; + fd = pdp[sds[i].id - 256]->id; } if (FD_ISSET(fd, &readfds)) sds[i].revents |= ADHOC_EV_RECV; - sds[i].revents &= sds[i].events; if (FD_ISSET(fd, &writefds)) - sds[i].revents |= ADHOC_EV_SEND; // Data can always be sent regardless of events bitmask? + sds[i].revents |= ADHOC_EV_SEND; // Does Data can always be sent regardless of events bitmask? + sds[i].revents &= sds[i].events; if (FD_ISSET(fd, &exceptfds)) - sds[i].revents |= ADHOC_EV_ALERT; // can be raised on revents regardless of events bitmask? + sds[i].revents |= ADHOC_EV_ALERT; // Does Alert can be raised on revents regardless of events bitmask? if (sds[i].revents) affectedsockets++; } } @@ -945,11 +942,12 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb // No Events generated // Non-blocking mode - // Bleach 7 seems to use nonblocking and check the return value > 0, or 0x80410709 (ERROR_NET_ADHOC_WOULD_BLOCK), also 0x80410717 (ERROR_NET_ADHOC_EXCEPTION_EVENT) - if (affectedsockets > 0) - return hleLogDebug(SCENET, affectedsockets, "success"); - - else if (affectedsockets == 0) + // Bleach 7 seems to use nonblocking and check the return value > 0, or 0x80410709 (ERROR_NET_ADHOC_WOULD_BLOCK), also 0x80410717 (ERROR_NET_ADHOC_EXCEPTION_EVENT), when using prx files on JPCSP it can return 0 + if (affectedsockets >= 0) { + DEBUG_LOG(SCENET, "%08x=sceNetAdhocPollSocket(%08x, %i, %i, %i) at %08x", affectedsockets, socketStructAddr, count, timeout, nonblock, currentMIPS->pc); + return affectedsockets; + } + else if (nonblock && affectedsockets < 0) return hleLogDebug(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block"); return hleLogDebug(SCENET, ERROR_NET_ADHOC_EXCEPTION_EVENT, "exception event"); @@ -967,9 +965,9 @@ int NetAdhocPdp_Delete(int id, int unknown) { // Library is initialized if (netAdhocInited) { // Valid Arguments - if (id > 0 && id <= 255) { + if (id > 255 && id <= 510) { // Cast Socket - SceNetAdhocPdpStat* sock = pdp[id - 1]; + SceNetAdhocPdpStat* sock = pdp[id - 256]; // Valid Socket if (sock != NULL) { @@ -984,7 +982,7 @@ int NetAdhocPdp_Delete(int id, int unknown) { free(sock); // Free Translation Slot - pdp[id - 1] = NULL; + pdp[id - 256] = NULL; // Success return 0; @@ -1780,7 +1778,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { buf[i] = *pdp[j]; // Fix Client View Socket ID - buf[i].id = j + 1; + buf[i].id = j + 256; // Write End of List Reference buf[i].next = 0; @@ -2867,7 +2865,7 @@ int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { // Dummy Value if (Memory::IsValidAddress(flagPtr)) { s32_le * flag = (s32_le*)Memory::GetPointer(flagPtr); - *flag = 0; + *flag = 0; //ADHOC_F_ALERTALL } // Dummy Result From 804dd07c930416ace28a45ab98a91321a9a937fc Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 4 Sep 2020 01:32:15 +0700 Subject: [PATCH 618/848] An attempt to sort AdhocMatching Member List in order to make a consistent list on all players (based on Host). Also fixed some disconnection issue on other players when a player is leaving the room on Gran Turismo and Patapon 3. --- Core/HLE/proAdhoc.cpp | 76 +++++++++++++-------- Core/HLE/proAdhoc.h | 6 +- Core/HLE/sceNetAdhoc.cpp | 138 ++++++++++++++++++++++++--------------- 3 files changed, 134 insertions(+), 86 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index b5f3a76662..eb016f8040 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -128,6 +128,8 @@ SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * contex // Already existed if (peer != NULL) { WARN_LOG(SCENET, "Member Peer Already Existed! Updating [%s]", mac2str(mac).c_str()); + peer->state = 0; + peer->sending = 0; peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); } // Member is not added yet @@ -137,8 +139,10 @@ SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * contex memset(peer, 0, sizeof(SceNetAdhocMatchingMemberInternal)); peer->mac = *mac; peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + peerlock.lock(); peer->next = context->peerlist; context->peerlist = peer; + peerlock.unlock(); } } return peer; @@ -437,7 +441,7 @@ void postAcceptCleanPeerList(SceNetAdhocMatchingContext * context) SceNetAdhocMatchingMemberInternal * next = peer->next; // Unneeded Peer - if (peer->state != PSP_ADHOC_MATCHING_PEER_CHILD && peer->state != PSP_ADHOC_MATCHING_PEER_P2P && peer->state != PSP_ADHOC_MATCHING_PEER_PARENT) { + if (peer->state != PSP_ADHOC_MATCHING_PEER_CHILD && peer->state != PSP_ADHOC_MATCHING_PEER_P2P && peer->state != PSP_ADHOC_MATCHING_PEER_PARENT && peer->state != 0) { deletePeer(context, peer); delcount++; } @@ -450,7 +454,7 @@ void postAcceptCleanPeerList(SceNetAdhocMatchingContext * context) // Free Peer Lock peerlock.unlock(); - INFO_LOG(SCENET, "Removing Unneeded Peer (%i/%i)", delcount, peercount); + INFO_LOG(SCENET, "Removing Unneeded Peers (%i/%i)", delcount, peercount); } /** @@ -466,39 +470,52 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun // As the buffer of "siblings" isn't properly aligned I don't want to risk a crash. uint8_t * siblings_u8 = (uint8_t *)siblings; - // Iterate Siblings - for (int i = 0; i < siblingcount; i++) + peerlock.lock(); + // Iterate Siblings. Reversed so these siblings are added into peerlist in the same order with the peerlist on host/parent side + for (int i = siblingcount - 1; i >= 0 ; i--) { - // Allocate Memory - SceNetAdhocMatchingMemberInternal * sibling = (SceNetAdhocMatchingMemberInternal *)malloc(sizeof(SceNetAdhocMatchingMemberInternal)); - - // Allocated Memory - if (sibling != NULL) - { - // Clear Memory - memset(sibling, 0, sizeof(SceNetAdhocMatchingMemberInternal)); - - // Save MAC Address - memcpy(&sibling->mac, siblings_u8 + sizeof(SceNetEtherAddr) * i, sizeof(SceNetEtherAddr)); + SceNetEtherAddr* mac = (SceNetEtherAddr*)(siblings_u8 + sizeof(SceNetEtherAddr) * i); + auto peer = findPeer(context, mac); + // Already exist + if (peer != NULL) { // Set Peer State - sibling->state = PSP_ADHOC_MATCHING_PEER_CHILD; + peer->state = PSP_ADHOC_MATCHING_PEER_CHILD; + peer->sending = 0; + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + WARN_LOG(SCENET, "Updating Sibling Peer %s", mac2str(mac).c_str()); + } + else { + // Allocate Memory + SceNetAdhocMatchingMemberInternal* sibling = (SceNetAdhocMatchingMemberInternal*)malloc(sizeof(SceNetAdhocMatchingMemberInternal)); - // Initialize Ping Timer - sibling->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + // Allocated Memory + if (sibling != NULL) + { + // Clear Memory + memset(sibling, 0, sizeof(SceNetAdhocMatchingMemberInternal)); - peerlock.lock(); - // Link Peer, should check whether it's already added before - sibling->next = context->peerlist; - context->peerlist = sibling; - peerlock.unlock(); + // Save MAC Address + memcpy(&sibling->mac, mac, sizeof(SceNetEtherAddr)); - // Spawn Established Event. FIXME: ESTABLISHED event should only be triggered for Parent/P2P peer? - //spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); + // Set Peer State + sibling->state = PSP_ADHOC_MATCHING_PEER_CHILD; - INFO_LOG(SCENET, "Accepting Peer %s", mac2str(&sibling->mac).c_str()); + // Initialize Ping Timer + sibling->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + + // Link Peer + sibling->next = context->peerlist; + context->peerlist = sibling; + + // Spawn Established Event. FIXME: ESTABLISHED event should only be triggered for Parent/P2P peer? + //spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL); + + INFO_LOG(SCENET, "Accepting Sibling Peer %s", mac2str(&sibling->mac).c_str()); + } } } + peerlock.unlock(); } /** @@ -888,13 +905,14 @@ void handleTimeout(SceNetAdhocMatchingContext * context) u64_le now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0 // Timeout!, may be we shouldn't kick timedout members ourself and let the game do it - if ((now - peer->lastping) >= context->timeout) + if (peer->state != 0 && (now - peer->lastping) >= context->timeout) { // Spawn Timeout Event - if ((context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD || peer->state == PSP_ADHOC_MATCHING_PEER_PARENT)) || + if ((context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && (/*peer->state == PSP_ADHOC_MATCHING_PEER_CHILD ||*/ peer->state == PSP_ADHOC_MATCHING_PEER_PARENT)) || (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT && peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) || (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && peer->state == PSP_ADHOC_MATCHING_PEER_P2P)) { - spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); // This is the only code that use PSP_ADHOC_MATCHING_EVENT_TIMEOUT, should we let it timedout? + // FIXME: TIMEOUT event should only be triggered on Parent/P2P mode and for Parent/P2P peer? + spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); } INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac).c_str(), (context->timeout/1000)); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 3f6fd7af59..88e7f5d312 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -646,10 +646,10 @@ enum { #define PSP_ADHOC_MATCHING_EVENT_DENY 4 #define PSP_ADHOC_MATCHING_EVENT_CANCEL 5 #define PSP_ADHOC_MATCHING_EVENT_ACCEPT 6 -#define PSP_ADHOC_MATCHING_EVENT_ESTABLISHED 7 -#define PSP_ADHOC_MATCHING_EVENT_TIMEOUT 8 +#define PSP_ADHOC_MATCHING_EVENT_ESTABLISHED 7 // Should only be triggered on Parent/P2P mode and for Parent/P2P peer ? +#define PSP_ADHOC_MATCHING_EVENT_TIMEOUT 8 // Should only be triggered on Parent/P2P mode and for Parent/P2P peer ? #define PSP_ADHOC_MATCHING_EVENT_ERROR 9 -#define PSP_ADHOC_MATCHING_EVENT_BYE 10 +#define PSP_ADHOC_MATCHING_EVENT_BYE 10 // Should only be triggered on Parent/P2P mode and for Parent/P2P peer ? #define PSP_ADHOC_MATCHING_EVENT_DATA 11 #define PSP_ADHOC_MATCHING_EVENT_DATA_ACK 12 #define PSP_ADHOC_MATCHING_EVENT_DATA_TIMEOUT 13 diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 498f8205d3..41796e88d3 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -3691,13 +3691,15 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Filled Request Counter int filledpeers = 0; - // Add Self-Peer if (requestedpeers > 0) { - // Add Local MAC - buf2[filledpeers++].mac_addr = context->mac; + // Add Self-Peer first, unless if there is existing Parent/P2P peer + if (peercount == 1 || context->mode != PSP_ADHOC_MATCHING_MODE_CHILD) { + // Add Local MAC + buf2[filledpeers++].mac_addr = context->mac; - DEBUG_LOG(SCENET, "MemberSelf [%s]", mac2str(&context->mac).c_str()); + DEBUG_LOG(SCENET, "MemberSelf [%s]", mac2str(&context->mac).c_str()); + } // Room for more than local peer if (requestedpeers > 1) @@ -3726,6 +3728,23 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Parent or Child Mode else { + // Add Parent first + SceNetAdhocMatchingMemberInternal* parentpeer = findParent(context); + if (parentpeer != NULL) { + // Faking lastping + auto friendpeer = findFriend(&parentpeer->mac); + if (parentpeer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) + parentpeer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + + // Add Parent MAC + buf2[filledpeers++].mac_addr = parentpeer->mac; + + DEBUG_LOG(SCENET, "MemberParent [%s]", mac2str(&parentpeer->mac).c_str()); + } + + // We may need to rearrange children where last joined player placed last + std::deque sortedPeers; + // Iterate Peer List SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL && filledpeers < requestedpeers; peer = peer->next) @@ -3737,35 +3756,45 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) if (peer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); - // Parent Mode - if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { - // Interested in Children - if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) { - // Add Child MAC - buf2[filledpeers++].mac_addr = peer->mac; - - DEBUG_LOG(SCENET, "MemberChild [%s]", mac2str(&peer->mac).c_str()); - } - } - - // Children Mode - else { - // Interested in Parent & Siblings - if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD || - peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) { - // Add Peer MAC - buf2[filledpeers++].mac_addr = peer->mac; - - if (peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) - DEBUG_LOG(SCENET, "MemberParent [%s]", mac2str(&peer->mac).c_str()); - else - DEBUG_LOG(SCENET, "MemberSibling [%s]", mac2str(&peer->mac).c_str()); - } - } + // Add Peer MAC + sortedPeers.push_front(peer); } } - } + // Iterate rearranged peers + for (const auto& peer : sortedPeers) { + // Parent Mode + if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { + // Interested in Children + if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) { + // Add Child MAC + buf2[filledpeers++].mac_addr = peer->mac; + + DEBUG_LOG(SCENET, "MemberChild [%s]", mac2str(&peer->mac).c_str()); + } + } + + // Child Mode + else { + // Interested in Siblings + if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) { + // Add Peer MAC + buf2[filledpeers++].mac_addr = peer->mac; + + DEBUG_LOG(SCENET, "MemberSibling [%s]", mac2str(&peer->mac).c_str()); + } + // Self Peer + else if (peer->state == 0) { + // Add Local MAC + buf2[filledpeers++].mac_addr = peer->mac; + + DEBUG_LOG(SCENET, "MemberSelf [%s]", mac2str(&peer->mac).c_str()); + } + + } + } + sortedPeers.clear(); + } } // Link Result List @@ -3773,7 +3802,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) { // Link Next Element //buf2[i].next = &buf2[i + 1]; - buf2[i].next = buf + (sizeof(SceNetAdhocMatchingMemberInfoEmu)*i) + sizeof(SceNetAdhocMatchingMemberInfoEmu); + buf2[i].next = buf + (sizeof(SceNetAdhocMatchingMemberInfoEmu)*(i+1LL)); } // Fix Last Element if (filledpeers > 0) buf2[filledpeers - 1].next = 0; @@ -5052,7 +5081,15 @@ void actOnAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * s postAcceptCleanPeerList(context); // Add Sibling Peers - if (context->mode == PSP_ADHOC_MATCHING_MODE_CHILD) postAcceptAddSiblings(context, siblingcount, siblings); + if (context->mode == PSP_ADHOC_MATCHING_MODE_CHILD) { + // Add existing siblings + postAcceptAddSiblings(context, siblingcount, siblings); + + // Add Self Peer to the following position (using peer->state = 0 to identify as Self) + SceNetEtherAddr selfMAC; + getLocalMac(&selfMAC); + addMember(context, &selfMAC); + } // IMPORTANT! The Event Order here is ok! // Internally the Event Stack appends to the front, so the order will be switched around. @@ -5081,15 +5118,6 @@ void actOnCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * s // Find Peer SceNetAdhocMatchingMemberInternal * peer = findPeer(context, sendermac); - // Get Parent - SceNetAdhocMatchingMemberInternal * parent = findParent(context); - - // Get Outgoing Join Request - SceNetAdhocMatchingMemberInternal * request = findOutgoingRequest(context); - - // Get P2P Partner - SceNetAdhocMatchingMemberInternal * p2p = findP2P(context); - // Interest Condition fulfilled if (peer != NULL) { @@ -5108,9 +5136,15 @@ void actOnCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * s // Extract Optional Data Pointer if (optlen > 0) opt = context->rxbuf + 5; + // Get Outgoing Join Request + SceNetAdhocMatchingMemberInternal* request = findOutgoingRequest(context); + // Child Mode if (context->mode == PSP_ADHOC_MATCHING_MODE_CHILD) { + // Get Parent + SceNetAdhocMatchingMemberInternal* parent = findParent(context); + // Join Request denied if (request == peer) { @@ -5168,6 +5202,9 @@ void actOnCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * s // P2P Mode else { + // Get P2P Partner + SceNetAdhocMatchingMemberInternal* p2p = findP2P(context); + // Join Request denied if (request == peer) { @@ -5348,8 +5385,10 @@ void actOnByePacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * send (context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) || (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && peer->state == PSP_ADHOC_MATCHING_PEER_P2P)) { - // Spawn Leave / Kick Event - spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_BYE, sendermac, 0, NULL); + if (context->mode != PSP_ADHOC_MATCHING_MODE_CHILD) { + // Spawn Leave / Kick Event. FIXME: DISCONNECT event should only be triggered on Parent/P2P mode and for Parent/P2P peer? + spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_BYE, sendermac, 0, NULL); + } // Delete Peer deletePeer(context, peer); @@ -5360,17 +5399,8 @@ void actOnByePacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * send // Parent Bye else if (context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) { - // Iterate Peers - SceNetAdhocMatchingMemberInternal * item = context->peerlist; - for (; item != NULL; item = item->next) - { - // Established Peer - if (item->state == PSP_ADHOC_MATCHING_PEER_CHILD || item->state == PSP_ADHOC_MATCHING_PEER_PARENT) - { - // Spawn Leave / Kick Event - spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_BYE, &item->mac, 0, NULL); - } - } + // Spawn Leave / Kick Event. FIXME: DISCONNECT event should only be triggered on Parent/P2P mode and for Parent/P2P peer? + spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_BYE, sendermac, 0, NULL); // Delete Peer from List clearPeerList(context); From 7083342046722eb84429a2c75747728997f03dcc Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 4 Sep 2020 02:36:29 +0700 Subject: [PATCH 619/848] Avoid using hleLog during a Shutdown --- Core/HLE/sceNetAdhoc.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 41796e88d3..4ad4c8faa5 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -94,14 +94,13 @@ void __NetAdhocShutdown() { } // Checks to avoid confusing logspam if (netAdhocMatchingInited) { - sceNetAdhocMatchingTerm(); + NetAdhocMatching_Term(); } if (netAdhocctlInited) { - sceNetAdhocctlTerm(); + NetAdhocctl_Term(); } if (netAdhocInited) { - // Should not really call HLE funcs from shutdown, but we need to cleanup - sceNetAdhocTerm(); + NetAdhoc_Term(); } if (dummyThreadHackAddr) { kernelMemory.Free(dummyThreadHackAddr); From d99f55465e434ac2d9df521bb4461831dd3d55e7 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 4 Sep 2020 01:48:15 +0700 Subject: [PATCH 620/848] Fixed possible crash issue due to lingering leftover callback events from previous multiplayer session. --- Core/HLE/sceNet.cpp | 7 +++++-- Core/HLE/sceNetAdhoc.cpp | 8 ++++++-- Core/HLE/sceNp.cpp | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 42c70cecec..aa4ab0c2ab 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -468,7 +468,8 @@ void __NetApctlCallbacks() } // Must be delayed long enough whenever there is a pending callback. - hleDelayResult(0, "Prevent Apctl thread from blocking", delayus); + sceKernelDelayThread(delayus); + hleSkipDeadbeef();; } static inline u32 AllocUser(u32 size, bool fromTop, const char *name) { @@ -758,6 +759,9 @@ static int sceNetApctlInit(int stackSize, int initPriority) { if (netApctlInited) return ERROR_NET_APCTL_ALREADY_INITIALIZED; + apctlEvents.clear(); + netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; + // Set default value before connected to an AP memset(&netApctlInfo, 0, sizeof(netApctlInfo)); // NetApctl_InitInfo(); std::string APname = "Wifi"; // fake AP/hotspot @@ -778,7 +782,6 @@ static int sceNetApctlInit(int stackSize, int initPriority) { } netApctlInited = true; - netApctlState = PSP_NET_APCTL_STATE_DISCONNECTED; return 0; } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 4ad4c8faa5..56e3e5e652 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -248,6 +248,7 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { Memory::ReadStruct(productAddr, &product_code); } + adhocctlEvents.clear(); netAdhocctlInited = true; //needed for cleanup during AdhocctlTerm even when it failed to connect to Adhoc Server (since it's being faked as success) // Create fake PSP Thread for callback @@ -3007,6 +3008,7 @@ int sceNetAdhocMatchingInit(u32 memsize) { fakePoolSize = memsize; // Initialize Library + matchingEvents.clear(); netAdhocMatchingInited = true; // Return Success @@ -4077,7 +4079,8 @@ void __NetTriggerCallbacks() } // Must be delayed long enough whenever there is a pending callback. Should it be 100-500ms for Adhocctl Events? or Not Less than the delays on sceNetAdhocctl HLE? - hleDelayResult(0, "Prevent Adhocctl thread from blocking", delayus); + sceKernelDelayThread(delayus); + hleSkipDeadbeef(); } void __NetMatchingCallbacks() //(int matchingId) @@ -4108,7 +4111,8 @@ void __NetMatchingCallbacks() //(int matchingId) } // Must be delayed long enough whenever there is a pending callback. Should it be 10-100ms for Matching Events? or Not Less than the delays on sceNetAdhocMatching HLE? - hleDelayResult(0, "Prevent AdhocMatching thread from blocking", delayus); + sceKernelDelayThread(delayus); + hleSkipDeadbeef(); } const HLEFunction sceNetAdhoc[] = { diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index 639776485d..cd0fc9a26b 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -162,6 +162,7 @@ static int sceNpAuthInit(u32 poolSize, u32 stackSize, u32 threadPrio) npAuthMemStat.npMemSize = poolSize; npAuthMemStat.npMaxMemSize = poolSize / 2; // Dummy npAuthMemStat.npFreeMemSize = poolSize - 16; // Dummy. + npAuthEvents.clear(); npAuthInited = true; return 0; From 515592551655b59e57c34f0098a6ee701291f709 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 4 Sep 2020 02:28:32 +0700 Subject: [PATCH 621/848] Fix connection issue on games using AdhocMatching due to sometimes events are removed prematurely before being processed. This fix Gran Turismo where some peers could permanently be in "busy data" state. --- Core/HLE/sceNetAdhoc.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 56e3e5e652..fc37dcd1d5 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -5466,7 +5466,7 @@ int matchingEventThread(int matchingId) INFO_LOG(SCENET, "EventLoop[%d]: Matching Event [%d=%s][%s] OptSize=%d", matchingId, msg->opcode, getMatchingEventStr(msg->opcode), mac2str(&msg->mac).c_str(), msg->optlen); // Unlock to prevent race-condition with other threads due to recursive lock - context->eventlock->unlock(); + //context->eventlock->unlock(); // Call Event Handler //context->handler(context->id, msg->opcode, &msg->mac, msg->optlen, opt); // Notify Event Handlers @@ -5477,7 +5477,7 @@ int matchingEventThread(int matchingId) //sleep_ms(10); //sceKernelDelayThread(10000); // Lock again - context->eventlock->lock(); + //context->eventlock->lock(); // Pop event stack from front (this should be queue instead of stack?) context->event_stack = msg->next; @@ -5514,12 +5514,12 @@ int matchingEventThread(int matchingId) INFO_LOG(SCENET, "EventLoop[%d]: Matching Event [EVENT=%d]\n", matchingId, msg->opcode); - context->eventlock->unlock(); + //context->eventlock->unlock(); // Original Call Event Handler //context->handler(context->id, msg->opcode, &msg->mac, msg->optlen, opt); // Notify Event Handlers notifyMatchingHandler(context, msg, opt, bufAddr, bufLen, args); - context->eventlock->lock(); + //context->eventlock->lock(); } // Clear Event Message Stack @@ -5618,7 +5618,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi // Iterate Message List ThreadMessage* msg = context->input_stack; - for (; msg != NULL; msg = msg->next) + while (msg != NULL) { // Default Optional Data void* opt = NULL; @@ -5626,7 +5626,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi // Grab Optional Data if (msg->optlen > 0) opt = ((u8*)msg) + sizeof(ThreadMessage); - context->inputlock->unlock(); // Unlock to prevent race condition when locking peerlock + //context->inputlock->unlock(); // Unlock to prevent race condition when locking peerlock // Send Accept Packet if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_ACCEPT) sendAcceptPacket(context, &msg->mac, msg->optlen, opt); @@ -5646,11 +5646,13 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi // Cancel Bulk Data Transfer (does nothing as of now as we fire and forget anyway) // Do we need to check DeathPacket and ByePacket here? //else if(msg->opcode == PSP_ADHOC_MATCHING_PACKET_BULK_ABORT) sendAbortBulkDataPacket(context, &msg->mac, msg->optlen, opt); - context->inputlock->lock(); // Lock again - } + //context->inputlock->lock(); // Lock again - // Clear IO Message Stack - clearStack(context, PSP_ADHOC_MATCHING_INPUT_STACK); + // Pop input stack from front (this should be queue instead of stack?) + context->input_stack = msg->next; + free(msg); + msg = context->input_stack; + } // Free Stack context->inputlock->unlock(); @@ -5727,6 +5729,9 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi } if (contexts != NULL) { + // Clear IO Message Stack + clearStack(context, PSP_ADHOC_MATCHING_INPUT_STACK); + // Send Bye Messages sendByePacket(context); From db3e7d80d9065f2d615b94850d22417e7a1eabe3 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 4 Sep 2020 08:35:40 +0700 Subject: [PATCH 622/848] Oops we already have local mac stored in context, no longer need to getLocalMac again --- Core/HLE/sceNetAdhoc.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index fc37dcd1d5..24a62fade5 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -5089,9 +5089,7 @@ void actOnAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * s postAcceptAddSiblings(context, siblingcount, siblings); // Add Self Peer to the following position (using peer->state = 0 to identify as Self) - SceNetEtherAddr selfMAC; - getLocalMac(&selfMAC); - addMember(context, &selfMAC); + addMember(context, &context->mac); } // IMPORTANT! The Event Order here is ok! From 6a9cf0f575422b45a9c5426e4c3f2bbd14842b7f Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 18 Aug 2020 00:39:46 +0700 Subject: [PATCH 623/848] An attempt to differentiate adhoc connect, create, and join. --- Core/Dialog/PSPNetconfDialog.cpp | 169 +++++++++++++++++++++++++++---- Core/Dialog/PSPNetconfDialog.h | 7 +- Core/HLE/proAdhoc.cpp | 13 +-- Core/HLE/proAdhoc.h | 10 +- Core/HLE/sceNet.cpp | 2 +- Core/HLE/sceNetAdhoc.cpp | 127 ++++++++++++++--------- Core/HLE/sceNetAdhoc.h | 15 ++- 7 files changed, 265 insertions(+), 78 deletions(-) diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index f4436d5564..a218382d68 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -18,17 +18,20 @@ #if defined(_WIN32) #include "Common/CommonWindows.h" #endif +#include #include "i18n/i18n.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" #include "Core/MemMapHelpers.h" #include "Core/Util/PPGeDraw.h" +#include "Core/HLE/sceKernelMemory.h" #include "Core/HLE/sceCtrl.h" #include "Core/HLE/sceUtility.h" -#include +#include "Core/HLE/sceNet.h" +#include "Core/HLE/sceNetAdhoc.h" #include "Core/Dialog/PSPNetconfDialog.h" -#include +#include "ext/native/util/text/utf8.h" #define NETCONF_CONNECT_APNET 0 @@ -44,6 +47,13 @@ static const float FONT_SCALE = 0.65f; const static int NET_INIT_DELAY_US = 300000; const static int NET_SHUTDOWN_DELAY_US = 26000; const static int NET_RUNNING_DELAY_US = 1000000; // KHBBS is showing adhoc dialog for about 3-4 seconds, but feels too long, so we're faking it to 1 sec instead to let players read the text +const static int NET_CONNECT_TIMEOUT = 5000000; + +struct ScanInfos { + s32_le sz; + SceNetAdhocctlScanInfoEmu si; +} PACK; + PSPNetconfDialog::PSPNetconfDialog() { } @@ -78,6 +88,11 @@ int PSPNetconfDialog::Init(u32 paramAddr) { cancelButtonFlag = CTRL_CIRCLE; } + connResult = -1; + scanInfosAddr = 0; + scanStep = 0; + startTime = (u64)(real_time_now() * 1000000.0); + StartFade(true); return 0; } @@ -114,7 +129,7 @@ void PSPNetconfDialog::DisplayMessage(std::string text1, std::string text2a, std // Without the scrollbar, we have 350 total pixels. float WRAP_WIDTH = 300.0f; - if (UTF8StringNonASCIICount(text1.c_str()) >= text1.size() / 4) { + if (UTF8StringNonASCIICount(text1.c_str()) >= (int)text1.size() / 4) { WRAP_WIDTH = 336.0f; if (text1.size() > 12) { messageStyle.scale = 0.6f; @@ -182,12 +197,20 @@ void PSPNetconfDialog::DisplayMessage(std::string text1, std::string text2a, std PPGeScissor(0, (int)(centerY - h2 - 2), 480, (int)(centerY + h2 + 2)); PPGeDrawTextWrapped(text1.c_str(), 240.0f, centerY - h2 - scrollPos_, WRAP_WIDTH, 0, messageStyle); - if (text2a != "") - PPGeDrawTextWrapped(text2a.c_str(), 240.0f - 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + marginTop, WRAP_WIDTH, 0, messageStyleRight); + if (text2a != "") { + if (text2b != "") + PPGeDrawTextWrapped(text2a.c_str(), 240.0f - 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + marginTop, WRAP_WIDTH, 0, messageStyleRight); + else + PPGeDrawTextWrapped(text2a.c_str(), 240.0f, centerY - h2 - scrollPos_ + totalHeight1 + marginTop, WRAP_WIDTH, 0, messageStyle); + } if (text2b != "") PPGeDrawTextWrapped(text2b.c_str(), 240.0f + 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + marginTop, WRAP_WIDTH, 0, messageStyleLeft); - if (text3a != "") - PPGeDrawTextWrapped(text3a.c_str(), 240.0f - 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + totalHeight2 + marginTop, WRAP_WIDTH, 0, messageStyleRight); + if (text3a != "") { + if (text3b != "") + PPGeDrawTextWrapped(text3a.c_str(), 240.0f - 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + totalHeight2 + marginTop, WRAP_WIDTH, 0, messageStyleRight); + else + PPGeDrawTextWrapped(text3a.c_str(), 240.0f, centerY - h2 - scrollPos_ + totalHeight1 + totalHeight2 + marginTop, WRAP_WIDTH, 0, messageStyle); + } if (text3b != "") PPGeDrawTextWrapped(text3b.c_str(), 240.0f + 5.0f, centerY - h2 - scrollPos_ + totalHeight1 + totalHeight2 + marginTop, WRAP_WIDTH, 0, messageStyleLeft); PPGeScissorReset(); @@ -229,6 +252,7 @@ int PSPNetconfDialog::Update(int animSpeed) { UpdateButtons(); auto di = GetI18NCategory("Dialog"); auto err = GetI18NCategory("Error"); + u64 now = (u64)(real_time_now() * 1000000.0); // It seems JPCSP doesn't check for NETCONF_STATUS_APNET if (request.netAction == NETCONF_CONNECT_APNET || request.netAction == NETCONF_STATUS_APNET || request.netAction == NETCONF_CONNECT_APNET_LAST) { @@ -310,6 +334,7 @@ int PSPNetconfDialog::Update(int animSpeed) { } else if (request.netAction == NETCONF_CONNECT_ADHOC || request.netAction == NETCONF_CREATE_ADHOC || request.netAction == NETCONF_JOIN_ADHOC) { int state = NetAdhocctl_GetState(); + bool timedout = (state == ADHOCCTL_STATE_DISCONNECTED && now - startTime > NET_CONNECT_TIMEOUT); UpdateFade(animSpeed); StartDraw(); @@ -317,18 +342,104 @@ int PSPNetconfDialog::Update(int animSpeed) { DrawBanner(); DrawIndicator(); - std::string channel = std::to_string(g_Config.iWlanAdhocChannel); - if (g_Config.iWlanAdhocChannel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) - channel = "Automatic"; + if (timedout) { + // FIXME: Do we need to show error message? + DisplayMessage(di->T("InternalError", "An internal error has occurred.") + StringFromFormat("\n(%08X)", connResult)); + DisplayButtons(DS_BUTTON_CANCEL, di->T("Back")); + } + else { + std::string channel = std::to_string(g_Config.iWlanAdhocChannel); + if (g_Config.iWlanAdhocChannel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) + channel = "Automatic"; - DisplayMessage(di->T("ConnectingChannel", "Connecting.\nPlease wait...\n\nChannel")+std::string(" ")+di->T(channel)); + DisplayMessage(di->T("ConnectingPleaseWait", "Connecting.\nPlease wait..."), di->T("Channel") + std::string(" ") + di->T(channel)); - // Only Join mode is showing Cancel button on KHBBS and the button will fade out before the dialog is fading out, probably because it's already connected thus can't be canceled anymore - if (request.netAction == NETCONF_JOIN_ADHOC) - DisplayButtons(DS_BUTTON_CANCEL, di->T("Cancel")); + // Only Join mode is showing Cancel button on KHBBS and the button will fade out before the dialog is fading out, probably because it's already connected thus can't be canceled anymore + if (request.netAction == NETCONF_JOIN_ADHOC) + DisplayButtons(DS_BUTTON_CANCEL, di->T("Cancel")); - if (state == ADHOCCTL_STATE_DISCONNECTED && request.NetconfData.IsValid()) { - connResult = sceNetAdhocctlCreate(request.NetconfData->groupName); + // KHBBS will first enter the arena using NETCONF_CONNECT_ADHOC (auto-create group when not exist yet?), but when the event started the event's creator use NETCONF_CREATE_ADHOC while the joining players use NETCONF_JOIN_ADHOC + if (request.NetconfData.IsValid()) { + if (state == ADHOCCTL_STATE_DISCONNECTED) { + switch (request.netAction) + { + case NETCONF_CREATE_ADHOC: + if (connResult < 0) { + connResult = sceNetAdhocctlCreate(request.NetconfData->groupName); + } + break; + case NETCONF_JOIN_ADHOC: + // FIXME: Should we Scan for a matching group first before Joining a Group (like adhoc games normally do)? Or Is it really allowed to join non-existing group? + if (scanStep == 0) { + if (sceNetAdhocctlScan() >= 0) { + u32 structsz = sizeof(ScanInfos); + if (Memory::IsValidAddress(scanInfosAddr)) + userMemory.Free(scanInfosAddr); + scanInfosAddr = userMemory.Alloc(structsz, false, "NetconfScanInfo"); + Memory::Write_U32(sizeof(SceNetAdhocctlScanInfoEmu), scanInfosAddr); + scanStep = 1; + } + } + else if (scanStep == 1) { + s32 sz = Memory::Read_U32(scanInfosAddr); + // Get required buffer size + if (sceNetAdhocctlGetScanInfo(scanInfosAddr, 0) >= 0) { + s32 reqsz = Memory::Read_U32(scanInfosAddr); + if (reqsz > sz) { + sz = reqsz; + if (Memory::IsValidAddress(scanInfosAddr)) + userMemory.Free(scanInfosAddr); + u32 structsz = sz + sizeof(s32); + scanInfosAddr = userMemory.Alloc(structsz, false, "NetconfScanInfo"); + Memory::Write_U32(sz, scanInfosAddr); + } + if (reqsz > 0) { + if (sceNetAdhocctlGetScanInfo(scanInfosAddr, scanInfosAddr + sizeof(s32)) >= 0) { + ScanInfos* scanInfos = (ScanInfos*)Memory::GetPointer(scanInfosAddr); + int n = scanInfos->sz / sizeof(SceNetAdhocctlScanInfoEmu); + // Assuming returned SceNetAdhocctlScanInfoEmu(s) are contagious where next is pointing to current addr + sizeof(SceNetAdhocctlScanInfoEmu) + while (n > 0) { + SceNetAdhocctlScanInfoEmu* si = (SceNetAdhocctlScanInfoEmu*)Memory::GetPointer(scanInfosAddr + sizeof(s32) + sizeof(SceNetAdhocctlScanInfoEmu) * (n - 1LL)); + if (memcmp(si->group_name.data, request.NetconfData->groupName, ADHOCCTL_GROUPNAME_LEN) == 0) { + // Moving found group info to the front so we can use it on sceNetAdhocctlJoin easily + memcpy((char*)scanInfos + sizeof(s32), si, sizeof(SceNetAdhocctlScanInfoEmu)); + scanStep = 2; + break; + } + n--; + } + // Target group not found, try to scan again later + if (n <= 0) { + scanStep = 0; + } + } + } + // No group found, try to scan again later + else { + scanStep = 0; + } + } + } + else if (scanStep == 2) { + if (connResult < 0) { + connResult = sceNetAdhocctlJoin(scanInfosAddr + sizeof(s32)); + if (connResult >= 0) { + // We are done! + if (Memory::IsValidAddress(scanInfosAddr)) + userMemory.Free(scanInfosAddr); + scanInfosAddr = 0; + } + } + } + break; + default: + if (connResult < 0) { + connResult = sceNetAdhocctlConnect(request.NetconfData->groupName); + } + break; + } + } + } } // The Netconf dialog stays visible until the network reaches @@ -342,12 +453,20 @@ int PSPNetconfDialog::Update(int animSpeed) { else if (GetStatus() == SCE_UTILITY_STATUS_FINISHED) { StartFade(false); } + // Let's not leaks any memory + if (Memory::IsValidAddress(scanInfosAddr)) + userMemory.Free(scanInfosAddr); + scanInfosAddr = 0; } - if (request.netAction == NETCONF_JOIN_ADHOC && IsButtonPressed(cancelButtonFlag)) { + if ((request.netAction == NETCONF_JOIN_ADHOC || timedout) && IsButtonPressed(cancelButtonFlag)) { StartFade(false); ChangeStatus(SCE_UTILITY_STATUS_FINISHED, NET_SHUTDOWN_DELAY_US); request.common.result = SCE_UTILITY_DIALOG_RESULT_ABORT; + // Let's not leaks any memory + if (Memory::IsValidAddress(scanInfosAddr)) + userMemory.Free(scanInfosAddr); + scanInfosAddr = 0; } EndDraw(); @@ -374,11 +493,25 @@ int PSPNetconfDialog::Shutdown(bool force) { void PSPNetconfDialog::DoState(PointerWrap &p) { PSPDialog::DoState(p); - auto s = p.Section("PSPNetconfigDialog", 0, 1); + auto s = p.Section("PSPNetconfigDialog", 0, 2); if (!s) return; Do(p, request); + if (s >= 2) { + Do(p, scanInfosAddr); + Do(p, scanStep); + Do(p, connResult); + } + else { + scanInfosAddr = 0; + scanStep = 0; + connResult = -1; + } + + if (p.mode == p.MODE_READ) { + startTime = 0; + } } pspUtilityDialogCommon* PSPNetconfDialog::GetCommonParam() diff --git a/Core/Dialog/PSPNetconfDialog.h b/Core/Dialog/PSPNetconfDialog.h index ea10471cc7..e02ebae5a0 100644 --- a/Core/Dialog/PSPNetconfDialog.h +++ b/Core/Dialog/PSPNetconfDialog.h @@ -34,6 +34,7 @@ struct SceUtilityNetconfParam { int netWifiSpot; // Flag to allow WIFI connections }; + class PSPNetconfDialog: public PSPDialog { public: PSPNetconfDialog(); @@ -57,11 +58,15 @@ private: SceUtilityNetconfParam request = {}; u32 requestAddr = 0; - int connResult = 0; + int connResult = -1; bool hideNotice = false; int yesnoChoice = 0; float scrollPos_ = 0.0f; int framesUpHeld_ = 0; int framesDownHeld_ = 0; + + u32 scanInfosAddr = 0; + int scanStep = 0; + u64 startTime = 0; }; diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index eb016f8040..b8f57cca83 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -55,7 +55,8 @@ bool friendFinderRunning = false; SceNetAdhocctlPeerInfo * friends = NULL; SceNetAdhocctlScanInfo * networks = NULL; SceNetAdhocctlScanInfo * newnetworks = NULL; -int threadStatus = ADHOCCTL_STATE_DISCONNECTED; +int adhocctlState = ADHOCCTL_STATE_DISCONNECTED; +int adhocConnectionType = ADHOC_CONNECT; int actionAfterAdhocMipsCall; int actionAfterMatchingMipsCall; @@ -1293,9 +1294,9 @@ int friendFinder(){ // Update User BSSID parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address // Notify Event Handlers - //notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); + notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); // Change State - threadStatus = ADHOCCTL_STATE_CONNECTED; + //threadStatus = ADHOCCTL_STATE_CONNECTED; // Give time a little time //sceKernelDelayThread(adhocEventDelayMS * 1000); //sleep_ms(adhocEventDelayMS); @@ -1492,14 +1493,14 @@ int friendFinder(){ peerlock.unlock(); // Notify Event Handlers - //notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); + notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) //{ // // Active Handler // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); //} // Change State - threadStatus = ADHOCCTL_STATE_DISCONNECTED; + //threadStatus = ADHOCCTL_STATE_DISCONNECTED; // Give time a little time //sceKernelDelayThread(adhocEventDelayMS * 1000); //sleep_ms(adhocEventDelayMS); @@ -1522,7 +1523,7 @@ int friendFinder(){ // Groups/Networks should be deallocated isn't? // Prevent the games from having trouble to reInitiate Adhoc (the next NetInit -> PdpCreate after NetTerm) - threadStatus = ADHOCCTL_STATE_DISCONNECTED; + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; // Log Shutdown INFO_LOG(SCENET, "FriendFinder: End of Friend Finder Thread"); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 88e7f5d312..c3607e4d36 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -847,9 +847,17 @@ extern int one; extern bool friendFinderRunning; extern SceNetAdhocctlPeerInfo * friends; extern SceNetAdhocctlScanInfo * networks; -extern int threadStatus; +extern int adhocctlState; +extern int adhocConnectionType; // End of Aux vars +enum AdhocConnectionType : int +{ + ADHOC_CONNECT = 0, + ADHOC_CREATE = 1, + ADHOC_JOIN = 2, +}; + // Check if Matching callback is running bool IsMatchingInCallback(SceNetAdhocMatchingContext * context); bool SetMatchingInCallback(SceNetAdhocMatchingContext* context, bool IsInCB); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index aa4ab0c2ab..a7d073ee1c 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -469,7 +469,7 @@ void __NetApctlCallbacks() // Must be delayed long enough whenever there is a pending callback. sceKernelDelayThread(delayus); - hleSkipDeadbeef();; + hleSkipDeadbeef(); } static inline u32 AllocUser(u32 size, bool fromTop, const char *name) { diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 24a62fade5..5aaa6aa0c4 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -113,7 +113,7 @@ void __NetAdhocShutdown() { } void __NetAdhocDoState(PointerWrap &p) { - auto s = p.Section("sceNetAdhoc", 1, 4); + auto s = p.Section("sceNetAdhoc", 1, 5); if (!s) return; @@ -156,6 +156,14 @@ void __NetAdhocDoState(PointerWrap &p) { it = 0; } } + if (s >= 5) { + Do(p, adhocConnectionType); + Do(p, adhocctlState); + } + else { + adhocConnectionType = ADHOC_CONNECT; + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + } if (p.mode == p.MODE_READ) { // Previously, this wasn't being saved. It needs its own space. @@ -276,10 +284,10 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { } int NetAdhocctl_GetState() { - return threadStatus; + return adhocctlState; } -static int sceNetAdhocctlGetState(u32 ptrToStatus) { +int sceNetAdhocctlGetState(u32 ptrToStatus) { // Library uninitialized if (!netAdhocctlInited) return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; @@ -1044,7 +1052,7 @@ static int sceNetAdhocctlGetAdhocId(u32 productStructAddr) { return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } -static int sceNetAdhocctlScan() { +int sceNetAdhocctlScan() { INFO_LOG(SCENET, "sceNetAdhocctlScan() at %08x", currentMIPS->pc); // Library initialized @@ -1052,14 +1060,14 @@ static int sceNetAdhocctlScan() { // Wait until Not connected if (friendFinderRunning) { int cnt = 0; - while ((threadStatus != ADHOCCTL_STATE_DISCONNECTED) && (cnt < adhocDefaultTimeout)) { + while ((adhocctlState != ADHOCCTL_STATE_DISCONNECTED) && (cnt < adhocDefaultTimeout)) { sleep_ms(1); cnt++; } } - if (threadStatus == ADHOCCTL_STATE_DISCONNECTED) { - threadStatus = ADHOCCTL_STATE_SCANNING; + if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED) { + adhocctlState = ADHOCCTL_STATE_SCANNING; // Reset Networks/Group list to prevent other threads from using these soon to be replaced networks peerlock.lock(); @@ -1075,24 +1083,24 @@ static int sceNetAdhocctlScan() { if (iResult == SOCKET_ERROR) { int error = errno; ERROR_LOG(SCENET, "Socket error (%i) when sending", error); - threadStatus = ADHOCCTL_STATE_DISCONNECTED; + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; //if (error == ECONNABORTED || error == ECONNRESET || error == ENOTCONN) return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // A case where it need to reconnect to AdhocServer return ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY } // Does Connected Event's mipscall need be executed after returning from sceNetAdhocctlScan ? - notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); - hleCheckCurrentCallbacks(); + //notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); + //hleCheckCurrentCallbacks(); // Wait for Status to be connected to prevent Ford Street Racing from Failed to find game session // TODO: Do this async while Delaying HLE Result - if (friendFinderRunning) { + /*if (friendFinderRunning) { int cnt = 0; - while ((threadStatus == ADHOCCTL_STATE_SCANNING) && (cnt < adhocDefaultTimeout)) { + while ((adhocctlState == ADHOCCTL_STATE_SCANNING) && (cnt < adhocDefaultTimeout)) { sleep_ms(1); cnt++; } - } + }*/ //sceKernelDelayThread(adhocEventPollDelayMS * 1000); //hleDelayResult(0, "give time to init/cleanup", adhocEventPollDelayMS * 1000); @@ -1109,7 +1117,7 @@ static int sceNetAdhocctlScan() { return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } -static int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { +int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { s32_le *buflen = NULL; if (Memory::IsValidAddress(sizeAddr)) buflen = (s32_le *)Memory::GetPointer(sizeAddr); SceNetAdhocctlScanInfoEmu *buf = NULL; @@ -1245,7 +1253,7 @@ u32 NetAdhocctl_Disconnect() { // Library initialized if (netAdhocctlInited) { // Connected State (Adhoc Mode) - if (threadStatus != ADHOCCTL_STATE_DISCONNECTED) { // (threadStatus == ADHOCCTL_STATE_CONNECTED) + if (adhocctlState != ADHOCCTL_STATE_DISCONNECTED) { // (threadStatus == ADHOCCTL_STATE_CONNECTED) // Clear Network Name memset(¶meter.group_name, 0, sizeof(parameter.group_name)); @@ -1265,7 +1273,7 @@ u32 NetAdhocctl_Disconnect() { } // Set Disconnected State - threadStatus = ADHOCCTL_STATE_DISCONNECTED; + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; // Free Network Lock //_freeNetworkLock(); @@ -1324,7 +1332,7 @@ static u32 sceNetAdhocctlDelHandler(u32 handlerID) { int NetAdhocctl_Term() { if (netAdhocctlInited) { - if (threadStatus != ADHOCCTL_STATE_DISCONNECTED) + if (adhocctlState != ADHOCCTL_STATE_DISCONNECTED) NetAdhocctl_Disconnect(); // Terminate Adhoc Threads @@ -1512,14 +1520,14 @@ int NetAdhocctl_Create(const char* groupName) { // Wait until Not connected if (friendFinderRunning) { int cnt = 0; - while ((threadStatus != ADHOCCTL_STATE_DISCONNECTED && threadStatus != ADHOCCTL_STATE_SCANNING) && (cnt < adhocDefaultTimeout)) { + while ((adhocctlState != ADHOCCTL_STATE_DISCONNECTED && adhocctlState != ADHOCCTL_STATE_SCANNING) && (cnt < adhocDefaultTimeout)) { sleep_ms(1); cnt++; } } // Disconnected State, may also need to check for Scanning state to prevent some games from failing to host a game session - if ((threadStatus == ADHOCCTL_STATE_DISCONNECTED) || (threadStatus == ADHOCCTL_STATE_SCANNING)) { + if ((adhocctlState == ADHOCCTL_STATE_DISCONNECTED) || (adhocctlState == ADHOCCTL_STATE_SCANNING)) { // Set Network Name if (groupNameStruct != NULL) parameter.group_name = *groupNameStruct; @@ -1546,7 +1554,7 @@ int NetAdhocctl_Create(const char* groupName) { ERROR_LOG(SCENET, "Socket error (%i) when sending", errno); //return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY; //Faking success, to prevent Full Auto 2 from freezing while Initializing Network - threadStatus = ADHOCCTL_STATE_CONNECTED; + adhocctlState = ADHOCCTL_STATE_CONNECTED; // Notify Event Handlers, Needed for the Nickname to be shown on the screen when success is faked // Might be better not to notify the game when faking success (failed to connect to adhoc server), at least the player will know that it failed to connect //__UpdateAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); //CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventAdhocctlHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); @@ -1558,17 +1566,17 @@ int NetAdhocctl_Create(const char* groupName) { //setConnectionStatus(1); // Connected Event's mipscall need be executed before returning from sceNetAdhocctlCreate (or before the next sceNet function?) - notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); + //notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); // Wait for Status to be connected to prevent Ford Street Racing from Failed to create game session // TODO: Do this async while Delaying HLE Result - if (friendFinderRunning) { // This is thread-unsafe + /*if (friendFinderRunning) { // This is thread-unsafe int cnt = 0; - while ((threadStatus != ADHOCCTL_STATE_CONNECTED) && (cnt < adhocDefaultTimeout)) { // This is thread-unsafe + while ((adhocctlState != ADHOCCTL_STATE_CONNECTED) && (cnt < adhocDefaultTimeout)) { // This is thread-unsafe sleep_ms(1); cnt++; } - } + }*/ //sceKernelDelayThreadCB(adhocEventDelayMS * 1000); //hleCheckCurrentCallbacks(); @@ -1602,24 +1610,24 @@ int sceNetAdhocctlCreate(const char *groupName) { return -1; } + adhocConnectionType = ADHOC_CREATE; return NetAdhocctl_Create(groupName); } -static int sceNetAdhocctlConnect(u32 ptrToGroupName) { - if (Memory::IsValidAddress(ptrToGroupName)) { - const char* groupName = Memory::GetCharPointer(ptrToGroupName); - char grpName[9] = { 0 }; - memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs +int sceNetAdhocctlConnect(const char* groupName) { + char grpName[9] = { 0 }; + memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + INFO_LOG(SCENET, "sceNetAdhocctlConnect(%s) at %08x", grpName, currentMIPS->pc); + if (!g_Config.bEnableWlan) { + return -1; + } - INFO_LOG(SCENET, "sceNetAdhocctlConnect(groupName=%s) at %08x", grpName, currentMIPS->pc); - return NetAdhocctl_Create(groupName); - } - - return ERROR_NET_ADHOC_INVALID_ARG; // ERROR_NET_ADHOC_INVALID_ADDR; + adhocConnectionType = ADHOC_CONNECT; + return NetAdhocctl_Create(groupName); } -static int sceNetAdhocctlJoin(u32 scanInfoAddr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlJoin(%08x) at %08x", scanInfoAddr, currentMIPS->pc); +int sceNetAdhocctlJoin(u32 scanInfoAddr) { + INFO_LOG(SCENET, "sceNetAdhocctlJoin(%08x) at %08x", scanInfoAddr, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; } @@ -1631,11 +1639,14 @@ static int sceNetAdhocctlJoin(u32 scanInfoAddr) { if (Memory::IsValidAddress(scanInfoAddr)) { SceNetAdhocctlScanInfoEmu* sinfo = (SceNetAdhocctlScanInfoEmu*)Memory::GetPointer(scanInfoAddr); - //while (true) sleep_ms(1); + char grpName[9] = { 0 }; + memcpy(grpName, sinfo->group_name.data, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + DEBUG_LOG(SCENET, "sceNetAdhocctlJoin - Group: %s", grpName); // We can ignore minor connection process differences here // TODO: Adhoc Server may need to be changed to differentiate between Host/Create and Join, otherwise it can't support multiple Host using the same Group name, thus causing one of the Host to be confused being treated as Join. - return NetAdhocctl_Create((const char*)&sinfo->group_name); + adhocConnectionType = ADHOC_JOIN; + return NetAdhocctl_Create(grpName); } // Invalid Argument @@ -4055,26 +4066,48 @@ void __NetTriggerCallbacks() args[0] = flags; args[1] = error; - //if (/*__KernelGetCurThread() == threadAdhocID &&*/ (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) && IsAdhocctlInCallback() == 0) + // FIXME: When Joining a group, Do we need to wait for group creator's peer data before triggering the callback to make sure the game not to thinks we're the group creator? + if (flags != ADHOCCTL_EVENT_CONNECT || adhocConnectionType != ADHOC_JOIN || getActivePeerCount() > 0) { // Since 0 is a valid index to types_ we use -1 to detects if it was loaded from an old save state if (actionAfterAdhocMipsCall < 0) { actionAfterAdhocMipsCall = __KernelRegisterActionType(AfterAdhocMipsCall::Create); } + + delayus = (adhocEventPollDelayMS + 2 * adhocExtraPollDelayMS) * 1000; // Added an extra delay to prevent I/O Timing method from causing disconnection + switch (flags) { + case ADHOCCTL_EVENT_CONNECT: + adhocctlState = ADHOCCTL_STATE_CONNECTED; + delayus = (adhocEventDelayMS + 2 * adhocExtraPollDelayMS) * 1000; // May affects Dissidia 012 and GTA VCS + break; + case ADHOCCTL_EVENT_SCAN: // notified only when scan completed? + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + break; + case ADHOCCTL_EVENT_DISCONNECT: + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + break; + case ADHOCCTL_EVENT_GAME: + adhocctlState = ADHOCCTL_STATE_GAMEMODE; + break; + case ADHOCCTL_EVENT_DISCOVER: + adhocctlState = ADHOCCTL_STATE_DISCOVER; + break; + case ADHOCCTL_EVENT_WOL_INTERRUPT: + adhocctlState = ADHOCCTL_STATE_WOL; + break; + case ADHOCCTL_EVENT_ERROR: + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + break; + } + for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { DEBUG_LOG(SCENET, "AdhocctlCallback: [ID=%i][EVENT=%i]", it->first, flags); args[2] = it->second.argument; AfterAdhocMipsCall* after = (AfterAdhocMipsCall*)__KernelCreateAction(actionAfterAdhocMipsCall); after->SetData(it->first, flags, args[2]); - //SetAdhocctlInCallback(true); - //__KernelDirectMipsCall(it->second.entryPoint, after, args, 3, true); hleEnqueueCall(it->second.entryPoint, 3, args, after); } adhocctlEvents.pop_front(); - if (flags == ADHOCCTL_EVENT_CONNECT) - delayus = (adhocEventDelayMS + 2*adhocExtraPollDelayMS) * 1000; // May affects Dissidia 012 and GTA VCS - else - delayus = (adhocEventPollDelayMS + 2*adhocExtraPollDelayMS) * 1000; // Added an extra delay to prevent I/O Timing method from causing disconnection } } @@ -4118,7 +4151,7 @@ void __NetMatchingCallbacks() //(int matchingId) const HLEFunction sceNetAdhoc[] = { {0XE1D621D7, &WrapU_V, "sceNetAdhocInit", 'x', "" }, {0XA62C6F57, &WrapI_V, "sceNetAdhocTerm", 'i', "" }, - {0X0AD043ED, &WrapI_U, "sceNetAdhocctlConnect", 'i', "x" }, + {0X0AD043ED, &WrapI_C, "sceNetAdhocctlConnect", 'i', "s" }, {0X6F92741B, &WrapI_CIIU, "sceNetAdhocPdpCreate", 'i', "siix" }, {0XABED3790, &WrapI_ICUVIII, "sceNetAdhocPdpSend", 'i', "isxpiii" }, {0XDFE53E03, &WrapI_IVVVVUI, "sceNetAdhocPdpRecv", 'i', "ippppxi" }, @@ -4386,7 +4419,7 @@ const HLEFunction sceNetAdhocctl[] = { {0X20B317A0, &WrapU_UU, "sceNetAdhocctlAddHandler", 'x', "xx" }, {0X6402490B, &WrapU_U, "sceNetAdhocctlDelHandler", 'x', "x" }, {0X34401D65, &WrapU_V, "sceNetAdhocctlDisconnect", 'x', "" }, - {0X0AD043ED, &WrapI_U, "sceNetAdhocctlConnect", 'i', "x" }, + {0X0AD043ED, &WrapI_C, "sceNetAdhocctlConnect", 'i', "s" }, {0X08FFF7A0, &WrapI_V, "sceNetAdhocctlScan", 'i', "" }, {0X75ECD386, &WrapI_U, "sceNetAdhocctlGetState", 'i', "x" }, {0X8916C003, &WrapI_CU, "sceNetAdhocctlGetNameByAddr", 'i', "sx" }, diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 98a859411d..bcd3ad6c73 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -41,7 +41,18 @@ void __UpdateAdhocctlHandlers(u32 flags, u32 error); void __UpdateMatchingHandler(MatchingArgs params); // I have to call this from netdialog +int sceNetAdhocctlGetState(u32 ptrToStatus); int sceNetAdhocctlCreate(const char * groupName); +int sceNetAdhocctlConnect(const char* groupName); +int sceNetAdhocctlJoin(u32 scanInfoAddr); +int sceNetAdhocctlScan(); +int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr); + +int NetAdhocMatching_Term(); +int NetAdhocctl_Term(); +int NetAdhocctl_GetState(); +int NetAdhocctl_Create(const char* groupName); +int NetAdhoc_Term(); // May need to use these from sceNet.cpp extern bool netAdhocInited; @@ -60,7 +71,3 @@ extern u32_le dummyThreadCode[3]; extern u32 matchingThreadHackAddr; extern u32_le matchingThreadCode[3]; -int NetAdhocMatching_Term(); -int NetAdhocctl_Term(); -int NetAdhocctl_GetState(); -int NetAdhoc_Term(); From 7d2236db2f9ac43da0c164ff33c2c377cec9de2b Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 31 Aug 2020 11:00:04 +0700 Subject: [PATCH 624/848] Increasing the shutdown delay so that there will be at least one "4=sceUtilityNetconfGetStatus()" after "0=sceUtilityNetconfShutdownStart()" instead of directly to "0=sceUtilityNetconfGetStatus()" (just like what happen when using utility.prx file with KHBBS on JPCSP) --- Core/Dialog/PSPNetconfDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index a218382d68..93571ce2ff 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -45,7 +45,7 @@ static const float FONT_SCALE = 0.65f; // Needs testing. const static int NET_INIT_DELAY_US = 300000; -const static int NET_SHUTDOWN_DELAY_US = 26000; +const static int NET_SHUTDOWN_DELAY_US = 260000; const static int NET_RUNNING_DELAY_US = 1000000; // KHBBS is showing adhoc dialog for about 3-4 seconds, but feels too long, so we're faking it to 1 sec instead to let players read the text const static int NET_CONNECT_TIMEOUT = 5000000; From 439171fc563f0161c15934d678fd503a58e2e2f6 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 18 Aug 2020 02:01:30 +0700 Subject: [PATCH 625/848] An attempt to reduce the lags/stutters during multiplayer caused by improper blocking behavior. --- Core/HLE/proAdhoc.cpp | 26 +- Core/HLE/proAdhoc.h | 11 +- Core/HLE/sceKernelThread.cpp | 1 + Core/HLE/sceKernelThread.h | 1 + Core/HLE/sceNet.cpp | 6 +- Core/HLE/sceNetAdhoc.cpp | 1195 +++++++++++++++++++++++----------- Core/HLE/sceNetAdhoc.h | 34 + 7 files changed, 898 insertions(+), 376 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index b8f57cca83..8458b2c9f1 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -55,6 +55,7 @@ bool friendFinderRunning = false; SceNetAdhocctlPeerInfo * friends = NULL; SceNetAdhocctlScanInfo * networks = NULL; SceNetAdhocctlScanInfo * newnetworks = NULL; +u64 adhocctlStartTime = 0; int adhocctlState = ADHOCCTL_STATE_DISCONNECTED; int adhocConnectionType = ADHOC_CONNECT; @@ -71,6 +72,7 @@ std::thread friendFinderThread; std::recursive_mutex peerlock; SceNetAdhocPdpStat * pdp[255]; SceNetAdhocPtpStat * ptp[255]; +std::map ptpConnectCount; std::vector chatLog; std::string name = ""; std::string incoming = ""; @@ -210,6 +212,15 @@ SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC) { return peer; } +int getNonBlockingFlag(int fd) { +#ifdef _WIN32 + return 0; +#else + int sockflag = fcntl(fd, F_GETFL, O_NONBLOCK); + return sockflag & O_NONBLOCK; +#endif +} + void changeBlockingMode(int fd, int nonblocking) { unsigned long on = 1; unsigned long off = 0; @@ -321,6 +332,7 @@ void deleteAllPTP() { // Delete Reference ptp[i] = NULL; + ptpConnectCount.erase(i); } } } @@ -1174,7 +1186,9 @@ void sendChat(std::string chatString) { message = chatString.substr(0, 60); // 64 return chat variable corrupted is it out of memory? strcpy(chat.message, message.c_str()); //Send Chat Messages + changeBlockingMode(metasocket, 0); int chatResult = send(metasocket, (const char *)&chat, sizeof(chat), 0); + changeBlockingMode(metasocket, 1); NOTICE_LOG(SCENET, "Send Chat %s to Adhoc Server", chat.message); name = g_Config.sNickName.c_str(); chatLog.push_back(name.substr(0, 8) + ": " + chat.message); @@ -1245,7 +1259,9 @@ int friendFinder(){ uint8_t opcode = OPCODE_PING; // Send Ping to Server, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) + changeBlockingMode(metasocket, 0); int iResult = send(metasocket, (const char*)&opcode, 1, 0); + changeBlockingMode(metasocket, 1); if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "FriendFinder: Socket Error (%i) when sending OPCODE_PING", errno); networkInited = false; @@ -1560,7 +1576,10 @@ int getLocalIp(sockaddr_in* SocketAddress) { struct sockaddr_in localAddr; localAddr.sin_addr.s_addr = INADDR_ANY; socklen_t addrLen = sizeof(localAddr); - if (SOCKET_ERROR != getsockname(metasocket, (struct sockaddr*) & localAddr, &addrLen)) { + changeBlockingMode(metasocket, 0); + int ret = getsockname(metasocket, (struct sockaddr*)&localAddr, &addrLen); + changeBlockingMode(metasocket, 1); + if (SOCKET_ERROR != ret) { if (isLocalServer) { localAddr.sin_addr = g_localhostIP.in.sin_addr; } @@ -1905,8 +1924,6 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ sleep_ms(1); cnt++; } - // Switch back to Blocking Behaviour - changeBlockingMode(metasocket, 0); if (iResult == SOCKET_ERROR && errorcode != EISCONN) { char buffer[512]; snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); @@ -1924,8 +1941,9 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ strncpy((char *)&packet.name.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN); packet.name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; memcpy(packet.game.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); + changeBlockingMode(metasocket, 0); int sent = send(metasocket, (char*)&packet, sizeof(packet), 0); - changeBlockingMode(metasocket, 1); // Change to non-blocking + changeBlockingMode(metasocket, 1); if (sent > 0) { socklen_t addrLen = sizeof(LocalIP); memset(&LocalIP, 0, addrLen); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index c3607e4d36..fa5194f17e 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -827,6 +827,7 @@ extern std::thread friendFinderThread; extern std::recursive_mutex peerlock; extern SceNetAdhocPdpStat * pdp[255]; extern SceNetAdhocPtpStat * ptp[255]; +extern std::map ptpConnectCount; union SockAddrIN4 { sockaddr addr; @@ -846,7 +847,8 @@ extern SceNetAdhocMatchingContext * contexts; extern int one; extern bool friendFinderRunning; extern SceNetAdhocctlPeerInfo * friends; -extern SceNetAdhocctlScanInfo * networks; +extern SceNetAdhocctlScanInfo * networks; +extern u64 adhocctlStartTime; extern int adhocctlState; extern int adhocConnectionType; // End of Aux vars @@ -925,6 +927,13 @@ extern int newChat; */ SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC); +/** + * Get the Non-Blocking Mode of the socket + * @param fd File Descriptor of the socket + * @return 1 for non-blocking, 0 for blocking + */ +int getNonBlockingFlag(int fd); + /** * Changes the Blocking Mode of the socket * @param fd File Descriptor of the socket diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 59b3ec3c7e..0e096111c0 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -81,6 +81,7 @@ const WaitTypeNames waitTypeNames[] = { { WAITTYPE_VMEM, "Volatile Mem" }, { WAITTYPE_ASYNCIO, "AsyncIO" }, { WAITTYPE_MICINPUT, "Microphone input"}, + { WAITTYPE_NET, "Network"}, }; const char *getWaitTypeName(WaitType type) diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index d36e12c986..bb08bb3b66 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -107,6 +107,7 @@ enum WaitType : int WAITTYPE_VMEM = 22, WAITTYPE_ASYNCIO = 23, WAITTYPE_MICINPUT = 24, // fake + WAITTYPE_NET = 25, // fake NUM_WAITTYPES }; diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index a7d073ee1c..a34167f275 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -162,7 +162,7 @@ void __NetInit() { SceNetEtherAddr mac; getLocalMac(&mac); - INFO_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(g_localhostIP.in.sin_addr), mac2str(&mac).c_str()); + NOTICE_LOG(SCENET, "LocalHost IP will be %s [%s]", inet_ntoa(g_localhostIP.in.sin_addr), mac2str(&mac).c_str()); // TODO: May be we should initialize & cleanup somewhere else than here for PortManager to be used as general purpose for whatever port forwarding PPSSPP needed __UPnPInit(); @@ -250,6 +250,9 @@ void __NetDoState(PointerWrap &p) { netInetInited = cur_netInetInited; netInited = cur_netInited; + // Discard leftover events + apctlEvents.clear(); + // Previously, this wasn't being saved. It needs its own space. if (!apctlThreadHackAddr || (apctlThreadHackAddr && strcmp("apctlThreadHack", kernelMemory.GetBlockTag(apctlThreadHackAddr)) != 0)) { u32 blockSize = sizeof(apctlThreadCode); @@ -582,6 +585,7 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini // Clear Socket Translator Memory memset(&pdp, 0, sizeof(pdp)); memset(&ptp, 0, sizeof(ptp)); + ptpConnectCount.clear(); return hleLogSuccessI(SCENET, 0); } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 5aaa6aa0c4..9d62792037 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -15,6 +15,10 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#if defined(_WIN32) +#include "Common/CommonWindows.h" +#endif + #if !defined(_WIN32) #include #endif @@ -46,6 +50,7 @@ #include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/sceNet.h" #include "Core/HLE/proAdhocServer.h" +#include "Core/HLE/KernelWaitHelpers.h" #include "i18n/i18n.h" // shared in sceNetAdhoc.h since it need to be used from sceNet.cpp also @@ -56,11 +61,11 @@ bool networkInited = false; static bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; -int adhocDefaultTimeout = 2000; //5000 +int adhocDefaultTimeout = 2000; //5000 ms int adhocExtraPollDelayMS = 10; //10 int adhocEventPollDelayMS = 100; //100 int adhocMatchingEventDelayMS = 30; //30 -int adhocEventDelayMS = 500; //500; This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 +int adhocEventDelayMS = 300; //500; This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 SceUID threadAdhocID; @@ -71,6 +76,11 @@ std::map adhocctlHandlers; std::vector matchingThreads; int IsAdhocctlInCB = 0; +int adhocctlNotifyEvent = -1; +int adhocSocketNotifyEvent = -1; +std::map adhocSocketRequests; +std::map sendTargetPeers; + u32 dummyThreadHackAddr = 0; u32_le dummyThreadCode[3]; u32 matchingThreadHackAddr = 0; @@ -78,11 +88,9 @@ u32_le matchingThreadCode[3]; int matchingEventThread(int matchingId); int matchingInputThread(int matchingId); +int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port); +int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout); -int sceNetAdhocTerm(); -int sceNetAdhocctlTerm(); -int sceNetAdhocMatchingTerm(); -int sceNetAdhocMatchingSetHelloOpt(int matchingId, int optLenAddr, u32 optDataAddr); void __NetAdhocShutdown() { // Kill AdhocServer Thread @@ -112,6 +120,455 @@ void __NetAdhocShutdown() { } } +static void __AdhocctlNotify(u64 userdata, int cyclesLate) { + SceUID threadID = userdata >> 32; + int uid = (int)(userdata & 0xFFFFFFFF); + + s64 result = 0; + u32 error = 0; + + SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_NET, error); + if (waitID == 0 || error != 0) + return; // FIXME: Is it safe to exit here like this without re-scheduling the event? Will this event be triggered again? What will happen to the result i might want to change if exited here? + + int waitVal = __KernelGetWaitValue(threadID, error); // FIXME: Is this value going to be a valid value if waitID == 0? or it's a value belonged to other event? + if (adhocctlState != waitVal && error == 0) { + // Detecting Adhocctl Initialization using waitVal < 0 + if (waitVal >= 0 || (waitVal < 0 && (g_Config.bEnableWlan && !networkInited))) { + u64 now = (u64)(real_time_now() * 1000.0); + if (now - adhocctlStartTime <= adhocDefaultTimeout) { + // Try again in another 0.5ms until state matched or timedout. + CoreTiming::ScheduleEvent(usToCycles(500) - cyclesLate, adhocctlNotifyEvent, userdata); + return; + } + else + result = 0; // ERROR_NET_ADHOCCTL_BUSY + } + else + result = 0; // Faking successfully connected to adhoc server + } + + //HLEKernel::ResumeFromWait(threadID, WAITTYPE_NET, uid, result); // FIXME: This won't do anything if waitID == 0, not sure what kind of value returned from the HLE which i might want to change here. + __KernelResumeThreadFromWait(threadID, result); // FIXME: Forcing to change the result, will it cause an issue if waitID == 0? + DEBUG_LOG(SCENET, "Returning (WaitID: %d, error: %d) Result (%08x) of sceNetAdhocctl - State: %d", waitID, error, (int)result, adhocctlState); +} + +void WaitAdhocctlState(int state, int usec, const char* reason) { + if (adhocctlNotifyEvent < 0) + adhocctlNotifyEvent = CoreTiming::RegisterEvent("__AdhocctlNotify", __AdhocctlNotify); + + int uid = (state < 0)? 1: metasocket; + u64 param = ((u64)__KernelGetCurThread()) << 32 | uid; + adhocctlStartTime = (u64)(real_time_now() * 1000.0); + CoreTiming::ScheduleEvent(usToCycles(usec), adhocctlNotifyEvent, param); + __KernelWaitCurThread(WAITTYPE_NET, uid, state, 0, false, reason); +} + +int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { + sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + socklen_t sinlen = sizeof(sin); + + int ret = recvfrom(uid, (char*)req.buffer, *req.length, MSG_PEEK, (sockaddr*)&sin, &sinlen); + int sockerr = errno; + + // Note: UDP must not be received partially, otherwise leftover data in socket's buffer will be discarded + if (ret >= 0 && ret <= *req.length) { + ret = recvfrom(uid, (char*)req.buffer, *req.length, 0, (sockaddr*)&sin, &sinlen); + // UDP can also receives 0 data, while on TCP receiving 0 data = connection gracefully closed, but not sure whether PDP can send/recv 0 data or not tho + if (ret > 0) { + DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", req.id, getLocalPort(uid), ret, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + + // Peer MAC + SceNetEtherAddr mac; + + // Find Peer MAC + if (resolveIP(sin.sin_addr.s_addr, &mac)) { + // Provide Sender Information + *req.remoteMAC = mac; + *req.remotePort = ntohs(sin.sin_port) - portOffset; + + // Save Length + *req.length = ret; + + // Update last recv timestamp + peerlock.lock(); + auto peer = findFriend(&mac); + if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + peerlock.unlock(); + } + // Unknown Peer + else { + *req.length = ret; + *req.remotePort = ntohs(sin.sin_port) - portOffset; + + WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %i bytes from Unknown Peer %s:%u", req.id, getLocalPort(uid), ret, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + } + } + result = 0; + } + // On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound yet), may need to disable SIO_UDP_CONNRESET error + else if (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ECONNRESET || sockerr == ETIMEDOUT) { + u64 now = (u64)(real_time_now() * 1000000.0); + if (req.timeout == 0 || now - req.startTime <= req.timeout) { + + return -1; + } + else + result = ERROR_NET_ADHOC_TIMEOUT; + } + else + result = ERROR_NET_ADHOC_INVALID_ARG; // ERROR_NET_ADHOC_DISCONNECTED + + if (ret == SOCKET_ERROR) + DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i]: Socket Error (%i)", req.id, sockerr); + + return 0; +} + +int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTargets& targetPeers) { + SceNetAdhocPdpStat* pdpsocket = pdp[req.id - 1]; + + result = 0; + bool retry = false; + for (auto peer = targetPeers.peers.begin(); peer != targetPeers.peers.end(); ) { + // Fill in Target Structure + sockaddr_in target; + target.sin_family = AF_INET; + target.sin_addr.s_addr = peer->ip; + target.sin_port = htons(peer->port + ((isOriPort && !isPrivateIP(peer->ip)) ? 0 : portOffset)); + + int ret = sendto(pdpsocket->id, (const char*)req.buffer, targetPeers.length, 0, (sockaddr*)&target, sizeof(target)); + int sockerr = errno; + + if (ret >= 0) { + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](B): Sent %u bytes to %s:%u\n", uid, getLocalPort(pdpsocket->id), ret, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); + // Remove successfully sent to peer to prevent sending the same data again during a retry + peer = targetPeers.peers.erase(peer); + } + else { + if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { + u64 now = (u64)(real_time_now() * 1000000.0); + if (req.timeout == 0 || now - req.startTime <= req.timeout) { + retry = true; + } + else + // FIXME: Does Broadcast always success? even with timeout/blocking? + result = ERROR_NET_ADHOC_TIMEOUT; + } + ++peer; + } + + if (ret == SOCKET_ERROR) + DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](B) [size=%i]", sockerr, uid, getLocalPort(pdpsocket->id), ntohs(target.sin_port), targetPeers.length); + } + + if (retry) + return -1; + + return 0; +} + +int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { + SceNetAdhocPtpStat* ptpsocket = ptp[req.id - 1]; + + // Send Data + int ret = send(uid, (const char*)req.buffer, *req.length, 0); + int sockerr = errno; + + // Success + if (ret > 0) { + // Save Length + *req.length = ret; + + DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u\n", req.id, ptpsocket->lport, ret, mac2str(&ptpsocket->paddr).c_str(), ptpsocket->pport); + + // Return Success + result = 0; + } + + // Non-Critical Error + else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { + u64 now = (u64)(real_time_now() * 1000000.0); + if (req.timeout == 0 || now - req.startTime <= req.timeout) { + + return -1; + } + else + result = ERROR_NET_ADHOC_TIMEOUT; + } + + // Change Socket State + ptpsocket->state = ADHOC_PTP_STATE_CLOSED; + + // Disconnected + result = ERROR_NET_ADHOC_DISCONNECTED; + + if (ret == SOCKET_ERROR) + DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i]: Socket Error (%i)", req.id, sockerr); + + return 0; +} + +int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { + SceNetAdhocPtpStat* ptpsocket = ptp[req.id - 1]; + + int ret = recv(uid, (char*)req.buffer, *req.length, 0); + int sockerr = errno; + + // Received Data + if (ret > 0) { + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u\n", req.id, ptpsocket->lport, ret, mac2str(&ptpsocket->paddr).c_str(), ptpsocket->pport); + // Save Length + *req.length = ret; + + // Update last recv timestamp + peerlock.lock(); + auto peer = findFriend(&ptpsocket->paddr); + if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + peerlock.unlock(); + + result = 0; + } + // Non-Critical Error + else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { + u64 now = (u64)(real_time_now() * 1000000.0); + if (req.timeout == 0 || now - req.startTime <= req.timeout) { + return -1; + } + else + result = ERROR_NET_ADHOC_TIMEOUT; + } + else { + // Change Socket State + ptpsocket->state = ADHOC_PTP_STATE_CLOSED; + + // Disconnected + result = ERROR_NET_ADHOC_DISCONNECTED; // ERROR_NET_ADHOC_INVALID_ARG + } + + if (ret == SOCKET_ERROR) + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i]: Socket Error (%i)", req.id, sockerr); + + return 0; +} + +int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { + sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + socklen_t sinlen = sizeof(sin); + + // Accept Connection + int ret = accept(uid, (sockaddr*)&sin, &sinlen); + int sockerr = errno; + + // Accepted New Connection + if (ret > 0) { + int newid = AcceptPtpSocket(req.id, ret, sin, req.remoteMAC, req.remotePort); + if (newid > 0) + result = newid; + } + else if (ret == SOCKET_ERROR && connectInProgress(sockerr)) { + u64 now = (u64)(real_time_now() * 1000000.0); + if (req.timeout == 0 || now - req.startTime <= req.timeout) { + return -1; + } + else + result = ERROR_NET_ADHOC_TIMEOUT; + } + else + result = ERROR_NET_ADHOC_INVALID_ARG; //ERROR_NET_ADHOC_TIMEOUT + + if (ret == SOCKET_ERROR) + DEBUG_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Socket Error (%i)", req.id, sockerr); + + return 0; +} + +int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { + fd_set readfds, writefds; + timeval tval; + FD_ZERO(&readfds); + FD_SET(uid, &readfds); + writefds = readfds; + tval.tv_sec = 0; + tval.tv_usec = 0; + + // Wait for Connection (assuming "connect" has been called before) + int ret = select(uid + 1, &readfds, &writefds, NULL, &tval); + int sockerr = errno; + + // Connection is ready + if (ret > 0) { + SceNetAdhocPtpStat* ptpsocket = ptp[req.id - 1]; + sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + socklen_t sinlen = sizeof(sin); + getpeername(uid, (sockaddr*)&sin, &sinlen); + + // Set Connected State + ptpsocket->state = ADHOC_PTP_STATE_ESTABLISHED; + + INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Established (%s:%u)", req.id, ptpsocket->lport, inet_ntoa(sin.sin_addr), ptpsocket->pport); + + // Success + result = 0; + } + // Timeout + else if (ret == 0) { + u64 now = (u64)(real_time_now() * 1000000.0); + if (req.timeout == 0 || now - req.startTime <= req.timeout) { + return -1; + } + else + result = ERROR_NET_ADHOC_TIMEOUT; + } + else + result = ERROR_NET_ADHOC_CONNECTION_REFUSED; // ERROR_NET_ADHOC_TIMEOUT; + + if (ret == SOCKET_ERROR) + DEBUG_LOG(SCENET, "sceNetAdhocPtpConnect[%i]: Socket Error (%i)", req.id, sockerr); + + return 0; +} + +int DoBlockingAdhocPollSocket(int uid, AdhocSocketRequest& req, s64& result) { + SceNetAdhocPollSd* sds = (SceNetAdhocPollSd*)req.buffer; + int ret = PollAdhocSocket(sds, req.id, 0); + if (ret <= 0) { + u64 now = (u64)(real_time_now() * 1000000.0); + if (req.timeout == 0 || now - req.startTime <= req.timeout) { + return -1; + } + else if (ret == 0) + result = ERROR_NET_ADHOC_TIMEOUT; + else + result = ERROR_NET_ADHOC_EXCEPTION_EVENT; + } + result = ret; + + return 0; +} + +static void __AdhocSocketNotify(u64 userdata, int cyclesLate) { + SceUID threadID = userdata >> 32; + int uid = (int)(userdata & 0xFFFFFFFF); // fd/socket id + + s64 result = -1; + u32 error = 0; + int delayUS = 500; + + SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_NET, error); + if (waitID == 0 || error != 0) + return; + + // Socket not found?! Should never happened! but if it ever happen should we just exit here or need to wake the thread first? + if (adhocSocketRequests.find(uid) == adhocSocketRequests.end()) { + WARN_LOG(SCENET, "sceNetAdhoc Socket WaitID(%i) not found!", uid); + //__KernelResumeThreadFromWait(threadID, ERROR_NET_ADHOC_TIMEOUT); + return; + } + + AdhocSocketRequest req = adhocSocketRequests[uid]; + + switch (req.type) { + case PDP_SEND: + if (sendTargetPeers.find(uid) == sendTargetPeers.end()) { + // No destination peers? + result = 0; + break; + } + if (DoBlockingPdpSend(uid, req, result, sendTargetPeers[uid])) { + // Try again in another 0.5ms until data available or timedout. + CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); + return; + } + sendTargetPeers.erase(uid); + break; + + case PDP_RECV: + if (DoBlockingPdpRecv(uid, req, result)) { + // Try again in another 0.5ms until data available or timedout. + CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); + return; + } + break; + + case PTP_SEND: + if (DoBlockingPtpSend(uid, req, result)) { + // Try again in another 0.5ms until data available or timedout. + CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); + return; + } + break; + + case PTP_RECV: + if (DoBlockingPtpRecv(uid, req, result)) { + // Try again in another 0.5ms until data available or timedout. + CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); + return; + } + break; + + case PTP_ACCEPT: + if (DoBlockingPtpAccept(uid, req, result)) { + // Try again in another 0.5ms until data available or timedout. + CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); + return; + } + break; + + case PTP_CONNECT: + if (DoBlockingPtpConnect(uid, req, result)) { + // Try again in another 0.5ms until data available or timedout. + CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); + return; + } + break; + + case ADHOC_POLL_SOCKET: + if (DoBlockingAdhocPollSocket(uid, req, result)) { + // Try again in another 0.5ms until data available or timedout. + CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); + return; + } + break; + } + + // We are done with this socket + adhocSocketRequests.erase(uid); + + __KernelResumeThreadFromWait(threadID, result); + DEBUG_LOG(SCENET, "Returning (WaitID: %d, error: %d) Result (%08x) of sceNetAdhoc - SocketID: %d", waitID, error, (int)result, req.id); +} + +int WaitBlockingAdhocSocket(int socketId, int type, int pspSocketId, void* buffer, s32_le* len, u32 timeoutUS, SceNetEtherAddr* remoteMAC, u16_le* remotePort, const char* reason) { + if (adhocSocketRequests.find(socketId) != adhocSocketRequests.end()) { + WARN_LOG(SCENET, "sceNetAdhoc - WaitID[%d] already existed, Socket[%d] is busy!", socketId, pspSocketId); + return ERROR_NET_ADHOC_BUSY; + } + + if (adhocSocketNotifyEvent < 0) + adhocSocketNotifyEvent = CoreTiming::RegisterEvent("__AdhocSocketNotify", __AdhocSocketNotify); + + if (getNonBlockingFlag(socketId) == 0) + changeBlockingMode(socketId, 1); + + u32 tmout = timeoutUS; + if (tmout > 0) + tmout = std::max(tmout, minSocketTimeoutUS); + + u64 param = ((u64)__KernelGetCurThread()) << 32 | socketId; + u64 startTime = (u64)(real_time_now() * 1000000.0); + adhocSocketRequests[socketId] = { type, pspSocketId, buffer, len, tmout, startTime, remoteMAC, remotePort }; + // Some games (ie. Power Stone Collection) are using as small as 100 usec timeout + CoreTiming::ScheduleEvent(usToCycles(100), adhocSocketNotifyEvent, param); + __KernelWaitCurThread(WAITTYPE_NET, socketId, 0, 0, false, reason); + + // Fallback return value + return ERROR_NET_ADHOC_TIMEOUT; +} + void __NetAdhocDoState(PointerWrap &p) { auto s = p.Section("sceNetAdhoc", 1, 5); if (!s) @@ -159,10 +616,16 @@ void __NetAdhocDoState(PointerWrap &p) { if (s >= 5) { Do(p, adhocConnectionType); Do(p, adhocctlState); + Do(p, adhocctlNotifyEvent); + CoreTiming::RestoreRegisterEvent(adhocctlNotifyEvent, "__AdhocctlNotify", __AdhocctlNotify); + Do(p, adhocSocketNotifyEvent); + CoreTiming::RestoreRegisterEvent(adhocSocketNotifyEvent, "__AdhocSocketNotify", __AdhocSocketNotify); } else { adhocConnectionType = ADHOC_CONNECT; adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + adhocctlNotifyEvent = -1; + adhocSocketNotifyEvent = -1; } if (p.mode == p.MODE_READ) { @@ -179,6 +642,12 @@ void __NetAdhocDoState(PointerWrap &p) { // Restore dummy Loop MIPS code to prevent crashes after loading from SaveState if (dummyThreadHackAddr) Memory::Memcpy(dummyThreadHackAddr, dummyThreadCode, sizeof(dummyThreadCode)); if (matchingThreadHackAddr) Memory::Memcpy(matchingThreadHackAddr, matchingThreadCode, sizeof(matchingThreadCode)); + + // Discard leftover events + adhocctlEvents.clear(); + matchingEvents.clear(); + adhocSocketRequests.clear(); + sendTargetPeers.clear(); // Let's not change "Inited" value when Loading SaveState to prevent memory & port leaks netAdhocMatchingInited = cur_netAdhocMatchingInited; @@ -197,15 +666,6 @@ void __UpdateMatchingHandler(MatchingArgs ArgsPtr) { matchingEvents.push_back(ArgsPtr); } -static int getBlockingFlag(int id) { -#ifdef _WIN32 - return 0; -#else - int sockflag = fcntl(id, F_GETFL, O_NONBLOCK); - return sockflag & O_NONBLOCK; -#endif -} - u32_le __CreateHLELoop(u32_le *loopAddr, const char *sceFuncName, const char *hleFuncName, const char *tagName) { if (loopAddr == NULL || sceFuncName == NULL || hleFuncName == NULL) return 0; @@ -219,12 +679,21 @@ u32_le __CreateHLELoop(u32_le *loopAddr, const char *sceFuncName, const char *hl return dummyThreadHackAddr; } +void __AdhocNotifInit() { + adhocctlNotifyEvent = CoreTiming::RegisterEvent("__AdhocctlNotify", __AdhocctlNotify); + adhocSocketNotifyEvent = CoreTiming::RegisterEvent("__AdhocSocketNotify", __AdhocSocketNotify); + + adhocSocketRequests.clear(); + sendTargetPeers.clear(); +} + void __NetAdhocInit() { friendFinderRunning = false; netAdhocInited = false; netAdhocctlInited = false; netAdhocMatchingInited = false; adhocctlHandlers.clear(); + __AdhocNotifInit(); __AdhocServerInit(); // Create built-in AdhocServer Thread @@ -273,13 +742,14 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { } // Need to make sure to be connected to adhoc server before returning to prevent GTA VCS failed to create/join a group and unable to see any game room - int cnt = 0; - while (g_Config.bEnableWlan && !networkInited && (cnt < adhocDefaultTimeout)) { - sleep_ms(1); - cnt++; + int us = adhocExtraPollDelayMS * 1000; + if (g_Config.bEnableWlan && !networkInited) { + WaitAdhocctlState(-1, us, "adhoc init"); } + // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? + else + hleDelayResult(0, "give some time", us); - //hleDelayResult(0, "give some time", adhocEventPollDelayMS * 1000); // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? return 0; } @@ -539,13 +1009,27 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int //_acquireNetworkLock(); // Send Data. UDP are guaranteed to be sent as a whole or nothing(failed if len > SO_MAX_MSG_SIZE), and never be partially sent/recv - changeBlockingMode(socket->id, flag); + changeBlockingMode(socket->id, 1); int sent = sendto(socket->id, (const char *)data, len, 0, (sockaddr *)&target, sizeof(target)); int error = errno; + if (sent == SOCKET_ERROR) { + // Simulate blocking behaviour with non-blocking socket + if (!flag && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT)) { + if (sendTargetPeers.find(socket->id) != sendTargetPeers.end()) { + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Socket(%d) is Busy!", id, getLocalPort(socket->id), socket->id); + return ERROR_NET_ADHOC_BUSY; + } + + AdhocSendTargets dest = { len, {}, false }; + dest.peers.push_back({ target.sin_addr.s_addr, dport }); + sendTargetPeers[socket->id] = dest; + return WaitBlockingAdhocSocket(socket->id, PDP_SEND, id, data, nullptr, timeout, nullptr, nullptr, "pdp send"); + } + DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u] (size=%i)", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); } - changeBlockingMode(socket->id, 0); + //changeBlockingMode(socket->id, 0); // Free Network Lock //_freeNetworkLock(); @@ -558,13 +1042,12 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int return 0; // sent; // MotorStorm will try to resend if return value is not 0 } - // Blocking Situation - if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; + // Non-Blocking + if (flag) + return ERROR_NET_ADHOC_WOULD_BLOCK; - // Timeout - /*if (timeout > 0) - return ERROR_NET_ADHOC_TIMEOUT;*/ - return ERROR_NET_ADHOC_INVALID_ADDR; // There is no concept of Timeout when sending UDP due to no ACK, not sure about PDP since some games did use the timeout arg + // Does PDP can Timeout? There is no concept of Timeout when sending UDP due to no ACK, but might happen if the socket buffer is full, not sure about PDP since some games did use the timeout arg + return ERROR_NET_ADHOC_TIMEOUT; // ERROR_NET_ADHOC_INVALID_ADDR; } //VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Unknown Target Peer %s:%u\n", id, getLocalPort(socket->id), mac2str(daddr, tmpmac), ntohs(target.sin_port)); } @@ -590,38 +1073,55 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Acquire Peer Lock peerlock.lock(); - - // Send Data - changeBlockingMode(socket->id, flag); // Do we need to switched to blocking-mode to make sure the data are fully sent? - + AdhocSendTargets dest = { len, {}, true }; // Iterate Peers - SceNetAdhocctlPeerInfo * peer = friends; + SceNetAdhocctlPeerInfo* peer = friends; for (; peer != NULL; peer = peer->next) { // Does Skipping sending to timed out friends could cause desync when players moving group at the time MP game started? - if (peer->last_recv == 0) + if (peer->last_recv == 0) continue; - // Fill in Target Structure - sockaddr_in target; - target.sin_family = AF_INET; - target.sin_addr.s_addr = peer->ip_addr; - target.sin_port = htons(dport + ((isOriPort && !isPrivateIP(peer->ip_addr)) ? 0 : portOffset)); - - int sent = sendto(socket->id, (const char *)data, len, 0, (sockaddr *)&target, sizeof(target)); - int error = errno; - if (sent == SOCKET_ERROR) { - DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](BC) [size=%i]", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); + dest.peers.push_back({ peer->ip_addr, dport }); + } + // Free Peer Lock + peerlock.unlock(); + + // Send Data + changeBlockingMode(socket->id, 1); // Do we need to switched to blocking-mode to make sure the data are fully sent? + + // Simulate blocking behaviour with non-blocking socket + if (!flag) { + if (sendTargetPeers.find(socket->id) != sendTargetPeers.end()) { + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Socket(%d) is Busy!", id, getLocalPort(socket->id), socket->id); + return ERROR_NET_ADHOC_BUSY; } - - if (sent >= 0) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Sent %u bytes to %s:%u\n", id, getLocalPort(socket->id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); + + sendTargetPeers[socket->id] = dest; + return WaitBlockingAdhocSocket(socket->id, PDP_SEND, id, data, nullptr, timeout, nullptr, nullptr, "pdp send broadcast"); + } + // Non-blocking + else { + // Iterate Peers + for (auto peer : dest.peers) { + // Fill in Target Structure + sockaddr_in target; + target.sin_family = AF_INET; + target.sin_addr.s_addr = peer.ip; + target.sin_port = htons(dport + ((isOriPort && !isPrivateIP(peer.ip)) ? 0 : portOffset)); + + int sent = sendto(socket->id, (const char*)data, len, 0, (sockaddr*)&target, sizeof(target)); + int error = errno; + if (sent == SOCKET_ERROR) { + DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](BC) [size=%i]", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); + } + + if (sent >= 0) { + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Sent %u bytes to %s:%u\n", id, getLocalPort(socket->id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); + } } } - changeBlockingMode(socket->id, 0); - - // Free Peer Lock - peerlock.unlock(); + //changeBlockingMode(socket->id, 0); // Free Network Lock //_freeNetworkLock(); @@ -764,23 +1264,18 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * received = recvfrom(socket->id, (char*)buf, *len, 0, (sockaddr*)&sin, &sinlen); error = errno; - if (flag == 0) { - // Simulate blocking behaviour with non-blocking socket - uint32_t starttime = (uint32_t)(real_time_now() * 1000000.0); - // Wait for Connection. On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound), may need to disable SIO_UDP_CONNRESET - while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && (connectInProgress(error) || error == ECONNRESET)) { - received = recvfrom(socket->id, (char*)buf, *len, 0, (sockaddr*)&sin, &sinlen); - error = errno; - // Wait 1ms - sleep_ms(1); - } - } - if (received == SOCKET_ERROR) { + if (flag == 0) { + // Simulate blocking behaviour with non-blocking socket + return WaitBlockingAdhocSocket(socket->id, PDP_RECV, id, buf, len, timeout, saddr, sport, "pdp recv"); + } + VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); } changeBlockingMode(socket->id, 0); + // Should we set output length to 0 on Error? + *len = 0; // Received Data. UDP can also receives 0 data, while on TCP 0 data = connection gracefully closed, but not sure about PDP tho if (received > 0) { @@ -864,6 +1359,57 @@ int sceNetAdhocSetSocketAlert(int id, int flag) { return 0; //Dummy Result } +int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { + //WSAPoll only available for Vista or newer, so we'll use an alternative way for XP since Windows doesn't have poll function like *NIX + fd_set readfds, writefds, exceptfds; + int fd; + int maxfd = 0; + FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); + // TODO: PDP and PTP should share the same indexing to prevent identical PDP & PTP socket id + for (int i = 0; i < count; i++) { + sds[i].revents = 0; + // Fill in Socket ID + if (sds[i].id <= 255 && ptp[sds[i].id - 1] != NULL) { + fd = ptp[sds[i].id - 1]->id; + if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_LISTEN) sds[i].revents |= ADHOC_EV_ACCEPT; + else + if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_CLOSED) sds[i].revents |= ADHOC_EV_CONNECT; + } + else { + fd = pdp[sds[i].id - 256]->id; + } + if (fd > maxfd) maxfd = fd; + if (sds[i].events & ADHOC_EV_RECV) FD_SET(fd, &readfds); + if (sds[i].events & ADHOC_EV_SEND) FD_SET(fd, &writefds); // Does Data can always be sent regardless of events bitmask? + //if (sds[i].events & ADHOC_EV_ALERT) + FD_SET(fd, &exceptfds); // Does Alert can be raised on revents regardless of events bitmask? + } + timeval tmout; + tmout.tv_sec = timeout / 1000000; // seconds + tmout.tv_usec = (timeout % 1000000); // microseconds + int affectedsockets = select(maxfd + 1, &readfds, &writefds, &exceptfds, &tmout); + if (affectedsockets > 0) { + affectedsockets = 0; + for (int i = 0; i < count; i++) { + if (sds[i].id <= 255 && ptp[sds[i].id - 1] != NULL) { + fd = ptp[sds[i].id - 1]->id; + } + else { + fd = pdp[sds[i].id - 256]->id; + } + if (FD_ISSET(fd, &readfds)) + sds[i].revents |= ADHOC_EV_RECV; + if (FD_ISSET(fd, &writefds)) + sds[i].revents |= ADHOC_EV_SEND; // Does Data can always be sent regardless of events bitmask? + sds[i].revents &= sds[i].events; + if (FD_ISSET(fd, &exceptfds)) + sds[i].revents |= ADHOC_EV_ALERT; // Does Alert can be raised on revents regardless of events bitmask? + if (sds[i].revents) affectedsockets++; + } + } + return affectedsockets; +} + int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonblock) { // timeout in microseconds // Library is initialized if (netAdhocInited) @@ -883,68 +1429,31 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb } // Nonblocking Mode - if (nonblock) timeout = 0; + if (nonblock) + timeout = 0; - // Prevent Nonblocking Mode - else - if (timeout == 0) timeout = 1; + // Blocking Mode + else + // Does timeout = 0 means undefinite on PSP? + if (timeout == 0) + timeout = adhocDefaultTimeout * 1000; // minSocketTimeoutUS; - int affectedsockets = 0; - if (count > (int)FD_SETSIZE) count = FD_SETSIZE; // return affectedsockets; + if (count > (int)FD_SETSIZE) + count = FD_SETSIZE; // return 0; //ERROR_NET_ADHOC_INVALID_ARG // Acquire Network Lock //acquireNetworkLock(); // Poll Sockets //int affectedsockets = sceNetInetPoll(isds, count, timeout); - - //WSAPoll only available for Vista or newer, so we'll use an alternative way for XP since Windows doesn't have poll function like *NIX - fd_set readfds, writefds, exceptfds; - int fd; - int maxfd = 0; - FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); - // TODO: PDP and PTP should share the same indexing to prevent identical PDP & PTP socket id - for (int i = 0; i < count; i++) { - sds[i].revents = 0; - // Fill in Socket ID - if (sds[i].id <= 255 && ptp[sds[i].id - 1] != NULL) { - fd = ptp[sds[i].id - 1]->id; - if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_LISTEN) sds[i].revents |= ADHOC_EV_ACCEPT; - else - if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_CLOSED) sds[i].revents |= ADHOC_EV_CONNECT; - } - else { - fd = pdp[sds[i].id - 256]->id; - } - if (fd > maxfd) maxfd = fd; - if (sds[i].events & ADHOC_EV_RECV) FD_SET(fd, &readfds); - if (sds[i].events & ADHOC_EV_SEND) FD_SET(fd, &writefds); // Does Data can always be sent regardless of events bitmask? - //if (sds[i].events & ADHOC_EV_ALERT) - FD_SET(fd, &exceptfds); // Does Alert can be raised on revents regardless of events bitmask? - } - timeval tmout; - tmout.tv_sec = timeout / 1000000; // seconds - tmout.tv_usec = (timeout % 1000000); // microseconds - affectedsockets = select(maxfd + 1, &readfds, &writefds, &exceptfds, &tmout); - if (affectedsockets > 0) { - affectedsockets = 0; - for (int i = 0; i < count; i++) { - if (sds[i].id <= 255 && ptp[sds[i].id - 1] != NULL) { - fd = ptp[sds[i].id - 1]->id; - } - else { - fd = pdp[sds[i].id - 256]->id; - } - if (FD_ISSET(fd, &readfds)) - sds[i].revents |= ADHOC_EV_RECV; - if (FD_ISSET(fd, &writefds)) - sds[i].revents |= ADHOC_EV_SEND; // Does Data can always be sent regardless of events bitmask? - sds[i].revents &= sds[i].events; - if (FD_ISSET(fd, &exceptfds)) - sds[i].revents |= ADHOC_EV_ALERT; // Does Alert can be raised on revents regardless of events bitmask? - if (sds[i].revents) affectedsockets++; - } - } + int affectedsockets = 0; + if (nonblock) + affectedsockets = PollAdhocSocket(sds, count, timeout); + else + // Simulate blocking behaviour with non-blocking socket + // Borrowing some arguments to pass some parameters. The dummy WaitID(count+1) might not be unique thus have duplicate possibilities if there are multiple thread trying to poll the same numbers of socket at the same time + return WaitBlockingAdhocSocket(count+1, ADHOC_POLL_SOCKET, count, sds, nullptr, timeout, nullptr, nullptr, "adhoc pollsocket"); + // Free Network Lock //freeNetworkLock(); @@ -980,6 +1489,7 @@ int NetAdhocPdp_Delete(int id, int unknown) { // Valid Socket if (sock != NULL) { // Close Connection + shutdown(sock->id, SD_BOTH); closesocket(sock->id); // Remove Port Forward from Router @@ -1052,20 +1562,13 @@ static int sceNetAdhocctlGetAdhocId(u32 productStructAddr) { return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } +// FIXME: Scan probably not a blocking function since there is ADHOCCTL_STATE_SCANNING state that can be polled by the game, right? int sceNetAdhocctlScan() { INFO_LOG(SCENET, "sceNetAdhocctlScan() at %08x", currentMIPS->pc); // Library initialized if (netAdhocctlInited) { - // Wait until Not connected - if (friendFinderRunning) { - int cnt = 0; - while ((adhocctlState != ADHOCCTL_STATE_DISCONNECTED) && (cnt < adhocDefaultTimeout)) { - sleep_ms(1); - cnt++; - } - } - + if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED) { adhocctlState = ADHOCCTL_STATE_SCANNING; @@ -1079,32 +1582,18 @@ int sceNetAdhocctlScan() { uint8_t opcode = OPCODE_SCAN; // Send Scan Request Packet, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) + changeBlockingMode(metasocket, 0); int iResult = send(metasocket, (char *)&opcode, 1, 0); + int error = errno; + changeBlockingMode(metasocket, 1); if (iResult == SOCKET_ERROR) { - int error = errno; ERROR_LOG(SCENET, "Socket error (%i) when sending", error); adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + //notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); //if (error == ECONNABORTED || error == ECONNRESET || error == ENOTCONN) return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // A case where it need to reconnect to AdhocServer return ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY } - // Does Connected Event's mipscall need be executed after returning from sceNetAdhocctlScan ? - //notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); - //hleCheckCurrentCallbacks(); - - // Wait for Status to be connected to prevent Ford Street Racing from Failed to find game session - // TODO: Do this async while Delaying HLE Result - /*if (friendFinderRunning) { - int cnt = 0; - while ((adhocctlState == ADHOCCTL_STATE_SCANNING) && (cnt < adhocDefaultTimeout)) { - sleep_ms(1); - cnt++; - } - }*/ - - //sceKernelDelayThread(adhocEventPollDelayMS * 1000); - //hleDelayResult(0, "give time to init/cleanup", adhocEventPollDelayMS * 1000); - // Return Success return 0; } @@ -1267,14 +1756,16 @@ u32 NetAdhocctl_Disconnect() { //_acquireNetworkLock(); // Send Disconnect Request Packet + changeBlockingMode(metasocket, 0); int iResult = send(metasocket, (const char*)&opcode, 1, 0); + int error = errno; + changeBlockingMode(metasocket, 1); if (iResult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "Socket error (%i) when sending", errno); + ERROR_LOG(SCENET, "Socket error (%i) when sending", error); + // Set Disconnected State + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; } - // Set Disconnected State - adhocctlState = ADHOCCTL_STATE_DISCONNECTED; - // Free Network Lock //_freeNetworkLock(); } @@ -1300,9 +1791,16 @@ u32 NetAdhocctl_Disconnect() { // Notify Event Handlers (even if we weren't connected, not doing this will freeze games like God Eater, which expect this behaviour) notifyAdhocctlHandlers(ADHOCCTL_EVENT_DISCONNECT, 0); - hleCheckCurrentCallbacks(); + //hleCheckCurrentCallbacks(); + int us = adhocEventPollDelayMS * 1000; + if (adhocctlState != ADHOCCTL_STATE_DISCONNECTED && friendFinderRunning) { + WaitAdhocctlState(ADHOCCTL_STATE_DISCONNECTED, us, "adhoc disconnect"); + } // Return Success, some games might ignore returned value and always treat it as success, otherwise repeatedly calling this function + else if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED) + hleDelayResult(0, "give time to init/cleanup", us); + return 0; } @@ -1517,15 +2015,6 @@ int NetAdhocctl_Create(const char* groupName) { if (netAdhocctlInited) { // Valid Argument if (validNetworkName(groupNameStruct)) { - // Wait until Not connected - if (friendFinderRunning) { - int cnt = 0; - while ((adhocctlState != ADHOCCTL_STATE_DISCONNECTED && adhocctlState != ADHOCCTL_STATE_SCANNING) && (cnt < adhocDefaultTimeout)) { - sleep_ms(1); - cnt++; - } - } - // Disconnected State, may also need to check for Scanning state to prevent some games from failing to host a game session if ((adhocctlState == ADHOCCTL_STATE_DISCONNECTED) || (adhocctlState == ADHOCCTL_STATE_SCANNING)) { // Set Network Name @@ -1549,15 +2038,18 @@ int NetAdhocctl_Create(const char* groupName) { // Acquire Network Lock // Send Packet + changeBlockingMode(metasocket, 0); int iResult = send(metasocket, (const char*)&packet, sizeof(packet), 0); + int error = errno; + changeBlockingMode(metasocket, 1); if (iResult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "Socket error (%i) when sending", errno); + ERROR_LOG(SCENET, "Socket error (%i) when sending", error); //return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY; //Faking success, to prevent Full Auto 2 from freezing while Initializing Network adhocctlState = ADHOCCTL_STATE_CONNECTED; // Notify Event Handlers, Needed for the Nickname to be shown on the screen when success is faked - // Might be better not to notify the game when faking success (failed to connect to adhoc server), at least the player will know that it failed to connect - //__UpdateAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); //CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventAdhocctlHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); + // Connected Event's mipscall need be executed before returning from sceNetAdhocctlCreate (or before the next sceNet function?) + __UpdateAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); //CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventAdhocctlHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); } // Free Network Lock @@ -1565,22 +2057,14 @@ int NetAdhocctl_Create(const char* groupName) { // Set HUD Connection Status //setConnectionStatus(1); - // Connected Event's mipscall need be executed before returning from sceNetAdhocctlCreate (or before the next sceNet function?) - //notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); - // Wait for Status to be connected to prevent Ford Street Racing from Failed to create game session - // TODO: Do this async while Delaying HLE Result - /*if (friendFinderRunning) { // This is thread-unsafe - int cnt = 0; - while ((adhocctlState != ADHOCCTL_STATE_CONNECTED) && (cnt < adhocDefaultTimeout)) { // This is thread-unsafe - sleep_ms(1); - cnt++; - } - }*/ - - //sceKernelDelayThreadCB(adhocEventDelayMS * 1000); - //hleCheckCurrentCallbacks(); - hleDelayResult(0, "give time to init/cleanup", adhocEventDelayMS * 1000); + int us = adhocEventDelayMS * 1000; + if (adhocctlState != ADHOCCTL_STATE_CONNECTED && friendFinderRunning) { + WaitAdhocctlState(ADHOCCTL_STATE_CONNECTED, us, "adhoc connect"); + } + // Giving time for Naruto Shippuden Ninja Heroes 3 to close down the "Connecting..." dialog, otherwise the dialog will stuck there. + else if (adhocctlState == ADHOCCTL_STATE_CONNECTED) + hleDelayResult(0, "give time to init/cleanup", us); // Return Success return 0; @@ -2006,6 +2490,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Link PTP Socket ptp[i] = internal; + ptpConnectCount[i] = 0; // Add Port Forward to Router. We may not even need to forward this local port, since PtpOpen usually have port 0 (any port) as source port and followed by PtpConnect (which mean acting as Client), right? //sceNetPortOpen("TCP", sport); @@ -2049,6 +2534,93 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, return 0; } +int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port) { + // Cast Socket + SceNetAdhocPtpStat* socket = ptp[ptpId - 1]; + + // Enable Port Re-use + setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + + // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? + if (g_Config.bTCPNoDelay) setSockNoDelay(newsocket, 1); + + // Local Address Information + sockaddr_in local; + memset(&local, 0, sizeof(local)); + socklen_t locallen = sizeof(local); + + // Grab Local Address + if (getsockname(newsocket, (sockaddr*)&local, &locallen) == 0) { + // Peer MAC + SceNetEtherAddr mac; + + // Find Peer MAC + if (resolveIP(peeraddr.sin_addr.s_addr, &mac)) { + // Allocate Memory + SceNetAdhocPtpStat* internal = (SceNetAdhocPtpStat*)malloc(sizeof(SceNetAdhocPtpStat)); + + // Allocated Memory + if (internal != NULL) { + // Find Free Translator ID + int i = 0; + for (; i < 255; i++) if (ptp[i] == NULL) break; + + // Found Free Translator ID + if (i < 255) { + // Clear Memory + memset(internal, 0, sizeof(SceNetAdhocPtpStat)); + + // Copy Socket Descriptor to Structure + internal->id = newsocket; + + // Set Buffer Size + if (getSockBufferSize(newsocket, SO_RCVBUF) < socket->rcv_sb_cc) setSockBufferSize(newsocket, SO_RCVBUF, socket->rcv_sb_cc); + if (getSockBufferSize(newsocket, SO_SNDBUF) < socket->snd_sb_cc) setSockBufferSize(newsocket, SO_SNDBUF, socket->snd_sb_cc); + internal->rcv_sb_cc = socket->rcv_sb_cc; + internal->snd_sb_cc = socket->snd_sb_cc; + + // Copy Local Address Data to Structure + getLocalMac(&internal->laddr); + internal->lport = ntohs(local.sin_port) - portOffset; + + // Copy Peer Address Data to Structure + internal->paddr = mac; + internal->pport = ntohs(peeraddr.sin_port) - portOffset; + + // Set Connected State + internal->state = ADHOC_PTP_STATE_ESTABLISHED; + + // Return Peer Address Information + *addr = internal->paddr; + if (port != NULL) *port = internal->pport; + + // Link PTP Socket + ptp[i] = internal; + ptpConnectCount[i] = 0; + + // Add Port Forward to Router. Or may be doesn't need to be forwarded since local port already accessible from outside if others were able to connect & get accepted at this point, right? + //sceNetPortOpen("TCP", internal->lport); + //g_PortManager.Add(IP_PROTOCOL_TCP, internal->lport + portOffset); + + INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", ptpId, i + 1, internal->lport, inet_ntoa(peeraddr.sin_addr), internal->pport); + + // Return Socket + return i + 1; + } + + // Free Memory + free(internal); + } + } + } + + // Close Socket + closesocket(newsocket); + + ERROR_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Failed (Socket Closed)", ptpId); + return -1; +} + /** * Adhoc Emulator PTP Connection Acceptor * @param id Socket File Descriptor @@ -2092,13 +2664,9 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int sockaddr_in peeraddr; memset(&peeraddr, 0, sizeof(peeraddr)); socklen_t peeraddrlen = sizeof(peeraddr); - // Local Address Information - sockaddr_in local; - memset(&local, 0, sizeof(local)); - socklen_t locallen = sizeof(local); // Grab Nonblocking Flag - uint32_t nbio = getBlockingFlag(socket->id); + uint32_t nbio = getNonBlockingFlag(socket->id); // Switch to Nonblocking Behaviour if (nbio == 0) { // Overwrite Socket Option @@ -2109,27 +2677,13 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Accept Connection int newsocket = accept(socket->id, (sockaddr *)&peeraddr, &peeraddrlen); int error = errno; - - // Blocking Behaviour - if (!flag && newsocket == SOCKET_ERROR) { - // Get Start Time - uint32_t starttime = (uint32_t)(real_time_now()*1000000.0); - - // Retry until Timeout hits - while ((timeout == 0 || ((uint32_t)(real_time_now()*1000000.0) - starttime) < (uint32_t)timeout) && (newsocket == SOCKET_ERROR) && connectInProgress(error)) { - // Accept Connection - newsocket = accept(socket->id, (sockaddr *)&peeraddr, &peeraddrlen); - error = errno; - - // Wait a bit... - sleep_ms(1); - } - } if (newsocket == SOCKET_ERROR) { - if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket - DEBUG_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Socket Error (%i)", id, error); + if (flag == 0) { + // Simulate blocking behaviour with non-blocking socket + return WaitBlockingAdhocSocket(socket->id, PTP_ACCEPT, id, nullptr, nullptr, timeout, addr, port, "ptp accept"); } + // Prevent spamming Debug Log with retries of non-bocking socket else { VERBOSE_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Socket Error (%i)", id, error); } @@ -2143,80 +2697,9 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Accepted New Connection if (newsocket > 0) { - // Enable Port Re-use - setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); - - // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - if (g_Config.bTCPNoDelay) setSockNoDelay(newsocket, 1); - - // Grab Local Address - if (getsockname(newsocket, (sockaddr *)&local, &locallen) == 0) { - // Peer MAC - SceNetEtherAddr mac; - - // Find Peer MAC - if (resolveIP(peeraddr.sin_addr.s_addr, &mac)) { - // Allocate Memory - SceNetAdhocPtpStat * internal = (SceNetAdhocPtpStat *)malloc(sizeof(SceNetAdhocPtpStat)); - - // Allocated Memory - if (internal != NULL) { - // Find Free Translator ID - int i = 0; - for (; i < 255; i++) if (ptp[i] == NULL) break; - - // Found Free Translator ID - if (i < 255) { - // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPtpStat)); - - // Copy Socket Descriptor to Structure - internal->id = newsocket; - - // Set Buffer Size - if (getSockBufferSize(newsocket, SO_RCVBUF) < socket->rcv_sb_cc) setSockBufferSize(newsocket, SO_RCVBUF, socket->rcv_sb_cc); - if (getSockBufferSize(newsocket, SO_SNDBUF) < socket->snd_sb_cc) setSockBufferSize(newsocket, SO_SNDBUF, socket->snd_sb_cc); - internal->rcv_sb_cc = socket->rcv_sb_cc; - internal->snd_sb_cc = socket->snd_sb_cc; - - // Copy Local Address Data to Structure - getLocalMac(&internal->laddr); - internal->lport = ntohs(local.sin_port) - portOffset; - - // Copy Peer Address Data to Structure - internal->paddr = mac; - internal->pport = ntohs(peeraddr.sin_port) - portOffset; - - // Set Connected State - internal->state = ADHOC_PTP_STATE_ESTABLISHED; - - // Return Peer Address Information - *addr = internal->paddr; - if (port != NULL) *port = internal->pport; - - // Link PTP Socket - ptp[i] = internal; - - // Add Port Forward to Router. Or may be doesn't need to be forwarded since local port already accessible from outside if others were able to connect & get accepted at this point, right? - //sceNetPortOpen("TCP", internal->lport); - //g_PortManager.Add(IP_PROTOCOL_TCP, internal->lport + portOffset); - - INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", id, i+1, internal->lport, inet_ntoa(peeraddr.sin_addr), internal->pport); - - // Return Socket - return i + 1; - } - - // Free Memory - free(internal); - } - } - } - - // Close Socket - closesocket(newsocket); - - ERROR_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Failed (Socket Closed)", id); + int newid = AcceptPtpSocket(id, newsocket, peeraddr, addr, port); + if (newid >= 0) + return newid; } // Action would block @@ -2284,17 +2767,15 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { sin.sin_port = htons(socket->pport + ((isOriPort && !isPrivateIP(sin.sin_addr.s_addr)) ? 0 : portOffset)); // Grab Nonblocking Flag - uint32_t nbio = getBlockingFlag(socket->id); + //uint32_t nbio = getNonBlockingFlag(socket->id); // Switch to Nonblocking Behaviour. Forcing blocking behaviour on the first connect may fix connection issue on GvG Next Plus, But i don't like using blocking socket with infinite timeout if the game it self were asking for non-blocking behaviour :( - /*if (nbio == 0) - { - // Overwrite Socket Option - changeBlockingMode(socket->id, 1); - }*/ + // We are using non-blocking to simulate blocking + changeBlockingMode(socket->id, 1); - // Connect Socket to Peer (Nonblocking) + // Connect Socket to Peer // NOTE: Based on what i read at stackoverflow, The First Non-blocking POSIX connect will always returns EAGAIN/EWOULDBLOCK because it returns without waiting for ACK/handshake, But GvG Next Plus is treating non-blocking PtpConnect just like blocking connect, May be on a real PSP the first non-blocking sceNetAdhocPtpConnect can be successfull? + // TODO: Keep track number of Connect attempts so we can simulate blocking on first attempt (getNonBlockingFlag can't be used to get non-blocking flag on Windows thus can't be used to keep track) int connectresult = connect(socket->id, (sockaddr *)&sin, sizeof(sin)); // Grab Error Code @@ -2303,16 +2784,10 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { if (connectresult == SOCKET_ERROR) { ERROR_LOG(SCENET, "sceNetAdhocPtpConnect[%i]: Socket Error (%i) to %s:%u", id, errorcode, inet_ntoa(sin.sin_addr), socket->pport); } - - // Restore Blocking Behaviour - if (nbio == 0) - { - // Restore Socket Option - changeBlockingMode(socket->id, 0); - } - + // Instant Connection (Lucky!) - if (connectresult == 0 || (connectresult == SOCKET_ERROR && (errorcode == EISCONN))) { + if (connectresult != SOCKET_ERROR || errorcode == EISCONN) { + ptpConnectCount[id - 1]++; // Set Connected State socket->state = ADHOC_PTP_STATE_ESTABLISHED; @@ -2323,39 +2798,16 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Connection in Progress else if (connectresult == SOCKET_ERROR && connectInProgress(errorcode)) { - // Nonblocking Mode - if (flag) { + ptpConnectCount[id - 1]++; + // Nonblocking Mode. First attempt need to be blocking for GvG Next Plus to work, even though it used non-blocking flag but only try to connect once per socket, which mean treating it just like blocking socket instead of non-blocking :( + if (flag && ptpConnectCount[id - 1] > 1) { //if (errorcode == EALREADY) return ERROR_NET_ADHOC_BUSY; return ERROR_NET_ADHOC_WOULD_BLOCK; } // Blocking Mode else { - // Grab Connection Start Time - uint32_t starttime = (uint32_t)(real_time_now()*1000000.0); - - // Peer Information (for Connection-Polling) - sockaddr_in peer; - memset(&peer, 0, sizeof(peer)); - socklen_t peerlen = sizeof(peer); - // Wait for Connection - while ((timeout == 0 || ( (uint32_t)(real_time_now()*1000000.0) - starttime) < (uint32_t)timeout) && getpeername(socket->id, (sockaddr *)&peer, &peerlen) != 0) { - // Wait 1ms - sleep_ms(1); - } - - // Connected in Time - if (sin.sin_addr.s_addr == peer.sin_addr.s_addr/* && sin.sin_port == peer.sin_port*/) { - // Set Connected State - socket->state = ADHOC_PTP_STATE_ESTABLISHED; - - INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Established (%s:%u)", id, socket->lport, inet_ntoa(peer.sin_addr), socket->pport); - - // Success - return 0; - } - - // Timeout occured - return ERROR_NET_ADHOC_CONNECTION_REFUSED; // ERROR_NET_ADHOC_TIMEOUT; + // Simulate blocking behaviour with non-blocking socket + return WaitBlockingAdhocSocket(socket->id, PTP_CONNECT, id, nullptr, nullptr, timeout, nullptr, nullptr, "ptp connect"); } } } @@ -2387,6 +2839,7 @@ int NetAdhocPtp_Close(int id, int unknown) { SceNetAdhocPtpStat* socket = ptp[id - 1]; // Close Connection + shutdown(socket->id, SD_BOTH); closesocket(socket->id); // Remove Port Forward from Router @@ -2398,6 +2851,7 @@ int NetAdhocPtp_Close(int id, int unknown) { // Free Reference ptp[id - 1] = NULL; + ptpConnectCount.erase(id - 1); // Success return 0; @@ -2538,6 +2992,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Link PTP Socket ptp[i] = internal; + ptpConnectCount[i] = 0; // Add Port Forward to Router //sceNetPortOpen("TCP", sport); @@ -2627,10 +3082,9 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // _acquireNetworkLock(); // Send Data - //changeBlockingMode(socket->id, flag); + changeBlockingMode(socket->id, 1); int sent = send(socket->id, data, *len, 0); int error = errno; - changeBlockingMode(socket->id, 0); // Free Network Lock // _freeNetworkLock(); @@ -2640,7 +3094,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Save Length *len = sent; - DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u", id, socket->lport, sent, mac2str(&socket->paddr).c_str(), socket->pport); + DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u\n", id, socket->lport, sent, mac2str(&socket->paddr).c_str(), socket->pport); // Return Success return 0; @@ -2648,11 +3102,12 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Non-Critical Error else if (sent == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT)) { - // Blocking Situation - if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; + // Non-Blocking + if (flag) + return ERROR_NET_ADHOC_WOULD_BLOCK; - // Timeout - return ERROR_NET_ADHOC_TIMEOUT; + // Simulate blocking behaviour with non-blocking socket + return WaitBlockingAdhocSocket(socket->id, PTP_SEND, id, (void*)data, len, timeout, nullptr, nullptr, "ptp send"); } // Change Socket State @@ -2722,25 +3177,21 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou received = recv(socket->id, (char*)buf, *len, 0); error = errno; - if (flag == 0) { - // Simulate blocking behaviour with non-blocking socket - uint32_t starttime = (uint32_t)(real_time_now() * 1000000.0); - // Wait for Connection - while ((timeout == 0 || ((uint32_t)(real_time_now() * 1000000.0) - starttime) < (uint32_t)timeout) && (received == SOCKET_ERROR) && connectInProgress(error)) { - received = recv(socket->id, (char*)buf, *len, 0); - error = errno; - // Wait 1ms - sleep_ms(1); - } - } - if (received == SOCKET_ERROR) { + if (flag == 0) { + // Simulate blocking behaviour with non-blocking socket + return WaitBlockingAdhocSocket(socket->id, PTP_RECV, id, buf, len, timeout, nullptr, nullptr, "ptp recv"); + } + VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPtpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); } changeBlockingMode(socket->id, 0); // Free Network Lock // _freeNetworkLock(); + + // Should we set output length to 0 on Error? + *len = 0; // Received Data if (received > 0) { @@ -2753,7 +3204,7 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); peerlock.unlock(); - DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u", id, socket->lport, received, mac2str(&socket->paddr).c_str(), socket->pport); + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, socket->lport, received, mac2str(&socket->paddr).c_str(), socket->pport); // Return Success return 0; @@ -2765,14 +3216,15 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; // Timeout - return ERROR_NET_ADHOC_TIMEOUT; + return hleLogError(SCENET, ERROR_NET_ADHOC_TIMEOUT, "ptp recv timeout"); } - + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Result:%i (Error:%i)", id, socket->lport, received, error); + // Change Socket State socket->state = ADHOC_PTP_STATE_CLOSED; // Disconnected - return ERROR_NET_ADHOC_DISCONNECTED; + return hleLogError(SCENET, ERROR_NET_ADHOC_DISCONNECTED, "ptp recv disconnected"); } // Invalid Arguments @@ -2820,10 +3272,10 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { setSockNoDelay(socket->id, 1); // Send Empty Data just to trigger Nagle on/off effect to flush the send buffer, Do we need to trigger this at all or is it automatically flushed? - changeBlockingMode(socket->id, nonblock); + //changeBlockingMode(socket->id, nonblock); int sent = send(socket->id, 0, 0, 0); int error = errno; - changeBlockingMode(socket->id, 0); + //changeBlockingMode(socket->id, 1); // Restore/Enable Nagle Algo setSockNoDelay(socket->id, n); @@ -2982,6 +3434,14 @@ int NetAdhocMatching_Delete(int matchingId) { free(item); item = NULL; + // Making sure there are no leftover matching events from this session which could cause a crash on the next session + for (auto it = matchingEvents.begin(); it != matchingEvents.end(); ) { + if (it->data[0] == matchingId) + it = matchingEvents.erase(it); + else + ++it; + } + // Stop Search break; } @@ -3045,7 +3505,7 @@ int NetAdhocMatching_Term() { } int sceNetAdhocMatchingTerm() { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingTerm()"); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingTerm() at %08x", currentMIPS->pc); // Should we cleanup all created matching contexts first? just in case there are games that doesn't delete them before calling this NetAdhocMatching_Term(); @@ -3072,14 +3532,6 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle if (rxbuflen >= 1) { //1024 //200 on DBZ Shin Budokai 2 // Valid Arguments if (mode >= 1 && mode <= 3) { - // Wait until Adhoc is fully connected (mipscall of ADHOCCTL_EVENT_CONNECT event is fully executed ?) - /*if (friendFinderRunning) { - int cnt = 0; - while ((threadStatus != ADHOCCTL_STATE_CONNECTED) && (cnt < adhocDefaultTimeout)) { - sleep_ms(1); - cnt++; - } - }*/ // Iterate Matching Contexts SceNetAdhocMatchingContext * item = contexts; @@ -3248,8 +3700,9 @@ int NetAdhocMatching_Start(int matchingId, int evthPri, int evthPartitionId, int // Multithreading Unlock peerlock.unlock(); - sleep_ms(adhocMatchingEventDelayMS); - //hleDelayResult(0, "give some time", adhocMatchingEventDelayMS * 1000); // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? + // Give a little time to make sure matching Threads are ready before the game use the next sceNet functions, should've checked for status instead of guessing the time? + //sleep_ms(adhocMatchingEventDelayMS); + hleDelayResult(0, "give some time", adhocMatchingEventDelayMS * 1000); return 0; } @@ -4127,20 +4580,16 @@ void __NetMatchingCallbacks() //(int matchingId) u32_le* args = (u32_le*)&(*params); //auto context = findMatchingContext(args[0]); - //if (/*__KernelGetCurThread() == context->matching_thid &&*/ (!__IsInInterrupt() && __KernelIsDispatchEnabled() && !__KernelInCallback()) /*&& !IsMatchingInCallback(context)*/) - { - if (actionAfterMatchingMipsCall < 0) { - actionAfterMatchingMipsCall = __KernelRegisterActionType(AfterMatchingMipsCall::Create); - } - DEBUG_LOG(SCENET, "AdhocMatchingCallback: [ID=%i][EVENT=%i][%s]", args[0], args[1], mac2str((SceNetEtherAddr*)Memory::GetPointer(args[2])).c_str()); - AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); - after->SetData(args[0], args[1], args[2]); - //SetMatchingInCallback(context, true); - //__KernelDirectMipsCall(args[5], after, args, 5, true); - hleEnqueueCall(args[5], 5, args, after); - matchingEvents.pop_front(); - delayus = (adhocMatchingEventDelayMS + 2*adhocExtraPollDelayMS) * 1000; // Added an extra delay to prevent I/O Timing method from causing disconnection + if (actionAfterMatchingMipsCall < 0) { + actionAfterMatchingMipsCall = __KernelRegisterActionType(AfterMatchingMipsCall::Create); } + + DEBUG_LOG(SCENET, "AdhocMatchingCallback: [ID=%i][EVENT=%i][%s]", args[0], args[1], mac2str((SceNetEtherAddr*)Memory::GetPointer(args[2])).c_str()); + AfterMatchingMipsCall* after = (AfterMatchingMipsCall*)__KernelCreateAction(actionAfterMatchingMipsCall); + after->SetData(args[0], args[1], args[2]); + hleEnqueueCall(args[5], 5, args, after); + matchingEvents.pop_front(); + delayus = (adhocMatchingEventDelayMS + 2 * adhocExtraPollDelayMS) * 1000; // Added an extra delay to prevent I/O Timing method from causing disconnection } // Must be delayed long enough whenever there is a pending callback. Should it be 10-100ms for Matching Events? or Not Less than the delays on sceNetAdhocMatching HLE? @@ -5586,7 +6035,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi // Multithreading Lock peerlock.lock(); // Cast Context - SceNetAdhocMatchingContext * context = findMatchingContext(matchingId); + SceNetAdhocMatchingContext* context = findMatchingContext(matchingId); // Multithreading Unlock peerlock.unlock(); @@ -5598,6 +6047,10 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi u64_le now; + static SceNetEtherAddr sendermac; + static uint16_t senderport; + static int rxbuflen; + // Log Startup INFO_LOG(SCENET, "InputLoop: Begin of InputLoop[%i] Thread", matchingId); @@ -5690,9 +6143,8 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi } // Receive PDP Datagram - SceNetEtherAddr sendermac; - uint16_t senderport; - int rxbuflen = context->rxbuflen; + rxbuflen = context->rxbuflen; + senderport = 0; context->socketlock->lock(); int recvresult = sceNetAdhocPdpRecv(context->socket, &sendermac, &senderport, context->rxbuf, &rxbuflen, 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); @@ -5714,6 +6166,9 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi DEBUG_LOG(SCENET, "Timestamp Delta: %llu (%llu - %llu) from %s", delta, now, peer->last_recv, mac2str(&sendermac).c_str()); if (/*context->rxbuf[0] > 0 &&*/ peer->last_recv != 0) peer->last_recv = now - 1; // - context->keepalive_int; // May need to deduce by ping interval to prevent Dissidia 012 unable to see other players (ie. disappearing issue) } + else { + WARN_LOG(SCENET, "InputLoop[%d]: Unknown Peer[%s:%u] (Recved=%i, Length=%i)", matchingId, mac2str(&sendermac).c_str(), senderport, recvresult, rxbuflen); + } peerlock.unlock(); // Ping Packet diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index bcd3ad6c73..08583433de 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -17,6 +17,7 @@ #pragma once +#include #include "Core/HLE/proAdhoc.h" #ifdef _MSC_VER @@ -29,6 +30,39 @@ typedef struct MatchingArgs { #pragma pack(pop) #endif +struct AdhocSendTarget { + u32 ip; + u16 port; // original port +}; + +struct AdhocSendTargets { + int length; + std::deque peers; + bool isBroadcast; +}; + +struct AdhocSocketRequest { + int type; + int id; // PDP/PTP socket id + void* buffer; + s32_le* length; + u32 timeout; + u64 startTime; + struct SceNetEtherAddr* remoteMAC; + u16_le* remotePort; +}; + +enum AdhocSocketRequestType : int +{ + PTP_CONNECT = 0, + PTP_ACCEPT = 1, + PTP_SEND = 2, + PTP_RECV = 3, + PDP_SEND = 4, + PDP_RECV = 5, + ADHOC_POLL_SOCKET = 6, +}; + class PointerWrap; void Register_sceNetAdhoc(); From 97904d7149e135da7c04176223c7ef562a66bff7 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 23 Aug 2020 01:35:43 +0700 Subject: [PATCH 626/848] Fix possible stalled thread when PPSSPP closed down --- Core/HLE/proAdhocServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 58e5fa7380..0d83b705b7 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -2075,7 +2075,7 @@ int server_loop(int server) sleep_ms(1); // Don't do anything if it's paused, otherwise the log will be flooded - while (adhocServerRunning && Core_IsStepping()) sleep_ms(1); + while (adhocServerRunning && Core_IsStepping() && coreState != CORE_POWERDOWN) sleep_ms(1); } // Free User Database Memory From a05da1a8c516a1bc6809e40f947d38633be7fdc8 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 26 Aug 2020 17:17:31 +0700 Subject: [PATCH 627/848] Fix communication issue with Adhoc Server where ping to the Adhoc Server sometimes getting socket error 10053 and disconnected from Adhoc Server --- Core/HLE/proAdhoc.cpp | 153 ++++++++++++++++++------------- Core/HLE/proAdhoc.h | 8 +- Core/HLE/sceNetAdhoc.cpp | 192 ++++++++++++++++++++++++--------------- Core/HLE/sceNetAdhoc.h | 7 +- 4 files changed, 219 insertions(+), 141 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 8458b2c9f1..a96fce131f 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -43,6 +43,7 @@ #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelMemory.h" +#include "Core/HLE/sceNetAdhoc.h" #include "Core/Instance.h" #include "proAdhoc.h" @@ -212,13 +213,26 @@ SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC) { return peer; } -int getNonBlockingFlag(int fd) { -#ifdef _WIN32 - return 0; -#else - int sockflag = fcntl(fd, F_GETFL, O_NONBLOCK); - return sockflag & O_NONBLOCK; -#endif +int IsSocketReady(int fd, bool readfd, bool writefd, int* errorcode, int timeoutUS) { + fd_set readfds, writefds; + timeval tval; + + FD_ZERO(&readfds); + writefds = readfds; + if (readfd) { + FD_SET(fd, &readfds); + } + if (writefd) { + FD_SET(fd, &writefds); + } + tval.tv_sec = timeoutUS / 1000000; + tval.tv_usec = timeoutUS % 1000000; + + int ret = select(fd + 1, &readfds, &writefds, nullptr, &tval); + if (errorcode != nullptr) + *errorcode = errno; + + return ret; } void changeBlockingMode(int fd, int nonblocking) { @@ -1186,14 +1200,14 @@ void sendChat(std::string chatString) { message = chatString.substr(0, 60); // 64 return chat variable corrupted is it out of memory? strcpy(chat.message, message.c_str()); //Send Chat Messages - changeBlockingMode(metasocket, 0); - int chatResult = send(metasocket, (const char *)&chat, sizeof(chat), 0); - changeBlockingMode(metasocket, 1); - NOTICE_LOG(SCENET, "Send Chat %s to Adhoc Server", chat.message); - name = g_Config.sNickName.c_str(); - chatLog.push_back(name.substr(0, 8) + ": " + chat.message); - if (chatScreenVisible) { - updateChatScreen = true; + if (IsSocketReady(metasocket, false, true) > 0) { + int chatResult = send(metasocket, (const char*)&chat, sizeof(chat), 0); + NOTICE_LOG(SCENET, "Send Chat %s to Adhoc Server", chat.message); + name = g_Config.sNickName.c_str(); + chatLog.push_back(name.substr(0, 8) + ": " + chat.message); + if (chatScreenVisible) { + updateChatScreen = true; + } } } } @@ -1242,49 +1256,66 @@ int friendFinder(){ // Reconnect when disconnected while Adhocctl is still inited if (metasocket == (int)INVALID_SOCKET && netAdhocctlInited) { - if (g_Config.bEnableWlan && initNetwork(&product_code) == 0) { - networkInited = true; - } - } - - if (networkInited) { - // Ping Server - now = real_time_now() * 1000000.0; // Use real_time_now()*1000000.0 instead of CoreTiming::GetGlobalTimeUsScaled() if the game gets disconnected from AdhocServer too soon when FPS wasn't stable - if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { // We may need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet - // original code : ((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT) - // Update Ping Time - lastping = now; - - // Prepare Packet - uint8_t opcode = OPCODE_PING; - - // Send Ping to Server, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) - changeBlockingMode(metasocket, 0); - int iResult = send(metasocket, (const char*)&opcode, 1, 0); - changeBlockingMode(metasocket, 1); - if (iResult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "FriendFinder: Socket Error (%i) when sending OPCODE_PING", errno); + if (g_Config.bEnableWlan) { + if (initNetwork(&product_code) == 0) { + networkInited = true; + INFO_LOG(SCENET, "FriendFinder: Network [RE]Initialized"); + } + else { networkInited = false; shutdown(metasocket, SD_BOTH); closesocket(metasocket); metasocket = (int)INVALID_SOCKET; } } + } - // Wait for Incoming Data - int received = recv(metasocket, (char*)(rx + rxpos), sizeof(rx) - rxpos, 0); + if (networkInited) { + // Ping Server + now = real_time_now() * 1000000.0; // Use real_time_now()*1000000.0 instead of CoreTiming::GetGlobalTimeUsScaled() if the game gets disconnected from AdhocServer too soon when FPS wasn't stable + // original code : ((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT) + if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { // We may need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet + // Prepare Packet + uint8_t opcode = OPCODE_PING; - // Free Network Lock - //_freeNetworkLock(); + // Send Ping to Server, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) + if (IsSocketReady(metasocket, false, true) > 0) { + int iResult = send(metasocket, (const char*)&opcode, 1, 0); + int error = errno; + // KHBBS seems to be getting error 10053 often + if (iResult == SOCKET_ERROR) { + ERROR_LOG(SCENET, "FriendFinder: Socket Error (%i) when sending OPCODE_PING", error); + if (error != EAGAIN && error != EWOULDBLOCK) { + networkInited = false; + shutdown(metasocket, SD_BOTH); + closesocket(metasocket); + metasocket = (int)INVALID_SOCKET; + } + } + else { + // Update Ping Time + lastping = now; + DEBUG_LOG(SCENET, "FriendFinder: Sending OPCODE_PING (%llu)", now); + } + } + } - // Received Data - if (received > 0) { - // Fix Position - rxpos += received; + // Check for Incoming Data + if (IsSocketReady(metasocket, true, false) > 0) { + int received = recv(metasocket, (char*)(rx + rxpos), sizeof(rx) - rxpos, 0); - // Log Incoming Traffic - //printf("Received %d Bytes of Data from Server\n", received); - INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received); + // Free Network Lock + //_freeNetworkLock(); + + // Received Data + if (received > 0) { + // Fix Position + rxpos += received; + + // Log Incoming Traffic + //printf("Received %d Bytes of Data from Server\n", received); + INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received); + } } // Handle Packets @@ -1297,6 +1328,9 @@ int friendFinder(){ SceNetAdhocctlConnectBSSIDPacketS2C* packet = (SceNetAdhocctlConnectBSSIDPacketS2C*)rx; INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac).c_str()); + // Update User BSSID + parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address + // From JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?) /*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { setState(ADHOCCTL_STATE_GAMEMODE); @@ -1307,8 +1341,6 @@ int friendFinder(){ notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); }*/ - // Update User BSSID - parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address // Notify Event Handlers notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); // Change State @@ -1576,9 +1608,7 @@ int getLocalIp(sockaddr_in* SocketAddress) { struct sockaddr_in localAddr; localAddr.sin_addr.s_addr = INADDR_ANY; socklen_t addrLen = sizeof(localAddr); - changeBlockingMode(metasocket, 0); int ret = getsockname(metasocket, (struct sockaddr*)&localAddr, &addrLen); - changeBlockingMode(metasocket, 1); if (SOCKET_ERROR != ret) { if (isLocalServer) { localAddr.sin_addr = g_localhostIP.in.sin_addr; @@ -1858,6 +1888,10 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ return SOCKET_ERROR; } setSockKeepAlive(metasocket, true); + // Disable Nagle Algo to prevent delaying small packets + setSockNoDelay(metasocket, 1); + // Switch to Nonblocking Behaviour + changeBlockingMode(metasocket, 1); struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; @@ -1914,17 +1948,14 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ product_code.type = adhoc_id->type; memcpy(product_code.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); - // Switch to Nonblocking Behaviour - changeBlockingMode(metasocket, 1); // Connect to Adhoc Server server_addr.sin_addr = serverIp; int errorcode = 0; int cnt = 0; - while ((iResult = connect(metasocket, (sockaddr*)&server_addr, sizeof(server_addr))) == SOCKET_ERROR && (errorcode = errno) != EISCONN && cnt < adhocDefaultTimeout) { - sleep_ms(1); - cnt++; - } - if (iResult == SOCKET_ERROR && errorcode != EISCONN) { + iResult = connect(metasocket, (sockaddr*)&server_addr, sizeof(server_addr)); + errorcode = errno; + + if (iResult == SOCKET_ERROR && errorcode != EISCONN && (IsSocketReady(metasocket, true, true, nullptr, adhocDefaultTimeout * 1000) <= 0)) { char buffer[512]; snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); ERROR_LOG(SCENET, "%s", buffer); @@ -1941,9 +1972,9 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ strncpy((char *)&packet.name.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN); packet.name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; memcpy(packet.game.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); - changeBlockingMode(metasocket, 0); + + IsSocketReady(metasocket, false, true, nullptr, adhocDefaultTimeout * 1000); int sent = send(metasocket, (char*)&packet, sizeof(packet), 0); - changeBlockingMode(metasocket, 1); if (sent > 0) { socklen_t addrLen = sizeof(LocalIP); memset(&LocalIP, 0, addrLen); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index fa5194f17e..8c88d471fc 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -49,7 +49,6 @@ #include "Core/MemMap.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLEHelperThread.h" -#include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelMutex.h" @@ -928,11 +927,12 @@ extern int newChat; SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC); /** - * Get the Non-Blocking Mode of the socket + * Get the Readability(ie. recv) and/or Writability(ie. send) of a socket * @param fd File Descriptor of the socket - * @return 1 for non-blocking, 0 for blocking + * @param timeout in usec (micro seconds), 0 = non-blocking + * @return > 0 = ready, 0 = timeout, -1 = error (errorcode only represent error of select and doesn't represent error of the socket) */ -int getNonBlockingFlag(int fd); +int IsSocketReady(int fd, bool readfd, bool writefd, int* errorcode = nullptr, int timeoutUS = 0); /** * Changes the Blocking Mode of the socket diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 9d62792037..7b9644e4e6 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -46,7 +46,6 @@ #include "Core/HLE/sceKernelMemory.h" #include "Core/HLE/sceKernelModule.h" #include "Core/HLE/sceKernelInterrupt.h" -#include "Core/HLE/proAdhoc.h" #include "Core/HLE/sceNetAdhoc.h" #include "Core/HLE/sceNet.h" #include "Core/HLE/proAdhocServer.h" @@ -63,7 +62,7 @@ static bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; int adhocDefaultTimeout = 2000; //5000 ms int adhocExtraPollDelayMS = 10; //10 -int adhocEventPollDelayMS = 100; //100 +int adhocEventPollDelayMS = 100; //100; Seems to be the same with PSP_ADHOCCTL_RECV_TIMEOUT int adhocMatchingEventDelayMS = 30; //30 int adhocEventDelayMS = 300; //500; This will affect the duration of "Connecting..." dialog/message box in .Hack//Link and Naruto Ultimate Ninja Heroes 3 @@ -78,6 +77,7 @@ int IsAdhocctlInCB = 0; int adhocctlNotifyEvent = -1; int adhocSocketNotifyEvent = -1; +std::map adhocctlRequests; std::map adhocSocketRequests; std::map sendTargetPeers; @@ -129,9 +129,51 @@ static void __AdhocctlNotify(u64 userdata, int cyclesLate) { SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_NET, error); if (waitID == 0 || error != 0) - return; // FIXME: Is it safe to exit here like this without re-scheduling the event? Will this event be triggered again? What will happen to the result i might want to change if exited here? + return; - int waitVal = __KernelGetWaitValue(threadID, error); // FIXME: Is this value going to be a valid value if waitID == 0? or it's a value belonged to other event? + // Socket not found?! Should never happened! but if it ever happen should we just exit here or need to wake the thread first? + if (adhocctlRequests.find(uid) == adhocctlRequests.end()) { + WARN_LOG(SCENET, "sceNetAdhocctl Socket WaitID(%i) not found!", uid); + //__KernelResumeThreadFromWait(threadID, ERROR_NET_ADHOCCTL_BUSY); + return; + } + + AdhocctlRequest& req = adhocctlRequests[uid]; + int len = 0; + + SceNetAdhocctlConnectPacketC2S packet; + memset(&packet, 0, sizeof(packet)); + packet.base.opcode = req.opcode; + packet.group = req.group; + + switch (req.opcode) + { + case OPCODE_CONNECT: + len = sizeof(packet); + break; + case OPCODE_SCAN: + case OPCODE_DISCONNECT: + len = 1; + break; + } + + // Send Packet if it wasn't succesfully sent before + if (len > 0) { + if (IsSocketReady(metasocket, false, true) > 0) { + int ret = send(metasocket, (const char*)&packet, len, 0); + int sockerr = errno; + + if (ret > 0 || (ret == SOCKET_ERROR && sockerr != EAGAIN && sockerr != EWOULDBLOCK)) { + // Prevent from sending again + req.opcode = 0; + if (ret == SOCKET_ERROR) + DEBUG_LOG(SCENET, "sceNetAdhocctl[%i]: Socket Error (%i)", uid, sockerr); + } + } + } + + // Now we just need to wait for replies from adhoc server and the change of state + int waitVal = __KernelGetWaitValue(threadID, error); if (adhocctlState != waitVal && error == 0) { // Detecting Adhocctl Initialization using waitVal < 0 if (waitVal >= 0 || (waitVal < 0 && (g_Config.bEnableWlan && !networkInited))) { @@ -148,20 +190,32 @@ static void __AdhocctlNotify(u64 userdata, int cyclesLate) { result = 0; // Faking successfully connected to adhoc server } - //HLEKernel::ResumeFromWait(threadID, WAITTYPE_NET, uid, result); // FIXME: This won't do anything if waitID == 0, not sure what kind of value returned from the HLE which i might want to change here. - __KernelResumeThreadFromWait(threadID, result); // FIXME: Forcing to change the result, will it cause an issue if waitID == 0? + __KernelResumeThreadFromWait(threadID, result); DEBUG_LOG(SCENET, "Returning (WaitID: %d, error: %d) Result (%08x) of sceNetAdhocctl - State: %d", waitID, error, (int)result, adhocctlState); + + // We are done with this request + adhocctlRequests.erase(uid); } -void WaitAdhocctlState(int state, int usec, const char* reason) { +int WaitAdhocctlState(AdhocctlRequest request, int state, int usec, const char* reason) { + int uid = (state < 0) ? 1 : metasocket; + + if (adhocctlRequests.find(uid) != adhocctlRequests.end()) { + WARN_LOG(SCENET, "sceNetAdhocctl - WaitID[%d] already existed, Socket is busy!", uid); + return ERROR_NET_ADHOCCTL_BUSY; + } + if (adhocctlNotifyEvent < 0) adhocctlNotifyEvent = CoreTiming::RegisterEvent("__AdhocctlNotify", __AdhocctlNotify); - int uid = (state < 0)? 1: metasocket; u64 param = ((u64)__KernelGetCurThread()) << 32 | uid; adhocctlStartTime = (u64)(real_time_now() * 1000.0); + adhocctlRequests[uid] = request; CoreTiming::ScheduleEvent(usToCycles(usec), adhocctlNotifyEvent, param); __KernelWaitCurThread(WAITTYPE_NET, uid, state, 0, false, reason); + + // faked success + return 0; } int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { @@ -386,17 +440,10 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { - fd_set readfds, writefds; - timeval tval; - FD_ZERO(&readfds); - FD_SET(uid, &readfds); - writefds = readfds; - tval.tv_sec = 0; - tval.tv_usec = 0; + int sockerr; // Wait for Connection (assuming "connect" has been called before) - int ret = select(uid + 1, &readfds, &writefds, NULL, &tval); - int sockerr = errno; + int ret = IsSocketReady(uid, true, true, &sockerr); // Connection is ready if (ret > 0) { @@ -535,11 +582,11 @@ static void __AdhocSocketNotify(u64 userdata, int cyclesLate) { break; } - // We are done with this socket - adhocSocketRequests.erase(uid); - __KernelResumeThreadFromWait(threadID, result); DEBUG_LOG(SCENET, "Returning (WaitID: %d, error: %d) Result (%08x) of sceNetAdhoc - SocketID: %d", waitID, error, (int)result, req.id); + + // We are done with this socket + adhocSocketRequests.erase(uid); } int WaitBlockingAdhocSocket(int socketId, int type, int pspSocketId, void* buffer, s32_le* len, u32 timeoutUS, SceNetEtherAddr* remoteMAC, u16_le* remotePort, const char* reason) { @@ -551,8 +598,7 @@ int WaitBlockingAdhocSocket(int socketId, int type, int pspSocketId, void* buffe if (adhocSocketNotifyEvent < 0) adhocSocketNotifyEvent = CoreTiming::RegisterEvent("__AdhocSocketNotify", __AdhocSocketNotify); - if (getNonBlockingFlag(socketId) == 0) - changeBlockingMode(socketId, 1); + //changeBlockingMode(socketId, 1); u32 tmout = timeoutUS; if (tmout > 0) @@ -646,6 +692,7 @@ void __NetAdhocDoState(PointerWrap &p) { // Discard leftover events adhocctlEvents.clear(); matchingEvents.clear(); + adhocctlRequests.clear(); adhocSocketRequests.clear(); sendTargetPeers.clear(); @@ -683,6 +730,7 @@ void __AdhocNotifInit() { adhocctlNotifyEvent = CoreTiming::RegisterEvent("__AdhocctlNotify", __AdhocctlNotify); adhocSocketNotifyEvent = CoreTiming::RegisterEvent("__AdhocSocketNotify", __AdhocSocketNotify); + adhocctlRequests.clear(); adhocSocketRequests.clear(); sendTargetPeers.clear(); } @@ -744,7 +792,8 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { // Need to make sure to be connected to adhoc server before returning to prevent GTA VCS failed to create/join a group and unable to see any game room int us = adhocExtraPollDelayMS * 1000; if (g_Config.bEnableWlan && !networkInited) { - WaitAdhocctlState(-1, us, "adhoc init"); + AdhocctlRequest dummyreq = { OPCODE_LOGIN, {0} }; + return WaitAdhocctlState(dummyreq, -1, us, "adhocctl init"); } // Give a little time for friendFinder thread to be ready before the game use the next sceNet functions, should've checked for friendFinderRunning status instead of guessing the time? else @@ -871,6 +920,9 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u //sceNetPortOpen("UDP", port); UPnP_Add(IP_PROTOCOL_UDP, isOriPort ? port : port + portOffset, port + portOffset); // g_PortManager.Add(IP_PROTOCOL_UDP, isOriPort ? port : port + portOffset, port + portOffset); + // Switch to non-blocking for futher usage + changeBlockingMode(usocket, 1); + // Success return i + 256; } @@ -1009,7 +1061,6 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int //_acquireNetworkLock(); // Send Data. UDP are guaranteed to be sent as a whole or nothing(failed if len > SO_MAX_MSG_SIZE), and never be partially sent/recv - changeBlockingMode(socket->id, 1); int sent = sendto(socket->id, (const char *)data, len, 0, (sockaddr *)&target, sizeof(target)); int error = errno; @@ -1087,8 +1138,6 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int peerlock.unlock(); // Send Data - changeBlockingMode(socket->id, 1); // Do we need to switched to blocking-mode to make sure the data are fully sent? - // Simulate blocking behaviour with non-blocking socket if (!flag) { if (sendTargetPeers.find(socket->id) != sendTargetPeers.end()) { @@ -1232,11 +1281,9 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Receive Data. PDP always sent in full size or nothing(failed), recvfrom will always receive in full size as requested (blocking) or failed (non-blocking). If available UDP data is larger than buffer, excess data is lost. - changeBlockingMode(socket->id, 1); // Should peek first for the available data size if it's more than len return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE along with required size in len to prevent losing excess data received = recvfrom(socket->id, (char*)buf, *len, MSG_PEEK, (sockaddr*)&sin, &sinlen); if (received != SOCKET_ERROR && *len < received) { - changeBlockingMode(socket->id, 0); WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Peeked %u/%u bytes from %s:%u\n", id, getLocalPort(socket->id), received, *len, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); *len = received; @@ -1272,7 +1319,6 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); } - changeBlockingMode(socket->id, 0); // Should we set output length to 0 on Error? *len = 0; @@ -1571,6 +1617,7 @@ int sceNetAdhocctlScan() { if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED) { adhocctlState = ADHOCCTL_STATE_SCANNING; + int us = adhocEventPollDelayMS * 1000; // Reset Networks/Group list to prevent other threads from using these soon to be replaced networks peerlock.lock(); @@ -1582,17 +1629,23 @@ int sceNetAdhocctlScan() { uint8_t opcode = OPCODE_SCAN; // Send Scan Request Packet, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) - changeBlockingMode(metasocket, 0); int iResult = send(metasocket, (char *)&opcode, 1, 0); int error = errno; - changeBlockingMode(metasocket, 1); + if (iResult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "Socket error (%i) when sending", error); - adhocctlState = ADHOCCTL_STATE_DISCONNECTED; - //notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); - //if (error == ECONNABORTED || error == ECONNRESET || error == ENOTCONN) return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // A case where it need to reconnect to AdhocServer - return ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY + if (error != EAGAIN && error != EWOULDBLOCK) { + ERROR_LOG(SCENET, "Socket error (%i) when sending", error); + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + //if (error == ECONNABORTED || error == ECONNRESET || error == ENOTCONN) return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // A case where it need to reconnect to AdhocServer + return ERROR_NET_ADHOCCTL_BUSY; + } + else if (friendFinderRunning) { + AdhocctlRequest req = { OPCODE_SCAN, {0} }; + return WaitAdhocctlState(req, ADHOCCTL_STATE_DISCONNECTED, us, "adhocctl scan"); + } } + else + hleDelayResult(0, "give a little time to be ready to receive the callback", us); // Not delaying here may cause Naruto Shippuden Ultimate Ninja Heroes 3 to get disconnected when the mission started // Return Success return 0; @@ -1741,6 +1794,8 @@ static u32 sceNetAdhocctlAddHandler(u32 handlerPtr, u32 handlerArg) { u32 NetAdhocctl_Disconnect() { // Library initialized if (netAdhocctlInited) { + int iResult, error; + int us = adhocEventPollDelayMS * 1000; // Connected State (Adhoc Mode) if (adhocctlState != ADHOCCTL_STATE_DISCONNECTED) { // (threadStatus == ADHOCCTL_STATE_CONNECTED) // Clear Network Name @@ -1756,14 +1811,20 @@ u32 NetAdhocctl_Disconnect() { //_acquireNetworkLock(); // Send Disconnect Request Packet - changeBlockingMode(metasocket, 0); - int iResult = send(metasocket, (const char*)&opcode, 1, 0); - int error = errno; - changeBlockingMode(metasocket, 1); + iResult = send(metasocket, (const char*)&opcode, 1, 0); + error = errno; + + // Sending may get socket error 10053 if the AdhocServer is already shutted down if (iResult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "Socket error (%i) when sending", error); - // Set Disconnected State - adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + if (error != EAGAIN && error != EWOULDBLOCK) { + ERROR_LOG(SCENET, "Socket error (%i) when sending", error); + // Set Disconnected State + adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + } + else if (friendFinderRunning) { + AdhocctlRequest req = { OPCODE_DISCONNECT, {0} }; + WaitAdhocctlState(req, ADHOCCTL_STATE_DISCONNECTED, us, "adhocctl disconnect"); + } } // Free Network Lock @@ -1793,12 +1854,8 @@ u32 NetAdhocctl_Disconnect() { notifyAdhocctlHandlers(ADHOCCTL_EVENT_DISCONNECT, 0); //hleCheckCurrentCallbacks(); - int us = adhocEventPollDelayMS * 1000; - if (adhocctlState != ADHOCCTL_STATE_DISCONNECTED && friendFinderRunning) { - WaitAdhocctlState(ADHOCCTL_STATE_DISCONNECTED, us, "adhoc disconnect"); - } // Return Success, some games might ignore returned value and always treat it as success, otherwise repeatedly calling this function - else if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED) + if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED || iResult != SOCKET_ERROR) hleDelayResult(0, "give time to init/cleanup", us); return 0; @@ -2038,10 +2095,9 @@ int NetAdhocctl_Create(const char* groupName) { // Acquire Network Lock // Send Packet - changeBlockingMode(metasocket, 0); int iResult = send(metasocket, (const char*)&packet, sizeof(packet), 0); int error = errno; - changeBlockingMode(metasocket, 1); + if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "Socket error (%i) when sending", error); //return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY; @@ -2059,11 +2115,13 @@ int NetAdhocctl_Create(const char* groupName) { // Wait for Status to be connected to prevent Ford Street Racing from Failed to create game session int us = adhocEventDelayMS * 1000; - if (adhocctlState != ADHOCCTL_STATE_CONNECTED && friendFinderRunning) { - WaitAdhocctlState(ADHOCCTL_STATE_CONNECTED, us, "adhoc connect"); + if (adhocctlState != ADHOCCTL_STATE_CONNECTED && iResult == SOCKET_ERROR && friendFinderRunning) { + AdhocctlRequest req = { OPCODE_CONNECT, {0} }; + if (groupNameStruct != NULL) req.group = *groupNameStruct; + return WaitAdhocctlState(req, ADHOCCTL_STATE_CONNECTED, us, "adhocctl connect"); } // Giving time for Naruto Shippuden Ninja Heroes 3 to close down the "Connecting..." dialog, otherwise the dialog will stuck there. - else if (adhocctlState == ADHOCCTL_STATE_CONNECTED) + else if (adhocctlState == ADHOCCTL_STATE_CONNECTED || iResult != SOCKET_ERROR) hleDelayResult(0, "give time to init/cleanup", us); // Return Success @@ -2497,6 +2555,9 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, if (!isClient) UPnP_Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); + // Switch to non-blocking for futher usage + changeBlockingMode(tcpsocket, 1); + // Return PTP Socket Pointer return i + 1; } @@ -2665,15 +2726,6 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int memset(&peeraddr, 0, sizeof(peeraddr)); socklen_t peeraddrlen = sizeof(peeraddr); - // Grab Nonblocking Flag - uint32_t nbio = getNonBlockingFlag(socket->id); - // Switch to Nonblocking Behaviour - if (nbio == 0) { - // Overwrite Socket Option - changeBlockingMode(socket->id, 1); - } - - // TODO: Use a different thread (similar to sceIo) for recvfrom, recv & accept to prevent blocking-socket from blocking emulation // Accept Connection int newsocket = accept(socket->id, (sockaddr *)&peeraddr, &peeraddrlen); int error = errno; @@ -2689,12 +2741,6 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int } } - // Restore Blocking Behaviour - if (nbio == 0) { - // Restore Socket Option - changeBlockingMode(socket->id, 0); - } - // Accepted New Connection if (newsocket > 0) { int newid = AcceptPtpSocket(id, newsocket, peeraddr, addr, port); @@ -2769,10 +2815,6 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Grab Nonblocking Flag //uint32_t nbio = getNonBlockingFlag(socket->id); - // Switch to Nonblocking Behaviour. Forcing blocking behaviour on the first connect may fix connection issue on GvG Next Plus, But i don't like using blocking socket with infinite timeout if the game it self were asking for non-blocking behaviour :( - // We are using non-blocking to simulate blocking - changeBlockingMode(socket->id, 1); - // Connect Socket to Peer // NOTE: Based on what i read at stackoverflow, The First Non-blocking POSIX connect will always returns EAGAIN/EWOULDBLOCK because it returns without waiting for ACK/handshake, But GvG Next Plus is treating non-blocking PtpConnect just like blocking connect, May be on a real PSP the first non-blocking sceNetAdhocPtpConnect can be successfull? // TODO: Keep track number of Connect attempts so we can simulate blocking on first attempt (getNonBlockingFlag can't be used to get non-blocking flag on Windows thus can't be used to keep track) @@ -2998,6 +3040,9 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int //sceNetPortOpen("TCP", sport); UPnP_Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); + // Switch to non-blocking for futher usage + changeBlockingMode(tcpsocket, 1); + // Return PTP Socket Pointer return i + 1; } @@ -3082,7 +3127,6 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // _acquireNetworkLock(); // Send Data - changeBlockingMode(socket->id, 1); int sent = send(socket->id, data, *len, 0); int error = errno; @@ -3173,7 +3217,6 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou int error = 0; // Receive Data - changeBlockingMode(socket->id, 1); received = recv(socket->id, (char*)buf, *len, 0); error = errno; @@ -3185,7 +3228,6 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPtpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); } - changeBlockingMode(socket->id, 0); // Free Network Lock // _freeNetworkLock(); diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 08583433de..6a12e19c97 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -30,6 +30,11 @@ typedef struct MatchingArgs { #pragma pack(pop) #endif +struct AdhocctlRequest { + u8 opcode; + SceNetAdhocctlGroupName group; +}; + struct AdhocSendTarget { u32 ip; u16 port; // original port @@ -48,7 +53,7 @@ struct AdhocSocketRequest { s32_le* length; u32 timeout; u64 startTime; - struct SceNetEtherAddr* remoteMAC; + SceNetEtherAddr* remoteMAC; u16_le* remotePort; }; From d3157205dd87efd66323263adf5bcb71902d322a Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 30 Aug 2020 23:50:31 +0700 Subject: [PATCH 628/848] Don't allocate PSP's Memory during DoState --- Core/HLE/sceNet.cpp | 21 ++++++++++++--------- Core/HLE/sceNetAdhoc.cpp | 30 ++++++++++++++++-------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index a34167f275..6187a3e1ad 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -200,6 +200,15 @@ void notifyApctlHandlers(int oldState, int newState, int flag, int error) { __UpdateApctlHandlers(oldState, newState, flag, error); } +void netValidateLoopMemory() { + // Allocate Memory if it wasn't valid/allocated after loaded from old SaveState + if (!apctlThreadHackAddr || (apctlThreadHackAddr && strcmp("apctlThreadHack", kernelMemory.GetBlockTag(apctlThreadHackAddr)) != 0)) { + u32 blockSize = sizeof(apctlThreadCode); + apctlThreadHackAddr = kernelMemory.Alloc(blockSize, false, "apctlThreadHack"); + if (apctlThreadHackAddr) Memory::Memcpy(apctlThreadHackAddr, apctlThreadCode, sizeof(apctlThreadCode)); + } +} + // This feels like a dubious proposition, mostly... void __NetDoState(PointerWrap &p) { auto s = p.Section("sceNet", 1, 4); @@ -244,22 +253,15 @@ void __NetDoState(PointerWrap &p) { apctlThreadHackAddr = 0; apctlThreadID = 0; } - // Let's not change "Inited" value when Loading SaveState in the middle of multiplayer to prevent memory & port leaks + if (p.mode == p.MODE_READ) { + // Let's not change "Inited" value when Loading SaveState in the middle of multiplayer to prevent memory & port leaks netApctlInited = cur_netApctlInited; netInetInited = cur_netInetInited; netInited = cur_netInited; // Discard leftover events apctlEvents.clear(); - - // Previously, this wasn't being saved. It needs its own space. - if (!apctlThreadHackAddr || (apctlThreadHackAddr && strcmp("apctlThreadHack", kernelMemory.GetBlockTag(apctlThreadHackAddr)) != 0)) { - u32 blockSize = sizeof(apctlThreadCode); - apctlThreadHackAddr = kernelMemory.Alloc(blockSize, false, "apctlThreadHack"); - } - // Restore Apctl Loop MIPS code to prevent crashes after loading from SaveState - if (apctlThreadHackAddr) Memory::Memcpy(apctlThreadHackAddr, apctlThreadCode, sizeof(apctlThreadCode)); } } @@ -780,6 +782,7 @@ static int sceNetApctlInit(int stackSize, int initPriority) { truncate_cpy(netApctlInfo.subNetMask, sizeof(netApctlInfo.subNetMask), "0.0.0.0"); // Create APctl fake-Thread + netValidateLoopMemory(); apctlThreadID = __KernelCreateThread("ApctlThread", __KernelGetCurThreadModuleId(), apctlThreadHackAddr, initPriority, stackSize, PSP_THREAD_ATTR_USER, 0, true); if (apctlThreadID > 0) { __KernelStartThread(apctlThreadID, 0, 0); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7b9644e4e6..03c5c579d0 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -615,6 +615,20 @@ int WaitBlockingAdhocSocket(int socketId, int type, int pspSocketId, void* buffe return ERROR_NET_ADHOC_TIMEOUT; } +void netAdhocValidateLoopMemory() { + // Allocate Memory if it wasn't valid/allocated after loaded from old SaveState + if (!dummyThreadHackAddr || (dummyThreadHackAddr && strcmp("dummythreadhack", kernelMemory.GetBlockTag(dummyThreadHackAddr)) != 0)) { + u32 blockSize = sizeof(dummyThreadCode); + dummyThreadHackAddr = kernelMemory.Alloc(blockSize, false, "dummythreadhack"); + if (dummyThreadHackAddr) Memory::Memcpy(dummyThreadHackAddr, dummyThreadCode, sizeof(dummyThreadCode)); + } + if (!matchingThreadHackAddr || (matchingThreadHackAddr && strcmp("matchingThreadHack", kernelMemory.GetBlockTag(matchingThreadHackAddr)) != 0)) { + u32 blockSize = sizeof(matchingThreadCode); + matchingThreadHackAddr = kernelMemory.Alloc(blockSize, false, "matchingThreadHack"); + if (matchingThreadHackAddr) Memory::Memcpy(matchingThreadHackAddr, matchingThreadCode, sizeof(matchingThreadCode)); + } +} + void __NetAdhocDoState(PointerWrap &p) { auto s = p.Section("sceNetAdhoc", 1, 5); if (!s) @@ -675,20 +689,6 @@ void __NetAdhocDoState(PointerWrap &p) { } if (p.mode == p.MODE_READ) { - // Previously, this wasn't being saved. It needs its own space. - if (!dummyThreadHackAddr || (dummyThreadHackAddr && strcmp("dummythreadhack", kernelMemory.GetBlockTag(dummyThreadHackAddr)) != 0)) { - u32 blockSize = sizeof(dummyThreadCode); - dummyThreadHackAddr = kernelMemory.Alloc(blockSize, false, "dummythreadhack"); - } - if (!matchingThreadHackAddr || (matchingThreadHackAddr && strcmp("matchingThreadHack", kernelMemory.GetBlockTag(matchingThreadHackAddr)) != 0)) { - u32 blockSize = sizeof(matchingThreadCode); - matchingThreadHackAddr = kernelMemory.Alloc(blockSize, false, "matchingThreadHack"); - } - - // Restore dummy Loop MIPS code to prevent crashes after loading from SaveState - if (dummyThreadHackAddr) Memory::Memcpy(dummyThreadHackAddr, dummyThreadCode, sizeof(dummyThreadCode)); - if (matchingThreadHackAddr) Memory::Memcpy(matchingThreadHackAddr, matchingThreadCode, sizeof(matchingThreadCode)); - // Discard leftover events adhocctlEvents.clear(); matchingEvents.clear(); @@ -778,6 +778,7 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { // Create fake PSP Thread for callback // TODO: Should use a separated threads for friendFinder, matchingEvent, and matchingInput and created on AdhocctlInit & AdhocMatchingStart instead of here + netAdhocValidateLoopMemory(); threadAdhocID = __KernelCreateThread("AdhocThread", __KernelGetCurThreadModuleId(), dummyThreadHackAddr, prio, stackSize, PSP_THREAD_ATTR_USER, 0, true); if (threadAdhocID > 0) { __KernelStartThread(threadAdhocID, 0, 0); @@ -3716,6 +3717,7 @@ int NetAdhocMatching_Start(int matchingId, int evthPri, int evthPartitionId, int }*/ // Create & Start the Fake PSP Thread ("matching_ev%d" and "matching_io%d") + netAdhocValidateLoopMemory(); std::string thrname = std::string("MatchingThr") + std::to_string(matchingId); matchingThreads[item->matching_thid] = sceKernelCreateThread(thrname.c_str(), matchingThreadHackAddr, evthPri, evthStack, 0, 0); //item->matchingThread = new HLEHelperThread(thrname.c_str(), "sceNetAdhocMatching", "__NetMatchingCallbacks", inthPri, inthStack); From 170d313fa7ba7766f9d8ad6ac391e8b2e40e045d Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 31 Aug 2020 09:20:46 +0700 Subject: [PATCH 629/848] Minor changes to make sure the output struct/arg have similar value to the one from prx file (based on Kingdom Hearts BBS) --- Core/HLE/proAdhoc.h | 12 +++++++----- Core/HLE/sceNetAdhoc.cpp | 30 ++++++++++-------------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 8c88d471fc..304657acdb 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -252,14 +252,16 @@ typedef struct SceNetAdhocctlParameter { SceNetAdhocctlNickname nickname; } PACK SceNetAdhocctlParameter; -// Peer Information +// Peer Information (internal use only) typedef struct SceNetAdhocctlPeerInfo { SceNetAdhocctlPeerInfo * next; SceNetAdhocctlNickname nickname; SceNetEtherAddr mac_addr; - u32_le ip_addr; - uint8_t padding[2]; + u16_le padding; + u32_le flags; u64_le last_recv; // Need to use the same method with sceKernelGetSystemTimeWide (ie. CoreTiming::GetGlobalTimeUsScaled) to prevent timing issue (ie. in game timeout) + + u32_le ip_addr; // internal use only } PACK SceNetAdhocctlPeerInfo; // Peer Information with u32 pointers @@ -267,8 +269,8 @@ typedef struct SceNetAdhocctlPeerInfoEmu { u32_le next; // Changed the pointer to u32 SceNetAdhocctlNickname nickname; SceNetEtherAddr mac_addr; - u32_le ip_addr; //jpcsp wrote 6bytes of 0x11 for this & padding - u16 padding; // Changed the padding to u16 + u16_le padding; //00 00 + u32_le flags; //00 04 00 00 // State of the peer? Or related to sceNetAdhocAuth_CF4D9BED ? u64_le last_recv; // Need to use the same method with sceKernelGetSystemTimeWide (ie. CoreTiming::GetGlobalTimeUsScaled) to prevent timing issue (ie. in game timeout) } PACK SceNetAdhocctlPeerInfoEmu; diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 03c5c579d0..8af2249f3d 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1321,9 +1321,6 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); } - // Should we set output length to 0 on Error? - *len = 0; - // Received Data. UDP can also receives 0 data, while on TCP 0 data = connection gracefully closed, but not sure about PDP tho if (received > 0) { DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, getLocalPort(socket->id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); @@ -1666,7 +1663,7 @@ int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { SceNetAdhocctlScanInfoEmu *buf = NULL; if (Memory::IsValidAddress(bufAddr)) buf = (SceNetAdhocctlScanInfoEmu *)Memory::GetPointer(bufAddr); - INFO_LOG(SCENET, "sceNetAdhocctlGetScanInfo([%08x]=%i, %08x)", sizeAddr, /*buflen ? *buflen : -1*/Memory::Read_U32(sizeAddr), bufAddr); + INFO_LOG(SCENET, "sceNetAdhocctlGetScanInfo([%08x]=%i, %08x)", sizeAddr, Memory::Read_U32(sizeAddr), bufAddr); if (!g_Config.bEnableWlan) { return 0; } @@ -2017,17 +2014,14 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { // Local MAC if (isLocalMAC(maddr)) { - sockaddr_in addr; SceNetAdhocctlNickname nickname; - getLocalIp(&addr); - strncpy((char*)&nickname.data, g_Config.sNickName.c_str(), ADHOCCTL_NICKNAME_LEN); - nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // making sure to be null-terminated since strncpy doesn't implicitly append null + truncate_cpy((char*)&nickname.data, ADHOCCTL_NICKNAME_LEN, g_Config.sNickName.c_str()); //buf->next = 0; buf->nickname = nickname; buf->nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char buf->mac_addr = *maddr; - buf->ip_addr = addr.sin_addr.s_addr; // 0x11111111; + buf->flags = 0x0400; buf->padding = 0; buf->last_recv = CoreTiming::GetGlobalTimeUsScaled(); @@ -2049,7 +2043,7 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { buf->nickname = peer->nickname; buf->nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char buf->mac_addr = *maddr; - buf->ip_addr = peer->ip_addr; // 0x11111111; + buf->flags = 0x0400; //peer->ip_addr; buf->padding = 0; buf->last_recv = peer->last_recv; //CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; //(uint64_t)time(NULL); //This timestamp is important issue on Dissidia 012 @@ -3233,9 +3227,6 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Free Network Lock // _freeNetworkLock(); - // Should we set output length to 0 on Error? - *len = 0; - // Received Data if (received > 0) { // Save Length @@ -3618,7 +3609,7 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle if (keepalive_int < 1) context->keepalive_int = PSP_ADHOCCTL_PING_TIMEOUT; else context->keepalive_int = keepalive_int; // client might set this to 0 context->keepalivecounter = init_count; // used to multiply keepalive_int as timeout context->timeout = ((u64_le)keepalive_int * (u64_le)init_count); - if (context->timeout < 5000000) context->timeout = 5000000; // For internet play we need higher timeout than what the game wanted + context->timeout = std::max(context->timeout, adhocDefaultTimeout * 1000ULL); // For internet play we need higher timeout than what the game wanted context->handler = handler; // Fill in Selfpeer @@ -4761,7 +4752,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { // Copy Peer Info buf[discovered].nickname = peer->nickname; buf[discovered].mac_addr = peer->mac_addr; - buf[discovered].ip_addr = peer->ip_addr; + buf[discovered].flags = 0x0400; //peer->ip_addr; buf[discovered].last_recv = peer->last_recv; discovered++; @@ -4846,12 +4837,10 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b sockaddr_in addr; getLocalIp(&addr); - //buf->next = 0; buf[discovered].nickname = parameter.nickname; buf[discovered].nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char getLocalMac(&buf[discovered].mac_addr); - buf[discovered].ip_addr = addr.sin_addr.s_addr; // 0x11111111; - //buf->padding = 0x1111; //0; + buf[discovered].flags = 0x0400; //addr.sin_addr.s_addr; buf[discovered++].last_recv = CoreTiming::GetGlobalTimeUsScaled(); } @@ -4865,13 +4854,14 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b if (strncmp((char *)&peer->nickname.data, nickName, ADHOCCTL_NICKNAME_LEN) == 0) { // Fake Receive Time - if (peer->last_recv != 0) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); //sceKernelGetSystemTimeWide(); + if (peer->last_recv != 0) + peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); //sceKernelGetSystemTimeWide(); // Copy Peer Info buf[discovered].nickname = peer->nickname; buf[discovered].nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char buf[discovered].mac_addr = peer->mac_addr; - buf[discovered].ip_addr = peer->ip_addr; + buf[discovered].flags = 0x0400; //peer->ip_addr; buf[discovered++].last_recv = peer->last_recv; } } From 56892944f6b0bb85bb837042d728367cab1761ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 4 Sep 2020 09:01:42 +0200 Subject: [PATCH 630/848] Fix crash in Digimon Adventures. Fixes #13371 --- GPU/Common/FramebufferManagerCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 240b75f28e..90f06fa10e 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1292,7 +1292,7 @@ void FramebufferManagerCommon::FindTransferFramebuffers(VirtualFramebuffer *&dst } } - if (!dstBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) { + if (srcBuffer && !dstBuffer && PSP_CoreParameter().compat.flags().BlockTransferAllowCreateFB) { GEBufferFormat ramFormat; // Try to guess the appropriate format. We only know the bpp from the block transfer command (16 or 32 bit). if (bpp == 4) { From c564e77b9f7a5058b1548dd689a23f7f551a9756 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 4 Sep 2020 16:08:07 +0700 Subject: [PATCH 631/848] Fix AdhocMatching P2P Mode. This fix Bleach Heat the Soul 7 --- Core/HLE/sceNetAdhoc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 8af2249f3d..e06b64cec6 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -5437,9 +5437,9 @@ void actOnHelloPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * se } // Peer available now - if (peer != NULL) + if (peer != NULL && peer->state != PSP_ADHOC_MATCHING_PEER_OUTGOING_REQUEST && peer->state != PSP_ADHOC_MATCHING_PEER_INCOMING_REQUEST) { - // Spawn Hello Event + // Spawn Hello Event. FIXME: HELLO event should not be triggered in the middle of joining? This will cause Bleach 7 to Cancel the join request spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_HELLO, sendermac, optlen, opt); } } From 423a7b2391b402f264a53c2cb5cff2886bdc308b Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 5 Sep 2020 06:40:35 +0700 Subject: [PATCH 632/848] Fix multiplayer on Valhalla Knights 2 --- Core/Dialog/PSPNetconfDialog.cpp | 2 +- Core/HLE/proAdhoc.cpp | 2 ++ Core/HLE/sceNetAdhoc.cpp | 32 +++++++++++++++++++++----------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 93571ce2ff..66f2b352f1 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -47,7 +47,7 @@ static const float FONT_SCALE = 0.65f; const static int NET_INIT_DELAY_US = 300000; const static int NET_SHUTDOWN_DELAY_US = 260000; const static int NET_RUNNING_DELAY_US = 1000000; // KHBBS is showing adhoc dialog for about 3-4 seconds, but feels too long, so we're faking it to 1 sec instead to let players read the text -const static int NET_CONNECT_TIMEOUT = 5000000; +const static int NET_CONNECT_TIMEOUT = 15000000; // Using 15 secs to match the timeout on Adhoc Server side (SERVER_USER_TIMEOUT) struct ScanInfos { s32_le sz; diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a96fce131f..779858dfd9 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1230,6 +1230,7 @@ std::vector getChatLog() { int friendFinder(){ setCurrentThreadName("FriendFinder"); + auto n = GetI18NCategory("Networking"); // Receive Buffer int rxpos = 0; uint8_t rx[1024]; @@ -1290,6 +1291,7 @@ int friendFinder(){ shutdown(metasocket, SD_BOTH); closesocket(metasocket); metasocket = (int)INVALID_SOCKET; + host->NotifyUserMessage(std::string(n->T("Disconnected from AdhocServer")) + " (" + std::string(n->T("Error")) + ": " + std::to_string(error) + ")", 2.0, 0x0000ff); } } else { diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index e06b64cec6..cf2561c25f 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1606,16 +1606,20 @@ static int sceNetAdhocctlGetAdhocId(u32 productStructAddr) { return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } -// FIXME: Scan probably not a blocking function since there is ADHOCCTL_STATE_SCANNING state that can be polled by the game, right? +// FIXME: Scan probably not a blocking function since there is ADHOCCTL_STATE_SCANNING state that can be polled by the game, right? But apparently it need to be delayed for Naruto Shippuden Ultimate Ninja Heroes 3 int sceNetAdhocctlScan() { INFO_LOG(SCENET, "sceNetAdhocctlScan() at %08x", currentMIPS->pc); + if (!g_Config.bEnableWlan) { + return -1; + } // Library initialized if (netAdhocctlInited) { + int us = adhocEventPollDelayMS * 1000; + // Only scan when in Disconnected state, otherwise AdhocServer will kick you out if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED) { adhocctlState = ADHOCCTL_STATE_SCANNING; - int us = adhocEventPollDelayMS * 1000; // Reset Networks/Group list to prevent other threads from using these soon to be replaced networks peerlock.lock(); @@ -1642,15 +1646,20 @@ int sceNetAdhocctlScan() { return WaitAdhocctlState(req, ADHOCCTL_STATE_DISCONNECTED, us, "adhocctl scan"); } } - else - hleDelayResult(0, "give a little time to be ready to receive the callback", us); // Not delaying here may cause Naruto Shippuden Ultimate Ninja Heroes 3 to get disconnected when the mission started - - // Return Success - return 0; + else { + // Return Success and let friendFinder thread to notify the handler when scan completed + // Not delaying here may cause Naruto Shippuden Ultimate Ninja Heroes 3 to get disconnected when the mission started + return hleDelayResult(0, "give a little time to be ready to receive the callback", us); + } } + else if (adhocctlState == ADHOCCTL_STATE_SCANNING) + return ERROR_NET_ADHOCCTL_BUSY; - // Library is busy - return ERROR_NET_ADHOCCTL_BUSY; // ERROR_NET_ADHOCCTL_BUSY may trigger the game (ie. Ford Street Racing) to call sceNetAdhocctlDisconnect + // Already connected to a group. Should we fake a success? + // We need to notify the handler on success, even if it was faked + notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); + // FIXME: returning ERROR_NET_ADHOCCTL_BUSY may trigger the game (ie. Ford Street Racing) to call sceNetAdhocctlDisconnect, But Not returning a Success(0) will cause Valhalla Knights 2 not working properly + return hleDelayResult(0, "give a little time to be ready to receive the callback", us); } // Library uninitialized @@ -1750,6 +1759,7 @@ int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { // TODO: How many handlers can the PSP actually have for Adhocctl? // TODO: Should we allow the same handler to be added more than once? +// FIXME: Do all Adhocctl HLE returning 0 and expecting error code through callback handler if there were error, instead of returning error code through the HLE ? static u32 sceNetAdhocctlAddHandler(u32 handlerPtr, u32 handlerArg) { bool foundHandler = false; u32 retval = 0; @@ -2093,7 +2103,7 @@ int NetAdhocctl_Create(const char* groupName) { int iResult = send(metasocket, (const char*)&packet, sizeof(packet), 0); int error = errno; - if (iResult == SOCKET_ERROR) { + if (iResult == SOCKET_ERROR && error != EAGAIN && error != EWOULDBLOCK) { ERROR_LOG(SCENET, "Socket error (%i) when sending", error); //return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY; //Faking success, to prevent Full Auto 2 from freezing while Initializing Network @@ -4589,7 +4599,7 @@ void __NetTriggerCallbacks() } for (std::map::iterator it = adhocctlHandlers.begin(); it != adhocctlHandlers.end(); ++it) { - DEBUG_LOG(SCENET, "AdhocctlCallback: [ID=%i][EVENT=%i]", it->first, flags); + DEBUG_LOG(SCENET, "AdhocctlCallback: [ID=%i][EVENT=%i][Error=%08x]", it->first, flags, error); args[2] = it->second.argument; AfterAdhocMipsCall* after = (AfterAdhocMipsCall*)__KernelCreateAction(actionAfterAdhocMipsCall); after->SetData(it->first, flags, args[2]); From e79d3b8204d43cd615d524add3a3ec8b128a75b9 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 5 Sep 2020 11:45:14 +0700 Subject: [PATCH 633/848] Fix Phantasy Star Portable 2 Timeout issue --- Core/HLE/sceNetAdhoc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index e06b64cec6..b160a6dc1a 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -3608,8 +3608,8 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle context->hello_int = hello_int; // client might set this to 0 if (keepalive_int < 1) context->keepalive_int = PSP_ADHOCCTL_PING_TIMEOUT; else context->keepalive_int = keepalive_int; // client might set this to 0 context->keepalivecounter = init_count; // used to multiply keepalive_int as timeout - context->timeout = ((u64_le)keepalive_int * (u64_le)init_count); - context->timeout = std::max(context->timeout, adhocDefaultTimeout * 1000ULL); // For internet play we need higher timeout than what the game wanted + context->timeout = (((u64)(keepalive_int) + (u64)rexmt_int) * (u64)init_count); + context->timeout += (adhocDefaultTimeout * 1000ULL); // For internet play we need higher timeout than what the game wanted context->handler = handler; // Fill in Selfpeer From 37737ceaa18ce173ec72aa1b3c49e05f007bc072 Mon Sep 17 00:00:00 2001 From: sum Date: Sat, 5 Sep 2020 13:29:56 +0800 Subject: [PATCH 634/848] Add draft sceKernelFindModuleByUID (#13380) * Add draft sceKernelFindModuleByUID #13205 * Add KERNEL_SYSCALL flag * oop * oop2 * Not sure why make this change before * Last night I might be too tried --- Core/HLE/HLETables.cpp | 2 +- Core/HLE/sceKernelModule.cpp | 6 ++++++ Core/HLE/sceKernelModule.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Core/HLE/HLETables.cpp b/Core/HLE/HLETables.cpp index 4c5ed553aa..562fdbf931 100644 --- a/Core/HLE/HLETables.cpp +++ b/Core/HLE/HLETables.cpp @@ -158,7 +158,7 @@ const HLEFunction LoadCoreForKernel[] = {0XAE7C6E76, nullptr, "sceKernelRegisterModule", '?', "" }, {0X74CF001A, nullptr, "sceKernelReleaseModule", '?', "" }, {0XFB8AE27D, nullptr, "sceKernelFindModuleByAddress", '?', "" }, - {0XCCE4A157, nullptr, "sceKernelFindModuleByUID", '?', "" }, + {0XCCE4A157, &WrapU_U, "sceKernelFindModuleByUID", 'x', "x" , HLE_KERNEL_SYSCALL }, {0X82CE54ED, nullptr, "sceKernelModuleCount", '?', "" }, {0XC0584F0C, nullptr, "sceKernelGetModuleList", '?', "" }, {0XCF8A41B1, &WrapU_C, "sceKernelFindModuleByName", 'x', "s", HLE_KERNEL_SYSCALL }, diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 486bd06bd0..0b2b55ae74 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2327,6 +2327,12 @@ static u32 sceKernelGetModuleId() return __KernelGetCurThreadModuleId(); } +u32 sceKernelFindModuleByUID(u32 uid) +{ + ERROR_LOG(SCEMODULE, "UNIMPL sceKernelFindModuleByUID(%d)", uid); + return 0; +} + u32 sceKernelFindModuleByName(const char *name) { ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelFindModuleByName(%s)", name); diff --git a/Core/HLE/sceKernelModule.h b/Core/HLE/sceKernelModule.h index e6fabd9829..99e5473b05 100644 --- a/Core/HLE/sceKernelModule.h +++ b/Core/HLE/sceKernelModule.h @@ -45,6 +45,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str void __KernelGPUReplay(); void __KernelReturnFromModuleFunc(); u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr, bool WithStatus); +u32 sceKernelFindModuleByUID(u32 uid); void Register_ModuleMgrForUser(); void Register_ModuleMgrForKernel(); From 19cc81fe9125deffd5c6b74d5fb41a27f20b59d2 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 5 Sep 2020 13:17:20 +0700 Subject: [PATCH 635/848] Fix crash issue due to out of bound when indexing PDP socket --- Core/HLE/sceNetAdhoc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index e06b64cec6..6f913a97a5 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -281,7 +281,7 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTargets& targetPeers) { - SceNetAdhocPdpStat* pdpsocket = pdp[req.id - 1]; + SceNetAdhocPdpStat* pdpsocket = pdp[req.id - 256]; result = 0; bool retry = false; From 00d2b488ddade25c96daba7133c3934e13c4bcdb Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 5 Sep 2020 13:26:27 +0700 Subject: [PATCH 636/848] Reindexing PDP and PTP socket using const/var instead of using confusing raw numbers --- Core/HLE/proAdhoc.cpp | 14 +++++----- Core/HLE/proAdhoc.h | 7 +++-- Core/HLE/sceNetAdhoc.cpp | 56 ++++++++++++++++++++-------------------- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a96fce131f..59a200e19c 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -71,8 +71,10 @@ SceNetAdhocctlParameter parameter; SceNetAdhocctlAdhocId product_code; std::thread friendFinderThread; std::recursive_mutex peerlock; -SceNetAdhocPdpStat * pdp[255]; -SceNetAdhocPtpStat * ptp[255]; +SceNetAdhocPdpStat * pdp[MAX_SOCKET]; +SceNetAdhocPtpStat * ptp[MAX_SOCKET]; +const int PdpIdStart = MAX_SOCKET + 1; //256 +const int PdpIdEnd = PdpIdStart + MAX_SOCKET; std::map ptpConnectCount; std::vector chatLog; std::string name = ""; @@ -101,7 +103,7 @@ bool isLocalMAC(const SceNetEtherAddr * addr) { bool isPDPPortInUse(uint16_t port) { // Iterate Elements - for (int i = 0; i < 255; i++) if (pdp[i] != NULL && pdp[i]->lport == port) return true; + for (int i = 0; i < MAX_SOCKET; i++) if (pdp[i] != NULL && pdp[i]->lport == port) return true; // Unused Port return false; @@ -109,7 +111,7 @@ bool isPDPPortInUse(uint16_t port) { bool isPTPPortInUse(uint16_t port) { // Iterate Sockets - for(int i = 0; i < 255; i++) if(ptp[i] != NULL && ptp[i]->lport == port) return true; + for(int i = 0; i < MAX_SOCKET; i++) if(ptp[i] != NULL && ptp[i]->lport == port) return true; // Unused Port return false; @@ -1861,7 +1863,7 @@ int getPDPSocketCount() int counter = 0; // Count Sockets - for (int i = 0; i < 255; i++) if (pdp[i] != NULL) counter++; + for (int i = 0; i < MAX_SOCKET; i++) if (pdp[i] != NULL) counter++; // Return Socket Count return counter; @@ -1872,7 +1874,7 @@ int getPTPSocketCount() { int counter = 0; // Count Sockets - for (int i = 0; i < 255; i++) if (ptp[i] != NULL) counter++; + for (int i = 0; i < MAX_SOCKET; i++) if (ptp[i] != NULL) counter++; // Return Socket Count return counter; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 304657acdb..255e4e1158 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -820,14 +820,17 @@ private: extern int actionAfterAdhocMipsCall; extern int actionAfterMatchingMipsCall; +#define MAX_SOCKET 255 // Aux vars extern int metasocket; extern SceNetAdhocctlParameter parameter; extern SceNetAdhocctlAdhocId product_code; extern std::thread friendFinderThread; extern std::recursive_mutex peerlock; -extern SceNetAdhocPdpStat * pdp[255]; -extern SceNetAdhocPtpStat * ptp[255]; +extern SceNetAdhocPdpStat * pdp[MAX_SOCKET]; +extern SceNetAdhocPtpStat * ptp[MAX_SOCKET]; +extern const int PdpIdStart; +extern const int PdpIdEnd; extern std::map ptpConnectCount; union SockAddrIN4 { diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 6f913a97a5..6fa95ae069 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -281,7 +281,7 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTargets& targetPeers) { - SceNetAdhocPdpStat* pdpsocket = pdp[req.id - 256]; + SceNetAdhocPdpStat* pdpsocket = pdp[req.id - PdpIdStart]; result = 0; bool retry = false; @@ -904,10 +904,10 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u // Find Free Translator Index int i = 0; - for (; i < 255; i++) if (pdp[i] == NULL) break; + for (; i < MAX_SOCKET; i++) if (pdp[i] == NULL) break; // Found Free Translator Index - if (i < 255) { + if (i < MAX_SOCKET) { // Fill in Data internal->id = usocket; internal->laddr = *saddr; @@ -925,7 +925,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u changeBlockingMode(usocket, 1); // Success - return i + 256; + return i + PdpIdStart; } // Free Memory for Internal Data @@ -1028,9 +1028,9 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Valid Data Length if (len >= 0) { // should we allow 0 size packet (for ping) ? // Valid Socket ID - if (id > 255 && id <= 510 && pdp[id - 256] != NULL) { + if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) { // Cast Socket - SceNetAdhocPdpStat * socket = pdp[id - 256]; + SceNetAdhocPdpStat * socket = pdp[id - PdpIdStart]; // Valid Data Buffer if (data != NULL) { @@ -1233,9 +1233,9 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * int * len = (int *)dataLength; if (netAdhocInited) { // Valid Socket ID - if (id > 255 && id <= 510 && pdp[id - 256] != NULL) { + if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) { // Cast Socket - SceNetAdhocPdpStat * socket = pdp[id - 256]; + SceNetAdhocPdpStat * socket = pdp[id - PdpIdStart]; // Valid Arguments if (saddr != NULL && port != NULL && buf != NULL && len != NULL && *len > 0) { @@ -1413,14 +1413,14 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { for (int i = 0; i < count; i++) { sds[i].revents = 0; // Fill in Socket ID - if (sds[i].id <= 255 && ptp[sds[i].id - 1] != NULL) { + if (sds[i].id <= MAX_SOCKET && ptp[sds[i].id - 1] != NULL) { fd = ptp[sds[i].id - 1]->id; if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_LISTEN) sds[i].revents |= ADHOC_EV_ACCEPT; else if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_CLOSED) sds[i].revents |= ADHOC_EV_CONNECT; } else { - fd = pdp[sds[i].id - 256]->id; + fd = pdp[sds[i].id - PdpIdStart]->id; } if (fd > maxfd) maxfd = fd; if (sds[i].events & ADHOC_EV_RECV) FD_SET(fd, &readfds); @@ -1435,11 +1435,11 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { if (affectedsockets > 0) { affectedsockets = 0; for (int i = 0; i < count; i++) { - if (sds[i].id <= 255 && ptp[sds[i].id - 1] != NULL) { + if (sds[i].id <= MAX_SOCKET && ptp[sds[i].id - 1] != NULL) { fd = ptp[sds[i].id - 1]->id; } else { - fd = pdp[sds[i].id - 256]->id; + fd = pdp[sds[i].id - PdpIdStart]->id; } if (FD_ISSET(fd, &readfds)) sds[i].revents |= ADHOC_EV_RECV; @@ -1468,7 +1468,7 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb for (int i = 0; i < count; i++) { // Invalid Socket - if (sds[i].id < 1 || sds[i].id > 510 || (pdp[sds[i].id - 256] == NULL && ptp[sds[i].id - 1] == NULL)) + if (sds[i].id < 1 || sds[i].id >= PdpIdEnd || (pdp[sds[i].id - PdpIdStart] == NULL && ptp[sds[i].id - 1] == NULL)) return hleLogDebug(SCENET, ERROR_NET_ADHOC_INVALID_SOCKET_ID, "invalid socket id"); } @@ -1526,9 +1526,9 @@ int NetAdhocPdp_Delete(int id, int unknown) { // Library is initialized if (netAdhocInited) { // Valid Arguments - if (id > 255 && id <= 510) { + if (id >= PdpIdStart && id < PdpIdEnd) { // Cast Socket - SceNetAdhocPdpStat* sock = pdp[id - 256]; + SceNetAdhocPdpStat* sock = pdp[id - PdpIdStart]; // Valid Socket if (sock != NULL) { @@ -1544,7 +1544,7 @@ int NetAdhocPdp_Delete(int id, int unknown) { free(sock); // Free Translation Slot - pdp[id - 256] = NULL; + pdp[id - PdpIdStart] = NULL; // Success return 0; @@ -2522,10 +2522,10 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, if (internal != NULL) { // Find Free Translator ID int i = 0; - for (; i < 255; i++) if (ptp[i] == NULL) break; + for (; i < MAX_SOCKET; i++) if (ptp[i] == NULL) break; // Found Free Translator ID - if (i < 255) { + if (i < MAX_SOCKET) { // Clear Memory memset(internal, 0, sizeof(SceNetAdhocPtpStat)); @@ -2619,10 +2619,10 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther if (internal != NULL) { // Find Free Translator ID int i = 0; - for (; i < 255; i++) if (ptp[i] == NULL) break; + for (; i < MAX_SOCKET; i++) if (ptp[i] == NULL) break; // Found Free Translator ID - if (i < 255) { + if (i < MAX_SOCKET) { // Clear Memory memset(internal, 0, sizeof(SceNetAdhocPtpStat)); @@ -2708,7 +2708,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Library is initialized if (netAdhocInited) { // Valid Socket - if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { + if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket SceNetAdhocPtpStat * socket = ptp[id - 1]; @@ -2783,7 +2783,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { if (netAdhocInited) { // Valid Socket - if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { + if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket SceNetAdhocPtpStat * socket = ptp[id - 1]; @@ -2871,7 +2871,7 @@ int NetAdhocPtp_Close(int id, int unknown) { // Library is initialized if (netAdhocInited) { // Valid Arguments & Atleast one Socket - if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { + if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket SceNetAdhocPtpStat* socket = ptp[id - 1]; @@ -3007,10 +3007,10 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int if (internal != NULL) { // Find Free Translator ID int i = 0; - for (; i < 255; i++) if (ptp[i] == NULL) break; + for (; i < MAX_SOCKET; i++) if (ptp[i] == NULL) break; // Found Free Translator ID - if (i < 255) { + if (i < MAX_SOCKET) { // Clear Memory memset(internal, 0, sizeof(SceNetAdhocPtpStat)); @@ -3103,7 +3103,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Library is initialized if (netAdhocInited) { // Valid Socket - if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { + if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket SceNetAdhocPtpStat * socket = ptp[id - 1]; @@ -3191,7 +3191,7 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Library is initialized if (netAdhocInited) { // Valid Socket - if (id > 0 && id <= 255 && ptp[id - 1] != NULL && ptp[id - 1]->state == ADHOC_PTP_STATE_ESTABLISHED) { + if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL && ptp[id - 1]->state == ADHOC_PTP_STATE_ESTABLISHED) { // Cast Socket SceNetAdhocPtpStat * socket = ptp[id - 1]; @@ -3289,7 +3289,7 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { // Library initialized if (netAdhocInited) { // Valid Socket - if (id > 0 && id <= 255 && ptp[id - 1] != NULL) { + if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket SceNetAdhocPtpStat* socket = ptp[id - 1]; From d0f18cbbe5eb44f68fd61f34a5d46e3b0263a37c Mon Sep 17 00:00:00 2001 From: sum2012 Date: Sat, 5 Sep 2020 22:02:47 +0800 Subject: [PATCH 637/848] Imp sceKernelFindModuleByName #13204 --- Core/HLE/sceKernelModule.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 0b2b55ae74..5f792b1033 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2335,14 +2335,10 @@ u32 sceKernelFindModuleByUID(u32 uid) u32 sceKernelFindModuleByName(const char *name) { - ERROR_LOG_REPORT(SCEMODULE, "UNIMPL sceKernelFindModuleByName(%s)", name); - int index = GetModuleIndex(name); - - if (index == -1) - return 0; - - return 1; + u32 temp = index + 1; + INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", temp, name); + return temp; } static u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr) From ff6b466effa6e7ed8f390c3446673a688e757a69 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 6 Sep 2020 05:53:16 +0700 Subject: [PATCH 638/848] Oops forgot to replace these numbers with const on adhoc socket reindexing PR --- Core/HLE/sceNetAdhoc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7d05bd2b4a..233d4e1919 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2327,7 +2327,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { int i = 0; // Iterate Translation Table - for (int j = 0; j < 255 && i < count; j++) + for (int j = 0; j < MAX_SOCKET && i < count; j++) { // Valid Socket Entry if (pdp[j] != NULL) @@ -2336,7 +2336,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { buf[i] = *pdp[j]; // Fix Client View Socket ID - buf[i].id = j + 256; + buf[i].id = j + PdpIdStart; // Write End of List Reference buf[i].next = 0; @@ -2405,7 +2405,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { int i = 0; // Iterate Sockets - for (int j = 0; j < 255 && i < count; j++) { + for (int j = 0; j < MAX_SOCKET && i < count; j++) { // Active Socket if (ptp[j] != NULL) { // Copy Socket Data from internal Memory From c2a4d564301736fa1bcf0afeed71b2b18261dcfc Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 6 Sep 2020 05:56:02 +0700 Subject: [PATCH 639/848] An attempt to implement AdhocSocketAlert --- Core/HLE/proAdhoc.cpp | 6 +- Core/HLE/proAdhoc.h | 48 +++++++++++---- Core/HLE/sceNetAdhoc.cpp | 127 +++++++++++++++++++++++---------------- 3 files changed, 115 insertions(+), 66 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index fae0ca72f2..a0a3e89cad 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -71,9 +71,9 @@ SceNetAdhocctlParameter parameter; SceNetAdhocctlAdhocId product_code; std::thread friendFinderThread; std::recursive_mutex peerlock; -SceNetAdhocPdpStat * pdp[MAX_SOCKET]; -SceNetAdhocPtpStat * ptp[MAX_SOCKET]; -const int PdpIdStart = MAX_SOCKET + 1; //256 +SceNetAdhocPdpStatInternal * pdp[MAX_SOCKET]; +SceNetAdhocPtpStatInternal * ptp[MAX_SOCKET]; +const int PdpIdStart = MAX_SOCKET + 1; const int PdpIdEnd = PdpIdStart + MAX_SOCKET; std::map ptpConnectCount; std::vector chatLog; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 255e4e1158..fa9d520e3e 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -302,18 +302,29 @@ typedef struct SceNetAdhocPollSd{ s32_le revents; } PACK SceNetAdhocPollSd; -// PDP Socket Status -typedef struct SceNetAdhocPdpStat{ +// PDP Socket Status (Internal use only) +typedef struct SceNetAdhocPdpStatInternal{ u32_le next; // struct SceNetAdhocPdpStat * next; s32_le id; SceNetEtherAddr laddr; u16_le lport; u32_le rcv_sb_cc; -} PACK SceNetAdhocPdpStat; -// PTP Socket Status -typedef struct SceNetAdhocPtpStat { - u32_le next; // Changed the pointer to u32 + s32_le flags; // Socket Alert Flags +} PACK SceNetAdhocPdpStatInternal; + +// PDP Socket Status +typedef struct SceNetAdhocPdpStatEmu { + u32_le next; + s32_le id; + SceNetEtherAddr laddr; + u16_le lport; + u32_le rcv_sb_cc; +} PACK SceNetAdhocPdpStatEmu; + +// PTP Socket Status (Internal use only) +typedef struct SceNetAdhocPtpStatInternal { + u32_le next; // struct SceNetAdhocPtpStat * next; s32_le id; SceNetEtherAddr laddr; SceNetEtherAddr paddr; @@ -322,7 +333,22 @@ typedef struct SceNetAdhocPtpStat { s32_le snd_sb_cc; s32_le rcv_sb_cc; s32_le state; -} PACK SceNetAdhocPtpStat; + + s32_le flags; // Socket Alert Flags +} PACK SceNetAdhocPtpStatInternal; + +// PTP Socket Status +typedef struct SceNetAdhocPtpStatEmu { + u32_le next; // Changed the pointer to u32 + s32_le id; + SceNetEtherAddr laddr; + SceNetEtherAddr paddr; + u16_le lport; + u16_le pport; + s32_le snd_sb_cc; + s32_le rcv_sb_cc; + s32_le state; +} PACK SceNetAdhocPtpStatEmu; // Gamemode Optional Peer Buffer Data typedef struct SceNetAdhocGameModeOptData { @@ -827,10 +853,10 @@ extern SceNetAdhocctlParameter parameter; extern SceNetAdhocctlAdhocId product_code; extern std::thread friendFinderThread; extern std::recursive_mutex peerlock; -extern SceNetAdhocPdpStat * pdp[MAX_SOCKET]; -extern SceNetAdhocPtpStat * ptp[MAX_SOCKET]; -extern const int PdpIdStart; -extern const int PdpIdEnd; +extern SceNetAdhocPdpStatInternal * pdp[MAX_SOCKET]; +extern SceNetAdhocPtpStatInternal * ptp[MAX_SOCKET]; +extern const int PdpIdStart; //256 +extern const int PdpIdEnd; //511 extern std::map ptpConnectCount; union SockAddrIN4 { diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 233d4e1919..242b0047b0 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -281,7 +281,7 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTargets& targetPeers) { - SceNetAdhocPdpStat* pdpsocket = pdp[req.id - PdpIdStart]; + auto pdpsocket = pdp[req.id - PdpIdStart]; result = 0; bool retry = false; @@ -324,7 +324,7 @@ int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTa } int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { - SceNetAdhocPtpStat* ptpsocket = ptp[req.id - 1]; + auto ptpsocket = ptp[req.id - 1]; // Send Data int ret = send(uid, (const char*)req.buffer, *req.length, 0); @@ -365,7 +365,7 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { - SceNetAdhocPtpStat* ptpsocket = ptp[req.id - 1]; + auto ptpsocket = ptp[req.id - 1]; int ret = recv(uid, (char*)req.buffer, *req.length, 0); int sockerr = errno; @@ -447,7 +447,7 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { // Connection is ready if (ret > 0) { - SceNetAdhocPtpStat* ptpsocket = ptp[req.id - 1]; + auto ptpsocket = ptp[req.id - 1]; sockaddr_in sin; memset(&sin, 0, sizeof(sin)); socklen_t sinlen = sizeof(sin); @@ -895,12 +895,12 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u } // Allocate Memory for Internal Data - SceNetAdhocPdpStat * internal = (SceNetAdhocPdpStat *)malloc(sizeof(SceNetAdhocPdpStat)); + SceNetAdhocPdpStatInternal * internal = (SceNetAdhocPdpStatInternal *)malloc(sizeof(SceNetAdhocPdpStatInternal)); // Allocated Memory if (internal != NULL) { // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPdpStat)); + memset(internal, 0, sizeof(SceNetAdhocPdpStatInternal)); // Find Free Translator Index int i = 0; @@ -1030,7 +1030,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Valid Socket ID if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) { // Cast Socket - SceNetAdhocPdpStat * socket = pdp[id - PdpIdStart]; + auto socket = pdp[id - PdpIdStart]; // Valid Data Buffer if (data != NULL) { @@ -1235,7 +1235,7 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Valid Socket ID if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) { // Cast Socket - SceNetAdhocPdpStat * socket = pdp[id - PdpIdStart]; + auto socket = pdp[id - PdpIdStart]; // Valid Arguments if (saddr != NULL && port != NULL && buf != NULL && len != NULL && *len > 0) { @@ -1396,11 +1396,25 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * return ERROR_NET_ADHOC_NOT_INITIALIZED; } +int NetAdhoc_SetSocketAlert(int id, int flag) { + // FIXME: Should we check for valid Alert Flags and/or Mask them? Should we return an error if we found an invalid flag? + int flg = flag & ADHOC_F_ALERTALL; + + if (id > 0 && id < MAX_SOCKET && ptp[id - 1] != NULL) + ptp[id - 1]->flags = flg; + else if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) + pdp[id - PdpIdStart]->flags = flg; + else + return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + + return 0; +} + // Flags seems to be bitmasks of ADHOC_F_ALERT... int sceNetAdhocSetSocketAlert(int id, int flag) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocSetSocketAlert(%d, %08x) at %08x", id, flag, currentMIPS->pc); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocSetSocketAlert(%d, %08x) at %08x", id, flag, currentMIPS->pc); - return 0; //Dummy Result + return NetAdhoc_SetSocketAlert(id, flag); } int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { @@ -1528,7 +1542,7 @@ int NetAdhocPdp_Delete(int id, int unknown) { // Valid Arguments if (id >= PdpIdStart && id < PdpIdEnd) { // Cast Socket - SceNetAdhocPdpStat* sock = pdp[id - PdpIdStart]; + auto sock = pdp[id - PdpIdStart]; // Valid Socket if (sock != NULL) { @@ -2300,14 +2314,17 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { { s32_le *buflen = NULL; if (Memory::IsValidAddress(structSize)) buflen = (s32_le *)Memory::GetPointer(structSize); - SceNetAdhocPdpStat *buf = NULL; - if (Memory::IsValidAddress(structAddr)) buf = (SceNetAdhocPdpStat *)Memory::GetPointer(structAddr); + SceNetAdhocPdpStatEmu *buf = NULL; + if (Memory::IsValidAddress(structAddr)) buf = (SceNetAdhocPdpStatEmu *)Memory::GetPointer(structAddr); + + // Socket Count + int socketcount = getPDPSocketCount(); // Length Returner Mode if (buflen != NULL && buf == NULL) { // Return Required Size - *buflen = sizeof(SceNetAdhocPdpStat) * getPDPSocketCount(); + *buflen = sizeof(SceNetAdhocPdpStatEmu) * socketcount; // Success return 0; @@ -2316,11 +2333,8 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { // Status Returner Mode else if (buflen != NULL && buf != NULL) { - // Socket Count - int socketcount = getPDPSocketCount(); - // Figure out how many Sockets we will return - int count = *buflen / sizeof(SceNetAdhocPdpStat); + int count = *buflen / sizeof(SceNetAdhocPdpStatEmu); if (count > socketcount) count = socketcount; // Copy Counter @@ -2333,7 +2347,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { if (pdp[j] != NULL) { // Copy Socket Data from Internal Memory - buf[i] = *pdp[j]; + memcpy(&buf[i], pdp[j], sizeof(SceNetAdhocPdpStatEmu)); // Fix Client View Socket ID buf[i].id = j + PdpIdStart; @@ -2343,7 +2357,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { // Link Previous Element if (i > 0) - buf[i - 1].next = structAddr + ((i - 1LL) * sizeof(SceNetAdhocPdpStat)) + sizeof(SceNetAdhocPdpStat); + buf[i - 1].next = structAddr + (i * sizeof(SceNetAdhocPdpStatEmu)); // Increment Counter i++; @@ -2351,7 +2365,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { } // Update Buffer Length - *buflen = i * sizeof(SceNetAdhocPdpStat); + *buflen = i * sizeof(SceNetAdhocPdpStatEmu); // Success return 0; @@ -2378,15 +2392,18 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { s32_le *buflen = NULL; if (Memory::IsValidAddress(structSize)) buflen = (s32_le *)Memory::GetPointer(structSize); - SceNetAdhocPtpStat *buf = NULL; - if (Memory::IsValidAddress(structAddr)) buf = (SceNetAdhocPtpStat *)Memory::GetPointer(structAddr); + SceNetAdhocPtpStatEmu *buf = NULL; + if (Memory::IsValidAddress(structAddr)) buf = (SceNetAdhocPtpStatEmu *)Memory::GetPointer(structAddr); // Library is initialized if (netAdhocInited) { + // Socket Count + int socketcount = getPTPSocketCount(); + // Length Returner Mode if (buflen != NULL && buf == NULL) { // Return Required Size - *buflen = sizeof(SceNetAdhocPtpStat) * getPTPSocketCount(); + *buflen = sizeof(SceNetAdhocPtpStatEmu) * socketcount; // Success return 0; @@ -2394,11 +2411,8 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Status Returner Mode else if (buflen != NULL && buf != NULL) { - // Socket Count - int socketcount = getPTPSocketCount(); - // Figure out how many Sockets we will return - int count = *buflen / sizeof(SceNetAdhocPtpStat); + int count = *buflen / sizeof(SceNetAdhocPtpStatEmu); if (count > socketcount) count = socketcount; // Copy Counter @@ -2409,7 +2423,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Active Socket if (ptp[j] != NULL) { // Copy Socket Data from internal Memory - buf[i] = *ptp[j]; + memcpy(&buf[i], ptp[j], sizeof(SceNetAdhocPtpStatEmu)); // Fix Client View Socket ID buf[i].id = j + 1; @@ -2419,7 +2433,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Link previous Element to this one if (i > 0) - buf[i - 1].next = structAddr + ((i - 1LL) * sizeof(SceNetAdhocPtpStat)) + sizeof(SceNetAdhocPtpStat); + buf[i - 1].next = structAddr + (i * sizeof(SceNetAdhocPtpStatEmu)); // Increment Counter i++; @@ -2427,7 +2441,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { } // Update Buffer Length - *buflen = i * sizeof(SceNetAdhocPtpStat); + *buflen = i * sizeof(SceNetAdhocPtpStatEmu); // Success return 0; @@ -2526,7 +2540,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, } // Allocate Memory - SceNetAdhocPtpStat * internal = (SceNetAdhocPtpStat *)malloc(sizeof(SceNetAdhocPtpStat)); + SceNetAdhocPtpStatInternal * internal = (SceNetAdhocPtpStatInternal *)malloc(sizeof(SceNetAdhocPtpStatInternal)); // Allocated Memory if (internal != NULL) { @@ -2537,7 +2551,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Found Free Translator ID if (i < MAX_SOCKET) { // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPtpStat)); + memset(internal, 0, sizeof(SceNetAdhocPtpStatInternal)); // Copy Infrastructure Socket ID internal->id = tcpsocket; @@ -2602,7 +2616,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port) { // Cast Socket - SceNetAdhocPtpStat* socket = ptp[ptpId - 1]; + auto socket = ptp[ptpId - 1]; // Enable Port Re-use setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); @@ -2623,7 +2637,7 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther // Find Peer MAC if (resolveIP(peeraddr.sin_addr.s_addr, &mac)) { // Allocate Memory - SceNetAdhocPtpStat* internal = (SceNetAdhocPtpStat*)malloc(sizeof(SceNetAdhocPtpStat)); + SceNetAdhocPtpStatInternal* internal = (SceNetAdhocPtpStatInternal*)malloc(sizeof(SceNetAdhocPtpStatInternal)); // Allocated Memory if (internal != NULL) { @@ -2634,7 +2648,7 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther // Found Free Translator ID if (i < MAX_SOCKET) { // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPtpStat)); + memset(internal, 0, sizeof(SceNetAdhocPtpStatInternal)); // Copy Socket Descriptor to Structure internal->id = newsocket; @@ -2720,7 +2734,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Valid Socket if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket - SceNetAdhocPtpStat * socket = ptp[id - 1]; + auto socket = ptp[id - 1]; // Listener Socket if (socket->state == ADHOC_PTP_STATE_LISTEN) { @@ -2795,7 +2809,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Valid Socket if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket - SceNetAdhocPtpStat * socket = ptp[id - 1]; + auto socket = ptp[id - 1]; // Phantasy Star Portable 2 will try to reconnect even when previous connect already success, so we should return success too if it's already connected if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) @@ -2883,7 +2897,7 @@ int NetAdhocPtp_Close(int id, int unknown) { // Valid Arguments & Atleast one Socket if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket - SceNetAdhocPtpStat* socket = ptp[id - 1]; + auto socket = ptp[id - 1]; // Close Connection shutdown(socket->id, SD_BOTH); @@ -3011,7 +3025,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Switch into Listening Mode if ((iResult = listen(tcpsocket, backlog)) == 0) { // Allocate Memory - SceNetAdhocPtpStat * internal = (SceNetAdhocPtpStat *)malloc(sizeof(SceNetAdhocPtpStat)); + SceNetAdhocPtpStatInternal * internal = (SceNetAdhocPtpStatInternal *)malloc(sizeof(SceNetAdhocPtpStatInternal)); // Allocated Memory if (internal != NULL) { @@ -3022,7 +3036,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Found Free Translator ID if (i < MAX_SOCKET) { // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPtpStat)); + memset(internal, 0, sizeof(SceNetAdhocPtpStatInternal)); // Copy Infrastructure Socket ID internal->id = tcpsocket; @@ -3115,7 +3129,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Valid Socket if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket - SceNetAdhocPtpStat * socket = ptp[id - 1]; + auto socket = ptp[id - 1]; // Connected Socket if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) { @@ -3203,7 +3217,7 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Valid Socket if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL && ptp[id - 1]->state == ADHOC_PTP_STATE_ESTABLISHED) { // Cast Socket - SceNetAdhocPtpStat * socket = ptp[id - 1]; + auto socket = ptp[id - 1]; // Valid Arguments if (buf != NULL && len != NULL && *len > 0) { @@ -3301,7 +3315,7 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { // Valid Socket if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { // Cast Socket - SceNetAdhocPtpStat* socket = ptp[id - 1]; + auto socket = ptp[id - 1]; // Connected Socket if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) { @@ -3367,15 +3381,21 @@ static int sceNetAdhocGameModeDeleteReplica(int id) { } int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGetSocketAlert(%i, %08x) at %08x", id, flagPtr, currentMIPS->pc); - - // Dummy Value - if (Memory::IsValidAddress(flagPtr)) { - s32_le * flag = (s32_le*)Memory::GetPointer(flagPtr); - *flag = 0; //ADHOC_F_ALERTALL - } + WARN_LOG(SCENET, "UNTESTED sceNetAdhocGetSocketAlert(%i, %08x) at %08x", id, flagPtr, currentMIPS->pc); + s32_le flg = 0; + + if (id > 0 && id < MAX_SOCKET && ptp[id - 1] != NULL) + flg = ptp[id - 1]->flags; + else if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) + flg = pdp[id - PdpIdStart]->flags; + else + return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + + if (!Memory::IsValidAddress(flagPtr)) + return ERROR_NET_ADHOC_INVALID_ARG; + + Memory::Write_U32(flg, flagPtr); - // Dummy Result return 0; } @@ -3383,6 +3403,9 @@ int NetAdhocMatching_Stop(int matchingId) { SceNetAdhocMatchingContext* item = findMatchingContext(matchingId); if (item != NULL) { + // This will cause using PdpRecv on this socket to return ERROR_NET_ADHOC_SOCKET_ALERTED (Based on Ys vs. Sora no Kiseki when tested with JPCSP + prx files). Is this used to abort inprogress socket activity? + NetAdhoc_SetSocketAlert(item->socket, ADHOC_F_ALERTRECV); + item->inputRunning = false; if (item->inputThread.joinable()) { item->inputThread.join(); From 69b3c788eb5072aab1f9577d19198d757321da8d Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 7 Sep 2020 02:38:45 +0700 Subject: [PATCH 640/848] Ignore SIGPIPE error on certain system (ie. Linux) --- Core/HLE/proAdhoc.cpp | 22 +++++++++++++--- Core/HLE/proAdhoc.h | 5 ++++ Core/HLE/proAdhocServer.cpp | 23 +++++++++------- Core/HLE/sceNetAdhoc.cpp | 52 ++++++++++++++++++++++++------------- 4 files changed, 71 insertions(+), 31 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a0a3e89cad..5b8e5bbc4d 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -30,6 +30,11 @@ #include #endif +#ifndef MSG_NOSIGNAL +// Default value to 0x00 (do nothing) in systems where it's not supported. +#define MSG_NOSIGNAL 0x00 +#endif + #include #include "i18n/i18n.h" @@ -1203,7 +1208,7 @@ void sendChat(std::string chatString) { strcpy(chat.message, message.c_str()); //Send Chat Messages if (IsSocketReady(metasocket, false, true) > 0) { - int chatResult = send(metasocket, (const char*)&chat, sizeof(chat), 0); + int chatResult = send(metasocket, (const char*)&chat, sizeof(chat), MSG_NOSIGNAL); NOTICE_LOG(SCENET, "Send Chat %s to Adhoc Server", chat.message); name = g_Config.sNickName.c_str(); chatLog.push_back(name.substr(0, 8) + ": " + chat.message); @@ -1283,7 +1288,7 @@ int friendFinder(){ // Send Ping to Server, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) if (IsSocketReady(metasocket, false, true) > 0) { - int iResult = send(metasocket, (const char*)&opcode, 1, 0); + int iResult = send(metasocket, (const char*)&opcode, 1, MSG_NOSIGNAL); int error = errno; // KHBBS seems to be getting error 10053 often if (iResult == SOCKET_ERROR) { @@ -1306,7 +1311,7 @@ int friendFinder(){ // Check for Incoming Data if (IsSocketReady(metasocket, true, false) > 0) { - int received = recv(metasocket, (char*)(rx + rxpos), sizeof(rx) - rxpos, 0); + int received = recv(metasocket, (char*)(rx + rxpos), sizeof(rx) - rxpos, MSG_NOSIGNAL); // Free Network Lock //_freeNetworkLock(); @@ -1807,6 +1812,15 @@ int setSockNoDelay(int tcpsock, int flag) { return setsockopt(tcpsock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt)); } +int setSockNoSIGPIPE(int sock, int flag) { + // Set SIGPIPE when supported (ie. BSD/MacOS X) + int opt = flag; +#if defined(SO_NOSIGPIPE) + return setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt)); +#endif + return -1; +} + #if !defined(TCP_KEEPIDLE) #define TCP_KEEPIDLE TCP_KEEPALIVE //TCP_KEEPIDLE on Linux is equivalent to TCP_KEEPALIVE on macOS #endif @@ -1978,7 +1992,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ memcpy(packet.game.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); IsSocketReady(metasocket, false, true, nullptr, adhocDefaultTimeout * 1000); - int sent = send(metasocket, (char*)&packet, sizeof(packet), 0); + int sent = send(metasocket, (char*)&packet, sizeof(packet), MSG_NOSIGNAL); if (sent > 0) { socklen_t addrLen = sizeof(LocalIP); memset(&LocalIP, 0, addrLen); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index fa9d520e3e..a843c589aa 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -1240,6 +1240,11 @@ int getSockNoDelay(int tcpsock); */ int setSockNoDelay(int tcpsock, int flag); +/* +* Set Socket SO_NOSIGPIPE when supported +*/ +int setSockNoSIGPIPE(int sock, int flag); + /* * Set Socket KeepAlive (opt = SO_KEEPALIVE) */ diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 0d83b705b7..b050ca43b2 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -44,6 +44,11 @@ #include //#include +#ifndef MSG_NOSIGNAL +// Default value to 0x00 (do nothing) in systems where it's not supported. +#define MSG_NOSIGNAL 0x00 +#endif + #include "i18n/i18n.h" #include "thread/threadutil.h" @@ -848,7 +853,7 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group packet.ip = user->resolver.ip; // Send Data - int iResult = send(peer->stream, (const char*)&packet, sizeof(packet), 0); + int iResult = send(peer->stream, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL); if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: connect_user[send peer] (Socket error %d)", errno); // Set Player Name @@ -861,7 +866,7 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group packet.ip = peer->resolver.ip; // Send Data - iResult = send(user->stream, (const char*)&packet, sizeof(packet), 0); + iResult = send(user->stream, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL); if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: connect_user[send user] (Socket error %d)", errno); // Set BSSID @@ -883,7 +888,7 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group g->playercount++; // Send Network BSSID to User - int iResult = send(user->stream, (const char*)&bssid, sizeof(bssid), 0); + int iResult = send(user->stream, (const char*)&bssid, sizeof(bssid), MSG_NOSIGNAL); if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: connect_user[send user bssid] (Socket error %d)", errno); // Notify User @@ -975,7 +980,7 @@ void disconnect_user(SceNetAdhocctlUserNode * user) packet.ip = user->resolver.ip; // Send Data - int iResult = send(peer->stream, (const char*)&packet, sizeof(packet), 0); + int iResult = send(peer->stream, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL); if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: disconnect_user[send peer] (Socket error %d)", errno); // Move Pointer @@ -1074,13 +1079,13 @@ void send_scan_results(SceNetAdhocctlUserNode * user) } // Send Group Packet - int iResult = send(user->stream, (const char*)&packet, sizeof(packet), 0); + int iResult = send(user->stream, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL); if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: send_scan_result[send user] (Socket error %d)", errno); } // Notify Player of End of Scan uint8_t opcode = OPCODE_SCAN_COMPLETE; - int iResult = send(user->stream, (const char*)&opcode, 1, 0); + int iResult = send(user->stream, (const char*)&opcode, 1, MSG_NOSIGNAL); if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: send_scan_result[send peer complete] (Socket error %d)", errno); // Notify User @@ -1139,7 +1144,7 @@ void spread_message(SceNetAdhocctlUserNode *user, const char *message) strcpy(packet.base.message, message); // Send Data - int iResult = send(user->stream, (const char*)&packet, sizeof(packet), 0); + int iResult = send(user->stream, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL); if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: spread_message[send user chat] (Socket error %d)", errno); } } @@ -1181,7 +1186,7 @@ void spread_message(SceNetAdhocctlUserNode *user, const char *message) packet.name = user->resolver.name; // Send Data - int iResult = send(peer->stream, (const char*)&packet, sizeof(packet), 0); + int iResult = send(peer->stream, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL); if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: spread_message[send peer chat] (Socket error %d)", errno); // Move Pointer @@ -1930,7 +1935,7 @@ int server_loop(int server) SceNetAdhocctlUserNode * next = user->next; // Receive Data from User - int recvresult = recv(user->stream, (char*)user->rx + user->rxpos, sizeof(user->rx) - user->rxpos, 0); + int recvresult = recv(user->stream, (char*)user->rx + user->rxpos, sizeof(user->rx) - user->rxpos, MSG_NOSIGNAL); // Connection Closed or Timed Out if(recvresult == 0 || (recvresult == -1 && errno != EAGAIN && errno != EWOULDBLOCK) || get_user_state(user) == USER_STATE_TIMED_OUT) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 242b0047b0..55abf64f27 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -23,6 +23,11 @@ #include #endif +#ifndef MSG_NOSIGNAL +// Default value to 0x00 (do nothing) in systems where it's not supported. +#define MSG_NOSIGNAL 0x00 +#endif + #include #include "thread/threadutil.h" // sceNetAdhoc @@ -160,7 +165,7 @@ static void __AdhocctlNotify(u64 userdata, int cyclesLate) { // Send Packet if it wasn't succesfully sent before if (len > 0) { if (IsSocketReady(metasocket, false, true) > 0) { - int ret = send(metasocket, (const char*)&packet, len, 0); + int ret = send(metasocket, (const char*)&packet, len, MSG_NOSIGNAL); int sockerr = errno; if (ret > 0 || (ret == SOCKET_ERROR && sockerr != EAGAIN && sockerr != EWOULDBLOCK)) { @@ -223,12 +228,12 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { memset(&sin, 0, sizeof(sin)); socklen_t sinlen = sizeof(sin); - int ret = recvfrom(uid, (char*)req.buffer, *req.length, MSG_PEEK, (sockaddr*)&sin, &sinlen); + int ret = recvfrom(uid, (char*)req.buffer, *req.length, MSG_PEEK | MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); int sockerr = errno; // Note: UDP must not be received partially, otherwise leftover data in socket's buffer will be discarded if (ret >= 0 && ret <= *req.length) { - ret = recvfrom(uid, (char*)req.buffer, *req.length, 0, (sockaddr*)&sin, &sinlen); + ret = recvfrom(uid, (char*)req.buffer, *req.length, MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); // UDP can also receives 0 data, while on TCP receiving 0 data = connection gracefully closed, but not sure whether PDP can send/recv 0 data or not tho if (ret > 0) { DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", req.id, getLocalPort(uid), ret, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); @@ -292,7 +297,7 @@ int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTa target.sin_addr.s_addr = peer->ip; target.sin_port = htons(peer->port + ((isOriPort && !isPrivateIP(peer->ip)) ? 0 : portOffset)); - int ret = sendto(pdpsocket->id, (const char*)req.buffer, targetPeers.length, 0, (sockaddr*)&target, sizeof(target)); + int ret = sendto(pdpsocket->id, (const char*)req.buffer, targetPeers.length, MSG_NOSIGNAL, (sockaddr*)&target, sizeof(target)); int sockerr = errno; if (ret >= 0) { @@ -327,7 +332,7 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { auto ptpsocket = ptp[req.id - 1]; // Send Data - int ret = send(uid, (const char*)req.buffer, *req.length, 0); + int ret = send(uid, (const char*)req.buffer, *req.length, MSG_NOSIGNAL); int sockerr = errno; // Success @@ -367,7 +372,7 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { auto ptpsocket = ptp[req.id - 1]; - int ret = recv(uid, (char*)req.buffer, *req.length, 0); + int ret = recv(uid, (char*)req.buffer, *req.length, MSG_NOSIGNAL); int sockerr = errno; // Received Data @@ -869,9 +874,11 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u // Enable KeepAlive setSockKeepAlive(usocket, true); + // Ignore SIGPIPE when supported (ie. BSD/MacOS) + setSockNoSIGPIPE(usocket, 1); + // Enable Port Re-use, this will allow binding to an already used port, but only one of them can read the data (shared receive buffer?) - int one = 1; - setsockopt(usocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); // NO idea if we need this + setsockopt(usocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); // Binding Information for local Port sockaddr_in addr; @@ -1062,7 +1069,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int //_acquireNetworkLock(); // Send Data. UDP are guaranteed to be sent as a whole or nothing(failed if len > SO_MAX_MSG_SIZE), and never be partially sent/recv - int sent = sendto(socket->id, (const char *)data, len, 0, (sockaddr *)&target, sizeof(target)); + int sent = sendto(socket->id, (const char *)data, len, MSG_NOSIGNAL, (sockaddr *)&target, sizeof(target)); int error = errno; if (sent == SOCKET_ERROR) { @@ -1159,7 +1166,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int target.sin_addr.s_addr = peer.ip; target.sin_port = htons(dport + ((isOriPort && !isPrivateIP(peer.ip)) ? 0 : portOffset)); - int sent = sendto(socket->id, (const char*)data, len, 0, (sockaddr*)&target, sizeof(target)); + int sent = sendto(socket->id, (const char*)data, len, MSG_NOSIGNAL, (sockaddr*)&target, sizeof(target)); int error = errno; if (sent == SOCKET_ERROR) { DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](BC) [size=%i]", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); @@ -1283,7 +1290,7 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Receive Data. PDP always sent in full size or nothing(failed), recvfrom will always receive in full size as requested (blocking) or failed (non-blocking). If available UDP data is larger than buffer, excess data is lost. // Should peek first for the available data size if it's more than len return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE along with required size in len to prevent losing excess data - received = recvfrom(socket->id, (char*)buf, *len, MSG_PEEK, (sockaddr*)&sin, &sinlen); + received = recvfrom(socket->id, (char*)buf, *len, MSG_PEEK | MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); if (received != SOCKET_ERROR && *len < received) { WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Peeked %u/%u bytes from %s:%u\n", id, getLocalPort(socket->id), received, *len, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); *len = received; @@ -1309,7 +1316,7 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE; //received; } - received = recvfrom(socket->id, (char*)buf, *len, 0, (sockaddr*)&sin, &sinlen); + received = recvfrom(socket->id, (char*)buf, *len, MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); error = errno; if (received == SOCKET_ERROR) { @@ -1645,7 +1652,7 @@ int sceNetAdhocctlScan() { uint8_t opcode = OPCODE_SCAN; // Send Scan Request Packet, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) - int iResult = send(metasocket, (char *)&opcode, 1, 0); + int iResult = send(metasocket, (char *)&opcode, 1, MSG_NOSIGNAL); int error = errno; if (iResult == SOCKET_ERROR) { @@ -1833,7 +1840,7 @@ u32 NetAdhocctl_Disconnect() { //_acquireNetworkLock(); // Send Disconnect Request Packet - iResult = send(metasocket, (const char*)&opcode, 1, 0); + iResult = send(metasocket, (const char*)&opcode, 1, MSG_NOSIGNAL); error = errno; // Sending may get socket error 10053 if the AdhocServer is already shutted down @@ -2114,7 +2121,7 @@ int NetAdhocctl_Create(const char* groupName) { // Acquire Network Lock // Send Packet - int iResult = send(metasocket, (const char*)&packet, sizeof(packet), 0); + int iResult = send(metasocket, (const char*)&packet, sizeof(packet), MSG_NOSIGNAL); int error = errno; if (iResult == SOCKET_ERROR && error != EAGAIN && error != EWOULDBLOCK) { @@ -2512,6 +2519,9 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Enable KeepAlive setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); + // Ignore SIGPIPE when supported (ie. BSD/MacOS) + setSockNoSIGPIPE(tcpsocket, 1); + // Enable Port Re-use setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); @@ -2618,6 +2628,9 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther // Cast Socket auto socket = ptp[ptpId - 1]; + // Ignore SIGPIPE when supported (ie. BSD/MacOS) + setSockNoSIGPIPE(newsocket, 1); + // Enable Port Re-use setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); @@ -2996,6 +3009,9 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Enable KeepAlive setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); + // Ignore SIGPIPE when supported (ie. BSD/MacOS) + setSockNoSIGPIPE(tcpsocket, 1); + // Enable Port Re-use setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); @@ -3146,7 +3162,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // _acquireNetworkLock(); // Send Data - int sent = send(socket->id, data, *len, 0); + int sent = send(socket->id, data, *len, MSG_NOSIGNAL); int error = errno; // Free Network Lock @@ -3236,7 +3252,7 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou int error = 0; // Receive Data - received = recv(socket->id, (char*)buf, *len, 0); + received = recv(socket->id, (char*)buf, *len, MSG_NOSIGNAL); error = errno; if (received == SOCKET_ERROR) { @@ -3331,7 +3347,7 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { // Send Empty Data just to trigger Nagle on/off effect to flush the send buffer, Do we need to trigger this at all or is it automatically flushed? //changeBlockingMode(socket->id, nonblock); - int sent = send(socket->id, 0, 0, 0); + int sent = send(socket->id, 0, 0, MSG_NOSIGNAL); int error = errno; //changeBlockingMode(socket->id, 1); From 442d3685dc802edccd43029434eb3de26c3ebbb2 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 7 Sep 2020 02:56:59 +0700 Subject: [PATCH 641/848] Fixed an issue where the 1st line showing 17 bytes of data instead of 16 bytes like the rest of the lines --- ext/native/base/stringutil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp index adcd94b20a..c26bc0c5bd 100644 --- a/ext/native/base/stringutil.cpp +++ b/ext/native/base/stringutil.cpp @@ -64,9 +64,9 @@ void StringUpper(char *str, int len) { void DataToHexString(const uint8_t *data, size_t size, std::string *output) { Buffer buffer; for (size_t i = 0; i < size; i++) { - buffer.Printf("%02x ", data[i]); if (i && !(i & 15)) buffer.Printf("\n"); + buffer.Printf("%02x ", data[i]); } buffer.TakeAll(output); } From 2040be06e1af1630374a6f6032bc15bca392f15a Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 7 Sep 2020 02:59:12 +0700 Subject: [PATCH 642/848] Added another HexData printing with offset and ASCII contents to help dumping some data in the logs --- ext/native/base/stringutil.cpp | 28 ++++++++++++++++++++++++++++ ext/native/base/stringutil.h | 1 + 2 files changed, 29 insertions(+) diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp index c26bc0c5bd..b3a992c711 100644 --- a/ext/native/base/stringutil.cpp +++ b/ext/native/base/stringutil.cpp @@ -71,6 +71,34 @@ void DataToHexString(const uint8_t *data, size_t size, std::string *output) { buffer.TakeAll(output); } +void DataToHexString(const char* prefix, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output) { + Buffer buffer; + size_t i = 0; + for (; i < size; i++) { + if (i && !(i & 15)) { + buffer.Printf(" "); + for (size_t j = i - 16; j < i; j++) { + buffer.Printf("%c", ((data[j] < 0x20) || (data[j] > 0x7e)) ? 0x2e : data[j]); + } + buffer.Printf("\n"); + } + if (!(i & 15)) + buffer.Printf("%s%08x ", prefix, startAddr + i); + buffer.Printf("%02x ", data[i]); + } + if (size & 15) { + size_t padded_size = ((size-1) | 15) + 1; + for (size_t j = size; j < padded_size; j++) { + buffer.Printf(" "); + } + buffer.Printf(" "); + for (size_t j = size & ~UINT64_C(0xF); j < size; j++) { + buffer.Printf("%c", ((data[j] < 0x20) || (data[j] > 0x7e)) ? 0x2e : data[j]); + } + } + buffer.TakeAll(output); +} + std::string StringFromFormat(const char* format, ...) { va_list args; diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h index 05551d4043..6721930195 100644 --- a/ext/native/base/stringutil.h +++ b/ext/native/base/stringutil.h @@ -55,6 +55,7 @@ inline bool endsWithNoCase(const std::string &str, const std::string &what) { } void DataToHexString(const uint8_t *data, size_t size, std::string *output); +void DataToHexString(const char* prefix, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output); inline void StringToHexString(const std::string &data, std::string *output) { DataToHexString((uint8_t *)(&data[0]), data.size(), output); } From b1d6f6aa484eaf9eda27ef1b8bc0d8851235fd1f Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 7 Sep 2020 03:21:29 +0700 Subject: [PATCH 643/848] Added some more info in Debug Log to help debugging --- Core/HLE/sceNet.cpp | 2 +- Core/HLE/sceNetAdhoc.cpp | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 6187a3e1ad..d1ad7e15e5 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -645,7 +645,7 @@ static u32 sceWlanGetSwitchState() { // Probably a void function, but often returns a useful value. static void sceNetEtherNtostr(u32 macPtr, u32 bufferPtr) { - DEBUG_LOG(SCENET, "sceNetEtherNtostr(%08x, %08x)", macPtr, bufferPtr); + DEBUG_LOG(SCENET, "sceNetEtherNtostr(%08x, %08x) at %08x", macPtr, bufferPtr, currentMIPS->pc); if (Memory::IsValidAddress(bufferPtr) && Memory::IsValidAddress(macPtr)) { char *buffer = (char *)Memory::GetPointer(bufferPtr); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 242b0047b0..0d311e144e 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1953,7 +1953,7 @@ int sceNetAdhocctlTerm() { } static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { - DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x)", mac2str((SceNetEtherAddr*)mac).c_str(), nameAddr); + DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), nameAddr, currentMIPS->pc); // Library initialized if (netAdhocctlInited) @@ -5043,9 +5043,17 @@ void broadcastHelloMessage(SceNetAdhocMatchingContext * context) // Hello Data Length (have to memcpy this to avoid cpu alignment crash) memcpy(hello + 1, &context->hellolen, sizeof(context->hellolen)); + // FIXME: When using JPCSP + prx files the data being sent have a header of 12 bytes instead of 5 bytes: + // [01(always 1? size of the next data? or combined with next byte as U16_BE opcode?) 01(matching opcode, or combined with previous byte as U16_BE opcode?) 01 E0(size of next data + hello data in big-endian/U16_BE) 00 0F 42 40(U32_BE? time?) 00 0F 42 40(U32_BE? time?)], + // followed by hello data (0x1D8 bytes of opt data, based on Ys vs. Sora no Kiseki), and followed by 16 bytes of (optional?) footer [01 00 00 .. 00 00](footer doesn't exist if the size after opcode is 00 00) + // Copy Hello Data if (context->hellolen > 0) memcpy(hello + 5, context->hello, context->hellolen); + std::string hellohex; + DataToHexString(" ", 0, context->hello, context->hellolen, &hellohex); + DEBUG_LOG(SCENET, "HELLO Dump:\n%s", hellohex.c_str()); + // Send Broadcast context->socketlock->lock(); sceNetAdhocPdpSend(context->socket, (const char*)(SceNetEtherAddr *)broadcastMAC, context->port, hello, 5 + context->hellolen, 0, ADHOC_F_NONBLOCK); @@ -5472,6 +5480,10 @@ void actOnHelloPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * se // Peer available now if (peer != NULL && peer->state != PSP_ADHOC_MATCHING_PEER_OUTGOING_REQUEST && peer->state != PSP_ADHOC_MATCHING_PEER_INCOMING_REQUEST) { + std::string hellohex; + DataToHexString(" ", 0, (u8*)opt, optlen, &hellohex); + DEBUG_LOG(SCENET, "HELLO Dump:\n%s", hellohex.c_str()); + // Spawn Hello Event. FIXME: HELLO event should not be triggered in the middle of joining? This will cause Bleach 7 to Cancel the join request spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_HELLO, sendermac, optlen, opt); } @@ -6210,6 +6222,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi } // Receive PDP Datagram + // FIXME: When using JPCSP + prx files, the "SceNetAdhocMatchingInput" thread is using blocking PdpRecv with infinite(0) timeout, which can be stopped/aborted using SetSocketAlert, while "SceNetAdhocMatchingEvent" thread is using non-blocking for sending rxbuflen = context->rxbuflen; senderport = 0; context->socketlock->lock(); From 6a2de8647f08955f2761c278b9ebfcbeb3bf97a1 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 7 Sep 2020 03:23:09 +0700 Subject: [PATCH 644/848] Fixed SceNetAdhocctlParameter structure --- Core/HLE/proAdhoc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index fa9d520e3e..f2728e3421 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -248,8 +248,8 @@ typedef struct SceNetAdhocctlNickname { typedef struct SceNetAdhocctlParameter { s32_le channel; SceNetAdhocctlGroupName group_name; // This group name is probably similar to SSID name on AP - SceNetAdhocctlBSSId bssid; - SceNetAdhocctlNickname nickname; + SceNetAdhocctlNickname nickname; // According to the old PSPSDK this is the bssid, but according to the dumped content when using newer firmware this is the nickname (this is also the nickname on VitaSDK) + SceNetAdhocctlBSSId bssid; // FIXME: bssid and nickname position might be swapped on older/newer firmware? } PACK SceNetAdhocctlParameter; // Peer Information (internal use only) @@ -270,7 +270,7 @@ typedef struct SceNetAdhocctlPeerInfoEmu { SceNetAdhocctlNickname nickname; SceNetEtherAddr mac_addr; u16_le padding; //00 00 - u32_le flags; //00 04 00 00 // State of the peer? Or related to sceNetAdhocAuth_CF4D9BED ? + u32_le flags; //00 04 00 00 on KHBBS and FF FF FF FF on Ys vs. Sora no Kiseki // State of the peer? Or related to sceNetAdhocAuth_CF4D9BED ? u64_le last_recv; // Need to use the same method with sceKernelGetSystemTimeWide (ie. CoreTiming::GetGlobalTimeUsScaled) to prevent timing issue (ie. in game timeout) } PACK SceNetAdhocctlPeerInfoEmu; From b92fab88b6080e3706baf22f541b565e2e80568c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 6 Sep 2020 13:41:29 -0700 Subject: [PATCH 645/848] Debugger: Add formats to breakpoint logging. --- Core/Debugger/Breakpoints.cpp | 47 ++++++++++++++++++++++++++++++++--- Windows/ppsspp.rc | 11 ++++---- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index f3501a370c..c988712be3 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -24,6 +24,7 @@ #include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/SymbolMap.h" #include "Core/Host.h" +#include "Core/MemMap.h" #include "Core/MIPS/MIPSAnalyst.h" #include "Core/MIPS/MIPSDebugInterface.h" #include "Core/MIPS/JitCommon/JitCommon.h" @@ -689,17 +690,55 @@ bool CBreakPoints::EvaluateLogFormat(DebugInterface *cpu, const std::string &fmt if (expression.empty()) { result += "{}"; } else { + int type = 'x'; + if (expression.length() > 2 && expression[expression.length() - 2] == ':') { + switch (expression[expression.length() - 1]) { + case 'd': + case 'f': + case 'p': + case 's': + case 'x': + type = expression[expression.length() - 1]; + expression.resize(expression.length() - 2); + break; + + default: + // Assume a ternary. + break; + } + } + if (!cpu->initExpression(expression.c_str(), exp)) { return false; } - u32 expResult; - char resultString[32]; - if (!cpu->parseExpression(exp, expResult)) { + union { + int i; + u32 u; + float f; + } expResult; + char resultString[256]; + if (!cpu->parseExpression(exp, expResult.u)) { return false; } - snprintf(resultString, 32, "%08x", expResult); + switch (type) { + case 'd': + snprintf(resultString, sizeof(resultString), "%d", expResult.i); + break; + case 'f': + snprintf(resultString, sizeof(resultString), "%f", expResult.f); + break; + case 'p': + snprintf(resultString, sizeof(resultString), "%08x[%08x]", expResult.u, Memory::IsValidAddress(expResult.u) ? Memory::Read_U32(expResult.u) : 0); + break; + case 's': + snprintf(resultString, sizeof(resultString) - 1, "%s", Memory::IsValidAddress(expResult.u) ? Memory::GetCharPointer(expResult.u) : "(invalid)"); + break; + case 'x': + snprintf(resultString, sizeof(resultString), "%08x", expResult.u); + break; + } result += resultString; } diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index f47d373935..5dcb0806a8 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -351,7 +351,7 @@ BEGIN CONTROL "",IDC_TABDATATYPE,"SysTabControl32",TCS_BUTTONS,0,1,205,15 END -IDD_BREAKPOINT DIALOGEX 0, 0, 236, 109 +IDD_BREAKPOINT DIALOGEX 0, 0, 236, 119 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Breakpoint" FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -369,10 +369,11 @@ BEGIN EDITTEXT IDC_BREAKPOINT_CONDITION,41,49,187,14,ES_AUTOHSCROLL LTEXT "Log fmt",IDC_STATIC,7,71,31,8 EDITTEXT IDC_BREAKPOINT_LOG_FORMAT,41,69,187,14,ES_AUTOHSCROLL - CONTROL "Break",IDC_BREAKPOINT_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,91,41,10 - CONTROL "Log",IDC_BREAKPOINT_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,91,27,10 - DEFPUSHBUTTON "OK",IDC_BREAKPOINT_OK,144,88,41,14 - PUSHBUTTON "Cancel",IDC_BREAKPOINT_CANCEL,186,88,42,14 + LTEXT "Use {a1+a2} or {s1:d} to log expressions",IDC_STATIC,41,85,187,8 + CONTROL "Break",IDC_BREAKPOINT_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,101,41,10 + CONTROL "Log",IDC_BREAKPOINT_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,101,27,10 + DEFPUSHBUTTON "OK",IDC_BREAKPOINT_OK,144,98,41,14 + PUSHBUTTON "Cancel",IDC_BREAKPOINT_CANCEL,186,98,42,14 END IDD_DUMPMEMORY DIALOGEX 0, 0, 230, 85 From 815580533c328c2f2b4d1532bb1ae77e21796aee Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 6 Sep 2020 14:38:56 -0700 Subject: [PATCH 646/848] GE Debugger: Include game ID inside dump file. Just so we're not relying on filename parsing. It's useful information. --- Core/System.cpp | 21 +++++++++++++++++++-- GPU/Debugger/Playback.cpp | 18 +++++++++++++----- GPU/Debugger/Record.cpp | 7 +++++-- GPU/Debugger/RecordFormat.h | 12 ++++++++++-- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/Core/System.cpp b/Core/System.cpp index cc77f58f97..b3b1e30756 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -68,6 +68,7 @@ #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" +#include "GPU/Debugger/RecordFormat.h" enum CPUThreadState { CPU_THREAD_NOT_RUNNING, @@ -185,7 +186,23 @@ bool CPU_HasPendingAction() { void CPU_Shutdown(); -bool DiscIDFromGEDumpPath(const std::string &path, std::string *id) { +bool DiscIDFromGEDumpPath(const std::string &path, FileLoader *fileLoader, std::string *id) { + using namespace GPURecord; + + // For newer files, it's stored in the dump. + Header header; + if (fileLoader->ReadAt(0, sizeof(header), &header) == sizeof(header)) { + const bool magicMatch = memcmp(header.magic, HEADER_MAGIC, sizeof(header.magic)) == 0; + if (magicMatch && header.version <= VERSION && header.version >= 4) { + size_t gameIDLength = strnlen(header.gameID, sizeof(header.gameID)); + if (gameIDLength != 0) { + *id = std::string(header.gameID, gameIDLength); + return true; + } + } + } + + // Fall back to using the filename. std::string filename = File::GetFilename(path); // Could be more discerning, but hey.. if (filename.size() > 10 && filename[0] == 'U' && filename[9] == '_') { @@ -254,7 +271,7 @@ bool CPU_Init() { // Try to grab the disc ID from the filename, since unfortunately, we don't store // it in the GE dump. This should probably be fixed, but as long as you don't rename the dumps, // this will do the trick. - if (!DiscIDFromGEDumpPath(filename, &discID)) { + if (!DiscIDFromGEDumpPath(filename, loadedFile, &discID)) { // Failed? Let the param SFO autogen a fake disc ID. discID = g_paramSFO.GetDiscID(); } diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index 6a4e2c2e97..d05b14bc37 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -26,6 +26,7 @@ #include "Common/Log.h" #include "Core/Core.h" #include "Core/CoreTiming.h" +#include "Core/ELF/ParamSFO.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/HLE/sceDisplay.h" #include "Core/HLE/sceKernelMemory.h" @@ -671,16 +672,23 @@ bool RunMountedReplay(const std::string &filename) { if (lastExecFilename != filename) { PROFILE_THIS_SCOPE("ReplayLoad"); u32 fp = pspFileSystem.OpenFile(filename, FILEACCESS_READ); - u8 header[8]{}; - int version = 0; - pspFileSystem.ReadFile(fp, header, sizeof(header)); - pspFileSystem.ReadFile(fp, (u8 *)&version, sizeof(version)); + Header header; + pspFileSystem.ReadFile(fp, (u8 *)&header, sizeof(header)); - if (memcmp(header, HEADER, sizeof(header)) != 0 || version > VERSION || version < MIN_VERSION) { + if (memcmp(header.magic, HEADER_MAGIC, sizeof(header.magic)) != 0 || header.version > VERSION || header.version < MIN_VERSION) { ERROR_LOG(SYSTEM, "Invalid GE dump or unsupported version"); pspFileSystem.CloseFile(fp); return false; } + if (header.version <= 3) { + pspFileSystem.SeekFile(fp, 12, FILEMOVE_BEGIN); + memset(header.gameID, 0, sizeof(header.gameID)); + } + + size_t gameIDLength = strnlen(header.gameID, sizeof(header.gameID)); + if (gameIDLength != 0) { + g_paramSFO.SetValue("DISC_ID", std::string(header.gameID, gameIDLength), (int)sizeof(header.gameID)); + } u32 sz = 0; pspFileSystem.ReadFile(fp, (u8 *)&sz, sizeof(sz)); diff --git a/GPU/Debugger/Record.cpp b/GPU/Debugger/Record.cpp index 1262cf9d48..32455e3c1a 100644 --- a/GPU/Debugger/Record.cpp +++ b/GPU/Debugger/Record.cpp @@ -115,8 +115,11 @@ static std::string WriteRecording() { NOTICE_LOG(G3D, "Recording filename: %s", filename.c_str()); FILE *fp = File::OpenCFile(filename, "wb"); - fwrite(HEADER, 8, 1, fp); - fwrite(&VERSION, sizeof(VERSION), 1, fp); + Header header{}; + strncpy(header.magic, HEADER_MAGIC, sizeof(header.magic)); + header.version = VERSION; + strncpy(header.gameID, g_paramSFO.GetDiscID().c_str(), sizeof(header.gameID)); + fwrite(&header, sizeof(header), 1, fp); u32 sz = (u32)commands.size(); fwrite(&sz, sizeof(sz), 1, fp); diff --git a/GPU/Debugger/RecordFormat.h b/GPU/Debugger/RecordFormat.h index aeb7791fe2..f59e71aa7e 100644 --- a/GPU/Debugger/RecordFormat.h +++ b/GPU/Debugger/RecordFormat.h @@ -21,11 +21,19 @@ namespace GPURecord { -static const char *HEADER = "PPSSPPGE"; +struct Header { + char magic[8]; + uint32_t version; + char gameID[9]; + uint8_t pad[3]; +}; + +static const char *HEADER_MAGIC = "PPSSPPGE"; // Version 1: Uncompressed // Version 2: Uses snappy // Version 3: Adds FRAMEBUF0-FRAMEBUF9 -static const int VERSION = 3; +// Version 4: Expanded header with game ID +static const int VERSION = 4; static const int MIN_VERSION = 2; enum class CommandType : u8 { From 85fb9a61e82407798d96292dfc8506607a0c11b7 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 6 Sep 2020 22:53:27 -0700 Subject: [PATCH 647/848] TexCache: Always apply detach matches if found. The "Invalid" matches will only apply if nothing was attached, so it's important that detaches happen. --- GPU/Common/TextureCacheCommon.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 73c8a5b918..f8141274b1 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -561,34 +561,35 @@ void TextureCacheCommon::SetTexture(bool force) { bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texAddrOffset) { bool success = false; + bool anyIgnores = false; std::vector candidates; - - bool anyIgnores = false; + std::vector detaches; FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { auto framebuffer = fbCache_[i]; uint32_t fb_addr = channel == NOTIFY_FB_DEPTH ? framebuffer->z_address : framebuffer->fb_address; FramebufferMatchInfo match = MatchFramebuffer(entry, fb_addr, framebuffer, texAddrOffset, channel); - if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { - candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); - } else if (match.match == FramebufferMatch::IGNORE) { + if (match.match == FramebufferMatch::IGNORE) { anyIgnores = true; + } else if (match.match == FramebufferMatch::NO_MATCH) { + detaches.push_back(AttachCandidate{ match, entry, framebuffer, channel }); + } else { + candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); + } + } + + // If this is set, we want to defer the decision, apparently. + if (!anyIgnores) { + // If not set, always detach. They may affect inexact matches. + for (AttachCandidate &candidate : detaches) { + DetachFramebuffer(entry, entry->addr, entry->framebuffer, channel); } } if (!candidates.size()) { // No candidates at all. - if (anyIgnores) { - // We want to defer the decision, apparently. - return false; - } - - // Actively detach the current framebuffer. - if (entry->framebuffer) { - DetachFramebuffer(entry, entry->addr, entry->framebuffer, channel); - } return false; } From ee6fbd9a0b6b38f07031ab0c4d5c592d85de8deb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 6 Sep 2020 23:00:17 -0700 Subject: [PATCH 648/848] TexCache: Rename "Invalid" attach to "Inexact". The name has seemed confusing to me for a while. --- GPU/Common/TextureCacheCommon.cpp | 12 ++++++------ GPU/Common/TextureCacheCommon.h | 9 +++++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index f8141274b1..c500049e4e 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -622,7 +622,7 @@ bool TextureCacheCommon::AttachBestCandidate(const std::vector case FramebufferMatch::VALID_DEPAL: relevancy += 1000; break; - case FramebufferMatch::INVALID: + case FramebufferMatch::INEXACT: relevancy += 100; break; } @@ -859,8 +859,8 @@ void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFra } } -void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel) { - _dbg_assert_(fbInfo.match == FramebufferMatch::INVALID); +void TextureCacheCommon::AttachFramebufferInexact(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel) { + _dbg_assert_(fbInfo.match == FramebufferMatch::INEXACT); const u64 cachekey = entry->CacheKey(); if (entry->framebuffer == nullptr || entry->framebuffer == framebuffer) { @@ -902,8 +902,8 @@ bool TextureCacheCommon::ApplyFramebufferMatch(FramebufferMatchInfo match, TexCa AttachFramebufferValid(entry, framebuffer, match, channel); entry->status |= TexCacheEntry::STATUS_DEPALETTIZE; return true; - case FramebufferMatch::INVALID: - AttachFramebufferInvalid(entry, framebuffer, match, channel); + case FramebufferMatch::INEXACT: + AttachFramebufferInexact(entry, framebuffer, match, channel); return true; case FramebufferMatch::NO_MATCH: DetachFramebuffer(entry, address, framebuffer, channel); @@ -1063,7 +1063,7 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, } else { WARN_LOG_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset); // If we return VALID here, God of War Ghost of Sparta/Chains of Olympus will be missing some special effect according to an old comment. - fbInfo.match = FramebufferMatch::INVALID; + fbInfo.match = FramebufferMatch::INEXACT; return fbInfo; } } else { diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 630ef43fa9..4a90489bd0 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -193,10 +193,15 @@ typedef std::map> TexCache; // TODO: Try to get rid of IGNORE, it doesn't match what we want to do enum class FramebufferMatch { + // Valid, exact match. VALID = 0, + // Valid match that is exact after depal. VALID_DEPAL, - INVALID, + // Inexact match (such as wrong fmt or at a questionable offset.) + INEXACT, + // Not a match, remove if currently attached. NO_MATCH, + // Not a match, but don't remove yet. Used to avoid deatching depth mismatch. IGNORE, }; @@ -288,7 +293,7 @@ protected: bool AttachBestCandidate(const std::vector &candidates); void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); - void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); + void AttachFramebufferInexact(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel); void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer); From b5712efdfbce66b5688c109f657a39acdeadc10b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 7 Sep 2020 07:11:33 -0700 Subject: [PATCH 649/848] Net: Correct save state from old loaded state. Fixes #13395. --- Core/HLE/sceNetAdhoc.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 4e4ca2a8c4..496a3a892b 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -682,9 +682,13 @@ void __NetAdhocDoState(PointerWrap &p) { Do(p, adhocConnectionType); Do(p, adhocctlState); Do(p, adhocctlNotifyEvent); - CoreTiming::RestoreRegisterEvent(adhocctlNotifyEvent, "__AdhocctlNotify", __AdhocctlNotify); + if (adhocctlNotifyEvent != -1) { + CoreTiming::RestoreRegisterEvent(adhocctlNotifyEvent, "__AdhocctlNotify", __AdhocctlNotify); + } Do(p, adhocSocketNotifyEvent); - CoreTiming::RestoreRegisterEvent(adhocSocketNotifyEvent, "__AdhocSocketNotify", __AdhocSocketNotify); + if (adhocSocketNotifyEvent != -1) { + CoreTiming::RestoreRegisterEvent(adhocSocketNotifyEvent, "__AdhocSocketNotify", __AdhocSocketNotify); + } } else { adhocConnectionType = ADHOC_CONNECT; From fcaef648ec2f8972e7ff0916619ade9db47ebf37 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 7 Sep 2020 07:23:13 -0700 Subject: [PATCH 650/848] Net: Fix memory corruption on save old state. Can't restore these if they're not inited either. --- Core/HLE/sceKernelThread.cpp | 1 + Core/HLE/sceNet.cpp | 4 +++- Core/HLE/sceNetAdhoc.cpp | 8 ++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 0e096111c0..cade794e08 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -683,6 +683,7 @@ int __KernelRegisterActionType(ActionCreator creator) void __KernelRestoreActionType(int actionType, ActionCreator creator) { + _assert_(actionType >= 0); mipsCalls.restoreActionType(actionType, creator); } diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index d1ad7e15e5..7ea5500995 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -244,7 +244,9 @@ void __NetDoState(PointerWrap &p) { Do(p, netApctlState); Do(p, netApctlInfo); Do(p, actionAfterApctlMipsCall); - __KernelRestoreActionType(actionAfterApctlMipsCall, AfterApctlMipsCall::Create); + if (actionAfterApctlMipsCall != -1) { + __KernelRestoreActionType(actionAfterApctlMipsCall, AfterApctlMipsCall::Create); + } Do(p, apctlThreadHackAddr); Do(p, apctlThreadID); } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 496a3a892b..683f0878ef 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -650,7 +650,9 @@ void __NetAdhocDoState(PointerWrap &p) { if (s >= 2) { Do(p, actionAfterMatchingMipsCall); - __KernelRestoreActionType(actionAfterMatchingMipsCall, AfterMatchingMipsCall::Create); + if (actionAfterMatchingMipsCall != -1) { + __KernelRestoreActionType(actionAfterMatchingMipsCall, AfterMatchingMipsCall::Create); + } Do(p, dummyThreadHackAddr); } @@ -660,7 +662,9 @@ void __NetAdhocDoState(PointerWrap &p) { } if (s >= 3) { Do(p, actionAfterAdhocMipsCall); - __KernelRestoreActionType(actionAfterAdhocMipsCall, AfterAdhocMipsCall::Create); + if (actionAfterAdhocMipsCall != -1) { + __KernelRestoreActionType(actionAfterAdhocMipsCall, AfterAdhocMipsCall::Create); + } Do(p, matchingThreadHackAddr); } From a817a60382d1e3c2e54df3b0281d13ade83dd291 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 7 Sep 2020 15:10:26 -0700 Subject: [PATCH 651/848] TexCache: Correct detaching textures. --- GPU/Common/TextureCacheCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index c500049e4e..d9405f468e 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -584,7 +584,7 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA if (!anyIgnores) { // If not set, always detach. They may affect inexact matches. for (AttachCandidate &candidate : detaches) { - DetachFramebuffer(entry, entry->addr, entry->framebuffer, channel); + DetachFramebuffer(entry, entry->addr, candidate.fb, channel); } } From 824beb7232838837339fd72ee5b91f0dd8dbfdf6 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 8 Sep 2020 08:30:40 +0700 Subject: [PATCH 652/848] Prevent sceNetGetMallocStat from spamming Info Logs --- Core/HLE/sceNet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 7ea5500995..99ef0cbba0 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -712,7 +712,7 @@ static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) { // Write static data since we don't actually manage any memory for sceNet* yet. static int sceNetGetMallocStat(u32 statPtr) { - WARN_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x)", statPtr); + DEBUG_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x)", statPtr); if(Memory::IsValidAddress(statPtr)) Memory::WriteStruct(statPtr, &netMallocStat); else From 87965ca89b48d1ef570a6041210a34354fb13fee Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 8 Sep 2020 08:31:36 +0700 Subject: [PATCH 653/848] Changing default Wlan Channel to 11 on Automatic to be the same with real PSP --- Core/HLE/proAdhoc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 5b8e5bbc4d..c7d2b78431 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -92,7 +92,7 @@ bool isOriPort = false; bool isLocalServer = false; SockAddrIN4 g_localhostIP; sockaddr LocalIP; -int defaultWlanChannel = PSP_SYSTEMPARAM_ADHOC_CHANNEL_1; // Don't put 0(Auto) here, it needed to be a valid/actual channel number +int defaultWlanChannel = PSP_SYSTEMPARAM_ADHOC_CHANNEL_11; // Don't put 0(Auto) here, it needed to be a valid/actual channel number bool isMacMatch(const SceNetEtherAddr* addr1, const SceNetEtherAddr* addr2) { // Ignoring the 1st byte since there are games (ie. Gran Turismo) who tamper with the 1st byte of OUI to change the unicast/multicast bit From 20ad57a5111b5fc26ae82e35f1d6a49a8ca8b026 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 8 Sep 2020 08:34:35 +0700 Subject: [PATCH 654/848] Fixed return value when using Automatic Wlan Channel. Fixes Ridge Racer 2 and Warriors Orochi 2 --- Core/HLE/sceUtility.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 0421c6bb67..bc738beebb 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -717,6 +717,15 @@ static u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) switch (id) { case PSP_SYSTEMPARAM_ID_INT_ADHOC_CHANNEL: param = g_Config.iWlanAdhocChannel; + if (param == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) { + // FIXME: Actually.. it's always returning 0x800ADF4 regardless using Auto channel or Not, and regardless the connection state either, + // Not sure whether this error code only returned after Adhocctl Initialized (ie. netAdhocctlInited) or also before initialized. + // FIXME: Outputted channel (might be unchanged?) either 0 when not connected to a group yet (ie. adhocctlState == ADHOCCTL_STATE_DISCONNECTED), + // or -1 (0xFFFFFFFF) when a scan is in progress (ie. adhocctlState == ADHOCCTL_STATE_SCANNING), + // or 0x60 early when in connected state (ie. adhocctlState == ADHOCCTL_STATE_CONNECTED) right after Creating a group, regardless the channel settings. + Memory::Write_U32(param, destaddr); + return 0x800ADF4; + } break; case PSP_SYSTEMPARAM_ID_INT_WLAN_POWERSAVE: param = g_Config.bWlanPowerSave?PSP_SYSTEMPARAM_WLAN_POWERSAVE_ON:PSP_SYSTEMPARAM_WLAN_POWERSAVE_OFF; From d8d2fd8107042f2741af1f2328683511aba829ec Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 8 Sep 2020 11:06:03 +0700 Subject: [PATCH 655/848] Making use Adhoc SocketAlert Flags to stop/abort blocking sockets --- Core/HLE/sceNetAdhoc.cpp | 82 +++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 683f0878ef..7238d2c3b9 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -269,8 +269,14 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { // On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound yet), may need to disable SIO_UDP_CONNRESET error else if (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ECONNRESET || sockerr == ETIMEDOUT) { u64 now = (u64)(real_time_now() * 1000000.0); - if (req.timeout == 0 || now - req.startTime <= req.timeout) { - + auto pdpsocket = pdp[req.id - PdpIdStart]; + if (pdpsocket && (pdpsocket->flags & ADHOC_F_ALERTRECV)) { + result = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + pdpsocket->flags &= ~ADHOC_F_ALERTRECV; + } + else if (req.timeout == 0 || now - req.startTime <= req.timeout) { + // Try again later return -1; } else @@ -308,7 +314,13 @@ int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTa else { if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { u64 now = (u64)(real_time_now() * 1000000.0); - if (req.timeout == 0 || now - req.startTime <= req.timeout) { + if (pdpsocket && (pdpsocket->flags & ADHOC_F_ALERTSEND)) { + result = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + pdpsocket->flags &= ~ADHOC_F_ALERTSEND; + break; + } + else if (req.timeout == 0 || now - req.startTime <= req.timeout) { retry = true; } else @@ -345,19 +357,21 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { // Return Success result = 0; } - - // Non-Critical Error else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { u64 now = (u64)(real_time_now() * 1000000.0); - if (req.timeout == 0 || now - req.startTime <= req.timeout) { - + if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTSEND)) { + result = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + ptpsocket->flags &= ~ADHOC_F_ALERTSEND; + } + else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; } else result = ERROR_NET_ADHOC_TIMEOUT; } - // Change Socket State + // Change Socket State. // FIXME: Does Alerted Socket should be closed too? ptpsocket->state = ADHOC_PTP_STATE_CLOSED; // Disconnected @@ -389,17 +403,21 @@ int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { result = 0; } - // Non-Critical Error else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { u64 now = (u64)(real_time_now() * 1000000.0); - if (req.timeout == 0 || now - req.startTime <= req.timeout) { + if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTRECV)) { + result = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + ptpsocket->flags &= ~ADHOC_F_ALERTRECV; + } + else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; } else result = ERROR_NET_ADHOC_TIMEOUT; } else { - // Change Socket State + // Change Socket State. // FIXME: Does Alerted Socket should be closed too? ptpsocket->state = ADHOC_PTP_STATE_CLOSED; // Disconnected @@ -413,6 +431,7 @@ int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { + auto ptpsocket = ptp[req.id - 1]; sockaddr_in sin; memset(&sin, 0, sizeof(sin)); socklen_t sinlen = sizeof(sin); @@ -429,7 +448,12 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { } else if (ret == SOCKET_ERROR && connectInProgress(sockerr)) { u64 now = (u64)(real_time_now() * 1000000.0); - if (req.timeout == 0 || now - req.startTime <= req.timeout) { + if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTACCEPT)) { + result = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + ptpsocket->flags &= ~ADHOC_F_ALERTACCEPT; + } + else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; } else @@ -445,6 +469,7 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { + auto ptpsocket = ptp[req.id - 1]; int sockerr; // Wait for Connection (assuming "connect" has been called before) @@ -452,7 +477,6 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { // Connection is ready if (ret > 0) { - auto ptpsocket = ptp[req.id - 1]; sockaddr_in sin; memset(&sin, 0, sizeof(sin)); socklen_t sinlen = sizeof(sin); @@ -469,7 +493,12 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { // Timeout else if (ret == 0) { u64 now = (u64)(real_time_now() * 1000000.0); - if (req.timeout == 0 || now - req.startTime <= req.timeout) { + if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTCONNECT)) { + result = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + ptpsocket->flags &= ~ADHOC_F_ALERTCONNECT; + } + else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; } else @@ -493,9 +522,11 @@ int DoBlockingAdhocPollSocket(int uid, AdhocSocketRequest& req, s64& result) { return -1; } else if (ret == 0) - result = ERROR_NET_ADHOC_TIMEOUT; + ret = ERROR_NET_ADHOC_TIMEOUT; else - result = ERROR_NET_ADHOC_EXCEPTION_EVENT; + ret = ERROR_NET_ADHOC_EXCEPTION_EVENT; + if (ret == ERROR_NET_ADHOC_WOULD_BLOCK) + ret = ERROR_NET_ADHOC_TIMEOUT; } result = ret; @@ -1464,11 +1495,16 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { if (affectedsockets > 0) { affectedsockets = 0; for (int i = 0; i < count; i++) { + s32_le* fd_flags; if (sds[i].id <= MAX_SOCKET && ptp[sds[i].id - 1] != NULL) { - fd = ptp[sds[i].id - 1]->id; + auto sock = ptp[sds[i].id - 1]; + fd = sock->id; + fd_flags = &sock->flags; } else { - fd = pdp[sds[i].id - PdpIdStart]->id; + auto sock = pdp[sds[i].id - PdpIdStart]; + fd = sock->id; + fd_flags = &sock->flags; } if (FD_ISSET(fd, &readfds)) sds[i].revents |= ADHOC_EV_RECV; @@ -1478,8 +1514,18 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { if (FD_ISSET(fd, &exceptfds)) sds[i].revents |= ADHOC_EV_ALERT; // Does Alert can be raised on revents regardless of events bitmask? if (sds[i].revents) affectedsockets++; + + if (*fd_flags & ADHOC_F_ALERTPOLL) { + affectedsockets = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + *fd_flags &= ~ADHOC_F_ALERTPOLL; + break; + } } } + else if (affectedsockets < 0) { + affectedsockets = ERROR_NET_ADHOC_WOULD_BLOCK; + } return affectedsockets; } From 871707c6a701b0dfe8e970c72dc033545af82083 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 8 Sep 2020 13:08:32 +0700 Subject: [PATCH 656/848] Allows blocking socket simulation on multiple threads simultaneously --- Core/HLE/sceNetAdhoc.cpp | 70 +++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7238d2c3b9..568a3bf36e 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -83,8 +83,8 @@ int IsAdhocctlInCB = 0; int adhocctlNotifyEvent = -1; int adhocSocketNotifyEvent = -1; std::map adhocctlRequests; -std::map adhocSocketRequests; -std::map sendTargetPeers; +std::map adhocSocketRequests; +std::map sendTargetPeers; u32 dummyThreadHackAddr = 0; u32_le dummyThreadCode[3]; @@ -546,27 +546,27 @@ static void __AdhocSocketNotify(u64 userdata, int cyclesLate) { return; // Socket not found?! Should never happened! but if it ever happen should we just exit here or need to wake the thread first? - if (adhocSocketRequests.find(uid) == adhocSocketRequests.end()) { - WARN_LOG(SCENET, "sceNetAdhoc Socket WaitID(%i) not found!", uid); + if (adhocSocketRequests.find(userdata) == adhocSocketRequests.end()) { + WARN_LOG(SCENET, "sceNetAdhoc Socket WaitID(%i) on Thread(%i) not found!", uid, threadID); //__KernelResumeThreadFromWait(threadID, ERROR_NET_ADHOC_TIMEOUT); return; } - AdhocSocketRequest req = adhocSocketRequests[uid]; + AdhocSocketRequest req = adhocSocketRequests[userdata]; switch (req.type) { case PDP_SEND: - if (sendTargetPeers.find(uid) == sendTargetPeers.end()) { + if (sendTargetPeers.find(userdata) == sendTargetPeers.end()) { // No destination peers? result = 0; break; } - if (DoBlockingPdpSend(uid, req, result, sendTargetPeers[uid])) { + if (DoBlockingPdpSend(uid, req, result, sendTargetPeers[userdata])) { // Try again in another 0.5ms until data available or timedout. CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); return; } - sendTargetPeers.erase(uid); + sendTargetPeers.erase(userdata); break; case PDP_RECV: @@ -622,12 +622,14 @@ static void __AdhocSocketNotify(u64 userdata, int cyclesLate) { DEBUG_LOG(SCENET, "Returning (WaitID: %d, error: %d) Result (%08x) of sceNetAdhoc - SocketID: %d", waitID, error, (int)result, req.id); // We are done with this socket - adhocSocketRequests.erase(uid); + adhocSocketRequests.erase(userdata); } -int WaitBlockingAdhocSocket(int socketId, int type, int pspSocketId, void* buffer, s32_le* len, u32 timeoutUS, SceNetEtherAddr* remoteMAC, u16_le* remotePort, const char* reason) { - if (adhocSocketRequests.find(socketId) != adhocSocketRequests.end()) { - WARN_LOG(SCENET, "sceNetAdhoc - WaitID[%d] already existed, Socket[%d] is busy!", socketId, pspSocketId); +// input threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socketId; +int WaitBlockingAdhocSocket(u64 threadSocketId, int type, int pspSocketId, void* buffer, s32_le* len, u32 timeoutUS, SceNetEtherAddr* remoteMAC, u16_le* remotePort, const char* reason) { + int uid = (int)(threadSocketId & 0xFFFFFFFF); + if (adhocSocketRequests.find(threadSocketId) != adhocSocketRequests.end()) { + WARN_LOG(SCENET, "sceNetAdhoc - WaitID[%d] already existed, Socket[%d] is busy!", uid, pspSocketId); return ERROR_NET_ADHOC_BUSY; } @@ -640,12 +642,11 @@ int WaitBlockingAdhocSocket(int socketId, int type, int pspSocketId, void* buffe if (tmout > 0) tmout = std::max(tmout, minSocketTimeoutUS); - u64 param = ((u64)__KernelGetCurThread()) << 32 | socketId; u64 startTime = (u64)(real_time_now() * 1000000.0); - adhocSocketRequests[socketId] = { type, pspSocketId, buffer, len, tmout, startTime, remoteMAC, remotePort }; + adhocSocketRequests[threadSocketId] = { type, pspSocketId, buffer, len, tmout, startTime, remoteMAC, remotePort }; // Some games (ie. Power Stone Collection) are using as small as 100 usec timeout - CoreTiming::ScheduleEvent(usToCycles(100), adhocSocketNotifyEvent, param); - __KernelWaitCurThread(WAITTYPE_NET, socketId, 0, 0, false, reason); + CoreTiming::ScheduleEvent(usToCycles(100), adhocSocketNotifyEvent, threadSocketId); + __KernelWaitCurThread(WAITTYPE_NET, uid, 0, 0, false, reason); // Fallback return value return ERROR_NET_ADHOC_TIMEOUT; @@ -1114,15 +1115,16 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int if (sent == SOCKET_ERROR) { // Simulate blocking behaviour with non-blocking socket if (!flag && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT)) { - if (sendTargetPeers.find(socket->id) != sendTargetPeers.end()) { + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + if (sendTargetPeers.find(threadSocketId) != sendTargetPeers.end()) { DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Socket(%d) is Busy!", id, getLocalPort(socket->id), socket->id); return ERROR_NET_ADHOC_BUSY; } AdhocSendTargets dest = { len, {}, false }; dest.peers.push_back({ target.sin_addr.s_addr, dport }); - sendTargetPeers[socket->id] = dest; - return WaitBlockingAdhocSocket(socket->id, PDP_SEND, id, data, nullptr, timeout, nullptr, nullptr, "pdp send"); + sendTargetPeers[threadSocketId] = dest; + return WaitBlockingAdhocSocket(threadSocketId, PDP_SEND, id, data, nullptr, timeout, nullptr, nullptr, "pdp send"); } DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u] (size=%i)", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); @@ -1187,13 +1189,14 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Send Data // Simulate blocking behaviour with non-blocking socket if (!flag) { - if (sendTargetPeers.find(socket->id) != sendTargetPeers.end()) { + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + if (sendTargetPeers.find(threadSocketId) != sendTargetPeers.end()) { DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Socket(%d) is Busy!", id, getLocalPort(socket->id), socket->id); return ERROR_NET_ADHOC_BUSY; } - sendTargetPeers[socket->id] = dest; - return WaitBlockingAdhocSocket(socket->id, PDP_SEND, id, data, nullptr, timeout, nullptr, nullptr, "pdp send broadcast"); + sendTargetPeers[threadSocketId] = dest; + return WaitBlockingAdhocSocket(threadSocketId, PDP_SEND, id, data, nullptr, timeout, nullptr, nullptr, "pdp send broadcast"); } // Non-blocking else { @@ -1361,7 +1364,8 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * if (received == SOCKET_ERROR) { if (flag == 0) { // Simulate blocking behaviour with non-blocking socket - return WaitBlockingAdhocSocket(socket->id, PDP_RECV, id, buf, len, timeout, saddr, sport, "pdp recv"); + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + return WaitBlockingAdhocSocket(threadSocketId, PDP_RECV, id, buf, len, timeout, saddr, sport, "pdp recv"); } VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); @@ -1568,11 +1572,13 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb int affectedsockets = 0; if (nonblock) affectedsockets = PollAdhocSocket(sds, count, timeout); - else + else { // Simulate blocking behaviour with non-blocking socket // Borrowing some arguments to pass some parameters. The dummy WaitID(count+1) might not be unique thus have duplicate possibilities if there are multiple thread trying to poll the same numbers of socket at the same time - return WaitBlockingAdhocSocket(count+1, ADHOC_POLL_SOCKET, count, sds, nullptr, timeout, nullptr, nullptr, "adhoc pollsocket"); - + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | (count + 1); + return WaitBlockingAdhocSocket(threadSocketId, ADHOC_POLL_SOCKET, count, sds, nullptr, timeout, nullptr, nullptr, "adhoc pollsocket"); + } + // Free Network Lock //freeNetworkLock(); @@ -2819,7 +2825,8 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int if (newsocket == SOCKET_ERROR) { if (flag == 0) { // Simulate blocking behaviour with non-blocking socket - return WaitBlockingAdhocSocket(socket->id, PTP_ACCEPT, id, nullptr, nullptr, timeout, addr, port, "ptp accept"); + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + return WaitBlockingAdhocSocket(threadSocketId, PTP_ACCEPT, id, nullptr, nullptr, timeout, addr, port, "ptp accept"); } // Prevent spamming Debug Log with retries of non-bocking socket else { @@ -2935,7 +2942,8 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Blocking Mode else { // Simulate blocking behaviour with non-blocking socket - return WaitBlockingAdhocSocket(socket->id, PTP_CONNECT, id, nullptr, nullptr, timeout, nullptr, nullptr, "ptp connect"); + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + return WaitBlockingAdhocSocket(threadSocketId, PTP_CONNECT, id, nullptr, nullptr, timeout, nullptr, nullptr, "ptp connect"); } } } @@ -3240,7 +3248,8 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou return ERROR_NET_ADHOC_WOULD_BLOCK; // Simulate blocking behaviour with non-blocking socket - return WaitBlockingAdhocSocket(socket->id, PTP_SEND, id, (void*)data, len, timeout, nullptr, nullptr, "ptp send"); + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + return WaitBlockingAdhocSocket(threadSocketId, PTP_SEND, id, (void*)data, len, timeout, nullptr, nullptr, "ptp send"); } // Change Socket State @@ -3312,7 +3321,8 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou if (received == SOCKET_ERROR) { if (flag == 0) { // Simulate blocking behaviour with non-blocking socket - return WaitBlockingAdhocSocket(socket->id, PTP_RECV, id, buf, len, timeout, nullptr, nullptr, "ptp recv"); + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + return WaitBlockingAdhocSocket(threadSocketId, PTP_RECV, id, buf, len, timeout, nullptr, nullptr, "ptp recv"); } VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPtpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); From 57584343a2e53a349ff2d945eddc0011dd23cea3 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 8 Sep 2020 19:16:44 +0700 Subject: [PATCH 657/848] Simulate blocking PtpFlush --- Core/HLE/sceNetAdhoc.cpp | 85 ++++++++++++++++++++++++++++++++++------ Core/HLE/sceNetAdhoc.h | 7 ++-- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 568a3bf36e..f59877f2df 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -95,6 +95,7 @@ int matchingEventThread(int matchingId); int matchingInputThread(int matchingId); int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port); int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout); +int FlushPtpSocket(int socketId); void __NetAdhocShutdown() { @@ -513,6 +514,40 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { return 0; } +int DoBlockingPtpFlush(int uid, AdhocSocketRequest& req, s64& result) { + auto ptpsocket = ptp[req.id - 1]; + + // Try Sending Empty Data + //int ret = send(uid, (const char*)req.buffer, *req.length, MSG_NOSIGNAL); + int sockerr = FlushPtpSocket(uid); + + if (sockerr >= 0) { + result = 0; + return 0; + } + else if (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT) { + u64 now = (u64)(real_time_now() * 1000000.0); + if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTFLUSH)) { + result = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + ptpsocket->flags &= ~ADHOC_F_ALERTFLUSH; + } + else if (req.timeout == 0 || now - req.startTime <= req.timeout) { + return -1; + } + else + result = ERROR_NET_ADHOC_TIMEOUT; + } + + // Change Socket State. // FIXME: Does Alerted Socket should be closed too? + ptpsocket->state = ADHOC_PTP_STATE_CLOSED; + + // Disconnected + result = ERROR_NET_ADHOC_DISCONNECTED; + + return 0; +} + int DoBlockingAdhocPollSocket(int uid, AdhocSocketRequest& req, s64& result) { SceNetAdhocPollSd* sds = (SceNetAdhocPollSd*)req.buffer; int ret = PollAdhocSocket(sds, req.id, 0); @@ -609,6 +644,14 @@ static void __AdhocSocketNotify(u64 userdata, int cyclesLate) { } break; + case PTP_FLUSH: + if (DoBlockingPtpFlush(uid, req, result)) { + // Try again in another 0.5ms until data available or timedout. + CoreTiming::ScheduleEvent(usToCycles(delayUS) - cyclesLate, adhocSocketNotifyEvent, userdata); + return; + } + break; + case ADHOC_POLL_SOCKET: if (DoBlockingAdhocPollSocket(uid, req, result)) { // Try again in another 0.5ms until data available or timedout. @@ -3377,6 +3420,25 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou return ERROR_NET_ADHOC_NOT_INITIALIZED; } +int FlushPtpSocket(int socketId) { + // Get original Nagle algo value + int n = getSockNoDelay(socketId); + + // Disable Nagle Algo to send immediately + setSockNoDelay(socketId, 1); + + // Send Empty Data just to trigger Nagle on/off effect to flush the send buffer, Do we need to trigger this at all or is it automatically flushed? + //changeBlockingMode(socket->id, nonblock); + int ret = send(socketId, nullptr, 0, MSG_NOSIGNAL); + if (ret == SOCKET_ERROR) ret = errno; + //changeBlockingMode(socket->id, 1); + + // Restore/Enable Nagle Algo + setSockNoDelay(socketId, n); + + return ret; +} + /** * Adhoc Emulator PTP Flusher * @param id Socket File Descriptor @@ -3403,23 +3465,20 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { // Apply Send Timeout Settings to Socket setSockTimeout(socket->id, SO_SNDTIMEO, timeout); - // Get original Nagle algo value - int n = getSockNoDelay(socket->id); + int error = FlushPtpSocket(socket->id); - // Disable Nagle Algo to send immediately - setSockNoDelay(socket->id, 1); + if (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT) { + // Non-Blocking + if (nonblock) + return ERROR_NET_ADHOC_WOULD_BLOCK; - // Send Empty Data just to trigger Nagle on/off effect to flush the send buffer, Do we need to trigger this at all or is it automatically flushed? - //changeBlockingMode(socket->id, nonblock); - int sent = send(socket->id, 0, 0, MSG_NOSIGNAL); - int error = errno; - //changeBlockingMode(socket->id, 1); - - // Restore/Enable Nagle Algo - setSockNoDelay(socket->id, n); + // Simulate blocking behaviour with non-blocking socket + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + return WaitBlockingAdhocSocket(threadSocketId, PTP_FLUSH, id, nullptr, nullptr, timeout, nullptr, nullptr, "ptp flush"); + } } - // Dummy Result, Always success + // Dummy Result, Always success? return 0; } diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index 6a12e19c97..0ec9218bb5 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -63,9 +63,10 @@ enum AdhocSocketRequestType : int PTP_ACCEPT = 1, PTP_SEND = 2, PTP_RECV = 3, - PDP_SEND = 4, - PDP_RECV = 5, - ADHOC_POLL_SOCKET = 6, + PTP_FLUSH = 4, + PDP_SEND = 5, + PDP_RECV = 6, + ADHOC_POLL_SOCKET = 7, }; class PointerWrap; From 8c80a97807bde101d016deb0336c4a0d57623b52 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 25 Aug 2020 18:01:04 -0700 Subject: [PATCH 658/848] Module: Split out module start to use externally. --- Core/HLE/sceKernelModule.cpp | 150 +++++++++++++++++++++-------------- Core/HLE/sceKernelModule.h | 3 + 2 files changed, 92 insertions(+), 61 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 0b2b55ae74..47961a04e4 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1541,6 +1541,27 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load return module; } +SceUID KernelLoadModule(const std::string &filename, std::string *error_string) { + PSPFileInfo info = pspFileSystem.GetFileInfo(filename); + if (!info.exists) + return SCE_KERNEL_ERROR_NOFILE; + + std::vector buffer; + buffer.resize((size_t)info.size); + + u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ); + pspFileSystem.ReadFile(handle, &buffer[0], info.size); + pspFileSystem.CloseFile(handle); + + u32 error = SCE_KERNEL_ERROR_ILLEGAL_OBJECT; + u32 magic; + PSPModule *module = __KernelLoadELFFromPtr(&buffer[0], buffer.size(), 0, false, error_string, &magic, error); + + if (module == nullptr) + return error; + return module->GetUID(); +} + static PSPModule *__KernelLoadModule(u8 *fileptr, size_t fileSize, SceKernelLMOption *options, std::string *error_string) { PSPModule *module = nullptr; // Check for PBP @@ -1960,12 +1981,71 @@ static u32 sceKernelLoadModuleNpDrm(const char *name, u32 flags, u32 optionAddr) return sceKernelLoadModule(name, flags, optionAddr); } +int KernelStartModule(SceUID moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, SceKernelSMOption *smoption, bool *needsWait) { + if (needsWait) { + *needsWait = false; + } + + u32 error; + PSPModule *module = kernelObjects.Get(moduleId, error); + if (!module) { + return error; + } + + u32 priority = 0x20; + u32 stacksize = 0x40000; + int attribute = module->nm.attribute; + u32 entryAddr = module->nm.entry_addr; + + if (module->nm.module_start_func != 0 && module->nm.module_start_func != (u32)-1) { + entryAddr = module->nm.module_start_func; + if (module->nm.module_start_thread_attr != 0) + attribute = module->nm.module_start_thread_attr; + } else if (entryAddr == (u32)-1 || entryAddr == module->memoryBlockAddr - 1) { + if (smoption) { + // TODO: Does sceKernelStartModule() really give an error when no entry only if you pass options? + attribute = smoption->attribute; + } else { + // TODO: Why are we just returning the module ID in this case? + WARN_LOG(SCEMODULE, "sceKernelStartModule(): module has no start or entry func"); + module->nm.status = MODULE_STATUS_STARTED; + return moduleId; + } + } + + if (Memory::IsValidAddress(entryAddr)) { + if (smoption && smoption->priority > 0) { + priority = smoption->priority; + } else if (module->nm.module_start_thread_priority > 0) { + priority = module->nm.module_start_thread_priority; + } + + if (smoption && smoption->stacksize > 0) { + stacksize = smoption->stacksize; + } else if (module->nm.module_start_thread_stacksize > 0) { + stacksize = module->nm.module_start_thread_stacksize; + } + + 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); + + if (needsWait) { + *needsWait = true; + } + } else if (entryAddr == 0) { + INFO_LOG(SCEMODULE, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x): no entry address", moduleId, argsize, argAddr, returnValueAddr); + module->nm.status = MODULE_STATUS_STARTED; + } else { + ERROR_LOG(SCEMODULE, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x): invalid entry address", moduleId, argsize, argAddr, returnValueAddr); + return -1; + } + + return moduleId; +} + static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, u32 optionAddr) { - u32 priority = 0x20; - u32 stacksize = 0x40000; - u32 attr = 0; - int stackPartition = 0; SceKernelSMOption smoption = {0}; if (optionAddr) { Memory::ReadStruct(optionAddr, &smoption); @@ -1994,71 +2074,19 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret INFO_LOG(SCEMODULE, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x,%08x)", moduleId,argsize,argAddr,returnValueAddr,optionAddr); - int attribute = module->nm.attribute; - u32 entryAddr = module->nm.entry_addr; + bool needsWait; + int ret = KernelStartModule(moduleId, argsize, argAddr, returnValueAddr, optionAddr ? &smoption : nullptr, &needsWait); - if (module->nm.module_start_func != 0 && module->nm.module_start_func != (u32)-1) - { - entryAddr = module->nm.module_start_func; - if (module->nm.module_start_thread_attr != 0) - attribute = module->nm.module_start_thread_attr; - } - else if ((entryAddr == (u32)-1) || entryAddr == module->memoryBlockAddr - 1) - { - if (optionAddr) - { - // TODO: Does sceKernelStartModule() really give an error when no entry only if you pass options? - attribute = smoption.attribute; - } - else - { - // TODO: Why are we just returning the module ID in this case? - WARN_LOG(SCEMODULE, "sceKernelStartModule(): module has no start or entry func"); - module->nm.status = MODULE_STATUS_STARTED; - RETURN(moduleId); - return; - } - } - - if (Memory::IsValidAddress(entryAddr)) - { - if ((optionAddr) && smoption.priority > 0) { - priority = smoption.priority; - } else if (module->nm.module_start_thread_priority > 0) { - priority = module->nm.module_start_thread_priority; - } - - if ((optionAddr) && (smoption.stacksize > 0)) { - stacksize = smoption.stacksize; - } else if (module->nm.module_start_thread_stacksize > 0) { - stacksize = module->nm.module_start_thread_stacksize; - } - - 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); + if (needsWait) { __KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "started module"); const ModuleWaitingThread mwt = {__KernelGetCurThread(), returnValueAddr}; module->nm.status = MODULE_STATUS_STARTING; module->waitingThreads.push_back(mwt); } - else if (entryAddr == 0) - { - INFO_LOG(SCEMODULE, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x,%08x): no entry address", - moduleId,argsize,argAddr,returnValueAddr,optionAddr); - module->nm.status = MODULE_STATUS_STARTED; - } - else - { - ERROR_LOG(SCEMODULE, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x,%08x): invalid entry address", - moduleId,argsize,argAddr,returnValueAddr,optionAddr); - RETURN(-1); - return; - } - } - RETURN(moduleId); + RETURN(ret); + } } static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 returnValueAddr, u32 optionAddr) diff --git a/Core/HLE/sceKernelModule.h b/Core/HLE/sceKernelModule.h index 99e5473b05..a227153477 100644 --- a/Core/HLE/sceKernelModule.h +++ b/Core/HLE/sceKernelModule.h @@ -33,6 +33,7 @@ struct PspModuleInfo { }; class PointerWrap; +struct SceKernelSMOption; KernelObject *__KernelModuleObject(); void __KernelModuleDoState(PointerWrap &p); @@ -44,6 +45,8 @@ bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_str bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string); void __KernelGPUReplay(); void __KernelReturnFromModuleFunc(); +SceUID KernelLoadModule(const std::string &filename, std::string *error_string); +int KernelStartModule(SceUID moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, SceKernelSMOption *smoption, bool *needsWait); u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr, bool WithStatus); u32 sceKernelFindModuleByUID(u32 uid); From e383b0279f5d1eee86ce63f8c9e8483f7a182399 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 25 Aug 2020 19:54:51 -0700 Subject: [PATCH 659/848] Plugins: Support for loading game-specific plugins. --- CMakeLists.txt | 2 + Core/Config.cpp | 1 + Core/Config.h | 1 + Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 6 + Core/HLE/Plugins.cpp | 210 ++++++++++++++++++++++++++++ Core/HLE/Plugins.h | 34 +++++ Core/HLE/sceKernelModule.cpp | 6 + Core/Reporting.cpp | 3 +- Core/System.cpp | 5 + Core/System.h | 1 + UI/NativeApp.cpp | 2 + UWP/CoreUWP/CoreUWP.vcxproj | 2 + UWP/CoreUWP/CoreUWP.vcxproj.filters | 2 + android/jni/Android.mk | 1 + libretro/Makefile.common | 1 + 16 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 Core/HLE/Plugins.cpp create mode 100644 Core/HLE/Plugins.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ac7149764..e83e590f44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1565,6 +1565,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/HLE/KernelWaitHelpers.h Core/HLE/KUBridge.h Core/HLE/KUBridge.cpp + Core/HLE/Plugins.h + Core/HLE/Plugins.cpp Core/HLE/ThreadQueueList.h Core/HLE/__sceAudio.cpp Core/HLE/__sceAudio.h diff --git a/Core/Config.cpp b/Core/Config.cpp index 3164c9af9b..48e8750fd6 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -501,6 +501,7 @@ static ConfigSetting generalSettings[] = { ConfigSetting("FullscreenOnDoubleclick", &g_Config.bFullscreenOnDoubleclick, true, false, false), ReportedConfigSetting("MemStickInserted", &g_Config.bMemStickInserted, true, true, true), + ConfigSetting("LoadPlugins", &g_Config.bLoadPlugins, false, true, true), ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index 3072efdbc3..b8eb5399dd 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -123,6 +123,7 @@ public: std::string sRemoteISOSubdir; bool bRemoteDebuggerOnStartup; bool bMemStickInserted; + bool bLoadPlugins; int iScreenRotation; // The rotation angle of the PPSSPP UI. Only supported on Android and possibly other mobile platforms. int iInternalScreenRotation; // The internal screen rotation angle. Useful for vertical SHMUPs and similar. diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index d690042fb9..d7e7d3343e 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -384,6 +384,7 @@ + @@ -918,6 +919,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 1a63c8b4a2..53b8252fe3 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -758,6 +758,9 @@ HW + + HLE + @@ -1406,6 +1409,9 @@ Core + + HLE + diff --git a/Core/HLE/Plugins.cpp b/Core/HLE/Plugins.cpp new file mode 100644 index 0000000000..6b7f5e6734 --- /dev/null +++ b/Core/HLE/Plugins.cpp @@ -0,0 +1,210 @@ +// Copyright (c) 2020- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include +#include "file/file_util.h" +#include "file/ini_file.h" +#include "Common/FileUtil.h" +#include "Common/Serialize/SerializeFuncs.h" +#include "Core/Config.h" +#include "Core/MemMap.h" +#include "Core/System.h" +#include "Core/ELF/ParamSFO.h" +#include "Core/HLE/Plugins.h" +#include "Core/HLE/sceKernelModule.h" + +namespace HLEPlugins { + +static bool anyEnabled = false; +static std::vector prxPlugins; + +enum class PluginType { + INVALID = 0, + PRX, +}; + +struct PluginInfo { + PluginType type; + std::string filename; + int version; + int memory; +}; + +static PluginInfo ReadPluginIni(const std::string &subdir, IniFile &ini) { + PluginInfo info; + + auto options = ini.GetOrCreateSection("options"); + std::string value; + int ivalue; + + if (options->Get("type", &value, "")) { + if (value == "prx") { + info.type = PluginType::PRX; + } + } + + if (options->Get("filename", &value, "")) { + info.filename = "ms0:/PSP/PLUGINS/" + subdir + "/" + value; + } else { + info.type = PluginType::INVALID; + } + + options->Get("version", &info.version, 0); + options->Get("memory", &info.memory, 0); + if (info.memory > 93) { + ERROR_LOG(SYSTEM, "Plugin memory too high, using 93 MB"); + info.memory = 93; + } + + if (info.version == 0) { + ERROR_LOG(SYSTEM, "Plugin without version ignored: %s", subdir.c_str()); + info.type = PluginType::INVALID; + info.memory = 0; + } else if (info.type == PluginType::INVALID && !info.filename.empty()) { + ERROR_LOG(SYSTEM, "Plugin without valid type: %s", subdir.c_str()); + } + + return info; +} + +static std::vector FindPlugins(const std::string &gameID, const std::string &lang) { + std::vector pluginDirs; + getFilesInDir(GetSysDirectory(DIRECTORY_PLUGINS).c_str(), &pluginDirs); + + std::vector found; + for (auto subdir : pluginDirs) { + if (!subdir.isDirectory || !File::Exists(subdir.fullName + "/plugin.ini")) + continue; + + IniFile ini; + if (!ini.Load(subdir.fullName + "/plugin.ini")) { + ERROR_LOG(SYSTEM, "Failed to load plugin ini: %s/plugin.ini", subdir.fullName.c_str()); + continue; + } + + std::set matches; + + std::string gameIni; + if (ini.GetOrCreateSection("games")->Get("ALL", &gameIni, "")) { + if (!strcasecmp(gameIni.c_str(), "true")) { + matches.insert("plugin.ini"); + } else if (!gameIni.empty()) { + matches.insert(gameIni); + } + } + + if (ini.GetOrCreateSection("games")->Get(gameID.c_str(), &gameIni, "")) { + if (!strcasecmp(gameIni.c_str(), "true")) { + matches.insert("plugin.ini"); + } else if (!gameIni.empty()) { + matches.insert(gameIni); + } + } + + std::set langMatches; + for (const std::string &subini : matches) { + if (!ini.Load(subdir.fullName + "/" + subini)) { + ERROR_LOG(SYSTEM, "Failed to load plugin ini: %s/%s", subdir.fullName.c_str(), subini.c_str()); + continue; + } + + found.push_back(ReadPluginIni(subdir.name, ini)); + + if (ini.GetOrCreateSection("lang")->Get(lang.c_str(), &gameIni, "")) { + if (!gameIni.empty() && matches.find(gameIni) == matches.end()) { + langMatches.insert(gameIni); + } + } + } + + for (const std::string &subini : langMatches) { + if (!ini.Load(subdir.fullName + "/" + subini)) { + ERROR_LOG(SYSTEM, "Failed to load plugin ini: %s/%s", subdir.fullName.c_str(), subini.c_str()); + continue; + } + + found.push_back(ReadPluginIni(subdir.name, ini)); + } + } + + return found; +} + +void Init() { + if (!g_Config.bLoadPlugins) { + return; + } + + std::vector plugins = FindPlugins(g_paramSFO.GetDiscID(), g_Config.sLanguageIni); + for (auto &plugin : plugins) { + if (plugin.memory << 20 > Memory::g_MemorySize) { + Memory::g_MemorySize = plugin.memory << 20; + anyEnabled = true; + } + + if (plugin.type == PluginType::PRX) { + prxPlugins.push_back(plugin.filename); + anyEnabled = true; + } + } +} + +void Load() { + for (const std::string &filename : prxPlugins) { + std::string error_string = ""; + SceUID module = KernelLoadModule(filename, &error_string); + if (!error_string.empty()) { + ERROR_LOG(SYSTEM, "Unable to load plugin %s: %s", filename.c_str(), error_string.c_str()); + return; + } + if (module < 0) { + ERROR_LOG(SYSTEM, "Unable to load plugin %s: %08x", filename.c_str(), module); + return; + } + + int ret = KernelStartModule(module, 0, 0, 0, nullptr, nullptr); + if (ret < 0) { + ERROR_LOG(SYSTEM, "Unable to start plugin %s: %08x", filename.c_str(), ret); + } + + INFO_LOG(SYSTEM, "Loaded plugin: %s", filename.c_str()); + } +} + +void Unload() { + // Nothing to do here, for now. +} + +void Shutdown() { + prxPlugins.clear(); + anyEnabled = false; +} + +void DoState(PointerWrap &p) { + auto s = p.Section("Plugins", 0, 1); + if (!s) + return; + + // Remember if any were enabled. + Do(p, anyEnabled); +} + +bool HasEnabled() { + return anyEnabled; +} + +}; diff --git a/Core/HLE/Plugins.h b/Core/HLE/Plugins.h new file mode 100644 index 0000000000..8626fea9e8 --- /dev/null +++ b/Core/HLE/Plugins.h @@ -0,0 +1,34 @@ +// Copyright (c) 2020- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +class PointerWrap; + +namespace HLEPlugins { + +void Init(); +void Shutdown(); + +void Load(); +void Unload(); + +void DoState(PointerWrap &p); + +bool HasEnabled(); + +}; diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 47961a04e4..4e67207967 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -32,6 +32,7 @@ #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/HLETables.h" +#include "Core/HLE/Plugins.h" #include "Core/HLE/ReplaceTables.h" #include "Core/Reporting.h" #include "Core/Host.h" @@ -331,6 +332,8 @@ public: } } + HLEPlugins::DoState(p); + RebuildImpExpModuleNames(); } @@ -529,6 +532,7 @@ void __KernelModuleShutdown() { loadedModules.clear(); MIPSAnalyst::Reset(); + HLEPlugins::Unload(); } // Sometimes there are multiple LO16's or HI16's per pair, even though the ABI says nothing of this. @@ -1621,6 +1625,8 @@ static void __KernelStartModule(PSPModule *m, int args, const char *argp, SceKer SceUID threadID = __KernelSetupRootThread(m->GetUID(), args, argp, options->priority, options->stacksize, options->attribute); __KernelSetThreadRA(threadID, NID_MODULERETURN); + + HLEPlugins::Load(); } diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 28c9609b01..1829fd8a97 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -34,6 +34,7 @@ #include "Core/System.h" #include "Core/FileSystems/BlockDevices.h" #include "Core/FileSystems/MetaFileSystem.h" +#include "Core/HLE/Plugins.h" #include "Core/HLE/sceDisplay.h" #include "Core/HLE/sceKernelMemory.h" #include "Core/ELF/ParamSFO.h" @@ -497,7 +498,7 @@ namespace Reporting bool IsSupported() { // Disabled when using certain hacks, because they make for poor reports. - if (CheatsInEffect()) + if (CheatsInEffect() || HLEPlugins::HasEnabled()) return false; if (g_Config.iLockedCPUSpeed != 0) return false; diff --git a/Core/System.cpp b/Core/System.cpp index b3b1e30756..ebf3eaaaa2 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -48,6 +48,7 @@ #include "Core/Host.h" #include "Core/System.h" #include "Core/HLE/HLE.h" +#include "Core/HLE/Plugins.h" #include "Core/HLE/ReplaceTables.h" #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelMemory.h" @@ -286,6 +287,7 @@ bool CPU_Init() { // likely to collide with any commercial ones. coreParameter.compat.Load(discID); + HLEPlugins::Init(); if (!Memory::Init()) { // We're screwed. return false; @@ -351,6 +353,7 @@ void CPU_Shutdown() { pspFileSystem.Shutdown(); mipsr4k.Shutdown(); Memory::Shutdown(); + HLEPlugins::Shutdown(); delete loadedFile; loadedFile = nullptr; @@ -592,6 +595,8 @@ std::string GetSysDirectory(PSPDirectories directoryType) { return g_Config.memStickDirectory + "PSP/SYSTEM/CACHE/"; case DIRECTORY_TEXTURES: return g_Config.memStickDirectory + "PSP/TEXTURES/"; + case DIRECTORY_PLUGINS: + return g_Config.memStickDirectory + "PSP/PLUGINS/"; case DIRECTORY_APP_CACHE: if (!g_Config.appCacheDirectory.empty()) { return g_Config.appCacheDirectory; diff --git a/Core/System.h b/Core/System.h index 0d21b0d1bb..fac6b16767 100644 --- a/Core/System.h +++ b/Core/System.h @@ -46,6 +46,7 @@ enum PSPDirectories { DIRECTORY_SAVESTATE, DIRECTORY_CACHE, DIRECTORY_TEXTURES, + DIRECTORY_PLUGINS, DIRECTORY_APP_CACHE, // Use the OS app cache if available DIRECTORY_VIDEO, DIRECTORY_AUDIO diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 0471116650..ffd0051677 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -361,6 +361,7 @@ void CreateDirectoriesAndroid() { File::CreateFullPath(GetSysDirectory(DIRECTORY_GAME)); File::CreateFullPath(GetSysDirectory(DIRECTORY_SYSTEM)); File::CreateFullPath(GetSysDirectory(DIRECTORY_TEXTURES)); + File::CreateFullPath(GetSysDirectory(DIRECTORY_PLUGINS)); // Avoid media scanners in PPSSPP_STATE and SAVEDATA directories, // and in the root PSP directory as well. @@ -368,6 +369,7 @@ void CreateDirectoriesAndroid() { File::CreateEmptyFile(GetSysDirectory(DIRECTORY_SAVEDATA) + ".nomedia"); File::CreateEmptyFile(GetSysDirectory(DIRECTORY_SYSTEM) + ".nomedia"); File::CreateEmptyFile(GetSysDirectory(DIRECTORY_TEXTURES) + ".nomedia"); + File::CreateEmptyFile(GetSysDirectory(DIRECTORY_PLUGINS) + ".nomedia"); } static void CheckFailedGPUBackends() { diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 31f2327547..7090fca695 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -561,6 +561,7 @@ + @@ -804,6 +805,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 6538bd1df1..1082a14160 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -89,6 +89,7 @@ + @@ -738,6 +739,7 @@ + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 36a29682f0..3e2c6367c0 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -346,6 +346,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/HLE/ReplaceTables.cpp \ $(SRC)/Core/HLE/HLE.cpp \ $(SRC)/Core/HLE/KUBridge.cpp \ + $(SRC)/Core/HLE/Plugins.cpp \ $(SRC)/Core/HLE/sceAdler.cpp \ $(SRC)/Core/HLE/sceAtrac.cpp \ $(SRC)/Core/HLE/__sceAudio.cpp.arm \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index d92fd54468..bf327b35a3 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -368,6 +368,7 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(COREDIR)/Font/PGF.cpp \ $(COREDIR)/HLE/HLE.cpp \ $(COREDIR)/HLE/KUBridge.cpp \ + $(COREDIR)/HLE/Plugins.cpp \ $(COREDIR)/HLE/sceSha256.cpp \ $(COREDIR)/HLE/sceG729.cpp \ $(COREDIR)/HLE/sceSfmt19937.cpp \ From 2f4945aad8a3024ed31426079d01571e8bd844e8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 26 Aug 2020 21:44:08 -0700 Subject: [PATCH 660/848] Plugins: Oops, typo. --- Core/HLE/Plugins.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/HLE/Plugins.cpp b/Core/HLE/Plugins.cpp index 6b7f5e6734..b3e01f4bde 100644 --- a/Core/HLE/Plugins.cpp +++ b/Core/HLE/Plugins.cpp @@ -49,7 +49,6 @@ static PluginInfo ReadPluginIni(const std::string &subdir, IniFile &ini) { auto options = ini.GetOrCreateSection("options"); std::string value; - int ivalue; if (options->Get("type", &value, "")) { if (value == "prx") { From ac7522b0ddd2a83d9865cbd9c41c6d9af35b2dfd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Aug 2020 01:05:02 -0700 Subject: [PATCH 661/848] Plugins: Schedule plugins before game thread. --- Core/HLE/Plugins.cpp | 12 ++++++++---- Core/HLE/Plugins.h | 2 +- Core/HLE/sceKernelModule.cpp | 5 ++++- Core/HLE/sceKernelThread.cpp | 22 ++++++++++++---------- Core/HLE/sceKernelThread.h | 1 + 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Core/HLE/Plugins.cpp b/Core/HLE/Plugins.cpp index b3e01f4bde..5f22e9fc37 100644 --- a/Core/HLE/Plugins.cpp +++ b/Core/HLE/Plugins.cpp @@ -41,7 +41,7 @@ struct PluginInfo { PluginType type; std::string filename; int version; - int memory; + uint32_t memory; }; static PluginInfo ReadPluginIni(const std::string &subdir, IniFile &ini) { @@ -162,17 +162,18 @@ void Init() { } } -void Load() { +bool Load() { + bool started = false; for (const std::string &filename : prxPlugins) { std::string error_string = ""; SceUID module = KernelLoadModule(filename, &error_string); if (!error_string.empty()) { ERROR_LOG(SYSTEM, "Unable to load plugin %s: %s", filename.c_str(), error_string.c_str()); - return; + continue; } if (module < 0) { ERROR_LOG(SYSTEM, "Unable to load plugin %s: %08x", filename.c_str(), module); - return; + continue; } int ret = KernelStartModule(module, 0, 0, 0, nullptr, nullptr); @@ -181,7 +182,10 @@ void Load() { } INFO_LOG(SYSTEM, "Loaded plugin: %s", filename.c_str()); + started = true; } + + return started; } void Unload() { diff --git a/Core/HLE/Plugins.h b/Core/HLE/Plugins.h index 8626fea9e8..6db2966d98 100644 --- a/Core/HLE/Plugins.h +++ b/Core/HLE/Plugins.h @@ -24,7 +24,7 @@ namespace HLEPlugins { void Init(); void Shutdown(); -void Load(); +bool Load(); void Unload(); void DoState(PointerWrap &p); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 4e67207967..e31e0f93e3 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1626,7 +1626,10 @@ static void __KernelStartModule(PSPModule *m, int args, const char *argp, SceKer SceUID threadID = __KernelSetupRootThread(m->GetUID(), args, argp, options->priority, options->stacksize, options->attribute); __KernelSetThreadRA(threadID, NID_MODULERETURN); - HLEPlugins::Load(); + if (HLEPlugins::Load()) { + KernelRotateThreadReadyQueue(0); + __KernelReSchedule("Started plugins"); + } } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index cade794e08..6bd3d2d434 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2246,10 +2246,7 @@ bool __KernelIsDispatchEnabled() return dispatchEnabled && __InterruptsEnabled(); } -int sceKernelRotateThreadReadyQueue(int priority) -{ - VERBOSE_LOG(SCEKERNEL, "sceKernelRotateThreadReadyQueue(%x)", priority); - +int KernelRotateThreadReadyQueue(int priority) { PSPThread *cur = __GetCurrentThread(); // 0 is special, it means "my current priority." @@ -2259,11 +2256,9 @@ int sceKernelRotateThreadReadyQueue(int priority) if (priority <= 0x07 || priority > 0x77) return SCE_KERNEL_ERROR_ILLEGAL_PRIORITY; - if (!threadReadyQueue.empty(priority)) - { + if (!threadReadyQueue.empty(priority)) { // In other words, yield to everyone else. - if (cur->nt.currentPriority == priority) - { + if (cur->nt.currentPriority == priority) { threadReadyQueue.push_back(priority, currentThread); cur->nt.status = (cur->nt.status & ~THREADSTATUS_RUNNING) | THREADSTATUS_READY; } @@ -2272,11 +2267,18 @@ int sceKernelRotateThreadReadyQueue(int priority) threadReadyQueue.rotate(priority); } - hleReSchedule("rotatethreadreadyqueue"); - hleEatCycles(250); return 0; } +int sceKernelRotateThreadReadyQueue(int priority) { + int result = KernelRotateThreadReadyQueue(priority); + if (result == 0) { + hleReSchedule("rotatethreadreadyqueue"); + hleEatCycles(250); + } + return hleLogSuccessVerboseI(SCEKERNEL, result); +} + int sceKernelDeleteThread(int threadID) { if (threadID == 0 || threadID == currentThread) { ERROR_LOG(SCEKERNEL, "sceKernelDeleteThread(%i): cannot delete current thread", threadID); diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index bb08bb3b66..65dce5ff54 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -57,6 +57,7 @@ u32 sceKernelReferThreadRunStatus(u32 uid, u32 statusPtr); int sceKernelReleaseWaitThread(SceUID threadID); int sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr); int sceKernelRotateThreadReadyQueue(int priority); +int KernelRotateThreadReadyQueue(int priority); int sceKernelCheckThreadStack(); int sceKernelSuspendThread(SceUID threadID); int sceKernelResumeThread(SceUID threadID); From cbeeb8fdf14e416c27b836d38c617ee0f2f819e6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 8 Sep 2020 15:52:01 -0700 Subject: [PATCH 662/848] GPU: Allow culling in through mode. It works per tests and is used in Soul Caliber. Fixes #13400. --- GPU/Common/TextureCacheCommon.cpp | 2 +- GPU/D3D11/StateMappingD3D11.cpp | 7 +++---- GPU/Directx9/StateMappingDX9.cpp | 7 ++----- GPU/GLES/StateMappingGLES.cpp | 8 +------- GPU/Vulkan/StateMappingVulkan.cpp | 6 +++--- 5 files changed, 10 insertions(+), 20 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index d9405f468e..4df49bac7d 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -1853,7 +1853,7 @@ bool TextureCacheCommon::CheckFullHash(TexCacheEntry *entry, bool &doDelete) { return true; } } else { - // It wasn't found, so we're about to throw away entry and rebuild a texture. + // It wasn't found, so we're about to throw away the entry and rebuild a texture. // Let's save this in the secondary cache in case it gets used again. secondKey = entry->fullhash | ((u64)entry->cluthash << 32); secondCacheSizeEstimate_ += EstimateTexMemoryUsage(entry); diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index cb10fd96f2..5f8e0d4ae4 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -276,14 +276,13 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) { keys_.raster.value = 0; + bool wantCull = !gstate.isModeClear() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); + keys_.raster.cullMode = wantCull ? (gstate.getCullMode() ? D3D11_CULL_FRONT : D3D11_CULL_BACK) : D3D11_CULL_NONE; + if (gstate.isModeClear() || gstate.isModeThrough()) { - keys_.raster.cullMode = D3D11_CULL_NONE; // TODO: Might happen in clear mode if not through... keys_.raster.depthClipEnable = 1; } else { - // Set cull - bool wantCull = prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); - keys_.raster.cullMode = wantCull ? (gstate.getCullMode() ? D3D11_CULL_FRONT : D3D11_CULL_BACK) : D3D11_CULL_NONE; if (gstate.getDepthRangeMin() == 0 || gstate.getDepthRangeMax() == 65535) { // TODO: Still has a bug where we clamp to depth range if one is not the full range. // But the alternate is not clamping in either direction... diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index f1c5309853..e37c60eaef 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -202,15 +202,12 @@ void DrawEngineDX9::ApplyDrawState(int prim) { } else { dxstate.dither.disable(); } + bool wantCull = !gstate.isModeClear() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); + dxstate.cullMode.set(wantCull, gstate.getCullMode()); if (gstate.isModeClear()) { - // Set Cull - dxstate.cullMode.set(false, false); // Well, probably doesn't matter... dxstate.shadeMode.set(D3DSHADE_GOURAUD); } else { - // Set cull - bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); - dxstate.cullMode.set(wantCull, gstate.getCullMode()); dxstate.shadeMode.set(gstate.getShadeMode() == GE_SHADE_GOURAUD ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); } } diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index ce958e0403..73a1805a59 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -259,13 +259,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { bool cullEnable; GLenum cullMode = cullingMode[gstate.getCullMode() ^ !useBufferedRendering]; - if (gstate.isModeClear()) { - // Culling - cullEnable = false; - } else { - // Set cull - cullEnable = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); - } + cullEnable = !gstate.isModeClear() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); renderManager->SetRaster(cullEnable, GL_CCW, cullMode, dither); } diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 68f4bffefd..56980441dc 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -255,14 +255,14 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag } if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) { + bool wantCull = !gstate.isModeClear() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); + key.cullMode = wantCull ? (gstate.getCullMode() ? VK_CULL_MODE_FRONT_BIT : VK_CULL_MODE_BACK_BIT) : VK_CULL_MODE_NONE; + if (gstate.isModeClear() || gstate.isModeThrough()) { - key.cullMode = VK_CULL_MODE_NONE; // TODO: Might happen in clear mode if not through... key.depthClampEnable = false; } else { // Set cull - bool wantCull = prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled(); - key.cullMode = wantCull ? (gstate.getCullMode() ? VK_CULL_MODE_FRONT_BIT : VK_CULL_MODE_BACK_BIT) : VK_CULL_MODE_NONE; if (gstate.getDepthRangeMin() == 0 || gstate.getDepthRangeMax() == 65535) { // TODO: Still has a bug where we clamp to depth range if one is not the full range. // But the alternate is not clamping in either direction... From c1ce8383aeadaa489afa9d61a67e03b76882a3f0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 8 Sep 2020 15:52:39 -0700 Subject: [PATCH 663/848] Headless: Setup logman earlier. So we can control all the GPU init logging. --- headless/Headless.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 7f5e5fdcf4..284f709c02 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -328,14 +328,6 @@ int main(int argc, const char* argv[]) if (testFilenames.empty()) return printUsage(argv[0], argc <= 1 ? NULL : "No executables specified"); - HeadlessHost *headlessHost = getHost(gpuCore); - headlessHost->SetGraphicsCore(gpuCore); - host = headlessHost; - - std::string error_string; - GraphicsContext *graphicsContext = nullptr; - bool glWorking = host->InitGraphics(&error_string, &graphicsContext); - LogManager::Init(&g_Config.bEnableLogging); LogManager *logman = LogManager::GetInstance(); @@ -348,6 +340,14 @@ int main(int argc, const char* argv[]) } logman->AddListener(printfLogger); + HeadlessHost *headlessHost = getHost(gpuCore); + headlessHost->SetGraphicsCore(gpuCore); + host = headlessHost; + + std::string error_string; + GraphicsContext *graphicsContext = nullptr; + bool glWorking = host->InitGraphics(&error_string, &graphicsContext); + CoreParameter coreParameter; coreParameter.cpuCore = cpuCore; coreParameter.gpuCore = glWorking ? gpuCore : GPUCORE_NULL; From 5fae2171cc72f22dfb91a11fc98f05f5b5b79eb4 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 8 Sep 2020 16:16:41 -0700 Subject: [PATCH 664/848] softgpu: Correct cull handling for sprites. --- GPU/Software/Clipper.cpp | 2 +- GPU/Software/RasterizerRectangle.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/GPU/Software/Clipper.cpp b/GPU/Software/Clipper.cpp index 86142582b9..b462bd5977 100644 --- a/GPU/Software/Clipper.cpp +++ b/GPU/Software/Clipper.cpp @@ -206,7 +206,7 @@ void ProcessRect(const VertexData& v0, const VertexData& v1) VertexData* bottomleft = &buf[2]; VertexData* bottomright = &buf[3]; - // Um. Why is this stuff needed? + // DrawTriangle always culls, so sort out the drawing order. for (int i = 0; i < 4; ++i) { if (buf[i].screenpos.x < topleft->screenpos.x && buf[i].screenpos.y < topleft->screenpos.y) topleft = &buf[i]; diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index b6697b52c7..db9c5bdcf9 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -237,8 +237,10 @@ bool RectangleFastPath(const VertexData &v0, const VertexData &v1) { bool coord_check = (xdiff == udiff || xdiff == -udiff) && (ydiff == vdiff || ydiff == -vdiff); + // Currently only works for TL/BR, which is the most common but not required. + bool orient_check = xdiff >= 0 && ydiff >= 0; bool state_check = !gstate.isModeClear(); // TODO: Add support for clear modes in Rasterizer::DrawSprite. - if ((coord_check || !gstate.isTextureMapEnabled()) && state_check) { + if ((coord_check || !gstate.isTextureMapEnabled()) && orient_check && state_check) { Rasterizer::DrawSprite(v0, v1); return true; } From 97e5a1f4470fa35a2d40225ce12ce87e5a567d66 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 9 Sep 2020 13:33:37 +0700 Subject: [PATCH 665/848] Combining PDP and PTP socket's array into a union array. Fixes Hot Shots Tennis that doesn't works well with socketId > 255 --- Core/HLE/proAdhoc.cpp | 71 ++-- Core/HLE/proAdhoc.h | 62 ++-- Core/HLE/sceNet.cpp | 10 +- Core/HLE/sceNetAdhoc.cpp | 701 ++++++++++++++++++++------------------- 4 files changed, 424 insertions(+), 420 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index c7d2b78431..0575631668 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -76,10 +76,7 @@ SceNetAdhocctlParameter parameter; SceNetAdhocctlAdhocId product_code; std::thread friendFinderThread; std::recursive_mutex peerlock; -SceNetAdhocPdpStatInternal * pdp[MAX_SOCKET]; -SceNetAdhocPtpStatInternal * ptp[MAX_SOCKET]; -const int PdpIdStart = MAX_SOCKET + 1; -const int PdpIdEnd = PdpIdStart + MAX_SOCKET; +AdhocSocket* adhocSockets[MAX_SOCKET]; std::map ptpConnectCount; std::vector chatLog; std::string name = ""; @@ -108,16 +105,24 @@ bool isLocalMAC(const SceNetEtherAddr * addr) { bool isPDPPortInUse(uint16_t port) { // Iterate Elements - for (int i = 0; i < MAX_SOCKET; i++) if (pdp[i] != NULL && pdp[i]->lport == port) return true; - + for (int i = 0; i < MAX_SOCKET; i++) { + auto sock = adhocSockets[i]; + if (sock != NULL && sock->type == SOCK_PDP) + if (sock->data.pdp.lport == port) + return true; + } // Unused Port return false; } bool isPTPPortInUse(uint16_t port) { // Iterate Sockets - for(int i = 0; i < MAX_SOCKET; i++) if(ptp[i] != NULL && ptp[i]->lport == port) return true; - + for (int i = 0; i < MAX_SOCKET; i++) { + auto sock = adhocSockets[i]; + if (sock != NULL && sock->type == SOCK_PTP) + if (sock->data.ptp.lport == port) + return true; + } // Unused Port return false; } @@ -323,37 +328,29 @@ void freeGroupsRecursive(SceNetAdhocctlScanInfo * node) { node = NULL; } -void deleteAllPDP() { +void deleteAllAdhocSockets() { // Iterate Element - for (int i = 0; i < 255; i++) { + for (int i = 0; i < MAX_SOCKET; i++) { // Active Socket - if (pdp[i] != NULL) { - // Close Socket - closesocket(pdp[i]->id); + if (adhocSockets[i] != NULL) { + auto sock = adhocSockets[i]; + int fd = -1; + if (sock->type == SOCK_PTP) + fd = sock->data.ptp.id; + else if (sock->type == SOCK_PDP) + fd = sock->data.pdp.id; + + if (fd > 0) { + // Close Socket + shutdown(fd, SD_BOTH); + closesocket(fd); + } // Free Memory - free(pdp[i]); + free(adhocSockets[i]); // Delete Reference - pdp[i] = NULL; - } - } -} - -void deleteAllPTP() { - // Iterate Element - for (int i = 0; i < 255; i++) { - // Active Socket - if (ptp[i] != NULL) { - // Close Socket - closesocket(ptp[i]->id); - - // Free Memory - free(ptp[i]); - - // Delete Reference - ptp[i] = NULL; - ptpConnectCount.erase(i); + adhocSockets[i] = NULL; } } } @@ -1879,7 +1876,9 @@ int getPDPSocketCount() int counter = 0; // Count Sockets - for (int i = 0; i < MAX_SOCKET; i++) if (pdp[i] != NULL) counter++; + for (int i = 0; i < MAX_SOCKET; i++) + if (adhocSockets[i] != NULL && adhocSockets[i]->type == SOCK_PDP) + counter++; // Return Socket Count return counter; @@ -1890,7 +1889,9 @@ int getPTPSocketCount() { int counter = 0; // Count Sockets - for (int i = 0; i < MAX_SOCKET; i++) if (ptp[i] != NULL) counter++; + for (int i = 0; i < MAX_SOCKET; i++) + if (adhocSockets[i] != NULL && adhocSockets[i]->type == SOCK_PTP) + counter++; // Return Socket Count return counter; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 73b26a9acc..149bae4c7a 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -302,43 +302,17 @@ typedef struct SceNetAdhocPollSd{ s32_le revents; } PACK SceNetAdhocPollSd; -// PDP Socket Status (Internal use only) -typedef struct SceNetAdhocPdpStatInternal{ - u32_le next; // struct SceNetAdhocPdpStat * next; - s32_le id; - SceNetEtherAddr laddr; - u16_le lport; - u32_le rcv_sb_cc; - - s32_le flags; // Socket Alert Flags -} PACK SceNetAdhocPdpStatInternal; - // PDP Socket Status -typedef struct SceNetAdhocPdpStatEmu { +typedef struct SceNetAdhocPdpStat { u32_le next; s32_le id; SceNetEtherAddr laddr; u16_le lport; u32_le rcv_sb_cc; -} PACK SceNetAdhocPdpStatEmu; - -// PTP Socket Status (Internal use only) -typedef struct SceNetAdhocPtpStatInternal { - u32_le next; // struct SceNetAdhocPtpStat * next; - s32_le id; - SceNetEtherAddr laddr; - SceNetEtherAddr paddr; - u16_le lport; - u16_le pport; - s32_le snd_sb_cc; - s32_le rcv_sb_cc; - s32_le state; - - s32_le flags; // Socket Alert Flags -} PACK SceNetAdhocPtpStatInternal; +} PACK SceNetAdhocPdpStat; // PTP Socket Status -typedef struct SceNetAdhocPtpStatEmu { +typedef struct SceNetAdhocPtpStat { u32_le next; // Changed the pointer to u32 s32_le id; SceNetEtherAddr laddr; @@ -348,7 +322,17 @@ typedef struct SceNetAdhocPtpStatEmu { s32_le snd_sb_cc; s32_le rcv_sb_cc; s32_le state; -} PACK SceNetAdhocPtpStatEmu; +} PACK SceNetAdhocPtpStat; + +// PDP & PTP Socket Union (Internal use only) +typedef struct AdhocSocket { + s32_le type; + s32_le flags; // Socket Alert Flags + union { + SceNetAdhocPdpStat pdp; + SceNetAdhocPtpStat ptp; + } data; +} PACK AdhocSocket; // Gamemode Optional Peer Buffer Data typedef struct SceNetAdhocGameModeOptData { @@ -846,17 +830,16 @@ private: extern int actionAfterAdhocMipsCall; extern int actionAfterMatchingMipsCall; -#define MAX_SOCKET 255 +#define MAX_SOCKET 255 // FIXME: PSP might not allows more than 255 sockets? Hotshots Tennis doesn't seems to works with socketId > 255 +#define SOCK_PDP 1 +#define SOCK_PTP 2 // Aux vars extern int metasocket; extern SceNetAdhocctlParameter parameter; extern SceNetAdhocctlAdhocId product_code; extern std::thread friendFinderThread; extern std::recursive_mutex peerlock; -extern SceNetAdhocPdpStatInternal * pdp[MAX_SOCKET]; -extern SceNetAdhocPtpStatInternal * ptp[MAX_SOCKET]; -extern const int PdpIdStart; //256 -extern const int PdpIdEnd; //511 +extern AdhocSocket* adhocSockets[MAX_SOCKET]; extern std::map ptpConnectCount; union SockAddrIN4 { @@ -989,14 +972,9 @@ SceNetAdhocctlScanInfo * findGroup(SceNetEtherAddr * MAC); void freeGroupsRecursive(SceNetAdhocctlScanInfo * node); /** - * Closes & Deletes all PDP Sockets + * Closes & Deletes all PDP & PTP Sockets */ -void deleteAllPDP(); - -/** - * Closes & Deletes all PTP sockets - */ -void deleteAllPTP(); +void deleteAllAdhocSockets(); /** * Delete Friend from Local List diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 99ef0cbba0..98dcc52c92 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -503,11 +503,8 @@ u32 Net_Term() { // Library is initialized if (netInited) { - // Delete PDP Sockets - deleteAllPDP(); - - // Delete PTP Sockets - deleteAllPTP(); + // Delete Adhoc Sockets + deleteAllAdhocSockets(); // Delete GameMode Buffer //deleteAllGMB(); @@ -587,8 +584,7 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini netMallocStat.free = poolSize - netMallocStat.maximum; // Clear Socket Translator Memory - memset(&pdp, 0, sizeof(pdp)); - memset(&ptp, 0, sizeof(ptp)); + memset(&adhocSockets, 0, sizeof(adhocSockets)); ptpConnectCount.clear(); return hleLogSuccessI(SCENET, 0); diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index f59877f2df..d321d567cb 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -270,11 +270,11 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { // On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound yet), may need to disable SIO_UDP_CONNRESET error else if (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ECONNRESET || sockerr == ETIMEDOUT) { u64 now = (u64)(real_time_now() * 1000000.0); - auto pdpsocket = pdp[req.id - PdpIdStart]; - if (pdpsocket && (pdpsocket->flags & ADHOC_F_ALERTRECV)) { + auto sock = adhocSockets[req.id - 1]; + if (sock->flags & ADHOC_F_ALERTRECV) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? - pdpsocket->flags &= ~ADHOC_F_ALERTRECV; + sock->flags &= ~ADHOC_F_ALERTRECV; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { // Try again later @@ -293,7 +293,8 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTargets& targetPeers) { - auto pdpsocket = pdp[req.id - PdpIdStart]; + auto sock = adhocSockets[req.id - 1]; + auto& pdpsocket = sock->data.pdp; result = 0; bool retry = false; @@ -304,21 +305,21 @@ int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTa target.sin_addr.s_addr = peer->ip; target.sin_port = htons(peer->port + ((isOriPort && !isPrivateIP(peer->ip)) ? 0 : portOffset)); - int ret = sendto(pdpsocket->id, (const char*)req.buffer, targetPeers.length, MSG_NOSIGNAL, (sockaddr*)&target, sizeof(target)); + int ret = sendto(pdpsocket.id, (const char*)req.buffer, targetPeers.length, MSG_NOSIGNAL, (sockaddr*)&target, sizeof(target)); int sockerr = errno; if (ret >= 0) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](B): Sent %u bytes to %s:%u\n", uid, getLocalPort(pdpsocket->id), ret, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](B): Sent %u bytes to %s:%u\n", uid, getLocalPort(pdpsocket.id), ret, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); // Remove successfully sent to peer to prevent sending the same data again during a retry peer = targetPeers.peers.erase(peer); } else { if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { u64 now = (u64)(real_time_now() * 1000000.0); - if (pdpsocket && (pdpsocket->flags & ADHOC_F_ALERTSEND)) { + if (sock->flags & ADHOC_F_ALERTSEND) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? - pdpsocket->flags &= ~ADHOC_F_ALERTSEND; + sock->flags &= ~ADHOC_F_ALERTSEND; break; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { @@ -332,7 +333,7 @@ int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTa } if (ret == SOCKET_ERROR) - DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](B) [size=%i]", sockerr, uid, getLocalPort(pdpsocket->id), ntohs(target.sin_port), targetPeers.length); + DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](B) [size=%i]", sockerr, uid, getLocalPort(pdpsocket.id), ntohs(target.sin_port), targetPeers.length); } if (retry) @@ -342,7 +343,8 @@ int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTa } int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { - auto ptpsocket = ptp[req.id - 1]; + auto sock = adhocSockets[req.id - 1]; + auto& ptpsocket = sock->data.ptp; // Send Data int ret = send(uid, (const char*)req.buffer, *req.length, MSG_NOSIGNAL); @@ -353,17 +355,17 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { // Save Length *req.length = ret; - DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u\n", req.id, ptpsocket->lport, ret, mac2str(&ptpsocket->paddr).c_str(), ptpsocket->pport); + DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u\n", req.id, ptpsocket.lport, ret, mac2str(&ptpsocket.paddr).c_str(), ptpsocket.pport); // Return Success result = 0; } else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { u64 now = (u64)(real_time_now() * 1000000.0); - if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTSEND)) { + if (sock->flags & ADHOC_F_ALERTSEND) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? - ptpsocket->flags &= ~ADHOC_F_ALERTSEND; + sock->flags &= ~ADHOC_F_ALERTSEND; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -373,7 +375,7 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { } // Change Socket State. // FIXME: Does Alerted Socket should be closed too? - ptpsocket->state = ADHOC_PTP_STATE_CLOSED; + ptpsocket.state = ADHOC_PTP_STATE_CLOSED; // Disconnected result = ERROR_NET_ADHOC_DISCONNECTED; @@ -385,20 +387,21 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { - auto ptpsocket = ptp[req.id - 1]; + auto sock = adhocSockets[req.id - 1]; + auto& ptpsocket = sock->data.ptp; int ret = recv(uid, (char*)req.buffer, *req.length, MSG_NOSIGNAL); int sockerr = errno; // Received Data if (ret > 0) { - DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u\n", req.id, ptpsocket->lport, ret, mac2str(&ptpsocket->paddr).c_str(), ptpsocket->pport); + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u\n", req.id, ptpsocket.lport, ret, mac2str(&ptpsocket.paddr).c_str(), ptpsocket.pport); // Save Length *req.length = ret; // Update last recv timestamp peerlock.lock(); - auto peer = findFriend(&ptpsocket->paddr); + auto peer = findFriend(&ptpsocket.paddr); if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); peerlock.unlock(); @@ -406,10 +409,10 @@ int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { } else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { u64 now = (u64)(real_time_now() * 1000000.0); - if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTRECV)) { + if (sock->flags & ADHOC_F_ALERTRECV) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? - ptpsocket->flags &= ~ADHOC_F_ALERTRECV; + sock->flags &= ~ADHOC_F_ALERTRECV; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -419,7 +422,7 @@ int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { } else { // Change Socket State. // FIXME: Does Alerted Socket should be closed too? - ptpsocket->state = ADHOC_PTP_STATE_CLOSED; + ptpsocket.state = ADHOC_PTP_STATE_CLOSED; // Disconnected result = ERROR_NET_ADHOC_DISCONNECTED; // ERROR_NET_ADHOC_INVALID_ARG @@ -432,7 +435,8 @@ int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { - auto ptpsocket = ptp[req.id - 1]; + auto sock = adhocSockets[req.id - 1]; + auto& ptpsocket = sock->data.ptp; sockaddr_in sin; memset(&sin, 0, sizeof(sin)); socklen_t sinlen = sizeof(sin); @@ -449,10 +453,10 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { } else if (ret == SOCKET_ERROR && connectInProgress(sockerr)) { u64 now = (u64)(real_time_now() * 1000000.0); - if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTACCEPT)) { + if (sock->flags & ADHOC_F_ALERTACCEPT) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? - ptpsocket->flags &= ~ADHOC_F_ALERTACCEPT; + sock->flags &= ~ADHOC_F_ALERTACCEPT; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -470,7 +474,8 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { - auto ptpsocket = ptp[req.id - 1]; + auto sock = adhocSockets[req.id - 1]; + auto& ptpsocket = sock->data.ptp; int sockerr; // Wait for Connection (assuming "connect" has been called before) @@ -484,9 +489,9 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { getpeername(uid, (sockaddr*)&sin, &sinlen); // Set Connected State - ptpsocket->state = ADHOC_PTP_STATE_ESTABLISHED; + ptpsocket.state = ADHOC_PTP_STATE_ESTABLISHED; - INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Established (%s:%u)", req.id, ptpsocket->lport, inet_ntoa(sin.sin_addr), ptpsocket->pport); + INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Established (%s:%u)", req.id, ptpsocket.lport, inet_ntoa(sin.sin_addr), ptpsocket.pport); // Success result = 0; @@ -494,10 +499,10 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { // Timeout else if (ret == 0) { u64 now = (u64)(real_time_now() * 1000000.0); - if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTCONNECT)) { + if (sock->flags & ADHOC_F_ALERTCONNECT) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? - ptpsocket->flags &= ~ADHOC_F_ALERTCONNECT; + sock->flags &= ~ADHOC_F_ALERTCONNECT; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -515,10 +520,10 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { } int DoBlockingPtpFlush(int uid, AdhocSocketRequest& req, s64& result) { - auto ptpsocket = ptp[req.id - 1]; + auto sock = adhocSockets[req.id - 1]; + auto& ptpsocket = sock->data.ptp; // Try Sending Empty Data - //int ret = send(uid, (const char*)req.buffer, *req.length, MSG_NOSIGNAL); int sockerr = FlushPtpSocket(uid); if (sockerr >= 0) { @@ -527,10 +532,10 @@ int DoBlockingPtpFlush(int uid, AdhocSocketRequest& req, s64& result) { } else if (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT) { u64 now = (u64)(real_time_now() * 1000000.0); - if (ptpsocket && (ptpsocket->flags & ADHOC_F_ALERTFLUSH)) { + if (sock->flags & ADHOC_F_ALERTFLUSH) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? - ptpsocket->flags &= ~ADHOC_F_ALERTFLUSH; + sock->flags &= ~ADHOC_F_ALERTFLUSH; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -540,7 +545,7 @@ int DoBlockingPtpFlush(int uid, AdhocSocketRequest& req, s64& result) { } // Change Socket State. // FIXME: Does Alerted Socket should be closed too? - ptpsocket->state = ADHOC_PTP_STATE_CLOSED; + ptpsocket.state = ADHOC_PTP_STATE_CLOSED; // Disconnected result = ERROR_NET_ADHOC_DISCONNECTED; @@ -985,27 +990,30 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u } // Allocate Memory for Internal Data - SceNetAdhocPdpStatInternal * internal = (SceNetAdhocPdpStatInternal *)malloc(sizeof(SceNetAdhocPdpStatInternal)); + AdhocSocket * internal = (AdhocSocket*)malloc(sizeof(AdhocSocket)); // Allocated Memory if (internal != NULL) { - // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPdpStatInternal)); - // Find Free Translator Index int i = 0; - for (; i < MAX_SOCKET; i++) if (pdp[i] == NULL) break; + for (; i < MAX_SOCKET; i++) if (adhocSockets[i] == NULL) break; // Found Free Translator Index if (i < MAX_SOCKET) { + // Clear Memory + memset(internal, 0, sizeof(AdhocSocket)); + + // Socket Type + internal->type = SOCK_PDP; + // Fill in Data - internal->id = usocket; - internal->laddr = *saddr; - internal->lport = port; //getLocalPort(usocket) - portOffset; - internal->rcv_sb_cc = bufferSize; + internal->data.pdp.id = usocket; + internal->data.pdp.laddr = *saddr; + internal->data.pdp.lport = port; //getLocalPort(usocket) - portOffset; + internal->data.pdp.rcv_sb_cc = bufferSize; // Link Socket to Translator ID - pdp[i] = internal; + adhocSockets[i] = internal; // Forward Port on Router //sceNetPortOpen("UDP", port); @@ -1015,7 +1023,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u changeBlockingMode(usocket, 1); // Success - return i + PdpIdStart; + return i + 1; } // Free Memory for Internal Data @@ -1118,9 +1126,10 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Valid Data Length if (len >= 0) { // should we allow 0 size packet (for ping) ? // Valid Socket ID - if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) { + if (id > 0 && id <= MAX_SOCKET && adhocSockets[id - 1] != NULL) { // Cast Socket - auto socket = pdp[id - PdpIdStart]; + auto socket = adhocSockets[id - 1]; + auto& pdpsocket = socket->data.pdp; // Valid Data Buffer if (data != NULL) { @@ -1132,9 +1141,9 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Apply Send Timeout Settings to Socket if (timeout > 0) - setSockTimeout(socket->id, SO_SNDTIMEO, timeout); + setSockTimeout(pdpsocket.id, SO_SNDTIMEO, timeout); - int maxlen = getSockMaxSize(socket->id); + int maxlen = getSockMaxSize(pdpsocket.id); // Single Target if (!isBroadcastMAC(daddr)) { @@ -1152,15 +1161,15 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int //_acquireNetworkLock(); // Send Data. UDP are guaranteed to be sent as a whole or nothing(failed if len > SO_MAX_MSG_SIZE), and never be partially sent/recv - int sent = sendto(socket->id, (const char *)data, len, MSG_NOSIGNAL, (sockaddr *)&target, sizeof(target)); + int sent = sendto(pdpsocket.id, (const char *)data, len, MSG_NOSIGNAL, (sockaddr *)&target, sizeof(target)); int error = errno; if (sent == SOCKET_ERROR) { // Simulate blocking behaviour with non-blocking socket if (!flag && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT)) { - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | pdpsocket.id; if (sendTargetPeers.find(threadSocketId) != sendTargetPeers.end()) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Socket(%d) is Busy!", id, getLocalPort(socket->id), socket->id); + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Socket(%d) is Busy!", id, getLocalPort(pdpsocket.id), pdpsocket.id); return ERROR_NET_ADHOC_BUSY; } @@ -1170,7 +1179,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int return WaitBlockingAdhocSocket(threadSocketId, PDP_SEND, id, data, nullptr, timeout, nullptr, nullptr, "pdp send"); } - DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u] (size=%i)", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); + DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u] (size=%i)", error, id, getLocalPort(pdpsocket.id), ntohs(target.sin_port), len); } //changeBlockingMode(socket->id, 0); @@ -1179,7 +1188,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Sent Data if (sent >= 0) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Sent %u bytes to %s:%u\n", id, getLocalPort(socket->id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Sent %u bytes to %s:%u\n", id, getLocalPort(pdpsocket.id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); // Success return 0; // sent; // MotorStorm will try to resend if return value is not 0 @@ -1192,7 +1201,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Does PDP can Timeout? There is no concept of Timeout when sending UDP due to no ACK, but might happen if the socket buffer is full, not sure about PDP since some games did use the timeout arg return ERROR_NET_ADHOC_TIMEOUT; // ERROR_NET_ADHOC_INVALID_ADDR; } - //VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Unknown Target Peer %s:%u\n", id, getLocalPort(socket->id), mac2str(daddr, tmpmac), ntohs(target.sin_port)); + //VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Unknown Target Peer %s:%u\n", id, getLocalPort(pdpsocket.id), mac2str(daddr, tmpmac), ntohs(target.sin_port)); } // Broadcast Target @@ -1232,9 +1241,9 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Send Data // Simulate blocking behaviour with non-blocking socket if (!flag) { - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | pdpsocket.id; if (sendTargetPeers.find(threadSocketId) != sendTargetPeers.end()) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Socket(%d) is Busy!", id, getLocalPort(socket->id), socket->id); + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Socket(%d) is Busy!", id, getLocalPort(pdpsocket.id), pdpsocket.id); return ERROR_NET_ADHOC_BUSY; } @@ -1251,14 +1260,14 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int target.sin_addr.s_addr = peer.ip; target.sin_port = htons(dport + ((isOriPort && !isPrivateIP(peer.ip)) ? 0 : portOffset)); - int sent = sendto(socket->id, (const char*)data, len, MSG_NOSIGNAL, (sockaddr*)&target, sizeof(target)); + int sent = sendto(pdpsocket.id, (const char*)data, len, MSG_NOSIGNAL, (sockaddr*)&target, sizeof(target)); int error = errno; if (sent == SOCKET_ERROR) { - DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](BC) [size=%i]", error, id, getLocalPort(socket->id), ntohs(target.sin_port), len); + DEBUG_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpSend[%i:%u->%u](BC) [size=%i]", error, id, getLocalPort(pdpsocket.id), ntohs(target.sin_port), len); } if (sent >= 0) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Sent %u bytes to %s:%u\n", id, getLocalPort(socket->id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); + DEBUG_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u](BC): Sent %u bytes to %s:%u\n", id, getLocalPort(pdpsocket.id), sent, inet_ntoa(target.sin_addr), ntohs(target.sin_port)); } } } @@ -1325,9 +1334,10 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * int * len = (int *)dataLength; if (netAdhocInited) { // Valid Socket ID - if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) { + if (id > 0 && id <= MAX_SOCKET && adhocSockets[id - 1] != NULL) { // Cast Socket - auto socket = pdp[id - PdpIdStart]; + auto socket = adhocSockets[id - 1]; + auto& pdpsocket = socket->data.pdp; // Valid Arguments if (saddr != NULL && port != NULL && buf != NULL && len != NULL && *len > 0) { @@ -1356,7 +1366,7 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Apply Receive Timeout Settings to Socket. Let's not wait forever (0 = indefinitely) if (timeout > 0) - setSockTimeout(socket->id, SO_RCVTIMEO, timeout); + setSockTimeout(pdpsocket.id, SO_RCVTIMEO, timeout); // Sender Address sockaddr_in sin; @@ -1372,12 +1382,11 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * int received = 0; int error = 0; - // Receive Data. PDP always sent in full size or nothing(failed), recvfrom will always receive in full size as requested (blocking) or failed (non-blocking). If available UDP data is larger than buffer, excess data is lost. // Should peek first for the available data size if it's more than len return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE along with required size in len to prevent losing excess data - received = recvfrom(socket->id, (char*)buf, *len, MSG_PEEK | MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); + received = recvfrom(pdpsocket.id, (char*)buf, *len, MSG_PEEK | MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); if (received != SOCKET_ERROR && *len < received) { - WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Peeked %u/%u bytes from %s:%u\n", id, getLocalPort(socket->id), received, *len, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Peeked %u/%u bytes from %s:%u\n", id, getLocalPort(pdpsocket.id), received, *len, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); *len = received; // Peer MAC @@ -1401,22 +1410,22 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE; //received; } - received = recvfrom(socket->id, (char*)buf, *len, MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); + received = recvfrom(pdpsocket.id, (char*)buf, *len, MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); error = errno; if (received == SOCKET_ERROR) { if (flag == 0) { // Simulate blocking behaviour with non-blocking socket - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | pdpsocket.id; return WaitBlockingAdhocSocket(threadSocketId, PDP_RECV, id, buf, len, timeout, saddr, sport, "pdp recv"); } - VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); + VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPdpRecv[%i:%u] [size=%i]", error, id, pdpsocket.lport, *len); } // Received Data. UDP can also receives 0 data, while on TCP 0 data = connection gracefully closed, but not sure about PDP tho if (received > 0) { - DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, getLocalPort(socket->id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, getLocalPort(pdpsocket.id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); // Peer MAC SceNetEtherAddr mac; @@ -1445,7 +1454,7 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Unknown Peer, let's not give any data else { //*len = 0; // received; // Is this going to be okay since saddr may not be valid? - WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %i bytes from Unknown Peer %s:%u", id, getLocalPort(socket->id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %i bytes from Unknown Peer %s:%u", id, getLocalPort(pdpsocket.id), received, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); } // Free Network Lock //_freeNetworkLock(); @@ -1489,17 +1498,15 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * return ERROR_NET_ADHOC_NOT_INITIALIZED; } -int NetAdhoc_SetSocketAlert(int id, int flag) { - // FIXME: Should we check for valid Alert Flags and/or Mask them? Should we return an error if we found an invalid flag? - int flg = flag & ADHOC_F_ALERTALL; - - if (id > 0 && id < MAX_SOCKET && ptp[id - 1] != NULL) - ptp[id - 1]->flags = flg; - else if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) - pdp[id - PdpIdStart]->flags = flg; - else +int NetAdhoc_SetSocketAlert(int id, s32_le flag) { + if (id < 1 || id > MAX_SOCKET || adhocSockets[id - 1] == NULL) return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + // FIXME: Should we check for valid Alert Flags and/or Mask them? Should we return an error if we found an invalid flag? + s32_le flg = flag & ADHOC_F_ALERTALL; + + adhocSockets[id - 1]->flags = flg; + return 0; } @@ -1516,24 +1523,28 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { int fd; int maxfd = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); - // TODO: PDP and PTP should share the same indexing to prevent identical PDP & PTP socket id + for (int i = 0; i < count; i++) { sds[i].revents = 0; // Fill in Socket ID - if (sds[i].id <= MAX_SOCKET && ptp[sds[i].id - 1] != NULL) { - fd = ptp[sds[i].id - 1]->id; - if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_LISTEN) sds[i].revents |= ADHOC_EV_ACCEPT; - else - if (ptp[sds[i].id - 1]->state == ADHOC_PTP_STATE_CLOSED) sds[i].revents |= ADHOC_EV_CONNECT; + if (sds[i].id > 0 && sds[i].id <= MAX_SOCKET && adhocSockets[sds[i].id - 1] != NULL) { + auto sock = adhocSockets[sds[i].id - 1]; + if (sock->type == SOCK_PTP) { + fd = sock->data.ptp.id; + if (sock->data.ptp.state == ADHOC_PTP_STATE_LISTEN) + sds[i].revents |= ADHOC_EV_ACCEPT; + else if (sock->data.ptp.state == ADHOC_PTP_STATE_CLOSED) + sds[i].revents |= ADHOC_EV_CONNECT; + } + else { + fd = sock->data.pdp.id; + } + if (fd > maxfd) maxfd = fd; + if (sds[i].events & ADHOC_EV_RECV) FD_SET(fd, &readfds); + if (sds[i].events & ADHOC_EV_SEND) FD_SET(fd, &writefds); // Does Data can always be sent regardless of events bitmask? + //if (sds[i].events & ADHOC_EV_ALERT) + FD_SET(fd, &exceptfds); // Does Alert can be raised on revents regardless of events bitmask? } - else { - fd = pdp[sds[i].id - PdpIdStart]->id; - } - if (fd > maxfd) maxfd = fd; - if (sds[i].events & ADHOC_EV_RECV) FD_SET(fd, &readfds); - if (sds[i].events & ADHOC_EV_SEND) FD_SET(fd, &writefds); // Does Data can always be sent regardless of events bitmask? - //if (sds[i].events & ADHOC_EV_ALERT) - FD_SET(fd, &exceptfds); // Does Alert can be raised on revents regardless of events bitmask? } timeval tmout; tmout.tv_sec = timeout / 1000000; // seconds @@ -1543,30 +1554,30 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { affectedsockets = 0; for (int i = 0; i < count; i++) { s32_le* fd_flags; - if (sds[i].id <= MAX_SOCKET && ptp[sds[i].id - 1] != NULL) { - auto sock = ptp[sds[i].id - 1]; - fd = sock->id; + if (sds[i].id > 0 && sds[i].id <= MAX_SOCKET && adhocSockets[sds[i].id - 1] != NULL) { + auto sock = adhocSockets[sds[i].id - 1]; fd_flags = &sock->flags; - } - else { - auto sock = pdp[sds[i].id - PdpIdStart]; - fd = sock->id; - fd_flags = &sock->flags; - } - if (FD_ISSET(fd, &readfds)) - sds[i].revents |= ADHOC_EV_RECV; - if (FD_ISSET(fd, &writefds)) - sds[i].revents |= ADHOC_EV_SEND; // Does Data can always be sent regardless of events bitmask? - sds[i].revents &= sds[i].events; - if (FD_ISSET(fd, &exceptfds)) - sds[i].revents |= ADHOC_EV_ALERT; // Does Alert can be raised on revents regardless of events bitmask? - if (sds[i].revents) affectedsockets++; + if (sock->type == SOCK_PTP) { + fd = sock->data.ptp.id; + } + else { + fd = sock->data.pdp.id; + } + if (FD_ISSET(fd, &readfds)) + sds[i].revents |= ADHOC_EV_RECV; + if (FD_ISSET(fd, &writefds)) + sds[i].revents |= ADHOC_EV_SEND; // Does Data can always be sent regardless of events bitmask? + sds[i].revents &= sds[i].events; + if (FD_ISSET(fd, &exceptfds)) + sds[i].revents |= ADHOC_EV_ALERT; // Does Alert can be raised on revents regardless of events bitmask? + if (sds[i].revents) affectedsockets++; - if (*fd_flags & ADHOC_F_ALERTPOLL) { - affectedsockets = ERROR_NET_ADHOC_SOCKET_ALERTED; - // FIXME: Should we clear the flag after alert signaled? - *fd_flags &= ~ADHOC_F_ALERTPOLL; - break; + if (*fd_flags & ADHOC_F_ALERTPOLL) { + affectedsockets = ERROR_NET_ADHOC_SOCKET_ALERTED; + // FIXME: Should we clear the flag after alert signaled? + *fd_flags &= ~ADHOC_F_ALERTPOLL; + break; + } } } } @@ -1587,10 +1598,9 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb if (sds != NULL && count > 0) { // Socket Check - for (int i = 0; i < count; i++) - { + for (int i = 0; i < count; i++) { // Invalid Socket - if (sds[i].id < 1 || sds[i].id >= PdpIdEnd || (pdp[sds[i].id - PdpIdStart] == NULL && ptp[sds[i].id - 1] == NULL)) + if (sds[i].id < 1 || sds[i].id > MAX_SOCKET || adhocSockets[sds[i].id - 1] == NULL) return hleLogDebug(SCENET, ERROR_NET_ADHOC_INVALID_SOCKET_ID, "invalid socket id"); } @@ -1618,7 +1628,7 @@ int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonb else { // Simulate blocking behaviour with non-blocking socket // Borrowing some arguments to pass some parameters. The dummy WaitID(count+1) might not be unique thus have duplicate possibilities if there are multiple thread trying to poll the same numbers of socket at the same time - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | (count + 1); + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | (count + 1ULL); return WaitBlockingAdhocSocket(threadSocketId, ADHOC_POLL_SOCKET, count, sds, nullptr, timeout, nullptr, nullptr, "adhoc pollsocket"); } @@ -1650,15 +1660,15 @@ int NetAdhocPdp_Delete(int id, int unknown) { // Library is initialized if (netAdhocInited) { // Valid Arguments - if (id >= PdpIdStart && id < PdpIdEnd) { + if (id > 0 && id <= MAX_SOCKET) { // Cast Socket - auto sock = pdp[id - PdpIdStart]; + auto sock = adhocSockets[id - 1]; // Valid Socket - if (sock != NULL) { + if (sock != NULL && sock->type == SOCK_PDP) { // Close Connection - shutdown(sock->id, SD_BOTH); - closesocket(sock->id); + shutdown(sock->data.pdp.id, SD_BOTH); + closesocket(sock->data.pdp.id); // Remove Port Forward from Router //sceNetPortClose("UDP", sock->lport); @@ -1668,7 +1678,7 @@ int NetAdhocPdp_Delete(int id, int unknown) { free(sock); // Free Translation Slot - pdp[id - PdpIdStart] = NULL; + adhocSockets[id - 1] = NULL; // Success return 0; @@ -2382,11 +2392,8 @@ int NetAdhoc_Term() { // Library is initialized if (netAdhocInited) { - // Delete PDP Sockets - deleteAllPDP(); - - // Delete PTP Sockets - deleteAllPTP(); + // Delete Adhoc Sockets + deleteAllAdhocSockets(); // Delete Gamemode Buffer //deleteAllGMB(); @@ -2424,8 +2431,8 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { { s32_le *buflen = NULL; if (Memory::IsValidAddress(structSize)) buflen = (s32_le *)Memory::GetPointer(structSize); - SceNetAdhocPdpStatEmu *buf = NULL; - if (Memory::IsValidAddress(structAddr)) buf = (SceNetAdhocPdpStatEmu *)Memory::GetPointer(structAddr); + SceNetAdhocPdpStat *buf = NULL; + if (Memory::IsValidAddress(structAddr)) buf = (SceNetAdhocPdpStat *)Memory::GetPointer(structAddr); // Socket Count int socketcount = getPDPSocketCount(); @@ -2434,7 +2441,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { if (buflen != NULL && buf == NULL) { // Return Required Size - *buflen = sizeof(SceNetAdhocPdpStatEmu) * socketcount; + *buflen = sizeof(SceNetAdhocPdpStat) * socketcount; // Success return 0; @@ -2444,7 +2451,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { else if (buflen != NULL && buf != NULL) { // Figure out how many Sockets we will return - int count = *buflen / sizeof(SceNetAdhocPdpStatEmu); + int count = *buflen / sizeof(SceNetAdhocPdpStat); if (count > socketcount) count = socketcount; // Copy Counter @@ -2454,20 +2461,20 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { for (int j = 0; j < MAX_SOCKET && i < count; j++) { // Valid Socket Entry - if (pdp[j] != NULL) - { + auto sock = adhocSockets[j]; + if (sock != NULL && sock->type == SOCK_PDP) { // Copy Socket Data from Internal Memory - memcpy(&buf[i], pdp[j], sizeof(SceNetAdhocPdpStatEmu)); + memcpy(&buf[i], &sock->data.pdp, sizeof(SceNetAdhocPdpStat)); // Fix Client View Socket ID - buf[i].id = j + PdpIdStart; + buf[i].id = j + 1; // Write End of List Reference buf[i].next = 0; // Link Previous Element if (i > 0) - buf[i - 1].next = structAddr + (i * sizeof(SceNetAdhocPdpStatEmu)); + buf[i - 1].next = structAddr + (i * sizeof(SceNetAdhocPdpStat)); // Increment Counter i++; @@ -2475,7 +2482,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { } // Update Buffer Length - *buflen = i * sizeof(SceNetAdhocPdpStatEmu); + *buflen = i * sizeof(SceNetAdhocPdpStat); // Success return 0; @@ -2502,8 +2509,8 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { s32_le *buflen = NULL; if (Memory::IsValidAddress(structSize)) buflen = (s32_le *)Memory::GetPointer(structSize); - SceNetAdhocPtpStatEmu *buf = NULL; - if (Memory::IsValidAddress(structAddr)) buf = (SceNetAdhocPtpStatEmu *)Memory::GetPointer(structAddr); + SceNetAdhocPtpStat *buf = NULL; + if (Memory::IsValidAddress(structAddr)) buf = (SceNetAdhocPtpStat *)Memory::GetPointer(structAddr); // Library is initialized if (netAdhocInited) { @@ -2513,7 +2520,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Length Returner Mode if (buflen != NULL && buf == NULL) { // Return Required Size - *buflen = sizeof(SceNetAdhocPtpStatEmu) * socketcount; + *buflen = sizeof(SceNetAdhocPtpStat) * socketcount; // Success return 0; @@ -2522,7 +2529,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Status Returner Mode else if (buflen != NULL && buf != NULL) { // Figure out how many Sockets we will return - int count = *buflen / sizeof(SceNetAdhocPtpStatEmu); + int count = *buflen / sizeof(SceNetAdhocPtpStat); if (count > socketcount) count = socketcount; // Copy Counter @@ -2530,10 +2537,11 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Iterate Sockets for (int j = 0; j < MAX_SOCKET && i < count; j++) { - // Active Socket - if (ptp[j] != NULL) { + // Valid Socket Entry + auto sock = adhocSockets[j]; + if ( sock != NULL && sock->type == SOCK_PTP) { // Copy Socket Data from internal Memory - memcpy(&buf[i], ptp[j], sizeof(SceNetAdhocPtpStatEmu)); + memcpy(&buf[i], &sock->data.ptp, sizeof(SceNetAdhocPtpStat)); // Fix Client View Socket ID buf[i].id = j + 1; @@ -2543,7 +2551,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Link previous Element to this one if (i > 0) - buf[i - 1].next = structAddr + (i * sizeof(SceNetAdhocPtpStatEmu)); + buf[i - 1].next = structAddr + (i * sizeof(SceNetAdhocPtpStat)); // Increment Counter i++; @@ -2551,7 +2559,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { } // Update Buffer Length - *buflen = i * sizeof(SceNetAdhocPtpStatEmu); + *buflen = i * sizeof(SceNetAdhocPtpStat); // Success return 0; @@ -2653,33 +2661,36 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, } // Allocate Memory - SceNetAdhocPtpStatInternal * internal = (SceNetAdhocPtpStatInternal *)malloc(sizeof(SceNetAdhocPtpStatInternal)); + AdhocSocket * internal = (AdhocSocket*)malloc(sizeof(AdhocSocket)); // Allocated Memory if (internal != NULL) { // Find Free Translator ID int i = 0; - for (; i < MAX_SOCKET; i++) if (ptp[i] == NULL) break; + for (; i < MAX_SOCKET; i++) if (adhocSockets[i] == NULL) break; // Found Free Translator ID if (i < MAX_SOCKET) { // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPtpStatInternal)); + memset(internal, 0, sizeof(AdhocSocket)); + // Socket Type + internal->type = SOCK_PTP; + // Copy Infrastructure Socket ID - internal->id = tcpsocket; + internal->data.ptp.id = tcpsocket; // Copy Address Information - internal->laddr = *saddr; - internal->paddr = *daddr; - internal->lport = sport; - internal->pport = dport; + internal->data.ptp.laddr = *saddr; + internal->data.ptp.paddr = *daddr; + internal->data.ptp.lport = sport; + internal->data.ptp.pport = dport; // Set Buffer Size - internal->rcv_sb_cc = bufsize; + internal->data.ptp.rcv_sb_cc = bufsize; // Link PTP Socket - ptp[i] = internal; + adhocSockets[i] = internal; ptpConnectCount[i] = 0; // Add Port Forward to Router. We may not even need to forward this local port, since PtpOpen usually have port 0 (any port) as source port and followed by PtpConnect (which mean acting as Client), right? @@ -2729,7 +2740,8 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port) { // Cast Socket - auto socket = ptp[ptpId - 1]; + auto socket = adhocSockets[ptpId - 1]; + auto& ptpsocket = socket->data.ptp; // Ignore SIGPIPE when supported (ie. BSD/MacOS) setSockNoSIGPIPE(newsocket, 1); @@ -2753,52 +2765,55 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther // Find Peer MAC if (resolveIP(peeraddr.sin_addr.s_addr, &mac)) { // Allocate Memory - SceNetAdhocPtpStatInternal* internal = (SceNetAdhocPtpStatInternal*)malloc(sizeof(SceNetAdhocPtpStatInternal)); + AdhocSocket* internal = (AdhocSocket*)malloc(sizeof(AdhocSocket)); // Allocated Memory if (internal != NULL) { // Find Free Translator ID int i = 0; - for (; i < MAX_SOCKET; i++) if (ptp[i] == NULL) break; + for (; i < MAX_SOCKET; i++) if (adhocSockets[i] == NULL) break; // Found Free Translator ID if (i < MAX_SOCKET) { // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPtpStatInternal)); + memset(internal, 0, sizeof(AdhocSocket)); + + // Socket Type + internal->type = SOCK_PTP; // Copy Socket Descriptor to Structure - internal->id = newsocket; + internal->data.ptp.id = newsocket; // Set Buffer Size - if (getSockBufferSize(newsocket, SO_RCVBUF) < socket->rcv_sb_cc) setSockBufferSize(newsocket, SO_RCVBUF, socket->rcv_sb_cc); - if (getSockBufferSize(newsocket, SO_SNDBUF) < socket->snd_sb_cc) setSockBufferSize(newsocket, SO_SNDBUF, socket->snd_sb_cc); - internal->rcv_sb_cc = socket->rcv_sb_cc; - internal->snd_sb_cc = socket->snd_sb_cc; + if (getSockBufferSize(newsocket, SO_RCVBUF) < ptpsocket.rcv_sb_cc) setSockBufferSize(newsocket, SO_RCVBUF, ptpsocket.rcv_sb_cc); + if (getSockBufferSize(newsocket, SO_SNDBUF) < ptpsocket.snd_sb_cc) setSockBufferSize(newsocket, SO_SNDBUF, ptpsocket.snd_sb_cc); + internal->data.ptp.rcv_sb_cc = ptpsocket.rcv_sb_cc; + internal->data.ptp.snd_sb_cc = ptpsocket.snd_sb_cc; // Copy Local Address Data to Structure - getLocalMac(&internal->laddr); - internal->lport = ntohs(local.sin_port) - portOffset; + getLocalMac(&internal->data.ptp.laddr); + internal->data.ptp.lport = ntohs(local.sin_port) - portOffset; // Copy Peer Address Data to Structure - internal->paddr = mac; - internal->pport = ntohs(peeraddr.sin_port) - portOffset; + internal->data.ptp.paddr = mac; + internal->data.ptp.pport = ntohs(peeraddr.sin_port) - portOffset; // Set Connected State - internal->state = ADHOC_PTP_STATE_ESTABLISHED; + internal->data.ptp.state = ADHOC_PTP_STATE_ESTABLISHED; // Return Peer Address Information - *addr = internal->paddr; - if (port != NULL) *port = internal->pport; + *addr = internal->data.ptp.paddr; + if (port != NULL) *port = internal->data.ptp.pport; // Link PTP Socket - ptp[i] = internal; + adhocSockets[i] = internal; ptpConnectCount[i] = 0; // Add Port Forward to Router. Or may be doesn't need to be forwarded since local port already accessible from outside if others were able to connect & get accepted at this point, right? //sceNetPortOpen("TCP", internal->lport); //g_PortManager.Add(IP_PROTOCOL_TCP, internal->lport + portOffset); - INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", ptpId, i + 1, internal->lport, inet_ntoa(peeraddr.sin_addr), internal->pport); + INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", ptpId, i + 1, internal->data.ptp.lport, inet_ntoa(peeraddr.sin_addr), internal->data.ptp.pport); // Return Socket return i + 1; @@ -2847,28 +2862,29 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Library is initialized if (netAdhocInited) { - // Valid Socket - if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { - // Cast Socket - auto socket = ptp[id - 1]; - - // Listener Socket - if (socket->state == ADHOC_PTP_STATE_LISTEN) { - // Valid Arguments - if (addr != NULL /*&& port != NULL*/) { //GTA:VCS seems to use 0 for the portPtr + // Valid Arguments + if (addr != NULL) { //GTA:VCS seems to use 0 for the portPtr + // Valid Socket + if (id > 0 && id <= MAX_SOCKET && adhocSockets[id - 1] != NULL) { + // Cast Socket + auto socket = adhocSockets[id - 1]; + auto& ptpsocket = socket->data.ptp; + + // Listener Socket + if (ptpsocket.state == ADHOC_PTP_STATE_LISTEN) { // Address Information sockaddr_in peeraddr; memset(&peeraddr, 0, sizeof(peeraddr)); socklen_t peeraddrlen = sizeof(peeraddr); - + // Accept Connection - int newsocket = accept(socket->id, (sockaddr *)&peeraddr, &peeraddrlen); + int newsocket = accept(ptpsocket.id, (sockaddr*)&peeraddr, &peeraddrlen); int error = errno; if (newsocket == SOCKET_ERROR) { - if (flag == 0) { + if (flag == 0) { // Simulate blocking behaviour with non-blocking socket - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; return WaitBlockingAdhocSocket(threadSocketId, PTP_ACCEPT, id, nullptr, nullptr, timeout, addr, port, "ptp accept"); } // Prevent spamming Debug Log with retries of non-bocking socket @@ -2876,31 +2892,32 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int VERBOSE_LOG(SCENET, "sceNetAdhocPtpAccept[%i]: Socket Error (%i)", id, error); } } - + // Accepted New Connection if (newsocket > 0) { int newid = AcceptPtpSocket(id, newsocket, peeraddr, addr, port); - if (newid >= 0) + if (newid >= 0) return newid; } - + // Action would block - if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; - + if (flag) + return ERROR_NET_ADHOC_WOULD_BLOCK; + // Timeout return ERROR_NET_ADHOC_TIMEOUT; } - - // Invalid Arguments - return ERROR_NET_ADHOC_INVALID_ARG; + + // Client Socket + return ERROR_NET_ADHOC_NOT_LISTENED; } - - // Client Socket - return ERROR_NET_ADHOC_NOT_LISTENED; + + // Invalid Socket + return ERROR_NET_ADHOC_INVALID_SOCKET_ID; } - - // Invalid Socket - return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + + // Invalid Arguments + return ERROR_NET_ADHOC_INVALID_ARG; } // Library is uninitialized @@ -2924,16 +2941,17 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { if (netAdhocInited) { // Valid Socket - if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { + if (id > 0 && id <= MAX_SOCKET && adhocSockets[id - 1] != NULL) { // Cast Socket - auto socket = ptp[id - 1]; + auto socket = adhocSockets[id - 1]; + auto& ptpsocket = socket->data.ptp; // Phantasy Star Portable 2 will try to reconnect even when previous connect already success, so we should return success too if it's already connected - if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) + if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED) return 0; // Valid Client Socket - if (socket->state == ADHOC_PTP_STATE_CLOSED) { + if (ptpsocket.state == ADHOC_PTP_STATE_CLOSED) { // Target Address sockaddr_in sin; memset(&sin, 0, sizeof(sin)); @@ -2941,12 +2959,12 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Setup Target Address // sin.sin_len = sizeof(sin); sin.sin_family = AF_INET; - sin.sin_port = htons(socket->pport + portOffset); + sin.sin_port = htons(ptpsocket.pport + portOffset); // Grab Peer IP - if (resolveMAC(&socket->paddr, (uint32_t *)&sin.sin_addr.s_addr)) { + if (resolveMAC(&ptpsocket.paddr, (uint32_t *)&sin.sin_addr.s_addr)) { // Some games (ie. PSP2) might try to talk to it's self, not sure if they talked through WAN or LAN when using public Adhoc Server tho - sin.sin_port = htons(socket->pport + ((isOriPort && !isPrivateIP(sin.sin_addr.s_addr)) ? 0 : portOffset)); + sin.sin_port = htons(ptpsocket.pport + ((isOriPort && !isPrivateIP(sin.sin_addr.s_addr)) ? 0 : portOffset)); // Grab Nonblocking Flag //uint32_t nbio = getNonBlockingFlag(socket->id); @@ -2954,22 +2972,22 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Connect Socket to Peer // NOTE: Based on what i read at stackoverflow, The First Non-blocking POSIX connect will always returns EAGAIN/EWOULDBLOCK because it returns without waiting for ACK/handshake, But GvG Next Plus is treating non-blocking PtpConnect just like blocking connect, May be on a real PSP the first non-blocking sceNetAdhocPtpConnect can be successfull? // TODO: Keep track number of Connect attempts so we can simulate blocking on first attempt (getNonBlockingFlag can't be used to get non-blocking flag on Windows thus can't be used to keep track) - int connectresult = connect(socket->id, (sockaddr *)&sin, sizeof(sin)); + int connectresult = connect(ptpsocket.id, (sockaddr *)&sin, sizeof(sin)); // Grab Error Code int errorcode = errno; if (connectresult == SOCKET_ERROR) { - ERROR_LOG(SCENET, "sceNetAdhocPtpConnect[%i]: Socket Error (%i) to %s:%u", id, errorcode, inet_ntoa(sin.sin_addr), socket->pport); + ERROR_LOG(SCENET, "sceNetAdhocPtpConnect[%i]: Socket Error (%i) to %s:%u", id, errorcode, inet_ntoa(sin.sin_addr), ptpsocket.pport); } // Instant Connection (Lucky!) if (connectresult != SOCKET_ERROR || errorcode == EISCONN) { ptpConnectCount[id - 1]++; // Set Connected State - socket->state = ADHOC_PTP_STATE_ESTABLISHED; + ptpsocket.state = ADHOC_PTP_STATE_ESTABLISHED; - INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Already Connected to %s:%u", id, socket->lport, inet_ntoa(sin.sin_addr), socket->pport); + INFO_LOG(SCENET, "sceNetAdhocPtpConnect[%i:%u]: Already Connected to %s:%u", id, ptpsocket.lport, inet_ntoa(sin.sin_addr), ptpsocket.pport); // Success return 0; } @@ -2985,7 +3003,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Blocking Mode else { // Simulate blocking behaviour with non-blocking socket - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; return WaitBlockingAdhocSocket(threadSocketId, PTP_CONNECT, id, nullptr, nullptr, timeout, nullptr, nullptr, "ptp connect"); } } @@ -2994,6 +3012,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Peer not found if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; + return ERROR_NET_ADHOC_CONNECTION_REFUSED; // ERROR_NET_ADHOC_TIMEOUT; } @@ -3012,32 +3031,37 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { int NetAdhocPtp_Close(int id, int unknown) { // Library is initialized if (netAdhocInited) { - // Valid Arguments & Atleast one Socket - if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { + // Valid Arguments + if (id > 0 && id <= MAX_SOCKET) { // Cast Socket - auto socket = ptp[id - 1]; + auto socket = adhocSockets[id - 1]; - // Close Connection - shutdown(socket->id, SD_BOTH); - closesocket(socket->id); + // Valid Socket + if (socket != NULL && socket->type == SOCK_PTP) { + // Close Connection + shutdown(socket->data.ptp.id, SD_BOTH); + closesocket(socket->data.ptp.id); - // Remove Port Forward from Router - //sceNetPortClose("TCP", socket->lport); - //g_PortManager.Remove(IP_PROTOCOL_TCP, isOriPort ? socket->lport : socket->lport + portOffset); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers + // Remove Port Forward from Router + //sceNetPortClose("TCP", socket->lport); + //g_PortManager.Remove(IP_PROTOCOL_TCP, isOriPort ? socket->lport : socket->lport + portOffset); // Let's not remove mapping in real-time as it could cause lags/disconnection when joining a room with slow routers - // Free Memory - free(socket); + // Free Memory + free(socket); - // Free Reference - ptp[id - 1] = NULL; - ptpConnectCount.erase(id - 1); + // Free Reference + adhocSockets[id - 1] = NULL; + ptpConnectCount.erase(id - 1); - // Success - return 0; + // Success + return 0; + } + + return ERROR_NET_ADHOC_INVALID_SOCKET_ID; } // Invalid Argument - return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + return ERROR_NET_ADHOC_INVALID_ARG; } // Library is uninitialized @@ -3146,34 +3170,37 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Switch into Listening Mode if ((iResult = listen(tcpsocket, backlog)) == 0) { // Allocate Memory - SceNetAdhocPtpStatInternal * internal = (SceNetAdhocPtpStatInternal *)malloc(sizeof(SceNetAdhocPtpStatInternal)); + AdhocSocket * internal = (AdhocSocket*)malloc(sizeof(AdhocSocket)); // Allocated Memory if (internal != NULL) { // Find Free Translator ID int i = 0; - for (; i < MAX_SOCKET; i++) if (ptp[i] == NULL) break; + for (; i < MAX_SOCKET; i++) if (adhocSockets[i] == NULL) break; // Found Free Translator ID if (i < MAX_SOCKET) { // Clear Memory - memset(internal, 0, sizeof(SceNetAdhocPtpStatInternal)); + memset(internal, 0, sizeof(AdhocSocket)); + // Socket Type + internal->type = SOCK_PTP; + // Copy Infrastructure Socket ID - internal->id = tcpsocket; + internal->data.ptp.id = tcpsocket; // Copy Address Information - internal->laddr = *saddr; - internal->lport = sport; + internal->data.ptp.laddr = *saddr; + internal->data.ptp.lport = sport; // Flag Socket as Listener - internal->state = ADHOC_PTP_STATE_LISTEN; + internal->data.ptp.state = ADHOC_PTP_STATE_LISTEN; // Set Buffer Size - internal->rcv_sb_cc = bufsize; + internal->data.ptp.rcv_sb_cc = bufsize; // Link PTP Socket - ptp[i] = internal; + adhocSockets[i] = internal; ptpConnectCount[i] = 0; // Add Port Forward to Router @@ -3248,12 +3275,13 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Library is initialized if (netAdhocInited) { // Valid Socket - if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { + if (id > 0 && id <= MAX_SOCKET && adhocSockets[id - 1] != NULL) { // Cast Socket - auto socket = ptp[id - 1]; + auto socket = adhocSockets[id - 1]; + auto& ptpsocket = socket->data.ptp; // Connected Socket - if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) { + if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED) { // Valid Arguments if (data != NULL && len != NULL && *len > 0) { // Schedule Timeout Removal @@ -3261,13 +3289,13 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Apply Send Timeout Settings to Socket if (timeout > 0) - setSockTimeout(socket->id, SO_SNDTIMEO, timeout); + setSockTimeout(ptpsocket.id, SO_SNDTIMEO, timeout); // Acquire Network Lock // _acquireNetworkLock(); // Send Data - int sent = send(socket->id, data, *len, MSG_NOSIGNAL); + int sent = send(ptpsocket.id, data, *len, MSG_NOSIGNAL); int error = errno; // Free Network Lock @@ -3278,7 +3306,7 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou // Save Length *len = sent; - DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u\n", id, socket->lport, sent, mac2str(&socket->paddr).c_str(), socket->pport); + DEBUG_LOG(SCENET, "sceNetAdhocPtpSend[%i:%u]: Sent %u bytes to %s:%u\n", id, ptpsocket.lport, sent, mac2str(&ptpsocket.paddr).c_str(), ptpsocket.pport); // Return Success return 0; @@ -3291,12 +3319,12 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou return ERROR_NET_ADHOC_WOULD_BLOCK; // Simulate blocking behaviour with non-blocking socket - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; return WaitBlockingAdhocSocket(threadSocketId, PTP_SEND, id, (void*)data, len, timeout, nullptr, nullptr, "ptp send"); } // Change Socket State - socket->state = ADHOC_PTP_STATE_CLOSED; + ptpsocket.state = ADHOC_PTP_STATE_CLOSED; // Disconnected return ERROR_NET_ADHOC_DISCONNECTED; @@ -3336,84 +3364,89 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou int * len = (int *)Memory::GetPointer(dataSizeAddr); // Library is initialized if (netAdhocInited) { - // Valid Socket - if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL && ptp[id - 1]->state == ADHOC_PTP_STATE_ESTABLISHED) { - // Cast Socket - auto socket = ptp[id - 1]; - - // Valid Arguments - if (buf != NULL && len != NULL && *len > 0) { - // Schedule Timeout Removal - //if (flag) timeout = 0; - - // Apply Receive Timeout Settings to Socket. Let's not wait forever (0 = indefinitely) - if (timeout > 0) - setSockTimeout(socket->id, SO_RCVTIMEO, timeout); - - // Acquire Network Lock - // _acquireNetworkLock(); - - // TODO: Use a different thread (similar to sceIo) for recvfrom, recv & accept to prevent blocking-socket from blocking emulation - int received = 0; - int error = 0; + // Valid Arguments + if (buf != NULL && len != NULL && *len > 0) { + // Valid Socket + if (id > 0 && id <= MAX_SOCKET && adhocSockets[id - 1] != NULL) { + // Cast Socket + auto socket = adhocSockets[id - 1]; + auto& ptpsocket = socket->data.ptp; - // Receive Data - received = recv(socket->id, (char*)buf, *len, MSG_NOSIGNAL); - error = errno; + if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED) { + // Schedule Timeout Removal + //if (flag) timeout = 0; - if (received == SOCKET_ERROR) { - if (flag == 0) { - // Simulate blocking behaviour with non-blocking socket - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; - return WaitBlockingAdhocSocket(threadSocketId, PTP_RECV, id, buf, len, timeout, nullptr, nullptr, "ptp recv"); + // Apply Receive Timeout Settings to Socket. Let's not wait forever (0 = indefinitely) + if (timeout > 0) + setSockTimeout(ptpsocket.id, SO_RCVTIMEO, timeout); + + // Acquire Network Lock + // _acquireNetworkLock(); + + // TODO: Use a different thread (similar to sceIo) for recvfrom, recv & accept to prevent blocking-socket from blocking emulation + int received = 0; + int error = 0; + + // Receive Data + received = recv(ptpsocket.id, (char*)buf, *len, MSG_NOSIGNAL); + error = errno; + + if (received == SOCKET_ERROR) { + if (flag == 0) { + // Simulate blocking behaviour with non-blocking socket + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; + return WaitBlockingAdhocSocket(threadSocketId, PTP_RECV, id, buf, len, timeout, nullptr, nullptr, "ptp recv"); + } + + VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPtpRecv[%i:%u] [size=%i]", error, id, ptpsocket.lport, *len); } - VERBOSE_LOG(SCENET, "Socket Error (%i) on sceNetAdhocPtpRecv[%i:%u] [size=%i]", error, id, socket->lport, *len); + // Free Network Lock + // _freeNetworkLock(); + + // Received Data + if (received > 0) { + // Save Length + *len = received; + + // Update last recv timestamp, may cause disconnection not detected properly tho + peerlock.lock(); + auto peer = findFriend(&ptpsocket.paddr); + if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + peerlock.unlock(); + + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, ptpsocket.lport, received, mac2str(&ptpsocket.paddr).c_str(), ptpsocket.pport); + + // Return Success + return 0; + } + + // Non-Critical Error + else if (received == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT)) { + // Blocking Situation + if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; + + // Timeout + return hleLogError(SCENET, ERROR_NET_ADHOC_TIMEOUT, "ptp recv timeout"); + } + DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Result:%i (Error:%i)", id, ptpsocket.lport, received, error); + + // Change Socket State + ptpsocket.state = ADHOC_PTP_STATE_CLOSED; + + // Disconnected + return hleLogError(SCENET, ERROR_NET_ADHOC_DISCONNECTED, "ptp recv disconnected"); } - - // Free Network Lock - // _freeNetworkLock(); - // Received Data - if (received > 0) { - // Save Length - *len = received; - - // Update last recv timestamp, may cause disconnection not detected properly tho - peerlock.lock(); - auto peer = findFriend(&socket->paddr); - if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); - peerlock.unlock(); - - DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, socket->lport, received, mac2str(&socket->paddr).c_str(), socket->pport); - - // Return Success - return 0; - } - - // Non-Critical Error - else if (received == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT)) { - // Blocking Situation - if (flag) return ERROR_NET_ADHOC_WOULD_BLOCK; - - // Timeout - return hleLogError(SCENET, ERROR_NET_ADHOC_TIMEOUT, "ptp recv timeout"); - } - DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Result:%i (Error:%i)", id, socket->lport, received, error); - - // Change Socket State - socket->state = ADHOC_PTP_STATE_CLOSED; - - // Disconnected - return hleLogError(SCENET, ERROR_NET_ADHOC_DISCONNECTED, "ptp recv disconnected"); + return ERROR_NET_ADHOC_NOT_CONNECTED; } - - // Invalid Arguments - return ERROR_NET_ADHOC_INVALID_ARG; + + // Invalid Socket + return ERROR_NET_ADHOC_INVALID_SOCKET_ID; } - - // Invalid Socket - return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + + // Invalid Arguments + return ERROR_NET_ADHOC_INVALID_ARG; } // Library is uninitialized @@ -3455,17 +3488,18 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { // Library initialized if (netAdhocInited) { // Valid Socket - if (id > 0 && id <= MAX_SOCKET && ptp[id - 1] != NULL) { + if (id > 0 && id <= MAX_SOCKET && adhocSockets[id - 1] != NULL) { // Cast Socket - auto socket = ptp[id - 1]; + auto socket = adhocSockets[id - 1]; + auto& ptpsocket = socket->data.ptp; // Connected Socket - if (socket->state == ADHOC_PTP_STATE_ESTABLISHED) { + if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED) { // There are two ways to flush, you can either set TCP_NODELAY to 1 or TCP_CORK to 0. // Apply Send Timeout Settings to Socket - setSockTimeout(socket->id, SO_SNDTIMEO, timeout); + setSockTimeout(ptpsocket.id, SO_SNDTIMEO, timeout); - int error = FlushPtpSocket(socket->id); + int error = FlushPtpSocket(ptpsocket.id); if (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT) { // Non-Blocking @@ -3473,7 +3507,7 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { return ERROR_NET_ADHOC_WOULD_BLOCK; // Simulate blocking behaviour with non-blocking socket - u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | socket->id; + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; return WaitBlockingAdhocSocket(threadSocketId, PTP_FLUSH, id, nullptr, nullptr, timeout, nullptr, nullptr, "ptp flush"); } } @@ -3521,18 +3555,13 @@ static int sceNetAdhocGameModeDeleteReplica(int id) { int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { WARN_LOG(SCENET, "UNTESTED sceNetAdhocGetSocketAlert(%i, %08x) at %08x", id, flagPtr, currentMIPS->pc); - s32_le flg = 0; - - if (id > 0 && id < MAX_SOCKET && ptp[id - 1] != NULL) - flg = ptp[id - 1]->flags; - else if (id >= PdpIdStart && id < PdpIdEnd && pdp[id - PdpIdStart] != NULL) - flg = pdp[id - PdpIdStart]->flags; - else - return ERROR_NET_ADHOC_INVALID_SOCKET_ID; - if (!Memory::IsValidAddress(flagPtr)) return ERROR_NET_ADHOC_INVALID_ARG; - + + if (id < 1 || id > MAX_SOCKET || adhocSockets[id - 1] == NULL) + return ERROR_NET_ADHOC_INVALID_SOCKET_ID; + + s32_le flg = adhocSockets[id - 1]->flags; Memory::Write_U32(flg, flagPtr); return 0; From 2affbb850c3d8f575de524b87c43598795567fe3 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 10 Sep 2020 00:58:52 +0700 Subject: [PATCH 666/848] Stop waiting for connection on Exit to Menu to prevent causing lags. --- Core/HLE/proAdhoc.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 0575631668..3860aa01b6 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1974,12 +1974,19 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ iResult = connect(metasocket, (sockaddr*)&server_addr, sizeof(server_addr)); errorcode = errno; - if (iResult == SOCKET_ERROR && errorcode != EISCONN && (IsSocketReady(metasocket, true, true, nullptr, adhocDefaultTimeout * 1000) <= 0)) { - char buffer[512]; - snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); - ERROR_LOG(SCENET, "%s", buffer); - host->NotifyUserMessage(n->T("Failed to connect to Adhoc Server"), 1.0f, 0x0000ff); - return iResult; + if (iResult == SOCKET_ERROR && errorcode != EISCONN) { + u64 startTime = (u64)(real_time_now() * 1000.0); + while (IsSocketReady(metasocket, true, true) <= 0) { + u64 now = (u64)(real_time_now() * 1000.0); + if (coreState == CORE_POWERDOWN) return iResult; + if (now - startTime > adhocDefaultTimeout) break; + sleep_ms(10); + } + if (IsSocketReady(metasocket, true, true) <= 0) { + ERROR_LOG(SCENET, "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); + host->NotifyUserMessage(n->T("Failed to connect to Adhoc Server"), 1.0f, 0x0000ff); + return iResult; + } } // Prepare Login Packet From 82a064adcfdae5e78afecd66d843f1831eb6977a Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 10 Sep 2020 11:22:39 +0700 Subject: [PATCH 667/848] Resolve Adhoc Server DNS early and cache it so we don't need to resolve it again later. --- Core/HLE/proAdhoc.cpp | 58 +++++++++++++++++++++---------------------- Core/HLE/proAdhoc.h | 1 + Core/HLE/sceNet.cpp | 5 ++++ 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 3860aa01b6..41f7fa0030 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -87,6 +87,7 @@ bool updateChatScreen = false; int newChat = 0; bool isOriPort = false; bool isLocalServer = false; +SockAddrIN4 g_adhocServerIP; SockAddrIN4 g_localhostIP; sockaddr LocalIP; int defaultWlanChannel = PSP_SYSTEMPARAM_ADHOC_CHANNEL_11; // Don't put 0(Auto) here, it needed to be a valid/actual channel number @@ -1254,6 +1255,26 @@ int friendFinder(){ // Log Startup INFO_LOG(SCENET, "FriendFinder: Begin of Friend Finder Thread"); + // Resolve and cache AdhocServer DNS + addrinfo* resolved = nullptr; + std::string err; + g_adhocServerIP.in.sin_addr.s_addr = INADDR_NONE; + if (!net::DNSResolve(g_Config.proAdhocServer, "", &resolved, err)) { + ERROR_LOG(SCENET, "DNS Error Resolving %s\n", g_Config.proAdhocServer.c_str()); + host->NotifyUserMessage(n->T("DNS Error Resolving ") + g_Config.proAdhocServer, 2.0f, 0x0000ff); + } + if (resolved) { + for (auto ptr = resolved; ptr != NULL; ptr = ptr->ai_next) { + switch (ptr->ai_family) { + case AF_INET: + g_adhocServerIP.in = *(sockaddr_in*)ptr->ai_addr; + break; + } + } + net::DNSResolveFree(resolved); + } + g_adhocServerIP.in.sin_port = htons(SERVER_PORT); + // Finder Loop while (friendFinderRunning) { // Acquire Network Lock @@ -1912,35 +1933,9 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ // Switch to Nonblocking Behaviour changeBlockingMode(metasocket, 1); - struct sockaddr_in server_addr; - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(SERVER_PORT); //27312 // Maybe read this from config too - - // Resolve dns - addrinfo * resultAddr; - addrinfo * ptr; - in_addr serverIp; - serverIp.s_addr = INADDR_NONE; - - iResult = getaddrinfo(g_Config.proAdhocServer.c_str(),0,NULL,&resultAddr); - if (iResult != 0) { - ERROR_LOG(SCENET, "DNS Error (%s)\n", g_Config.proAdhocServer.c_str()); - host->NotifyUserMessage(n->T("DNS Error connecting to ") + g_Config.proAdhocServer, 2.0f, 0x0000ff); - return iResult; - } - for (ptr = resultAddr; ptr != NULL; ptr = ptr->ai_next) { - switch (ptr->ai_family) { - case AF_INET: - serverIp = ((sockaddr_in *)ptr->ai_addr)->sin_addr; - break; - } - } - - freeaddrinfo(resultAddr); - // If Server is at localhost Try to Bind socket to specific adapter before connecting to prevent 2nd instance being recognized as already existing 127.0.0.1 by AdhocServer // (may not works in WinXP/2003 for IPv4 due to "Weak End System" model) - if (((uint8_t*)&serverIp.s_addr)[0] == 0x7f) { // (serverIp.S_un.S_un_b.s_b1 == 0x7f) + if (((uint8_t*)&g_adhocServerIP.in.sin_addr.s_addr)[0] == 0x7f) { // (serverIp.S_un.S_un_b.s_b1 == 0x7f) int on = 1; setsockopt(metasocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); setsockopt(metasocket, SOL_SOCKET, SO_DONTROUTE, (const char*)&on, sizeof(on)); @@ -1967,11 +1962,14 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ product_code.type = adhoc_id->type; memcpy(product_code.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); + // Don't need to connect if AdhocServer DNS was not resolved + if (g_adhocServerIP.in.sin_addr.s_addr == INADDR_NONE) + return -1; + // Connect to Adhoc Server - server_addr.sin_addr = serverIp; int errorcode = 0; int cnt = 0; - iResult = connect(metasocket, (sockaddr*)&server_addr, sizeof(server_addr)); + iResult = connect(metasocket, &g_adhocServerIP.addr, sizeof(g_adhocServerIP)); errorcode = errno; if (iResult == SOCKET_ERROR && errorcode != EISCONN) { @@ -1983,7 +1981,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ sleep_ms(10); } if (IsSocketReady(metasocket, true, true) <= 0) { - ERROR_LOG(SCENET, "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); + ERROR_LOG(SCENET, "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(g_adhocServerIP.in.sin_addr), ntohs(g_adhocServerIP.in.sin_port)); host->NotifyUserMessage(n->T("Failed to connect to Adhoc Server"), 1.0f, 0x0000ff); return iResult; } diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 149bae4c7a..28cf7203b1 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -851,6 +851,7 @@ extern uint16_t portOffset; extern uint32_t minSocketTimeoutUS; extern bool isOriPort; extern bool isLocalServer; +extern SockAddrIN4 g_adhocServerIP; // Resolved Adhoc Server IP so we don't need to repeatedly resolve the DNS again later extern SockAddrIN4 g_localhostIP; // Used to differentiate localhost IP on multiple-instance extern sockaddr LocalIP; // IP of Network Adapter used to connect to Adhoc Server (LAN/WAN) extern int defaultWlanChannel; // Default WLAN Channel for Auto, JPCSP uses 11 diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 98dcc52c92..dcd6ccd2a4 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -158,6 +158,11 @@ void __NetInit() { isOriPort = g_Config.bEnableUPnP && g_Config.bUPnPUseOriginalPort; minSocketTimeoutUS = g_Config.iMinTimeout * 1000UL; + // Init Default AdhocServer struct + g_adhocServerIP.in.sin_family = AF_INET; + g_adhocServerIP.in.sin_port = htons(SERVER_PORT); //27312 // Maybe read this from config too + g_adhocServerIP.in.sin_addr.s_addr = INADDR_NONE; + InitLocalhostIP(); SceNetEtherAddr mac; From 406fed791429f0b23643984f56059d3af1616773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 10 Sep 2020 23:47:54 +0200 Subject: [PATCH 668/848] Add option for the clear-fb-on-first-use speedhack. See #13295 --- Core/Config.cpp | 2 ++ Core/Config.h | 1 + GPU/Common/FramebufferManagerCommon.cpp | 6 +----- GPU/Common/FramebufferManagerCommon.h | 1 - UI/GameSettingsScreen.cpp | 9 +++++++++ 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 3164c9af9b..7e22329a73 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -818,6 +818,8 @@ static ConfigSetting graphicsSettings[] = { ConfigSetting("InflightFrames", &g_Config.iInflightFrames, 3, true, false), ConfigSetting("RenderDuplicateFrames", &g_Config.bRenderDuplicateFrames, false, true, true), + ConfigSetting("ClearFramebuffersOnFirstUseHack", &g_Config.bClearFramebuffersOnFirstUseHack, false, true, true), + ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index 3072efdbc3..f55a060dad 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -165,6 +165,7 @@ public: int iFrameSkipType; int iUnthrottleMode; // See UnthrottleMode in ConfigValues.h. bool bAutoFrameSkip; + bool bClearFramebuffersOnFirstUseHack; bool bEnableCardboardVR; // Cardboard Master Switch int iCardboardScreenSize; // Screen Size (in %) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 90f06fa10e..bd36e95532 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -44,10 +44,6 @@ FramebufferManagerCommon::FramebufferManagerCommon(Draw::DrawContext *draw) : draw_(draw), displayFormat_(GE_FORMAT_565) { presentation_ = new PresentationCommon(draw); - - // See comment from where it's used below. - // As for the use of IsGLES, just the way it was. Scary to change it. - clearFramebufferOnFirstUseHack_ = gl_extensions.IsGLES; } FramebufferManagerCommon::~FramebufferManagerCommon() { @@ -536,7 +532,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe if (useBufferedRendering_) { if (vfb->fbo) { shaderManager_->DirtyLastShader(); - if (clearFramebufferOnFirstUseHack_) { + if (g_Config.bClearFramebuffersOnFirstUseHack) { // HACK: Some tiled mobile GPUs benefit IMMENSELY from clearing an FBO before rendering // to it (or in Vulkan, clear during framebuffer load). This is a hack to force this // the first time a framebuffer is bound for rendering in a frame. diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 66954c511c..5738f930e8 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -396,7 +396,6 @@ protected: std::vector bvfbs_; // blitting framebuffers (for download) bool gameUsesSequentialCopies_ = false; - bool clearFramebufferOnFirstUseHack_ = false; // Sampled in BeginFrame for safety. float renderWidth_ = 0.0f; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 0e248c2981..60d2757f41 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -415,6 +415,15 @@ void GameSettingsScreen::CreateViews() { return !g_Config.bSoftwareRendering && g_Config.bHardwareTransform; }); + CheckBox *clearHack = graphicsSettings->Add(new CheckBox(&g_Config.bClearFramebuffersOnFirstUseHack, gr->T("Clear Speedhack", "Clear framebuffers on first use (speedhack)"))); + clearHack->OnClick.Add([=](EventParams &e) { + settingInfo_->Show(gr->T("ClearSpeedhack Tip", "Sometimes faster (mostly on mobile devices), may cause glitches"), e.v); + return UI::EVENT_CONTINUE; + }); + clearHack->SetEnabledFunc([] { + return !g_Config.bSoftwareRendering; + }); + CheckBox *texBackoff = graphicsSettings->Add(new CheckBox(&g_Config.bTextureBackoffCache, gr->T("Lazy texture caching", "Lazy texture caching (speedup)"))); texBackoff->SetDisabledPtr(&g_Config.bSoftwareRendering); From c57d81cc3ecb0d1196f332cad7d48988426b0192 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 6 Sep 2020 04:50:11 +0700 Subject: [PATCH 669/848] Fixed sceNetAdhocMatchingGetMembers error return value --- Core/HLE/sceNetAdhoc.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index d321d567cb..6f1e5ff5f5 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -4327,11 +4327,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) if (!g_Config.bEnableWlan) return -1; - // Ys vs. Sora no Kiseki seems to be using this function even after AdhocMatching is Terminated, May be member list persist even after AdhocMatching terminated until the next init? - if (!netAdhocMatchingInited) { - //WARN_LOG(SCENET, "sceNetAdhocMatchingGetMembers - AdhocMatching is Not Initialized"); - return 0; // ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; - } + if (!netAdhocMatchingInited) + return ERROR_NET_ADHOC_MATCHING_NOT_INITIALIZED; // Minimum Argument if (!Memory::IsValidAddress(sizeAddr)) From 2e9952cf6e1ced6305ee7f2eea1c2cd0f0cff65c Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 6 Sep 2020 05:38:46 +0700 Subject: [PATCH 670/848] Prevent spamming the log too much on some games --- Core/HLE/sceNetAdhoc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 6f1e5ff5f5..7024529b96 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -4708,7 +4708,7 @@ static int sceNetAdhocMatchingGetPoolMaxAlloc() { } int sceNetAdhocMatchingGetPoolStat(u32 poolstatPtr) { - WARN_LOG(SCENET, "UNTESTED sceNetAdhocMatchingGetPoolStat(%08x)", poolstatPtr); + DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocMatchingGetPoolStat(%08x)", poolstatPtr); if (!g_Config.bEnableWlan) return -1; From 1e6593f791e35da1a7be8c750f266d0d43a35d71 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 11 Sep 2020 13:24:45 +0700 Subject: [PATCH 671/848] Sleep a bit longer, especially when PPSSPP paused. --- Core/HLE/proAdhoc.cpp | 4 ++-- Core/HLE/proAdhocServer.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 41f7fa0030..6bced5fb21 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1589,10 +1589,10 @@ int friendFinder(){ } } // This delay time should be 100ms when there is an event otherwise 500ms ? - sleep_ms(1); // Using 1ms for faster response just like AdhocServer? + sleep_ms(10); // Using 1ms for faster response just like AdhocServer? // Don't do anything if it's paused, otherwise the log will be flooded - while (Core_IsStepping() && coreState != CORE_POWERDOWN && friendFinderRunning) sleep_ms(1); + while (Core_IsStepping() && coreState != CORE_POWERDOWN && friendFinderRunning) sleep_ms(10); } // Groups/Networks should be deallocated isn't? diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index b050ca43b2..8b8246b858 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -2077,10 +2077,10 @@ int server_loop(int server) } // Prevent needless CPU Overload (1ms Sleep) - sleep_ms(1); + sleep_ms(10); // Don't do anything if it's paused, otherwise the log will be flooded - while (adhocServerRunning && Core_IsStepping() && coreState != CORE_POWERDOWN) sleep_ms(1); + while (adhocServerRunning && Core_IsStepping() && coreState != CORE_POWERDOWN) sleep_ms(10); } // Free User Database Memory From 3eeb48bb40709ed27abe3c21cc6d048b4ecbbf12 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 11 Sep 2020 13:08:01 +0700 Subject: [PATCH 672/848] Clients shouldn't try to detects timeout of other clients, because most of the time the client side doesn't have timeout information given, better wait for the host to tells them if a client got disconnected. --- Core/HLE/proAdhoc.cpp | 19 +++++++++--------- Core/HLE/sceNetAdhoc.cpp | 43 ++++++++++++++++++++++++++++++---------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 0575631668..5a382ede62 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -935,22 +935,23 @@ void handleTimeout(SceNetAdhocMatchingContext * context) SceNetAdhocMatchingMemberInternal * next = peer->next; u64_le now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0 - // Timeout!, may be we shouldn't kick timedout members ourself and let the game do it - if (peer->state != 0 && (now - peer->lastping) >= context->timeout) + // Timeout! + if (peer->state != 0 && (now - peer->lastping) > context->timeout) { // Spawn Timeout Event - if ((context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && (/*peer->state == PSP_ADHOC_MATCHING_PEER_CHILD ||*/ peer->state == PSP_ADHOC_MATCHING_PEER_PARENT)) || + if ((context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) || (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT && peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) || (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && peer->state == PSP_ADHOC_MATCHING_PEER_P2P)) { // FIXME: TIMEOUT event should only be triggered on Parent/P2P mode and for Parent/P2P peer? spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); + + INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac).c_str(), (context->timeout / 1000)); + + if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) + sendDeathMessage(context, peer); + else + sendCancelMessage(context, peer, 0, NULL); } - - INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac).c_str(), (context->timeout/1000)); - - // Delete Peer from List - deletePeer(context, peer); - //peer->lastping = 0; //Let's just make the game kick timedout members during sceNetAdhocMatchingGetMembers } // Move Pointer diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7024529b96..398d328521 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -4415,6 +4415,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) auto friendpeer = findFriend(&p2p->mac); if (p2p->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) p2p->lastping = CoreTiming::GetGlobalTimeUsScaled(); + else + p2p->lastping = 0; // Add P2P Brother MAC buf2[filledpeers++].mac_addr = p2p->mac; @@ -4433,6 +4435,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) auto friendpeer = findFriend(&parentpeer->mac); if (parentpeer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) parentpeer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + else + parentpeer->lastping = 0; // Add Parent MAC buf2[filledpeers++].mac_addr = parentpeer->mac; @@ -4453,6 +4457,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) auto friendpeer = findFriend(&peer->mac); if (peer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + else + peer->lastping = 0; // Add Peer MAC sortedPeers.push_front(peer); @@ -5517,9 +5523,6 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac // Packet Buffer uint8_t packet[7]; - // Set Opcode - packet[0] = PSP_ADHOC_MATCHING_PACKET_DEATH; - // Set abandoned Child MAC memcpy(packet + 1, mac, sizeof(SceNetEtherAddr)); @@ -5527,18 +5530,32 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) { - // Skip dead Child - if (peer == deadkid) continue; + // Skip dead Child? Or May be we should also tells the disconnected Child, that they have been disconnected from the Host (in the case they were disconnected because they went to PPSSPP settings for too long) + if (peer == deadkid) { + // Set Opcode + packet[0] = PSP_ADHOC_MATCHING_PACKET_BYE; - // Send only to children + // Send Bye Packet + context->socketlock->lock(); + sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, context->port, packet, sizeof(packet[0]), 0, ADHOC_F_NONBLOCK); + context->socketlock->unlock(); + } + else + // Send to other children if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) { - // Send Packet + // Set Opcode + packet[0] = PSP_ADHOC_MATCHING_PACKET_DEATH; + + // Send Death Packet context->socketlock->lock(); sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, context->port, packet, sizeof(packet), 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); } } + + // Delete Peer + deletePeer(context, deadkid); } } @@ -5692,7 +5709,7 @@ void actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen // If we got the peer in the table already and are a parent, there is nothing left to be done. // This is because the only way a parent can know of a child is via a join request... // If we thus know of a possible child, then we already had a previous join request thus no need for double tapping. - if (peer != NULL && context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { + if (peer != NULL && peer->lastping != 0 && context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { WARN_LOG(SCENET, "Join Event(2) Ignored"); return; } @@ -5738,6 +5755,9 @@ void actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen // Set Peer State peer->state = PSP_ADHOC_MATCHING_PEER_INCOMING_REQUEST; + // Initialize Ping Timer + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + // Spawn Request Event spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_REQUEST, sendermac, optlen, opt); @@ -6217,7 +6237,7 @@ int matchingEventThread(int matchingId) sleep_ms(10); //1 //sceKernelDelayThread(10000); // Don't do anything if it's paused, otherwise the log will be flooded - while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->eventRunning) sleep_ms(1); + while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->eventRunning) sleep_ms(10); } // Process Last Messages @@ -6371,6 +6391,9 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi // Send Birth Packet else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_BIRTH) sendBirthPacket(context, &msg->mac); + // Send Death Packet + else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_DEATH) sendDeathPacket(context, &msg->mac); + // Cancel Bulk Data Transfer (does nothing as of now as we fire and forget anyway) // Do we need to check DeathPacket and ByePacket here? //else if(msg->opcode == PSP_ADHOC_MATCHING_PACKET_BULK_ABORT) sendAbortBulkDataPacket(context, &msg->mac, msg->optlen, opt); @@ -6456,7 +6479,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi sleep_ms(10); //1 //sceKernelDelayThread(10000); // Don't do anything if it's paused, otherwise the log will be flooded - while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->inputRunning) sleep_ms(1); + while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->inputRunning) sleep_ms(10); } if (contexts != NULL) { From 210413cba7673fc3169effe024ab415e313b6939 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Fri, 11 Sep 2020 20:29:49 +0700 Subject: [PATCH 673/848] Allows reusing the same port for PtpListen and PtpOpen. This fixes Shin Sangoku Musou Multi Raid 2, and probably other games with similar issue (ie. Dynasty Warrior Strikeforce) --- Core/HLE/sceNetAdhoc.cpp | 483 +++++++++++++++++++-------------------- 1 file changed, 230 insertions(+), 253 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 398d328521..4483cfc998 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2605,130 +2605,119 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Random Port required if (sport == 0) { isClient = true; - // Find unused Port - // while (sport == 0 || _IsPTPPortInUse(sport)) { - // // Generate Port Number - // sport = (uint16_t)_getRandomNumber(65535); - // } - } - - // Valid Ports - if (!isPTPPortInUse(sport) /*&& dport != 0*/) { //sport 0 should be shifted back to 0 when using offset Phantasy Star Portable 2 use this - if (sport == 0) sport = -(int)portOffset; - // Valid Arguments - if (bufsize > 0 && rexmt_int > 0 && rexmt_cnt > 0) { - // Create Infrastructure Socket - int tcpsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - // Valid Socket produced - if (tcpsocket > 0) { - // Change socket buffer size when necessary - if (getSockBufferSize(tcpsocket, SO_SNDBUF) < bufsize) setSockBufferSize(tcpsocket, SO_SNDBUF, bufsize); - if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); - - // Enable KeepAlive - setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); - - // Ignore SIGPIPE when supported (ie. BSD/MacOS) - setSockNoSIGPIPE(tcpsocket, 1); - - // Enable Port Re-use - setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); - - // Apply Default Send Timeout Settings to Socket - setSockTimeout(tcpsocket, SO_SNDTIMEO, rexmt_int); - - // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1); - - // Binding Information for local Port - sockaddr_in addr; - // addr.sin_len = sizeof(addr); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - if (isLocalServer) { - getLocalIp(&addr); - } - addr.sin_port = htons(sport + portOffset); - - // Bound Socket to local Port - if (bind(tcpsocket, (sockaddr *)&addr, sizeof(addr)) == 0) { - // Update sport with the port assigned internal->lport = ntohs(local.sin_port) - socklen_t len = sizeof(addr); - if (getsockname(tcpsocket, (sockaddr *)&addr, &len) == 0) { - sport = ntohs(addr.sin_port) - portOffset; - } - - // Allocate Memory - AdhocSocket * internal = (AdhocSocket*)malloc(sizeof(AdhocSocket)); - - // Allocated Memory - if (internal != NULL) { - // Find Free Translator ID - int i = 0; - for (; i < MAX_SOCKET; i++) if (adhocSockets[i] == NULL) break; - - // Found Free Translator ID - if (i < MAX_SOCKET) { - // Clear Memory - memset(internal, 0, sizeof(AdhocSocket)); - - // Socket Type - internal->type = SOCK_PTP; - - // Copy Infrastructure Socket ID - internal->data.ptp.id = tcpsocket; - - // Copy Address Information - internal->data.ptp.laddr = *saddr; - internal->data.ptp.paddr = *daddr; - internal->data.ptp.lport = sport; - internal->data.ptp.pport = dport; - - // Set Buffer Size - internal->data.ptp.rcv_sb_cc = bufsize; - - // Link PTP Socket - adhocSockets[i] = internal; - ptpConnectCount[i] = 0; - - // Add Port Forward to Router. We may not even need to forward this local port, since PtpOpen usually have port 0 (any port) as source port and followed by PtpConnect (which mean acting as Client), right? - //sceNetPortOpen("TCP", sport); - if (!isClient) - UPnP_Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); - - // Switch to non-blocking for futher usage - changeBlockingMode(tcpsocket, 1); - - // Return PTP Socket Pointer - return i + 1; - } - - // Free Memory - free(internal); - } - } - else { - ERROR_LOG(SCENET, "Socket error (%i) when binding port %u", errno, ntohs(addr.sin_port)); - auto n = GetI18NCategory("Networking"); - host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(sport + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); - } - - // Close Socket - closesocket(tcpsocket); - - // Port not available (exclusively in use?) - return ERROR_NET_ADHOC_PORT_IN_USE; // ERROR_NET_ADHOC_PORT_NOT_AVAIL; - } - } - - // Invalid Arguments - return ERROR_NET_ADHOC_INVALID_ARG; + sport = -(int)portOffset; } - // Invalid Ports - return ERROR_NET_ADHOC_PORT_IN_USE; // ERROR_NET_ADHOC_INVALID_PORT; + // Valid Arguments + if (bufsize > 0 && rexmt_int > 0 && rexmt_cnt > 0) { + // Create Infrastructure Socket + int tcpsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + // Valid Socket produced + if (tcpsocket > 0) { + // Change socket buffer size when necessary + if (getSockBufferSize(tcpsocket, SO_SNDBUF) < bufsize) setSockBufferSize(tcpsocket, SO_SNDBUF, bufsize); + if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); + + // Enable KeepAlive + setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); + + // Ignore SIGPIPE when supported (ie. BSD/MacOS) + setSockNoSIGPIPE(tcpsocket, 1); + + // Enable Port Re-use + setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + + // Apply Default Send Timeout Settings to Socket + setSockTimeout(tcpsocket, SO_SNDTIMEO, rexmt_int); + + // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? + if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1); + + // Binding Information for local Port + sockaddr_in addr; + // addr.sin_len = sizeof(addr); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + if (isLocalServer) { + getLocalIp(&addr); + } + addr.sin_port = htons(sport + portOffset); + + // Bound Socket to local Port + if (bind(tcpsocket, (sockaddr*)&addr, sizeof(addr)) == 0) { + // Update sport with the port assigned internal->lport = ntohs(local.sin_port) + socklen_t len = sizeof(addr); + if (getsockname(tcpsocket, (sockaddr*)&addr, &len) == 0) { + sport = ntohs(addr.sin_port) - portOffset; + } + + // Allocate Memory + AdhocSocket* internal = (AdhocSocket*)malloc(sizeof(AdhocSocket)); + + // Allocated Memory + if (internal != NULL) { + // Find Free Translator ID + int i = 0; + for (; i < MAX_SOCKET; i++) if (adhocSockets[i] == NULL) break; + + // Found Free Translator ID + if (i < MAX_SOCKET) { + // Clear Memory + memset(internal, 0, sizeof(AdhocSocket)); + + // Socket Type + internal->type = SOCK_PTP; + + // Copy Infrastructure Socket ID + internal->data.ptp.id = tcpsocket; + + // Copy Address Information + internal->data.ptp.laddr = *saddr; + internal->data.ptp.paddr = *daddr; + internal->data.ptp.lport = sport; + internal->data.ptp.pport = dport; + + // Set Buffer Size + internal->data.ptp.rcv_sb_cc = bufsize; + + // Link PTP Socket + adhocSockets[i] = internal; + ptpConnectCount[i] = 0; + + // Add Port Forward to Router. We may not even need to forward this local port, since PtpOpen usually have port 0 (any port) as source port and followed by PtpConnect (which mean acting as Client), right? + //sceNetPortOpen("TCP", sport); + if (!isClient) + UPnP_Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); + + // Switch to non-blocking for futher usage + changeBlockingMode(tcpsocket, 1); + + // Return PTP Socket Pointer + return i + 1; + } + + // Free Memory + free(internal); + } + } + else { + ERROR_LOG(SCENET, "Socket error (%i) when binding port %u", errno, ntohs(addr.sin_port)); + auto n = GetI18NCategory("Networking"); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(sport + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); + } + + // Close Socket + closesocket(tcpsocket); + + // Port not available (exclusively in use?) + return ERROR_NET_ADHOC_INVALID_PORT; // ERROR_NET_ADHOC_PORT_IN_USE; // ERROR_NET_ADHOC_PORT_NOT_AVAIL; + } + } + + // Invalid Arguments + return ERROR_NET_ADHOC_INVALID_ARG; } // Invalid Addresses @@ -3111,141 +3100,129 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int if (saddr != NULL && isLocalMAC(saddr)) { // Random Port required if (sport == 0) { - // Find unused Port - // while (sport == 0 || __IsPTPPortInUse(sport)) - // { - // // Generate Port Number - // sport = (uint16_t)_getRandomNumber(65535); - // } - } - - // Valid Ports - if (!isPTPPortInUse(sport)) { //sport 0 should be shifted back to 0 when using offset Phantasy Star Portable 2 use this - if (sport == 0) sport = -(int)portOffset; - // Valid Arguments - if (bufsize > 0 && rexmt_int > 0 && rexmt_cnt > 0 && backlog > 0) - { - // Create Infrastructure Socket - int tcpsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - // Valid Socket produced - if (tcpsocket > 0) { - // Change socket buffer size when necessary - if (getSockBufferSize(tcpsocket, SO_SNDBUF) < bufsize) setSockBufferSize(tcpsocket, SO_SNDBUF, bufsize); - if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); - - // Enable KeepAlive - setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); - - // Ignore SIGPIPE when supported (ie. BSD/MacOS) - setSockNoSIGPIPE(tcpsocket, 1); - - // Enable Port Re-use - setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); - - // Apply Default Receive Timeout Settings to Socket - setSockTimeout(tcpsocket, SO_RCVTIMEO, rexmt_int); - - // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1); - - // Binding Information for local Port - sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - if (isLocalServer) { - getLocalIp(&addr); - } - addr.sin_port = htons(sport + portOffset); - - int iResult = 0; - // Bound Socket to local Port - if ((iResult = bind(tcpsocket, (sockaddr *)&addr, sizeof(addr))) == 0) { - // Update sport with the port assigned internal->lport = ntohs(local.sin_port) - socklen_t len = sizeof(addr); - if (getsockname(tcpsocket, (sockaddr*)&addr, &len) == 0) { - sport = ntohs(addr.sin_port) - portOffset; - } - // Switch into Listening Mode - if ((iResult = listen(tcpsocket, backlog)) == 0) { - // Allocate Memory - AdhocSocket * internal = (AdhocSocket*)malloc(sizeof(AdhocSocket)); - - // Allocated Memory - if (internal != NULL) { - // Find Free Translator ID - int i = 0; - for (; i < MAX_SOCKET; i++) if (adhocSockets[i] == NULL) break; - - // Found Free Translator ID - if (i < MAX_SOCKET) { - // Clear Memory - memset(internal, 0, sizeof(AdhocSocket)); - - // Socket Type - internal->type = SOCK_PTP; - - // Copy Infrastructure Socket ID - internal->data.ptp.id = tcpsocket; - - // Copy Address Information - internal->data.ptp.laddr = *saddr; - internal->data.ptp.lport = sport; - - // Flag Socket as Listener - internal->data.ptp.state = ADHOC_PTP_STATE_LISTEN; - - // Set Buffer Size - internal->data.ptp.rcv_sb_cc = bufsize; - - // Link PTP Socket - adhocSockets[i] = internal; - ptpConnectCount[i] = 0; - - // Add Port Forward to Router - //sceNetPortOpen("TCP", sport); - UPnP_Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); // g_PortManager.Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); - - // Switch to non-blocking for futher usage - changeBlockingMode(tcpsocket, 1); - - // Return PTP Socket Pointer - return i + 1; - } - - // Free Memory - free(internal); - } - } - } - else { - auto n = GetI18NCategory("Networking"); - host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(sport + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); - } - - if (iResult == SOCKET_ERROR) { - int error = errno; - ERROR_LOG(SCENET, "sceNetAdhocPtpListen[%i]: Socket Error (%i)", sport, error); - } - - // Close Socket - closesocket(tcpsocket); - - // Port not available (exclusively in use?) - return ERROR_NET_ADHOC_PORT_IN_USE; // ERROR_NET_ADHOC_PORT_NOT_AVAIL; - } - - // Socket not available - return ERROR_NET_ADHOC_SOCKET_ID_NOT_AVAIL; - } - - // Invalid Arguments - return ERROR_NET_ADHOC_INVALID_ARG; + sport = -(int)portOffset; } - // Invalid Ports - return ERROR_NET_ADHOC_PORT_IN_USE; + // Valid Arguments + if (bufsize > 0 && rexmt_int > 0 && rexmt_cnt > 0 && backlog > 0) + { + // Create Infrastructure Socket + int tcpsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + // Valid Socket produced + if (tcpsocket > 0) { + // Change socket buffer size when necessary + if (getSockBufferSize(tcpsocket, SO_SNDBUF) < bufsize) setSockBufferSize(tcpsocket, SO_SNDBUF, bufsize); + if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); + + // Enable KeepAlive + setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); + + // Ignore SIGPIPE when supported (ie. BSD/MacOS) + setSockNoSIGPIPE(tcpsocket, 1); + + // Enable Port Re-use + setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + + // Apply Default Receive Timeout Settings to Socket + setSockTimeout(tcpsocket, SO_RCVTIMEO, rexmt_int); + + // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? + if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1); + + // Binding Information for local Port + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + if (isLocalServer) { + getLocalIp(&addr); + } + addr.sin_port = htons(sport + portOffset); + + int iResult = 0; + // Bound Socket to local Port + if ((iResult = bind(tcpsocket, (sockaddr*)&addr, sizeof(addr))) == 0) { + // Update sport with the port assigned internal->lport = ntohs(local.sin_port) + socklen_t len = sizeof(addr); + if (getsockname(tcpsocket, (sockaddr*)&addr, &len) == 0) { + sport = ntohs(addr.sin_port) - portOffset; + } + // Switch into Listening Mode + if ((iResult = listen(tcpsocket, backlog)) == 0) { + // Allocate Memory + AdhocSocket* internal = (AdhocSocket*)malloc(sizeof(AdhocSocket)); + + // Allocated Memory + if (internal != NULL) { + // Find Free Translator ID + int i = 0; + for (; i < MAX_SOCKET; i++) if (adhocSockets[i] == NULL) break; + + // Found Free Translator ID + if (i < MAX_SOCKET) { + // Clear Memory + memset(internal, 0, sizeof(AdhocSocket)); + + // Socket Type + internal->type = SOCK_PTP; + + // Copy Infrastructure Socket ID + internal->data.ptp.id = tcpsocket; + + // Copy Address Information + internal->data.ptp.laddr = *saddr; + internal->data.ptp.lport = sport; + + // Flag Socket as Listener + internal->data.ptp.state = ADHOC_PTP_STATE_LISTEN; + + // Set Buffer Size + internal->data.ptp.rcv_sb_cc = bufsize; + + // Link PTP Socket + adhocSockets[i] = internal; + ptpConnectCount[i] = 0; + + // Add Port Forward to Router + //sceNetPortOpen("TCP", sport); + UPnP_Add(IP_PROTOCOL_TCP, isOriPort ? sport : sport + portOffset, sport + portOffset); + + // Switch to non-blocking for futher usage + changeBlockingMode(tcpsocket, 1); + + // Return PTP Socket Pointer + return i + 1; + } + + // Free Memory + free(internal); + } + } + } + else { + auto n = GetI18NCategory("Networking"); + host->NotifyUserMessage(std::string(n->T("Failed to Bind Port")) + " " + std::to_string(sport + portOffset) + "\n" + std::string(n->T("Please change your Port Offset")), 3.0, 0x0000ff); + } + + if (iResult == SOCKET_ERROR) { + int error = errno; + ERROR_LOG(SCENET, "sceNetAdhocPtpListen[%i]: Socket Error (%i)", sport, error); + } + + // Close Socket + closesocket(tcpsocket); + + // Port not available (exclusively in use?) + return ERROR_NET_ADHOC_INVALID_PORT; //ERROR_NET_ADHOC_PORT_IN_USE; // ERROR_NET_ADHOC_PORT_NOT_AVAIL; + } + + // Socket not available + return ERROR_NET_ADHOC_SOCKET_ID_NOT_AVAIL; + } + + // Invalid Arguments + return ERROR_NET_ADHOC_INVALID_ARG; } // Invalid Addresses From 2b109f46408b55f6686458b50cc18d18564f7f94 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 12 Sep 2020 06:14:28 +0700 Subject: [PATCH 674/848] Avoid getting Fatal signal 6 (SIGABRT) on linux/android when losing connectivity to the Adhoc Server. --- Core/HLE/proAdhoc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 0bba246171..d3eae80ce3 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -230,6 +230,10 @@ int IsSocketReady(int fd, bool readfd, bool writefd, int* errorcode, int timeout fd_set readfds, writefds; timeval tval; + // Avoid getting Fatal signal 6 (SIGABRT) on linux/android + if (fd < 0) + return SOCKET_ERROR; + FD_ZERO(&readfds); writefds = readfds; if (readfd) { From 3b38062a4778356578d19e62bb6a7e91160ae233 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 12 Sep 2020 09:08:50 +0700 Subject: [PATCH 675/848] Fix Failed to Bind already used port issue on Android (and probably linux too). This should fix Dynasty Warrior Strikeforce and Shin Sangoku Musou Multi Raid 2 --- Core/HLE/proAdhoc.cpp | 12 +++++++++++- Core/HLE/proAdhoc.h | 5 +++++ Core/HLE/proAdhocServer.cpp | 5 +---- Core/HLE/sceNetAdhoc.cpp | 17 ++++++++++------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 0bba246171..9feff43ab1 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1840,6 +1840,16 @@ int setSockNoSIGPIPE(int sock, int flag) { return -1; } +int setSockReuseAddrPort(int sock) { + int opt = 1; + // Should we set SO_BROADCAST too for SO_REUSEADDR to works like SO_REUSEPORT ? + // Set SO_REUSEPORT also when supported (ie. Android) +#if defined(SO_REUSEPORT) + setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&opt, sizeof(opt)); +#endif + return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt)); +} + #if !defined(TCP_KEEPIDLE) #define TCP_KEEPIDLE TCP_KEEPALIVE //TCP_KEEPIDLE on Linux is equivalent to TCP_KEEPALIVE on macOS #endif @@ -1938,8 +1948,8 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ // (may not works in WinXP/2003 for IPv4 due to "Weak End System" model) if (((uint8_t*)&g_adhocServerIP.in.sin_addr.s_addr)[0] == 0x7f) { // (serverIp.S_un.S_un_b.s_b1 == 0x7f) int on = 1; - setsockopt(metasocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); setsockopt(metasocket, SOL_SOCKET, SO_DONTROUTE, (const char*)&on, sizeof(on)); + setSockReuseAddrPort(metasocket); g_localhostIP.in.sin_port = 0; // Bind Local Address to Socket diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 28cf7203b1..d7b0269844 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -1224,6 +1224,11 @@ int setSockNoDelay(int tcpsock, int flag); */ int setSockNoSIGPIPE(int sock, int flag); +/* +* Set Socket SO_REUSEADDR and SO_REUSEPORT when supported +*/ +int setSockReuseAddrPort(int sock); + /* * Set Socket KeepAlive (opt = SO_KEEPALIVE) */ diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 8b8246b858..32fea38db0 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -1733,11 +1733,8 @@ void interrupt(int sig) */ void enable_address_reuse(int fd) { - // Enable Value - int on = 1; - // Enable Port Reuse - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); + setSockReuseAddrPort(fd); } /** diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 4483cfc998..1773d0fe49 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -966,7 +966,7 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u setSockNoSIGPIPE(usocket, 1); // Enable Port Re-use, this will allow binding to an already used port, but only one of them can read the data (shared receive buffer?) - setsockopt(usocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + setSockReuseAddrPort(usocket); // Binding Information for local Port sockaddr_in addr; @@ -2627,13 +2627,14 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, setSockNoSIGPIPE(tcpsocket, 1); // Enable Port Re-use - setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + setSockReuseAddrPort(tcpsocket); // Apply Default Send Timeout Settings to Socket setSockTimeout(tcpsocket, SO_SNDTIMEO, rexmt_int); // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1); + if (g_Config.bTCPNoDelay) + setSockNoDelay(tcpsocket, 1); // Binding Information for local Port sockaddr_in addr; @@ -2736,10 +2737,11 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther setSockNoSIGPIPE(newsocket, 1); // Enable Port Re-use - setsockopt(newsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + setSockReuseAddrPort(newsocket); // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - if (g_Config.bTCPNoDelay) setSockNoDelay(newsocket, 1); + if (g_Config.bTCPNoDelay) + setSockNoDelay(newsocket, 1); // Local Address Information sockaddr_in local; @@ -3123,13 +3125,14 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int setSockNoSIGPIPE(tcpsocket, 1); // Enable Port Re-use - setsockopt(tcpsocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one, sizeof(one)); + setSockReuseAddrPort(tcpsocket); // Apply Default Receive Timeout Settings to Socket setSockTimeout(tcpsocket, SO_RCVTIMEO, rexmt_int); // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? - if (g_Config.bTCPNoDelay) setSockNoDelay(tcpsocket, 1); + if (g_Config.bTCPNoDelay) + setSockNoDelay(tcpsocket, 1); // Binding Information for local Port sockaddr_in addr; From a24e2e694624ec6f36513fe2fa1be517624e71ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 12 Sep 2020 12:30:44 +0200 Subject: [PATCH 676/848] Minor cleanups in CaptureDevice --- Windows/CaptureDevice.cpp | 27 ++++++++++----------------- Windows/CaptureDevice.h | 26 +++++++++++++------------- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/Windows/CaptureDevice.cpp b/Windows/CaptureDevice.cpp index 6ae0733e51..a475901137 100644 --- a/Windows/CaptureDevice.cpp +++ b/Windows/CaptureDevice.cpp @@ -111,13 +111,15 @@ MediaParam defaultAudioParam = { 44100, 2, 16, MFAudioFormat_PCM }; HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride); -ReaderCallback::ReaderCallback(WindowsCaptureDevice *device): img_convert_ctx(nullptr), resample_ctx(nullptr){ - this->device = device; -} +ReaderCallback::ReaderCallback(WindowsCaptureDevice *_device) : device(_device) {} ReaderCallback::~ReaderCallback() { - sws_freeContext(img_convert_ctx); - swr_free(&resample_ctx); + if (img_convert_ctx) { + sws_freeContext(img_convert_ctx); + } + if (resample_ctx) { + swr_free(&resample_ctx); + } } HRESULT ReaderCallback::QueryInterface(REFIID riid, void** ppv) @@ -439,20 +441,10 @@ u32 ReaderCallback::doResample(u8 **dst, u32 &dstSampleRate, u32 &dstChannels, u return av_samples_get_buffer_size(nullptr, dstChannels, outSamplesCount, AV_SAMPLE_FMT_S16, 0); } -WindowsCaptureDevice::WindowsCaptureDevice(CAPTUREDEVIDE_TYPE type) : - type(type), - m_pCallback(nullptr), - m_pSource(nullptr), - m_pReader(nullptr), - imageRGB(nullptr), - imageJpeg(nullptr), - imgJpegSize(0), - resampleBuf(nullptr), - resampleBufSize(0), - rawAudioBuf(nullptr), +WindowsCaptureDevice::WindowsCaptureDevice(CAPTUREDEVIDE_TYPE _type) : + type(_type), error(CAPTUREDEVIDE_ERROR_NO_ERROR), errorMessage(""), - isDeviceChanged(false), state(CAPTUREDEVIDE_STATE::UNINITIALIZED) { param = { 0 }; deviceParam = { 0 }; @@ -482,6 +474,7 @@ WindowsCaptureDevice::~WindowsCaptureDevice() { break; } } + void WindowsCaptureDevice::CheckDevices() { isDeviceChanged = true; } diff --git a/Windows/CaptureDevice.h b/Windows/CaptureDevice.h index 60f9b61b05..0829bdb2bc 100644 --- a/Windows/CaptureDevice.h +++ b/Windows/CaptureDevice.h @@ -171,8 +171,8 @@ public: protected: WindowsCaptureDevice *device; - SwsContext *img_convert_ctx; - SwrContext *resample_ctx; + SwsContext *img_convert_ctx = nullptr; + SwrContext *resample_ctx = nullptr; }; class WindowsCaptureDevice { @@ -222,12 +222,12 @@ protected: CAPTUREDEVIDE_ERROR error; std::string errorMessage; - bool isDeviceChanged; + bool isDeviceChanged = false; // MF interface. - ReaderCallback *m_pCallback; - IMFSourceReader *m_pReader; - IMFMediaSource *m_pSource; + ReaderCallback *m_pCallback = nullptr; + IMFSourceReader *m_pReader = nullptr; + IMFMediaSource *m_pSource = nullptr; // Message loop. std::mutex mutex; @@ -241,15 +241,15 @@ protected: std::mutex paramMutex; // Camera only - unsigned char *imageRGB; - int imgRGBLineSizes[4]; - unsigned char *imageJpeg; - int imgJpegSize; + unsigned char *imageRGB = nullptr; + int imgRGBLineSizes[4]{}; + unsigned char *imageJpeg = nullptr; + int imgJpegSize = 0; //Microphone only - u8 *resampleBuf; - u32 resampleBufSize; - QueueBuf *rawAudioBuf; + u8 *resampleBuf = nullptr; + u32 resampleBufSize = 0; + QueueBuf *rawAudioBuf = nullptr; }; extern WindowsCaptureDevice *winCamera; From b9645726798fb47739a5641b7de4b339b8039e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 12 Sep 2020 12:32:24 +0200 Subject: [PATCH 677/848] Make SetColorUpdated static, reorder some fields --- GPU/Common/FramebufferManagerCommon.h | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 5738f930e8..0cf50cb7ff 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -49,24 +49,12 @@ namespace Draw { class VulkanFBO; struct VirtualFramebuffer { - int last_frame_used; - int last_frame_attached; - int last_frame_render; - int last_frame_displayed; - int last_frame_clut; - int last_frame_failed; - int last_frame_depth_updated; - int last_frame_depth_render; - u32 clutUpdatedBytes; - bool memoryUpdated; - bool firstFrameSaved; - u32 fb_address; u32 z_address; // If 0, it's a "RAM" framebuffer. int fb_stride; int z_stride; - // There's also a top left of the drawing region, but meh... + GEBufferFormat format; // virtual, right now they are all RGBA8888 // width/height: The detected size of the current framebuffer, in original PSP pixels. u16 width; @@ -89,8 +77,6 @@ struct VirtualFramebuffer { u16 newHeight; int lastFrameNewSize; - GEBufferFormat format; // virtual, right now they are all RGBA8888 - // TODO: Handle fbo and colorDepth better. u8 colorDepth; Draw::Framebuffer *fbo; @@ -103,6 +89,18 @@ struct VirtualFramebuffer { bool dirtyAfterDisplay; bool reallyDirtyAfterDisplay; // takes frame skipping into account + + int last_frame_used; + int last_frame_attached; + int last_frame_render; + int last_frame_displayed; + int last_frame_clut; + int last_frame_failed; + int last_frame_depth_updated; + int last_frame_depth_render; + u32 clutUpdatedBytes; + bool memoryUpdated; + bool firstFrameSaved; }; struct FramebufferHeuristicParams { @@ -354,7 +352,7 @@ protected: void UpdateFramebufUsage(VirtualFramebuffer *vfb); - void SetColorUpdated(VirtualFramebuffer *dstBuffer, int skipDrawReason) { + static void SetColorUpdated(VirtualFramebuffer *dstBuffer, int skipDrawReason) { dstBuffer->memoryUpdated = false; dstBuffer->clutUpdatedBytes = 0; dstBuffer->dirtyAfterDisplay = true; From c7a5f45f8109c3457ce50662afa54bf48780c181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 12 Sep 2020 12:37:05 +0200 Subject: [PATCH 678/848] Remove fbCache_ from TextureCacheCommon.cpp. --- GPU/Common/FramebufferManagerCommon.h | 4 ++++ GPU/Common/TextureCacheCommon.cpp | 22 ++++++++-------------- GPU/Common/TextureCacheCommon.h | 2 -- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 0cf50cb7ff..ff43f6d504 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -311,6 +311,10 @@ public: virtual bool GetStencilbuffer(u32 fb_address, int fb_stride, GPUDebugBuffer &buffer); virtual bool GetOutputFramebuffer(GPUDebugBuffer &buffer); + const std::vector &Framebuffers() { + return vfbs_; + } + protected: virtual void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h); void SetViewport2D(int x, int y, int w, int h); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 4df49bac7d..1f23c012a0 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -567,8 +567,11 @@ bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texA std::vector detaches; FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; - for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { - auto framebuffer = fbCache_[i]; + + auto framebuffers = framebufferManager_->Framebuffers(); + + for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { + auto framebuffer = framebuffers[i]; uint32_t fb_addr = channel == NOTIFY_FB_DEPTH ? framebuffer->z_address : framebuffer->fb_address; FramebufferMatchInfo match = MatchFramebuffer(entry, fb_addr, framebuffer, texAddrOffset, channel); if (match.match == FramebufferMatch::IGNORE) { @@ -765,14 +768,6 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram // Try to match the new framebuffer to existing textures. // Backwards from the "usual" texturing case so can't share a utility function. - // Ensure it's in the framebuffer cache. - if (std::find(fbCache_.begin(), fbCache_.end(), framebuffer) == fbCache_.end()) { - // TODO: This is kind of silly. We should probably simply share this list of framebuffers - // with the framebuffer manager. - WARN_LOG(G3D, "TextureCache got info about new framebuffer, at %08x", address); - fbCache_.push_back(framebuffer); - } - std::vector candidates; // TODO: Rework this to not try to "apply" all matches, only the best one. @@ -810,8 +805,6 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram break; } case NOTIFY_FB_DESTROYED: - fbCache_.erase(std::remove(fbCache_.begin(), fbCache_.end(), framebuffer), fbCache_.end()); - // We may have an offset texture attached. So we use fbTexInfo as a guide. // We're not likely to have many attached framebuffers. for (auto it = fbTexInfo_.begin(); it != fbTexInfo_.end(); ) { @@ -1205,8 +1198,9 @@ void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) { static const u32 MAX_CLUT_OFFSET = 4096; clutRenderOffset_ = MAX_CLUT_OFFSET; - for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { - auto framebuffer = fbCache_[i]; + auto framebuffers = framebufferManager_->Framebuffers(); + for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { + auto framebuffer = framebuffers[i]; const u32 fb_address = framebuffer->fb_address & 0x3FFFFFFF; const u32 bpp = framebuffer->drawnFormat == GE_FORMAT_8888 ? 4 : 2; u32 offset = clutFramebufAddr - fb_address; diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 4a90489bd0..37836c2f74 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -340,9 +340,7 @@ protected: TexCache secondCache_; u32 secondCacheSizeEstimate_; - std::vector fbCache_; std::map fbTexInfo_; - std::map videos_; SimpleBuf tmpTexBuf32_; From 766bd8e6bb182f4ef6523083efaea251114cd646 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sat, 12 Sep 2020 19:00:03 +0800 Subject: [PATCH 679/848] Don't read data more than data size of pgd files. --- Core/HLE/sceIo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 9316bae16f..e9b76785b9 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -967,6 +967,8 @@ static u32 npdrmRead(FileNode *f, u8 *data, int size) { block = pgd->file_offset/pgd->block_size; offset = pgd->file_offset%pgd->block_size; + if (size > pgd->data_size) + size = pgd->data_size; remain_size = size; while(remain_size){ From fbea8f438df4bef4b56399c7d6dd529c9ab0ce96 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sat, 12 Sep 2020 19:45:25 +0800 Subject: [PATCH 680/848] Update symbol list of disassembly window when loadexec. --- Core/HLE/sceKernelModule.cpp | 2 ++ Core/Host.h | 1 + Qt/QtHost.h | 3 +++ UI/HostTypes.h | 1 + UWP/UWPHost.cpp | 4 ++++ UWP/UWPHost.h | 1 + Windows/WindowsHost.cpp | 5 +++++ Windows/WindowsHost.h | 1 + headless/StubHost.h | 1 + 9 files changed, 19 insertions(+) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 3f34ea3d38..34b3a9bc3c 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1743,6 +1743,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str return false; } + host->NotifySymbolMapUpdated(); + mipsr4k.pc = module->nm.entry_addr; INFO_LOG(LOADER, "Module entry: %08x", mipsr4k.pc); diff --git a/Core/Host.h b/Core/Host.h index 2fd79e9510..35838c8083 100644 --- a/Core/Host.h +++ b/Core/Host.h @@ -48,6 +48,7 @@ public: virtual bool IsDebuggingEnabled() {return true;} virtual bool AttemptLoadSymbolMap(); virtual void SaveSymbolMap() {} + virtual void NotifySymbolMapUpdated() {} virtual void SetWindowTitle(const char *message) {} virtual bool CanCreateShortcut() {return false;} diff --git a/Qt/QtHost.h b/Qt/QtHost.h index 1a15740806..e0c7ef4b7e 100644 --- a/Qt/QtHost.h +++ b/Qt/QtHost.h @@ -67,6 +67,9 @@ public: auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart); return g_symbolMap->LoadSymbolMap(fn.c_str()); } + + virtual void NotifySymbolMapUpdated() override { g_symbolMap->SortSymbols(); } + void PrepareShutdown() { auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart); g_symbolMap->SaveSymbolMap(fn.c_str()); diff --git a/UI/HostTypes.h b/UI/HostTypes.h index e489aa668d..134c808862 100644 --- a/UI/HostTypes.h +++ b/UI/HostTypes.h @@ -43,6 +43,7 @@ public: bool IsDebuggingEnabled() override {return false;} bool AttemptLoadSymbolMap() override {return false;} + void NotifySymbolMapUpdated() override {} void SetWindowTitle(const char *message) override {} void NotifyUserMessage(const std::string &message, float duration = 1.0f, u32 color = 0x00FFFFFF, const char *id = nullptr) override { diff --git a/UWP/UWPHost.cpp b/UWP/UWPHost.cpp index 49bc413d4f..5edd05cd3b 100644 --- a/UWP/UWPHost.cpp +++ b/UWP/UWPHost.cpp @@ -158,6 +158,10 @@ void UWPHost::SaveSymbolMap() { g_symbolMap->SaveSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart.c_str(), ".ppmap").c_str()); } +void UWPHost::NotifySymbolMapUpdated() { + g_symbolMap->SortSymbols(); +} + bool UWPHost::IsDebuggingEnabled() { return false; } diff --git a/UWP/UWPHost.h b/UWP/UWPHost.h index 597886189e..3c70db9991 100644 --- a/UWP/UWPHost.h +++ b/UWP/UWPHost.h @@ -30,6 +30,7 @@ public: void BootDone() override; bool AttemptLoadSymbolMap() override; void SaveSymbolMap() override; + void NotifySymbolMapUpdated() override; void SetWindowTitle(const char *message) override; void ToggleDebugConsoleVisibility() override; diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index e197877ce7..48b79bde30 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -312,6 +312,11 @@ void WindowsHost::SaveSymbolMap() { g_symbolMap->SaveSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart.c_str(),".ppmap").c_str()); } +void WindowsHost::NotifySymbolMapUpdated() { + g_symbolMap->SortSymbols(); + PostMessage(mainWindow_, WM_USER + 1, 0, 0); +} + bool WindowsHost::IsDebuggingEnabled() { #ifdef _DEBUG return true; diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h index 7c96fe6631..581a8064d3 100644 --- a/Windows/WindowsHost.h +++ b/Windows/WindowsHost.h @@ -52,6 +52,7 @@ public: void BootDone() override; bool AttemptLoadSymbolMap() override; void SaveSymbolMap() override; + void NotifySymbolMapUpdated() override; void SetWindowTitle(const char *message) override; void ToggleDebugConsoleVisibility() override; diff --git a/headless/StubHost.h b/headless/StubHost.h index d6498e2b0f..8ac54ddff8 100644 --- a/headless/StubHost.h +++ b/headless/StubHost.h @@ -44,6 +44,7 @@ public: bool IsDebuggingEnabled() override { return false; } bool AttemptLoadSymbolMap() override { g_symbolMap->Clear(); return false; } + void NotifySymbolMapUpdated() override {} bool ShouldSkipUI() override { return true; } From 41eee6a1a4eac367315672e389306c01c8636952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 12 Sep 2020 14:25:50 +0200 Subject: [PATCH 681/848] Decouple framebuffers from texcache entries entirely. --- GPU/Common/TextureCacheCommon.cpp | 373 +++++++++--------------------- GPU/Common/TextureCacheCommon.h | 54 +++-- GPU/D3D11/TextureCacheD3D11.cpp | 19 +- GPU/D3D11/TextureCacheD3D11.h | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 17 +- GPU/Directx9/TextureCacheDX9.h | 2 +- GPU/GLES/TextureCacheGLES.cpp | 17 +- GPU/GLES/TextureCacheGLES.h | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 34 +-- GPU/Vulkan/TextureCacheVulkan.h | 2 +- 10 files changed, 169 insertions(+), 353 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 1f23c012a0..34b47a277e 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -99,12 +99,9 @@ inline int dimHeight(u16 dim) { // TODO TextureCacheCommon::TextureCacheCommon(Draw::DrawContext *draw) : draw_(draw), - clearCacheNextFrame_(false), - lowMemoryMode_(false), texelsScaledThisFrame_(0), cacheSizeEstimate_(0), secondCacheSizeEstimate_(0), - nextTexture_(nullptr), clutLastFormat_(0xFFFFFFFF), clutTotalBytes_(0), clutMaxBytes_(0), @@ -134,18 +131,6 @@ TextureCacheCommon::~TextureCacheCommon() { FreeAlignedMemory(clutBufRaw_); } -int TextureCacheCommon::AttachedDrawingHeight() { - if (nextTexture_) { - if (nextTexture_->framebuffer) { - return nextTexture_->framebuffer->height; - } - u16 dim = nextTexture_->dim; - const u8 dimY = dim >> 8; - return 1 << dimY; - } - return 0; -} - // Produces a signed 1.23.8 value. static int TexLog2(float delta) { union FloatBits { @@ -262,10 +247,6 @@ void TextureCacheCommon::UpdateSamplingParams(TexCacheEntry &entry, SamplerCache break; } } - - if (entry.framebuffer) { - WARN_LOG_REPORT_ONCE(wrongFramebufAttach, G3D, "Framebuffer still attached in UpdateSamplingParams()?"); - } } void TextureCacheCommon::UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode) { @@ -314,8 +295,7 @@ void TextureCacheCommon::UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode) } } - -void TextureCacheCommon::SetTexture(bool force) { +TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { #ifdef DEBUG_TEXTURES if (SetDebugTexture()) { // A different texture was bound, let's rebind next time. @@ -335,7 +315,7 @@ void TextureCacheCommon::SetTexture(bool force) { if (!Memory::IsValidAddress(texaddr)) { // Bind a null texture and return. Unbind(); - return; + return nullptr; } const u16 dim = gstate.getTextureDimension(level); @@ -386,21 +366,10 @@ void TextureCacheCommon::SetTexture(bool force) { bool match = entry->Matches(dim, format, maxLevel); const char *reason = "different params"; - // Check for FBO - slow! - if (entry->framebuffer) { - if (match) { - if (hasClut && clutRenderAddress_ != 0xFFFFFFFF) { - WARN_LOG_REPORT_ONCE(clutAndTexRender, G3D, "Using rendered texture with rendered CLUT: texfmt=%d, clutfmt=%d", gstate.getTextureFormat(), gstate.getClutPaletteFormat()); - } - - SetTextureFramebuffer(entry, entry->framebuffer); - return; - } else { - // Make sure we re-evaluate framebuffers. - DetachFramebuffer(entry, texaddr, entry->framebuffer, (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR); - reason = "detached framebuf"; - match = false; - } + // Check for FBO changes. + if (entry->status & TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP) { + // Fall through to the end where we'll delete the entry if there's a framebuffer. + match = false; } bool rehash = entry->GetHashStatus() == TexCacheEntry::STATUS_UNRELIABLE; @@ -463,7 +432,7 @@ void TextureCacheCommon::SetTexture(bool force) { if (match) { // TODO: Mark the entry reliable if it's been safe for long enough? - //got one! + // got one! gstate_c.curTextureWidth = w; gstate_c.curTextureHeight = h; if (rehash) { @@ -479,14 +448,38 @@ void TextureCacheCommon::SetTexture(bool force) { // Might need a rebuild if the hash fails, but that will be set later. nextNeedsRebuild_ = false; VERBOSE_LOG(G3D, "Texture at %08x Found in Cache, applying", texaddr); - return; //Done! + return entry; //Done! } else { // Wasn't a match, we will rebuild. nextChangeReason_ = reason; nextNeedsChange_ = true; + // Fall through to the rebuild case. } - } else { - VERBOSE_LOG(G3D, "No texture in cache, decoding..."); + } + + // No texture found, or changed (depending on entry). + // Check for framebuffers. + + TextureDefinition def{}; + def.addr = texaddr; + def.dim = dim; + def.format = format; + def.bufw = bufw; + + std::vector candidates = GetFramebufferCandidates(def, 0); + if (candidates.size() > 0) { + int index = GetBestCandidateIndex(candidates); + if (index != -1) { + nextTexture_ = nullptr; + SetTextureFramebuffer(candidates[index]); + return nullptr; + } + } + + // Didn't match a framebuffer, keep going. + + if (!entry) { + VERBOSE_LOG(G3D, "No texture in cache for %08x, decoding...", texaddr); TexCacheEntry *entryNew = new TexCacheEntry{}; cache_[cachekey].reset(entryNew); @@ -539,78 +532,48 @@ void TextureCacheCommon::SetTexture(bool force) { gstate_c.curTextureWidth = w; gstate_c.curTextureHeight = h; - // Before we go reading the texture from memory, let's check for render-to-texture. - // We must do this early so we have the right w/h. - entry->framebuffer = nullptr; - if (Memory::IsDepthTexVRAMAddress(texaddr)) { - entry->status |= TexCacheEntry::STATUS_DEPTH; - } - - AttachFramebufferToEntry(entry, 0); - - // If we ended up with a framebuffer, attach it - no texture decoding needed. - if (entry->framebuffer) { - SetTextureFramebuffer(entry, entry->framebuffer); - } - nextTexture_ = entry; - nextNeedsRehash_ = entry->framebuffer == nullptr; + nextNeedsRehash_ = false; // We still need to rebuild, to allocate a texture. But we'll bail early. nextNeedsRebuild_ = true; + return entry; } -bool TextureCacheCommon::AttachFramebufferToEntry(TexCacheEntry *entry, u32 texAddrOffset) { +std::vector TextureCacheCommon::GetFramebufferCandidates(const TextureDefinition &entry, u32 texAddrOffset) { bool success = false; bool anyIgnores = false; std::vector candidates; - std::vector detaches; - FramebufferNotificationChannel channel = (entry->status & TexCacheEntry::STATUS_DEPTH) ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR; + FramebufferNotificationChannel channel = Memory::IsDepthTexVRAMAddress(entry.addr) ? FramebufferNotificationChannel::NOTIFY_FB_DEPTH : FramebufferNotificationChannel::NOTIFY_FB_COLOR; auto framebuffers = framebufferManager_->Framebuffers(); for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { auto framebuffer = framebuffers[i]; uint32_t fb_addr = channel == NOTIFY_FB_DEPTH ? framebuffer->z_address : framebuffer->fb_address; - FramebufferMatchInfo match = MatchFramebuffer(entry, fb_addr, framebuffer, texAddrOffset, channel); + FramebufferMatchInfo match = MatchFramebuffer(entry, fb_addr, framebuffer, 0, channel); if (match.match == FramebufferMatch::IGNORE) { anyIgnores = true; - } else if (match.match == FramebufferMatch::NO_MATCH) { - detaches.push_back(AttachCandidate{ match, entry, framebuffer, channel }); - } else { + } else if (match.match != FramebufferMatch::NO_MATCH) { candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); } } - // If this is set, we want to defer the decision, apparently. - if (!anyIgnores) { - // If not set, always detach. They may affect inexact matches. - for (AttachCandidate &candidate : detaches) { - DetachFramebuffer(entry, entry->addr, candidate.fb, channel); - } - } - - if (!candidates.size()) { - // No candidates at all. - return false; - } - if (candidates.size() > 1) { bool depth = channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH; - WARN_LOG_REPORT_ONCE(multifbcandidate, G3D, "AttachFramebufferToEntry(%s): Multiple (%d) candidate framebuffers. texaddr: %08x offset: %d (%dx%d stride %d, %s)", - depth ? "DEPTH" : "COLOR", (int)candidates.size(), entry->addr, texAddrOffset, dimWidth(entry->dim), dimHeight(entry->dim), entry->bufw, GeTextureFormatToString((GETextureFormat)entry->format)); + WARN_LOG_REPORT_ONCE(multifbcandidate, G3D, "GetFramebufferCandidates(%s): Multiple (%d) candidate framebuffers. texaddr: %08x offset: %d (%dx%d stride %d, %s)", + depth ? "DEPTH" : "COLOR", (int)candidates.size(), entry.addr, texAddrOffset, dimWidth(entry.dim), dimHeight(entry.dim), entry.bufw, GeTextureFormatToString(entry.format)); } - return AttachBestCandidate(candidates); + return candidates; } -bool TextureCacheCommon::AttachBestCandidate(const std::vector &candidates) { +int TextureCacheCommon::GetBestCandidateIndex(const std::vector &candidates) { _dbg_assert_(!candidates.empty()); if (candidates.size() == 1) { - VirtualFramebuffer *framebuffer = candidates[0].fb; - return ApplyFramebufferMatch(candidates[0].match, candidates[0].entry, framebuffer->fb_address, framebuffer, candidates[0].channel); + return 0; } // OK, multiple possible candidates. Will need to figure out which one is the most relevant. @@ -631,7 +594,7 @@ bool TextureCacheCommon::AttachBestCandidate(const std::vector } // Bonus point for matching stride. - if (candidate.channel == NOTIFY_FB_COLOR && candidate.fb->fb_stride == candidate.entry->bufw) { + if (candidate.channel == NOTIFY_FB_COLOR && candidate.fb->fb_stride == candidate.entry.bufw) { relevancy += 10; } @@ -646,8 +609,7 @@ bool TextureCacheCommon::AttachBestCandidate(const std::vector } } - VirtualFramebuffer *framebuffer = candidates[bestIndex].fb; - return ApplyFramebufferMatch(candidates[bestIndex].match, candidates[bestIndex].entry, framebuffer->fb_address, framebuffer, candidates[bestIndex].channel); + return bestIndex; } // Removes old textures. @@ -774,11 +736,8 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram if (channel == FramebufferNotificationChannel::NOTIFY_FB_COLOR) { // Color - no need to look in the mirrors. for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { - TexCacheEntry *entry = it->second.get(); - FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); - if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { - candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); - } + // Just mark them all dirty somehow. + it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; } } else { // Depth. Just look in the mirrors. @@ -786,135 +745,25 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram const u64 mirrorlessKey = it->first & ~0x0060000000000000ULL; // Let's still make sure it's in the cache range. if (mirrorlessKey >= cacheKey && mirrorlessKey <= cacheKeyEnd) { - TexCacheEntry *entry = it->second.get(); - FramebufferMatchInfo match = MatchFramebuffer(entry, addr, framebuffer, 0, channel); - if (match.match != FramebufferMatch::IGNORE && match.match != FramebufferMatch::NO_MATCH) { - candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); - } + // Just mark them all dirty somehow. + it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; } } } - - if (!candidates.empty()) { - // There can actually be multiple ones to update here! This can be the case where two textures point to different framebuffers that share depth buffers. - // So we have no choice but to run all the matches. - for (int i = 0; i < (int)candidates.size(); i++) { - ApplyFramebufferMatch(candidates[i].match, candidates[i].entry, framebuffer->fb_address, framebuffer, candidates[i].channel); - } - } break; } - case NOTIFY_FB_DESTROYED: - // We may have an offset texture attached. So we use fbTexInfo as a guide. - // We're not likely to have many attached framebuffers. - for (auto it = fbTexInfo_.begin(); it != fbTexInfo_.end(); ) { - u64 cachekey = it->first; - // We might erase, so move to the next one already (which won't become invalid.) - ++it; - - DetachFramebuffer(cache_[cachekey].get(), addr, framebuffer, channel); - } - break; } } -void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel) { - _dbg_assert_((fbInfo.match == FramebufferMatch::VALID) || (fbInfo.match == FramebufferMatch::VALID_DEPAL)); - const u64 cachekey = entry->CacheKey(); - const bool hasInvalidFramebuffer = entry->framebuffer == nullptr || entry->invalidHint == -1; - const bool hasOlderFramebuffer = entry->framebuffer != nullptr && entry->framebuffer->last_frame_render < framebuffer->last_frame_render; - bool hasFartherFramebuffer = false; - - if (!hasInvalidFramebuffer && !hasOlderFramebuffer) { - // If it's valid, but the offset is greater, then we still win. - // TODO: This check should probably be moved to MatchFramebuffer somehow. - if (fbTexInfo_[cachekey].yOffset == fbInfo.yOffset) - hasFartherFramebuffer = fbTexInfo_[cachekey].xOffset > fbInfo.xOffset; - else - hasFartherFramebuffer = fbTexInfo_[cachekey].yOffset > fbInfo.yOffset; - } - - if (hasInvalidFramebuffer || hasOlderFramebuffer || hasFartherFramebuffer) { - if (entry->framebuffer == nullptr) { - cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry); - } - ReleaseTexture(entry, true); - - entry->framebuffer = framebuffer; - entry->invalidHint = 0; - entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; - entry->maxLevel = 0; - fbTexInfo_[cachekey] = fbInfo; - framebuffer->last_frame_attached = gpuStats.numFlips; - GPUDebug::NotifyTextureAttachment(entry->addr); - } else if (entry->framebuffer == framebuffer) { - framebuffer->last_frame_attached = gpuStats.numFlips; - } -} - -void TextureCacheCommon::AttachFramebufferInexact(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel) { - _dbg_assert_(fbInfo.match == FramebufferMatch::INEXACT); - const u64 cachekey = entry->CacheKey(); - - if (entry->framebuffer == nullptr || entry->framebuffer == framebuffer) { - if (entry->framebuffer == nullptr) { - cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry); - } - ReleaseTexture(entry, true); - entry->framebuffer = framebuffer; - entry->invalidHint = -1; - entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; - entry->maxLevel = 0; - fbTexInfo_[cachekey] = fbInfo; - GPUDebug::NotifyTextureAttachment(entry->addr); - } -} - -void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel) { - if (entry->framebuffer == framebuffer) { - const u64 cachekey = entry->CacheKey(); - cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); - entry->framebuffer = nullptr; - // Force recreate the texture in case we had one before and the hash matches. - // Otherwise we never recreate the texture. - entry->status |= TexCacheEntry::STATUS_FORCE_REBUILD; - fbTexInfo_.erase(cachekey); - GPUDebug::NotifyTextureAttachment(entry->addr); - InvalidateLastTexture(entry); - } -} - -bool TextureCacheCommon::ApplyFramebufferMatch(FramebufferMatchInfo match, TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel) { - // There were five possible outcomes of the old ApplyFramebuffer, these have been - // mapped to the FramebufferMatch enum, and we handle them the same old ways here. - switch (match.match) { - case FramebufferMatch::VALID: - AttachFramebufferValid(entry, framebuffer, match, channel); - return true; - case FramebufferMatch::VALID_DEPAL: - AttachFramebufferValid(entry, framebuffer, match, channel); - entry->status |= TexCacheEntry::STATUS_DEPALETTIZE; - return true; - case FramebufferMatch::INEXACT: - AttachFramebufferInexact(entry, framebuffer, match, channel); - return true; - case FramebufferMatch::NO_MATCH: - DetachFramebuffer(entry, address, framebuffer, channel); - return false; - case FramebufferMatch::IGNORE: - // The purpose of this seems to be to delay a decision to the next frame. - default: - return false; - } -} - -FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, u32 fb_address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const { +FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer( + const TextureDefinition &entry, + u32 fb_address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const { static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32; const u32 mirrorMask = 0x00600000; u32 addr = fb_address & 0x3FFFFFFF; - u32 texaddr = entry->addr + texaddrOffset; + u32 texaddr = entry.addr + texaddrOffset; bool texInVRAM = Memory::IsVRAMAddress(texaddr); bool fbInVRAM = Memory::IsVRAMAddress(fb_address); @@ -930,7 +779,7 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, // to the bpp of the color format used when rendering to it). // It's fairly unlikely that games would screw this up since the result will be garbage so // we use it to filter out unlikely matches. - switch (entry->addr & mirrorMask) { + switch (entry.addr & mirrorMask) { case 0x00000000: case 0x00400000: // Don't match the depth channel with these addresses when texturing. @@ -953,20 +802,20 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, } const bool noOffset = texaddr == addr; - const bool exactMatch = noOffset && entry->format < 4 && channel == NOTIFY_FB_COLOR; - const u32 w = 1 << ((entry->dim >> 0) & 0xf); - const u32 h = 1 << ((entry->dim >> 8) & 0xf); + const bool exactMatch = noOffset && entry.format < 4 && channel == NOTIFY_FB_COLOR; + const u32 w = 1 << ((entry.dim >> 0) & 0xf); + const u32 h = 1 << ((entry.dim >> 8) & 0xf); // 512 on a 272 framebuffer is sane, so let's be lenient. const u32 minSubareaHeight = h / 4; // If they match "exactly", it's non-CLUT and from the top left. if (exactMatch) { - if (framebuffer->fb_stride != entry->bufw) { - WARN_LOG_ONCE(diffStrides1, G3D, "Texturing from framebuffer with different strides %d != %d", entry->bufw, framebuffer->fb_stride); + if (framebuffer->fb_stride != entry.bufw) { + WARN_LOG_ONCE(diffStrides1, G3D, "Texturing from framebuffer with different strides %d != %d", entry.bufw, framebuffer->fb_stride); } // NOTE: This check is okay because the first texture formats are the same as the buffer formats. - if (entry->format != (GETextureFormat)framebuffer->format) { - WARN_LOG_ONCE(diffFormat1, G3D, "Texturing from framebuffer with different formats %s != %s", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format)); + if (entry.format != (GETextureFormat)framebuffer->format) { + WARN_LOG_ONCE(diffFormat1, G3D, "Texturing from framebuffer with different formats %s != %s", GeTextureFormatToString(entry.format), GeBufferFormatToString(framebuffer->format)); // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. // However, some games use a different format to clear the buffer. if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) { @@ -988,21 +837,21 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, // Check works for D16 too (???) const bool matchingClutFormat = - (channel != NOTIFY_FB_COLOR && entry->format == GE_TFMT_CLUT16) || - (channel == NOTIFY_FB_COLOR && framebuffer->format == GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT32) || - (channel == NOTIFY_FB_COLOR && framebuffer->format != GE_FORMAT_8888 && entry->format == GE_TFMT_CLUT16); + (channel != NOTIFY_FB_COLOR && entry.format == GE_TFMT_CLUT16) || + (channel == NOTIFY_FB_COLOR && framebuffer->format == GE_FORMAT_8888 && entry.format == GE_TFMT_CLUT32) || + (channel == NOTIFY_FB_COLOR && framebuffer->format != GE_FORMAT_8888 && entry.format == GE_TFMT_CLUT16); - const bool clutFormat = IsClutFormat((GETextureFormat)(entry->format)); + const bool clutFormat = IsClutFormat((GETextureFormat)(entry.format)); // To avoid ruining git blame, kept the same name as the old struct. FramebufferMatchInfo fbInfo{ FramebufferMatch::VALID }; const u32 bitOffset = (texaddr - addr) * 8; if (bitOffset != 0) { - const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry->format]); + const u32 pixelOffset = bitOffset / std::max(1U, (u32)textureBitsPerPixel[entry.format]); - fbInfo.yOffset = entry->bufw == 0 ? 0 : pixelOffset / entry->bufw; - fbInfo.xOffset = entry->bufw == 0 ? 0 : pixelOffset % entry->bufw; + fbInfo.yOffset = entry.bufw == 0 ? 0 : pixelOffset / entry.bufw; + fbInfo.xOffset = entry.bufw == 0 ? 0 : pixelOffset % entry.bufw; } if (fbInfo.yOffset + minSubareaHeight >= framebuffer->height) { @@ -1010,9 +859,9 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } - if (framebuffer->fb_stride != entry->bufw) { + if (framebuffer->fb_stride != entry.bufw) { if (noOffset) { - WARN_LOG_ONCE(diffStrides2, G3D, "Texturing from framebuffer (matching_clut=%s) different strides %d != %d", matchingClutFormat ? "yes" : "no", entry->bufw, framebuffer->fb_stride); + WARN_LOG_ONCE(diffStrides2, G3D, "Texturing from framebuffer (matching_clut=%s) different strides %d != %d", matchingClutFormat ? "yes" : "no", entry.bufw, framebuffer->fb_stride); // Continue on with other checks. // Not actually sure why we even try here. There's no way it'll go well if the strides are different. } else { @@ -1042,16 +891,16 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, } fbInfo.match = FramebufferMatch::VALID_DEPAL; return fbInfo; - } else if (IsClutFormat((GETextureFormat)(entry->format)) || IsDXTFormat((GETextureFormat)(entry->format))) { - WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffer of format %s", GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format)); + } else if (IsClutFormat((GETextureFormat)(entry.format)) || IsDXTFormat((GETextureFormat)(entry.format))) { + WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffer of format %s", GeTextureFormatToString(entry.format), GeBufferFormatToString(framebuffer->format)); return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } // This is either normal or we failed to generate a shader to depalettize - if (framebuffer->format == entry->format || matchingClutFormat) { - if (framebuffer->format != entry->format) { + if (framebuffer->format == entry.format || matchingClutFormat) { + if (framebuffer->format != entry.format) { WARN_LOG_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", - GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), fb_address); + GeTextureFormatToString(entry.format), GeBufferFormatToString(framebuffer->format), fb_address); return fbInfo; // Valid! } else { WARN_LOG_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset); @@ -1061,20 +910,20 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer(TexCacheEntry *entry, } } else { WARN_LOG_ONCE(diffFormat2, G3D, "Texturing from framebuffer with incompatible format %s != %s at %08x", - GeTextureFormatToString((GETextureFormat)entry->format), GeBufferFormatToString(framebuffer->format), fb_address); + GeTextureFormatToString(entry.format), GeBufferFormatToString(framebuffer->format), fb_address); return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } } } -void TextureCacheCommon::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) { +void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate) { + VirtualFramebuffer *framebuffer = candidate.fb; + FramebufferMatchInfo fbInfo = candidate.match; + _dbg_assert_msg_(framebuffer != nullptr, "Framebuffer must not be null."); framebuffer->usageFlags |= FB_USAGE_TEXTURE; if (framebufferManager_->UseBufferedRendering()) { - const u64 cachekey = entry->CacheKey(); - const auto &fbInfo = fbTexInfo_[cachekey]; - // Keep the framebuffer alive. framebuffer->last_frame_used = gpuStats.numFlips; @@ -1096,7 +945,8 @@ void TextureCacheCommon::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram gstate_c.SetNeedShaderTexclamp(true); } - nextTexture_ = entry; + nextTexture_ = nullptr; + nextFramebufferTexture_ = framebuffer; } else { if (framebuffer->fbo) { framebuffer->fbo->Release(); @@ -1111,6 +961,7 @@ void TextureCacheCommon::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram nextNeedsRebuild_ = false; } +// Only looks for framebuffers. bool TextureCacheCommon::SetOffsetTexture(u32 yOffset) { if (!framebufferManager_->UseBufferedRendering()) { return false; @@ -1125,22 +976,20 @@ bool TextureCacheCommon::SetOffsetTexture(u32 yOffset) { return false; } - const u16 dim = gstate.getTextureDimension(0); - u64 cachekey = TexCacheEntry::CacheKey(texaddr, fmt, dim, 0); - TexCache::iterator iter = cache_.find(cachekey); - if (iter == cache_.end()) { - return false; + TextureDefinition def; + def.addr = texaddr; + def.format = fmt; + def.bufw = GetTextureBufw(0, texaddr, fmt); + def.dim = gstate.getTextureDimension(0); + + std::vector candidates = GetFramebufferCandidates(def, texaddrOffset); + if (candidates.size() > 0) { + int index = GetBestCandidateIndex(candidates); + if (index != -1) { + SetTextureFramebuffer(candidates[index]); + return true; + } } - TexCacheEntry *entry = iter->second.get(); - - bool success = AttachFramebufferToEntry(entry, texaddrOffset); - - if (success && entry->framebuffer) { - // This will not apply the texture immediately. - SetTextureFramebuffer(entry, entry->framebuffer); - return true; - } - return false; } @@ -1710,8 +1559,15 @@ void TextureCacheCommon::ReadIndexedTex(u8 *out, int outPitch, int level, const void TextureCacheCommon::ApplyTexture() { TexCacheEntry *entry = nextTexture_; if (entry == nullptr) { + // Maybe we bound a framebuffer? + if (nextFramebufferTexture_) { + bool depth = Memory::IsDepthTexVRAMAddress(gstate.getTextureAddress(0)); + ApplyTextureFramebuffer(nextFramebufferTexture_, gstate.getTextureFormat(), depth ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR); + nextFramebufferTexture_ = nullptr; + } return; } + nextTexture_ = nullptr; UpdateMaxSeenV(entry, gstate.isModeThrough()); @@ -1761,12 +1617,8 @@ void TextureCacheCommon::ApplyTexture() { } entry->lastFrame = gpuStats.numFlips; - if (entry->framebuffer) { - ApplyTextureFramebuffer(entry, entry->framebuffer); - } else { - BindTexture(entry); - gstate_c.SetTextureFullAlpha(entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL); - } + BindTexture(entry); + gstate_c.SetTextureFullAlpha(entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL); } void TextureCacheCommon::Clear(bool delete_them) { @@ -1785,16 +1637,11 @@ void TextureCacheCommon::Clear(bool delete_them) { cacheSizeEstimate_ = 0; secondCacheSizeEstimate_ = 0; } - fbTexInfo_.clear(); videos_.clear(); } void TextureCacheCommon::DeleteTexture(TexCache::iterator it) { ReleaseTexture(it->second.get(), true); - auto fbInfo = fbTexInfo_.find(it->first); - if (fbInfo != fbTexInfo_.end()) { - fbTexInfo_.erase(fbInfo); - } cacheSizeEstimate_ -= EstimateTexMemoryUsage(it->second.get()); cache_.erase(it); } @@ -1923,7 +1770,7 @@ void TextureCacheCommon::Invalidate(u32 addr, int size, GPUInvalidationType type } } iter->second->framesUntilNextFullHash = 0; - } else if (!iter->second->framebuffer) { + } else { iter->second->invalidHint++; } } @@ -1945,9 +1792,7 @@ void TextureCacheCommon::InvalidateAll(GPUInvalidationType /*unused*/) { if (iter->second->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) { iter->second->SetHashStatus(TexCacheEntry::STATUS_HASHING); } - if (!iter->second->framebuffer) { - iter->second->invalidHint++; - } + iter->second->invalidHint++; } } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 37836c2f74..2bdaffd15f 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -93,7 +93,19 @@ struct SamplerCacheKey { class GLRTexture; class VulkanTexture; +// Enough information about a texture to match it to framebuffers. +struct TextureDefinition { + u32 addr; + GETextureFormat format; + u32 dim; + u32 bufw; +}; + + // TODO: Shrink this struct. There is some fluff. + +// NOTE: These only handle textures loaded directly from PSP memory contents. +// Framebuffer textures do not have entries, we bind the framebuffers directly. struct TexCacheEntry { ~TexCacheEntry() { if (texturePtr || textureName || vkTex) @@ -115,7 +127,6 @@ struct TexCacheEntry { STATUS_CLUT_VARIANTS = 0x08, // Has multiple CLUT variants. STATUS_CHANGE_FREQUENT = 0x10, // Changes often (less than 6 frames in between.) STATUS_CLUT_RECHECK = 0x20, // Another texture with same addr had a hashfail. - STATUS_DEPALETTIZE = 0x40, // Needs to go through a depalettize pass. STATUS_TO_SCALE = 0x80, // Pending texture scaling in a later frame. STATUS_IS_SCALED = 0x100, // Has been scaled (can't be replaceImages'd.) // When hashing large textures, we optimize 512x512 down to 512x272 by default, since this @@ -125,7 +136,8 @@ struct TexCacheEntry { STATUS_BAD_MIPS = 0x400, // Has bad or unusable mipmap levels. - STATUS_DEPTH = 0x800, + STATUS_FRAMEBUFFER_OVERLAP = 0x800, + STATUS_FORCE_REBUILD = 0x1000, }; @@ -134,7 +146,6 @@ struct TexCacheEntry { u32 addr; u32 hash; - VirtualFramebuffer *framebuffer; // if null, not sourced from an FBO. TODO: Collapse into texturePtr u32 sizeInRAM; // Could be computed u8 format; // GeTextureFormat u8 maxLevel; @@ -181,8 +192,7 @@ struct TexCacheEntry { static u64 CacheKey(u32 addr, u8 format, u16 dim, u32 cluthash); }; -class FramebufferManagerCommon; -// Can't be unordered_map, we use lower_bound ... although for some reason that compiles on MSVC. +// Can't be unordered_map, we use lower_bound ... although for some reason that (used to?) compiles on MSVC. // Would really like to replace this with DenseHashMap but can't as long as we need lower_bound. typedef std::map> TexCache; @@ -214,11 +224,13 @@ struct FramebufferMatchInfo { struct AttachCandidate { FramebufferMatchInfo match; - TexCacheEntry *entry; + TextureDefinition entry; VirtualFramebuffer *fb; FramebufferNotificationChannel channel; }; +class FramebufferManagerCommon; + class TextureCacheCommon { public: TextureCacheCommon(Draw::DrawContext *draw); @@ -227,7 +239,7 @@ public: void LoadClut(u32 clutAddr, u32 loadBytes); bool GetCurrentClutBuffer(GPUDebugBuffer &buffer); - void SetTexture(bool force = false); + TexCacheEntry *SetTexture(bool force = false); void ApplyTexture(); bool SetOffsetTexture(u32 yOffset); void Invalidate(u32 addr, int size, GPUInvalidationType type); @@ -243,8 +255,6 @@ public: virtual void NotifyConfigChanged(); void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt); - int AttachedDrawingHeight(); - size_t NumLoadedTextures() const { return cache_.size(); } @@ -264,7 +274,8 @@ protected: void DeleteTexture(TexCache::iterator it); void Decimate(bool forcePressure = false); - virtual void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) = 0; + virtual void ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) = 0; + void HandleTextureChange(TexCacheEntry *const entry, const char *reason, bool initialMatch, bool doDelete); virtual void BuildTexture(TexCacheEntry *const entry) = 0; virtual void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) = 0; @@ -284,19 +295,12 @@ protected: void UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key); // Used by D3D11 and Vulkan. void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode); - FramebufferMatchInfo MatchFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; + FramebufferMatchInfo MatchFramebuffer(const TextureDefinition &entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; - bool AttachFramebufferToEntry(TexCacheEntry *entry, u32 texAddrOffset); + std::vector GetFramebufferCandidates(const TextureDefinition &entry, u32 texAddrOffset); + int GetBestCandidateIndex(const std::vector &candidates); - // Temporary utility during conversion - bool ApplyFramebufferMatch(FramebufferMatchInfo match, TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel); - bool AttachBestCandidate(const std::vector &candidates); - - void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); - void AttachFramebufferInexact(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const FramebufferMatchInfo &fbInfo, FramebufferNotificationChannel channel); - void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, FramebufferNotificationChannel channel); - - void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer); + void SetTextureFramebuffer(const AttachCandidate &candidate); void DecimateVideos(); @@ -327,8 +331,8 @@ protected: TextureReplacer replacer_; FramebufferManagerCommon *framebufferManager_; - bool clearCacheNextFrame_; - bool lowMemoryMode_; + bool clearCacheNextFrame_ = false; + bool lowMemoryMode_ = false; int decimationCounter_; int texelsScaledThisFrame_; @@ -340,13 +344,13 @@ protected: TexCache secondCache_; u32 secondCacheSizeEstimate_; - std::map fbTexInfo_; std::map videos_; SimpleBuf tmpTexBuf32_; SimpleBuf tmpTexBufRearrange_; - TexCacheEntry *nextTexture_; + TexCacheEntry *nextTexture_ = nullptr; + VirtualFramebuffer *nextFramebufferTexture_ = nullptr; u32 clutHash_ = 0; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 9b6ad9b70c..ca1e693723 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -378,10 +378,11 @@ protected: int renderH_; }; -void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) { +void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) { ID3D11PixelShader *pshader = nullptr; uint32_t clutMode = gstate.clutformat & 0xFFFFFF; - if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { + bool need_depalettize = IsClutFormat(texFormat); + if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) { pshader = depalShaderCache_->GetDepalettizePixelShader(clutMode, framebuffer->drawnFormat); } @@ -421,8 +422,6 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra TexCacheEntry::TexStatus alphaStatus = CheckAlpha(clutBuf_, GetClutDestFormatD3D11(clutFormat), clutTotalColors, clutTotalColors, 1); gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); } else { - entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; - framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); @@ -432,7 +431,6 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey); ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey); context_->PSSetSamplers(0, 1, &state); - InvalidateLastTexture(); gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE); } @@ -444,14 +442,6 @@ void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) { // For the estimate, we assume cluts always point to 8888 for simplicity. cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); - // TODO: If a framebuffer is attached here, might end up with a bad entry.texture. - // Should just always create one here or something (like GLES.) - - if (entry->framebuffer) { - // Nothing else to do here. - return; - } - if ((entry->bufw == 0 || (gstate.texbufwidth[0] & 0xf800) != 0) && entry->addr >= PSP_GetKernelMemoryEnd()) { ERROR_LOG_REPORT(G3D, "Texture with unexpected bufw (full=%d)", gstate.texbufwidth[0] & 0xffff); // Proceeding here can cause a crash. @@ -779,7 +769,9 @@ bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level TexCacheEntry *entry = nextTexture_; ApplyTexture(); + /* // TODO: Centralize. + // TODO: Fix! if (entry->framebuffer) { VirtualFramebuffer *vfb = entry->framebuffer; buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); @@ -791,6 +783,7 @@ bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); return retval; } + */ ID3D11Texture2D *texture = (ID3D11Texture2D *)entry->texturePtr; if (!texture) diff --git a/GPU/D3D11/TextureCacheD3D11.h b/GPU/D3D11/TextureCacheD3D11.h index 8cfa249269..db154c5a77 100644 --- a/GPU/D3D11/TextureCacheD3D11.h +++ b/GPU/D3D11/TextureCacheD3D11.h @@ -74,7 +74,7 @@ private: TexCacheEntry::TexStatus CheckAlpha(const u32 *pixelData, u32 dstFmt, int stride, int w, int h); void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override; - void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override; + void ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) override; void BuildTexture(TexCacheEntry *const entry) override; ID3D11Device *device_; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index c5e70491ef..5f118f76db 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -416,10 +416,11 @@ protected: int renderH_; }; -void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) { +void TextureCacheDX9::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) { LPDIRECT3DPIXELSHADER9 pshader = nullptr; uint32_t clutMode = gstate.clutformat & 0xFFFFFF; - if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { + bool need_depalettize = IsClutFormat(texFormat); + if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) { pshader = depalShaderCache_->GetDepalettizePixelShader(clutMode, framebuffer->drawnFormat); } @@ -460,8 +461,6 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame TexCacheEntry::TexStatus alphaStatus = CheckAlpha(clutBuf_, getClutDestFormat(clutFormat), clutTotalColors, clutTotalColors, 1); gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); } else { - entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; - framebufferManagerDX9_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); @@ -469,8 +468,6 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame framebufferManagerDX9_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFromFramebuffer"); SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); - - InvalidateLastTexture(); } void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) { @@ -479,14 +476,6 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) { // For the estimate, we assume cluts always point to 8888 for simplicity. cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); - // TODO: If a framebuffer is attached here, might end up with a bad entry.texture. - // Should just always create one here or something (like GLES.) - - if (entry->framebuffer) { - // Nothing else to do here. - return; - } - if ((entry->bufw == 0 || (gstate.texbufwidth[0] & 0xf800) != 0) && entry->addr >= PSP_GetKernelMemoryEnd()) { ERROR_LOG_REPORT(G3D, "Texture with unexpected bufw (full=%d)", gstate.texbufwidth[0] & 0xffff); // Proceeding here can cause a crash. diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index 4d9b308793..a0d488c77b 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -68,7 +68,7 @@ private: TexCacheEntry::TexStatus CheckAlpha(const u32 *pixelData, u32 dstFmt, int stride, int w, int h); void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override; - void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override; + void ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) override; void BuildTexture(TexCacheEntry *const entry) override; LPDIRECT3DTEXTURE9 &DxTex(TexCacheEntry *entry) { diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 6ecfd51443..776405ba49 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -441,15 +441,16 @@ protected: int renderH_; }; -void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) { +void TextureCacheGLES::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) { DepalShader *depal = nullptr; uint32_t clutMode = gstate.clutformat & 0xFFFFFF; + bool need_depalettize = IsClutFormat(texFormat); bool useShaderDepal = framebufferManager_->GetCurrentRenderVFB() != framebuffer && gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300); if (!gstate_c.Supports(GPU_SUPPORTS_32BIT_INT_FSHADER)) { useShaderDepal = false; } - if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { + if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) { if (useShaderDepal) { const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); GLRTexture *clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_); @@ -500,8 +501,6 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram TexCacheEntry::TexStatus alphaStatus = CheckAlpha((const uint8_t *)clutBuf_, getClutDestFormat(clutFormat), clutTotalColors, clutTotalColors, 1); gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); } else { - entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; - framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); @@ -510,8 +509,6 @@ void TextureCacheGLES::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFram framebufferManagerGL_->RebindFramebuffer("ApplyTextureFramebuffer"); SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, false); - InvalidateLastTexture(); - // Since we started/ended render passes, might need these. gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } @@ -541,11 +538,6 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) { // For the estimate, we assume cluts always point to 8888 for simplicity. cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); - if (entry->framebuffer) { - // Nothing else to do here. - return; - } - // Always generate a texture name unless it's a framebuffer, we might need it if the texture is replaced later. if (!entry->textureName) { entry->textureName = render_->CreateTexture(GL_TEXTURE_2D); @@ -839,7 +831,9 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) framebufferManagerGL_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); ApplyTexture(); + /* // TODO: Centralize? + // TODO: Needs fixing! if (entry->framebuffer) { VirtualFramebuffer *vfb = entry->framebuffer; buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); @@ -853,6 +847,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) ERROR_LOG(G3D, "Failed to get debug texture: copy to memory failed"); return retval; } + */ GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index abb4d2d2fb..36e203579f 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -81,7 +81,7 @@ private: TexCacheEntry::TexStatus CheckAlpha(const uint8_t *pixelData, Draw::DataFormat dstFmt, int stride, int w, int h); void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override; - void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override; + void ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) override; void BuildTexture(TexCacheEntry *const entry) override; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 93e39d87fd..6b11ceb560 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -554,7 +554,7 @@ void TextureCacheVulkan::Unbind() { InvalidateLastTexture(); } -void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) { +void TextureCacheVulkan::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) { SamplerCacheKey samplerKey{}; SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey); @@ -562,10 +562,12 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr uint32_t clutMode = gstate.clutformat & 0xFFFFFF; bool expand32 = !gstate_c.Supports(GPU_SUPPORTS_16BIT_FORMATS); - bool depth = (entry->status & TexCacheEntry::STATUS_DEPTH) != 0; + bool depth = channel == NOTIFY_FB_DEPTH; bool useShaderDepal = framebufferManager_->GetCurrentRenderVFB() != framebuffer && !depth; - if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { + bool need_depalettize = IsClutFormat(texFormat); + + if (need_depalettize && !g_Config.bDisableSlowFramebufEffects) { if (useShaderDepal) { depalShaderCache_->SetPushBuffer(drawEngine_->GetPushBufferForTextureData()); const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); @@ -584,7 +586,6 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr TexCacheEntry::TexStatus alphaStatus = CheckAlpha(clutBuf_, getClutDestFormatVulkan(clutFormat), clutTotalColors, clutTotalColors, 1); gstate_c.SetTextureFullAlpha(alphaStatus == TexCacheEntry::STATUS_ALPHA_FULL); curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey); - InvalidateLastTexture(entry); imageView_ = framebufferManagerVulkan_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); return; } else { @@ -694,16 +695,14 @@ void TextureCacheVulkan::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFr // Since we may have switched render targets, we need to re-set depth/stencil etc states. gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); } else { - entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE; - imageView_ = framebufferManagerVulkan_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); drawEngine_->SetDepalTexture(VK_NULL_HANDLE); gstate_c.SetUseShaderDepal(false); gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); } + curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey); - InvalidateLastTexture(entry); } ReplacedTextureFormat FromVulkanFormat(VkFormat fmt) { @@ -730,11 +729,6 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { // For the estimate, we assume cluts always point to 8888 for simplicity. cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); - if (entry->framebuffer) { - // Nothing else to do here. - return; - } - if ((entry->bufw == 0 || (gstate.texbufwidth[0] & 0xf800) != 0) && entry->addr >= PSP_GetKernelMemoryEnd()) { ERROR_LOG_REPORT(G3D, "Texture with unexpected bufw (full=%d)", gstate.texbufwidth[0] & 0xffff); // Proceeding here can cause a crash. @@ -1007,16 +1001,9 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { entry->vkTex->UploadMip(cmdInit, i, mipWidth, mipHeight, localBuf, localOffset, stride / bpp); } else { - // Don't even try to read depth data. - if (entry->status & TexCacheEntry::STATUS_DEPTH) { - // Clear with a warning value (hot pink). This should not be seen - means we missed matching a framebuffer - // that a game rendered depth to. - entry->vkTex->ClearMip(cmdInit, i, 0xFFFF00FF); - } else { - data = drawEngine_->GetPushBufferForTextureData()->PushAligned(size, &bufferOffset, &texBuf, pushAlignment); - LoadTextureLevel(*entry, (uint8_t *)data, stride, i, scaleFactor, dstFmt); - entry->vkTex->UploadMip(cmdInit, i, mipWidth, mipHeight, texBuf, bufferOffset, stride / bpp); - } + data = drawEngine_->GetPushBufferForTextureData()->PushAligned(size, &bufferOffset, &texBuf, pushAlignment); + LoadTextureLevel(*entry, (uint8_t *)data, stride, i, scaleFactor, dstFmt); + entry->vkTex->UploadMip(cmdInit, i, mipWidth, mipHeight, texBuf, bufferOffset, stride / bpp); } } if (replacer_.Enabled()) { @@ -1160,7 +1147,9 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve TexCacheEntry *entry = nextTexture_; ApplyTexture(); + /* // TODO: Centralize? + // TODO: Fix! if (entry->framebuffer) { VirtualFramebuffer *vfb = entry->framebuffer; buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); @@ -1172,6 +1161,7 @@ bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int leve framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); return retval; } + */ if (!entry->vkTex) return false; diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index a9163f2e18..059b4be0ec 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -122,7 +122,7 @@ private: TexCacheEntry::TexStatus CheckAlpha(const u32 *pixelData, VkFormat dstFmt, int stride, int w, int h); void UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) override; - void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) override; + void ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) override; void BuildTexture(TexCacheEntry *const entry) override; void CompileScalingShader(); From f7feca96a70b7383fa1e0015dd69edf66f0bc6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 12 Sep 2020 14:53:33 +0200 Subject: [PATCH 682/848] Mostly fix Katamari by boosting fbs from the same frame --- GPU/Common/TextureCacheCommon.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 34b47a277e..ba58ba75b0 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -603,6 +603,12 @@ int TextureCacheCommon::GetBestCandidateIndex(const std::vector relevancy += 9; } + if (candidate.channel == NOTIFY_FB_COLOR && candidate.fb->last_frame_render == gpuStats.numFlips) { + relevancy += 5; + } else if (candidate.channel == NOTIFY_FB_DEPTH && candidate.fb->last_frame_depth_render == gpuStats.numFlips) { + relevancy += 5; + } + if (relevancy > bestRelevancy) { bestRelevancy = relevancy; bestIndex = i; From 61d792e27a83de414d9af838bf8464845e8330b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 12 Sep 2020 15:25:54 +0200 Subject: [PATCH 683/848] Re-fix BOF III - accidentally lost the texaddr offset --- GPU/Common/TextureCacheCommon.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index ba58ba75b0..91a8cbb5d9 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -471,6 +471,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { int index = GetBestCandidateIndex(candidates); if (index != -1) { nextTexture_ = nullptr; + nextNeedsRebuild_ = false; SetTextureFramebuffer(candidates[index]); return nullptr; } @@ -552,7 +553,7 @@ std::vector TextureCacheCommon::GetFramebufferCandidates(const for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { auto framebuffer = framebuffers[i]; uint32_t fb_addr = channel == NOTIFY_FB_DEPTH ? framebuffer->z_address : framebuffer->fb_address; - FramebufferMatchInfo match = MatchFramebuffer(entry, fb_addr, framebuffer, 0, channel); + FramebufferMatchInfo match = MatchFramebuffer(entry, fb_addr, framebuffer, texAddrOffset, channel); if (match.match == FramebufferMatch::IGNORE) { anyIgnores = true; } else if (match.match != FramebufferMatch::NO_MATCH) { From f6db1c2b01db47cc21d0f499c779f5f515ccf545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 12 Sep 2020 15:37:03 +0200 Subject: [PATCH 684/848] Show how many times we evaluate framebuffers per frame in debug statistics. --- GPU/Common/TextureCacheCommon.cpp | 1 + GPU/D3D11/GPU_D3D11.cpp | 6 +++--- GPU/Directx9/GPU_DX9.cpp | 6 +++--- GPU/GLES/GPU_GLES.cpp | 6 +++--- GPU/GPU.h | 2 ++ GPU/Vulkan/GPU_Vulkan.cpp | 6 +++--- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 91a8cbb5d9..6c83310e19 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -541,6 +541,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { } std::vector TextureCacheCommon::GetFramebufferCandidates(const TextureDefinition &entry, u32 texAddrOffset) { + gpuStats.numFramebufferEvaluations++; bool success = false; bool anyIgnores = false; diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 3d8a463838..552d303555 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -308,14 +308,13 @@ void GPU_D3D11::GetStats(char *buffer, size_t bufsize) { float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; snprintf(buffer, bufsize - 1, "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i\n" - "Cached Draw calls: %i\n" + "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" "Num Tracked Vertex Arrays: %i\n" "GPU cycles executed: %d (%f per vertex)\n" "Commands per call level: %i %i %i %i\n" "Vertices submitted: %i\n" "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i\n" + "FBOs active: %i (evaluations: %d)\n" "Textures active: %i, decoded: %i invalidated: %i\n" "Readbacks: %d, uploads: %d\n" "Vertex, Fragment shaders loaded: %i, %i\n", @@ -332,6 +331,7 @@ void GPU_D3D11::GetStats(char *buffer, size_t bufsize) { gpuStats.numCachedVertsDrawn, gpuStats.numUncachedVertsDrawn, (int)framebufferManagerD3D11_->NumVFBs(), + gpuStats.numFramebufferEvaluations, (int)textureCacheD3D11_->NumLoadedTextures(), gpuStats.numTexturesDecoded, gpuStats.numTextureInvalidations, diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 1ba0958f66..936dcee7a8 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -347,14 +347,13 @@ void GPU_DX9::GetStats(char *buffer, size_t bufsize) { float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; snprintf(buffer, bufsize - 1, "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i\n" - "Cached Draw calls: %i\n" + "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" "Num Tracked Vertex Arrays: %i\n" "GPU cycles executed: %d (%f per vertex)\n" "Commands per call level: %i %i %i %i\n" "Vertices submitted: %i\n" "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i\n" + "FBOs active: %i (evaluations: %d)\n" "Textures active: %i, decoded: %i invalidated: %i\n" "Readbacks: %d, uploads: %d\n" "Vertex, Fragment shaders loaded: %i, %i\n", @@ -371,6 +370,7 @@ void GPU_DX9::GetStats(char *buffer, size_t bufsize) { gpuStats.numCachedVertsDrawn, gpuStats.numUncachedVertsDrawn, (int)framebufferManagerDX9_->NumVFBs(), + gpuStats.numFramebufferEvaluations, (int)textureCacheDX9_->NumLoadedTextures(), gpuStats.numTexturesDecoded, gpuStats.numTextureInvalidations, diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 8c9df27705..e1de25d4e5 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -454,14 +454,13 @@ void GPU_GLES::GetStats(char *buffer, size_t bufsize) { float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; snprintf(buffer, bufsize - 1, "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i\n" - "Cached Draw calls: %i\n" + "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" "Num Tracked Vertex Arrays: %i\n" "GPU cycles executed: %d (%f per vertex)\n" "Commands per call level: %i %i %i %i\n" "Vertices submitted: %i\n" "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i\n" + "FBOs active: %i (evaluations: %d)\n" "Textures active: %i, decoded: %i invalidated: %i\n" "Readbacks: %d, uploads: %d\n" "Vertex, Fragment, Programs loaded: %i, %i, %i\n", @@ -478,6 +477,7 @@ void GPU_GLES::GetStats(char *buffer, size_t bufsize) { gpuStats.numCachedVertsDrawn, gpuStats.numUncachedVertsDrawn, (int)framebufferManagerGL_->NumVFBs(), + gpuStats.numFramebufferEvaluations, (int)textureCacheGL_->NumLoadedTextures(), gpuStats.numTexturesDecoded, gpuStats.numTextureInvalidations, diff --git a/GPU/GPU.h b/GPU/GPU.h index 2c2fa9cc70..2c47c53ac5 100644 --- a/GPU/GPU.h +++ b/GPU/GPU.h @@ -67,6 +67,7 @@ struct GPUStatistics { numShaderSwitches = 0; numFlushes = 0; numTexturesDecoded = 0; + numFramebufferEvaluations = 0; numReadbacks = 0; numUploads = 0; numClears = 0; @@ -88,6 +89,7 @@ struct GPUStatistics { int numTextureSwitches; int numShaderSwitches; int numTexturesDecoded; + int numFramebufferEvaluations; int numReadbacks; int numUploads; int numClears; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 6a5d2415f9..66d9ebfe04 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -558,14 +558,13 @@ void GPU_Vulkan::GetStats(char *buffer, size_t bufsize) { float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; snprintf(buffer, bufsize - 1, "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i\n" - "Cached Draw calls: %i\n" + "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" "Num Tracked Vertex Arrays: %i\n" "GPU cycles executed: %d (%f per vertex)\n" "Commands per call level: %i %i %i %i\n" "Vertices submitted: %i\n" "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i\n" + "FBOs active: %i (evaluations: %d)\n" "Textures active: %i, decoded: %i invalidated: %i\n" "Readbacks: %d, uploads: %d\n" "Vertex, Fragment, Pipelines loaded: %i, %i, %i\n" @@ -584,6 +583,7 @@ void GPU_Vulkan::GetStats(char *buffer, size_t bufsize) { gpuStats.numCachedVertsDrawn, gpuStats.numUncachedVertsDrawn, (int)framebufferManager_->NumVFBs(), + gpuStats.numFramebufferEvaluations, (int)textureCacheVulkan_->NumLoadedTextures(), gpuStats.numTexturesDecoded, gpuStats.numTextureInvalidations, From 60a6bf6d439824c582100ed273d77fe8289f3d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 1 Sep 2020 01:43:54 +0200 Subject: [PATCH 685/848] Optimize the DarkStalkers software rendering path a little more. --- Common/ColorConv.h | 14 +++++--------- GPU/Software/RasterizerRectangle.cpp | 15 +++++++-------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/Common/ColorConv.h b/Common/ColorConv.h index e2ae708bf7..15e800b736 100644 --- a/Common/ColorConv.h +++ b/Common/ColorConv.h @@ -76,15 +76,11 @@ inline u16 RGBA8888ToRGB565(u32 value) { } inline u16 RGBA8888ToRGBA5551(u32 value) { - u8 r = value & 0xFF; - u8 g = (value >> 8) & 0xFF; - u8 b = (value >> 16) & 0xFF; - u8 a = (value >> 24) & 0xFF; - r >>= 3; - g >>= 3; - b >>= 3; - a >>= 7; - return (u16)r | ((u16)g << 5) | ((u16)b << 10) | ((u16)a << 15); + u32 r = (value >> 3) & 0x1F; + u32 g = (value >> 11) & 0x1F; + u32 b = (value >> 19) & 0x1F; + u32 a = (value >> 31) & 0x1; + return (u16)(r | (g << 5) | (b << 10) | (a << 15)); } inline u16 RGBA8888ToRGBA4444(u32 value) { diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index db9c5bdcf9..8ec1992084 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -31,18 +31,17 @@ extern bool currentDialogActive; namespace Rasterizer { // Through mode, with the specific Darkstalker settings. -inline void DrawSinglePixel5551(u16 *pixel, const Vec4 &color_in) { +inline void DrawSinglePixel5551(u16 *pixel, const u32 color_in) { u32 new_color; - if (color_in.a() == 255) { - new_color = color_in.ToRGBA() & 0xFFFFFF; + if ((color_in >> 24) == 255) { + new_color = color_in & 0xFFFFFF; } else { const u32 old_color = RGBA5551ToRGBA8888(*pixel); const Vec4 dst = Vec4::FromRGBA(old_color); - Vec3 blended = AlphaBlendingResult(color_in, dst); + Vec3 blended = AlphaBlendingResult(Vec4::FromRGBA(color_in), dst); // ToRGB() always automatically clamps. new_color = blended.ToRGB(); } - new_color |= (*pixel & 0x8000) ? 0xff000000 : 0x00000000; *pixel = RGBA8888ToRGBA5551(new_color); } @@ -148,7 +147,7 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { for (int x = pos0.x; x < pos1.x; x++) { u32 tex_color = nearestFunc(s, t, texptr, texbufw, 0); if (tex_color & 0xFF000000) { - DrawSinglePixel5551(pixel, Vec4::FromRGBA(tex_color)); + DrawSinglePixel5551(pixel, tex_color); } s += ds; pixel++; @@ -159,7 +158,7 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { Vec4 tex_color = Vec4::FromRGBA(nearestFunc(s, t, texptr, texbufw, 0)); prim_color = ModulateRGBA(prim_color, tex_color); if (prim_color.a() > 0) { - DrawSinglePixel5551(pixel, prim_color); + DrawSinglePixel5551(pixel, prim_color.ToRGBA()); } s += ds; pixel++; @@ -208,7 +207,7 @@ void DrawSprite(const VertexData& v0, const VertexData& v1) { u16 *pixel = fb.Get16Ptr(pos0.x, y, gstate.FrameBufStride()); for (int x = pos0.x; x < pos1.x; x++) { Vec4 prim_color = v0.color0; - DrawSinglePixel5551(pixel, prim_color); + DrawSinglePixel5551(pixel, prim_color.ToRGBA()); pixel++; } } From f595f7368fc0222c4af6c5dd27bb8fe426788d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 2 Sep 2020 00:25:44 +0200 Subject: [PATCH 686/848] Optimize a couple more single color conversion functions --- Common/ColorConv.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Common/ColorConv.h b/Common/ColorConv.h index 15e800b736..9e66b73ea8 100644 --- a/Common/ColorConv.h +++ b/Common/ColorConv.h @@ -66,21 +66,18 @@ inline u32 RGB565ToRGBA8888(u16 src) { } inline u16 RGBA8888ToRGB565(u32 value) { - u8 r = value & 0xFF; - u8 g = (value >> 8) & 0xFF; - u8 b = (value >> 16) & 0xFF; - r >>= 3; - g >>= 2; - b >>= 3; - return (u16)r | ((u16)g << 5) | ((u16)b << 11); + u32 r = (value >> 3) & 0x1F; + u32 g = (value >> 5) & (0x3F << 5); + u32 b = (value >> 8) & (0x1F << 11); + return (u16)(r | g | b); } inline u16 RGBA8888ToRGBA5551(u32 value) { u32 r = (value >> 3) & 0x1F; - u32 g = (value >> 11) & 0x1F; - u32 b = (value >> 19) & 0x1F; - u32 a = (value >> 31) & 0x1; - return (u16)(r | (g << 5) | (b << 10) | (a << 15)); + u32 g = (value >> 6) & (0x1F << 5); + u32 b = (value >> 9) & (0x1F << 10); + u32 a = (value >> 16) & 0x8000; + return (u16)(r | g | b | a); } inline u16 RGBA8888ToRGBA4444(u32 value) { From 7f27f569d7fdff41334f2aaf020c42e10eea12ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 2 Sep 2020 00:26:08 +0200 Subject: [PATCH 687/848] x64: Fix stack alignment in vertex decoder, just because. --- GPU/Common/VertexDecoderX86.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/GPU/Common/VertexDecoderX86.cpp b/GPU/Common/VertexDecoderX86.cpp index c8329ec1c4..6fb69c99df 100644 --- a/GPU/Common/VertexDecoderX86.cpp +++ b/GPU/Common/VertexDecoderX86.cpp @@ -167,7 +167,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int BeginWrite(); const u8 *start = this->AlignCode16(); -#ifdef _M_IX86 +#if PPSSPP_ARCH(X86) // Store register values PUSH(ESI); PUSH(EDI); @@ -179,12 +179,20 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int MOV(32, R(srcReg), MDisp(ESP, 16 + offset + 0)); MOV(32, R(dstReg), MDisp(ESP, 16 + offset + 4)); MOV(32, R(counterReg), MDisp(ESP, 16 + offset + 8)); + + const uint8_t STACK_FIXED_ALLOC = 64; +#else + // Parameters automatically fall into place. + + // This will align the stack properly to 16 bytes (the call of this function pushed RIP, which is 8 bytes). + const uint8_t STACK_FIXED_ALLOC = 64 + 8; #endif + // Allocate temporary storage on the stack. + SUB(PTRBITS, R(ESP), Imm8(STACK_FIXED_ALLOC)); // Save XMM4/XMM5 which apparently can be problematic? // Actually, if they are, it must be a compiler bug because they SHOULD be ok. // So I won't bother. - SUB(PTRBITS, R(ESP), Imm8(64)); MOVUPS(MDisp(ESP, 0), XMM4); MOVUPS(MDisp(ESP, 16), XMM5); MOVUPS(MDisp(ESP, 32), XMM6); @@ -265,7 +273,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int MOVUPS(XMM5, MDisp(ESP, 16)); MOVUPS(XMM6, MDisp(ESP, 32)); MOVUPS(XMM7, MDisp(ESP, 48)); - ADD(PTRBITS, R(ESP), Imm8(64)); + ADD(PTRBITS, R(ESP), Imm8(STACK_FIXED_ALLOC)); #ifdef _M_IX86 // Restore register values From 37d7096703a935beedc303392a978c16fb7c0c0c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 12 Sep 2020 18:12:51 -0700 Subject: [PATCH 688/848] SaveState: Update to latest Snappy v1.1.8. --- Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 6 + UWP/CoreUWP/CoreUWP.vcxproj | 2 + UWP/CoreUWP/CoreUWP.vcxproj.filters | 6 + android/jni/Android.mk | 2 + ext/snappy/CMakeLists.txt | 2 + ext/snappy/snappy-c.h | 6 +- ext/snappy/snappy-internal.h | 145 ++- ext/snappy/snappy-sinksource.cpp | 104 +++ ext/snappy/snappy-sinksource.h | 57 +- ext/snappy/snappy-stubs-internal.cpp | 42 + ext/snappy/snappy-stubs-internal.h | 211 ++++- ext/snappy/snappy-stubs-public.h | 7 +- ext/snappy/snappy.cpp | 1293 ++++++++++++++++---------- ext/snappy/snappy.h | 87 +- libretro/Makefile.common | 2 + 16 files changed, 1366 insertions(+), 608 deletions(-) create mode 100644 ext/snappy/snappy-sinksource.cpp create mode 100644 ext/snappy/snappy-stubs-internal.cpp diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index d7e7d3343e..22276dc688 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -359,6 +359,8 @@ + + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 53b8252fe3..b9c3ce66be 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -761,6 +761,12 @@ HLE + + Ext\Snappy + + + Ext\Snappy + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 7090fca695..166da83a30 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -836,6 +836,8 @@ + + NotUsing NotUsing diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 1082a14160..944ccc3509 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -563,6 +563,12 @@ Ext\snappy + + Ext\snappy + + + Ext\snappy + Ext\udis86 diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 3e2c6367c0..a87e755684 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -193,6 +193,8 @@ EXEC_AND_LIB_FILES := \ $(SRC)/ext/libkirk/kirk_engine.c \ $(SRC)/ext/sfmt19937/SFMT.c \ $(SRC)/ext/snappy/snappy-c.cpp \ + $(SRC)/ext/snappy/snappy-sinksource.cpp \ + $(SRC)/ext/snappy/snappy-stubs-internal.cpp \ $(SRC)/ext/snappy/snappy.cpp \ $(SRC)/ext/udis86/decode.c \ $(SRC)/ext/udis86/itab.c \ diff --git a/ext/snappy/CMakeLists.txt b/ext/snappy/CMakeLists.txt index 6ab38acd0e..f25386b63a 100644 --- a/ext/snappy/CMakeLists.txt +++ b/ext/snappy/CMakeLists.txt @@ -9,7 +9,9 @@ else() snappy-c.cpp snappy-c.h snappy-internal.h + snappy-sinksource.cpp snappy-sinksource.h + snappy-stubs-internal.cpp snappy-stubs-internal.h snappy-stubs-public.h snappy.cpp diff --git a/ext/snappy/snappy-c.h b/ext/snappy/snappy-c.h index c6c2a860a4..32aa0c6b8b 100644 --- a/ext/snappy/snappy-c.h +++ b/ext/snappy/snappy-c.h @@ -30,8 +30,8 @@ * Plain C interface (a wrapper around the C++ implementation). */ -#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_ -#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_ +#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_ +#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_ #ifdef __cplusplus extern "C" { @@ -135,4 +135,4 @@ snappy_status snappy_validate_compressed_buffer(const char* compressed, } // extern "C" #endif -#endif /* UTIL_SNAPPY_OPENSOURCE_SNAPPY_C_H_ */ +#endif /* THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_C_H_ */ diff --git a/ext/snappy/snappy-internal.h b/ext/snappy/snappy-internal.h index c99d33130b..1e1c307fef 100644 --- a/ext/snappy/snappy-internal.h +++ b/ext/snappy/snappy-internal.h @@ -28,29 +28,38 @@ // // Internals shared between the Snappy implementation and its unittest. -#ifndef UTIL_SNAPPY_SNAPPY_INTERNAL_H_ -#define UTIL_SNAPPY_SNAPPY_INTERNAL_H_ +#ifndef THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_ +#define THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_ #include "snappy-stubs-internal.h" namespace snappy { namespace internal { +// Working memory performs a single allocation to hold all scratch space +// required for compression. class WorkingMemory { public: - WorkingMemory() : large_table_(NULL) { } - ~WorkingMemory() { delete[] large_table_; } + explicit WorkingMemory(size_t input_size); + ~WorkingMemory(); // Allocates and clears a hash table using memory in "*this", // stores the number of buckets in "*table_size" and returns a pointer to // the base of the hash table. - uint16* GetHashTable(size_t input_size, int* table_size); + uint16* GetHashTable(size_t fragment_size, int* table_size) const; + char* GetScratchInput() const { return input_; } + char* GetScratchOutput() const { return output_; } private: - uint16 small_table_[1<<10]; // 2KB - uint16* large_table_; // Allocated only when needed + char* mem_; // the allocated memory, never nullptr + size_t size_; // the size of the allocated memory, never 0 + uint16* table_; // the pointer to the hashtable + char* input_; // the pointer to the input scratch buffer + char* output_; // the pointer to the output scratch buffer - DISALLOW_COPY_AND_ASSIGN(WorkingMemory); + // No copying + WorkingMemory(const WorkingMemory&); + void operator=(const WorkingMemory&); }; // Flat array compression that does not emit the "uncompressed length" @@ -70,57 +79,72 @@ char* CompressFragment(const char* input, uint16* table, const int table_size); -// Return the largest n such that +// Find the largest n such that // // s1[0,n-1] == s2[0,n-1] // and n <= (s2_limit - s2). // +// Return make_pair(n, n < 8). // Does not read *s2_limit or beyond. // Does not read *(s1 + (s2_limit - s2)) or beyond. // Requires that s2_limit >= s2. // -// Separate implementation for x86_64, for speed. Uses the fact that -// x86_64 is little endian. -#if defined(ARCH_K8) -static inline int FindMatchLength(const char* s1, - const char* s2, - const char* s2_limit) { +// Separate implementation for 64-bit, little-endian cpus. +#if !defined(SNAPPY_IS_BIG_ENDIAN) && \ + (defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM)) +static inline std::pair FindMatchLength(const char* s1, + const char* s2, + const char* s2_limit) { assert(s2_limit >= s2); - int matched = 0; + size_t matched = 0; + + // This block isn't necessary for correctness; we could just start looping + // immediately. As an optimization though, it is useful. It creates some not + // uncommon code paths that determine, without extra effort, whether the match + // length is less than 8. In short, we are hoping to avoid a conditional + // branch, and perhaps get better code layout from the C++ compiler. + if (SNAPPY_PREDICT_TRUE(s2 <= s2_limit - 8)) { + uint64 a1 = UNALIGNED_LOAD64(s1); + uint64 a2 = UNALIGNED_LOAD64(s2); + if (a1 != a2) { + return std::pair(Bits::FindLSBSetNonZero64(a1 ^ a2) >> 3, + true); + } else { + matched = 8; + s2 += 8; + } + } // Find out how long the match is. We loop over the data 64 bits at a // time until we find a 64-bit block that doesn't match; then we find // the first non-matching bit and use that to calculate the total // length of the match. - while (PREDICT_TRUE(s2 <= s2_limit - 8)) { - if (PREDICT_FALSE(UNALIGNED_LOAD64(s2) == UNALIGNED_LOAD64(s1 + matched))) { + while (SNAPPY_PREDICT_TRUE(s2 <= s2_limit - 8)) { + if (UNALIGNED_LOAD64(s2) == UNALIGNED_LOAD64(s1 + matched)) { s2 += 8; matched += 8; } else { - // On current (mid-2008) Opteron models there is a 3% more - // efficient code sequence to find the first non-matching byte. - // However, what follows is ~10% better on Intel Core 2 and newer, - // and we expect AMD's bsf instruction to improve. uint64 x = UNALIGNED_LOAD64(s2) ^ UNALIGNED_LOAD64(s1 + matched); int matching_bits = Bits::FindLSBSetNonZero64(x); matched += matching_bits >> 3; - return matched; + assert(matched >= 8); + return std::pair(matched, false); } } - while (PREDICT_TRUE(s2 < s2_limit)) { - if (PREDICT_TRUE(s1[matched] == *s2)) { + while (SNAPPY_PREDICT_TRUE(s2 < s2_limit)) { + if (s1[matched] == *s2) { ++s2; ++matched; } else { - return matched; + return std::pair(matched, matched < 8); } } - return matched; + return std::pair(matched, matched < 8); } #else -static inline int FindMatchLength(const char* s1, - const char* s2, - const char* s2_limit) { +static inline std::pair FindMatchLength(const char* s1, + const char* s2, + const char* s2_limit) { // Implementation based on the x86-64 version, above. assert(s2_limit >= s2); int matched = 0; @@ -140,11 +164,68 @@ static inline int FindMatchLength(const char* s1, ++matched; } } - return matched; + return std::pair(matched, matched < 8); } #endif +// Lookup tables for decompression code. Give --snappy_dump_decompression_table +// to the unit test to recompute char_table. + +enum { + LITERAL = 0, + COPY_1_BYTE_OFFSET = 1, // 3 bit length + 3 bits of offset in opcode + COPY_2_BYTE_OFFSET = 2, + COPY_4_BYTE_OFFSET = 3 +}; +static const int kMaximumTagLength = 5; // COPY_4_BYTE_OFFSET plus the actual offset. + +// Data stored per entry in lookup table: +// Range Bits-used Description +// ------------------------------------ +// 1..64 0..7 Literal/copy length encoded in opcode byte +// 0..7 8..10 Copy offset encoded in opcode byte / 256 +// 0..4 11..13 Extra bytes after opcode +// +// We use eight bits for the length even though 7 would have sufficed +// because of efficiency reasons: +// (1) Extracting a byte is faster than a bit-field +// (2) It properly aligns copy offset so we do not need a <<8 +static const uint16 char_table[256] = { + 0x0001, 0x0804, 0x1001, 0x2001, 0x0002, 0x0805, 0x1002, 0x2002, + 0x0003, 0x0806, 0x1003, 0x2003, 0x0004, 0x0807, 0x1004, 0x2004, + 0x0005, 0x0808, 0x1005, 0x2005, 0x0006, 0x0809, 0x1006, 0x2006, + 0x0007, 0x080a, 0x1007, 0x2007, 0x0008, 0x080b, 0x1008, 0x2008, + 0x0009, 0x0904, 0x1009, 0x2009, 0x000a, 0x0905, 0x100a, 0x200a, + 0x000b, 0x0906, 0x100b, 0x200b, 0x000c, 0x0907, 0x100c, 0x200c, + 0x000d, 0x0908, 0x100d, 0x200d, 0x000e, 0x0909, 0x100e, 0x200e, + 0x000f, 0x090a, 0x100f, 0x200f, 0x0010, 0x090b, 0x1010, 0x2010, + 0x0011, 0x0a04, 0x1011, 0x2011, 0x0012, 0x0a05, 0x1012, 0x2012, + 0x0013, 0x0a06, 0x1013, 0x2013, 0x0014, 0x0a07, 0x1014, 0x2014, + 0x0015, 0x0a08, 0x1015, 0x2015, 0x0016, 0x0a09, 0x1016, 0x2016, + 0x0017, 0x0a0a, 0x1017, 0x2017, 0x0018, 0x0a0b, 0x1018, 0x2018, + 0x0019, 0x0b04, 0x1019, 0x2019, 0x001a, 0x0b05, 0x101a, 0x201a, + 0x001b, 0x0b06, 0x101b, 0x201b, 0x001c, 0x0b07, 0x101c, 0x201c, + 0x001d, 0x0b08, 0x101d, 0x201d, 0x001e, 0x0b09, 0x101e, 0x201e, + 0x001f, 0x0b0a, 0x101f, 0x201f, 0x0020, 0x0b0b, 0x1020, 0x2020, + 0x0021, 0x0c04, 0x1021, 0x2021, 0x0022, 0x0c05, 0x1022, 0x2022, + 0x0023, 0x0c06, 0x1023, 0x2023, 0x0024, 0x0c07, 0x1024, 0x2024, + 0x0025, 0x0c08, 0x1025, 0x2025, 0x0026, 0x0c09, 0x1026, 0x2026, + 0x0027, 0x0c0a, 0x1027, 0x2027, 0x0028, 0x0c0b, 0x1028, 0x2028, + 0x0029, 0x0d04, 0x1029, 0x2029, 0x002a, 0x0d05, 0x102a, 0x202a, + 0x002b, 0x0d06, 0x102b, 0x202b, 0x002c, 0x0d07, 0x102c, 0x202c, + 0x002d, 0x0d08, 0x102d, 0x202d, 0x002e, 0x0d09, 0x102e, 0x202e, + 0x002f, 0x0d0a, 0x102f, 0x202f, 0x0030, 0x0d0b, 0x1030, 0x2030, + 0x0031, 0x0e04, 0x1031, 0x2031, 0x0032, 0x0e05, 0x1032, 0x2032, + 0x0033, 0x0e06, 0x1033, 0x2033, 0x0034, 0x0e07, 0x1034, 0x2034, + 0x0035, 0x0e08, 0x1035, 0x2035, 0x0036, 0x0e09, 0x1036, 0x2036, + 0x0037, 0x0e0a, 0x1037, 0x2037, 0x0038, 0x0e0b, 0x1038, 0x2038, + 0x0039, 0x0f04, 0x1039, 0x2039, 0x003a, 0x0f05, 0x103a, 0x203a, + 0x003b, 0x0f06, 0x103b, 0x203b, 0x003c, 0x0f07, 0x103c, 0x203c, + 0x0801, 0x0f08, 0x103d, 0x203d, 0x1001, 0x0f09, 0x103e, 0x203e, + 0x1801, 0x0f0a, 0x103f, 0x203f, 0x2001, 0x0f0b, 0x1040, 0x2040 +}; + } // end namespace internal } // end namespace snappy -#endif // UTIL_SNAPPY_SNAPPY_INTERNAL_H_ +#endif // THIRD_PARTY_SNAPPY_SNAPPY_INTERNAL_H_ diff --git a/ext/snappy/snappy-sinksource.cpp b/ext/snappy/snappy-sinksource.cpp new file mode 100644 index 0000000000..369a13215b --- /dev/null +++ b/ext/snappy/snappy-sinksource.cpp @@ -0,0 +1,104 @@ +// Copyright 2011 Google Inc. All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include "snappy-sinksource.h" + +namespace snappy { + +Source::~Source() { } + +Sink::~Sink() { } + +char* Sink::GetAppendBuffer(size_t length, char* scratch) { + return scratch; +} + +char* Sink::GetAppendBufferVariable( + size_t min_size, size_t desired_size_hint, char* scratch, + size_t scratch_size, size_t* allocated_size) { + *allocated_size = scratch_size; + return scratch; +} + +void Sink::AppendAndTakeOwnership( + char* bytes, size_t n, + void (*deleter)(void*, const char*, size_t), + void *deleter_arg) { + Append(bytes, n); + (*deleter)(deleter_arg, bytes, n); +} + +ByteArraySource::~ByteArraySource() { } + +size_t ByteArraySource::Available() const { return left_; } + +const char* ByteArraySource::Peek(size_t* len) { + *len = left_; + return ptr_; +} + +void ByteArraySource::Skip(size_t n) { + left_ -= n; + ptr_ += n; +} + +UncheckedByteArraySink::~UncheckedByteArraySink() { } + +void UncheckedByteArraySink::Append(const char* data, size_t n) { + // Do no copying if the caller filled in the result of GetAppendBuffer() + if (data != dest_) { + memcpy(dest_, data, n); + } + dest_ += n; +} + +char* UncheckedByteArraySink::GetAppendBuffer(size_t len, char* scratch) { + return dest_; +} + +void UncheckedByteArraySink::AppendAndTakeOwnership( + char* data, size_t n, + void (*deleter)(void*, const char*, size_t), + void *deleter_arg) { + if (data != dest_) { + memcpy(dest_, data, n); + (*deleter)(deleter_arg, data, n); + } + dest_ += n; +} + +char* UncheckedByteArraySink::GetAppendBufferVariable( + size_t min_size, size_t desired_size_hint, char* scratch, + size_t scratch_size, size_t* allocated_size) { + *allocated_size = desired_size_hint; + return dest_; +} + +} // namespace snappy diff --git a/ext/snappy/snappy-sinksource.h b/ext/snappy/snappy-sinksource.h index faabfa1e6f..8afcdaaa2c 100644 --- a/ext/snappy/snappy-sinksource.h +++ b/ext/snappy/snappy-sinksource.h @@ -26,12 +26,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_ -#define UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_ +#ifndef THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_ +#define THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_ #include - namespace snappy { // A Sink is an interface that consumes a sequence of bytes. @@ -60,6 +59,47 @@ class Sink { // The default implementation always returns the scratch buffer. virtual char* GetAppendBuffer(size_t length, char* scratch); + // For higher performance, Sink implementations can provide custom + // AppendAndTakeOwnership() and GetAppendBufferVariable() methods. + // These methods can reduce the number of copies done during + // compression/decompression. + + // Append "bytes[0,n-1] to the sink. Takes ownership of "bytes" + // and calls the deleter function as (*deleter)(deleter_arg, bytes, n) + // to free the buffer. deleter function must be non NULL. + // + // The default implementation just calls Append and frees "bytes". + // Other implementations may avoid a copy while appending the buffer. + virtual void AppendAndTakeOwnership( + char* bytes, size_t n, void (*deleter)(void*, const char*, size_t), + void *deleter_arg); + + // Returns a writable buffer for appending and writes the buffer's capacity to + // *allocated_size. Guarantees *allocated_size >= min_size. + // May return a pointer to the caller-owned scratch buffer which must have + // scratch_size >= min_size. + // + // The returned buffer is only valid until the next operation + // on this ByteSink. + // + // After writing at most *allocated_size bytes, call Append() with the + // pointer returned from this function and the number of bytes written. + // Many Append() implementations will avoid copying bytes if this function + // returned an internal buffer. + // + // If the sink implementation allocates or reallocates an internal buffer, + // it should use the desired_size_hint if appropriate. If a caller cannot + // provide a reasonable guess at the desired capacity, it should set + // desired_size_hint = 0. + // + // If a non-scratch buffer is returned, the caller may only pass + // a prefix to it to Append(). That is, it is not correct to pass an + // interior pointer to Append(). + // + // The default implementation always returns the scratch buffer. + virtual char* GetAppendBufferVariable( + size_t min_size, size_t desired_size_hint, char* scratch, + size_t scratch_size, size_t* allocated_size); private: // No copying @@ -122,6 +162,12 @@ class UncheckedByteArraySink : public Sink { virtual ~UncheckedByteArraySink(); virtual void Append(const char* data, size_t n); virtual char* GetAppendBuffer(size_t len, char* scratch); + virtual char* GetAppendBufferVariable( + size_t min_size, size_t desired_size_hint, char* scratch, + size_t scratch_size, size_t* allocated_size); + virtual void AppendAndTakeOwnership( + char* bytes, size_t n, void (*deleter)(void*, const char*, size_t), + void *deleter_arg); // Return the current output pointer so that a caller can see how // many bytes were produced. @@ -131,7 +177,6 @@ class UncheckedByteArraySink : public Sink { char* dest_; }; +} // namespace snappy -} - -#endif // UTIL_SNAPPY_SNAPPY_SINKSOURCE_H_ +#endif // THIRD_PARTY_SNAPPY_SNAPPY_SINKSOURCE_H_ diff --git a/ext/snappy/snappy-stubs-internal.cpp b/ext/snappy/snappy-stubs-internal.cpp new file mode 100644 index 0000000000..66ed2e9039 --- /dev/null +++ b/ext/snappy/snappy-stubs-internal.cpp @@ -0,0 +1,42 @@ +// Copyright 2011 Google Inc. All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include + +#include "snappy-stubs-internal.h" + +namespace snappy { + +void Varint::Append32(std::string* s, uint32 value) { + char buf[Varint::kMax32]; + const char* p = Varint::Encode32(buf, value); + s->append(buf, p - buf); +} + +} // namespace snappy diff --git a/ext/snappy/snappy-stubs-internal.h b/ext/snappy/snappy-stubs-internal.h index eae1e4fae8..4854689d17 100644 --- a/ext/snappy/snappy-stubs-internal.h +++ b/ext/snappy/snappy-stubs-internal.h @@ -28,8 +28,8 @@ // // Various stubs for the open-source version of Snappy. -#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_ -#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_ +#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_ +#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_ #ifdef HAVE_CONFIG_H #include "config.h" @@ -45,13 +45,41 @@ #include #endif +#ifdef HAVE_UNISTD_H +#include +#endif + +#if defined(_MSC_VER) +#include +#endif // defined(_MSC_VER) + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if __has_feature(memory_sanitizer) +#include +#define SNAPPY_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + __msan_unpoison((address), (size)) +#else +#define SNAPPY_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */ +#endif // __has_feature(memory_sanitizer) + #include "snappy-stubs-public.h" -#if defined(__x86_64__) || defined(_M_X64) +#if defined(__x86_64__) // Enable 64-bit optimized versions of some routines. #define ARCH_K8 1 +#elif defined(__ppc64__) + +#define ARCH_PPC 1 + +#elif defined(__aarch64__) + +#define ARCH_ARM 1 + #endif // Needed by OS X, among others. @@ -59,10 +87,6 @@ #define MAP_ANONYMOUS MAP_ANON #endif -// Pull in std::min, std::ostream, and the likes. This is safe because this -// header file is never used from any public header files. -using namespace std; - // The size of an array, if known at compile-time. // Will give unexpected results if used on a pointer. // We undefine it first, since some compilers already have a definition. @@ -73,11 +97,11 @@ using namespace std; // Static prediction hints. #ifdef HAVE_BUILTIN_EXPECT -#define PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#define SNAPPY_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#define SNAPPY_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) #else -#define PREDICT_FALSE(x) x -#define PREDICT_TRUE(x) x +#define SNAPPY_PREDICT_FALSE(x) x +#define SNAPPY_PREDICT_TRUE(x) x #endif // This is only used for recomputing the tag byte table used during @@ -96,13 +120,10 @@ static const int64 kint64max = static_cast(0x7FFFFFFFFFFFFFFFLL); // Potentially unaligned loads and stores. -// x86 and PowerPC can simply do these loads and stores native. +// x86, PowerPC, and ARM64 can simply do these loads and stores native. -#if defined(_M_IX86) && defined(_MSC_VER) && !defined(ARM) && !defined(MIPS) && !defined(__i386__) -#define __i386__ 1 -#endif - -#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(_M_X64) +#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \ + defined(__aarch64__) #define UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) #define UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) @@ -120,6 +141,15 @@ static const int64 kint64max = static_cast(0x7FFFFFFFFFFFFFFFLL); // sub-architectures. // // This is a mess, but there's not much we can do about it. +// +// To further complicate matters, only LDR instructions (single reads) are +// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we +// explicitly tell the compiler that these accesses can be unaligned, it can and +// will combine accesses. On armcc, the way to signal this is done by accessing +// through the type (uint32 __packed *), but GCC has no such attribute +// (it ignores __attribute__((packed)) on individual variables). However, +// we can tell it that a _struct_ is unaligned, which has the same effect, +// so we do that. #elif defined(__arm__) && \ !defined(__ARM_ARCH_4__) && \ @@ -135,13 +165,41 @@ static const int64 kint64max = static_cast(0x7FFFFFFFFFFFFFFFLL); !defined(__ARM_ARCH_6ZK__) && \ !defined(__ARM_ARCH_6T2__) -#define UNALIGNED_LOAD16(_p) (*reinterpret_cast(_p)) -#define UNALIGNED_LOAD32(_p) (*reinterpret_cast(_p)) +#if __GNUC__ +#define ATTRIBUTE_PACKED __attribute__((__packed__)) +#else +#define ATTRIBUTE_PACKED +#endif -#define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast(_p) = (_val)) -#define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast(_p) = (_val)) +namespace base { +namespace internal { -// TODO(user): NEON supports unaligned 64-bit loads and stores. +struct Unaligned16Struct { + uint16 value; + uint8 dummy; // To make the size non-power-of-two. +} ATTRIBUTE_PACKED; + +struct Unaligned32Struct { + uint32 value; + uint8 dummy; // To make the size non-power-of-two. +} ATTRIBUTE_PACKED; + +} // namespace internal +} // namespace base + +#define UNALIGNED_LOAD16(_p) \ + ((reinterpret_cast(_p))->value) +#define UNALIGNED_LOAD32(_p) \ + ((reinterpret_cast(_p))->value) + +#define UNALIGNED_STORE16(_p, _val) \ + ((reinterpret_cast< ::snappy::base::internal::Unaligned16Struct *>(_p))->value = \ + (_val)) +#define UNALIGNED_STORE32(_p, _val) \ + ((reinterpret_cast< ::snappy::base::internal::Unaligned32Struct *>(_p))->value = \ + (_val)) + +// TODO: NEON supports unaligned 64-bit loads and stores. // See if that would be more efficient on platforms supporting it, // at least for copies. @@ -192,22 +250,8 @@ inline void UNALIGNED_STORE64(void *p, uint64 v) { #endif -// This can be more efficient than UNALIGNED_LOAD64 + UNALIGNED_STORE64 -// on some platforms, in particular ARM. -inline void UnalignedCopy64(const void *src, void *dst) { - if (sizeof(void *) == 8) { - UNALIGNED_STORE64(dst, UNALIGNED_LOAD64(src)); - } else { - const char *src_char = reinterpret_cast(src); - char *dst_char = reinterpret_cast(dst); - - UNALIGNED_STORE32(dst_char, UNALIGNED_LOAD32(src_char)); - UNALIGNED_STORE32(dst_char + 4, UNALIGNED_LOAD32(src_char + 4)); - } -} - // The following guarantees declaration of the byte swap functions. -#ifdef WORDS_BIGENDIAN +#if defined(SNAPPY_IS_BIG_ENDIAN) #ifdef HAVE_SYS_BYTEORDER_H #include @@ -264,7 +308,7 @@ inline uint64 bswap_64(uint64 x) { #endif -#endif // WORDS_BIGENDIAN +#endif // defined(SNAPPY_IS_BIG_ENDIAN) // Convert to little-endian storage, opposite of network format. // Convert x from host to little endian: x = LittleEndian.FromHost(x); @@ -278,7 +322,7 @@ inline uint64 bswap_64(uint64 x) { class LittleEndian { public: // Conversion functions. -#ifdef WORDS_BIGENDIAN +#if defined(SNAPPY_IS_BIG_ENDIAN) static uint16 FromHost16(uint16 x) { return bswap_16(x); } static uint16 ToHost16(uint16 x) { return bswap_16(x); } @@ -288,7 +332,7 @@ class LittleEndian { static bool IsLittleEndian() { return false; } -#else // !defined(WORDS_BIGENDIAN) +#else // !defined(SNAPPY_IS_BIG_ENDIAN) static uint16 FromHost16(uint16 x) { return x; } static uint16 ToHost16(uint16 x) { return x; } @@ -298,7 +342,7 @@ class LittleEndian { static bool IsLittleEndian() { return true; } -#endif // !defined(WORDS_BIGENDIAN) +#endif // !defined(SNAPPY_IS_BIG_ENDIAN) // Functions to do unaligned loads and stores in little-endian order. static uint16 Load16(const void *p) { @@ -321,6 +365,9 @@ class LittleEndian { // Some bit-manipulation functions. class Bits { public: + // Return floor(log2(n)) for positive integer n. + static int Log2FloorNonZero(uint32 n); + // Return floor(log2(n)) for positive integer n. Returns -1 iff n == 0. static int Log2Floor(uint32 n); @@ -328,31 +375,85 @@ class Bits { // undefined value if n == 0. FindLSBSetNonZero() is similar to ffs() except // that it's 0-indexed. static int FindLSBSetNonZero(uint32 n); + +#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM) static int FindLSBSetNonZero64(uint64 n); +#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM) private: - DISALLOW_COPY_AND_ASSIGN(Bits); + // No copying + Bits(const Bits&); + void operator=(const Bits&); }; #ifdef HAVE_BUILTIN_CTZ +inline int Bits::Log2FloorNonZero(uint32 n) { + assert(n != 0); + // (31 ^ x) is equivalent to (31 - x) for x in [0, 31]. An easy proof + // represents subtraction in base 2 and observes that there's no carry. + // + // GCC and Clang represent __builtin_clz on x86 as 31 ^ _bit_scan_reverse(x). + // Using "31 ^" here instead of "31 -" allows the optimizer to strip the + // function body down to _bit_scan_reverse(x). + return 31 ^ __builtin_clz(n); +} + inline int Bits::Log2Floor(uint32 n) { - return n == 0 ? -1 : 31 ^ __builtin_clz(n); + return (n == 0) ? -1 : Bits::Log2FloorNonZero(n); } inline int Bits::FindLSBSetNonZero(uint32 n) { + assert(n != 0); return __builtin_ctz(n); } +#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM) inline int Bits::FindLSBSetNonZero64(uint64 n) { + assert(n != 0); return __builtin_ctzll(n); } +#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM) + +#elif defined(_MSC_VER) + +inline int Bits::Log2FloorNonZero(uint32 n) { + assert(n != 0); + unsigned long where; + _BitScanReverse(&where, n); + return static_cast(where); +} + +inline int Bits::Log2Floor(uint32 n) { + unsigned long where; + if (_BitScanReverse(&where, n)) + return static_cast(where); + return -1; +} + +inline int Bits::FindLSBSetNonZero(uint32 n) { + assert(n != 0); + unsigned long where; + if (_BitScanForward(&where, n)) + return static_cast(where); + return 32; +} + +#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM) +inline int Bits::FindLSBSetNonZero64(uint64 n) { + assert(n != 0); + unsigned long where; + if (_BitScanForward64(&where, n)) + return static_cast(where); + return 64; +} +#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM) #else // Portable versions. -inline int Bits::Log2Floor(uint32 n) { - if (n == 0) - return -1; +inline int Bits::Log2FloorNonZero(uint32 n) { + assert(n != 0); + int log = 0; uint32 value = n; for (int i = 4; i >= 0; --i) { @@ -367,7 +468,13 @@ inline int Bits::Log2Floor(uint32 n) { return log; } +inline int Bits::Log2Floor(uint32 n) { + return (n == 0) ? -1 : Bits::Log2FloorNonZero(n); +} + inline int Bits::FindLSBSetNonZero(uint32 n) { + assert(n != 0); + int rc = 31; for (int i = 4, shift = 1 << 4; i >= 0; --i) { const uint32 x = n << shift; @@ -380,8 +487,11 @@ inline int Bits::FindLSBSetNonZero(uint32 n) { return rc; } +#if defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM) // FindLSBSetNonZero64() is defined in terms of FindLSBSetNonZero(). inline int Bits::FindLSBSetNonZero64(uint64 n) { + assert(n != 0); + const uint32 bottombits = static_cast(n); if (bottombits == 0) { // Bottom bits are zero, so scan in top bits @@ -390,6 +500,7 @@ inline int Bits::FindLSBSetNonZero64(uint64 n) { return FindLSBSetNonZero(bottombits); } } +#endif // defined(ARCH_K8) || defined(ARCH_PPC) || defined(ARCH_ARM) #endif // End portable versions. @@ -413,7 +524,7 @@ class Varint { static char* Encode32(char* ptr, uint32 v); // EFFECTS Appends the varint representation of "value" to "*s". - static void Append32(string* s, uint32 value); + static void Append32(std::string* s, uint32 value); }; inline const char* Varint::Parse32WithLimit(const char* p, @@ -470,7 +581,7 @@ inline char* Varint::Encode32(char* sptr, uint32 v) { // replace this function with one that resizes the string without // filling the new space with zeros (if applicable) -- // it will be non-portable but faster. -inline void STLStringResizeUninitialized(string* s, size_t new_size) { +inline void STLStringResizeUninitialized(std::string* s, size_t new_size) { s->resize(new_size); } @@ -486,10 +597,10 @@ inline void STLStringResizeUninitialized(string* s, size_t new_size) { // (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-defects.html#530) // proposes this as the method. It will officially be part of the standard // for C++0x. This should already work on all current implementations. -inline char* string_as_array(string* str) { +inline char* string_as_array(std::string* str) { return str->empty() ? NULL : &*str->begin(); } } // namespace snappy -#endif // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_ +#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_ diff --git a/ext/snappy/snappy-stubs-public.h b/ext/snappy/snappy-stubs-public.h index f5cd2fca59..50d501324d 100644 --- a/ext/snappy/snappy-stubs-public.h +++ b/ext/snappy/snappy-stubs-public.h @@ -1,5 +1,4 @@ // Copyright 2011 Google Inc. All Rights Reserved. -// Author: sesse@google.com (Steinar H. Gunderson) // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -33,8 +32,8 @@ // which is a public header. Instead, snappy-stubs-public.h is generated by // from snappy-stubs-public.h.in at configure time. -#ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ -#define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ +#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ +#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ #include "base/basictypes.h" #include @@ -65,4 +64,4 @@ struct iovec { } // namespace snappy -#endif // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ +#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ diff --git a/ext/snappy/snappy.cpp b/ext/snappy/snappy.cpp index 42a217883f..ce1eef4630 100644 --- a/ext/snappy/snappy.cpp +++ b/ext/snappy/snappy.cpp @@ -30,6 +30,44 @@ #include "snappy-internal.h" #include "snappy-sinksource.h" +#if !defined(SNAPPY_HAVE_SSSE3) +// __SSSE3__ is defined by GCC and Clang. Visual Studio doesn't target SIMD +// support between SSE2 and AVX (so SSSE3 instructions require AVX support), and +// defines __AVX__ when AVX support is available. +#if defined(__SSSE3__) || defined(__AVX__) +#define SNAPPY_HAVE_SSSE3 1 +#else +#define SNAPPY_HAVE_SSSE3 0 +#endif +#endif // !defined(SNAPPY_HAVE_SSSE3) + +#if !defined(SNAPPY_HAVE_BMI2) +// __BMI2__ is defined by GCC and Clang. Visual Studio doesn't target BMI2 +// specifically, but it does define __AVX2__ when AVX2 support is available. +// Fortunately, AVX2 was introduced in Haswell, just like BMI2. +// +// BMI2 is not defined as a subset of AVX2 (unlike SSSE3 and AVX above). So, +// GCC and Clang can build code with AVX2 enabled but BMI2 disabled, in which +// case issuing BMI2 instructions results in a compiler error. +#if defined(__BMI2__) || (defined(_MSC_VER) && defined(__AVX2__)) +#define SNAPPY_HAVE_BMI2 1 +#else +#define SNAPPY_HAVE_BMI2 0 +#endif +#endif // !defined(SNAPPY_HAVE_BMI2) + +#if SNAPPY_HAVE_SSSE3 +// Please do not replace with . or with headers that assume more +// advanced SSE versions without checking with all the OWNERS. +#include +#endif + +#if SNAPPY_HAVE_BMI2 +// Please do not replace with . or with headers that assume more +// advanced SSE versions without checking with all the OWNERS. +#include +#endif + #include #include @@ -38,46 +76,11 @@ namespace snappy { - Source::~Source() { } - - Sink::~Sink() { } - - char* Sink::GetAppendBuffer(size_t length, char* scratch) { - return scratch; - } - - ByteArraySource::~ByteArraySource() { } - - size_t ByteArraySource::Available() const { return left_; } - - const char* ByteArraySource::Peek(size_t* len) { - *len = left_; - return ptr_; - } - - void ByteArraySource::Skip(size_t n) { - left_ -= n; - ptr_ += n; - } - - UncheckedByteArraySink::~UncheckedByteArraySink() { } - - void UncheckedByteArraySink::Append(const char* data, size_t n) { - // Do no copying if the caller filled in the result of GetAppendBuffer() - if (data != dest_) { - memcpy(dest_, data, n); - } - dest_ += n; - } - - char* UncheckedByteArraySink::GetAppendBuffer(size_t len, char* scratch) { - return dest_; - } - -} - - -namespace snappy { +using internal::COPY_1_BYTE_OFFSET; +using internal::COPY_2_BYTE_OFFSET; +using internal::LITERAL; +using internal::char_table; +using internal::kMaximumTagLength; // Any hash function will produce a valid compressed bitstream, but a good // hash function reduces the number of collisions and thus yields better @@ -116,168 +119,314 @@ size_t MaxCompressedLength(size_t source_len) { return 32 + source_len + source_len/6; } -enum { - LITERAL = 0, - COPY_1_BYTE_OFFSET = 1, // 3 bit length + 3 bits of offset in opcode - COPY_2_BYTE_OFFSET = 2, - COPY_4_BYTE_OFFSET = 3 -}; -static const int kMaximumTagLength = 5; // COPY_4_BYTE_OFFSET plus the actual offset. - -void Varint::Append32(string* s, uint32 value) { - char buf[Varint::kMax32]; - const char* p = Varint::Encode32(buf, value); - s->append(buf, p - buf); -} - -// Copy "len" bytes from "src" to "op", one byte at a time. Used for -// handling COPY operations where the input and output regions may -// overlap. For example, suppose: -// src == "ab" -// op == src + 2 -// len == 20 -// After IncrementalCopy(src, op, len), the result will have -// eleven copies of "ab" -// ababababababababababab -// Note that this does not match the semantics of either memcpy() -// or memmove(). -static inline void IncrementalCopy(const char* src, char* op, ssize_t len) { - assert(len > 0); - do { - *op++ = *src++; - } while (--len > 0); -} - -// Equivalent to IncrementalCopy except that it can write up to ten extra -// bytes after the end of the copy, and that it is faster. -// -// The main part of this loop is a simple copy of eight bytes at a time until -// we've copied (at least) the requested amount of bytes. However, if op and -// src are less than eight bytes apart (indicating a repeating pattern of -// length < 8), we first need to expand the pattern in order to get the correct -// results. For instance, if the buffer looks like this, with the eight-byte -// and patterns marked as intervals: -// -// abxxxxxxxxxxxx -// [------] src -// [------] op -// -// a single eight-byte copy from to will repeat the pattern once, -// after which we can move two bytes without moving : -// -// ababxxxxxxxxxx -// [------] src -// [------] op -// -// and repeat the exercise until the two no longer overlap. -// -// This allows us to do very well in the special case of one single byte -// repeated many times, without taking a big hit for more general cases. -// -// The worst case of extra writing past the end of the match occurs when -// op - src == 1 and len == 1; the last copy will read from byte positions -// [0..7] and write to [4..11], whereas it was only supposed to write to -// position 1. Thus, ten excess bytes. - namespace { -const int kMaxIncrementCopyOverflow = 10; +void UnalignedCopy64(const void* src, void* dst) { + char tmp[8]; + memcpy(tmp, src, 8); + memcpy(dst, tmp, 8); +} -inline void IncrementalCopyFastPath(const char* src, char* op, ssize_t len) { - while (op - src < 8) { - UnalignedCopy64(src, op); - len -= op - src; - op += op - src; +void UnalignedCopy128(const void* src, void* dst) { + // memcpy gets vectorized when the appropriate compiler options are used. + // For example, x86 compilers targeting SSE2+ will optimize to an SSE2 load + // and store. + char tmp[16]; + memcpy(tmp, src, 16); + memcpy(dst, tmp, 16); +} + +// Copy [src, src+(op_limit-op)) to [op, (op_limit-op)) a byte at a time. Used +// for handling COPY operations where the input and output regions may overlap. +// For example, suppose: +// src == "ab" +// op == src + 2 +// op_limit == op + 20 +// After IncrementalCopySlow(src, op, op_limit), the result will have eleven +// copies of "ab" +// ababababababababababab +// Note that this does not match the semantics of either memcpy() or memmove(). +inline char* IncrementalCopySlow(const char* src, char* op, + char* const op_limit) { + // TODO: Remove pragma when LLVM is aware this + // function is only called in cold regions and when cold regions don't get + // vectorized or unrolled. +#ifdef __clang__ +#pragma clang loop unroll(disable) +#endif + while (op < op_limit) { + *op++ = *src++; } - while (len > 0) { + return op_limit; +} + +#if SNAPPY_HAVE_SSSE3 + +// This is a table of shuffle control masks that can be used as the source +// operand for PSHUFB to permute the contents of the destination XMM register +// into a repeating byte pattern. +alignas(16) const char pshufb_fill_patterns[7][16] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}, + {0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0}, + {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3}, + {0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0}, + {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3}, + {0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1}, +}; + +#endif // SNAPPY_HAVE_SSSE3 + +// Copy [src, src+(op_limit-op)) to [op, (op_limit-op)) but faster than +// IncrementalCopySlow. buf_limit is the address past the end of the writable +// region of the buffer. +inline char* IncrementalCopy(const char* src, char* op, char* const op_limit, + char* const buf_limit) { + // Terminology: + // + // slop = buf_limit - op + // pat = op - src + // len = limit - op + assert(src < op); + assert(op <= op_limit); + assert(op_limit <= buf_limit); + // NOTE: The compressor always emits 4 <= len <= 64. It is ok to assume that + // to optimize this function but we have to also handle other cases in case + // the input does not satisfy these conditions. + + size_t pattern_size = op - src; + // The cases are split into different branches to allow the branch predictor, + // FDO, and static prediction hints to work better. For each input we list the + // ratio of invocations that match each condition. + // + // input slop < 16 pat < 8 len > 16 + // ------------------------------------------ + // html|html4|cp 0% 1.01% 27.73% + // urls 0% 0.88% 14.79% + // jpg 0% 64.29% 7.14% + // pdf 0% 2.56% 58.06% + // txt[1-4] 0% 0.23% 0.97% + // pb 0% 0.96% 13.88% + // bin 0.01% 22.27% 41.17% + // + // It is very rare that we don't have enough slop for doing block copies. It + // is also rare that we need to expand a pattern. Small patterns are common + // for incompressible formats and for those we are plenty fast already. + // Lengths are normally not greater than 16 but they vary depending on the + // input. In general if we always predict len <= 16 it would be an ok + // prediction. + // + // In order to be fast we want a pattern >= 8 bytes and an unrolled loop + // copying 2x 8 bytes at a time. + + // Handle the uncommon case where pattern is less than 8 bytes. + if (SNAPPY_PREDICT_FALSE(pattern_size < 8)) { +#if SNAPPY_HAVE_SSSE3 + // Load the first eight bytes into an 128-bit XMM register, then use PSHUFB + // to permute the register's contents in-place into a repeating sequence of + // the first "pattern_size" bytes. + // For example, suppose: + // src == "abc" + // op == op + 3 + // After _mm_shuffle_epi8(), "pattern" will have five copies of "abc" + // followed by one byte of slop: abcabcabcabcabca. + // + // The non-SSE fallback implementation suffers from store-forwarding stalls + // because its loads and stores partly overlap. By expanding the pattern + // in-place, we avoid the penalty. + if (SNAPPY_PREDICT_TRUE(op <= buf_limit - 16)) { + const __m128i shuffle_mask = _mm_load_si128( + reinterpret_cast(pshufb_fill_patterns) + + pattern_size - 1); + const __m128i pattern = _mm_shuffle_epi8( + _mm_loadl_epi64(reinterpret_cast(src)), shuffle_mask); + // Uninitialized bytes are masked out by the shuffle mask. + // TODO: remove annotation and macro defs once MSan is fixed. + SNAPPY_ANNOTATE_MEMORY_IS_INITIALIZED(&pattern, sizeof(pattern)); + pattern_size *= 16 / pattern_size; + char* op_end = std::min(op_limit, buf_limit - 15); + while (op < op_end) { + _mm_storeu_si128(reinterpret_cast<__m128i*>(op), pattern); + op += pattern_size; + } + if (SNAPPY_PREDICT_TRUE(op >= op_limit)) return op_limit; + } + return IncrementalCopySlow(src, op, op_limit); +#else // !SNAPPY_HAVE_SSSE3 + // If plenty of buffer space remains, expand the pattern to at least 8 + // bytes. The way the following loop is written, we need 8 bytes of buffer + // space if pattern_size >= 4, 11 bytes if pattern_size is 1 or 3, and 10 + // bytes if pattern_size is 2. Precisely encoding that is probably not + // worthwhile; instead, invoke the slow path if we cannot write 11 bytes + // (because 11 are required in the worst case). + if (SNAPPY_PREDICT_TRUE(op <= buf_limit - 11)) { + while (pattern_size < 8) { + UnalignedCopy64(src, op); + op += pattern_size; + pattern_size *= 2; + } + if (SNAPPY_PREDICT_TRUE(op >= op_limit)) return op_limit; + } else { + return IncrementalCopySlow(src, op, op_limit); + } +#endif // SNAPPY_HAVE_SSSE3 + } + assert(pattern_size >= 8); + + // Copy 2x 8 bytes at a time. Because op - src can be < 16, a single + // UnalignedCopy128 might overwrite data in op. UnalignedCopy64 is safe + // because expanding the pattern to at least 8 bytes guarantees that + // op - src >= 8. + // + // Typically, the op_limit is the gating factor so try to simplify the loop + // based on that. + if (SNAPPY_PREDICT_TRUE(op_limit <= buf_limit - 16)) { + // There is at least one, and at most four 16-byte blocks. Writing four + // conditionals instead of a loop allows FDO to layout the code with respect + // to the actual probabilities of each length. + // TODO: Replace with loop with trip count hint. + UnalignedCopy64(src, op); + UnalignedCopy64(src + 8, op + 8); + + if (op + 16 < op_limit) { + UnalignedCopy64(src + 16, op + 16); + UnalignedCopy64(src + 24, op + 24); + } + if (op + 32 < op_limit) { + UnalignedCopy64(src + 32, op + 32); + UnalignedCopy64(src + 40, op + 40); + } + if (op + 48 < op_limit) { + UnalignedCopy64(src + 48, op + 48); + UnalignedCopy64(src + 56, op + 56); + } + return op_limit; + } + + // Fall back to doing as much as we can with the available slop in the + // buffer. This code path is relatively cold however so we save code size by + // avoiding unrolling and vectorizing. + // + // TODO: Remove pragma when when cold regions don't get vectorized + // or unrolled. +#ifdef __clang__ +#pragma clang loop unroll(disable) +#endif + for (char *op_end = buf_limit - 16; op < op_end; op += 16, src += 16) { + UnalignedCopy64(src, op); + UnalignedCopy64(src + 8, op + 8); + } + if (op >= op_limit) + return op_limit; + + // We only take this branch if we didn't have enough slop and we can do a + // single 8 byte copy. + if (SNAPPY_PREDICT_FALSE(op <= buf_limit - 8)) { UnalignedCopy64(src, op); src += 8; op += 8; - len -= 8; } + return IncrementalCopySlow(src, op, op_limit); } } // namespace +template static inline char* EmitLiteral(char* op, const char* literal, - int len, - bool allow_fast_path) { - int n = len - 1; // Zero-length literals are disallowed - if (n < 60) { + int len) { + // The vast majority of copies are below 16 bytes, for which a + // call to memcpy is overkill. This fast path can sometimes + // copy up to 15 bytes too much, but that is okay in the + // main loop, since we have a bit to go on for both sides: + // + // - The input will always have kInputMarginBytes = 15 extra + // available bytes, as long as we're in the main loop, and + // if not, allow_fast_path = false. + // - The output will always have 32 spare bytes (see + // MaxCompressedLength). + assert(len > 0); // Zero-length literals are disallowed + int n = len - 1; + if (allow_fast_path && len <= 16) { // Fits in tag byte *op++ = LITERAL | (n << 2); - // The vast majority of copies are below 16 bytes, for which a - // call to memcpy is overkill. This fast path can sometimes - // copy up to 15 bytes too much, but that is okay in the - // main loop, since we have a bit to go on for both sides: - // - // - The input will always have kInputMarginBytes = 15 extra - // available bytes, as long as we're in the main loop, and - // if not, allow_fast_path = false. - // - The output will always have 32 spare bytes (see - // MaxCompressedLength). - if (allow_fast_path && len <= 16) { - UnalignedCopy64(literal, op); - UnalignedCopy64(literal + 8, op + 8); - return op + len; - } + UnalignedCopy128(literal, op); + return op + len; + } + + if (n < 60) { + // Fits in tag byte + *op++ = LITERAL | (n << 2); } else { - // Encode in upcoming bytes - char* base = op; - int count = 0; - op++; - while (n > 0) { - *op++ = n & 0xff; - n >>= 8; - count++; - } + int count = (Bits::Log2Floor(n) >> 3) + 1; assert(count >= 1); assert(count <= 4); - *base = LITERAL | ((59+count) << 2); + *op++ = LITERAL | ((59 + count) << 2); + // Encode in upcoming bytes. + // Write 4 bytes, though we may care about only 1 of them. The output buffer + // is guaranteed to have at least 3 more spaces left as 'len >= 61' holds + // here and there is a memcpy of size 'len' below. + LittleEndian::Store32(op, n); + op += count; } memcpy(op, literal, len); return op + len; } -static inline char* EmitCopyLessThan64(char* op, size_t offset, int len) { +template +static inline char* EmitCopyAtMost64(char* op, size_t offset, size_t len) { assert(len <= 64); assert(len >= 4); assert(offset < 65536); + assert(len_less_than_12 == (len < 12)); - if ((len < 12) && (offset < 2048)) { - size_t len_minus_4 = len - 4; - assert(len_minus_4 < 8); // Must fit in 3 bits - *op++ = static_cast(COPY_1_BYTE_OFFSET + ((len_minus_4) << 2) + ((offset >> 8) << 5)); + if (len_less_than_12 && SNAPPY_PREDICT_TRUE(offset < 2048)) { + // offset fits in 11 bits. The 3 highest go in the top of the first byte, + // and the rest go in the second byte. + *op++ = COPY_1_BYTE_OFFSET + ((len - 4) << 2) + ((offset >> 3) & 0xe0); *op++ = offset & 0xff; } else { - *op++ = COPY_2_BYTE_OFFSET + ((len-1) << 2); - LittleEndian::Store16(op, static_cast(offset)); - op += 2; + // Write 4 bytes, though we only care about 3 of them. The output buffer + // is required to have some slack, so the extra byte won't overrun it. + uint32 u = COPY_2_BYTE_OFFSET + ((len - 1) << 2) + (offset << 8); + LittleEndian::Store32(op, u); + op += 3; } return op; } -static inline char* EmitCopy(char* op, size_t offset, int len) { - // Emit 64 byte copies but make sure to keep at least four bytes reserved - while (len >= 68) { - op = EmitCopyLessThan64(op, offset, 64); - len -= 64; - } +template +static inline char* EmitCopy(char* op, size_t offset, size_t len) { + assert(len_less_than_12 == (len < 12)); + if (len_less_than_12) { + return EmitCopyAtMost64(op, offset, len); + } else { + // A special case for len <= 64 might help, but so far measurements suggest + // it's in the noise. - // Emit an extra 60 byte copy if have too much data to fit in one copy - if (len > 64) { - op = EmitCopyLessThan64(op, offset, 60); - len -= 60; - } + // Emit 64 byte copies but make sure to keep at least four bytes reserved. + while (SNAPPY_PREDICT_FALSE(len >= 68)) { + op = EmitCopyAtMost64(op, offset, 64); + len -= 64; + } - // Emit remainder - op = EmitCopyLessThan64(op, offset, len); - return op; + // One or two copies will now finish the job. + if (len > 64) { + op = EmitCopyAtMost64(op, offset, 60); + len -= 60; + } + + // Emit remainder. + if (len < 12) { + op = EmitCopyAtMost64(op, offset, len); + } else { + op = EmitCopyAtMost64(op, offset, len); + } + return op; + } } - bool GetUncompressedLength(const char* start, size_t n, size_t* result) { uint32 v = 0; const char* limit = start + n; @@ -289,31 +438,45 @@ bool GetUncompressedLength(const char* start, size_t n, size_t* result) { } } +namespace { +uint32 CalculateTableSize(uint32 input_size) { + static_assert( + kMaxHashTableSize >= kMinHashTableSize, + "kMaxHashTableSize should be greater or equal to kMinHashTableSize."); + if (input_size > kMaxHashTableSize) { + return kMaxHashTableSize; + } + if (input_size < kMinHashTableSize) { + return kMinHashTableSize; + } + // This is equivalent to Log2Ceiling(input_size), assuming input_size > 1. + // 2 << Log2Floor(x - 1) is equivalent to 1 << (1 + Log2Floor(x - 1)). + return 2u << Bits::Log2Floor(input_size - 1); +} +} // namespace + namespace internal { -uint16* WorkingMemory::GetHashTable(size_t input_size, int* table_size) { - // Use smaller hash table when input.size() is smaller, since we - // fill the table, incurring O(hash table size) overhead for - // compression, and if the input is short, we won't need that - // many hash table entries anyway. - assert(kMaxHashTableSize >= 256); - size_t htsize = 256; - while (htsize < kMaxHashTableSize && htsize < input_size) { - htsize <<= 1; - } +WorkingMemory::WorkingMemory(size_t input_size) { + const size_t max_fragment_size = std::min(input_size, kBlockSize); + const size_t table_size = CalculateTableSize(max_fragment_size); + size_ = table_size * sizeof(*table_) + max_fragment_size + + MaxCompressedLength(max_fragment_size); + mem_ = std::allocator().allocate(size_); + table_ = reinterpret_cast(mem_); + input_ = mem_ + table_size * sizeof(*table_); + output_ = input_ + max_fragment_size; +} - uint16* table; - if (htsize <= ARRAYSIZE(small_table_)) { - table = small_table_; - } else { - if (large_table_ == NULL) { - large_table_ = new uint16[kMaxHashTableSize]; - } - table = large_table_; - } +WorkingMemory::~WorkingMemory() { + std::allocator().deallocate(mem_, size_); +} - *table_size = static_cast(htsize); - memset(table, 0, htsize * sizeof(*table)); - return table; +uint16* WorkingMemory::GetHashTable(size_t fragment_size, + int* table_size) const { + const size_t htsize = CalculateTableSize(fragment_size); + memset(table_, 0, htsize * sizeof(*table_)); + *table_size = htsize; + return table_; } } // end namespace internal @@ -380,7 +543,7 @@ char* CompressFragment(const char* input, // "ip" is the input pointer, and "op" is the output pointer. const char* ip = input; assert(input_size <= kBlockSize); - assert((table_size & (table_size - 1)) == 0); // table must be power of two + assert((table_size & (table_size - 1)) == 0); // table must be power of two const int shift = 32 - Bits::Log2Floor(table_size); assert(static_cast(kuint32max >> shift) == table_size - 1); const char* ip_end = input + input_size; @@ -390,7 +553,7 @@ char* CompressFragment(const char* input, const char* next_emit = ip; const size_t kInputMarginBytes = 15; - if (PREDICT_TRUE(input_size >= kInputMarginBytes)) { + if (SNAPPY_PREDICT_TRUE(input_size >= kInputMarginBytes)) { const char* ip_limit = input + input_size - kInputMarginBytes; for (uint32 next_hash = Hash(++ip, shift); ; ) { @@ -410,9 +573,9 @@ char* CompressFragment(const char* input, // // Heuristic match skipping: If 32 bytes are scanned with no matches // found, start looking only at every other byte. If 32 more bytes are - // scanned, look at every third byte, etc.. When a match is found, - // immediately go back to looking at every byte. This is a small loss - // (~5% performance, ~0.1% density) for compressible data due to more + // scanned (or skipped), look at every third byte, etc.. When a match is + // found, immediately go back to looking at every byte. This is a small + // loss (~5% performance, ~0.1% density) for compressible data due to more // bookkeeping, but for non-compressible data (such as JPEG) it's a huge // win since the compressor quickly "realizes" the data is incompressible // and doesn't bother looking for matches everywhere. @@ -428,9 +591,10 @@ char* CompressFragment(const char* input, ip = next_ip; uint32 hash = next_hash; assert(hash == Hash(ip, shift)); - uint32 bytes_between_hash_lookups = skip++ >> 5; + uint32 bytes_between_hash_lookups = skip >> 5; + skip += bytes_between_hash_lookups; next_ip = ip + bytes_between_hash_lookups; - if (PREDICT_FALSE(next_ip > ip_limit)) { + if (SNAPPY_PREDICT_FALSE(next_ip > ip_limit)) { goto emit_remainder; } next_hash = Hash(next_ip, shift); @@ -439,14 +603,14 @@ char* CompressFragment(const char* input, assert(candidate < ip); table[hash] = ip - base_ip; - } while (PREDICT_TRUE(UNALIGNED_LOAD32(ip) != - UNALIGNED_LOAD32(candidate))); + } while (SNAPPY_PREDICT_TRUE(UNALIGNED_LOAD32(ip) != + UNALIGNED_LOAD32(candidate))); // Step 2: A 4-byte match has been found. We'll later see if more // than 4 bytes match. But, prior to the match, input // bytes [next_emit, ip) are unmatched. Emit them as "literal bytes." assert(next_emit + 16 <= ip_end); - op = EmitLiteral(op, next_emit, ip - next_emit, true); + op = EmitLiteral(op, next_emit, ip - next_emit); // Step 3: Call EmitCopy, and then see if another EmitCopy could // be our next move. Repeat until we find no match for the @@ -463,19 +627,25 @@ char* CompressFragment(const char* input, // We have a 4-byte match at ip, and no need to emit any // "literal bytes" prior to ip. const char* base = ip; - int matched = 4 + FindMatchLength(candidate + 4, ip + 4, ip_end); + std::pair p = + FindMatchLength(candidate + 4, ip + 4, ip_end); + size_t matched = 4 + p.first; ip += matched; size_t offset = base - candidate; assert(0 == memcmp(base, candidate, matched)); - op = EmitCopy(op, offset, matched); - // We could immediately start working at ip now, but to improve - // compression we first update table[Hash(ip - 1, ...)]. - const char* insert_tail = ip - 1; + if (p.second) { + op = EmitCopy(op, offset, matched); + } else { + op = EmitCopy(op, offset, matched); + } next_emit = ip; - if (PREDICT_FALSE(ip >= ip_limit)) { + if (SNAPPY_PREDICT_FALSE(ip >= ip_limit)) { goto emit_remainder; } - input_bytes = GetEightBytesAt(insert_tail); + // We are now looking for a 4-byte match again. We read + // table[Hash(ip, shift)] for that. To improve compression, + // we also update table[Hash(ip - 1, shift)] and table[Hash(ip, shift)]. + input_bytes = GetEightBytesAt(ip - 1); uint32 prev_hash = HashBytes(GetUint32AtOffset(input_bytes, 0), shift); table[prev_hash] = ip - base_ip - 1; uint32 cur_hash = HashBytes(GetUint32AtOffset(input_bytes, 1), shift); @@ -492,13 +662,18 @@ char* CompressFragment(const char* input, emit_remainder: // Emit the remaining bytes as a literal if (next_emit < ip_end) { - op = EmitLiteral(op, next_emit, ip_end - next_emit, false); + op = EmitLiteral(op, next_emit, + ip_end - next_emit); } return op; } } // end namespace internal +// Called back at avery compression call to trace parameters and sizes. +static inline void Report(const char *algorithm, size_t compressed_size, + size_t uncompressed_size) {} + // Signature of output types needed by decompression code. // The decompression code is templatized on a type that obeys this // signature so that we do not pay virtual function call overhead in @@ -539,162 +714,28 @@ char* CompressFragment(const char* input, // bool TryFastAppend(const char* ip, size_t available, size_t length); // }; -// ----------------------------------------------------------------------- -// Lookup table for decompression code. Generated by ComputeTable() below. -// ----------------------------------------------------------------------- - -// Mapping from i in range [0,4] to a mask to extract the bottom 8*i bits -static const uint32 wordmask[] = { - 0u, 0xffu, 0xffffu, 0xffffffu, 0xffffffffu -}; - -// Data stored per entry in lookup table: -// Range Bits-used Description -// ------------------------------------ -// 1..64 0..7 Literal/copy length encoded in opcode byte -// 0..7 8..10 Copy offset encoded in opcode byte / 256 -// 0..4 11..13 Extra bytes after opcode -// -// We use eight bits for the length even though 7 would have sufficed -// because of efficiency reasons: -// (1) Extracting a byte is faster than a bit-field -// (2) It properly aligns copy offset so we do not need a <<8 -static const uint16 char_table[256] = { - 0x0001, 0x0804, 0x1001, 0x2001, 0x0002, 0x0805, 0x1002, 0x2002, - 0x0003, 0x0806, 0x1003, 0x2003, 0x0004, 0x0807, 0x1004, 0x2004, - 0x0005, 0x0808, 0x1005, 0x2005, 0x0006, 0x0809, 0x1006, 0x2006, - 0x0007, 0x080a, 0x1007, 0x2007, 0x0008, 0x080b, 0x1008, 0x2008, - 0x0009, 0x0904, 0x1009, 0x2009, 0x000a, 0x0905, 0x100a, 0x200a, - 0x000b, 0x0906, 0x100b, 0x200b, 0x000c, 0x0907, 0x100c, 0x200c, - 0x000d, 0x0908, 0x100d, 0x200d, 0x000e, 0x0909, 0x100e, 0x200e, - 0x000f, 0x090a, 0x100f, 0x200f, 0x0010, 0x090b, 0x1010, 0x2010, - 0x0011, 0x0a04, 0x1011, 0x2011, 0x0012, 0x0a05, 0x1012, 0x2012, - 0x0013, 0x0a06, 0x1013, 0x2013, 0x0014, 0x0a07, 0x1014, 0x2014, - 0x0015, 0x0a08, 0x1015, 0x2015, 0x0016, 0x0a09, 0x1016, 0x2016, - 0x0017, 0x0a0a, 0x1017, 0x2017, 0x0018, 0x0a0b, 0x1018, 0x2018, - 0x0019, 0x0b04, 0x1019, 0x2019, 0x001a, 0x0b05, 0x101a, 0x201a, - 0x001b, 0x0b06, 0x101b, 0x201b, 0x001c, 0x0b07, 0x101c, 0x201c, - 0x001d, 0x0b08, 0x101d, 0x201d, 0x001e, 0x0b09, 0x101e, 0x201e, - 0x001f, 0x0b0a, 0x101f, 0x201f, 0x0020, 0x0b0b, 0x1020, 0x2020, - 0x0021, 0x0c04, 0x1021, 0x2021, 0x0022, 0x0c05, 0x1022, 0x2022, - 0x0023, 0x0c06, 0x1023, 0x2023, 0x0024, 0x0c07, 0x1024, 0x2024, - 0x0025, 0x0c08, 0x1025, 0x2025, 0x0026, 0x0c09, 0x1026, 0x2026, - 0x0027, 0x0c0a, 0x1027, 0x2027, 0x0028, 0x0c0b, 0x1028, 0x2028, - 0x0029, 0x0d04, 0x1029, 0x2029, 0x002a, 0x0d05, 0x102a, 0x202a, - 0x002b, 0x0d06, 0x102b, 0x202b, 0x002c, 0x0d07, 0x102c, 0x202c, - 0x002d, 0x0d08, 0x102d, 0x202d, 0x002e, 0x0d09, 0x102e, 0x202e, - 0x002f, 0x0d0a, 0x102f, 0x202f, 0x0030, 0x0d0b, 0x1030, 0x2030, - 0x0031, 0x0e04, 0x1031, 0x2031, 0x0032, 0x0e05, 0x1032, 0x2032, - 0x0033, 0x0e06, 0x1033, 0x2033, 0x0034, 0x0e07, 0x1034, 0x2034, - 0x0035, 0x0e08, 0x1035, 0x2035, 0x0036, 0x0e09, 0x1036, 0x2036, - 0x0037, 0x0e0a, 0x1037, 0x2037, 0x0038, 0x0e0b, 0x1038, 0x2038, - 0x0039, 0x0f04, 0x1039, 0x2039, 0x003a, 0x0f05, 0x103a, 0x203a, - 0x003b, 0x0f06, 0x103b, 0x203b, 0x003c, 0x0f07, 0x103c, 0x203c, - 0x0801, 0x0f08, 0x103d, 0x203d, 0x1001, 0x0f09, 0x103e, 0x203e, - 0x1801, 0x0f0a, 0x103f, 0x203f, 0x2001, 0x0f0b, 0x1040, 0x2040 -}; - -// In debug mode, allow optional computation of the table at startup. -// Also, check that the decompression table is correct. -#ifdef _DEBUG -DEFINE_bool(snappy_dump_decompression_table, false, - "If true, we print the decompression table at startup."); - -static uint16 MakeEntry(unsigned int extra, - unsigned int len, - unsigned int copy_offset) { - // Check that all of the fields fit within the allocated space - assert(extra == (extra & 0x7)); // At most 3 bits - assert(copy_offset == (copy_offset & 0x7)); // At most 3 bits - assert(len == (len & 0x7f)); // At most 7 bits - return len | (copy_offset << 8) | (extra << 11); +static inline uint32 ExtractLowBytes(uint32 v, int n) { + assert(n >= 0); + assert(n <= 4); +#if SNAPPY_HAVE_BMI2 + return _bzhi_u32(v, 8 * n); +#else + // This needs to be wider than uint32 otherwise `mask << 32` will be + // undefined. + uint64 mask = 0xffffffff; + return v & ~(mask << (8 * n)); +#endif } -static void ComputeTable() { - uint16 dst[256]; - - // Place invalid entries in all places to detect missing initialization - int assigned = 0; - for (int i = 0; i < 256; i++) { - dst[i] = 0xffff; - } - - // Small LITERAL entries. We store (len-1) in the top 6 bits. - for (unsigned int len = 1; len <= 60; len++) { - dst[LITERAL | ((len-1) << 2)] = MakeEntry(0, len, 0); - assigned++; - } - - // Large LITERAL entries. We use 60..63 in the high 6 bits to - // encode the number of bytes of length info that follow the opcode. - for (unsigned int extra_bytes = 1; extra_bytes <= 4; extra_bytes++) { - // We set the length field in the lookup table to 1 because extra - // bytes encode len-1. - dst[LITERAL | ((extra_bytes+59) << 2)] = MakeEntry(extra_bytes, 1, 0); - assigned++; - } - - // COPY_1_BYTE_OFFSET. - // - // The tag byte in the compressed data stores len-4 in 3 bits, and - // offset/256 in 5 bits. offset%256 is stored in the next byte. - // - // This format is used for length in range [4..11] and offset in - // range [0..2047] - for (unsigned int len = 4; len < 12; len++) { - for (unsigned int offset = 0; offset < 2048; offset += 256) { - dst[COPY_1_BYTE_OFFSET | ((len-4)<<2) | ((offset>>8)<<5)] = - MakeEntry(1, len, offset>>8); - assigned++; - } - } - - // COPY_2_BYTE_OFFSET. - // Tag contains len-1 in top 6 bits, and offset in next two bytes. - for (unsigned int len = 1; len <= 64; len++) { - dst[COPY_2_BYTE_OFFSET | ((len-1)<<2)] = MakeEntry(2, len, 0); - assigned++; - } - - // COPY_4_BYTE_OFFSET. - // Tag contents len-1 in top 6 bits, and offset in next four bytes. - for (unsigned int len = 1; len <= 64; len++) { - dst[COPY_4_BYTE_OFFSET | ((len-1)<<2)] = MakeEntry(4, len, 0); - assigned++; - } - - // Check that each entry was initialized exactly once. - if (assigned != 256) { - fprintf(stderr, "ComputeTable: assigned only %d of 256\n", assigned); - abort(); - } - for (int i = 0; i < 256; i++) { - if (dst[i] == 0xffff) { - fprintf(stderr, "ComputeTable: did not assign byte %d\n", i); - abort(); - } - } - - if (FLAGS_snappy_dump_decompression_table) { - printf("static const uint16 char_table[256] = {\n "); - for (int i = 0; i < 256; i++) { - printf("0x%04x%s", - dst[i], - ((i == 255) ? "\n" : (((i%8) == 7) ? ",\n " : ", "))); - } - printf("};\n"); - } - - // Check that computed table matched recorded table - for (int i = 0; i < 256; i++) { - if (dst[i] != char_table[i]) { - fprintf(stderr, "ComputeTable: byte %d: computed (%x), expect (%x)\n", - i, static_cast(dst[i]), static_cast(char_table[i])); - abort(); - } - } +static inline bool LeftShiftOverflows(uint8 value, uint32 shift) { + assert(shift < 32); + static const uint8 masks[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; + return (value & masks[shift]) != 0; } -#endif /* !NDEBUG */ // Helper class for decompression class SnappyDecompressor { @@ -733,7 +774,7 @@ class SnappyDecompressor { } // Read the uncompressed length stored at the start of the compressed data. - // On succcess, stores the length in *result and returns true. + // On success, stores the length in *result and returns true. // On failure, returns false. bool ReadUncompressedLength(uint32* result) { assert(ip_ == NULL); // Must not have read anything yet @@ -747,7 +788,9 @@ class SnappyDecompressor { if (n == 0) return false; const unsigned char c = *(reinterpret_cast(ip)); reader_->Skip(1); - *result |= static_cast(c & 0x7f) << shift; + uint32 val = c & 0x7f; + if (LeftShiftOverflows(static_cast(val), shift)) return false; + *result |= val << shift; if (c < 128) { break; } @@ -759,9 +802,27 @@ class SnappyDecompressor { // Process the next item found in the input. // Returns true if successful, false on error or end of input. template +#if defined(__GNUC__) && defined(__x86_64__) + __attribute__((aligned(32))) +#endif void DecompressAllTags(Writer* writer) { - const char* ip = ip_; + // In x86, pad the function body to start 16 bytes later. This function has + // a couple of hotspots that are highly sensitive to alignment: we have + // observed regressions by more than 20% in some metrics just by moving the + // exact same code to a different position in the benchmark binary. + // + // Putting this code on a 32-byte-aligned boundary + 16 bytes makes us hit + // the "lucky" case consistently. Unfortunately, this is a very brittle + // workaround, and future differences in code generation may reintroduce + // this regression. If you experience a big, difficult to explain, benchmark + // performance regression here, first try removing this hack. +#if defined(__GNUC__) && defined(__x86_64__) + // Two 8-byte "NOP DWORD ptr [EAX + EAX*1 + 00000000H]" instructions. + asm(".byte 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00"); + asm(".byte 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00"); +#endif + const char* ip = ip_; // We could have put this refill fragment only at the beginning of the loop. // However, duplicating it at the end of each branch gives the compiler more // scope to optimize the expression based on the local @@ -777,21 +838,34 @@ class SnappyDecompressor { for ( ;; ) { const unsigned char c = *(reinterpret_cast(ip++)); - if ((c & 0x3) == LITERAL) { + // Ratio of iterations that have LITERAL vs non-LITERAL for different + // inputs. + // + // input LITERAL NON_LITERAL + // ----------------------------------- + // html|html4|cp 23% 77% + // urls 36% 64% + // jpg 47% 53% + // pdf 19% 81% + // txt[1-4] 25% 75% + // pb 24% 76% + // bin 24% 76% + if (SNAPPY_PREDICT_FALSE((c & 0x3) == LITERAL)) { size_t literal_length = (c >> 2) + 1u; if (writer->TryFastAppend(ip, ip_limit_ - ip, literal_length)) { assert(literal_length < 61); ip += literal_length; - // NOTE(user): There is no MAYBE_REFILL() here, as TryFastAppend() + // NOTE: There is no MAYBE_REFILL() here, as TryFastAppend() // will not return true unless there's already at least five spare // bytes in addition to the literal. continue; } - if (PREDICT_FALSE(literal_length >= 61)) { + if (SNAPPY_PREDICT_FALSE(literal_length >= 61)) { // Long literal. const size_t literal_length_length = literal_length - 60; literal_length = - (LittleEndian::Load32(ip) & wordmask[literal_length_length]) + 1; + ExtractLowBytes(LittleEndian::Load32(ip), literal_length_length) + + 1; ip += literal_length_length; } @@ -803,7 +877,7 @@ class SnappyDecompressor { size_t n; ip = reader_->Peek(&n); avail = n; - peeked_ = static_cast(avail); + peeked_ = avail; if (avail == 0) return; // Premature end of input ip_limit_ = ip + avail; } @@ -813,15 +887,16 @@ class SnappyDecompressor { ip += literal_length; MAYBE_REFILL(); } else { - const uint32 entry = char_table[c]; - const uint32 trailer = LittleEndian::Load32(ip) & wordmask[entry >> 11]; - const uint32 length = entry & 0xff; + const size_t entry = char_table[c]; + const size_t trailer = + ExtractLowBytes(LittleEndian::Load32(ip), entry >> 11); + const size_t length = entry & 0xff; ip += entry >> 11; // copy_offset/256 is encoded in bits 8..10. By just fetching // those bits, we get copy_offset (since the bit-field starts at // bit 8). - const uint32 copy_offset = entry & 0x700; + const size_t copy_offset = entry & 0x700; if (!writer->AppendFromSelf(copy_offset + trailer, length)) { return; } @@ -840,11 +915,9 @@ bool SnappyDecompressor::RefillTag() { reader_->Skip(peeked_); // All peeked bytes are used up size_t n; ip = reader_->Peek(&n); - peeked_ = static_cast(n); - if (n == 0) { - eof_ = true; - return false; - } + peeked_ = n; + eof_ = (n == 0); + if (eof_) return false; ip_limit_ = ip + n; } @@ -869,7 +942,7 @@ bool SnappyDecompressor::RefillTag() { size_t length; const char* src = reader_->Peek(&length); if (length == 0) return false; - uint32 to_add = min(needed - nbuf, static_cast(length)); + uint32 to_add = std::min(needed - nbuf, length); memcpy(scratch_ + nbuf, src, to_add); nbuf += to_add; reader_->Skip(to_add); @@ -898,17 +971,23 @@ static bool InternalUncompress(Source* r, Writer* writer) { SnappyDecompressor decompressor(r); uint32 uncompressed_len = 0; if (!decompressor.ReadUncompressedLength(&uncompressed_len)) return false; - return InternalUncompressAllTags(&decompressor, writer, uncompressed_len); + + return InternalUncompressAllTags(&decompressor, writer, r->Available(), + uncompressed_len); } template static bool InternalUncompressAllTags(SnappyDecompressor* decompressor, Writer* writer, + uint32 compressed_len, uint32 uncompressed_len) { + Report("snappy_uncompress", compressed_len, uncompressed_len); + writer->SetExpectedLength(uncompressed_len); // Process the entire input decompressor->DecompressAllTags(writer); + writer->Flush(); return (decompressor->eof() && writer->CheckLength()); } @@ -920,21 +999,20 @@ bool GetUncompressedLength(Source* source, uint32* result) { size_t Compress(Source* reader, Sink* writer) { size_t written = 0; size_t N = reader->Available(); + const size_t uncompressed_size = N; char ulength[Varint::kMax32]; - char* p = Varint::Encode32(ulength, static_cast(N)); + char* p = Varint::Encode32(ulength, N); writer->Append(ulength, p-ulength); written += (p - ulength); - internal::WorkingMemory wmem; - char* scratch = NULL; - char* scratch_output = NULL; + internal::WorkingMemory wmem(N); while (N > 0) { // Get next block to compress (without copying if possible) size_t fragment_size; const char* fragment = reader->Peek(&fragment_size); assert(fragment_size != 0); // premature end of input - const size_t num_to_read = min(N, kBlockSize); + const size_t num_to_read = std::min(N, kBlockSize); size_t bytes_read = fragment_size; size_t pending_advance = 0; @@ -943,19 +1021,13 @@ size_t Compress(Source* reader, Sink* writer) { pending_advance = num_to_read; fragment_size = num_to_read; } else { - // Read into scratch buffer - if (scratch == NULL) { - // If this is the last iteration, we want to allocate N bytes - // of space, otherwise the max possible kBlockSize space. - // num_to_read contains exactly the correct value - scratch = new char[num_to_read]; - } + char* scratch = wmem.GetScratchInput(); memcpy(scratch, fragment, bytes_read); reader->Skip(bytes_read); while (bytes_read < num_to_read) { fragment = reader->Peek(&fragment_size); - size_t n = min(fragment_size, num_to_read - bytes_read); + size_t n = std::min(fragment_size, num_to_read - bytes_read); memcpy(scratch + bytes_read, fragment, n); bytes_read += n; reader->Skip(n); @@ -971,20 +1043,17 @@ size_t Compress(Source* reader, Sink* writer) { uint16* table = wmem.GetHashTable(num_to_read, &table_size); // Compress input_fragment and append to dest - const size_t max_output = MaxCompressedLength(num_to_read); + const int max_output = MaxCompressedLength(num_to_read); // Need a scratch buffer for the output, in case the byte sink doesn't // have room for us directly. - if (scratch_output == NULL) { - scratch_output = new char[max_output]; - } else { - // Since we encode kBlockSize regions followed by a region - // which is <= kBlockSize in length, a previously allocated - // scratch_output[] region is big enough for this iteration. - } - char* dest = writer->GetAppendBuffer(max_output, scratch_output); - char* end = internal::CompressFragment(fragment, fragment_size, - dest, table, table_size); + + // Since we encode kBlockSize regions followed by a region + // which is <= kBlockSize in length, a previously allocated + // scratch_output[] region is big enough for this iteration. + char* dest = writer->GetAppendBuffer(max_output, wmem.GetScratchOutput()); + char* end = internal::CompressFragment(fragment, fragment_size, dest, table, + table_size); writer->Append(dest, end - dest); written += (end - dest); @@ -992,8 +1061,7 @@ size_t Compress(Source* reader, Sink* writer) { reader->Skip(pending_advance); } - delete[] scratch; - delete[] scratch_output; + Report("snappy_compress", written, uncompressed_size); return written; } @@ -1007,14 +1075,22 @@ size_t Compress(Source* reader, Sink* writer) { // Writer template argument to SnappyDecompressor::DecompressAllTags(). class SnappyIOVecWriter { private: + // output_iov_end_ is set to iov + count and used to determine when + // the end of the iovs is reached. + const struct iovec* output_iov_end_; + +#if !defined(NDEBUG) const struct iovec* output_iov_; - const size_t output_iov_count_; +#endif // !defined(NDEBUG) - // We are currently writing into output_iov_[curr_iov_index_]. - int curr_iov_index_; + // Current iov that is being written into. + const struct iovec* curr_iov_; - // Bytes written to output_iov_[curr_iov_index_] so far. - size_t curr_iov_written_; + // Pointer to current iov's write location. + char* curr_iov_output_; + + // Remaining bytes to write into curr_iov_output. + size_t curr_iov_remaining_; // Total bytes decompressed into output_iov_ so far. size_t total_written_; @@ -1022,22 +1098,24 @@ class SnappyIOVecWriter { // Maximum number of bytes that will be decompressed into output_iov_. size_t output_limit_; - inline char* GetIOVecPointer(int index, size_t offset) { - return reinterpret_cast(output_iov_[index].iov_base) + - offset; + static inline char* GetIOVecPointer(const struct iovec* iov, size_t offset) { + return reinterpret_cast(iov->iov_base) + offset; } public: // Does not take ownership of iov. iov must be valid during the // entire lifetime of the SnappyIOVecWriter. inline SnappyIOVecWriter(const struct iovec* iov, size_t iov_count) - : output_iov_(iov), - output_iov_count_(iov_count), - curr_iov_index_(0), - curr_iov_written_(0), + : output_iov_end_(iov + iov_count), +#if !defined(NDEBUG) + output_iov_(iov), +#endif // !defined(NDEBUG) + curr_iov_(iov), + curr_iov_output_(iov_count ? reinterpret_cast(iov->iov_base) + : nullptr), + curr_iov_remaining_(iov_count ? iov->iov_len : 0), total_written_(0), - output_limit_(-1) { - } + output_limit_(-1) {} inline void SetExpectedLength(size_t len) { output_limit_ = len; @@ -1052,23 +1130,25 @@ class SnappyIOVecWriter { return false; } + return AppendNoCheck(ip, len); + } + + inline bool AppendNoCheck(const char* ip, size_t len) { while (len > 0) { - assert(curr_iov_written_ <= output_iov_[curr_iov_index_].iov_len); - if (curr_iov_written_ >= output_iov_[curr_iov_index_].iov_len) { + if (curr_iov_remaining_ == 0) { // This iovec is full. Go to the next one. - if (static_cast(curr_iov_index_) + 1 >= output_iov_count_) { + if (curr_iov_ + 1 >= output_iov_end_) { return false; } - curr_iov_written_ = 0; - ++curr_iov_index_; + ++curr_iov_; + curr_iov_output_ = reinterpret_cast(curr_iov_->iov_base); + curr_iov_remaining_ = curr_iov_->iov_len; } - const size_t to_write = std::min( - len, output_iov_[curr_iov_index_].iov_len - curr_iov_written_); - memcpy(GetIOVecPointer(curr_iov_index_, curr_iov_written_), - ip, - to_write); - curr_iov_written_ += to_write; + const size_t to_write = std::min(len, curr_iov_remaining_); + memcpy(curr_iov_output_, ip, to_write); + curr_iov_output_ += to_write; + curr_iov_remaining_ -= to_write; total_written_ += to_write; ip += to_write; len -= to_write; @@ -1080,12 +1160,11 @@ class SnappyIOVecWriter { inline bool TryFastAppend(const char* ip, size_t available, size_t len) { const size_t space_left = output_limit_ - total_written_; if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16 && - output_iov_[curr_iov_index_].iov_len - curr_iov_written_ >= 16) { + curr_iov_remaining_ >= 16) { // Fast path, used for the majority (about 95%) of invocations. - char* ptr = GetIOVecPointer(curr_iov_index_, curr_iov_written_); - UnalignedCopy64(ip, ptr); - UnalignedCopy64(ip + 8, ptr + 8); - curr_iov_written_ += len; + UnalignedCopy128(ip, curr_iov_output_); + curr_iov_output_ += len; + curr_iov_remaining_ -= len; total_written_ += len; return true; } @@ -1094,7 +1173,9 @@ class SnappyIOVecWriter { } inline bool AppendFromSelf(size_t offset, size_t len) { - if (offset > total_written_ || offset == 0) { + // See SnappyArrayWriter::AppendFromSelf for an explanation of + // the "offset - 1u" trick. + if (offset - 1u >= total_written_) { return false; } const size_t space_left = output_limit_ - total_written_; @@ -1103,8 +1184,8 @@ class SnappyIOVecWriter { } // Locate the iovec from which we need to start the copy. - int from_iov_index = curr_iov_index_; - size_t from_iov_offset = curr_iov_written_; + const iovec* from_iov = curr_iov_; + size_t from_iov_offset = curr_iov_->iov_len - curr_iov_remaining_; while (offset > 0) { if (from_iov_offset >= offset) { from_iov_offset -= offset; @@ -1112,46 +1193,47 @@ class SnappyIOVecWriter { } offset -= from_iov_offset; - --from_iov_index; - assert(from_iov_index >= 0); - from_iov_offset = output_iov_[from_iov_index].iov_len; + --from_iov; +#if !defined(NDEBUG) + assert(from_iov >= output_iov_); +#endif // !defined(NDEBUG) + from_iov_offset = from_iov->iov_len; } // Copy bytes starting from the iovec pointed to by from_iov_index to // the current iovec. while (len > 0) { - assert(from_iov_index <= curr_iov_index_); - if (from_iov_index != curr_iov_index_) { - const size_t to_copy = std::min( - output_iov_[from_iov_index].iov_len - from_iov_offset, - len); - Append(GetIOVecPointer(from_iov_index, from_iov_offset), to_copy); + assert(from_iov <= curr_iov_); + if (from_iov != curr_iov_) { + const size_t to_copy = + std::min(from_iov->iov_len - from_iov_offset, len); + AppendNoCheck(GetIOVecPointer(from_iov, from_iov_offset), to_copy); len -= to_copy; if (len > 0) { - ++from_iov_index; + ++from_iov; from_iov_offset = 0; } } else { - assert(curr_iov_written_ <= output_iov_[curr_iov_index_].iov_len); - size_t to_copy = std::min(output_iov_[curr_iov_index_].iov_len - - curr_iov_written_, - len); + size_t to_copy = curr_iov_remaining_; if (to_copy == 0) { // This iovec is full. Go to the next one. - if (static_cast(curr_iov_index_) + 1 >= output_iov_count_) { + if (curr_iov_ + 1 >= output_iov_end_) { return false; } - ++curr_iov_index_; - curr_iov_written_ = 0; + ++curr_iov_; + curr_iov_output_ = reinterpret_cast(curr_iov_->iov_base); + curr_iov_remaining_ = curr_iov_->iov_len; continue; } if (to_copy > len) { to_copy = len; } - IncrementalCopy(GetIOVecPointer(from_iov_index, from_iov_offset), - GetIOVecPointer(curr_iov_index_, curr_iov_written_), - to_copy); - curr_iov_written_ += to_copy; + + IncrementalCopy(GetIOVecPointer(from_iov, from_iov_offset), + curr_iov_output_, curr_iov_output_ + to_copy, + curr_iov_output_ + curr_iov_remaining_); + curr_iov_output_ += to_copy; + curr_iov_remaining_ -= to_copy; from_iov_offset += to_copy; total_written_ += to_copy; len -= to_copy; @@ -1161,20 +1243,21 @@ class SnappyIOVecWriter { return true; } + inline void Flush() {} }; -bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov, - size_t iov_cnt) { - SnappyIOVecWriter output(iov, iov_cnt); - return InternalUncompress(compressed, &output); -} - bool RawUncompressToIOVec(const char* compressed, size_t compressed_length, const struct iovec* iov, size_t iov_cnt) { ByteArraySource reader(compressed, compressed_length); return RawUncompressToIOVec(&reader, iov, iov_cnt); } +bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov, + size_t iov_cnt) { + SnappyIOVecWriter output(iov, iov_cnt); + return InternalUncompress(compressed, &output); +} + // ----------------------------------------------------------------------- // Flat array interfaces // ----------------------------------------------------------------------- @@ -1191,7 +1274,8 @@ class SnappyArrayWriter { public: inline explicit SnappyArrayWriter(char* dst) : base_(dst), - op_(dst) { + op_(dst), + op_limit_(dst) { } inline void SetExpectedLength(size_t len) { @@ -1218,8 +1302,7 @@ class SnappyArrayWriter { const size_t space_left = op_limit_ - op; if (len <= 16 && available >= 16 + kMaximumTagLength && space_left >= 16) { // Fast path, used for the majority (about 95%) of invocations. - UnalignedCopy64(ip, op); - UnalignedCopy64(ip + 8, op + 8); + UnalignedCopy128(ip, op); op_ = op + len; return true; } else { @@ -1228,8 +1311,7 @@ class SnappyArrayWriter { } inline bool AppendFromSelf(size_t offset, size_t len) { - char* op = op_; - const size_t space_left = op_limit_ - op; + char* const op_end = op_ + len; // Check if we try to append from before the start of the buffer. // Normally this would just be a check for "produced < offset", @@ -1238,29 +1320,16 @@ class SnappyArrayWriter { // to a very big number. This is convenient, as offset==0 is another // invalid case that we also want to catch, so that we do not go // into an infinite loop. - assert(op >= base_); - size_t produced = op - base_; - if (produced <= offset - 1u) { - return false; - } - if (len <= 16 && offset >= 8 && space_left >= 16) { - // Fast path, used for the majority (70-80%) of dynamic invocations. - UnalignedCopy64(op - offset, op); - UnalignedCopy64(op - offset + 8, op + 8); - } else { - if (space_left >= len + kMaxIncrementCopyOverflow) { - IncrementalCopyFastPath(op - offset, op, len); - } else { - if (space_left < len) { - return false; - } - IncrementalCopy(op - offset, op, len); - } - } + if (Produced() <= offset - 1u || op_end > op_limit_) return false; + op_ = IncrementalCopy(op_ - offset, op_, op_end, op_limit_); - op_ = op + len; return true; } + inline size_t Produced() const { + assert(op_ >= base_); + return op_ - base_; + } + inline void Flush() {} }; bool RawUncompress(const char* compressed, size_t n, char* uncompressed) { @@ -1273,7 +1342,7 @@ bool RawUncompress(Source* compressed, char* uncompressed) { return InternalUncompress(compressed, &output); } -bool Uncompress(const char* compressed, size_t n, string* uncompressed) { +bool Uncompress(const char* compressed, size_t n, std::string* uncompressed) { size_t ulength; if (!GetUncompressedLength(compressed, n, &ulength)) { return false; @@ -1287,7 +1356,6 @@ bool Uncompress(const char* compressed, size_t n, string* uncompressed) { return RawUncompress(compressed, n, string_as_array(uncompressed)); } - // A Writer that drops everything on the floor and just does validation class SnappyDecompressionValidator { private: @@ -1295,7 +1363,7 @@ class SnappyDecompressionValidator { size_t produced_; public: - inline SnappyDecompressionValidator() : produced_(0) { } + inline SnappyDecompressionValidator() : expected_(0), produced_(0) { } inline void SetExpectedLength(size_t len) { expected_ = len; } @@ -1316,6 +1384,7 @@ class SnappyDecompressionValidator { produced_ += len; return produced_ <= expected_; } + inline void Flush() {} }; bool IsValidCompressedBuffer(const char* compressed, size_t n) { @@ -1324,6 +1393,11 @@ bool IsValidCompressedBuffer(const char* compressed, size_t n) { return InternalUncompress(&reader, &writer); } +bool IsValidCompressed(Source* compressed) { + SnappyDecompressionValidator writer; + return InternalUncompress(compressed, &writer); +} + void RawCompress(const char* input, size_t input_length, char* compressed, @@ -1336,9 +1410,10 @@ void RawCompress(const char* input, *compressed_length = (writer.CurrentDestination() - compressed); } -size_t Compress(const char* input, size_t input_length, string* compressed) { +size_t Compress(const char* input, size_t input_length, + std::string* compressed) { // Pre-grow the buffer to the max length of the compressed output - compressed->resize(MaxCompressedLength(input_length)); + STLStringResizeUninitialized(compressed, MaxCompressedLength(input_length)); size_t compressed_length; RawCompress(input, input_length, string_as_array(compressed), @@ -1347,6 +1422,240 @@ size_t Compress(const char* input, size_t input_length, string* compressed) { return compressed_length; } +// ----------------------------------------------------------------------- +// Sink interface +// ----------------------------------------------------------------------- -} // end namespace snappy +// A type that decompresses into a Sink. The template parameter +// Allocator must export one method "char* Allocate(int size);", which +// allocates a buffer of "size" and appends that to the destination. +template +class SnappyScatteredWriter { + Allocator allocator_; + // We need random access into the data generated so far. Therefore + // we keep track of all of the generated data as an array of blocks. + // All of the blocks except the last have length kBlockSize. + std::vector blocks_; + size_t expected_; + + // Total size of all fully generated blocks so far + size_t full_size_; + + // Pointer into current output block + char* op_base_; // Base of output block + char* op_ptr_; // Pointer to next unfilled byte in block + char* op_limit_; // Pointer just past block + + inline size_t Size() const { + return full_size_ + (op_ptr_ - op_base_); + } + + bool SlowAppend(const char* ip, size_t len); + bool SlowAppendFromSelf(size_t offset, size_t len); + + public: + inline explicit SnappyScatteredWriter(const Allocator& allocator) + : allocator_(allocator), + full_size_(0), + op_base_(NULL), + op_ptr_(NULL), + op_limit_(NULL) { + } + + inline void SetExpectedLength(size_t len) { + assert(blocks_.empty()); + expected_ = len; + } + + inline bool CheckLength() const { + return Size() == expected_; + } + + // Return the number of bytes actually uncompressed so far + inline size_t Produced() const { + return Size(); + } + + inline bool Append(const char* ip, size_t len) { + size_t avail = op_limit_ - op_ptr_; + if (len <= avail) { + // Fast path + memcpy(op_ptr_, ip, len); + op_ptr_ += len; + return true; + } else { + return SlowAppend(ip, len); + } + } + + inline bool TryFastAppend(const char* ip, size_t available, size_t length) { + char* op = op_ptr_; + const int space_left = op_limit_ - op; + if (length <= 16 && available >= 16 + kMaximumTagLength && + space_left >= 16) { + // Fast path, used for the majority (about 95%) of invocations. + UnalignedCopy128(ip, op); + op_ptr_ = op + length; + return true; + } else { + return false; + } + } + + inline bool AppendFromSelf(size_t offset, size_t len) { + char* const op_end = op_ptr_ + len; + // See SnappyArrayWriter::AppendFromSelf for an explanation of + // the "offset - 1u" trick. + if (SNAPPY_PREDICT_TRUE(offset - 1u < op_ptr_ - op_base_ && + op_end <= op_limit_)) { + // Fast path: src and dst in current block. + op_ptr_ = IncrementalCopy(op_ptr_ - offset, op_ptr_, op_end, op_limit_); + return true; + } + return SlowAppendFromSelf(offset, len); + } + + // Called at the end of the decompress. We ask the allocator + // write all blocks to the sink. + inline void Flush() { allocator_.Flush(Produced()); } +}; + +template +bool SnappyScatteredWriter::SlowAppend(const char* ip, size_t len) { + size_t avail = op_limit_ - op_ptr_; + while (len > avail) { + // Completely fill this block + memcpy(op_ptr_, ip, avail); + op_ptr_ += avail; + assert(op_limit_ - op_ptr_ == 0); + full_size_ += (op_ptr_ - op_base_); + len -= avail; + ip += avail; + + // Bounds check + if (full_size_ + len > expected_) { + return false; + } + + // Make new block + size_t bsize = std::min(kBlockSize, expected_ - full_size_); + op_base_ = allocator_.Allocate(bsize); + op_ptr_ = op_base_; + op_limit_ = op_base_ + bsize; + blocks_.push_back(op_base_); + avail = bsize; + } + + memcpy(op_ptr_, ip, len); + op_ptr_ += len; + return true; +} + +template +bool SnappyScatteredWriter::SlowAppendFromSelf(size_t offset, + size_t len) { + // Overflow check + // See SnappyArrayWriter::AppendFromSelf for an explanation of + // the "offset - 1u" trick. + const size_t cur = Size(); + if (offset - 1u >= cur) return false; + if (expected_ - cur < len) return false; + + // Currently we shouldn't ever hit this path because Compress() chops the + // input into blocks and does not create cross-block copies. However, it is + // nice if we do not rely on that, since we can get better compression if we + // allow cross-block copies and thus might want to change the compressor in + // the future. + size_t src = cur - offset; + while (len-- > 0) { + char c = blocks_[src >> kBlockLog][src & (kBlockSize-1)]; + Append(&c, 1); + src++; + } + return true; +} + +class SnappySinkAllocator { + public: + explicit SnappySinkAllocator(Sink* dest): dest_(dest) {} + ~SnappySinkAllocator() {} + + char* Allocate(int size) { + Datablock block(new char[size], size); + blocks_.push_back(block); + return block.data; + } + + // We flush only at the end, because the writer wants + // random access to the blocks and once we hand the + // block over to the sink, we can't access it anymore. + // Also we don't write more than has been actually written + // to the blocks. + void Flush(size_t size) { + size_t size_written = 0; + size_t block_size; + for (int i = 0; i < blocks_.size(); ++i) { + block_size = std::min(blocks_[i].size, size - size_written); + dest_->AppendAndTakeOwnership(blocks_[i].data, block_size, + &SnappySinkAllocator::Deleter, NULL); + size_written += block_size; + } + blocks_.clear(); + } + + private: + struct Datablock { + char* data; + size_t size; + Datablock(char* p, size_t s) : data(p), size(s) {} + }; + + static void Deleter(void* arg, const char* bytes, size_t size) { + delete[] bytes; + } + + Sink* dest_; + std::vector blocks_; + + // Note: copying this object is allowed +}; + +size_t UncompressAsMuchAsPossible(Source* compressed, Sink* uncompressed) { + SnappySinkAllocator allocator(uncompressed); + SnappyScatteredWriter writer(allocator); + InternalUncompress(compressed, &writer); + return writer.Produced(); +} + +bool Uncompress(Source* compressed, Sink* uncompressed) { + // Read the uncompressed length from the front of the compressed input + SnappyDecompressor decompressor(compressed); + uint32 uncompressed_len = 0; + if (!decompressor.ReadUncompressedLength(&uncompressed_len)) { + return false; + } + + char c; + size_t allocated_size; + char* buf = uncompressed->GetAppendBufferVariable( + 1, uncompressed_len, &c, 1, &allocated_size); + + const size_t compressed_len = compressed->Available(); + // If we can get a flat buffer, then use it, otherwise do block by block + // uncompression + if (allocated_size >= uncompressed_len) { + SnappyArrayWriter writer(buf); + bool result = InternalUncompressAllTags(&decompressor, &writer, + compressed_len, uncompressed_len); + uncompressed->Append(buf, writer.Produced()); + return result; + } else { + SnappySinkAllocator allocator(uncompressed); + SnappyScatteredWriter writer(allocator); + return InternalUncompressAllTags(&decompressor, &writer, compressed_len, + uncompressed_len); + } +} + +} // namespace snappy diff --git a/ext/snappy/snappy.h b/ext/snappy/snappy.h index d15ffbf0a8..e9805bfb7d 100644 --- a/ext/snappy/snappy.h +++ b/ext/snappy/snappy.h @@ -36,10 +36,10 @@ // using BMDiff and then compressing the output of BMDiff with // Snappy. -#ifndef UTIL_SNAPPY_SNAPPY_H__ -#define UTIL_SNAPPY_SNAPPY_H__ +#ifndef THIRD_PARTY_SNAPPY_SNAPPY_H__ +#define THIRD_PARTY_SNAPPY_SNAPPY_H__ -#include +#include #include #include "snappy-stubs-public.h" @@ -69,11 +69,12 @@ namespace snappy { // Higher-level string based routines (should be sufficient for most users) // ------------------------------------------------------------------------ - // Sets "*output" to the compressed version of "input[0,input_length-1]". - // Original contents of *output are lost. + // Sets "*compressed" to the compressed version of "input[0,input_length-1]". + // Original contents of *compressed are lost. // - // REQUIRES: "input[]" is not an alias of "*output". - size_t Compress(const char* input, size_t input_length, string* output); + // REQUIRES: "input[]" is not an alias of "*compressed". + size_t Compress(const char* input, size_t input_length, + std::string* compressed); // Decompresses "compressed[0,compressed_length-1]" to "*uncompressed". // Original contents of "*uncompressed" are lost. @@ -82,8 +83,20 @@ namespace snappy { // // returns false if the message is corrupted and could not be decompressed bool Uncompress(const char* compressed, size_t compressed_length, - string* uncompressed); + std::string* uncompressed); + // Decompresses "compressed" to "*uncompressed". + // + // returns false if the message is corrupted and could not be decompressed + bool Uncompress(Source* compressed, Sink* uncompressed); + + // This routine uncompresses as much of the "compressed" as possible + // into sink. It returns the number of valid bytes added to sink + // (extra invalid bytes may have been added due to errors; the caller + // should ignore those). The emitted data typically has length + // GetUncompressedLength(), but may be shorter if an error is + // encountered. + size_t UncompressAsMuchAsPossible(Source* compressed, Sink* uncompressed); // ------------------------------------------------------------------------ // Lower-level character array based routines. May be useful for @@ -124,6 +137,28 @@ namespace snappy { // returns false if the message is corrupted and could not be decrypted bool RawUncompress(Source* compressed, char* uncompressed); + // Given data in "compressed[0..compressed_length-1]" generated by + // calling the Snappy::Compress routine, this routine + // stores the uncompressed data to the iovec "iov". The number of physical + // buffers in "iov" is given by iov_cnt and their cumulative size + // must be at least GetUncompressedLength(compressed). The individual buffers + // in "iov" must not overlap with each other. + // + // returns false if the message is corrupted and could not be decrypted + bool RawUncompressToIOVec(const char* compressed, size_t compressed_length, + const struct iovec* iov, size_t iov_cnt); + + // Given data from the byte source 'compressed' generated by calling + // the Snappy::Compress routine, this routine stores the uncompressed + // data to the iovec "iov". The number of physical + // buffers in "iov" is given by iov_cnt and their cumulative size + // must be at least GetUncompressedLength(compressed). The individual buffers + // in "iov" must not overlap with each other. + // + // returns false if the message is corrupted and could not be decrypted + bool RawUncompressToIOVec(Source* compressed, const struct iovec* iov, + size_t iov_cnt); + // Returns the maximal size of the compressed representation of // input data that is "source_bytes" bytes in length; size_t MaxCompressedLength(size_t source_bytes); @@ -142,21 +177,31 @@ namespace snappy { bool IsValidCompressedBuffer(const char* compressed, size_t compressed_length); - // *** DO NOT CHANGE THE VALUE OF kBlockSize *** + // Returns true iff the contents of "compressed" can be uncompressed + // successfully. Does not return the uncompressed data. Takes + // time proportional to *compressed length, but is usually at least + // a factor of four faster than actual decompression. + // On success, consumes all of *compressed. On failure, consumes an + // unspecified prefix of *compressed. + bool IsValidCompressed(Source* compressed); + + // The size of a compression block. Note that many parts of the compression + // code assumes that kBlockSize <= 65536; in particular, the hash table + // can only store 16-bit offsets, and EmitCopy() also assumes the offset + // is 65535 bytes or less. Note also that if you change this, it will + // affect the framing format (see framing_format.txt). // - // New Compression code chops up the input into blocks of at most - // the following size. This ensures that back-references in the - // output never cross kBlockSize block boundaries. This can be - // helpful in implementing blocked decompression. However the - // decompression code should not rely on this guarantee since older - // compression code may not obey it. - static const int kBlockLog = 15; - static const size_t kBlockSize = 1 << kBlockLog; + // Note that there might be older data around that is compressed with larger + // block sizes, so the decompression code should not rely on the + // non-existence of long backreferences. + static constexpr int kBlockLog = 16; + static constexpr size_t kBlockSize = 1 << kBlockLog; - static const int kMaxHashTableBits = 14; - static const size_t kMaxHashTableSize = 1 << kMaxHashTableBits; + static constexpr int kMinHashTableBits = 8; + static constexpr size_t kMinHashTableSize = 1 << kMinHashTableBits; + static constexpr int kMaxHashTableBits = 14; + static constexpr size_t kMaxHashTableSize = 1 << kMaxHashTableBits; } // end namespace snappy - -#endif // UTIL_SNAPPY_SNAPPY_H__ +#endif // THIRD_PARTY_SNAPPY_SNAPPY_H__ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index bf327b35a3..f5c2ef547f 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -126,6 +126,8 @@ SOURCES_C += $(EXTDIR)/xxhash.c SOURCES_CXX += \ $(EXTDIR)/snappy/snappy-c.cpp \ + $(EXTDIR)/snappy/snappy-sinksource.cpp \ + $(EXTDIR)/snappy/snappy-stubs-internal.cpp \ $(EXTDIR)/snappy/snappy.cpp SOURCES_CXX += $(EXTDIR)/xbrz/xbrz.cpp From a28954d311a2da3f236d43a1668b6142fc72c81f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 09:03:31 +0200 Subject: [PATCH 689/848] Further simplify framebuffer matching. --- GPU/Common/TextureCacheCommon.cpp | 52 ++++++++++++------------------- GPU/Common/TextureCacheCommon.h | 16 +++------- 2 files changed, 25 insertions(+), 43 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 6c83310e19..1049f024db 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -543,7 +543,6 @@ TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { std::vector TextureCacheCommon::GetFramebufferCandidates(const TextureDefinition &entry, u32 texAddrOffset) { gpuStats.numFramebufferEvaluations++; bool success = false; - bool anyIgnores = false; std::vector candidates; @@ -553,12 +552,13 @@ std::vector TextureCacheCommon::GetFramebufferCandidates(const for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { auto framebuffer = framebuffers[i]; - uint32_t fb_addr = channel == NOTIFY_FB_DEPTH ? framebuffer->z_address : framebuffer->fb_address; - FramebufferMatchInfo match = MatchFramebuffer(entry, fb_addr, framebuffer, texAddrOffset, channel); - if (match.match == FramebufferMatch::IGNORE) { - anyIgnores = true; - } else if (match.match != FramebufferMatch::NO_MATCH) { + FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer, texAddrOffset, channel); + switch (match.match) { + case FramebufferMatch::VALID: candidates.push_back(AttachCandidate{ match, entry, framebuffer, channel }); + break; + default: + break; } } @@ -582,27 +582,25 @@ int TextureCacheCommon::GetBestCandidateIndex(const std::vector int bestRelevancy = -1; int bestIndex = -1; + // TODO: Instead of scores, we probably want to use std::min_element to pick the top element, using + // a comparison function. for (int i = 0; i < (int)candidates.size(); i++) { const AttachCandidate &candidate = candidates[i]; int relevancy = 0; switch (candidate.match.match) { case FramebufferMatch::VALID: - case FramebufferMatch::VALID_DEPAL: relevancy += 1000; break; - case FramebufferMatch::INEXACT: - relevancy += 100; - break; } // Bonus point for matching stride. if (candidate.channel == NOTIFY_FB_COLOR && candidate.fb->fb_stride == candidate.entry.bufw) { - relevancy += 10; + relevancy += 100; } // Bonus points for no offset. if (candidate.match.xOffset == 0 && candidate.match.yOffset == 0) { - relevancy += 9; + relevancy += 10; } if (candidate.channel == NOTIFY_FB_COLOR && candidate.fb->last_frame_render == gpuStats.numFlips) { @@ -765,10 +763,10 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer( const TextureDefinition &entry, - u32 fb_address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const { + VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const { static const u32 MAX_SUBAREA_Y_OFFSET_SAFE = 32; - const u32 mirrorMask = 0x00600000; + uint32_t fb_address = channel == NOTIFY_FB_DEPTH ? framebuffer->z_address : framebuffer->fb_address; u32 addr = fb_address & 0x3FFFFFFF; u32 texaddr = entry.addr + texaddrOffset; @@ -782,6 +780,8 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer( } if (texInVRAM) { + const u32 mirrorMask = 0x00600000; + // This bit controls swizzle. The swizzles at 0x00200000 and 0x00600000 are designed // to perfectly match reading depth as color (which one to use I think might be related // to the bpp of the color format used when rendering to it). @@ -792,15 +792,14 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer( case 0x00400000: // Don't match the depth channel with these addresses when texturing. if (channel == FramebufferNotificationChannel::NOTIFY_FB_DEPTH) { - // God of War: If we actively detach here, the shadows disappear. - return FramebufferMatchInfo{ FramebufferMatch::IGNORE }; + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } break; case 0x00200000: case 0x00600000: // Don't match the color channel with these addresses when texturing. if (channel == FramebufferNotificationChannel::NOTIFY_FB_COLOR) { - return FramebufferMatchInfo{ FramebufferMatch::IGNORE }; + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } break; } @@ -824,16 +823,7 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer( // NOTE: This check is okay because the first texture formats are the same as the buffer formats. if (entry.format != (GETextureFormat)framebuffer->format) { WARN_LOG_ONCE(diffFormat1, G3D, "Texturing from framebuffer with different formats %s != %s", GeTextureFormatToString(entry.format), GeBufferFormatToString(framebuffer->format)); - // Let's avoid using it when we know the format is wrong. May be a video/etc. updating memory. - // However, some games use a different format to clear the buffer. - if (framebuffer->last_frame_attached + 1 < gpuStats.numFlips) { - return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; - } else { - // TODO: This is a weird outcome. The purpose seems to be to delay - // a decision to the next frame. - // Should really try to map it to something else. - return FramebufferMatchInfo{ FramebufferMatch::IGNORE }; - } + return FramebufferMatchInfo{ FramebufferMatch::NO_MATCH }; } else { return FramebufferMatchInfo{ FramebufferMatch::VALID }; } @@ -897,7 +887,7 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer( if (!noOffset) { WARN_LOG_ONCE(subareaClut, G3D, "Texturing from framebuffer using CLUT with offset at %08x +%dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset); } - fbInfo.match = FramebufferMatch::VALID_DEPAL; + fbInfo.match = FramebufferMatch::VALID; // We check the format again later, no need to return a special value here. return fbInfo; } else if (IsClutFormat((GETextureFormat)(entry.format)) || IsDXTFormat((GETextureFormat)(entry.format))) { WARN_LOG_ONCE(fourEightBit, G3D, "%s format not supported when texturing from framebuffer of format %s", GeTextureFormatToString(entry.format), GeBufferFormatToString(framebuffer->format)); @@ -909,11 +899,9 @@ FramebufferMatchInfo TextureCacheCommon::MatchFramebuffer( if (framebuffer->format != entry.format) { WARN_LOG_ONCE(diffFormat2, G3D, "Texturing from framebuffer with different formats %s != %s at %08x", GeTextureFormatToString(entry.format), GeBufferFormatToString(framebuffer->format), fb_address); - return fbInfo; // Valid! + return fbInfo; } else { - WARN_LOG_ONCE(subarea, G3D, "Render to area containing texture at %08x +%dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset); - // If we return VALID here, God of War Ghost of Sparta/Chains of Olympus will be missing some special effect according to an old comment. - fbInfo.match = FramebufferMatch::INEXACT; + WARN_LOG_ONCE(subarea, G3D, "Texturing from framebuffer at %08x +%dx%d", fb_address, fbInfo.xOffset, fbInfo.yOffset); return fbInfo; } } else { diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 2bdaffd15f..609693521c 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -205,17 +205,10 @@ typedef std::map> TexCache; enum class FramebufferMatch { // Valid, exact match. VALID = 0, - // Valid match that is exact after depal. - VALID_DEPAL, - // Inexact match (such as wrong fmt or at a questionable offset.) - INEXACT, // Not a match, remove if currently attached. NO_MATCH, - // Not a match, but don't remove yet. Used to avoid deatching depth mismatch. - IGNORE, }; -// Separate to keep main texture cache size down. struct FramebufferMatchInfo { FramebufferMatch match; u32 xOffset; @@ -249,10 +242,11 @@ public: virtual void ForgetLastTexture() = 0; virtual void InvalidateLastTexture(TexCacheEntry *entry = nullptr) = 0; virtual void Clear(bool delete_them); - - // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to. - void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel); virtual void NotifyConfigChanged(); + + // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to, + // so that it can invalidate TexCacheEntries pointed at those addresses. + void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel); void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt); size_t NumLoadedTextures() const { @@ -295,7 +289,7 @@ protected: void UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key); // Used by D3D11 and Vulkan. void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode); - FramebufferMatchInfo MatchFramebuffer(const TextureDefinition &entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; + FramebufferMatchInfo MatchFramebuffer(const TextureDefinition &entry, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; std::vector GetFramebufferCandidates(const TextureDefinition &entry, u32 texAddrOffset); int GetBestCandidateIndex(const std::vector &candidates); From 72df3fd339b0ae09b6a52c169791f6b57fc1b302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 09:13:18 +0200 Subject: [PATCH 690/848] Try unknown's workaround for clang code gen bug. See #13187. --- Core/Dialog/SavedataParam.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 37776d489e..e038e87342 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -1034,8 +1034,9 @@ int SavedataParam::GetSizes(SceUtilitySavedataParam *param) } if (param->msData.IsValid()) { - const std::string gameName(param->msData->gameName, strnlen(param->msData->gameName, sizeof(param->msData->gameName))); - const std::string saveName(param->msData->saveName, strnlen(param->msData->saveName, sizeof(param->msData->saveName))); + const SceUtilitySavedataMsDataInfo *msData = param->msData; + const std::string gameName(msData->gameName, strnlen(msData->gameName, sizeof(msData->gameName))); + const std::string saveName(msData->saveName, strnlen(msData->saveName, sizeof(msData->saveName))); // TODO: How should <> be handled? std::string path = GetSaveFilePath(param, gameName + (saveName == "<>" ? "" : saveName)); PSPFileInfo finfo = pspFileSystem.GetFileInfo(path); From 3dff9781fcda8529789f4776fcbce58d1aef4f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 09:33:06 +0200 Subject: [PATCH 691/848] Fix GetCurrentTextureDebug --- GPU/D3D11/TextureCacheD3D11.cpp | 33 +++++++++++++--------------- GPU/GLES/TextureCacheGLES.cpp | 36 ++++++++++++++----------------- GPU/Vulkan/TextureCacheVulkan.cpp | 33 +++++++++++++--------------- 3 files changed, 46 insertions(+), 56 deletions(-) diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index ca1e693723..7953eff1d9 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -762,29 +762,26 @@ void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture & bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { SetTexture(false); - if (!nextTexture_) - return false; + if (!nextTexture_) { + if (nextFramebufferTexture_) { + VirtualFramebuffer *vfb = nextFramebufferTexture_; + buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); + // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. + // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); + // We may have blitted to a temp FBO. + framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); + return retval; + } else { + return false; + } + } // Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer. TexCacheEntry *entry = nextTexture_; ApplyTexture(); - /* - // TODO: Centralize. - // TODO: Fix! - if (entry->framebuffer) { - VirtualFramebuffer *vfb = entry->framebuffer; - buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); - bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); - // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. - // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); - // We may have blitted to a temp FBO. - framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); - return retval; - } - */ - ID3D11Texture2D *texture = (ID3D11Texture2D *)entry->texturePtr; if (!texture) return false; diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 776405ba49..afdcf2681d 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -821,8 +821,22 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) SetTexture(true); if (!nextTexture_) { - ERROR_LOG(G3D, "Failed to get debug texture: no texture set"); - return false; + if (nextFramebufferTexture_) { + VirtualFramebuffer *vfb = nextFramebufferTexture_; + buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); + // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. + // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); + // We may have blitted to a temp FBO. + framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); + if (!retval) + ERROR_LOG(G3D, "Failed to get debug texture: copy to memory failed"); + return retval; + } else { + ERROR_LOG(G3D, "Failed to get debug texture: no texture set"); + return false; + } } // Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer. @@ -831,24 +845,6 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) framebufferManagerGL_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); ApplyTexture(); - /* - // TODO: Centralize? - // TODO: Needs fixing! - if (entry->framebuffer) { - VirtualFramebuffer *vfb = entry->framebuffer; - buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); - bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); - // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. - // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); - // We may have blitted to a temp FBO. - framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); - if (!retval) - ERROR_LOG(G3D, "Failed to get debug texture: copy to memory failed"); - return retval; - } - */ - GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); // Not a framebuffer, so let's assume these are right. diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 6b11ceb560..3a2da88759 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -1140,29 +1140,26 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePt bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { SetTexture(false); - if (!nextTexture_) - return false; + if (!nextTexture_) { + if (nextFramebufferTexture_) { + VirtualFramebuffer *vfb = nextFramebufferTexture_; + buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); + bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); + // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. + // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); + // We may have blitted to a temp FBO. + framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); + return retval; + } else { + return false; + } + } // Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer. TexCacheEntry *entry = nextTexture_; ApplyTexture(); - /* - // TODO: Centralize? - // TODO: Fix! - if (entry->framebuffer) { - VirtualFramebuffer *vfb = entry->framebuffer; - buffer.Allocate(vfb->bufferWidth, vfb->bufferHeight, GPU_DBG_FORMAT_8888, false); - bool retval = draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->bufferWidth, vfb->bufferHeight, Draw::DataFormat::R8G8B8A8_UNORM, buffer.GetData(), vfb->bufferWidth, "GetCurrentTextureDebug"); - // Vulkan requires us to re-apply all dynamic state for each command buffer, and the above will cause us to start a new cmdbuf. - // So let's dirty the things that are involved in Vulkan dynamic state. Readbacks are not frequent so this won't hurt other backends. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); - // We may have blitted to a temp FBO. - framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug"); - return retval; - } - */ - if (!entry->vkTex) return false; VulkanTexture *texture = entry->vkTex; From 2b49c3e4643e68d23ee667f0fe18b9691cb90e44 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 13 Sep 2020 00:36:20 -0700 Subject: [PATCH 692/848] MemMap: Check for MAP_FAILED in mmap call. --- Common/MemArenaAndroid.cpp | 2 +- Common/MemArenaPosix.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Common/MemArenaAndroid.cpp b/Common/MemArenaAndroid.cpp index b43a0815b2..462d1a3a94 100644 --- a/Common/MemArenaAndroid.cpp +++ b/Common/MemArenaAndroid.cpp @@ -140,7 +140,7 @@ u8* MemArena::Find4GBBase() { // address by grabbing 8GB and aligning the pointer. const uint64_t EIGHT_GIGS = 0x200000000ULL; void *base = mmap(0, EIGHT_GIGS, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); - if (base) { + if (base && base != MAP_FAILED) { INFO_LOG(SYSTEM, "base: %p", base); uint64_t aligned_base = ((uint64_t)base + 0xFFFFFFFF) & ~0xFFFFFFFFULL; INFO_LOG(SYSTEM, "aligned_base: %p", (void *)aligned_base); diff --git a/Common/MemArenaPosix.cpp b/Common/MemArenaPosix.cpp index 15647b147a..87e18c9fff 100644 --- a/Common/MemArenaPosix.cpp +++ b/Common/MemArenaPosix.cpp @@ -109,7 +109,7 @@ u8* MemArena::Find4GBBase() { // address by grabbing 8GB and aligning the pointer. const uint64_t EIGHT_GIGS = 0x200000000ULL; void *base = mmap(0, EIGHT_GIGS, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); - if (base) { + if (base && base != MAP_FAILED) { INFO_LOG(MEMMAP, "base: %p", base); uint64_t aligned_base = ((uint64_t)base + 0xFFFFFFFF) & ~0xFFFFFFFFULL; INFO_LOG(MEMMAP, "aligned_base: %p", (void *)aligned_base); From 6f2310b8ea83c3473f7b38aadde099d7f5f52efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Sun, 13 Sep 2020 15:07:08 +0700 Subject: [PATCH 693/848] Fix libretro OSX build Fixes these errors: ``` ../ext/zlib/gzlib.c:492:14: error: implicit declaration of function 'lseek' is invalid in C99 [-Werror,-Wimplicit-function-declaration] ../ext/zlib/gzwrite.c:84:15: error: implicit declaration of function 'write' is invalid in C99 [-Werror,-Wimplicit-function-declaration] 1 /* gzguts.h -- zlib internal header definitions for gz* operations got = write(state->fd, strm->next_in, strm->avail_in); ``` --- ext/zlib/gzguts.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/zlib/gzguts.h b/ext/zlib/gzguts.h index d87659d031..cbd680da48 100644 --- a/ext/zlib/gzguts.h +++ b/ext/zlib/gzguts.h @@ -27,6 +27,10 @@ #endif #include +#ifdef __APPLE__ +#include +#endif + #ifdef _WIN32 # include #endif From 5d5e5fe6ff66683dd313792995c8370ef7ed95f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 12:18:38 +0200 Subject: [PATCH 694/848] Remove some outdated debugging code (SetDebugTexture) --- GPU/Common/TextureCacheCommon.cpp | 8 ------ GPU/GLES/TextureCacheGLES.cpp | 42 ------------------------------- 2 files changed, 50 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 1049f024db..69b33818ce 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -296,14 +296,6 @@ void TextureCacheCommon::UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode) } TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { -#ifdef DEBUG_TEXTURES - if (SetDebugTexture()) { - // A different texture was bound, let's rebind next time. - InvalidateLastTexture(); - return; - } -#endif - if (force) { InvalidateLastTexture(); } diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index afdcf2681d..b0de874f69 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -282,48 +282,6 @@ void TextureCacheGLES::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBas clutLastFormat_ = gstate.clutformat; } -// #define DEBUG_TEXTURES - -#ifdef DEBUG_TEXTURES -bool SetDebugTexture() { - static const int highlightFrames = 30; - - static int numTextures = 0; - static int lastFrames = 0; - static int mostTextures = 1; - - if (lastFrames != gpuStats.numFlips) { - mostTextures = std::max(mostTextures, numTextures); - numTextures = 0; - lastFrames = gpuStats.numFlips; - } - - static GLuint solidTexture = 0; - - bool changed = false; - if (((gpuStats.numFlips / highlightFrames) % mostTextures) == numTextures) { - if (gpuStats.numFlips % highlightFrames == 0) { - NOTICE_LOG(G3D, "Highlighting texture # %d / %d", numTextures, mostTextures); - } - static const u32 solidTextureData[] = {0x99AA99FF}; - - if (solidTexture == 0) { - glGenTextures(1, &solidTexture); - glBindTexture(GL_TEXTURE_2D, solidTexture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, solidTextureData); - } else { - glBindTexture(GL_TEXTURE_2D, solidTexture); - } - changed = true; - } - - ++numTextures; - return changed; -} -#endif - void TextureCacheGLES::BindTexture(TexCacheEntry *entry) { if (entry->textureName != lastBoundTexture) { render_->BindTexture(0, entry->textureName); From c9693ee061e6cdc5f86f30ee5a39aa07e6259497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 15:36:30 +0200 Subject: [PATCH 695/848] Texfilter: Rewrite some checks in GetSamplingParams to be faster and more understandable. --- GPU/Common/TextureCacheCommon.cpp | 33 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 69b33818ce..3925c09840 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -154,7 +154,10 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl GETexLevelMode mipMode = gstate.getTexLevelMode(); mode = mipMode; + bool autoMip = mipMode == GE_TEXLEVEL_MODE_AUTO; + + // TODO: Slope mipmap bias is still not well understood. lodBias = (float)gstate.getTexLevelOffset16() * (1.0f / 16.0f); if (mipMode == GE_TEXLEVEL_MODE_SLOPE) { lodBias += 1.0f + TexLog2(gstate.getTextureLodSlope()) * (1.0f / 256.0f); @@ -162,8 +165,9 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl // If mip level is forced to zero, disable mipmapping. bool noMip = maxLevel == 0 || (!autoMip && lodBias <= 0.0f); - if (IsFakeMipmapChange()) + if (IsFakeMipmapChange()) { noMip = noMip || !autoMip; + } if (noMip) { // Enforce no mip filtering, for safety. @@ -171,29 +175,27 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl lodBias = 0.0f; } - if (g_Config.iTexFiltering == TEX_FILTER_LINEAR_VIDEO) { - bool isVideo = videos_.find(addr & 0x3FFFFFFF) != videos_.end(); - if (isVideo) { + if (!(magFilt & 1) && addr != 0 && g_Config.iTexFiltering == TEX_FILTER_LINEAR_VIDEO) { + if (videos_.find(addr & 0x3FFFFFFF) != videos_.end()) { magFilt |= 1; minFilt |= 1; } } - if (g_Config.iTexFiltering == TEX_FILTER_LINEAR && (!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue())) { - if (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue()) { + + // Filtering overrides + if (g_Config.iTexFiltering == TEX_FILTER_LINEAR) { + // Only override to linear filtering if there's no alpha or color testing going on. + if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) && + (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) { magFilt |= 1; minFilt |= 1; } - } - bool forceNearest = g_Config.iTexFiltering == TEX_FILTER_NEAREST; - // Force Nearest when color test enabled and rendering resolution greater than 480x272 - if ((gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue()) && g_Config.iInternalResolution != 1 && gstate.isModeThrough()) { + } else if (g_Config.iTexFiltering == TEX_FILTER_NEAREST || + (gstate.isModeThrough() && g_Config.iInternalResolution != 1 && + gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0)) { + // Force Nearest when override is on, or color test enabled and rendering resolution greater than 480x272 // Some games use 0 as the color test color, which won't be too bad if it bleeds. // Fuchsia and green, etc. are the problem colors. - if (gstate.getColorTestRef() != 0) { - forceNearest = true; - } - } - if (forceNearest) { magFilt &= ~1; minFilt &= ~1; } @@ -208,6 +210,7 @@ void TextureCacheCommon::UpdateSamplingParams(TexCacheEntry &entry, SamplerCache float lodBias; int maxLevel = (entry.status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry.maxLevel; GETexLevelMode mode; + GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, entry.addr, mode); key.minFilt = minFilt & 1; key.mipEnable = (minFilt >> 2) & 1; From cea35007ae827e5364b70d5049a3d6afeb48640e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 15:41:51 +0200 Subject: [PATCH 696/848] Always use a linear filter for video, unless forcing NEAREST filtering. --- Core/Config.cpp | 1 + Core/Config.h | 1 + GPU/Common/TextureCacheCommon.cpp | 6 +++--- GPU/Common/TextureCacheCommon.h | 5 ++--- GPU/Software/Rasterizer.cpp | 4 ++-- UI/GameSettingsScreen.cpp | 2 +- Windows/MainWindowMenu.cpp | 11 ++++------- Windows/ppsspp.rc | 1 - Windows/resource.h | 1 - 9 files changed, 14 insertions(+), 18 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index a3c7be9017..0764f7b6c2 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -821,6 +821,7 @@ static ConfigSetting graphicsSettings[] = { ConfigSetting("ClearFramebuffersOnFirstUseHack", &g_Config.bClearFramebuffersOnFirstUseHack, false, true, true), + ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index 5a1a6b57b7..cfa071a878 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -186,6 +186,7 @@ public: bool bFullScreenMulti; int iInternalResolution; // 0 = Auto (native), 1 = 1x (480x272), 2 = 2x, 3 = 3x, 4 = 4x and so on. int iAnisotropyLevel; // 0 - 5, powers of 2: 0 = 1x = no aniso + int iMipmapMode; // 0 = default, 1 = performance, 2 = quality int bHighQualityDepth; bool bReplaceTextures; bool bSaveNewTextures; diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 3925c09840..f65a8e4333 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -175,7 +175,7 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl lodBias = 0.0f; } - if (!(magFilt & 1) && addr != 0 && g_Config.iTexFiltering == TEX_FILTER_LINEAR_VIDEO) { + if (!(magFilt & 1) && addr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) { if (videos_.find(addr & 0x3FFFFFFF) != videos_.end()) { magFilt |= 1; minFilt |= 1; @@ -183,14 +183,14 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl } // Filtering overrides - if (g_Config.iTexFiltering == TEX_FILTER_LINEAR) { + if (g_Config.iTexFiltering == TEX_FILTER_FORCE_LINEAR) { // Only override to linear filtering if there's no alpha or color testing going on. if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) && (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) { magFilt |= 1; minFilt |= 1; } - } else if (g_Config.iTexFiltering == TEX_FILTER_NEAREST || + } else if (g_Config.iTexFiltering == TEX_FILTER_FORCE_NEAREST || (gstate.isModeThrough() && g_Config.iInternalResolution != 1 && gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0)) { // Force Nearest when override is on, or color test enabled and rendering resolution greater than 480x272 diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 609693521c..a59ef9771d 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -30,9 +30,8 @@ enum TextureFiltering { TEX_FILTER_AUTO = 1, - TEX_FILTER_NEAREST = 2, - TEX_FILTER_LINEAR = 3, - TEX_FILTER_LINEAR_VIDEO = 4, + TEX_FILTER_FORCE_NEAREST = 2, + TEX_FILTER_FORCE_LINEAR = 3, }; enum FramebufferNotification { diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 9933fac43e..545de958d1 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -1036,9 +1036,9 @@ static inline void CalculateSamplingParams(const float ds, const float dt, const levelFrac = 0; } - if (g_Config.iTexFiltering == TEX_FILTER_LINEAR) { + if (g_Config.iTexFiltering == TEX_FILTER_FORCE_LINEAR) { filt = true; - } else if (g_Config.iTexFiltering == TEX_FILTER_NEAREST) { + } else if (g_Config.iTexFiltering == TEX_FILTER_FORCE_NEAREST) { filt = false; } else { filt = detail > 0 ? gstate.isMinifyFilteringEnabled() : gstate.isMagnifyFilteringEnabled(); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 60d2757f41..99888d9e3a 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -512,7 +512,7 @@ void GameSettingsScreen::CreateViews() { PopupMultiChoice *anisoFiltering = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iAnisotropyLevel, gr->T("Anisotropic Filtering"), anisoLevels, 0, ARRAY_SIZE(anisoLevels), gr->GetName(), screenManager())); anisoFiltering->SetDisabledPtr(&g_Config.bSoftwareRendering); - static const char *texFilters[] = { "Auto", "Nearest", "Linear", "Linear on FMV", }; + static const char *texFilters[] = { "Auto", "Nearest", "Linear" }; graphicsSettings->Add(new PopupMultiChoice(&g_Config.iTexFiltering, gr->T("Texture Filter"), texFilters, 1, ARRAY_SIZE(texFilters), gr->GetName(), screenManager())); static const char *bufFilters[] = { "Linear", "Nearest", }; diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 858a4e919f..50ad9881e6 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -313,7 +313,6 @@ namespace MainWindow { TranslateMenuItem(menu, ID_OPTIONS_TEXTUREFILTERING_AUTO); TranslateMenuItem(menu, ID_OPTIONS_NEARESTFILTERING); TranslateMenuItem(menu, ID_OPTIONS_LINEARFILTERING); - TranslateMenuItem(menu, ID_OPTIONS_LINEARFILTERING_CG); TranslateMenuItem(menu, ID_OPTIONS_SCREENFILTER_MENU); TranslateMenuItem(menu, ID_OPTIONS_BUFLINEARFILTER); TranslateMenuItem(menu, ID_OPTIONS_BUFNEARESTFILTER); @@ -979,9 +978,8 @@ namespace MainWindow { break; case ID_OPTIONS_TEXTUREFILTERING_AUTO: setTexFiltering(TEX_FILTER_AUTO); break; - case ID_OPTIONS_NEARESTFILTERING: setTexFiltering(TEX_FILTER_NEAREST); break; - case ID_OPTIONS_LINEARFILTERING: setTexFiltering(TEX_FILTER_LINEAR); break; - case ID_OPTIONS_LINEARFILTERING_CG: setTexFiltering(TEX_FILTER_LINEAR_VIDEO); break; + case ID_OPTIONS_NEARESTFILTERING: setTexFiltering(TEX_FILTER_FORCE_NEAREST); break; + case ID_OPTIONS_LINEARFILTERING: setTexFiltering(TEX_FILTER_FORCE_LINEAR); break; case ID_OPTIONS_BUFLINEARFILTER: setBufFilter(SCALE_LINEAR); break; case ID_OPTIONS_BUFNEARESTFILTER: setBufFilter(SCALE_NEAREST); break; @@ -1221,12 +1219,11 @@ namespace MainWindow { ID_OPTIONS_TEXTUREFILTERING_AUTO, ID_OPTIONS_NEARESTFILTERING, ID_OPTIONS_LINEARFILTERING, - ID_OPTIONS_LINEARFILTERING_CG, }; if (g_Config.iTexFiltering < TEX_FILTER_AUTO) g_Config.iTexFiltering = TEX_FILTER_AUTO; - else if (g_Config.iTexFiltering > TEX_FILTER_LINEAR_VIDEO) - g_Config.iTexFiltering = TEX_FILTER_LINEAR_VIDEO; + else if (g_Config.iTexFiltering > TEX_FILTER_FORCE_LINEAR) + g_Config.iTexFiltering = TEX_FILTER_FORCE_LINEAR; for (int i = 0; i < ARRAY_SIZE(texfilteringitems); i++) { CheckMenuItem(menu, texfilteringitems[i], MF_BYCOMMAND | ((i + 1) == g_Config.iTexFiltering ? MF_CHECKED : MF_UNCHECKED)); diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 5dcb0806a8..966cd1e3b8 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -629,7 +629,6 @@ BEGIN MENUITEM "Auto", ID_OPTIONS_TEXTUREFILTERING_AUTO MENUITEM "Nearest", ID_OPTIONS_NEARESTFILTERING MENUITEM "Linear", ID_OPTIONS_LINEARFILTERING - MENUITEM "Linear on FMV", ID_OPTIONS_LINEARFILTERING_CG END POPUP "Screen Scaling Filter", ID_OPTIONS_SCREENFILTER_MENU BEGIN diff --git a/Windows/resource.h b/Windows/resource.h index adb597eab7..914629f889 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -242,7 +242,6 @@ #define ID_OPTIONS_TEXTUREFILTERING_AUTO 40067 #define ID_OPTIONS_NEARESTFILTERING 40068 #define ID_DISASM_DISASSEMBLETOFILE 40069 -#define ID_OPTIONS_LINEARFILTERING_CG 40070 #define ID_DISASM_DISABLEBREAKPOINT 40071 #define ID_DISASM_THREAD_FORCERUN 40072 #define ID_DISASM_THREAD_KILL 40073 From a4c071261b0f22c84ee6876145d53150f6a1ba7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 15:57:26 +0200 Subject: [PATCH 697/848] TextureCacheCommon::UpdateSamplingParams no longer takes a TexCacheEntry --- Core/Config.cpp | 1 - Core/Config.h | 1 - GPU/Common/TextureCacheCommon.cpp | 9 ++++----- GPU/Common/TextureCacheCommon.h | 2 +- GPU/D3D11/TextureCacheD3D11.cpp | 3 ++- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 5 +++-- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 0764f7b6c2..a3c7be9017 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -821,7 +821,6 @@ static ConfigSetting graphicsSettings[] = { ConfigSetting("ClearFramebuffersOnFirstUseHack", &g_Config.bClearFramebuffersOnFirstUseHack, false, true, true), - ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index cfa071a878..5a1a6b57b7 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -186,7 +186,6 @@ public: bool bFullScreenMulti; int iInternalResolution; // 0 = Auto (native), 1 = 1x (480x272), 2 = 2x, 3 = 3x, 4 = 4x and so on. int iAnisotropyLevel; // 0 - 5, powers of 2: 0 = 1x = no aniso - int iMipmapMode; // 0 = default, 1 = performance, 2 = quality int bHighQualityDepth; bool bReplaceTextures; bool bSaveNewTextures; diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index f65a8e4333..9c50471da4 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -201,17 +201,16 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl } } -void TextureCacheCommon::UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key) { +void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key) { // TODO: Make GetSamplingParams write SamplerCacheKey directly int minFilt; int magFilt; bool sClamp; bool tClamp; float lodBias; - int maxLevel = (entry.status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry.maxLevel; GETexLevelMode mode; - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, entry.addr, mode); + GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, texAddr, mode); key.minFilt = minFilt & 1; key.mipEnable = (minFilt >> 2) & 1; key.mipFilt = (minFilt >> 1) & 1; @@ -227,7 +226,7 @@ void TextureCacheCommon::UpdateSamplingParams(TexCacheEntry &entry, SamplerCache } else { switch (mode) { case GE_TEXLEVEL_MODE_AUTO: - key.maxLevel = entry.maxLevel * 256; + key.maxLevel = maxLevel * 256; key.minLevel = 0; key.lodBias = (int)(lodBias * 256.0f); if (gstate_c.Supports(GPU_SUPPORTS_ANISOTROPY) && g_Config.iAnisotropyLevel > 0) { @@ -244,7 +243,7 @@ void TextureCacheCommon::UpdateSamplingParams(TexCacheEntry &entry, SamplerCache // It's incorrect to use the slope as a bias. Instead it should be passed // into the shader directly as an explicit lod level, with the bias on top. For now, we just kill the // lodBias in this mode, working around #9772. - key.maxLevel = entry.maxLevel * 256; + key.maxLevel = maxLevel * 256; key.minLevel = 0; key.lodBias = 0; break; diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index a59ef9771d..652eba6578 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -285,7 +285,7 @@ protected: u32 EstimateTexMemoryUsage(const TexCacheEntry *entry); void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel, u32 addr, GETexLevelMode &mode); - void UpdateSamplingParams(TexCacheEntry &entry, SamplerCacheKey &key); // Used by D3D11 and Vulkan. + void UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key); // Used by D3D11 and Vulkan. void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode); FramebufferMatchInfo MatchFramebuffer(const TextureDefinition &entry, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 7953eff1d9..01d102271a 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -240,7 +240,8 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) { lastBoundTexture = textureView; } SamplerCacheKey key{}; - UpdateSamplingParams(*entry, key); + int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; + UpdateSamplingParams(maxLevel, entry->addr, key); ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, key); context_->PSSetSamplers(0, 1, &state); } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 5f118f76db..667a972349 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -221,7 +221,7 @@ void TextureCacheDX9::StartFrame() { timesInvalidatedAllThisFrame_ = 0; if (texelsScaledThisFrame_) { - // INFO_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); + VERBOSE_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); } texelsScaledThisFrame_ = 0; if (clearCacheNextFrame_) { diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index b0de874f69..6ee2eabcd8 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -227,7 +227,7 @@ void TextureCacheGLES::StartFrame() { } if (texelsScaledThisFrame_) { - // INFO_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); + VERBOSE_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); } texelsScaledThisFrame_ = 0; if (clearCacheNextFrame_) { diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 3a2da88759..8627099be6 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -492,7 +492,7 @@ void TextureCacheVulkan::EndFrame() { computeShaderManager_.EndFrame(); if (texelsScaledThisFrame_) { - // INFO_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); + VERBOSE_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); } } @@ -542,7 +542,8 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) { entry->vkTex->Touch(); imageView_ = entry->vkTex->GetImageView(); SamplerCacheKey key{}; - UpdateSamplingParams(*entry, key); + int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; + UpdateSamplingParams(maxLevel, entry->addr, key); curSampler_ = samplerCache_.GetOrCreateSampler(key); drawEngine_->SetDepalTexture(VK_NULL_HANDLE); gstate_c.SetUseShaderDepal(false); From 6bcff8cbda817db2710fa9db2a1604b730fe139b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 17:09:36 +0200 Subject: [PATCH 698/848] Linux: Use MAP_NORESERVE when finding a memory base pointer. See #13187 --- Common/MemArenaPosix.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Common/MemArenaPosix.cpp b/Common/MemArenaPosix.cpp index 87e18c9fff..566af59ce4 100644 --- a/Common/MemArenaPosix.cpp +++ b/Common/MemArenaPosix.cpp @@ -108,7 +108,7 @@ u8* MemArena::Find4GBBase() { // aligned to 4GB for the movk trick. We can ensure that we get an aligned 4GB // address by grabbing 8GB and aligning the pointer. const uint64_t EIGHT_GIGS = 0x200000000ULL; - void *base = mmap(0, EIGHT_GIGS, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); + void *base = mmap(0, EIGHT_GIGS, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED | MAP_NORESERVE, -1, 0); if (base && base != MAP_FAILED) { INFO_LOG(MEMMAP, "base: %p", base); uint64_t aligned_base = ((uint64_t)base + 0xFFFFFFFF) & ~0xFFFFFFFFULL; @@ -124,7 +124,7 @@ u8* MemArena::Find4GBBase() { } #else size_t size = 0x10000000; - void* base = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); + void* base = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED | MAP_NORESERVE, -1, 0); _assert_msg_(base != MAP_FAILED, "Failed to map 256 MB of memory space: %s", strerror(errno)); munmap(base, size); return static_cast(base); From 0c885db052dac59f0ea2a8c841fdb11e6136b1c8 Mon Sep 17 00:00:00 2001 From: iota97 Date: Mon, 18 May 2020 11:17:45 +0200 Subject: [PATCH 699/848] User chain support --- Core/Config.cpp | 40 ++++++++++++++++- Core/Config.h | 5 ++- Core/CwCheat.cpp | 4 +- Core/HLE/sceDisplay.cpp | 7 +-- GPU/Common/PostShader.cpp | 19 ++++++++ GPU/Common/PostShader.h | 2 + GPU/Common/PresentationCommon.cpp | 8 ++-- UI/GameSettingsScreen.cpp | 73 +++++++++++++++++++++---------- UI/GameSettingsScreen.h | 2 +- UI/MiscScreens.cpp | 6 +-- UI/MiscScreens.h | 3 +- UI/NativeApp.cpp | 1 + Windows/MainWindowMenu.cpp | 12 +++-- 13 files changed, 134 insertions(+), 48 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index a3c7be9017..ace8561175 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -805,7 +805,6 @@ static ConfigSetting graphicsSettings[] = { // Not really a graphics setting... ReportedConfigSetting("SplineBezierQuality", &g_Config.iSplineBezierQuality, 2, true, true), ReportedConfigSetting("HardwareTessellation", &g_Config.bHardwareTessellation, false, true, true), - ReportedConfigSetting("PostShader", &g_Config.sPostShaderName, "Off", true, true), ConfigSetting("TextureShader", &g_Config.sTextureShaderName, "Off", true, true), ReportedConfigSetting("MemBlockTransferGPU", &g_Config.bBlockTransferGPU, true, true, true), @@ -1254,6 +1253,14 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { mPostShaderSetting[it.first] = std::stof(it.second); } + auto postShaderChain = iniFile.GetOrCreateSection("PostShaderList")->ToMap(); + vPostShaderNames.clear(); + for (auto it : postShaderChain) { + vPostShaderNames.push_back(it.second); + } + if (vPostShaderNames.empty()) + vPostShaderNames.push_back("Off"); + // This caps the exponent 4 (so 16x.) if (iAnisotropyLevel > 4) { iAnisotropyLevel = 4; @@ -1385,6 +1392,13 @@ void Config::Save(const char *saveReason) { for (auto it = mPostShaderSetting.begin(), end = mPostShaderSetting.end(); it != end; ++it) { postShaderSetting->Set(it->first.c_str(), it->second); } + Section *postShaderChain = iniFile.GetOrCreateSection("PostShaderList"); + postShaderChain->Clear(); + for (size_t i = 0; i < vPostShaderNames.size(); ++i) { + char keyName[64]; + snprintf(keyName, sizeof(keyName), "PostShader%d", (int)i+1); + postShaderChain->Set(keyName, vPostShaderNames[i]); + } } Section *control = iniFile.GetOrCreateSection("Control"); @@ -1643,6 +1657,14 @@ bool Config::saveGameConfig(const std::string &pGameId, const std::string &title postShaderSetting->Set(it->first.c_str(), it->second); } + Section *postShaderChain = iniFile.GetOrCreateSection("PostShaderList"); + postShaderChain->Clear(); + for (size_t i = 0; i < vPostShaderNames.size(); ++i) { + char keyName[64]; + snprintf(keyName, sizeof(keyName), "PostShader%d", (int)i+1); + postShaderChain->Set(keyName, vPostShaderNames[i]); + } + KeyMap::SaveToIni(iniFile); iniFile.Save(fullIniFilePath); @@ -1667,6 +1689,14 @@ bool Config::loadGameConfig(const std::string &pGameId, const std::string &title mPostShaderSetting[it.first] = std::stof(it.second); } + auto postShaderChain = iniFile.GetOrCreateSection("PostShaderList")->ToMap(); + vPostShaderNames.clear(); + for (auto it : postShaderChain) { + vPostShaderNames.push_back(it.second); + } + if (vPostShaderNames.empty()) + vPostShaderNames.push_back("Off"); + IterateSettings(iniFile, [](Section *section, ConfigSetting *setting) { if (setting->perGame_) { setting->Get(section); @@ -1697,6 +1727,14 @@ void Config::unloadGameConfig() { mPostShaderSetting[it.first] = std::stof(it.second); } + auto postShaderChain = iniFile.GetOrCreateSection("PostShaderList")->ToMap(); + vPostShaderNames.clear(); + for (auto it : postShaderChain) { + vPostShaderNames.push_back(it.second); + } + if (vPostShaderNames.empty()) + vPostShaderNames.push_back("Off"); + LoadStandardControllerIni(); } } diff --git a/Core/Config.h b/Core/Config.h index 5a1a6b57b7..b999569eda 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -212,9 +212,10 @@ public: bool bFragmentTestCache; int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High bool bHardwareTessellation; - std::string sPostShaderName; // Off for off. - std::string sTextureShaderName; + + std::vector vPostShaderNames; // Off for chain end (only Off for no shader) std::map mPostShaderSetting; + std::string sTextureShaderName; bool bGfxDebugOutput; bool bGfxDebugSplitSubmit; int iInflightFrames; diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 7ed008f886..38b70abd77 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -950,7 +950,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, case CheatOp::PostShader: { - auto shaderChain = GetPostShaderChain(g_Config.sPostShaderName); + auto shaderChain = GetFullPostShadersChain(g_Config.vPostShaderNames); if (op.PostShaderUniform.shader < shaderChain.size()) { std::string shaderName = shaderChain[op.PostShaderUniform.shader]->section; if (shaderName != "Off") @@ -961,7 +961,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, case CheatOp::PostShaderFromMemory: { - auto shaderChain = GetPostShaderChain(g_Config.sPostShaderName); + auto shaderChain = GetFullPostShadersChain(g_Config.vPostShaderNames); if (Memory::IsValidAddress(op.addr) && op.PostShaderUniform.shader < shaderChain.size()) { union { float f; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 01c07a5182..7d0b9e7b60 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -751,7 +751,6 @@ void __DisplayFlip(int cyclesLate) { // But, let's flip at least once every 10 vblanks, to update fps, etc. const bool noRecentFlip = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && numVBlanksSinceFlip >= 10; // Also let's always flip for animated shaders. - const ShaderInfo *shaderInfo = g_Config.sPostShaderName == "Off" ? nullptr : GetPostShaderInfo(g_Config.sPostShaderName); bool postEffectRequiresFlip = false; bool duplicateFrames = g_Config.bRenderDuplicateFrames && g_Config.iFrameSkip == 0; @@ -764,11 +763,7 @@ void __DisplayFlip(int cyclesLate) { // postEffectRequiresFlip is not compatible with frameskip unthrottling, see #12325. if (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && !(unthrottleNeedsSkip && !FrameTimingThrottled())) { - if (shaderInfo) { - postEffectRequiresFlip = (shaderInfo->requires60fps || duplicateFrames); - } else { - postEffectRequiresFlip = duplicateFrames; - } + postEffectRequiresFlip = duplicateFrames || PostShaderChainRequires60FPS(GetFullPostShadersChain(g_Config.vPostShaderNames)); } const bool fbDirty = gpu->FramebufferDirty(); diff --git a/GPU/Common/PostShader.cpp b/GPU/Common/PostShader.cpp index 57eaf1f50d..d0d9ec8963 100644 --- a/GPU/Common/PostShader.cpp +++ b/GPU/Common/PostShader.cpp @@ -213,6 +213,25 @@ std::vector GetPostShaderChain(const std::string &name) { return backwards; } +std::vector GetFullPostShadersChain(const std::vector &names) { + std::vector fullChain; + for (auto shaderName : names) { + if (shaderName == "Off") + break; + auto shaderChain = GetPostShaderChain(shaderName); + fullChain.insert(fullChain.end(), shaderChain.begin(), shaderChain.end()); + } + return fullChain; +} + +bool PostShaderChainRequires60FPS(const std::vector &chain) { + for (auto shaderInfo : chain) { + if (shaderInfo->requires60fps) + return true; + } + return false; +} + const std::vector &GetAllPostShaderInfo() { return shaderInfo; } diff --git a/GPU/Common/PostShader.h b/GPU/Common/PostShader.h index 6febf0ee2d..3ad0d50485 100644 --- a/GPU/Common/PostShader.h +++ b/GPU/Common/PostShader.h @@ -83,6 +83,8 @@ void ReloadAllPostShaderInfo(); const ShaderInfo *GetPostShaderInfo(const std::string &name); std::vector GetPostShaderChain(const std::string &name); +std::vector GetFullPostShadersChain(const std::vector &names); +bool PostShaderChainRequires60FPS(const std::vector &chain); const std::vector &GetAllPostShaderInfo(); const TextureShaderInfo *GetTextureShaderInfo(const std::string &name); diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index d11bf72b95..f2ce4721da 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -210,9 +210,9 @@ static std::string ReadShaderSrc(const std::string &filename) { // Note: called on resize and settings changes. bool PresentationCommon::UpdatePostShader() { std::vector shaderInfo; - if (g_Config.sPostShaderName != "Off") { + if (g_Config.vPostShaderNames[0] != "Off") { ReloadAllPostShaderInfo(); - shaderInfo = GetPostShaderChain(g_Config.sPostShaderName); + shaderInfo = GetFullPostShadersChain(g_Config.vPostShaderNames); } DestroyPostShader(); @@ -754,9 +754,9 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u void PresentationCommon::CalculateRenderResolution(int *width, int *height, bool *upscaling, bool *ssaa) { // Check if postprocessing shader is doing upscaling as it requires native resolution std::vector shaderInfo; - if (g_Config.sPostShaderName != "Off") { + if (g_Config.vPostShaderNames[0] != "Off") { ReloadAllPostShaderInfo(); - shaderInfo = GetPostShaderChain(g_Config.sPostShaderName); + shaderInfo = GetFullPostShadersChain(g_Config.vPostShaderNames); } bool firstIsUpscalingFilter = shaderInfo.empty() ? false : shaderInfo.front()->isUpscalingFilter; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 60d2757f41..4fa553bc8b 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -74,6 +74,8 @@ #include "Windows/W32Util/ShellUtil.h" #endif +extern bool g_ShaderNameListChanged; + GameSettingsScreen::GameSettingsScreen(std::string gamePath, std::string gameID, bool editThenRestore) : UIDialogScreenWithGameBackground(gamePath), gameID_(gameID), enableReports_(false), editThenRestore_(editThenRestore) { lastVertical_ = UseVerticalLayout(); @@ -305,24 +307,51 @@ void GameSettingsScreen::CreateViews() { altSpeed2->SetZeroLabel(gr->T("Unlimited")); altSpeed2->SetNegativeDisable(gr->T("Disabled")); - graphicsSettings->Add(new ItemHeader(gr->T("Features"))); - postProcChoice_ = graphicsSettings->Add(new ChoiceWithValueDisplay(&g_Config.sPostShaderName, gr->T("Postprocessing Shader"), &PostShaderTranslateName)); - postProcChoice_->OnClick.Handle(this, &GameSettingsScreen::OnPostProcShader); - postProcChoice_->SetEnabledFunc([] { - return g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; - }); + graphicsSettings->Add(new ItemHeader(gr->T("Postprocessing effect"))); - auto shaderChain = GetPostShaderChain(g_Config.sPostShaderName); - for (auto shaderInfo : shaderChain) { - for (size_t i = 0; i < ARRAY_SIZE(shaderInfo->settings); ++i) { - auto &setting = shaderInfo->settings[i]; - if (!setting.name.empty()) { - auto &value = g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderInfo->section.c_str(), i + 1)]; - graphicsSettings->Add(new PopupSliderChoiceFloat(&value, setting.minValue, setting.maxValue, ps->T(setting.name), setting.step, screenManager())); + std::vector alreadyAddedShader; + for (int i = 0; i < g_Config.vPostShaderNames.size() && i < ARRAY_SIZE(shaderNames_); ++i) { + // Vector pointer get invalidated on resize, cache name to have always a valid reference for drawing + shaderNames_[i] = g_Config.vPostShaderNames[i]; + postProcChoice_ = graphicsSettings->Add(new ChoiceWithValueDisplay(&shaderNames_[i], StringFromFormat("%s #%d", gr->T("Postprocessing Shader"), i + 1), &PostShaderTranslateName)); + postProcChoice_->OnClick.Add([=](EventParams &e) { + auto gr = GetI18NCategory("Graphics"); + auto procScreen = new PostProcScreen(gr->T("Postprocessing Shader"), i); + procScreen->OnChoice.Handle(this, &GameSettingsScreen::OnPostProcShaderChange); + if (e.v) + procScreen->SetPopupOrigin(e.v); + screenManager()->push(procScreen); + return UI::EVENT_DONE; + }); + postProcChoice_->SetEnabledFunc([] { + return g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; + }); + + auto shaderChain = GetPostShaderChain(g_Config.vPostShaderNames[i]); + for (auto shaderInfo : shaderChain) { + // Disable duplicated shader slider + bool duplicated = std::find(alreadyAddedShader.begin(), alreadyAddedShader.end(), shaderInfo->section) != alreadyAddedShader.end(); + alreadyAddedShader.push_back(shaderInfo->section); + for (size_t i = 0; i < ARRAY_SIZE(shaderInfo->settings); ++i) { + auto &setting = shaderInfo->settings[i]; + if (!setting.name.empty()) { + auto &value = g_Config.mPostShaderSetting[StringFromFormat("%sSettingValue%d", shaderInfo->section.c_str(), i + 1)]; + if (duplicated) { + auto sliderName = StringFromFormat("%s %s", ps->T(setting.name), ps->T("(duplicated setting, previous slider will be used)")); + PopupSliderChoiceFloat *settingValue = graphicsSettings->Add(new PopupSliderChoiceFloat(&value, setting.minValue, setting.maxValue, sliderName, setting.step, screenManager())); + settingValue->SetEnabled(false); + } else { + PopupSliderChoiceFloat *settingValue = graphicsSettings->Add(new PopupSliderChoiceFloat(&value, setting.minValue, setting.maxValue, ps->T(setting.name), setting.step, screenManager())); + settingValue->SetEnabledFunc([] { + return g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; + }); + } + } } } } + graphicsSettings->Add(new ItemHeader(gr->T("Screen layout"))); #if !defined(MOBILE_DEVICE) graphicsSettings->Add(new CheckBox(&g_Config.bFullScreen, gr->T("FullScreen", "Full Screen")))->OnClick.Handle(this, &GameSettingsScreen::OnFullscreenChange); if (System_GetPropertyInt(SYSPROP_DISPLAY_COUNT) > 1) { @@ -1226,6 +1255,10 @@ void GameSettingsScreen::update() { RecreateViews(); lastVertical_ = vertical; } + if (g_ShaderNameListChanged) { + g_ShaderNameListChanged = false; + RecreateViews(); + } } void GameSettingsScreen::onFinish(DialogResult result) { @@ -1489,19 +1522,11 @@ UI::EventReturn GameSettingsScreen::OnLanguageChange(UI::EventParams &e) { return UI::EVENT_DONE; } -UI::EventReturn GameSettingsScreen::OnPostProcShader(UI::EventParams &e) { - auto gr = GetI18NCategory("Graphics"); - auto procScreen = new PostProcScreen(gr->T("Postprocessing Shader")); - procScreen->OnChoice.Handle(this, &GameSettingsScreen::OnPostProcShaderChange); - if (e.v) - procScreen->SetPopupOrigin(e.v); - screenManager()->push(procScreen); - return UI::EVENT_DONE; -} - UI::EventReturn GameSettingsScreen::OnPostProcShaderChange(UI::EventParams &e) { + g_Config.vPostShaderNames.erase(std::remove(g_Config.vPostShaderNames.begin(), g_Config.vPostShaderNames.end(), "Off"), g_Config.vPostShaderNames.end()); + g_Config.vPostShaderNames.push_back("Off"); + g_ShaderNameListChanged = true; NativeMessageReceived("gpu_resized", ""); - RecreateViews(); // Update setting name return UI::EVENT_DONE; } diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index 3b0859e0d0..00697f6f86 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -80,7 +80,6 @@ private: UI::EventReturn OnLanguage(UI::EventParams &e); UI::EventReturn OnLanguageChange(UI::EventParams &e); UI::EventReturn OnAutoFrameskip(UI::EventParams &e); - UI::EventReturn OnPostProcShader(UI::EventParams &e); UI::EventReturn OnPostProcShaderChange(UI::EventParams &e); UI::EventReturn OnTextureShader(UI::EventParams &e); UI::EventReturn OnTextureShaderChange(UI::EventParams &e); @@ -132,6 +131,7 @@ private: int prevInflightFrames_; bool enableReports_; bool tessHWEnable_; + std::string shaderNames_[256]; //edit the game-specific settings and restore the global settings after exiting bool editThenRestore_; diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index a5e2952483..00b3f02b9e 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -301,7 +301,7 @@ void PromptScreen::TriggerFinish(DialogResult result) { UIDialogScreenWithBackground::TriggerFinish(result); } -PostProcScreen::PostProcScreen(const std::string &title) : ListPopupScreen(title) { +PostProcScreen::PostProcScreen(const std::string &title, int id) : ListPopupScreen(title), id_(id) { auto ps = GetI18NCategory("PostShaders"); ReloadAllPostShaderInfo(); shaders_ = GetAllPostShaderInfo(); @@ -310,7 +310,7 @@ PostProcScreen::PostProcScreen(const std::string &title) : ListPopupScreen(title for (int i = 0; i < (int)shaders_.size(); i++) { if (!shaders_[i].visible) continue; - if (shaders_[i].section == g_Config.sPostShaderName) + if (shaders_[i].section == g_Config.vPostShaderNames[id_]) selected = i; items.push_back(ps->T(shaders_[i].section.c_str(), shaders_[i].name.c_str())); } @@ -320,7 +320,7 @@ PostProcScreen::PostProcScreen(const std::string &title) : ListPopupScreen(title void PostProcScreen::OnCompleted(DialogResult result) { if (result != DR_OK) return; - g_Config.sPostShaderName = shaders_[listView_->GetSelected()].section; + g_Config.vPostShaderNames[id_] = shaders_[listView_->GetSelected()].section; } TextureShaderScreen::TextureShaderScreen(const std::string &title) : ListPopupScreen(title) { diff --git a/UI/MiscScreens.h b/UI/MiscScreens.h index b1c5881bc4..d920fc77fe 100644 --- a/UI/MiscScreens.h +++ b/UI/MiscScreens.h @@ -105,12 +105,13 @@ private: class PostProcScreen : public ListPopupScreen { public: - PostProcScreen(const std::string &title); + PostProcScreen(const std::string &title, int id); private: void OnCompleted(DialogResult result) override; bool ShowButtons() const override { return true; } std::vector shaders_; + int id_; }; class TextureShaderScreen : public ListPopupScreen { diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index ffd0051677..b783140809 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -148,6 +148,7 @@ std::string config_filename; // Really need to clean this mess of globals up... but instead I add more :P bool g_TakeScreenshot; +bool g_ShaderNameListChanged = false; static bool isOuya; static bool resized = false; static bool restarting = false; diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 858a4e919f..8e5b83aeec 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -47,6 +47,7 @@ #include "Core/Core.h" extern bool g_TakeScreenshot; +extern bool g_ShaderNameListChanged; namespace MainWindow { extern HINSTANCE hInst; @@ -154,7 +155,7 @@ namespace MainWindow { int item = ID_SHADERS_BASE + 1; for (size_t i = 0; i < availableShaders.size(); i++) - CheckMenuItem(menu, item++, ((g_Config.sPostShaderName == availableShaders[i]) ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(menu, item++, ((g_Config.vPostShaderNames[0] == availableShaders[i] && (g_Config.vPostShaderNames[0] == "Off" || g_Config.vPostShaderNames[1] == "Off")) ? MF_CHECKED : MF_UNCHECKED)); } bool CreateShadersSubmenu(HMENU menu) { @@ -188,7 +189,7 @@ namespace MainWindow { continue; int checkedStatus = MF_UNCHECKED; availableShaders.push_back(i->section); - if (g_Config.sPostShaderName == i->section) { + if (g_Config.vPostShaderNames[0] == i->section && (g_Config.vPostShaderNames[0] == "Off" || g_Config.vPostShaderNames[1] == "Off")) { checkedStatus = MF_CHECKED; } @@ -1064,8 +1065,11 @@ namespace MainWindow { // ID_SHADERS_BASE and an additional 1 off it. u32 index = (wParam - ID_SHADERS_BASE - 1); if (index < availableShaders.size()) { - g_Config.sPostShaderName = availableShaders[index]; - + g_Config.vPostShaderNames.clear(); + if (availableShaders[index] != "Off") + g_Config.vPostShaderNames.push_back(availableShaders[index]); + g_Config.vPostShaderNames.push_back("Off"); + g_ShaderNameListChanged = true; NativeMessageReceived("gpu_resized", ""); break; } From 854ff7c5f158a5713bbe4b7531621cffeb0802f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 22:19:18 +0200 Subject: [PATCH 700/848] Improve readability of the boolean expression mess in GetSamplingParams --- GPU/Common/TextureCacheCommon.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 9c50471da4..698803fd92 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -177,27 +177,39 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl if (!(magFilt & 1) && addr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) { if (videos_.find(addr & 0x3FFFFFFF) != videos_.end()) { + // Enforce bilinear filtering on magnification. magFilt |= 1; - minFilt |= 1; } } // Filtering overrides - if (g_Config.iTexFiltering == TEX_FILTER_FORCE_LINEAR) { - // Only override to linear filtering if there's no alpha or color testing going on. + switch (g_Config.iTexFiltering) { + case TEX_FILTER_AUTO: + // Follow what the game wants. We just do a single heuristic change to avoid bleeding of wacky color test colors + // in higher resolution (used by some games for sprites, and they accidentally have linear filter on). + // This does duplicate the body of the above if, but it's clearer this way. + if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) { + bool uglyColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0; + if (uglyColorTest) { + magFilt &= ~1; + minFilt &= ~1; + } + } + break; + case TEX_FILTER_FORCE_LINEAR: + // Override to linear filtering if there's no alpha or color testing going on. if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) && (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) { magFilt |= 1; minFilt |= 1; } - } else if (g_Config.iTexFiltering == TEX_FILTER_FORCE_NEAREST || - (gstate.isModeThrough() && g_Config.iInternalResolution != 1 && - gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0)) { - // Force Nearest when override is on, or color test enabled and rendering resolution greater than 480x272 - // Some games use 0 as the color test color, which won't be too bad if it bleeds. - // Fuchsia and green, etc. are the problem colors. + break; + case TEX_FILTER_FORCE_NEAREST: + default: + // Just override everything to nearest without checks. Safe (but ugly). magFilt &= ~1; minFilt &= ~1; + break; } } From 8d68e917b79e46ba0ed611d40b8fa7a7d05bffa6 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 13 Sep 2020 07:51:58 +0700 Subject: [PATCH 701/848] Prevent Client side from forever re-trying to connect to Exited Host on Shin Sangoku Musou Multi Raid 2 --- Core/HLE/proAdhoc.cpp | 3 ++- Core/HLE/proAdhoc.h | 8 +++++--- Core/HLE/sceNet.cpp | 1 - Core/HLE/sceNetAdhoc.cpp | 24 +++++++++++------------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 96a66ca543..85534e45e9 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -77,7 +77,6 @@ SceNetAdhocctlAdhocId product_code; std::thread friendFinderThread; std::recursive_mutex peerlock; AdhocSocket* adhocSockets[MAX_SOCKET]; -std::map ptpConnectCount; std::vector chatLog; std::string name = ""; std::string incoming = ""; @@ -1322,6 +1321,8 @@ int friendFinder(){ closesocket(metasocket); metasocket = (int)INVALID_SOCKET; host->NotifyUserMessage(std::string(n->T("Disconnected from AdhocServer")) + " (" + std::string(n->T("Error")) + ": " + std::to_string(error) + ")", 2.0, 0x0000ff); + // Mark all friends as timedout since we won't be able to detects disconnected friends anymore without being connected to Adhoc Server + timeoutFriendsRecursive(friends); } } else { diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index d7b0269844..c571bcdfea 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -328,6 +328,9 @@ typedef struct SceNetAdhocPtpStat { typedef struct AdhocSocket { s32_le type; s32_le flags; // Socket Alert Flags + u32 send_timeout; + u32 recv_timeout; + s32 connectCount; union { SceNetAdhocPdpStat pdp; SceNetAdhocPtpStat ptp; @@ -840,7 +843,6 @@ extern SceNetAdhocctlAdhocId product_code; extern std::thread friendFinderThread; extern std::recursive_mutex peerlock; extern AdhocSocket* adhocSockets[MAX_SOCKET]; -extern std::map ptpConnectCount; union SockAddrIN4 { sockaddr addr; @@ -987,9 +989,9 @@ void deleteFriendByIP(uint32_t ip); * Recursive Memory Freeing-Helper for Friend-Structures * @param node Current Node in List */ -void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count); +void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count = nullptr); -void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count); +void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count = nullptr); /** * Friend Finder Thread (Receives Peer Information) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index dcd6ccd2a4..a0cd41f6ca 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -590,7 +590,6 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini // Clear Socket Translator Memory memset(&adhocSockets, 0, sizeof(adhocSockets)); - ptpConnectCount.clear(); return hleLogSuccessI(SCENET, 0); } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 1773d0fe49..76654c3745 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -393,7 +393,7 @@ int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { int ret = recv(uid, (char*)req.buffer, *req.length, MSG_NOSIGNAL); int sockerr = errno; - // Received Data + // Received Data. POSIX: May received 0 bytes when the remote peer already closed the connection. if (ret > 0) { DEBUG_LOG(SCENET, "sceNetAdhocPtpRecv[%i:%u]: Received %u bytes from %s:%u\n", req.id, ptpsocket.lport, ret, mac2str(&ptpsocket.paddr).c_str(), ptpsocket.pport); // Save Length @@ -1413,7 +1413,7 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * received = recvfrom(pdpsocket.id, (char*)buf, *len, MSG_NOSIGNAL, (sockaddr*)&sin, &sinlen); error = errno; - if (received == SOCKET_ERROR) { + if (received == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK)) { if (flag == 0) { // Simulate blocking behaviour with non-blocking socket u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | pdpsocket.id; @@ -2670,6 +2670,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Socket Type internal->type = SOCK_PTP; + internal->send_timeout = rexmt_int; // Copy Infrastructure Socket ID internal->data.ptp.id = tcpsocket; @@ -2685,7 +2686,6 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Link PTP Socket adhocSockets[i] = internal; - ptpConnectCount[i] = 0; // Add Port Forward to Router. We may not even need to forward this local port, since PtpOpen usually have port 0 (any port) as source port and followed by PtpConnect (which mean acting as Client), right? //sceNetPortOpen("TCP", sport); @@ -2798,7 +2798,6 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther // Link PTP Socket adhocSockets[i] = internal; - ptpConnectCount[i] = 0; // Add Port Forward to Router. Or may be doesn't need to be forwarded since local port already accessible from outside if others were able to connect & get accepted at this point, right? //sceNetPortOpen("TCP", internal->lport); @@ -2872,7 +2871,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int int newsocket = accept(ptpsocket.id, (sockaddr*)&peeraddr, &peeraddrlen); int error = errno; - if (newsocket == SOCKET_ERROR) { + if (newsocket == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK)) { if (flag == 0) { // Simulate blocking behaviour with non-blocking socket u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; @@ -2974,7 +2973,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Instant Connection (Lucky!) if (connectresult != SOCKET_ERROR || errorcode == EISCONN) { - ptpConnectCount[id - 1]++; + socket->connectCount++; // Set Connected State ptpsocket.state = ADHOC_PTP_STATE_ESTABLISHED; @@ -2985,9 +2984,9 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Connection in Progress else if (connectresult == SOCKET_ERROR && connectInProgress(errorcode)) { - ptpConnectCount[id - 1]++; + socket->connectCount++; // Nonblocking Mode. First attempt need to be blocking for GvG Next Plus to work, even though it used non-blocking flag but only try to connect once per socket, which mean treating it just like blocking socket instead of non-blocking :( - if (flag && ptpConnectCount[id - 1] > 1) { + if (flag && socket->connectCount > 1) { //if (errorcode == EALREADY) return ERROR_NET_ADHOC_BUSY; return ERROR_NET_ADHOC_WOULD_BLOCK; } @@ -2995,7 +2994,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { else { // Simulate blocking behaviour with non-blocking socket u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; - return WaitBlockingAdhocSocket(threadSocketId, PTP_CONNECT, id, nullptr, nullptr, timeout, nullptr, nullptr, "ptp connect"); + return WaitBlockingAdhocSocket(threadSocketId, PTP_CONNECT, id, nullptr, nullptr, (flag)? socket->send_timeout: timeout, nullptr, nullptr, "ptp connect"); } } } @@ -3042,7 +3041,6 @@ int NetAdhocPtp_Close(int id, int unknown) { // Free Reference adhocSockets[id - 1] = NULL; - ptpConnectCount.erase(id - 1); // Success return 0; @@ -3169,6 +3167,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Socket Type internal->type = SOCK_PTP; + internal->recv_timeout = rexmt_int; // Copy Infrastructure Socket ID internal->data.ptp.id = tcpsocket; @@ -3185,7 +3184,6 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Link PTP Socket adhocSockets[i] = internal; - ptpConnectCount[i] = 0; // Add Port Forward to Router //sceNetPortOpen("TCP", sport); @@ -3367,11 +3365,11 @@ static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeou int received = 0; int error = 0; - // Receive Data + // Receive Data. POSIX: May received 0 bytes when the remote peer already closed the connection. received = recv(ptpsocket.id, (char*)buf, *len, MSG_NOSIGNAL); error = errno; - if (received == SOCKET_ERROR) { + if (received == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK)) { if (flag == 0) { // Simulate blocking behaviour with non-blocking socket u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; From 2808903663d81ebcf570ce78ebecdc9002151f88 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 14 Sep 2020 03:36:39 +0700 Subject: [PATCH 702/848] Making sure the are no compiler warnings on adhoc code on android --- Core/HLE/proAdhoc.cpp | 2 +- Core/HLE/sceNetAdhoc.cpp | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 85534e45e9..405e400d1c 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1328,7 +1328,7 @@ int friendFinder(){ else { // Update Ping Time lastping = now; - DEBUG_LOG(SCENET, "FriendFinder: Sending OPCODE_PING (%llu)", now); + DEBUG_LOG(SCENET, "FriendFinder: Sending OPCODE_PING (%llu)", static_cast(now)); } } } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 76654c3745..f9a1d8ed8f 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1553,10 +1553,8 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { if (affectedsockets > 0) { affectedsockets = 0; for (int i = 0; i < count; i++) { - s32_le* fd_flags; if (sds[i].id > 0 && sds[i].id <= MAX_SOCKET && adhocSockets[sds[i].id - 1] != NULL) { auto sock = adhocSockets[sds[i].id - 1]; - fd_flags = &sock->flags; if (sock->type == SOCK_PTP) { fd = sock->data.ptp.id; } @@ -1572,10 +1570,10 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { sds[i].revents |= ADHOC_EV_ALERT; // Does Alert can be raised on revents regardless of events bitmask? if (sds[i].revents) affectedsockets++; - if (*fd_flags & ADHOC_F_ALERTPOLL) { + if (sock->flags & ADHOC_F_ALERTPOLL) { affectedsockets = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? - *fd_flags &= ~ADHOC_F_ALERTPOLL; + sock->flags &= ~ADHOC_F_ALERTPOLL; break; } } From d5717c835f4ec26ad79ed7eb8790b857dc3b74d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 22:51:22 +0200 Subject: [PATCH 703/848] Comment fix --- GPU/Common/TextureCacheCommon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 698803fd92..668db2a130 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -187,10 +187,10 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl case TEX_FILTER_AUTO: // Follow what the game wants. We just do a single heuristic change to avoid bleeding of wacky color test colors // in higher resolution (used by some games for sprites, and they accidentally have linear filter on). - // This does duplicate the body of the above if, but it's clearer this way. if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) { bool uglyColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0; if (uglyColorTest) { + // Force to nearest. magFilt &= ~1; minFilt &= ~1; } @@ -206,7 +206,7 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl break; case TEX_FILTER_FORCE_NEAREST: default: - // Just override everything to nearest without checks. Safe (but ugly). + // Just force to nearest without checks. Safe (but ugly). magFilt &= ~1; minFilt &= ~1; break; From b81e0669e6a6cfac09a2767a4ae3042cce2794a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 22:37:16 +0200 Subject: [PATCH 704/848] TextureCacheDX9: Use the already centralized sampler setup code from D3D11/Vulkan. --- GPU/D3D11/TextureCacheD3D11.cpp | 14 ++---- GPU/Directx9/TextureCacheDX9.cpp | 84 ++++++++------------------------ GPU/Directx9/TextureCacheDX9.h | 3 +- GPU/GLES/TextureCacheGLES.cpp | 2 + 4 files changed, 28 insertions(+), 75 deletions(-) diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 01d102271a..8e4b72b338 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -157,19 +157,11 @@ void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) { } void TextureCacheD3D11::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { - int minFilt; - int magFilt; - bool sClamp; - bool tClamp; - float lodBias; - GETexLevelMode mode; - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, 0, 0, mode); + UpdateSamplingParams(0, 0, key); - key.minFilt = minFilt & 1; + key.minFilt &= 1; key.mipFilt = 0; - key.magFilt = magFilt & 1; - key.sClamp = sClamp; - key.tClamp = tClamp; + key.magFilt &= 1; // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. // This happens whether we have OES_texture_npot or not. diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 667a972349..89b294b763 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -146,74 +146,30 @@ static const u8 MagFilt[2] = { D3DTEXF_LINEAR }; -void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) { - int minFilt; - int magFilt; - bool sClamp; - bool tClamp; - float lodBias; - GETexLevelMode mode; - u8 maxLevel = (entry.status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry.maxLevel; - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, entry.addr, mode); - - if (maxLevel != 0) { - if (mode == GE_TEXLEVEL_MODE_AUTO) { - dxstate.texMaxMipLevel.set(0); - dxstate.texMipLodBias.set(lodBias); - } else if (mode == GE_TEXLEVEL_MODE_CONST) { - // TODO: This is just an approximation - texMaxMipLevel sets the lowest numbered mip to use. - // Unfortunately, this doesn't support a const 1.5 or etc. - dxstate.texMaxMipLevel.set(std::max(0, std::min((int)maxLevel, (int)lodBias))); - dxstate.texMipLodBias.set(-1000.0f); - } else { // if (mode == GE_TEXLEVEL_MODE_SLOPE{ - dxstate.texMaxMipLevel.set(0); - dxstate.texMipLodBias.set(0.0f); - } - } else { - dxstate.texMaxMipLevel.set(0); - dxstate.texMipLodBias.set(0.0f); - } - - D3DTEXTUREFILTERTYPE minf = (D3DTEXTUREFILTERTYPE)MinFilt[minFilt]; - D3DTEXTUREFILTERTYPE mipf = (D3DTEXTUREFILTERTYPE)MipFilt[minFilt]; - D3DTEXTUREFILTERTYPE magf = (D3DTEXTUREFILTERTYPE)MagFilt[magFilt]; - - if (gstate_c.Supports(GPU_SUPPORTS_ANISOTROPY) && g_Config.iAnisotropyLevel > 0 && minf == D3DTEXF_LINEAR) { - minf = D3DTEXF_ANISOTROPIC; - } - - dxstate.texMinFilter.set(minf); - dxstate.texMipFilter.set(mipf); - dxstate.texMagFilter.set(magf); - dxstate.texAddressU.set(sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); - dxstate.texAddressV.set(tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); -} - void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { - int minFilt; - int magFilt; - bool sClamp; - bool tClamp; - float lodBias; - GETexLevelMode mode; - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, 0, 0, mode); + SamplerCacheKey key; + UpdateSamplingParams(0, 0, key); - dxstate.texMinFilter.set(MinFilt[minFilt]); - dxstate.texMipFilter.set(MipFilt[minFilt]); - dxstate.texMagFilter.set(MagFilt[magFilt]); - dxstate.texMipLodBias.set(0.0f); - dxstate.texMaxMipLevel.set(0.0f); - - // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. - // This happens whether we have OES_texture_npot or not. + // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. int w = gstate.getTextureWidth(0); int h = gstate.getTextureHeight(0); if (w != bufferWidth || h != bufferHeight) { - return; + key.sClamp = true; + key.tClamp = true; } - dxstate.texAddressU.set(sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); - dxstate.texAddressV.set(tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); + ApplySamplingParams(key); +} + +void TextureCacheDX9::ApplySamplingParams(const SamplerCacheKey &key) { + dxstate.texMinFilter.set(key.minFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); + dxstate.texMipFilter.set(key.mipFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); + dxstate.texMagFilter.set(key.magFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); + dxstate.texMipLodBias.set((float)key.lodBias / 256.0f); + dxstate.texMaxMipLevel.set(key.maxLevel / 256); + + dxstate.texAddressU.set(key.sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); + dxstate.texAddressV.set(key.tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); } void TextureCacheDX9::StartFrame() { @@ -236,7 +192,6 @@ void TextureCacheDX9::StartFrame() { DWORD anisotropyLevel = aniso > maxAnisotropyLevel ? maxAnisotropyLevel : aniso; device_->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, anisotropyLevel); } - } void TextureCacheDX9::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutBase, bool clutIndexIsSimple) { @@ -281,7 +236,10 @@ void TextureCacheDX9::BindTexture(TexCacheEntry *entry) { device_->SetTexture(0, texture); lastBoundTexture = texture; } - UpdateSamplingParams(*entry, false); + + SamplerCacheKey key; + UpdateSamplingParams(entry->maxLevel, entry->addr, key); + ApplySamplingParams(key); } void TextureCacheDX9::Unbind() { diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index a0d488c77b..4e48ffc376 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -62,7 +62,8 @@ protected: void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override; private: - void UpdateSamplingParams(TexCacheEntry &entry, bool force); + void ApplySamplingParams(const SamplerCacheKey &key); + void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, int maxLevel, int scaleFactor, u32 dstFmt); D3DFORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; TexCacheEntry::TexStatus CheckAlpha(const u32 *pixelData, u32 dstFmt, int stride, int w, int h); diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 6ee2eabcd8..34294ca681 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -161,6 +161,8 @@ void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) { } void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, bool forcePoint) { + SamplerCacheKey key; + UpdateSamplingParams(0, 0, key); int minFilt; int magFilt; bool sClamp; From 9ea295093bdd364d343b126218d3e1059b95ef12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 22:48:44 +0200 Subject: [PATCH 705/848] TextureCacheGLES: Also share the same sampler calculation for GLES. --- GPU/GLES/TextureCacheGLES.cpp | 78 +++++++++---------------------- GPU/GLES/TextureCacheGLES.h | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 15 ++---- 3 files changed, 27 insertions(+), 68 deletions(-) diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 34294ca681..9a4b5df1ab 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -115,78 +115,39 @@ static const GLuint MagFiltGL[2] = { GL_LINEAR }; -// This should not have to be done per texture! OpenGL is silly yo -void TextureCacheGLES::UpdateSamplingParams(TexCacheEntry &entry, bool force) { - int minFilt; - int magFilt; - bool sClamp; - bool tClamp; - float lodBias; - u8 maxLevel = (entry.status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry.maxLevel; - GETexLevelMode mode; - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, entry.addr, mode); - +void TextureCacheGLES::ApplySamplingParams(const SamplerCacheKey &key) { if (gstate_c.Supports(GPU_SUPPORTS_TEXTURE_LOD_CONTROL)) { - float minLod = 0.0f; - float maxLod = 0.0f; - if (maxLevel != 0) { - // TODO: What about a swap of autoMip mode? - if (true) { - if (mode == GE_TEXLEVEL_MODE_AUTO) { - minLod = 0.0f; - maxLod = (float)maxLevel; - } else if (mode == GE_TEXLEVEL_MODE_CONST) { - minLod = std::max(0.0f, std::min((float)maxLevel, lodBias)); - maxLod = std::max(0.0f, std::min((float)maxLevel, lodBias)); - } else { // mode == GE_TEXLEVEL_MODE_SLOPE) { - // It's incorrect to use the slope as a bias. Instead it should be passed - // into the shader directly as an explicit lod level, with the bias on top. For now, we just kill the - // lodBias in this mode, working around #9772. -#ifndef USING_GLES2 - lodBias = 0.0f; -#endif - minLod = 0.0f; - maxLod = (float)maxLevel; - } - } - } else { - minLod = 0.0f; - maxLod = 0.0f; - } + float minLod = (float)key.minLevel / 256.0f; + float maxLod = (float)key.maxLevel / 256.0f; + float lodBias = (float)key.lodBias / 256.0f; render_->SetTextureLod(0, minLod, maxLod, lodBias); } float aniso = 0.0f; - render_->SetTextureSampler(0, sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, MagFiltGL[magFilt], MinFiltGL[minFilt], aniso); + int magKey = ((int)key.mipEnable << 2) | ((int)key.mipFilt << 1) | ((int)key.magFilt); + render_->SetTextureSampler(0, + key.sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, key.tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, + MagFiltGL[magKey], key.minFilt ? GL_LINEAR : GL_NEAREST, aniso); } void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, bool forcePoint) { SamplerCacheKey key; UpdateSamplingParams(0, 0, key); - int minFilt; - int magFilt; - bool sClamp; - bool tClamp; - float lodBias; - GETexLevelMode mode; - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, 0, 0, mode); - - minFilt &= 1; // framebuffers can't mipmap. + key.mipEnable = false; // framebuffers can't mipmap. if (forcePoint) { - minFilt &= ~1; - magFilt &= ~1; + key.magFilt = false; + key.minFilt = false; } - // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. // This happens whether we have OES_texture_npot or not. int w = gstate.getTextureWidth(0); int h = gstate.getTextureHeight(0); if (w != bufferWidth || h != bufferHeight) { - sClamp = true; - tClamp = true; + key.sClamp = true; + key.tClamp = true; } - float aniso = 0.0f; - render_->SetTextureSampler(TEX_SLOT_PSP_TEXTURE, sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, MagFiltGL[magFilt], MinFiltGL[minFilt], aniso); + key.aniso = 0.0f; + ApplySamplingParams(key); } static void ConvertColors(void *dstBuf, const void *srcBuf, Draw::DataFormat dstFmt, int numPixels) { @@ -289,7 +250,9 @@ void TextureCacheGLES::BindTexture(TexCacheEntry *entry) { render_->BindTexture(0, entry->textureName); lastBoundTexture = entry->textureName; } - UpdateSamplingParams(*entry, false); + SamplerCacheKey key; + UpdateSamplingParams(entry->maxLevel, entry->addr, key); + ApplySamplingParams(key); gstate_c.SetUseShaderDepal(false); } @@ -650,7 +613,10 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) { // This will rebind it, but that's okay. // Need to actually bind it now - it might only have gotten bound in the init phase. render_->BindTexture(TEX_SLOT_PSP_TEXTURE, entry->textureName); - UpdateSamplingParams(*entry, true); + + SamplerCacheKey key; + UpdateSamplingParams(entry->maxLevel, entry->addr, key); + ApplySamplingParams(key); } Draw::DataFormat TextureCacheGLES::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const { diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index 36e203579f..0e85dc58c3 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -75,7 +75,7 @@ protected: void ReleaseTexture(TexCacheEntry *entry, bool delete_them) override; private: - void UpdateSamplingParams(TexCacheEntry &entry, bool force); + void ApplySamplingParams(const SamplerCacheKey &key); void LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &replaced, int level, int scaleFactor, Draw::DataFormat dstFmt); Draw::DataFormat GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 8627099be6..0b3fa58544 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -440,24 +440,17 @@ static const VkFilter MagFiltVK[2] = { }; void TextureCacheVulkan::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { - int minFilt; - int magFilt; - bool sClamp; - bool tClamp; - float lodBias; - GETexLevelMode mode; - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, 0, 0, mode); + UpdateSamplingParams(0, 0, key); - key.minFilt = minFilt & 1; + key.minFilt &= 1; key.mipFilt = 0; - key.magFilt = magFilt & 1; - key.sClamp = sClamp; - key.tClamp = tClamp; + key.magFilt &= 1; // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. // This happens whether we have OES_texture_npot or not. int w = gstate.getTextureWidth(0); int h = gstate.getTextureHeight(0); + if (w != bufferWidth || h != bufferHeight) { key.sClamp = true; key.tClamp = true; From 46b3fb0821b43edfd6c86706b648474a2998f31e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 23:10:43 +0200 Subject: [PATCH 706/848] Workarounds for D3D9's very limited mip level control. --- GPU/Common/TextureCacheCommon.cpp | 31 +++++++-------------- GPU/D3D11/TextureCacheD3D11.cpp | 1 + GPU/Directx9/TextureCacheDX9.cpp | 45 +++++++++++-------------------- GPU/Vulkan/TextureCacheVulkan.cpp | 1 + 4 files changed, 28 insertions(+), 50 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 668db2a130..1fedfa67d3 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -146,19 +146,18 @@ static int TexLog2(float delta) { return useful - 127 * 256; } -void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel, u32 addr, GETexLevelMode &mode) { - minFilt = gstate.texfilter & 0x7; - magFilt = gstate.isMagnifyFilteringEnabled(); - sClamp = gstate.isTexCoordClampedS(); - tClamp = gstate.isTexCoordClampedT(); +void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key) { + int minFilt = gstate.texfilter & 0x7; + int magFilt = gstate.isMagnifyFilteringEnabled(); + bool sClamp = gstate.isTexCoordClampedS(); + bool tClamp = gstate.isTexCoordClampedT(); GETexLevelMode mipMode = gstate.getTexLevelMode(); - mode = mipMode; bool autoMip = mipMode == GE_TEXLEVEL_MODE_AUTO; // TODO: Slope mipmap bias is still not well understood. - lodBias = (float)gstate.getTexLevelOffset16() * (1.0f / 16.0f); + float lodBias = (float)gstate.getTexLevelOffset16() * (1.0f / 16.0f); if (mipMode == GE_TEXLEVEL_MODE_SLOPE) { lodBias += 1.0f + TexLog2(gstate.getTextureLodSlope()) * (1.0f / 256.0f); } @@ -175,8 +174,8 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl lodBias = 0.0f; } - if (!(magFilt & 1) && addr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) { - if (videos_.find(addr & 0x3FFFFFFF) != videos_.end()) { + if (!(magFilt & 1) && texAddr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) { + if (videos_.find(texAddr & 0x3FFFFFFF) != videos_.end()) { // Enforce bilinear filtering on magnification. magFilt |= 1; } @@ -211,18 +210,7 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl minFilt &= ~1; break; } -} -void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key) { - // TODO: Make GetSamplingParams write SamplerCacheKey directly - int minFilt; - int magFilt; - bool sClamp; - bool tClamp; - float lodBias; - GETexLevelMode mode; - - GetSamplingParams(minFilt, magFilt, sClamp, tClamp, lodBias, maxLevel, texAddr, mode); key.minFilt = minFilt & 1; key.mipEnable = (minFilt >> 2) & 1; key.mipFilt = (minFilt >> 1) & 1; @@ -235,8 +223,9 @@ void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, Sampler key.maxLevel = 0; key.minLevel = 0; key.lodBias = 0; + key.mipFilt = 0; } else { - switch (mode) { + switch (mipMode) { case GE_TEXLEVEL_MODE_AUTO: key.maxLevel = maxLevel * 256; key.minLevel = 0; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 8e4b72b338..717a4b8119 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -159,6 +159,7 @@ void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) { void TextureCacheD3D11::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { UpdateSamplingParams(0, 0, key); + key.mipEnable = false; key.minFilt &= 1; key.mipFilt = 0; key.magFilt &= 1; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 89b294b763..16272c3b84 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -119,37 +119,15 @@ D3DFORMAT getClutDestFormat(GEPaletteFormat format) { return D3DFMT_A8R8G8B8; } -static const u8 MinFilt[8] = { - D3DTEXF_POINT, - D3DTEXF_LINEAR, - D3DTEXF_POINT, - D3DTEXF_LINEAR, - D3DTEXF_POINT, // GL_NEAREST_MIPMAP_NEAREST, - D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_NEAREST, - D3DTEXF_POINT, // GL_NEAREST_MIPMAP_LINEAR, - D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR, -}; - -static const u8 MipFilt[8] = { - D3DTEXF_NONE, - D3DTEXF_NONE, - D3DTEXF_NONE, - D3DTEXF_NONE, - D3DTEXF_POINT, // GL_NEAREST_MIPMAP_NEAREST, - D3DTEXF_POINT, // GL_LINEAR_MIPMAP_NEAREST, - D3DTEXF_LINEAR, // GL_NEAREST_MIPMAP_LINEAR, - D3DTEXF_LINEAR, // GL_LINEAR_MIPMAP_LINEAR, -}; - -static const u8 MagFilt[2] = { - D3DTEXF_POINT, - D3DTEXF_LINEAR -}; - void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { SamplerCacheKey key; UpdateSamplingParams(0, 0, key); + key.mipEnable = false; + key.minFilt &= 1; + key.mipFilt = 0; + key.magFilt &= 1; + // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. int w = gstate.getTextureWidth(0); int h = gstate.getTextureHeight(0); @@ -165,8 +143,17 @@ void TextureCacheDX9::ApplySamplingParams(const SamplerCacheKey &key) { dxstate.texMinFilter.set(key.minFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); dxstate.texMipFilter.set(key.mipFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); dxstate.texMagFilter.set(key.magFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); - dxstate.texMipLodBias.set((float)key.lodBias / 256.0f); - dxstate.texMaxMipLevel.set(key.maxLevel / 256); + + // DX9 mip levels are .. odd. The "max level" sets the LARGEST mip to use. + // We can enforce only the top mip level by setting a massive negative lod bias. + + if (!key.mipEnable) { + dxstate.texMaxMipLevel.set(0); + dxstate.texMipLodBias.set(-100.0f); + } else { + dxstate.texMipLodBias.set((float)key.lodBias / 256.0f); + dxstate.texMaxMipLevel.set(key.minLevel / 256); + } dxstate.texAddressU.set(key.sClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); dxstate.texAddressV.set(key.tClamp ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 0b3fa58544..6ecd34e419 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -442,6 +442,7 @@ static const VkFilter MagFiltVK[2] = { void TextureCacheVulkan::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { UpdateSamplingParams(0, 0, key); + key.mipEnable = false; key.minFilt &= 1; key.mipFilt = 0; key.magFilt &= 1; From d8263d50f467061d34a8b72bcdf0df93eaea879b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 23:25:21 +0200 Subject: [PATCH 707/848] Make the signature of all the SetFramebufferSamplingParams the same --- GPU/D3D11/TextureCacheD3D11.cpp | 1 + GPU/Directx9/TextureCacheDX9.cpp | 10 +++++----- GPU/Directx9/TextureCacheDX9.h | 2 +- GPU/GLES/TextureCacheGLES.cpp | 20 +++++++++++--------- GPU/GLES/TextureCacheGLES.h | 2 +- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 717a4b8119..b9ceb5326e 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -421,6 +421,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, gstate_c.SetTextureFullAlpha(gstate.getTextureFormat() == GE_TFMT_5650); framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); // Probably not necessary. } + SamplerCacheKey samplerKey{}; SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey); ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 16272c3b84..cafe16f7d0 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -119,8 +119,7 @@ D3DFORMAT getClutDestFormat(GEPaletteFormat format) { return D3DFMT_A8R8G8B8; } -void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { - SamplerCacheKey key; +void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { UpdateSamplingParams(0, 0, key); key.mipEnable = false; @@ -135,8 +134,6 @@ void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHe key.sClamp = true; key.tClamp = true; } - - ApplySamplingParams(key); } void TextureCacheDX9::ApplySamplingParams(const SamplerCacheKey &key) { @@ -412,7 +409,10 @@ void TextureCacheDX9::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, G } framebufferManagerDX9_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFromFramebuffer"); - SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); + + SamplerCacheKey key; + SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, key); + ApplySamplingParams(key); } void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) { diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index 4e48ffc376..9b2d9315bc 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -52,7 +52,7 @@ public: void ForgetLastTexture() override; void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override; - void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight); + void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 9a4b5df1ab..cb0ce93ef2 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -130,14 +130,9 @@ void TextureCacheGLES::ApplySamplingParams(const SamplerCacheKey &key) { MagFiltGL[magKey], key.minFilt ? GL_LINEAR : GL_NEAREST, aniso); } -void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, bool forcePoint) { - SamplerCacheKey key; +void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { UpdateSamplingParams(0, 0, key); key.mipEnable = false; // framebuffers can't mipmap. - if (forcePoint) { - key.magFilt = false; - key.minFilt = false; - } // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. // This happens whether we have OES_texture_npot or not. int w = gstate.getTextureWidth(0); @@ -147,7 +142,6 @@ void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferH key.tClamp = true; } key.aniso = 0.0f; - ApplySamplingParams(key); } static void ConvertColors(void *dstBuf, const void *srcBuf, Draw::DataFormat dstFmt, int numPixels) { @@ -380,7 +374,12 @@ void TextureCacheGLES::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, render_->BindTexture(TEX_SLOT_CLUT, clutTexture); render_->SetTextureSampler(TEX_SLOT_CLUT, GL_REPEAT, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST, 0.0f); framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); - SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, true); + SamplerCacheKey key; + SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, key); + key.magFilt = false; + key.minFilt = false; + key.mipEnable = false; + ApplySamplingParams(key); InvalidateLastTexture(); // Since we started/ended render passes, might need these. @@ -430,7 +429,10 @@ void TextureCacheGLES::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, } framebufferManagerGL_->RebindFramebuffer("ApplyTextureFramebuffer"); - SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, false); + + SamplerCacheKey key; + SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, key); + ApplySamplingParams(key); // Since we started/ended render passes, might need these. gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index 0e85dc58c3..42329b57a2 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -63,7 +63,7 @@ public: } } - void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, bool forcePoint); + void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; void DeviceLost(); From 5190f85c8e426c4e12d8ce4b9b810acd64ecb999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 23:34:00 +0200 Subject: [PATCH 708/848] Unify/centralize SetFramebufferSamplingParams. Some include cleanup. --- GPU/Common/TextureCacheCommon.cpp | 18 ++++++++++++++++++ GPU/Common/TextureCacheCommon.h | 3 ++- GPU/D3D11/GPU_D3D11.h | 6 +++--- GPU/D3D11/TextureCacheD3D11.cpp | 18 ------------------ GPU/D3D11/TextureCacheD3D11.h | 1 - GPU/Directx9/GPU_DX9.h | 6 +++--- GPU/Directx9/TextureCacheDX9.cpp | 17 ----------------- GPU/Directx9/TextureCacheDX9.h | 2 -- GPU/GLES/GPU_GLES.h | 6 +++--- GPU/GLES/TextureCacheGLES.cpp | 14 -------------- GPU/GLES/TextureCacheGLES.h | 1 - GPU/Vulkan/DebugVisVulkan.cpp | 1 + GPU/Vulkan/GPU_Vulkan.h | 6 +++--- GPU/Vulkan/StateMappingVulkan.cpp | 1 - GPU/Vulkan/TextureCacheVulkan.cpp | 19 ------------------- GPU/Vulkan/TextureCacheVulkan.h | 1 - 16 files changed, 33 insertions(+), 87 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 1fedfa67d3..04a8669ce1 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -252,6 +252,24 @@ void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, Sampler } } +void TextureCacheCommon::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { + UpdateSamplingParams(0, 0, key); + + key.mipEnable = false; + key.minFilt &= 1; + key.mipFilt = 0; + key.magFilt &= 1; + key.aniso = 0.0; + + // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. + int w = gstate.getTextureWidth(0); + int h = gstate.getTextureHeight(0); + if (w != bufferWidth || h != bufferHeight) { + key.sClamp = true; + key.tClamp = true; + } +} + void TextureCacheCommon::UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode) { // If the texture is >= 512 pixels tall... if (entry->dim >= 0x900) { diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 652eba6578..db75b9baba 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -284,8 +284,9 @@ protected: } u32 EstimateTexMemoryUsage(const TexCacheEntry *entry); - void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel, u32 addr, GETexLevelMode &mode); + void UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key); // Used by D3D11 and Vulkan. + void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode); FramebufferMatchInfo MatchFramebuffer(const TextureDefinition &entry, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; diff --git a/GPU/D3D11/GPU_D3D11.h b/GPU/D3D11/GPU_D3D11.h index 0c1f1d3524..bf41243b88 100644 --- a/GPU/D3D11/GPU_D3D11.h +++ b/GPU/D3D11/GPU_D3D11.h @@ -17,19 +17,19 @@ #pragma once -#include -#include +#include +#include #include #include "GPU/GPUCommon.h" #include "GPU/D3D11/DrawEngineD3D11.h" -#include "GPU/D3D11/TextureCacheD3D11.h" #include "GPU/D3D11/DepalettizeShaderD3D11.h" #include "GPU/Common/VertexDecoderCommon.h" class FramebufferManagerD3D11; class ShaderManagerD3D11; class LinkedShaderD3D11; +class TextureCacheD3D11; class GPU_D3D11 : public GPUCommon { public: diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index b9ceb5326e..3957b48c5c 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -156,24 +156,6 @@ void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) { } } -void TextureCacheD3D11::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { - UpdateSamplingParams(0, 0, key); - - key.mipEnable = false; - key.minFilt &= 1; - key.mipFilt = 0; - key.magFilt &= 1; - - // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. - // This happens whether we have OES_texture_npot or not. - int w = gstate.getTextureWidth(0); - int h = gstate.getTextureHeight(0); - if (w != bufferWidth || h != bufferHeight) { - key.sClamp = true; - key.tClamp = true; - } -} - void TextureCacheD3D11::StartFrame() { InvalidateLastTexture(); timesInvalidatedAllThisFrame_ = 0; diff --git a/GPU/D3D11/TextureCacheD3D11.h b/GPU/D3D11/TextureCacheD3D11.h index db154c5a77..6aa3bcda9e 100644 --- a/GPU/D3D11/TextureCacheD3D11.h +++ b/GPU/D3D11/TextureCacheD3D11.h @@ -60,7 +60,6 @@ public: void ForgetLastTexture() override; void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override; - void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; protected: diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h index aab20eabe1..6f33fcf90c 100644 --- a/GPU/Directx9/GPU_DX9.h +++ b/GPU/Directx9/GPU_DX9.h @@ -17,13 +17,12 @@ #pragma once -#include -#include +#include +#include #include "GPU/GPUCommon.h" #include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/DrawEngineDX9.h" -#include "GPU/Directx9/TextureCacheDX9.h" #include "GPU/Directx9/DepalettizeShaderDX9.h" #include "GPU/Common/VertexDecoderCommon.h" @@ -31,6 +30,7 @@ namespace DX9 { class ShaderManagerDX9; class LinkedShaderDX9; +class TextureCacheDX9; class GPU_DX9 : public GPUCommon { public: diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index cafe16f7d0..5343a3100b 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -119,23 +119,6 @@ D3DFORMAT getClutDestFormat(GEPaletteFormat format) { return D3DFMT_A8R8G8B8; } -void TextureCacheDX9::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { - UpdateSamplingParams(0, 0, key); - - key.mipEnable = false; - key.minFilt &= 1; - key.mipFilt = 0; - key.magFilt &= 1; - - // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. - int w = gstate.getTextureWidth(0); - int h = gstate.getTextureHeight(0); - if (w != bufferWidth || h != bufferHeight) { - key.sClamp = true; - key.tClamp = true; - } -} - void TextureCacheDX9::ApplySamplingParams(const SamplerCacheKey &key) { dxstate.texMinFilter.set(key.minFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); dxstate.texMipFilter.set(key.mipFilt ? D3DTEXF_LINEAR : D3DTEXF_POINT); diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index 9b2d9315bc..3a0c291586 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -52,8 +52,6 @@ public: void ForgetLastTexture() override; void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override; - void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); - bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; protected: diff --git a/GPU/GLES/GPU_GLES.h b/GPU/GLES/GPU_GLES.h index 0775ec8d8b..5bb68e2ef3 100644 --- a/GPU/GLES/GPU_GLES.h +++ b/GPU/GLES/GPU_GLES.h @@ -17,17 +17,17 @@ #pragma once -#include -#include +#include +#include #include "GPU/GPUCommon.h" #include "GPU/GLES/FramebufferManagerGLES.h" #include "GPU/GLES/DrawEngineGLES.h" -#include "GPU/GLES/TextureCacheGLES.h" #include "GPU/GLES/DepalettizeShaderGLES.h" #include "GPU/GLES/FragmentTestCacheGLES.h" class ShaderManagerGLES; +class TextureCacheGLES; class LinkedShader; class GPU_GLES : public GPUCommon { diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index cb0ce93ef2..1b7af5f044 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -130,20 +130,6 @@ void TextureCacheGLES::ApplySamplingParams(const SamplerCacheKey &key) { MagFiltGL[magKey], key.minFilt ? GL_LINEAR : GL_NEAREST, aniso); } -void TextureCacheGLES::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { - UpdateSamplingParams(0, 0, key); - key.mipEnable = false; // framebuffers can't mipmap. - // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. - // This happens whether we have OES_texture_npot or not. - int w = gstate.getTextureWidth(0); - int h = gstate.getTextureHeight(0); - if (w != bufferWidth || h != bufferHeight) { - key.sClamp = true; - key.tClamp = true; - } - key.aniso = 0.0f; -} - static void ConvertColors(void *dstBuf, const void *srcBuf, Draw::DataFormat dstFmt, int numPixels) { const u32 *src = (const u32 *)srcBuf; u32 *dst = (u32 *)dstBuf; diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index 42329b57a2..7564b635b5 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -63,7 +63,6 @@ public: } } - void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; void DeviceLost(); diff --git a/GPU/Vulkan/DebugVisVulkan.cpp b/GPU/Vulkan/DebugVisVulkan.cpp index 8f2cc381a4..023e840d56 100644 --- a/GPU/Vulkan/DebugVisVulkan.cpp +++ b/GPU/Vulkan/DebugVisVulkan.cpp @@ -25,6 +25,7 @@ #include "Common/Vulkan/VulkanImage.h" #include "GPU/Vulkan/GPU_Vulkan.h" #include "GPU/Vulkan/VulkanUtil.h" +#include "GPU/Vulkan/TextureCacheVulkan.h" #undef DrawText diff --git a/GPU/Vulkan/GPU_Vulkan.h b/GPU/Vulkan/GPU_Vulkan.h index a56304869b..894cc295b4 100644 --- a/GPU/Vulkan/GPU_Vulkan.h +++ b/GPU/Vulkan/GPU_Vulkan.h @@ -17,18 +17,18 @@ #pragma once -#include -#include +#include +#include #include "GPU/GPUCommon.h" #include "GPU/Vulkan/DrawEngineVulkan.h" #include "GPU/Vulkan/PipelineManagerVulkan.h" -#include "GPU/Vulkan/TextureCacheVulkan.h" #include "GPU/Vulkan/DepalettizeShaderVulkan.h" class FramebufferManagerVulkan; class ShaderManagerVulkan; class LinkedShader; +class TextureCacheVulkan; class GPU_Vulkan : public GPUCommon { public: diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 56980441dc..596badb5c7 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -28,7 +28,6 @@ #include "Core/Reporting.h" #include "GPU/Vulkan/GPU_Vulkan.h" #include "GPU/Vulkan/PipelineManagerVulkan.h" -#include "GPU/Vulkan/TextureCacheVulkan.h" #include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Vulkan/DrawEngineVulkan.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 6ecd34e419..e17cbae949 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -439,25 +439,6 @@ static const VkFilter MagFiltVK[2] = { VK_FILTER_LINEAR }; -void TextureCacheVulkan::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { - UpdateSamplingParams(0, 0, key); - - key.mipEnable = false; - key.minFilt &= 1; - key.mipFilt = 0; - key.magFilt &= 1; - - // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. - // This happens whether we have OES_texture_npot or not. - int w = gstate.getTextureWidth(0); - int h = gstate.getTextureHeight(0); - - if (w != bufferWidth || h != bufferHeight) { - key.sClamp = true; - key.tClamp = true; - } -} - void TextureCacheVulkan::StartFrame() { InvalidateLastTexture(); depalShaderCache_->Decimate(); diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index 059b4be0ec..7aaa04d56e 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -100,7 +100,6 @@ public: imageView = imageView_; sampler = curSampler_; } - void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; From a222b2017ecb6c587e3eab1ba3498b819cbc1807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 23:46:57 +0200 Subject: [PATCH 709/848] Switch to a returned value and rename these functions. --- GPU/Common/TextureCacheCommon.cpp | 12 +++++++++--- GPU/Common/TextureCacheCommon.h | 4 ++-- GPU/D3D11/TextureCacheD3D11.cpp | 8 +++----- GPU/Directx9/TextureCacheDX9.cpp | 12 +++++------- GPU/GLES/TextureCacheGLES.cpp | 27 ++++++++++++--------------- GPU/Vulkan/TextureCacheVulkan.cpp | 8 +++----- 6 files changed, 34 insertions(+), 37 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 04a8669ce1..33ae0baa1b 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -146,7 +146,9 @@ static int TexLog2(float delta) { return useful - 127 * 256; } -void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key) { +SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) { + SamplerCacheKey key; + int minFilt = gstate.texfilter & 0x7; int magFilt = gstate.isMagnifyFilteringEnabled(); bool sClamp = gstate.isTexCoordClampedS(); @@ -250,11 +252,14 @@ void TextureCacheCommon::UpdateSamplingParams(int maxLevel, u32 texAddr, Sampler break; } } + + return key; } -void TextureCacheCommon::SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key) { - UpdateSamplingParams(0, 0, key); +SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { + SamplerCacheKey key = GetSamplingParams(0, 0); + // Kill any mipmapping settings. key.mipEnable = false; key.minFilt &= 1; key.mipFilt = 0; @@ -268,6 +273,7 @@ void TextureCacheCommon::SetFramebufferSamplingParams(u16 bufferWidth, u16 buffe key.sClamp = true; key.tClamp = true; } + return key; } void TextureCacheCommon::UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode) { diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index db75b9baba..17a1aa4de7 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -285,8 +285,8 @@ protected: u32 EstimateTexMemoryUsage(const TexCacheEntry *entry); - void UpdateSamplingParams(int maxLevel, u32 texAddr, SamplerCacheKey &key); // Used by D3D11 and Vulkan. - void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight, SamplerCacheKey &key); + SamplerCacheKey GetSamplingParams(int maxLevel, u32 texAddr); + SamplerCacheKey GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight); void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode); FramebufferMatchInfo MatchFramebuffer(const TextureDefinition &entry, VirtualFramebuffer *framebuffer, u32 texaddrOffset, FramebufferNotificationChannel channel) const; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 3957b48c5c..2d3ec0f29f 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -214,10 +214,9 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) { context_->PSSetShaderResources(0, 1, &textureView); lastBoundTexture = textureView; } - SamplerCacheKey key{}; int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; - UpdateSamplingParams(maxLevel, entry->addr, key); - ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, key); + SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr); + ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey); context_->PSSetSamplers(0, 1, &state); } @@ -404,8 +403,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); // Probably not necessary. } - SamplerCacheKey samplerKey{}; - SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey); + SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey); context_->PSSetSamplers(0, 1, &state); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 5343a3100b..65480a8520 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -203,10 +203,9 @@ void TextureCacheDX9::BindTexture(TexCacheEntry *entry) { device_->SetTexture(0, texture); lastBoundTexture = texture; } - - SamplerCacheKey key; - UpdateSamplingParams(entry->maxLevel, entry->addr, key); - ApplySamplingParams(key); + int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; + SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr); + ApplySamplingParams(samplerKey); } void TextureCacheDX9::Unbind() { @@ -393,9 +392,8 @@ void TextureCacheDX9::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, G framebufferManagerDX9_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFromFramebuffer"); - SamplerCacheKey key; - SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, key); - ApplySamplingParams(key); + SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); + ApplySamplingParams(samplerKey); } void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry) { diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 1b7af5f044..292fa20ba1 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -230,9 +230,9 @@ void TextureCacheGLES::BindTexture(TexCacheEntry *entry) { render_->BindTexture(0, entry->textureName); lastBoundTexture = entry->textureName; } - SamplerCacheKey key; - UpdateSamplingParams(entry->maxLevel, entry->addr, key); - ApplySamplingParams(key); + int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; + SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr); + ApplySamplingParams(samplerKey); gstate_c.SetUseShaderDepal(false); } @@ -360,12 +360,11 @@ void TextureCacheGLES::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, render_->BindTexture(TEX_SLOT_CLUT, clutTexture); render_->SetTextureSampler(TEX_SLOT_CLUT, GL_REPEAT, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST, 0.0f); framebufferManagerGL_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_MAY_COPY_WITH_UV | BINDFBCOLOR_APPLY_TEX_OFFSET); - SamplerCacheKey key; - SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, key); - key.magFilt = false; - key.minFilt = false; - key.mipEnable = false; - ApplySamplingParams(key); + SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); + samplerKey.magFilt = false; + samplerKey.minFilt = false; + samplerKey.mipEnable = false; + ApplySamplingParams(samplerKey); InvalidateLastTexture(); // Since we started/ended render passes, might need these. @@ -416,9 +415,8 @@ void TextureCacheGLES::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, framebufferManagerGL_->RebindFramebuffer("ApplyTextureFramebuffer"); - SamplerCacheKey key; - SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, key); - ApplySamplingParams(key); + SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); + ApplySamplingParams(samplerKey); // Since we started/ended render passes, might need these. gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); @@ -602,9 +600,8 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) { // Need to actually bind it now - it might only have gotten bound in the init phase. render_->BindTexture(TEX_SLOT_PSP_TEXTURE, entry->textureName); - SamplerCacheKey key; - UpdateSamplingParams(entry->maxLevel, entry->addr, key); - ApplySamplingParams(key); + SamplerCacheKey samplerKey = GetSamplingParams(entry->maxLevel, entry->addr); + ApplySamplingParams(samplerKey); } Draw::DataFormat TextureCacheGLES::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const { diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index e17cbae949..c015c498e1 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -516,10 +516,9 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) { entry->vkTex->Touch(); imageView_ = entry->vkTex->GetImageView(); - SamplerCacheKey key{}; int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; - UpdateSamplingParams(maxLevel, entry->addr, key); - curSampler_ = samplerCache_.GetOrCreateSampler(key); + SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr); + curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey); drawEngine_->SetDepalTexture(VK_NULL_HANDLE); gstate_c.SetUseShaderDepal(false); } @@ -531,8 +530,7 @@ void TextureCacheVulkan::Unbind() { } void TextureCacheVulkan::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, GETextureFormat texFormat, FramebufferNotificationChannel channel) { - SamplerCacheKey samplerKey{}; - SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight, samplerKey); + SamplerCacheKey samplerKey = GetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight); DepalShaderVulkan *depalShader = nullptr; uint32_t clutMode = gstate.clutformat & 0xFFFFFF; From 0e464a61e02c3f23f47e70a9dfec2549e06f8d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 13 Sep 2020 23:59:26 +0200 Subject: [PATCH 710/848] Move overrides to the end of GetSamplingParams --- GPU/Common/TextureCacheCommon.cpp | 61 ++++++++++++++++--------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 33ae0baa1b..a37d5fecb9 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -183,36 +183,6 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) } } - // Filtering overrides - switch (g_Config.iTexFiltering) { - case TEX_FILTER_AUTO: - // Follow what the game wants. We just do a single heuristic change to avoid bleeding of wacky color test colors - // in higher resolution (used by some games for sprites, and they accidentally have linear filter on). - if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) { - bool uglyColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0; - if (uglyColorTest) { - // Force to nearest. - magFilt &= ~1; - minFilt &= ~1; - } - } - break; - case TEX_FILTER_FORCE_LINEAR: - // Override to linear filtering if there's no alpha or color testing going on. - if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) && - (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) { - magFilt |= 1; - minFilt |= 1; - } - break; - case TEX_FILTER_FORCE_NEAREST: - default: - // Just force to nearest without checks. Safe (but ugly). - magFilt &= ~1; - minFilt &= ~1; - break; - } - key.minFilt = minFilt & 1; key.mipEnable = (minFilt >> 2) & 1; key.mipFilt = (minFilt >> 1) & 1; @@ -253,6 +223,37 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) } } + // Filtering overrides + switch (g_Config.iTexFiltering) { + case TEX_FILTER_AUTO: + // Follow what the game wants. We just do a single heuristic change to avoid bleeding of wacky color test colors + // in higher resolution (used by some games for sprites, and they accidentally have linear filter on). + if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) { + bool uglyColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0; + if (uglyColorTest) { + // Force to nearest. + key.magFilt = 0; + key.minFilt = 0; + } + } + break; + case TEX_FILTER_FORCE_LINEAR: + // Override to linear filtering if there's no alpha or color testing going on. + if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) && + (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) { + key.magFilt = 1; + key.minFilt = 1; + key.mipFilt = 1; + } + break; + case TEX_FILTER_FORCE_NEAREST: + default: + // Just force to nearest without checks. Safe (but ugly). + key.magFilt = 0; + key.minFilt = 0; + break; + } + return key; } From f3ce685b0e2bdb48403d5b0207aefbc3ca910cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 14 Sep 2020 00:00:52 +0200 Subject: [PATCH 711/848] Also move video filtering override. --- GPU/Common/TextureCacheCommon.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index a37d5fecb9..2ae3adc900 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -176,13 +176,6 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) lodBias = 0.0f; } - if (!(magFilt & 1) && texAddr != 0 && g_Config.iTexFiltering != TEX_FILTER_FORCE_NEAREST) { - if (videos_.find(texAddr & 0x3FFFFFFF) != videos_.end()) { - // Enforce bilinear filtering on magnification. - magFilt |= 1; - } - } - key.minFilt = minFilt & 1; key.mipEnable = (minFilt >> 2) & 1; key.mipFilt = (minFilt >> 1) & 1; @@ -223,6 +216,14 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) } } + // Video bilinear override + if (!key.magFilt && texAddr != 0) { + if (videos_.find(texAddr & 0x3FFFFFFF) != videos_.end()) { + // Enforce bilinear filtering on magnification. + key.magFilt = 1; + } + } + // Filtering overrides switch (g_Config.iTexFiltering) { case TEX_FILTER_AUTO: From dce7dde5e6927229ebc1ef7f3fd58f76771062a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 14 Sep 2020 00:03:29 +0200 Subject: [PATCH 712/848] More moves --- GPU/Common/TextureCacheCommon.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 2ae3adc900..0df8d251e6 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -150,12 +150,15 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) SamplerCacheKey key; int minFilt = gstate.texfilter & 0x7; - int magFilt = gstate.isMagnifyFilteringEnabled(); - bool sClamp = gstate.isTexCoordClampedS(); - bool tClamp = gstate.isTexCoordClampedT(); + key.minFilt = minFilt & 1; + key.mipEnable = (minFilt >> 2) & 1; + key.mipFilt = (minFilt >> 1) & 1; + key.magFilt = gstate.isMagnifyFilteringEnabled(); + key.sClamp = gstate.isTexCoordClampedS(); + key.tClamp = gstate.isTexCoordClampedT(); + key.aniso = false; GETexLevelMode mipMode = gstate.getTexLevelMode(); - bool autoMip = mipMode == GE_TEXLEVEL_MODE_AUTO; // TODO: Slope mipmap bias is still not well understood. @@ -172,18 +175,11 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) if (noMip) { // Enforce no mip filtering, for safety. - minFilt &= 1; // no mipmaps yet + key.mipEnable = false; + key.mipFilt = 0; lodBias = 0.0f; } - key.minFilt = minFilt & 1; - key.mipEnable = (minFilt >> 2) & 1; - key.mipFilt = (minFilt >> 1) & 1; - key.magFilt = magFilt & 1; - key.sClamp = sClamp; - key.tClamp = tClamp; - key.aniso = false; - if (!key.mipEnable) { key.maxLevel = 0; key.minLevel = 0; From e690dc62dce86ad8f480f6a96f5d38ea4baacb35 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 15 Sep 2020 01:53:18 +0700 Subject: [PATCH 713/848] Fix an issue of major performance drops when using accepted PTP Sockets. --- Core/HLE/proAdhoc.cpp | 6 +++--- Core/HLE/proAdhoc.h | 11 +++++----- Core/HLE/sceNetAdhoc.cpp | 46 ++++++++++++++++++++++++++++------------ 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 405e400d1c..a7c7db0d2b 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -244,7 +244,7 @@ int IsSocketReady(int fd, bool readfd, bool writefd, int* errorcode, int timeout tval.tv_sec = timeoutUS / 1000000; tval.tv_usec = timeoutUS % 1000000; - int ret = select(fd + 1, &readfds, &writefds, nullptr, &tval); + int ret = select(fd + 1, readfd? &readfds: nullptr, writefd? &writefds: nullptr, nullptr, &tval); if (errorcode != nullptr) *errorcode = errno; @@ -1990,13 +1990,13 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ if (iResult == SOCKET_ERROR && errorcode != EISCONN) { u64 startTime = (u64)(real_time_now() * 1000.0); - while (IsSocketReady(metasocket, true, true) <= 0) { + while (IsSocketReady(metasocket, false, true) <= 0) { u64 now = (u64)(real_time_now() * 1000.0); if (coreState == CORE_POWERDOWN) return iResult; if (now - startTime > adhocDefaultTimeout) break; sleep_ms(10); } - if (IsSocketReady(metasocket, true, true) <= 0) { + if (IsSocketReady(metasocket, false, true) <= 0) { ERROR_LOG(SCENET, "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errorcode, g_Config.proAdhocServer.c_str(), inet_ntoa(g_adhocServerIP.in.sin_addr), ntohs(g_adhocServerIP.in.sin_port)); host->NotifyUserMessage(n->T("Failed to connect to Adhoc Server"), 1.0f, 0x0000ff); return iResult; diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index c571bcdfea..35d455e609 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -96,7 +96,7 @@ inline bool connectInProgress(int errcode){ return (errcode == EAGAIN || errcode #endif #ifndef SD_BOTH -#define SD_BOTH 0x02 +#define SD_BOTH SHUT_RDWR //0x02 #endif #define IsMatch(buf1, buf2) (memcmp(&buf1, &buf2, sizeof(buf1)) == 0) @@ -326,11 +326,12 @@ typedef struct SceNetAdhocPtpStat { // PDP & PTP Socket Union (Internal use only) typedef struct AdhocSocket { - s32_le type; + s32_le type; // SOCK_PDP/SOCK_PTP s32_le flags; // Socket Alert Flags - u32 send_timeout; - u32 recv_timeout; - s32 connectCount; + u32 send_timeout; // default connect timeout + u32 recv_timeout; // default accept timeout + s32 retry_count; // combined with timeout to be used on keepalive + s32 attemptCount; // connect/accept attempts union { SceNetAdhocPdpStat pdp; SceNetAdhocPtpStat ptp; diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index f9a1d8ed8f..84975f95c8 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -440,10 +440,15 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { sockaddr_in sin; memset(&sin, 0, sizeof(sin)); socklen_t sinlen = sizeof(sin); + int ret, sockerr; - // Accept Connection - int ret = accept(uid, (sockaddr*)&sin, &sinlen); - int sockerr = errno; + // Check if listening socket is ready to accept + ret = IsSocketReady(uid, true, false, &sockerr); + if (ret > 0) { + // Accept Connection + ret = accept(uid, (sockaddr*)&sin, &sinlen); + sockerr = errno; + } // Accepted New Connection if (ret > 0) { @@ -451,7 +456,7 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { if (newid > 0) result = newid; } - else if (ret == SOCKET_ERROR && connectInProgress(sockerr)) { + else if (ret == 0 || (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT))) { u64 now = (u64)(real_time_now() * 1000000.0); if (sock->flags & ADHOC_F_ALERTACCEPT) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; @@ -479,7 +484,7 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { int sockerr; // Wait for Connection (assuming "connect" has been called before) - int ret = IsSocketReady(uid, true, true, &sockerr); + int ret = IsSocketReady(uid, false, true, &sockerr); // Connection is ready if (ret > 0) { @@ -2669,6 +2674,7 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Socket Type internal->type = SOCK_PTP; internal->send_timeout = rexmt_int; + internal->retry_count = rexmt_cnt; // Copy Infrastructure Socket ID internal->data.ptp.id = tcpsocket; @@ -2737,6 +2743,9 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther // Enable Port Re-use setSockReuseAddrPort(newsocket); + // Enable KeepAlive + setSockKeepAlive(newsocket, true, socket->recv_timeout / 1000000L, socket->retry_count); + // Disable Nagle Algo to send immediately. Or may be we shouldn't disable Nagle since there is PtpFlush function? if (g_Config.bTCPNoDelay) setSockNoDelay(newsocket, 1); @@ -2801,6 +2810,9 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther //sceNetPortOpen("TCP", internal->lport); //g_PortManager.Add(IP_PROTOCOL_TCP, internal->lport + portOffset); + // Switch to non-blocking for futher usage + changeBlockingMode(newsocket, 1); + INFO_LOG(SCENET, "sceNetAdhocPtpAccept[%i->%i:%u]: Established (%s:%u)", ptpId, i + 1, internal->data.ptp.lport, inet_ntoa(peeraddr.sin_addr), internal->data.ptp.pport); // Return Socket @@ -2864,16 +2876,22 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int sockaddr_in peeraddr; memset(&peeraddr, 0, sizeof(peeraddr)); socklen_t peeraddrlen = sizeof(peeraddr); + int error; - // Accept Connection - int newsocket = accept(ptpsocket.id, (sockaddr*)&peeraddr, &peeraddrlen); - int error = errno; + // Check if listening socket is ready to accept + int newsocket = IsSocketReady(ptpsocket.id, true, false, &error); + if (newsocket > 0) { + // Accept Connection + newsocket = accept(ptpsocket.id, (sockaddr*)&peeraddr, &peeraddrlen); + error = errno; + } - if (newsocket == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK)) { + if (newsocket == 0 || (newsocket == SOCKET_ERROR && (error == EAGAIN || error == EWOULDBLOCK || error == ETIMEDOUT))) { + socket->attemptCount++; if (flag == 0) { // Simulate blocking behaviour with non-blocking socket u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | ptpsocket.id; - return WaitBlockingAdhocSocket(threadSocketId, PTP_ACCEPT, id, nullptr, nullptr, timeout, addr, port, "ptp accept"); + return WaitBlockingAdhocSocket(threadSocketId, PTP_ACCEPT, id, nullptr, nullptr, (flag) ? socket->recv_timeout : timeout, addr, port, "ptp accept"); } // Prevent spamming Debug Log with retries of non-bocking socket else { @@ -2883,6 +2901,7 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int // Accepted New Connection if (newsocket > 0) { + socket->attemptCount++; int newid = AcceptPtpSocket(id, newsocket, peeraddr, addr, port); if (newid >= 0) return newid; @@ -2971,7 +2990,7 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Instant Connection (Lucky!) if (connectresult != SOCKET_ERROR || errorcode == EISCONN) { - socket->connectCount++; + socket->attemptCount++; // Set Connected State ptpsocket.state = ADHOC_PTP_STATE_ESTABLISHED; @@ -2982,9 +3001,9 @@ static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { // Connection in Progress else if (connectresult == SOCKET_ERROR && connectInProgress(errorcode)) { - socket->connectCount++; + socket->attemptCount++; // Nonblocking Mode. First attempt need to be blocking for GvG Next Plus to work, even though it used non-blocking flag but only try to connect once per socket, which mean treating it just like blocking socket instead of non-blocking :( - if (flag && socket->connectCount > 1) { + if (flag && socket->attemptCount > 1) { //if (errorcode == EALREADY) return ERROR_NET_ADHOC_BUSY; return ERROR_NET_ADHOC_WOULD_BLOCK; } @@ -3166,6 +3185,7 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Socket Type internal->type = SOCK_PTP; internal->recv_timeout = rexmt_int; + internal->retry_count = rexmt_cnt; // Copy Infrastructure Socket ID internal->data.ptp.id = tcpsocket; From fe86f257b5d3d5633bf6af247e20ab25a5dbe313 Mon Sep 17 00:00:00 2001 From: iota97 Date: Tue, 15 Sep 2020 07:45:57 +0200 Subject: [PATCH 714/848] Cache 60 FPS requirement --- Core/Config.cpp | 1 + Core/Config.h | 1 + Core/HLE/sceDisplay.cpp | 2 +- UI/GameSettingsScreen.cpp | 3 ++- Windows/MainWindowMenu.cpp | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index ace8561175..c5e36508f9 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -806,6 +806,7 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("SplineBezierQuality", &g_Config.iSplineBezierQuality, 2, true, true), ReportedConfigSetting("HardwareTessellation", &g_Config.bHardwareTessellation, false, true, true), ConfigSetting("TextureShader", &g_Config.sTextureShaderName, "Off", true, true), + ConfigSetting("ShaderChainRequires60FPS", &g_Config.bShaderChainRequires60FPS, false, true, true), ReportedConfigSetting("MemBlockTransferGPU", &g_Config.bBlockTransferGPU, true, true, true), ReportedConfigSetting("DisableSlowFramebufEffects", &g_Config.bDisableSlowFramebufEffects, false, true, true), diff --git a/Core/Config.h b/Core/Config.h index b999569eda..f34d87c6f3 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -215,6 +215,7 @@ public: std::vector vPostShaderNames; // Off for chain end (only Off for no shader) std::map mPostShaderSetting; + bool bShaderChainRequires60FPS; std::string sTextureShaderName; bool bGfxDebugOutput; bool bGfxDebugSplitSubmit; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 7d0b9e7b60..a421736d93 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -763,7 +763,7 @@ void __DisplayFlip(int cyclesLate) { // postEffectRequiresFlip is not compatible with frameskip unthrottling, see #12325. if (g_Config.iRenderingMode != FB_NON_BUFFERED_MODE && !(unthrottleNeedsSkip && !FrameTimingThrottled())) { - postEffectRequiresFlip = duplicateFrames || PostShaderChainRequires60FPS(GetFullPostShadersChain(g_Config.vPostShaderNames)); + postEffectRequiresFlip = duplicateFrames || g_Config.bShaderChainRequires60FPS; } const bool fbDirty = gpu->FramebufferDirty(); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4fa553bc8b..ec82b7a296 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -311,7 +311,7 @@ void GameSettingsScreen::CreateViews() { std::vector alreadyAddedShader; for (int i = 0; i < g_Config.vPostShaderNames.size() && i < ARRAY_SIZE(shaderNames_); ++i) { - // Vector pointer get invalidated on resize, cache name to have always a valid reference for drawing + // Vector element pointer get invalidated on resize, cache name to have always a valid reference in the rendering thread shaderNames_[i] = g_Config.vPostShaderNames[i]; postProcChoice_ = graphicsSettings->Add(new ChoiceWithValueDisplay(&shaderNames_[i], StringFromFormat("%s #%d", gr->T("Postprocessing Shader"), i + 1), &PostShaderTranslateName)); postProcChoice_->OnClick.Add([=](EventParams &e) { @@ -1257,6 +1257,7 @@ void GameSettingsScreen::update() { } if (g_ShaderNameListChanged) { g_ShaderNameListChanged = false; + g_Config.bShaderChainRequires60FPS = PostShaderChainRequires60FPS(GetFullPostShadersChain(g_Config.vPostShaderNames)); RecreateViews(); } } diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 8e5b83aeec..2f2ba2da5b 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -1070,6 +1070,7 @@ namespace MainWindow { g_Config.vPostShaderNames.push_back(availableShaders[index]); g_Config.vPostShaderNames.push_back("Off"); g_ShaderNameListChanged = true; + g_Config.bShaderChainRequires60FPS = PostShaderChainRequires60FPS(GetFullPostShadersChain(g_Config.vPostShaderNames)); NativeMessageReceived("gpu_resized", ""); break; } From 290efbc349a32f804a2384bb41aed01d9db1a16f Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Tue, 15 Sep 2020 21:48:55 +0800 Subject: [PATCH 715/848] Check whether there may be more than one save file names by mode. --- Core/Dialog/PSPSaveDialog.cpp | 3 +++ Core/Dialog/SavedataParam.cpp | 23 ++++++++++++++++++++++- Core/Dialog/SavedataParam.h | 2 ++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 1e58737c2a..23e1303780 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -129,6 +129,9 @@ int PSPSaveDialog::Init(int paramAddr) break; } + if(!param.wouldHasMultiSaveName(param.GetPspParam())) + currentSelectedSave = 0; + switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode) { case SCE_UTILITY_SAVEDATA_TYPE_LOAD: diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index e038e87342..46940fb9db 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -1398,7 +1398,7 @@ int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) saveDataListCount++; } - if (saveDataListCount > 0) + if (saveDataListCount > 0 && wouldHasMultiSaveName(param)) { hasMultipleFileName = true; saveDataList = new SaveFileInfo[saveDataListCount]; @@ -1724,6 +1724,27 @@ int SavedataParam::GetSaveNameIndex(SceUtilitySavedataParam* param) return 0; } +bool SavedataParam::wouldHasMultiSaveName(SceUtilitySavedataParam* param) { + switch ((SceUtilitySavedataType)(u32)param->mode) { + case SCE_UTILITY_SAVEDATA_TYPE_LOAD: + case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: + case SCE_UTILITY_SAVEDATA_TYPE_SAVE: + case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: + case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE: + case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA: + case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE: + case SCE_UTILITY_SAVEDATA_TYPE_READDATA: + case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE: + case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA: + case SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE: + case SCE_UTILITY_SAVEDATA_TYPE_ERASE: + case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA: + return false; + default: + return true; + } +} + void SavedataParam::DoState(PointerWrap &p) { auto s = p.Section("SavedataParam", 1); diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h index 857c69779b..ba5c442222 100644 --- a/Core/Dialog/SavedataParam.h +++ b/Core/Dialog/SavedataParam.h @@ -353,6 +353,8 @@ public: int GetLastEmptySave(); int GetSaveNameIndex(SceUtilitySavedataParam* param); + bool wouldHasMultiSaveName(SceUtilitySavedataParam* param); + void DoState(PointerWrap &p); private: From 7630fae4b9c96d8ac5a8cda958d527e1c8fbdbbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 15 Sep 2020 09:34:40 +0200 Subject: [PATCH 716/848] Fix bug in new framebuffer code, reducing unnecessary texture invalidations. Improves the performance issue in #13431 --- GPU/Common/FramebufferManagerCommon.cpp | 22 +++++++++++----------- GPU/Common/TextureCacheCommon.cpp | 19 +++++++++++++++---- GPU/Common/TextureCacheCommon.h | 2 +- GPU/GPU.h | 2 ++ GPU/Vulkan/GPU_Vulkan.cpp | 3 ++- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index bd36e95532..08972e868a 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -441,8 +441,8 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { // Notify the texture cache of both the color and depth buffers. - textureCache_->NotifyFramebuffer(v->fb_address, v, NOTIFY_FB_DESTROYED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(v->z_address, v, NOTIFY_FB_DESTROYED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(v, NOTIFY_FB_DESTROYED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(v, NOTIFY_FB_DESTROYED, NOTIFY_FB_DEPTH); if (v->fbo) { v->fbo->Release(); v->fbo = nullptr; @@ -469,8 +469,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer DownloadFramebufferOnSwitch(currentRenderVfb_); } - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb->z_address, vfb, NOTIFY_FB_CREATED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_CREATED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_CREATED, NOTIFY_FB_DEPTH); // Ugly... if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { @@ -484,8 +484,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged) { if (vfbFormatChanged) { - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb->z_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); if (vfb->drawnFormat != vfb->format) { ReformatFramebufferFrom(vfb, vfb->drawnFormat); } @@ -553,8 +553,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe } else { if (vfb->fbo) { // This should only happen very briefly when toggling useBufferedRendering_. - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_DESTROYED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb->z_address, vfb, NOTIFY_FB_DESTROYED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_DESTROYED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_DESTROYED, NOTIFY_FB_DEPTH); vfb->fbo->Release(); vfb->fbo = nullptr; } @@ -566,8 +566,8 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB; } } - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb->z_address, vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); // ugly... is all this needed? if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { @@ -1348,7 +1348,7 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd SetColorUpdated(vfb, 0); char name[64]; snprintf(name, sizeof(name), "%08x_color_RAM", vfb->fb_address); - textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_CREATED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_CREATED, NOTIFY_FB_COLOR); vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, name }); vfbs_.push_back(vfb); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 0df8d251e6..a0a9780300 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -386,6 +386,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { // Check for FBO changes. if (entry->status & TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP) { // Fall through to the end where we'll delete the entry if there's a framebuffer. + entry->status &= ~TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; match = false; } @@ -551,6 +552,9 @@ TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { gstate_c.curTextureHeight = h; nextTexture_ = entry; + if (nextFramebufferTexture_) { + nextFramebufferTexture_ = nullptr; // in case it was accidentally set somehow? + } nextNeedsRehash_ = false; // We still need to rebuild, to allocate a texture. But we'll bail early. nextNeedsRebuild_ = true; @@ -731,16 +735,19 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c entry->numFrames = 0; } -void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel) { +void TextureCacheCommon::NotifyFramebuffer(VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel) { // Mask to ignore the Z memory mirrors if the address is in VRAM. // These checks are mainly to reduce scanning all textures. const u32 mirrorMask = 0x00600000; + const u32 address = channel == NOTIFY_FB_COLOR ? framebuffer->fb_address : framebuffer->z_address; const u32 addr = Memory::IsVRAMAddress(address) ? (address & ~mirrorMask) : address; const u32 bpp = (framebuffer->format == GE_FORMAT_8888 && channel == NOTIFY_FB_COLOR) ? 4 : 2; + const u32 stride = channel == NOTIFY_FB_COLOR ? framebuffer->fb_stride : framebuffer->z_stride; + const u32 endAddr = addr + stride * framebuffer->height * bpp; const u64 cacheKey = (u64)addr << 32; // If it has a clut, those are the low 32 bits, so it'll be inside this range. // Also, if it's a subsample of the buffer, it'll also be within the FBO. - const u64 cacheKeyEnd = cacheKey + ((u64)(framebuffer->fb_stride * framebuffer->height * bpp) << 32); + const u64 cacheKeyEnd = (u64)endAddr << 32; // The first mirror starts at 0x04200000 and there are 3. We search all for framebuffers. const u64 mirrorCacheKey = (u64)0x04200000 << 32; @@ -761,6 +768,7 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { // Just mark them all dirty somehow. it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; + gpuStats.numTextureInvalidationsByFramebuffer++; } } else { // Depth. Just look in the mirrors. @@ -770,6 +778,7 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram if (mirrorlessKey >= cacheKey && mirrorlessKey <= cacheKeyEnd) { // Just mark them all dirty somehow. it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; + gpuStats.numTextureInvalidationsByFramebuffer++; } } } @@ -958,8 +967,8 @@ void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate) gstate_c.SetNeedShaderTexclamp(true); } - nextTexture_ = nullptr; nextFramebufferTexture_ = framebuffer; + nextTexture_ = nullptr; } else { if (framebuffer->fbo) { framebuffer->fbo->Release(); @@ -967,6 +976,8 @@ void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate) } Unbind(); gstate_c.SetNeedShaderTexclamp(false); + nextFramebufferTexture_ = nullptr; + nextTexture_ = nullptr; } nextNeedsRehash_ = false; @@ -1571,7 +1582,7 @@ void TextureCacheCommon::ReadIndexedTex(u8 *out, int outPitch, int level, const void TextureCacheCommon::ApplyTexture() { TexCacheEntry *entry = nextTexture_; - if (entry == nullptr) { + if (!entry) { // Maybe we bound a framebuffer? if (nextFramebufferTexture_) { bool depth = Memory::IsDepthTexVRAMAddress(gstate.getTextureAddress(0)); diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 17a1aa4de7..7ed78e911d 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -245,7 +245,7 @@ public: // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to, // so that it can invalidate TexCacheEntries pointed at those addresses. - void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel); + void NotifyFramebuffer(VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel); void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt); size_t NumLoadedTextures() const { diff --git a/GPU/GPU.h b/GPU/GPU.h index 2c47c53ac5..92785b8de4 100644 --- a/GPU/GPU.h +++ b/GPU/GPU.h @@ -63,6 +63,7 @@ struct GPUStatistics { numUncachedVertsDrawn = 0; numTrackedVertexArrays = 0; numTextureInvalidations = 0; + numTextureInvalidationsByFramebuffer = 0; numTextureSwitches = 0; numShaderSwitches = 0; numFlushes = 0; @@ -86,6 +87,7 @@ struct GPUStatistics { int numUncachedVertsDrawn; int numTrackedVertexArrays; int numTextureInvalidations; + int numTextureInvalidationsByFramebuffer; int numTextureSwitches; int numShaderSwitches; int numTexturesDecoded; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 66d9ebfe04..c24afc5f69 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -565,7 +565,7 @@ void GPU_Vulkan::GetStats(char *buffer, size_t bufsize) { "Vertices submitted: %i\n" "Cached, Uncached Vertices Drawn: %i, %i\n" "FBOs active: %i (evaluations: %d)\n" - "Textures active: %i, decoded: %i invalidated: %i\n" + "Textures active: %i, decoded: %i invalidated: %d (%d by fb)\n" "Readbacks: %d, uploads: %d\n" "Vertex, Fragment, Pipelines loaded: %i, %i, %i\n" "Pushbuffer space used: UBO %d, Vtx %d, Idx %d\n" @@ -587,6 +587,7 @@ void GPU_Vulkan::GetStats(char *buffer, size_t bufsize) { (int)textureCacheVulkan_->NumLoadedTextures(), gpuStats.numTexturesDecoded, gpuStats.numTextureInvalidations, + gpuStats.numTextureInvalidationsByFramebuffer, gpuStats.numReadbacks, gpuStats.numUploads, shaderManagerVulkan_->GetNumVertexShaders(), From bf55986a7afe703b6decd05f9d832491a225f785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 15 Sep 2020 22:40:46 +0200 Subject: [PATCH 717/848] Delete TexCacheEntries that get replaced by a framebuffer --- GPU/Common/TextureCacheCommon.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index a0a9780300..4233deb4c8 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -365,7 +365,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { u32 texhash = MiniHash((const u32 *)Memory::GetPointerUnchecked(texaddr)); - TexCache::iterator iter = cache_.find(cachekey); + TexCache::iterator entryIter = cache_.find(cachekey); TexCacheEntry *entry = nullptr; // Note: It's necessary to reset needshadertexclamp, for otherwise DIRTY_TEXCLAMP won't get set later. @@ -377,8 +377,8 @@ TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { } gstate_c.bgraTexture = isBgraBackend_; - if (iter != cache_.end()) { - entry = iter->second.get(); + if (entryIter != cache_.end()) { + entry = entryIter->second.get(); // Validate the texture still matches the cache entry. bool match = entry->Matches(dim, format, maxLevel); const char *reason = "different params"; @@ -488,6 +488,11 @@ TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { if (candidates.size() > 0) { int index = GetBestCandidateIndex(candidates); if (index != -1) { + // If we had a texture entry here, let's get rid of it. + if (entryIter != cache_.end()) { + DeleteTexture(entryIter); + } + nextTexture_ = nullptr; nextNeedsRebuild_ = false; SetTextureFramebuffer(candidates[index]); From 59098a9a568ae2202a70fb8d8372bb2bf5abd61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 15 Sep 2020 22:53:01 +0200 Subject: [PATCH 718/848] Sneak in a fix for a limited memory leak in Vulkan vertex cache --- GPU/Vulkan/DrawEngineVulkan.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 4a9b9a29fb..f88ba62877 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -287,6 +287,9 @@ void DrawEngineVulkan::BeginFrame() { 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, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + vai_.Iterate([&](uint32_t hash, VertexArrayInfoVulkan *vai) { + delete vai; + }); vai_.Clear(); } From 74bc9785d91f0cf5227331f4b060fa2cd649ab2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 15 Sep 2020 22:53:37 +0200 Subject: [PATCH 719/848] Don't over-invalidate textures when a framebuffer is created or modified. Should help #13431. --- GPU/Common/TextureCacheCommon.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 4233deb4c8..369c4c2ea7 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + #include "ppsspp_config.h" #include "profiler/profiler.h" #include "Common/ColorConv.h" @@ -743,21 +744,22 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c void TextureCacheCommon::NotifyFramebuffer(VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel) { // Mask to ignore the Z memory mirrors if the address is in VRAM. // These checks are mainly to reduce scanning all textures. + const u32 mirrorMask = 0x00600000; const u32 address = channel == NOTIFY_FB_COLOR ? framebuffer->fb_address : framebuffer->z_address; const u32 addr = Memory::IsVRAMAddress(address) ? (address & ~mirrorMask) : address; const u32 bpp = (framebuffer->format == GE_FORMAT_8888 && channel == NOTIFY_FB_COLOR) ? 4 : 2; const u32 stride = channel == NOTIFY_FB_COLOR ? framebuffer->fb_stride : framebuffer->z_stride; - const u32 endAddr = addr + stride * framebuffer->height * bpp; + + // NOTE: Some games like Burnout massively misdetects the height of some framebuffers, leading to a lot of unnecessary invalidations. + // Let's only actually get rid of textures that cover the very start of the framebuffer. + const u32 endAddr = addr + stride * std::min((int)framebuffer->height, 16) * bpp; + const u64 cacheKey = (u64)addr << 32; // If it has a clut, those are the low 32 bits, so it'll be inside this range. // Also, if it's a subsample of the buffer, it'll also be within the FBO. const u64 cacheKeyEnd = (u64)endAddr << 32; - // The first mirror starts at 0x04200000 and there are 3. We search all for framebuffers. - const u64 mirrorCacheKey = (u64)0x04200000 << 32; - const u64 mirrorCacheKeyEnd = (u64)0x04800000 << 32; - switch (msg) { case NOTIFY_FB_CREATED: case NOTIFY_FB_UPDATED: @@ -771,20 +773,19 @@ void TextureCacheCommon::NotifyFramebuffer(VirtualFramebuffer *framebuffer, Fram if (channel == FramebufferNotificationChannel::NOTIFY_FB_COLOR) { // Color - no need to look in the mirrors. for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { - // Just mark them all dirty somehow. it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; gpuStats.numTextureInvalidationsByFramebuffer++; } } else { - // Depth. Just look in the mirrors. - for (auto it = cache_.lower_bound(mirrorCacheKey), end = cache_.upper_bound(mirrorCacheKeyEnd); it != end; ++it) { - const u64 mirrorlessKey = it->first & ~0x0060000000000000ULL; - // Let's still make sure it's in the cache range. - if (mirrorlessKey >= cacheKey && mirrorlessKey <= cacheKeyEnd) { - // Just mark them all dirty somehow. - it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; - gpuStats.numTextureInvalidationsByFramebuffer++; - } + // Depth. Just look at the range, but in each mirror (0x04200000 and 0x04600000). + // Games don't use 0x04400000 as far as I know - it has no swizzle effect so kinda useless. + for (auto it = cache_.lower_bound(cacheKey | 0x200000), end = cache_.upper_bound(cacheKeyEnd | 0x200000); it != end; ++it) { + it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; + gpuStats.numTextureInvalidationsByFramebuffer++; + } + for (auto it = cache_.lower_bound(cacheKey | 0x600000), end = cache_.upper_bound(cacheKeyEnd | 0x600000); it != end; ++it) { + it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; + gpuStats.numTextureInvalidationsByFramebuffer++; } } break; From 7f1e35e761ebc23bf877d5431a0b6f24e8b88110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 15 Sep 2020 23:09:58 +0200 Subject: [PATCH 720/848] Add missing asserts after some VK resource creation functions --- GPU/Vulkan/DrawEngineVulkan.cpp | 1 + GPU/Vulkan/TextureCacheVulkan.cpp | 3 ++- GPU/Vulkan/VulkanUtil.cpp | 3 ++- ext/native/thin3d/VulkanQueueRunner.cpp | 5 +++-- ext/native/thin3d/VulkanRenderManager.cpp | 9 ++++++--- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index f88ba62877..b89ac08892 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -172,6 +172,7 @@ void DrawEngineVulkan::InitDeviceObjects() { samp.magFilter = VK_FILTER_NEAREST; samp.minFilter = VK_FILTER_NEAREST; res = vkCreateSampler(device, &samp, nullptr, &samplerSecondary_); + _dbg_assert_(VK_SUCCESS == res); res = vkCreateSampler(device, &samp, nullptr, &nullSampler_); _dbg_assert_(VK_SUCCESS == res); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index c015c498e1..c6d9971770 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -363,7 +363,8 @@ void TextureCacheVulkan::DeviceRestore(VulkanContext *vulkan, Draw::DrawContext samp.magFilter = VK_FILTER_NEAREST; samp.minFilter = VK_FILTER_NEAREST; samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &samplerNearest_); + VkResult res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &samplerNearest_); + _assert_(res == VK_SUCCESS); CompileScalingShader(); diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index 9a617645d1..9a65aa750c 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -549,7 +549,8 @@ VkPipeline VulkanComputeShaderManager::GetPipeline(VkShaderModule cs) { pci.layout = pipelineLayout_; pci.flags = 0; - vkCreateComputePipelines(vulkan_->GetDevice(), pipelineCache_, 1, &pci, nullptr, &pipeline); + VkResult res = vkCreateComputePipelines(vulkan_->GetDevice(), pipelineCache_, 1, &pci, nullptr, &pipeline); + _assert_(res == VK_SUCCESS); pipelines_.Insert(key, pipeline); return pipeline; diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 87f811eb6c..b97a9a0f4a 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -49,7 +49,8 @@ void VulkanQueueRunner::ResizeReadbackBuffer(VkDeviceSize requiredSize) { buf.size = readbackBufferSize_; buf.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; - vkCreateBuffer(device, &buf, nullptr, &readbackBuffer_); + VkResult res = vkCreateBuffer(device, &buf, nullptr, &readbackBuffer_); + _assert_(res == VK_SUCCESS); VkMemoryRequirements reqs{}; vkGetBufferMemoryRequirements(device, readbackBuffer_, &reqs); @@ -75,7 +76,7 @@ void VulkanQueueRunner::ResizeReadbackBuffer(VkDeviceSize requiredSize) { _assert_(successTypeReqs != 0); readbackBufferIsCoherent_ = (successTypeReqs & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0; - VkResult res = vkAllocateMemory(device, &allocInfo, nullptr, &readbackMemory_); + res = vkAllocateMemory(device, &allocInfo, nullptr, &readbackMemory_); if (res != VK_SUCCESS) { readbackMemory_ = VK_NULL_HANDLE; vkDestroyBuffer(device, readbackBuffer_, nullptr); diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 6f439134a3..825a437681 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -38,7 +38,9 @@ VKRFramebuffer::VKRFramebuffer(VulkanContext *vk, VkCommandBuffer initCmd, VkRen fbci.height = height; fbci.layers = 1; - vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf); + VkResult res = vkCreateFramebuffer(vulkan_->GetDevice(), &fbci, nullptr, &framebuf); + _assert_(res == VK_SUCCESS); + if (tag && vk->Extensions().EXT_debug_utils) { vk->SetDebugName(color.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_color_%s", tag).c_str()); vk->SetDebugName(depth.image, VK_OBJECT_TYPE_IMAGE, StringFromFormat("fb_depth_%s", tag).c_str()); @@ -86,7 +88,8 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int ici.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; } - vkCreateImage(vulkan->GetDevice(), &ici, nullptr, &img.image); + VkResult res = vkCreateImage(vulkan->GetDevice(), &ici, nullptr, &img.image); + _dbg_assert_(res == VK_SUCCESS); VkMemoryRequirements memreq; bool dedicatedAllocation = false; @@ -102,7 +105,7 @@ void CreateImage(VulkanContext *vulkan, VkCommandBuffer cmd, VKRImage &img, int vulkan->MemoryTypeFromProperties(memreq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &alloc.memoryTypeIndex); - VkResult res = vkAllocateMemory(vulkan->GetDevice(), &alloc, nullptr, &img.memory); + res = vkAllocateMemory(vulkan->GetDevice(), &alloc, nullptr, &img.memory); _dbg_assert_(res == VK_SUCCESS); res = vkBindImageMemory(vulkan->GetDevice(), img.image, img.memory, 0); From 1b3413945bf4462e8a61fe81766a6ba1535cd605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 15 Sep 2020 00:34:45 +0200 Subject: [PATCH 721/848] Some header include cleanup --- GPU/Common/DrawEngineCommon.h | 1 - GPU/Common/IndexGenerator.cpp | 3 +-- GPU/Common/IndexGenerator.h | 1 - GPU/D3D11/StateMappingD3D11.cpp | 2 ++ GPU/D3D11/TextureCacheD3D11.cpp | 1 - GPU/Directx9/DrawEngineDX9.cpp | 2 ++ GPU/Directx9/TextureCacheDX9.cpp | 1 - GPU/GLES/DepthBufferGLES.cpp | 1 + GPU/GLES/DrawEngineGLES.cpp | 2 ++ GPU/GLES/FramebufferManagerGLES.cpp | 1 - GPU/GPUState.h | 2 -- GPU/Software/TransformUnit.cpp | 2 ++ GPU/Vulkan/DepalettizeShaderVulkan.cpp | 3 +++ GPU/Vulkan/DepalettizeShaderVulkan.h | 5 +---- GPU/Vulkan/DrawEngineVulkan.cpp | 2 ++ GPU/Vulkan/DrawEngineVulkan.h | 4 ---- GPU/Vulkan/FramebufferManagerVulkan.cpp | 1 - UI/GameSettingsScreen.cpp | 2 ++ UWP/UWPHost.cpp | 2 ++ UWP/XAudioSoundStream.cpp | 4 +++- 20 files changed, 23 insertions(+), 19 deletions(-) diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index 0aa5f36b42..bf2f3968e4 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -18,7 +18,6 @@ #pragma once #include -#include #include "Common/CommonTypes.h" #include "Common/Hashmaps.h" diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index d339fb4790..1f2c7e4674 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -16,9 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "IndexGenerator.h" -#include "Common/Common.h" +#include "IndexGenerator.h" // Points don't need indexing... const u8 IndexGenerator::indexedPrimitiveType[7] = { diff --git a/GPU/Common/IndexGenerator.h b/GPU/Common/IndexGenerator.h index 6fb24930ee..dd983536f8 100644 --- a/GPU/Common/IndexGenerator.h +++ b/GPU/Common/IndexGenerator.h @@ -18,7 +18,6 @@ #pragma once -#include #include "Common/CommonTypes.h" #include "Common/Swap.h" #include "GPU/ge_constants.h" diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 5f8e0d4ae4..fc2fd6971e 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -18,6 +18,8 @@ #include #include +#include + #include "math/dataconv.h" #include "GPU/Math3D.h" diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 2d3ec0f29f..e8d288d192 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include #include #include diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 66f269ff58..9c59f01f20 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include + #include "Common/Log.h" #include "Common/MemoryUtil.h" #include "Common/TimeUtil.h" diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 65480a8520..f2557ab92d 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include #include #include diff --git a/GPU/GLES/DepthBufferGLES.cpp b/GPU/GLES/DepthBufferGLES.cpp index 145963cd7b..13ec48128c 100644 --- a/GPU/GLES/DepthBufferGLES.cpp +++ b/GPU/GLES/DepthBufferGLES.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + #include "gfx_es2/gpu_features.h" #include "Core/ConfigValues.h" #include "Core/Reporting.h" diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index cd8a7910a9..c97bf558de 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include + #include "Common/MemoryUtil.h" #include "Common/TimeUtil.h" #include "Core/MemMap.h" diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 3d28e9bc98..51bd76da3d 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include #include #include "profiler/profiler.h" diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 4aac1e9907..2eac6bcef1 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -17,8 +17,6 @@ #pragma once -#include - #include "Common/Common.h" #include "Common/Swap.h" #include "GPU/GPU.h" diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index a30f7f875f..6a5819bdfa 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -16,6 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include +#include + #include "math/math_util.h" #include "Common/MemoryUtil.h" #include "Core/Config.h" diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.cpp b/GPU/Vulkan/DepalettizeShaderVulkan.cpp index f0ab47eb1c..42fe013372 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.cpp +++ b/GPU/Vulkan/DepalettizeShaderVulkan.cpp @@ -16,7 +16,10 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ColorConv.h" +#include "Common/Vulkan/VulkanImage.h" +#include "Common/Vulkan/VulkanMemory.h" #include "Common/Vulkan/VulkanContext.h" +#include "GPU/ge_constants.h" #include "GPU/GPUState.h" #include "GPU/Common/DepalettizeShaderCommon.h" #include "GPU/Vulkan/DepalettizeShaderVulkan.h" diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.h b/GPU/Vulkan/DepalettizeShaderVulkan.h index ec01a17b96..86cd6e615f 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.h +++ b/GPU/Vulkan/DepalettizeShaderVulkan.h @@ -21,9 +21,6 @@ #include "Common/CommonTypes.h" #include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanImage.h" -#include "Common/Vulkan/VulkanMemory.h" -#include "GPU/ge_constants.h" #include "thin3d/thin3d.h" #include "GPU/Common/DepalettizeShaderCommon.h" @@ -45,6 +42,7 @@ public: class VulkanTexture; class Vulkan2D; +class VulkanPushBuffer; // Caches both shaders and palette textures. // Could even avoid bothering with palette texture and just use uniform data... @@ -74,7 +72,6 @@ private: VkShaderModule vshader_ = VK_NULL_HANDLE; Vulkan2D *vulkan2D_ = nullptr; - // GLuint vertexShader_; std::map cache_; std::map texCache_; }; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index b89ac08892..4ac47d392e 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include + #include "math/dataconv.h" #include "profiler/profiler.h" #include "thin3d/VulkanRenderManager.h" diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 0cb4a5bdcd..4b807315d0 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -31,11 +31,7 @@ // The format of the various uniform buffers may vary though - vertex shaders that don't skin // won't get any bone data, etc. -#include -#include - #include "Common/Hashmaps.h" -#include "Common/Vulkan/VulkanMemory.h" #include "GPU/Vulkan/VulkanUtil.h" diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 17ad7045d0..9d57f8b85e 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include #include #include "profiler/profiler.h" diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 99888d9e3a..d5763142d7 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -17,6 +17,8 @@ #include "ppsspp_config.h" +#include + #include "base/display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres #include "base/colorutil.h" diff --git a/UWP/UWPHost.cpp b/UWP/UWPHost.cpp index 5edd05cd3b..b78e8ac055 100644 --- a/UWP/UWPHost.cpp +++ b/UWP/UWPHost.cpp @@ -17,6 +17,8 @@ #include "ppsspp_config.h" +#include + #include "file/file_util.h" #include "base/NativeApp.h" #include "input/input_state.h" diff --git a/UWP/XAudioSoundStream.cpp b/UWP/XAudioSoundStream.cpp index ad82c1e93f..8932b298a0 100644 --- a/UWP/XAudioSoundStream.cpp +++ b/UWP/XAudioSoundStream.cpp @@ -1,4 +1,6 @@ #include "pch.h" + +#include #include #include "thread/threadutil.h" @@ -187,4 +189,4 @@ void XAudioBackend::PollLoop() WindowsAudioBackend *CreateAudioBackend( AudioBackendType type ) { return new XAudioBackend(); -} \ No newline at end of file +} From c1194dcb523396211368fa1d005abadae010d2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 16 Sep 2020 09:21:42 +0200 Subject: [PATCH 722/848] Help the compiler out a little bit in IndexGenerator::AddStrip. The generated code wasn't good - this helps break long register dependency chains. Speed boost is measurable but small on x86, but might be bigger on simpler CPUs. --- GPU/Common/IndexGenerator.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index d339fb4790..c80a866b48 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -88,12 +88,22 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { const int numTris = numVerts - 2; u16 *outInds = inds_; int ibase = index_; - for (int i = 0; i < numTris; i++) { + size_t numPairs = numTris / 2; + while (numPairs > 0) { + *outInds++ = ibase; + *outInds++ = ibase + wind; + *outInds++ = ibase + (wind ^ 3); + *outInds++ = ibase + 1; + *outInds++ = ibase + 1 + (wind ^ 3); + *outInds++ = ibase + 1 + wind; + ibase += 2; + numPairs--; + } + if (numTris & 1) { *outInds++ = ibase; *outInds++ = ibase + wind; wind ^= 3; // toggle between 1 and 2 *outInds++ = ibase + wind; - ibase++; } inds_ = outInds; index_ += numVerts; From bfc88badb8797dccfc9a98a3edb01e1cbba3b121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 16 Sep 2020 13:11:39 +0200 Subject: [PATCH 723/848] Buildfix --- GPU/Vulkan/StateMappingVulkan.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 596badb5c7..c97bd380be 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -15,6 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include + #include "Common/Vulkan/VulkanLoader.h" #include "thin3d/VulkanRenderManager.h" From 6b5de6c27bb025ea8b30093a88165b4e67edce44 Mon Sep 17 00:00:00 2001 From: iota97 Date: Thu, 17 Sep 2020 07:52:09 +0200 Subject: [PATCH 724/848] Use system date format on savestate as well --- Core/SaveState.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 442475876e..c0261d2746 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -43,6 +43,7 @@ #include "Core/HLE/sceDisplay.h" #include "Core/HLE/ReplaceTables.h" #include "Core/HLE/sceKernel.h" +#include "Core/HLE/sceUtility.h" #include "Core/MemMap.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" @@ -618,7 +619,19 @@ namespace SaveState if (File::GetModifTime(fn, time)) { char buf[256]; // TODO: Use local time format? Americans and some others might not like ISO standard :) - strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &time); + switch (g_Config.iDateFormat) { + case PSP_SYSTEMPARAM_DATE_FORMAT_YYYYMMDD: + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &time); + break; + case PSP_SYSTEMPARAM_DATE_FORMAT_MMDDYYYY: + strftime(buf, sizeof(buf), "%m-%d-%Y %H:%M:%S", &time); + break; + case PSP_SYSTEMPARAM_DATE_FORMAT_DDMMYYYY: + strftime(buf, sizeof(buf), "%d-%m-%Y %H:%M:%S", &time); + break; + default: // Should never happen + return ""; + } return std::string(buf); } } From 28b58ca05d188b81df2a247195fd35b54aef20a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 00:49:17 +0200 Subject: [PATCH 725/848] More asserts --- Common/Vulkan/VulkanContext.cpp | 1 + Common/Vulkan/VulkanContext.h | 31 ++++++++++++++++--------------- GPU/Vulkan/DrawEngineVulkan.cpp | 9 ++++++--- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 2cb47926f0..b659681a73 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -1,4 +1,5 @@ #define __STDC_LIMIT_MACROS + #include #include #include diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index 17509f6c72..fa12d26d79 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -5,6 +5,7 @@ #include #include +#include "Common/Log.h" #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanDebug.h" @@ -66,21 +67,21 @@ class VulkanDeleteList { public: // NOTE: These all take reference handles so they can zero the input value. - void QueueDeleteCommandPool(VkCommandPool &pool) { cmdPools_.push_back(pool); pool = VK_NULL_HANDLE; } - void QueueDeleteDescriptorPool(VkDescriptorPool &pool) { descPools_.push_back(pool); pool = VK_NULL_HANDLE; } - void QueueDeleteShaderModule(VkShaderModule &module) { modules_.push_back(module); module = VK_NULL_HANDLE; } - void QueueDeleteBuffer(VkBuffer &buffer) { buffers_.push_back(buffer); buffer = VK_NULL_HANDLE; } - void QueueDeleteBufferView(VkBufferView &bufferView) { bufferViews_.push_back(bufferView); bufferView = VK_NULL_HANDLE; } - void QueueDeleteImage(VkImage &image) { images_.push_back(image); image = VK_NULL_HANDLE; } - void QueueDeleteImageView(VkImageView &imageView) { imageViews_.push_back(imageView); imageView = VK_NULL_HANDLE; } - void QueueDeleteDeviceMemory(VkDeviceMemory &deviceMemory) { deviceMemory_.push_back(deviceMemory); deviceMemory = VK_NULL_HANDLE; } - void QueueDeleteSampler(VkSampler &sampler) { samplers_.push_back(sampler); sampler = VK_NULL_HANDLE; } - void QueueDeletePipeline(VkPipeline &pipeline) { pipelines_.push_back(pipeline); pipeline = VK_NULL_HANDLE; } - void QueueDeletePipelineCache(VkPipelineCache &pipelineCache) { pipelineCaches_.push_back(pipelineCache); pipelineCache = VK_NULL_HANDLE; } - void QueueDeleteRenderPass(VkRenderPass &renderPass) { renderPasses_.push_back(renderPass); renderPass = VK_NULL_HANDLE; } - void QueueDeleteFramebuffer(VkFramebuffer &framebuffer) { framebuffers_.push_back(framebuffer); framebuffer = VK_NULL_HANDLE; } - void QueueDeletePipelineLayout(VkPipelineLayout &pipelineLayout) { pipelineLayouts_.push_back(pipelineLayout); pipelineLayout = VK_NULL_HANDLE; } - void QueueDeleteDescriptorSetLayout(VkDescriptorSetLayout &descSetLayout) { descSetLayouts_.push_back(descSetLayout); descSetLayout = VK_NULL_HANDLE; } + void QueueDeleteCommandPool(VkCommandPool &pool) { _dbg_assert_(pool != VK_NULL_HANDLE); cmdPools_.push_back(pool); pool = VK_NULL_HANDLE; } + void QueueDeleteDescriptorPool(VkDescriptorPool &pool) { _dbg_assert_(pool != VK_NULL_HANDLE); descPools_.push_back(pool); pool = VK_NULL_HANDLE; } + void QueueDeleteShaderModule(VkShaderModule &module) { _dbg_assert_(module != VK_NULL_HANDLE); modules_.push_back(module); module = VK_NULL_HANDLE; } + void QueueDeleteBuffer(VkBuffer &buffer) { _dbg_assert_(buffer != VK_NULL_HANDLE); buffers_.push_back(buffer); buffer = VK_NULL_HANDLE; } + void QueueDeleteBufferView(VkBufferView &bufferView) { _dbg_assert_(bufferView != VK_NULL_HANDLE); bufferViews_.push_back(bufferView); bufferView = VK_NULL_HANDLE; } + void QueueDeleteImage(VkImage &image) { _dbg_assert_(image != VK_NULL_HANDLE); images_.push_back(image); image = VK_NULL_HANDLE; } + void QueueDeleteImageView(VkImageView &imageView) { _dbg_assert_(imageView != VK_NULL_HANDLE); imageViews_.push_back(imageView); imageView = VK_NULL_HANDLE; } + void QueueDeleteDeviceMemory(VkDeviceMemory &deviceMemory) { _dbg_assert_(deviceMemory != VK_NULL_HANDLE); deviceMemory_.push_back(deviceMemory); deviceMemory = VK_NULL_HANDLE; } + void QueueDeleteSampler(VkSampler &sampler) { _dbg_assert_(sampler != VK_NULL_HANDLE); samplers_.push_back(sampler); sampler = VK_NULL_HANDLE; } + void QueueDeletePipeline(VkPipeline &pipeline) { _dbg_assert_(pipeline != VK_NULL_HANDLE); pipelines_.push_back(pipeline); pipeline = VK_NULL_HANDLE; } + void QueueDeletePipelineCache(VkPipelineCache &pipelineCache) { _dbg_assert_(pipelineCache != VK_NULL_HANDLE); pipelineCaches_.push_back(pipelineCache); pipelineCache = VK_NULL_HANDLE; } + void QueueDeleteRenderPass(VkRenderPass &renderPass) { _dbg_assert_(renderPass != VK_NULL_HANDLE); renderPasses_.push_back(renderPass); renderPass = VK_NULL_HANDLE; } + void QueueDeleteFramebuffer(VkFramebuffer &framebuffer) { _dbg_assert_(framebuffer != VK_NULL_HANDLE); framebuffers_.push_back(framebuffer); framebuffer = VK_NULL_HANDLE; } + void QueueDeletePipelineLayout(VkPipelineLayout &pipelineLayout) { _dbg_assert_(pipelineLayout != VK_NULL_HANDLE); pipelineLayouts_.push_back(pipelineLayout); pipelineLayout = VK_NULL_HANDLE; } + void QueueDeleteDescriptorSetLayout(VkDescriptorSetLayout &descSetLayout) { _dbg_assert_(descSetLayout != VK_NULL_HANDLE); descSetLayouts_.push_back(descSetLayout); descSetLayout = VK_NULL_HANDLE; } void QueueCallback(void(*func)(void *userdata), void *userdata) { callbacks_.push_back(Callback(func, userdata)); } void Take(VulkanDeleteList &del); diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 4ac47d392e..f6c07886b3 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -388,6 +388,10 @@ VkResult DrawEngineVulkan::RecreateDescriptorPool(FrameData &frame, int newSize) } VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView, VkSampler sampler, VkBuffer base, VkBuffer light, VkBuffer bone, bool tess) { + _dbg_assert_(base != VK_NULL_HANDLE); + _dbg_assert_(light != VK_NULL_HANDLE); + _dbg_assert_(bone != VK_NULL_HANDLE); + DescriptorSetKey key; key.imageView_ = imageView; key.sampler_ = sampler; @@ -396,9 +400,6 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView key.base_ = base; key.light_ = light; key.bone_ = bone; - _dbg_assert_(base != VK_NULL_HANDLE); - _dbg_assert_(light != VK_NULL_HANDLE); - _dbg_assert_(bone != VK_NULL_HANDLE); FrameData &frame = frame_[vulkan_->GetCurFrame()]; // See if we already have this descriptor set cached. @@ -443,6 +444,8 @@ VkDescriptorSet DrawEngineVulkan::GetOrCreateDescriptorSet(VkImageView imageView int n = 0; VkDescriptorImageInfo tex[3]{}; if (imageView) { + _dbg_assert_(sampler != VK_NULL_HANDLE); + #ifdef VULKAN_USE_GENERAL_LAYOUT_FOR_COLOR tex[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL; #else From 608d082e49e041fb5a67b0aaf395e9875ab958d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 18:54:17 +0200 Subject: [PATCH 726/848] FPURegCache: The invariant checking is very slow in debug mode. Let's only turn it on when we need it. --- Core/MIPS/x86/RegCacheFPU.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/MIPS/x86/RegCacheFPU.cpp b/Core/MIPS/x86/RegCacheFPU.cpp index 26e1e0dd55..e217bfc9e7 100644 --- a/Core/MIPS/x86/RegCacheFPU.cpp +++ b/Core/MIPS/x86/RegCacheFPU.cpp @@ -901,8 +901,8 @@ OpArg FPURegCache::GetDefaultLocation(int reg) const { } void FPURegCache::Invariant() const { -#ifdef _DEBUG - _dbg_assert_msg_(SanityCheck() == 0, "Sanity check failed: %d", SanityCheck()); +#if 0 + _assert_msg_(SanityCheck() == 0, "Sanity check failed: %d", SanityCheck()); #endif } From 181ddd842a4d6aeac3a1a190066ee7b6336db6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 19:18:32 +0200 Subject: [PATCH 727/848] Unify some GPU_SUPPORT* bits --- GPU/Common/FramebufferManagerCommon.cpp | 8 ++++++++ GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/GLES/FramebufferManagerGLES.cpp | 5 ++--- GPU/GLES/GPU_GLES.cpp | 10 ++-------- GPU/GLES/StencilBufferGLES.cpp | 2 +- GPU/GPUState.h | 4 +--- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- 7 files changed, 16 insertions(+), 17 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 08972e868a..d26d635a86 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -347,6 +347,14 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame vfb->fb_stride = params.fb_stride; vfb->z_address = params.z_address; vfb->z_stride = params.z_stride; + + if (vfb->z_address == vfb->fb_address) { + // Probably indicates that the game doesn't care about Z for this VFB. + // Let's avoid matching it for Z copies. + // vfb->z_address = 0; + // vfb->z_stride = 0; + } + vfb->width = drawing_width; vfb->height = drawing_height; vfb->newWidth = drawing_width; diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 552d303555..cb053da7b0 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -150,7 +150,7 @@ void GPU_D3D11::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_FLOAT; features |= GPU_SUPPORTS_INSTANCE_RENDERING; features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; - features |= GPU_SUPPORTS_FBO; + features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; uint32_t fmt4444 = draw_->GetDataFormatSupport(Draw::DataFormat::A4R4G4B4_UNORM_PACK16); uint32_t fmt1555 = draw_->GetDataFormatSupport(Draw::DataFormat::A1R5G5B5_UNORM_PACK16); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 51bd76da3d..50c5fce743 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -272,7 +272,7 @@ void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, Virtu int w = std::min(src->renderWidth, dst->renderWidth); int h = std::min(src->renderHeight, dst->renderHeight); - if (gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT)) { + if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { // Let's only do this if not clearing depth. draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); dst->last_frame_depth_updated = gpuStats.numFlips; @@ -330,8 +330,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, return; } - bool useBlit = gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT); - bool useNV = useBlit && !gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT); + bool useBlit = gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT); float srcXFactor = useBlit ? (float)src->renderWidth / (float)src->bufferWidth : 1.0f; float srcYFactor = useBlit ? (float)src->renderHeight / (float)src->bufferHeight : 1.0f; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index e1de25d4e5..743682e369 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -182,14 +182,8 @@ void GPU_GLES::CheckGPUFeatures() { } } - if (gl_extensions.ARB_framebuffer_object || gl_extensions.EXT_framebuffer_object || gl_extensions.IsGLES) { - features |= GPU_SUPPORTS_FBO; - } - if (gl_extensions.ARB_framebuffer_object || gl_extensions.GLES3) { - features |= GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT; - } - if (gl_extensions.NV_framebuffer_blit) { - features |= GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT; + if (gl_extensions.ARB_framebuffer_object || gl_extensions.NV_framebuffer_blit || gl_extensions.GLES3) { + features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; } if (gl_extensions.ARB_vertex_array_object && gl_extensions.IsCoreContext) { features |= GPU_SUPPORTS_VAO; diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 8ca12e5c09..d9e7fadbf1 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -158,7 +158,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo shaderManagerGL_->DirtyLastShader(); - bool useBlit = gstate_c.Supports(GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT | GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT); + bool useBlit = gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT); // Our fragment shader (and discard) is slow. Since the source is 1x, we can stencil to 1x. // Then after we're done, we'll just blit it across and stretch it there. diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 2eac6bcef1..9ecf84bba2 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -489,9 +489,7 @@ enum { GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT = FLAG_BIT(22), GPU_ROUND_DEPTH_TO_16BIT = FLAG_BIT(23), // Can be disabled either per game or if we use a real 16-bit depth buffer GPU_SUPPORTS_TEXTURE_LOD_CONTROL = FLAG_BIT(24), - GPU_SUPPORTS_FBO = FLAG_BIT(25), - GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT = FLAG_BIT(26), - GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT = FLAG_BIT(27), + GPU_SUPPORTS_FRAMEBUFFER_BLIT = FLAG_BIT(26), GPU_SUPPORTS_OES_TEXTURE_NPOT = FLAG_BIT(28), GPU_NEEDS_Z_EQUAL_W_HACK = FLAG_BIT(29), GPU_PREFER_CPU_DOWNLOAD = FLAG_BIT(30), diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index c24afc5f69..f6e63a7a30 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -224,7 +224,7 @@ void GPU_Vulkan::CheckGPUFeatures() { // Mandatory features on Vulkan, which may be checked in "centralized" code features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; - features |= GPU_SUPPORTS_FBO; + features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; features |= GPU_SUPPORTS_BLEND_MINMAX; features |= GPU_SUPPORTS_ANY_COPY_IMAGE; features |= GPU_SUPPORTS_OES_TEXTURE_NPOT; From d0f7b1e30f58bf2611e8eaf657cb212a94b67528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:23:04 +0200 Subject: [PATCH 728/848] Make the implementations of CopyFramebufferDepth more similar. Also avoid matching framebuffers with bad z for copies. --- GPU/Common/FramebufferManagerCommon.cpp | 4 ++-- GPU/D3D11/FramebufferManagerD3D11.cpp | 7 ++++--- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/Directx9/FramebufferManagerDX9.cpp | 7 ++++++- GPU/GLES/FramebufferManagerGLES.cpp | 14 ++++++-------- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GPUState.h | 2 +- GPU/Vulkan/FramebufferManagerVulkan.cpp | 13 ++++--------- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- ext/native/thin3d/thin3d_d3d9.cpp | 4 +++- 10 files changed, 29 insertions(+), 28 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index d26d635a86..44162893bf 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -351,8 +351,8 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame if (vfb->z_address == vfb->fb_address) { // Probably indicates that the game doesn't care about Z for this VFB. // Let's avoid matching it for Z copies. - // vfb->z_address = 0; - // vfb->z_stride = 0; + vfb->z_address = 0; + vfb->z_stride = 0; } vfb->width = drawing_width; diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 74ded8bc75..93648cbcbb 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -318,10 +318,11 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; - bool matchingRenderSize = src->renderWidth == dst->renderWidth && src->renderHeight == dst->renderHeight; - if (matchingDepthBuffer && matchingSize && matchingRenderSize) { + if (matchingDepthBuffer && matchingSize) { + int w = std::min(src->renderWidth, dst->renderWidth); + int h = std::min(src->renderHeight, dst->renderHeight); // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); dst->last_frame_depth_updated = gpuStats.numFlips; } diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index cb053da7b0..fcd579f5ed 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -146,7 +146,7 @@ void GPU_D3D11::CheckGPUFeatures() { features |= GPU_SUPPORTS_DUALSOURCE_BLEND; if (draw_->GetDeviceCaps().depthClampSupported) features |= GPU_SUPPORTS_DEPTH_CLAMP; - features |= GPU_SUPPORTS_ANY_COPY_IMAGE; + features |= GPU_SUPPORTS_COPY_IMAGE; features |= GPU_SUPPORTS_TEXTURE_FLOAT; features |= GPU_SUPPORTS_INSTANCE_RENDERING; features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 012846f25c..3575ed82e9 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -309,7 +309,12 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; if (matchingDepthBuffer && matchingSize) { - // Should use StretchRect here? Note: should only copy depth and NOT copy stencil. See #9740. + // Should use StretchRect here? Note: should only copy depth and ideally NOT copy stencil. See #9740. + int w = std::min(src->renderWidth, dst->renderWidth); + int h = std::min(src->renderHeight, dst->renderHeight); + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); + dst->last_frame_depth_updated = gpuStats.numFlips; } } diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 50c5fce743..e030effb22 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -268,15 +268,13 @@ void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, Virtu bool matchingSize = src->width == dst->width && src->height == dst->height; // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. - if (matchingDepthBuffer && matchingSize) { + if (matchingDepthBuffer && matchingSize && gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { int w = std::min(src->renderWidth, dst->renderWidth); int h = std::min(src->renderHeight, dst->renderHeight); - - if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { - // Let's only do this if not clearing depth. - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } + // Let's only do this if not clearing depth. + draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + dst->last_frame_depth_updated = gpuStats.numFlips; } } @@ -360,7 +358,7 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, return; } - if (gstate_c.Supports(GPU_SUPPORTS_ANY_COPY_IMAGE)) { + if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) { // glBlitFramebuffer can clip, but glCopyImageSubData is more restricted. // In case the src goes outside, we just skip the optimization in that case. const bool sameSize = dstX2 - dstX1 == srcX2 - srcX1 && dstY2 - dstY1 == srcY2 - srcY1; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 743682e369..2ba4922a2c 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -214,7 +214,7 @@ void GPU_GLES::CheckGPUFeatures() { features |= GPU_SUPPORTS_BLEND_MINMAX; if (gl_extensions.OES_copy_image || gl_extensions.NV_copy_image || gl_extensions.EXT_copy_image || gl_extensions.ARB_copy_image) - features |= GPU_SUPPORTS_ANY_COPY_IMAGE; + features |= GPU_SUPPORTS_COPY_IMAGE; if (!gl_extensions.IsGLES) features |= GPU_SUPPORTS_LOGIC_OP; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 9ecf84bba2..f012e023bc 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -483,7 +483,7 @@ enum { // Free bit: 16 GPU_SUPPORTS_ACCURATE_DEPTH = FLAG_BIT(17), GPU_SUPPORTS_VAO = FLAG_BIT(18), - GPU_SUPPORTS_ANY_COPY_IMAGE = FLAG_BIT(19), + GPU_SUPPORTS_COPY_IMAGE = FLAG_BIT(19), GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH = FLAG_BIT(20), GPU_SCALE_DEPTH_FROM_24BIT_TO_16BIT = FLAG_BIT(21), GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT = FLAG_BIT(22), diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 9d57f8b85e..8a39fdc85e 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -273,17 +273,12 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, void FramebufferManagerVulkan::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; bool matchingSize = src->width == dst->width && src->height == dst->height; - bool matchingRenderSize = src->renderWidth == dst->renderWidth && src->renderHeight == dst->renderHeight; - if (matchingDepthBuffer && matchingRenderSize && matchingSize) { - // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, src->renderWidth, src->renderHeight, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } else if (matchingDepthBuffer && matchingSize) { - /* + if (matchingDepthBuffer && matchingSize) { int w = std::min(src->renderWidth, dst->renderWidth); int h = std::min(src->renderHeight, dst->renderHeight); - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST); - */ + // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + dst->last_frame_depth_updated = gpuStats.numFlips; } } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index f6e63a7a30..9c7f36afe7 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -226,7 +226,7 @@ void GPU_Vulkan::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; features |= GPU_SUPPORTS_BLEND_MINMAX; - features |= GPU_SUPPORTS_ANY_COPY_IMAGE; + features |= GPU_SUPPORTS_COPY_IMAGE; features |= GPU_SUPPORTS_OES_TEXTURE_NPOT; features |= GPU_SUPPORTS_INSTANCE_RENDERING; features |= GPU_SUPPORTS_VERTEX_TEXTURE_FETCH; diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 9843af9358..8a97cbd26e 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -526,7 +526,9 @@ public: void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) override; - void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) override {} + void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) override { + // Not implemented + } bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) override; // These functions should be self explanatory. From d6d72db0a9717b8eefa874a0fc9806bf83a00c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:31:40 +0200 Subject: [PATCH 729/848] Unify BlitFramebufferDepth. --- GPU/Common/FramebufferManagerCommon.cpp | 20 ++++++++++++++++++++ GPU/Common/FramebufferManagerCommon.h | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 13 ------------- GPU/D3D11/FramebufferManagerD3D11.h | 2 -- GPU/Directx9/FramebufferManagerDX9.cpp | 13 ------------- GPU/Directx9/FramebufferManagerDX9.h | 2 -- GPU/GLES/FramebufferManagerGLES.cpp | 15 --------------- GPU/GLES/FramebufferManagerGLES.h | 2 -- GPU/Vulkan/FramebufferManagerVulkan.cpp | 13 ------------- GPU/Vulkan/FramebufferManagerVulkan.h | 2 -- 10 files changed, 21 insertions(+), 63 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 44162893bf..5776bc4919 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -469,6 +469,26 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { delete v; } +void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { + bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; + bool matchingSize = src->width == dst->width && src->height == dst->height; + + // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. + if (matchingDepthBuffer && matchingSize) { + int w = std::min(src->renderWidth, dst->renderWidth); + int h = std::min(src->renderHeight, dst->renderHeight); + // Let's only do this if not clearing depth. + if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { + draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + } else if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) { + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + } + dst->last_frame_depth_updated = gpuStats.numFlips; + } +} + void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) { if (!useBufferedRendering_) { // Let's ignore rendering to targets that have not (yet) been displayed. diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index ff43f6d504..05a2a787b6 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -339,7 +339,7 @@ protected: void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth); virtual void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) = 0; - virtual void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) = 0; + void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst); void ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, int h, bool force = false, bool skipCopy = false); void ShowScreenResolution(); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 93648cbcbb..4440ebf4b3 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -315,19 +315,6 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { } } -void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - void FramebufferManagerD3D11::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { ID3D11ShaderResourceView *view = nullptr; diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index a1683c299c..e951e277a1 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -45,8 +45,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 3575ed82e9..be7f751eda 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -305,19 +305,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { } } - void FramebufferManagerDX9::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - // Should use StretchRect here? Note: should only copy depth and ideally NOT copy stencil. See #9740. - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } - } - LPDIRECT3DSURFACE9 FramebufferManagerDX9::GetOffscreenSurface(LPDIRECT3DSURFACE9 similarSurface, VirtualFramebuffer *vfb) { D3DSURFACE_DESC desc = {}; HRESULT hr = similarSurface->GetDesc(&desc); diff --git a/GPU/Directx9/FramebufferManagerDX9.h b/GPU/Directx9/FramebufferManagerDX9.h index b164a9b0e7..3a8578599a 100644 --- a/GPU/Directx9/FramebufferManagerDX9.h +++ b/GPU/Directx9/FramebufferManagerDX9.h @@ -50,8 +50,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index e030effb22..f2709663cf 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -263,21 +263,6 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE } } -void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - - // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. - if (matchingDepthBuffer && matchingSize && gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // Let's only do this if not clearing depth. - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); - RebindFramebuffer("BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - void FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { render_->BindTexture(stage, nullptr); diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 12a3eb85c5..9177b62767 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -49,8 +49,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - // For use when texturing from a framebuffer. May create a duplicate if target. void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 8a39fdc85e..293ff77be5 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -269,19 +269,6 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, } } -// Except for a missing rebind and silly scissor enables, identical copy of the same function in GPU_GLES - tricky parts are in thin3d. -void FramebufferManagerVulkan::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; diff --git a/GPU/Vulkan/FramebufferManagerVulkan.h b/GPU/Vulkan/FramebufferManagerVulkan.h index b66eeb6033..a09f6ef755 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.h +++ b/GPU/Vulkan/FramebufferManagerVulkan.h @@ -54,8 +54,6 @@ public: int GetLineWidth(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; VkImageView BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); From d71ec8d82c8a60c9dc6b6389718eda98b3823840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:33:19 +0200 Subject: [PATCH 730/848] The new asserts found something. --- ext/native/thin3d/VulkanQueueRunner.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index b97a9a0f4a..991374fb92 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -89,8 +89,12 @@ void VulkanQueueRunner::ResizeReadbackBuffer(VkDeviceSize requiredSize) { void VulkanQueueRunner::DestroyDeviceObjects() { INFO_LOG(G3D, "VulkanQueueRunner::DestroyDeviceObjects"); - vulkan_->Delete().QueueDeleteDeviceMemory(readbackMemory_); - vulkan_->Delete().QueueDeleteBuffer(readbackBuffer_); + if (readbackMemory_) { + vulkan_->Delete().QueueDeleteDeviceMemory(readbackMemory_); + } + if (readbackBuffer_) { + vulkan_->Delete().QueueDeleteBuffer(readbackBuffer_); + } readbackBufferSize_ = 0; renderPasses_.Iterate([&](const RPKey &rpkey, VkRenderPass rp) { From 277f0e4ec6fd08523f0911808c025c37bca14690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:47:22 +0200 Subject: [PATCH 731/848] Fix bug in GLES texture filter setup --- GPU/GLES/TextureCacheGLES.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 292fa20ba1..de6852d556 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -124,10 +124,10 @@ void TextureCacheGLES::ApplySamplingParams(const SamplerCacheKey &key) { } float aniso = 0.0f; - int magKey = ((int)key.mipEnable << 2) | ((int)key.mipFilt << 1) | ((int)key.magFilt); + int minKey = ((int)key.mipEnable << 2) | ((int)key.mipFilt << 1) | ((int)key.minFilt); render_->SetTextureSampler(0, key.sClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, key.tClamp ? GL_CLAMP_TO_EDGE : GL_REPEAT, - MagFiltGL[magKey], key.minFilt ? GL_LINEAR : GL_NEAREST, aniso); + key.magFilt ? GL_LINEAR : GL_NEAREST, MinFiltGL[minKey], aniso); } static void ConvertColors(void *dstBuf, const void *srcBuf, Draw::DataFormat dstFmt, int numPixels) { From 7c76f4e65ca3dd9a27dc8033cd651253c3eb8e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 17 Sep 2020 20:48:24 +0200 Subject: [PATCH 732/848] Minor improvement to gl_debug_log.h --- ext/native/gfx/gl_debug_log.cpp | 4 +++- ext/native/gfx/gl_debug_log.h | 4 ++-- ext/native/thin3d/GLQueueRunner.cpp | 4 ++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ext/native/gfx/gl_debug_log.cpp b/ext/native/gfx/gl_debug_log.cpp index 078b4ed843..fc66ccf1dd 100644 --- a/ext/native/gfx/gl_debug_log.cpp +++ b/ext/native/gfx/gl_debug_log.cpp @@ -34,9 +34,11 @@ std::string GLEnumToString(uint16_t value) { } } -void CheckGLError(const char *file, int line) { +bool CheckGLError(const char *file, int line) { GLenum err = glGetError(); if (err != GL_NO_ERROR) { ERROR_LOG(G3D, "GL error %s on %s:%d", GLEnumToString(err).c_str(), file, line); + return false; } + return true; } diff --git a/ext/native/gfx/gl_debug_log.h b/ext/native/gfx/gl_debug_log.h index ae22ab1700..d6d37c4271 100644 --- a/ext/native/gfx/gl_debug_log.h +++ b/ext/native/gfx/gl_debug_log.h @@ -10,8 +10,8 @@ #if defined(DEBUG_OPENGL) -void CheckGLError(const char *file, int line); -#define CHECK_GL_ERROR_IF_DEBUG() CheckGLError(__FILE__, __LINE__) +bool CheckGLError(const char *file, int line); +#define CHECK_GL_ERROR_IF_DEBUG() if (!CheckGLError(__FILE__, __LINE__)) __debugbreak(); #else diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index 9c380ee622..c5da0e4c21 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -1146,6 +1146,7 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last if (!tex) { break; } + CHECK_GL_ERROR_IF_DEBUG(); if (tex->canWrap) { if (tex->wrapS != c.textureSampler.wrapS) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, c.textureSampler.wrapS); @@ -1156,14 +1157,17 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last tex->wrapT = c.textureSampler.wrapT; } } + CHECK_GL_ERROR_IF_DEBUG(); if (tex->magFilter != c.textureSampler.magFilter) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, c.textureSampler.magFilter); tex->magFilter = c.textureSampler.magFilter; } + CHECK_GL_ERROR_IF_DEBUG(); if (tex->minFilter != c.textureSampler.minFilter) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, c.textureSampler.minFilter); tex->minFilter = c.textureSampler.minFilter; } + CHECK_GL_ERROR_IF_DEBUG(); if (tex->anisotropy != c.textureSampler.anisotropy) { if (c.textureSampler.anisotropy != 0.0f) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, c.textureSampler.anisotropy); From 02ed5058c084c692d82f3df34a2d780b31ff073b Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 17 Sep 2020 22:24:30 +0700 Subject: [PATCH 733/848] Fixed crash issue when creating/connecting to a null group name. --- Core/HLE/sceNetAdhoc.cpp | 56 +++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 84975f95c8..4efcb2a2a7 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2287,8 +2287,9 @@ int NetAdhocctl_Create(const char* groupName) { * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG, ADHOCCTL_BUSY */ int sceNetAdhocctlCreate(const char *groupName) { - char grpName[9] = { 0 }; - memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; + if (groupName) + memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated INFO_LOG(SCENET, "sceNetAdhocctlCreate(%s) at %08x", grpName, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; @@ -2299,8 +2300,9 @@ int sceNetAdhocctlCreate(const char *groupName) { } int sceNetAdhocctlConnect(const char* groupName) { - char grpName[9] = { 0 }; - memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; + if (groupName) + memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated INFO_LOG(SCENET, "sceNetAdhocctlConnect(%s) at %08x", grpName, currentMIPS->pc); if (!g_Config.bEnableWlan) { return -1; @@ -2323,8 +2325,8 @@ int sceNetAdhocctlJoin(u32 scanInfoAddr) { if (Memory::IsValidAddress(scanInfoAddr)) { SceNetAdhocctlScanInfoEmu* sinfo = (SceNetAdhocctlScanInfoEmu*)Memory::GetPointer(scanInfoAddr); - char grpName[9] = { 0 }; - memcpy(grpName, sinfo->group_name.data, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; + memcpy(grpName, sinfo->group_name.data, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated DEBUG_LOG(SCENET, "sceNetAdhocctlJoin - Group: %s", grpName); // We can ignore minor connection process differences here @@ -2341,27 +2343,34 @@ int sceNetAdhocctlJoin(u32 scanInfoAddr) { return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } -// Connect to the Adhoc control game mode (as a Host) -static int sceNetAdhocctlCreateEnterGameMode(const char *groupName, int unknown, int playerNum, u32 macsAddr, int timeout, int unknown2) { - char grpName[9] = { 0 }; - memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs - +int NetAdhocctl_CreateEnterGameMode(const char* group_name, int game_type, int num_members, u32 membersAddr, u32 timeout, int flag) { SceNetEtherAddr* addrs = NULL; // List of participating MAC addresses (started from host) - if (Memory::IsValidAddress(macsAddr)) { - addrs = PSPPointer::Create(macsAddr); + if (Memory::IsValidAddress(membersAddr)) { + addrs = PSPPointer::Create(membersAddr); } - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, unknown, playerNum, macsAddr, timeout, unknown2, currentMIPS->pc); - + // TODO: Implement this + return 0; } -// Connect to the Adhoc control game mode (as a Client) -static int sceNetAdhocctlJoinEnterGameMode(const char *groupName, const char *macAddr, int timeout, int unknown2) { - char grpName[9] = { 0 }; - memcpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs +// Connect to the Adhoc control game mode (as a Host) +static int sceNetAdhocctlCreateEnterGameMode(const char * group_name, int game_type, int num_members, u32 membersAddr, int timeout, int flag) { + char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; + if (group_name) + memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, game_type, num_members, membersAddr, timeout, flag, currentMIPS->pc); - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)macAddr).c_str(), timeout, unknown2, currentMIPS->pc); + return NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); +} + +// Connect to the Adhoc control game mode (as a Client) +static int sceNetAdhocctlJoinEnterGameMode(const char * group_name, const char *macAddr, int timeout, int flag) { + char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; + if (group_name) + memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated + + ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)macAddr).c_str(), timeout, flag, currentMIPS->pc); return 0; } @@ -2379,11 +2388,12 @@ static int sceNetAdhocctlJoinEnterGameMode(const char *groupName, const char *ma */ int sceNetAdhocctlCreateEnterGameModeMin(const char *group_name, int game_type, int min_members, int num_members, u32 membersAddr, u32 timeout, int flag) { - char grpName[9] = { 0 }; - memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs + char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; + if (group_name) + memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", grpName, game_type, min_members, num_members, membersAddr, timeout, flag, currentMIPS->pc); // We don't really need the Minimum User Check - return sceNetAdhocctlCreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); //0; + return NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); //0; } int NetAdhoc_Term() { From 7ed1ade56b1d2d82f6828d236d01f59ee736ae12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 19 Sep 2020 14:14:06 +0200 Subject: [PATCH 734/848] A couple of D3D11 fixes. --- GPU/D3D11/GPU_D3D11.cpp | 1 - GPU/D3D11/TextureCacheD3D11.cpp | 1 + assets/lang | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index fcd579f5ed..f4e8f20db8 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -150,7 +150,6 @@ void GPU_D3D11::CheckGPUFeatures() { features |= GPU_SUPPORTS_TEXTURE_FLOAT; features |= GPU_SUPPORTS_INSTANCE_RENDERING; features |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; - features |= GPU_SUPPORTS_FRAMEBUFFER_BLIT; uint32_t fmt4444 = draw_->GetDataFormatSupport(Draw::DataFormat::A4R4G4B4_UNORM_PACK16); uint32_t fmt1555 = draw_->GetDataFormatSupport(Draw::DataFormat::A1R5G5B5_UNORM_PACK16); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index e8d288d192..78e7327716 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -387,6 +387,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DWrap); shaderApply.Shade(); + context_->PSSetShaderResources(0, 1, &nullTexture); // Make D3D11 validation happy. Really of no consequence since we rebind anyway. framebufferManagerD3D11_->RebindFramebuffer("RebindFramebuffer - ApplyTextureFramebuffer"); draw_->BindFramebufferAsTexture(depalFBO, 0, Draw::FB_COLOR_BIT, 0); diff --git a/assets/lang b/assets/lang index d5a2a51942..1c64b8fbd3 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit d5a2a51942377820764604d9bb424fa9a879c4bd +Subproject commit 1c64b8fbd3cb6bd87935eb53f302f7de6f86e209 From a18e4ecd6bc3c470aea28f60f5f640672edfe64e Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sat, 19 Sep 2020 00:09:18 +0700 Subject: [PATCH 735/848] Minor changes to adhoc timestamps --- Core/HLE/sceNetAdhoc.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 4efcb2a2a7..c51d7d71c3 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2170,7 +2170,7 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { buf->mac_addr = *maddr; buf->flags = 0x0400; buf->padding = 0; - buf->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + buf->last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1; // Success retval = 0; @@ -2184,7 +2184,8 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { SceNetAdhocctlPeerInfo * peer = findFriend(maddr); if (peer != NULL) { // Fake Receive Time - if (peer->last_recv != 0) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + if (peer->last_recv != 0) + peer->last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1; //buf->next = 0; buf->nickname = peer->nickname; @@ -4420,7 +4421,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Faking lastping auto friendpeer = findFriend(&p2p->mac); if (p2p->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) - p2p->lastping = CoreTiming::GetGlobalTimeUsScaled(); + p2p->lastping = CoreTiming::GetGlobalTimeUsScaled() - 1; else p2p->lastping = 0; @@ -4440,7 +4441,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Faking lastping auto friendpeer = findFriend(&parentpeer->mac); if (parentpeer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) - parentpeer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + parentpeer->lastping = CoreTiming::GetGlobalTimeUsScaled() - 1; else parentpeer->lastping = 0; @@ -4462,7 +4463,7 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) // Faking lastping auto friendpeer = findFriend(&peer->mac); if (peer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) - peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + peer->lastping = CoreTiming::GetGlobalTimeUsScaled() - 1; else peer->lastping = 0; @@ -4765,7 +4766,8 @@ void __NetTriggerCallbacks() args[1] = error; // FIXME: When Joining a group, Do we need to wait for group creator's peer data before triggering the callback to make sure the game not to thinks we're the group creator? - if (flags != ADHOCCTL_EVENT_CONNECT || adhocConnectionType != ADHOC_JOIN || getActivePeerCount() > 0) + u64 now = (u64)(real_time_now() * 1000.0); + if (flags != ADHOCCTL_EVENT_CONNECT || adhocConnectionType != ADHOC_JOIN || getActivePeerCount() > 0 || now - adhocctlStartTime > adhocDefaultTimeout) { // Since 0 is a valid index to types_ we use -1 to detects if it was loaded from an old save state if (actionAfterAdhocMipsCall < 0) { @@ -4957,12 +4959,12 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { if (!excludeTimedout || peer->last_recv != 0) { // Faking Last Receive Time if (peer->last_recv != 0) - peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + peer->last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1; // Copy Peer Info buf[discovered].nickname = peer->nickname; buf[discovered].mac_addr = peer->mac_addr; - buf[discovered].flags = 0x0400; //peer->ip_addr; + buf[discovered].flags = 0x0400; buf[discovered].last_recv = peer->last_recv; discovered++; @@ -5050,8 +5052,8 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b buf[discovered].nickname = parameter.nickname; buf[discovered].nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char getLocalMac(&buf[discovered].mac_addr); - buf[discovered].flags = 0x0400; //addr.sin_addr.s_addr; - buf[discovered++].last_recv = CoreTiming::GetGlobalTimeUsScaled(); + buf[discovered].flags = 0x0400; + buf[discovered++].last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1; } // Peer Reference @@ -5065,13 +5067,13 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b { // Fake Receive Time if (peer->last_recv != 0) - peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); //sceKernelGetSystemTimeWide(); + peer->last_recv = CoreTiming::GetGlobalTimeUsScaled() - 1; // Copy Peer Info buf[discovered].nickname = peer->nickname; buf[discovered].nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char buf[discovered].mac_addr = peer->mac_addr; - buf[discovered].flags = 0x0400; //peer->ip_addr; + buf[discovered].flags = 0x0400; buf[discovered++].last_recv = peer->last_recv; } } From 3439511e0cfb9f75f867796bfb5598d71ad1bebf Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 20 Sep 2020 11:29:08 +0700 Subject: [PATCH 736/848] Implementing Adhoc GameMode HLE --- Core/HLE/proAdhoc.cpp | 125 +++++++++--- Core/HLE/proAdhoc.h | 50 ++++- Core/HLE/sceNetAdhoc.cpp | 429 ++++++++++++++++++++++++++++++++++----- 3 files changed, 530 insertions(+), 74 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a7c7db0d2b..1875ff8dd9 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -63,8 +63,16 @@ SceNetAdhocctlScanInfo * networks = NULL; SceNetAdhocctlScanInfo * newnetworks = NULL; u64 adhocctlStartTime = 0; int adhocctlState = ADHOCCTL_STATE_DISCONNECTED; +int adhocctlCurrentMode = ADHOCCTL_MODE_NONE; int adhocConnectionType = ADHOC_CONNECT; +int gameModeSocket = (int)INVALID_SOCKET; // UDP/PDP socket? on Master only? +u8* gameModeBuffer = nullptr; +GameModeArea masterGameModeArea; +std::vector replicaGameModeAreas; +std::vector requiredGameModeMacs; +std::vector gameModeMacs; + int actionAfterAdhocMipsCall; int actionAfterMatchingMipsCall; @@ -225,6 +233,19 @@ SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC) { return peer; } +SceNetAdhocctlPeerInfo* findFriendByIP(uint32_t ip) { + // Friends Reference + SceNetAdhocctlPeerInfo* peer = friends; + + // Iterate Friends + for (; peer != NULL; peer = peer->next) { + if (peer->ip_addr == ip) break; + } + + // Return found friend + return peer; +} + int IsSocketReady(int fd, bool readfd, bool writefd, int* errorcode, int timeoutUS) { fd_set readfds, writefds; timeval tval; @@ -359,6 +380,26 @@ void deleteAllAdhocSockets() { } } +void deleteAllGMB() { + if (gameModeBuffer) { + free(gameModeBuffer); + gameModeBuffer = nullptr; + } + if (masterGameModeArea.data) { + free(masterGameModeArea.data); + masterGameModeArea = { 0 }; + } + for (auto& it : replicaGameModeAreas) { + if (it.data) { + free(it.data); + it.data = nullptr; + } + } + replicaGameModeAreas.clear(); + gameModeMacs.clear(); + requiredGameModeMacs.clear(); +} + void deleteFriendByIP(uint32_t ip) { // Previous Peer Reference SceNetAdhocctlPeerInfo * prev = NULL; @@ -1365,19 +1406,30 @@ int friendFinder(){ parameter.bssid.mac_addr = packet->mac; // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address // From JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?) - /*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { - setState(ADHOCCTL_STATE_GAMEMODE); - notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0); + // Notify Event Handlers + if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { + SceNetEtherAddr localMac; + getLocalMac(&localMac); + if (std::find_if(gameModeMacs.begin(), gameModeMacs.end(), + [localMac](SceNetEtherAddr const& e) { + return IsMatch(e, localMac); + }) == gameModeMacs.end()) { + // Arrange the order to be consistent on all players (Host on top), Starting from our self the rest of new players will be added to the back + gameModeMacs.push_back(localMac); + } + else + WARN_LOG(SCENET, "GameMode SelfMember [%s] Already Existed!", mac2str(&localMac).c_str()); + + if (gameModeMacs.size() >= requiredGameModeMacs.size()) { + //adhocctlState = ADHOCCTL_STATE_GAMEMODE; + notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0); + } } else { - setState(ADHOCCTL_STATE_CONNECTED); + //adhocctlState = ADHOCCTL_STATE_CONNECTED; notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); - }*/ + } - // Notify Event Handlers - notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); - // Change State - //threadStatus = ADHOCCTL_STATE_CONNECTED; // Give time a little time //sceKernelDelayThread(adhocEventDelayMS * 1000); //sleep_ms(adhocEventDelayMS); @@ -1445,10 +1497,39 @@ int friendFinder(){ // Add User addFriend(packet); - /* // Make sure GameMode participants are all joined (including self MAC) - if (adhocctlCurrentMode == PSP_ADHOCCTL_MODE_GAMEMODE) { + // Make sure GameMode participants are all joined (including self MAC) + if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { + if (std::find_if(gameModeMacs.begin(), gameModeMacs.end(), + [packet](SceNetEtherAddr const& e) { + return IsMatch(e, packet->mac); + }) == gameModeMacs.end()) { + // Arrange the order to be consistent on all players (Host on top), Existing players are sent in reverse by AdhocServer + SceNetEtherAddr localMac; + getLocalMac(&localMac); + auto it = std::find_if(gameModeMacs.begin(), gameModeMacs.end(), + [localMac](SceNetEtherAddr const& e) { + return IsMatch(e, localMac); + }); + // Starting from our self the rest of new players will be added to the back + if (it != gameModeMacs.end()) { + gameModeMacs.push_back(packet->mac); + } + else { + it = gameModeMacs.begin() + 1; + gameModeMacs.insert(it, packet->mac); + } + } + else + WARN_LOG(SCENET, "GameMode Member [%s] Already Existed!", mac2str(&packet->mac).c_str()); + // From JPCSP: Join complete when all the required MACs have joined - }*/ + if (requiredGameModeMacs.size() > 0 && gameModeMacs.size() >= requiredGameModeMacs.size()) { + // TODO: Should we replace gameModeMacs contents with requiredGameModeMacs contents to make sure they are in the same order with macs from sceNetAdhocctlCreateEnterGameMode? But may not be consistent with the list on client side! + //gameModeMacs = requiredGameModeMacs; + //adhocctlState = ADHOCCTL_STATE_GAMEMODE; + notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0); + } + } // Update HUD User Count incoming = ""; @@ -1488,6 +1569,14 @@ int friendFinder(){ // Log Incoming Peer Delete Request INFO_LOG(SCENET, "FriendFinder: Incoming Peer Data Delete Request..."); + /*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { + auto peer = findFriendByIP(packet->ip); + gameModeMacs.erase(std::remove_if(gameModeMacs.begin(), gameModeMacs.end(), + [peer](auto const& e) { + return IsMatch(e, peer->mac_addr); + }), gameModeMacs.end()); + }*/ + // Delete User by IP, should delete by MAC since IP can be shared (behind NAT) isn't? deleteFriendByIP(packet->ip); @@ -1541,7 +1630,7 @@ int friendFinder(){ // Set group parameters // Since 0 is not a valid active channel we fake the channel for Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?) group->channel = parameter.channel; //(parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) ? defaultWlanChannel : parameter.channel; - group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode; + group->mode = adhocctlCurrentMode; // Link into Group List newnetworks = group; @@ -1575,16 +1664,6 @@ int friendFinder(){ // Notify Event Handlers notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0); - //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) - //{ - // // Active Handler - // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); - //} - // Change State - //threadStatus = ADHOCCTL_STATE_DISCONNECTED; - // Give time a little time - //sceKernelDelayThread(adhocEventDelayMS * 1000); - //sleep_ms(adhocEventDelayMS); // Move RX Buffer memmove(rx, rx + 1, sizeof(rx) - 1); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 35d455e609..91c898381b 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -104,10 +104,16 @@ inline bool connectInProgress(int errcode){ return (errcode == EAGAIN || errcode // Server Listening Port #define SERVER_PORT 27312 +// Default GameMode Port +#define ADHOC_GAMEMODE_PORT 31000 + +#define GAMEMODE_UPDATE_INTERVAL 12000 // usec, based on JPCSP +#define GAMEMODE_BUFFER_SIZE 0x8000 + // psp strutcs and definitions -#define ADHOCCTL_MODE_NONE -1 -#define ADHOCCTL_MODE_ADHOC 0 //ADHOCCTL_MODE_NORMAL -#define ADHOCCTL_MODE_GAMEMODE 1 +#define ADHOCCTL_MODE_NONE -1 +#define ADHOCCTL_MODE_NORMAL 0 // ADHOCCTL_MODE_ADHOC +#define ADHOCCTL_MODE_GAMEMODE 1 // Event Types for Event Handler #define ADHOCCTL_EVENT_ERROR 0 @@ -292,9 +298,27 @@ typedef struct SceNetAdhocMatchingMemberInfoEmu { #define ADHOCCTL_GAMEMODE_MAX_MEMBERS 16 typedef struct SceNetAdhocctlGameModeInfo { s32_le num; - SceNetEtherAddr member[ADHOCCTL_GAMEMODE_MAX_MEMBERS]; + SceNetEtherAddr members[ADHOCCTL_GAMEMODE_MAX_MEMBERS]; } PACK SceNetAdhocctlGameModeInfo; +// GameModeUpdateInfo +typedef struct GameModeUpdateInfo { + s32_le updated; + u64_le timeStamp; +} PACK GameModeUpdateInfo; + +// GameModeArea (Internal use only) +typedef struct GameModeArea { + int id; // started from 1 for replica? master = 0 or -1? + int size; + u32 addr; + //int socket; // PDP socket? + u64 updateTimestamp; + int dataUpdated; + SceNetEtherAddr mac; + u8* data; // upto "size" bytes started from "addr" ? +} PACK GameModeArea; + // Socket Polling Event Listener typedef struct SceNetAdhocPollSd{ s32_le id; @@ -867,7 +891,15 @@ extern SceNetAdhocctlPeerInfo * friends; extern SceNetAdhocctlScanInfo * networks; extern u64 adhocctlStartTime; extern int adhocctlState; +extern int adhocctlCurrentMode; extern int adhocConnectionType; + +extern int gameModeSocket; +extern u8* gameModeBuffer; +extern GameModeArea masterGameModeArea; +extern std::vector replicaGameModeAreas; +extern std::vector requiredGameModeMacs; +extern std::vector gameModeMacs; // End of Aux vars enum AdhocConnectionType : int @@ -944,6 +976,11 @@ extern int newChat; */ SceNetAdhocctlPeerInfo * findFriend(SceNetEtherAddr * MAC); +/* + * Find a Peer/Friend by IP address + */ +SceNetAdhocctlPeerInfo* findFriendByIP(uint32_t ip); + /** * Get the Readability(ie. recv) and/or Writability(ie. send) of a socket * @param fd File Descriptor of the socket @@ -980,6 +1017,11 @@ void freeGroupsRecursive(SceNetAdhocctlScanInfo * node); */ void deleteAllAdhocSockets(); +/* +* Deletes all GameMode Buffers +*/ +void deleteAllGMB(); + /** * Delete Friend from Local List * @param ip Friend IP diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index c51d7d71c3..9b816c14fe 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -63,7 +63,9 @@ bool netAdhocInited; bool netAdhocctlInited; bool networkInited = false; -static bool netAdhocMatchingInited; +bool netAdhocGameModeEntered; + +bool netAdhocMatchingInited; int netAdhocMatchingStarted = 0; int adhocDefaultTimeout = 2000; //5000 ms int adhocExtraPollDelayMS = 10; //10 @@ -86,6 +88,8 @@ std::map adhocctlRequests; std::map adhocSocketRequests; std::map sendTargetPeers; +int gameModeNotifyEvent = -1; + u32 dummyThreadHackAddr = 0; u32_le dummyThreadCode[3]; u32 matchingThreadHackAddr = 0; @@ -96,6 +100,9 @@ int matchingInputThread(int matchingId); int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port); int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout); int FlushPtpSocket(int socketId); +int NetAdhocctl_ExitGameMode(); +static int sceNetAdhocPdpSend(int id, const char* mac, u32 port, void* data, int len, int timeout, int flag); +static int sceNetAdhocPdpRecv(int id, void* addr, void* port, void* buf, void* dataLength, u32 timeout, int flag); void __NetAdhocShutdown() { @@ -126,6 +133,57 @@ void __NetAdhocShutdown() { } } +bool IsGameModeActive() { + return netAdhocGameModeEntered && gameModeBuffer != nullptr && gameModeSocket > 0 && adhocSockets[gameModeSocket - 1] != nullptr; +} + +static void __GameModeNotify(u64 userdata, int cyclesLate) { + SceUID threadID = userdata >> 32; + int uid = (int)(userdata & 0xFFFFFFFF); + + // TODO: May be we should check for timeout too? since EnterGammeMode have timeout arg + if (IsGameModeActive()) { + auto sock = adhocSockets[gameModeSocket - 1]; + + // Send Master data + if (masterGameModeArea.dataUpdated) { + for (auto& gma : replicaGameModeAreas) { + if (IsGameModeActive() && IsSocketReady(sock->data.pdp.id, false, true) > 0) { + int sent = sceNetAdhocPdpSend(gameModeSocket, (const char*)&gma.mac, ADHOC_GAMEMODE_PORT, masterGameModeArea.data, masterGameModeArea.size, 0, ADHOC_F_NONBLOCK); + if (sent >= 0) { + masterGameModeArea.dataUpdated = 0; + DEBUG_LOG(SCENET, "GameMode Sent %d bytes to %s", masterGameModeArea.size, mac2str(&gma.mac).c_str()); + } + } + } + } + + // Recv new Replica data + while (IsGameModeActive() && IsSocketReady(sock->data.pdp.id, true, false) > 0) { + SceNetEtherAddr sendermac; + s32_le senderport = ADHOC_GAMEMODE_PORT; + s32_le bufsz = GAMEMODE_BUFFER_SIZE; + int ret = sceNetAdhocPdpRecv(gameModeSocket, &sendermac, &senderport, gameModeBuffer, &bufsz, 0, ADHOC_F_NONBLOCK); + if (ret >= 0 && bufsz > 0) { + for (auto& gma : replicaGameModeAreas) { + if (IsMatch(gma.mac, sendermac)) { + DEBUG_LOG(SCENET, "GameMode Received %d bytes of new Data for Area [%s]", bufsz, mac2str(&sendermac).c_str()); + memcpy(gma.data, gameModeBuffer, std::min(gma.size, bufsz)); + gma.dataUpdated = 1; + gma.updateTimestamp = CoreTiming::GetGlobalTimeUsScaled(); + break; + } + } + } + } + + // ReSchedule + CoreTiming::ScheduleEvent(usToCycles(GAMEMODE_UPDATE_INTERVAL) - cyclesLate, gameModeNotifyEvent, userdata); + return; + } + INFO_LOG(SCENET, "GameMode Scheduler (%d) has finished", uid); +} + static void __AdhocctlNotify(u64 userdata, int cyclesLate) { SceUID threadID = userdata >> 32; int uid = (int)(userdata & 0xFFFFFFFF); @@ -224,6 +282,20 @@ int WaitAdhocctlState(AdhocctlRequest request, int state, int usec, const char* return 0; } +int StartGameModeScheduler() { + if (gameModeSocket < 0) + return -1; + + if (gameModeNotifyEvent < 0) + gameModeNotifyEvent = CoreTiming::RegisterEvent("__GameModeNotify", __GameModeNotify); + + INFO_LOG(SCENET, "GameMode Scheduler (%d) has started", gameModeSocket); + u64 param = ((u64)__KernelGetCurThread()) << 32 | gameModeSocket; + CoreTiming::ScheduleEvent(usToCycles(GAMEMODE_UPDATE_INTERVAL), gameModeNotifyEvent, param); + + return 0; +} + int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { sockaddr_in sin; memset(&sin, 0, sizeof(sin)); @@ -720,7 +792,7 @@ void netAdhocValidateLoopMemory() { } void __NetAdhocDoState(PointerWrap &p) { - auto s = p.Section("sceNetAdhoc", 1, 5); + auto s = p.Section("sceNetAdhoc", 1, 6); if (!s) return; @@ -785,6 +857,15 @@ void __NetAdhocDoState(PointerWrap &p) { adhocctlNotifyEvent = -1; adhocSocketNotifyEvent = -1; } + if (s >= 6) { + Do(p, gameModeNotifyEvent); + if (gameModeNotifyEvent != -1) { + CoreTiming::RestoreRegisterEvent(gameModeNotifyEvent, "__GameModeNotify", __GameModeNotify); + } + } + else { + gameModeNotifyEvent = -1; + } if (p.mode == p.MODE_READ) { // Discard leftover events @@ -827,6 +908,7 @@ u32_le __CreateHLELoop(u32_le *loopAddr, const char *sceFuncName, const char *hl void __AdhocNotifInit() { adhocctlNotifyEvent = CoreTiming::RegisterEvent("__AdhocctlNotify", __AdhocctlNotify); adhocSocketNotifyEvent = CoreTiming::RegisterEvent("__AdhocSocketNotify", __AdhocSocketNotify); + gameModeNotifyEvent = CoreTiming::RegisterEvent("__GameModeNotify", __GameModeNotify); adhocctlRequests.clear(); adhocSocketRequests.clear(); @@ -1995,6 +2077,7 @@ u32 NetAdhocctl_Disconnect() { // Multithreading Unlock //peerlock.unlock(); + adhocctlCurrentMode = ADHOCCTL_MODE_NONE; // Notify Event Handlers (even if we weren't connected, not doing this will freeze games like God Eater, which expect this behaviour) notifyAdhocctlHandlers(ADHOCCTL_EVENT_DISCONNECT, 0); //hleCheckCurrentCallbacks(); @@ -2032,8 +2115,12 @@ static u32 sceNetAdhocctlDelHandler(u32 handlerID) { int NetAdhocctl_Term() { if (netAdhocctlInited) { - if (adhocctlState != ADHOCCTL_STATE_DISCONNECTED) - NetAdhocctl_Disconnect(); + if (adhocctlState != ADHOCCTL_STATE_DISCONNECTED) { + if (netAdhocGameModeEntered) + NetAdhocctl_ExitGameMode(); + else + NetAdhocctl_Disconnect(); + } // Terminate Adhoc Threads friendFinderRunning = false; @@ -2060,6 +2147,7 @@ int NetAdhocctl_Term() { __KernelDeleteThread(threadAdhocID, SCE_KERNEL_ERROR_THREAD_TERMINATED, "AdhocThread deleted"); threadAdhocID = 0; } + adhocctlCurrentMode = ADHOCCTL_MODE_NONE; netAdhocctlInited = false; } @@ -2245,10 +2333,16 @@ int NetAdhocctl_Create(const char* groupName) { ERROR_LOG(SCENET, "Socket error (%i) when sending", error); //return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; // ERROR_NET_ADHOCCTL_DISCONNECTED; // ERROR_NET_ADHOCCTL_BUSY; //Faking success, to prevent Full Auto 2 from freezing while Initializing Network - adhocctlState = ADHOCCTL_STATE_CONNECTED; - // Notify Event Handlers, Needed for the Nickname to be shown on the screen when success is faked - // Connected Event's mipscall need be executed before returning from sceNetAdhocctlCreate (or before the next sceNet function?) - __UpdateAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); //CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventAdhocctlHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); + if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) { + adhocctlState = ADHOCCTL_STATE_GAMEMODE; + notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0); + } + else { + adhocctlState = ADHOCCTL_STATE_CONNECTED; + // Notify Event Handlers, Needed for the Nickname to be shown on the screen when success is faked + // Connected Event's mipscall need be executed before returning from sceNetAdhocctlCreate (or before the next sceNet function?) + notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0); //CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventAdhocctlHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); + } } // Free Network Lock @@ -2296,6 +2390,7 @@ int sceNetAdhocctlCreate(const char *groupName) { return -1; } + adhocctlCurrentMode = ADHOCCTL_MODE_NORMAL; adhocConnectionType = ADHOC_CREATE; return NetAdhocctl_Create(groupName); } @@ -2309,6 +2404,7 @@ int sceNetAdhocctlConnect(const char* groupName) { return -1; } + adhocctlCurrentMode = ADHOCCTL_MODE_NORMAL; adhocConnectionType = ADHOC_CONNECT; return NetAdhocctl_Create(groupName); } @@ -2332,6 +2428,7 @@ int sceNetAdhocctlJoin(u32 scanInfoAddr) { // We can ignore minor connection process differences here // TODO: Adhoc Server may need to be changed to differentiate between Host/Create and Join, otherwise it can't support multiple Host using the same Group name, thus causing one of the Host to be confused being treated as Join. + adhocctlCurrentMode = ADHOCCTL_MODE_NORMAL; adhocConnectionType = ADHOC_JOIN; return NetAdhocctl_Create(grpName); } @@ -2345,35 +2442,93 @@ int sceNetAdhocctlJoin(u32 scanInfoAddr) { } int NetAdhocctl_CreateEnterGameMode(const char* group_name, int game_type, int num_members, u32 membersAddr, u32 timeout, int flag) { - SceNetEtherAddr* addrs = NULL; // List of participating MAC addresses (started from host) - if (Memory::IsValidAddress(membersAddr)) { - addrs = PSPPointer::Create(membersAddr); + if (!netAdhocctlInited) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); + + if (!Memory::IsValidAddress(membersAddr)) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG, "invalid arg"); + + if (game_type <= 0 || game_type > 3 || num_members < 2 || num_members > 16 || (game_type == 1 && num_members > 4)) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG, "invalid arg"); + + if (gameModeBuffer) + free(gameModeBuffer); + gameModeBuffer = (u8*)malloc(GAMEMODE_BUFFER_SIZE); + + SceNetEtherAddr* addrs = PSPPointer::Create(membersAddr); // List of participating MAC addresses (started from host) + gameModeMacs.clear(); + requiredGameModeMacs.clear(); + for (int i = 0; i < num_members; i++) { + requiredGameModeMacs.push_back(*addrs); + DEBUG_LOG(SCENET, "GameMode macAddress#%d=%s", i, mac2str(addrs).c_str()); + addrs++; } + // Add local MAC (Host) first + SceNetEtherAddr localMac; + getLocalMac(&localMac); + gameModeMacs.push_back(localMac); - // TODO: Implement this - - return 0; + // We have to wait for all the MACs to have joined to go into CONNECTED state + adhocctlCurrentMode = ADHOCCTL_MODE_GAMEMODE; + adhocConnectionType = ADHOC_CREATE; + netAdhocGameModeEntered = true; + return NetAdhocctl_Create(group_name); } -// Connect to the Adhoc control game mode (as a Host) +/** +* Connect to the Adhoc control game mode (as a host) +* +* @param group_name - The name of the connection (maximum 8 alphanumeric characters). +* @param game_type - Pass 1. +* @param num_members - The total number of players (including the host). +* @param membersmacAddr - A pointer to a list of the participating mac addresses, host first, then clients. +* @param timeout - Timeout in microseconds. +* @param flag - pass 0. +* +* @return 0 on success, < 0 on error. +*/ static int sceNetAdhocctlCreateEnterGameMode(const char * group_name, int game_type, int num_members, u32 membersAddr, int timeout, int flag) { char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, game_type, num_members, membersAddr, timeout, flag, currentMIPS->pc); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, game_type, num_members, membersAddr, timeout, flag, currentMIPS->pc); return NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); } -// Connect to the Adhoc control game mode (as a Client) -static int sceNetAdhocctlJoinEnterGameMode(const char * group_name, const char *macAddr, int timeout, int flag) { +/** +* Connect to the Adhoc control game mode (as a client) +* +* @param group_name - The name of the connection (maximum 8 alphanumeric characters). +* @param hostmacAddr - The mac address of the host. +* @param timeout - Timeout in microseconds. +* @param flag - pass 0. +* +* @return 0 on success, < 0 on error. +*/ +static int sceNetAdhocctlJoinEnterGameMode(const char * group_name, const char *hostMac, int timeout, int flag) { char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)hostMac).c_str(), timeout, flag, currentMIPS->pc); - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)macAddr).c_str(), timeout, flag, currentMIPS->pc); + if (!netAdhocctlInited) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); - return 0; + if (!hostMac) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG, "invalid arg"); + + if (gameModeBuffer) + free(gameModeBuffer); + gameModeBuffer = (u8*)malloc(GAMEMODE_BUFFER_SIZE); + + // Add host mac first + gameModeMacs.push_back(*(SceNetEtherAddr*)hostMac); + + adhocctlCurrentMode = ADHOCCTL_MODE_GAMEMODE; + adhocConnectionType = ADHOC_JOIN; + netAdhocGameModeEntered = true; + return NetAdhocctl_Create(group_name); } /** @@ -2387,14 +2542,13 @@ static int sceNetAdhocctlJoinEnterGameMode(const char * group_name, const char * * @param flag Unused Bitflags * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG, ADHOCCTL_BUSY, ADHOCCTL_CHANNEL_NOT_AVAILABLE */ -int sceNetAdhocctlCreateEnterGameModeMin(const char *group_name, int game_type, int min_members, int num_members, u32 membersAddr, u32 timeout, int flag) -{ +int sceNetAdhocctlCreateEnterGameModeMin(const char *group_name, int game_type, int min_members, int num_members, u32 membersAddr, u32 timeout, int flag) { char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", grpName, game_type, min_members, num_members, membersAddr, timeout, flag, currentMIPS->pc); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", grpName, game_type, min_members, num_members, membersAddr, timeout, flag, currentMIPS->pc); // We don't really need the Minimum User Check - return NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); //0; + return NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); } int NetAdhoc_Term() { @@ -2409,8 +2563,8 @@ int NetAdhoc_Term() { // Delete Adhoc Sockets deleteAllAdhocSockets(); - // Delete Gamemode Buffer - //deleteAllGMB(); + // Delete GameMode Buffers + deleteAllGMB(); // Terminate Internet Library //sceNetInetTerm(); @@ -3530,33 +3684,189 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { return ERROR_NET_ADHOC_NOT_INITIALIZED; } -static int sceNetAdhocGameModeCreateMaster(u32 data, int size) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeCreateMaster(%08x, %i) at %08x", data, size, currentMIPS->pc); - return 0; +/** +* Create own game object type data. +* +* @param dataAddr - A pointer to the game object data. +* @param size - Size of the game data. +* +* @return 0 on success, < 0 on error. +*/ +static int sceNetAdhocGameModeCreateMaster(u32 dataAddr, int size) { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocGameModeCreateMaster(%08x, %i) at %08x", dataAddr, size, currentMIPS->pc); + if (!netAdhocctlInited) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); + + if (adhocctlCurrentMode != ADHOCCTL_MODE_GAMEMODE) + return hleLogError(SCENET, ERROR_NET_ADHOC_NOT_IN_GAMEMODE, "not in gamemode"); + + if (!netAdhocGameModeEntered) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_ENTER_GAMEMODE, "not enter gamemode"); + + if (size < 0 || !Memory::IsValidAddress(dataAddr)) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG, "invalid arg"); + + SceNetEtherAddr localMac; + getLocalMac(&localMac); + u8* data = (u8*)malloc(size); + if (data) { + Memory::Memcpy(data, dataAddr, size); + gameModeSocket = sceNetAdhocPdpCreate((const char*)&localMac, ADHOC_GAMEMODE_PORT, GAMEMODE_BUFFER_SIZE, 0); + masterGameModeArea = { 0, size, dataAddr, CoreTiming::GetGlobalTimeUsScaled(), 1, localMac, data }; + StartGameModeScheduler(); + } + + return 0; // returned an id just like CreateReplica? always return 0? } -static int sceNetAdhocGameModeCreateReplica(const char *mac, u32 data, int size) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeCreateReplica(%s, %08x, %i) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), data, size, currentMIPS->pc); - return 0; +/** +* Create peer game object type data. +* +* @param mac - The mac address of the peer. +* @param dataAddr - A pointer to the game object data. +* @param size - Size of the game data. +* +* @return The id of the replica on success, < 0 on error. +*/ +static int sceNetAdhocGameModeCreateReplica(const char *mac, u32 dataAddr, int size) { + WARN_LOG(SCENET, "UNTESTED sceNetAdhocGameModeCreateReplica(%s, %08x, %i) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), dataAddr, size, currentMIPS->pc); + if (!netAdhocctlInited) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); + + if (adhocctlCurrentMode != ADHOCCTL_MODE_GAMEMODE) + return hleLogError(SCENET, ERROR_NET_ADHOC_NOT_IN_GAMEMODE, "not in gamemode"); + + if (!netAdhocGameModeEntered) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_ENTER_GAMEMODE, "not enter gamemode"); + + if (mac == nullptr || size < 0 || !Memory::IsValidAddress(dataAddr)) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG, "invalid arg"); + + int maxid = 0; + auto it = std::find_if(replicaGameModeAreas.begin(), replicaGameModeAreas.end(), + [mac, &maxid](GameModeArea const& e) { + if (e.id > maxid) maxid = e.id; + return IsMatch(e.mac, mac); + }); + // MAC address already existed! + if (it != replicaGameModeAreas.end()) { + WARN_LOG(SCENET, "sceNetAdhocGameModeCreateReplica - [%s] is already existed (id: %d)", mac2str((SceNetEtherAddr*)mac).c_str(), it->id); + return it->id; + } + + int ret = 0; + u8* data = (u8*)malloc(size); + if (data) { + Memory::Memcpy(data, dataAddr, size); + //int sock = sceNetAdhocPdpCreate(mac, ADHOC_GAMEMODE_PORT, GAMEMODE_BUFFER_SIZE, 0); + GameModeArea gma = { maxid + 1, size, dataAddr, CoreTiming::GetGlobalTimeUsScaled(), 0, *(SceNetEtherAddr*)mac, data }; + replicaGameModeAreas.push_back(gma); + ret = gma.id; + } + return hleLogSuccessInfoI(SCENET, ret, "success"); // valid id for replica started from 1? } static int sceNetAdhocGameModeUpdateMaster() { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeUpdateMaster()"); + DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocGameModeUpdateMaster()"); + if (!netAdhocctlInited) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); + + if (adhocctlCurrentMode != ADHOCCTL_MODE_GAMEMODE) + return hleLogError(SCENET, ERROR_NET_ADHOC_NOT_IN_GAMEMODE, "not in gamemode"); + + if (!netAdhocGameModeEntered) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_ENTER_GAMEMODE, "not enter gamemode"); + + if (masterGameModeArea.data) { + Memory::Memcpy(masterGameModeArea.data, masterGameModeArea.addr, masterGameModeArea.size); + masterGameModeArea.dataUpdated = 1; + masterGameModeArea.updateTimestamp = CoreTiming::GetGlobalTimeUsScaled(); + } + return 0; } static int sceNetAdhocGameModeDeleteMaster() { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeDeleteMaster()"); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocGameModeDeleteMaster()"); + if (isZeroMAC(&masterGameModeArea.mac)) + return hleLogError(SCENET, ERROR_NET_ADHOC_NOT_CREATED, "not created"); + + if (masterGameModeArea.data) { + free(masterGameModeArea.data); + } + //sceNetAdhocPdpDelete(masterGameModeArea.socket, 0); + masterGameModeArea = { 0 }; + + if (replicaGameModeAreas.size() <= 0) { + sceNetAdhocPdpDelete(gameModeSocket, 0); + gameModeSocket = (int)INVALID_SOCKET; + } + return 0; } static int sceNetAdhocGameModeUpdateReplica(int id, u32 infoAddr) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeUpdateReplica(%i, %08x)", id, infoAddr); + DEBUG_LOG(SCENET, "UNTESTED sceNetAdhocGameModeUpdateReplica(%i, %08x)", id, infoAddr); + if (!netAdhocctlInited) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); + + if (adhocctlCurrentMode != ADHOCCTL_MODE_GAMEMODE) + return hleLogError(SCENET, ERROR_NET_ADHOC_NOT_IN_GAMEMODE, "not in gamemode"); + + if (!netAdhocGameModeEntered) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_ENTER_GAMEMODE, "not enter gamemode"); + + auto it = std::find_if(replicaGameModeAreas.begin(), replicaGameModeAreas.end(), + [id](GameModeArea const& e) { + return e.id == id; + }); + + if (it == replicaGameModeAreas.end()) + return hleLogError(SCENET, ERROR_NET_ADHOC_NOT_CREATED, "not created"); + + for (auto gma : replicaGameModeAreas) { + if (gma.id == id) { + if (Memory::IsValidAddress(infoAddr)) { + GameModeUpdateInfo* gmuinfo = (GameModeUpdateInfo*)Memory::GetPointer(infoAddr); + if (gma.data && gma.dataUpdated) { + memcpy(Memory::GetPointer(gma.addr), gma.data, gma.size); + gma.dataUpdated = 0; + gmuinfo->updated = 1; + } + else { + gmuinfo->updated = 0; + } + gmuinfo->timeStamp = CoreTiming::GetGlobalTimeUsScaled(); + } + break; + } + } + return 0; } static int sceNetAdhocGameModeDeleteReplica(int id) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocGameModeDeleteReplica(%i)", id); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocGameModeDeleteReplica(%i)", id); + auto it = std::find_if(replicaGameModeAreas.begin(), replicaGameModeAreas.end(), + [id](GameModeArea const& e) { + return e.id == id; + }); + + if (it == replicaGameModeAreas.end()) + return hleLogError(SCENET, ERROR_NET_ADHOC_NOT_CREATED, "not created"); + + if (it->data) { + free(it->data); + it->data = nullptr; + } + //sceNetAdhocPdpDelete(it->socket, 0); + replicaGameModeAreas.erase(it); + + if (replicaGameModeAreas.size() <= 0 && isZeroMAC(&masterGameModeArea.mac)) { + //sceNetAdhocPdpDelete(gameModeSocket, 0); + //gameModeSocket = (int)INVALID_SOCKET; + } + return 0; } @@ -3606,7 +3916,7 @@ int NetAdhocMatching_Stop(int matchingId) { // Multithreading Lock peerlock.lock(); - // Remove your own MAC, or All memebers, or don't remove at all or we should do this on MatchingDelete ? + // Remove your own MAC, or All members, or don't remove at all or we should do this on MatchingDelete ? clearPeerList(item); //deleteAllMembers(item); item->running = 0; @@ -3788,9 +4098,9 @@ static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbufle // Allocated Memory if (context != NULL) { // Create PDP Socket - SceNetEtherAddr localmac; getLocalMac(&localmac); - const char * mac = (const char *)&localmac.data; - int socket = sceNetAdhocPdpCreate(mac, (uint32_t)port, rxbuflen, 0); + SceNetEtherAddr localmac; + getLocalMac(&localmac); + int socket = sceNetAdhocPdpCreate((const char*)&localmac, (uint32_t)port, rxbuflen, 0); // Created PDP Socket if (socket > 0) { // Clear Memory @@ -4767,7 +5077,7 @@ void __NetTriggerCallbacks() // FIXME: When Joining a group, Do we need to wait for group creator's peer data before triggering the callback to make sure the game not to thinks we're the group creator? u64 now = (u64)(real_time_now() * 1000.0); - if (flags != ADHOCCTL_EVENT_CONNECT || adhocConnectionType != ADHOC_JOIN || getActivePeerCount() > 0 || now - adhocctlStartTime > adhocDefaultTimeout) + if ((flags != ADHOCCTL_EVENT_CONNECT && flags != ADHOCCTL_EVENT_GAME) || adhocConnectionType != ADHOC_JOIN || getActivePeerCount() > 0 || now - adhocctlStartTime > adhocDefaultTimeout) { // Since 0 is a valid index to types_ we use -1 to detects if it was loaded from an old save state if (actionAfterAdhocMipsCall < 0) { @@ -4788,6 +5098,7 @@ void __NetTriggerCallbacks() break; case ADHOCCTL_EVENT_GAME: adhocctlState = ADHOCCTL_STATE_GAMEMODE; + delayus = (adhocEventDelayMS + 2 * adhocExtraPollDelayMS) * 1000; break; case ADHOCCTL_EVENT_DISCOVER: adhocctlState = ADHOCCTL_STATE_DISCOVER; @@ -4897,17 +5208,41 @@ const HLEFunction sceNetAdhocMatching[] = { {0X756E6F00, &WrapV_V<__NetMatchingCallbacks>, "__NetMatchingCallbacks", 'v', "" }, }; +int NetAdhocctl_ExitGameMode() { + if (gameModeSocket > 0) + sceNetAdhocPdpDelete(gameModeSocket, 0); + + deleteAllGMB(); + + adhocctlCurrentMode = ADHOCCTL_MODE_NONE; + netAdhocGameModeEntered = false; + return NetAdhocctl_Disconnect(); +} + static int sceNetAdhocctlExitGameMode() { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlExitGameMode()"); - return 0; + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlExitGameMode()"); + + return NetAdhocctl_ExitGameMode(); } static int sceNetAdhocctlGetGameModeInfo(u32 infoAddr) { - ERROR_LOG(SCENET, "UNIMPL sceNetAdhocctlGetGameModeInfo(%08x)", infoAddr); + WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlGetGameModeInfo(%08x)", infoAddr); + if (!netAdhocctlInited) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); - SceNetAdhocctlGameModeInfo* gmInfo = NULL; - if (Memory::IsValidAddress(infoAddr)) gmInfo = (SceNetAdhocctlGameModeInfo*)Memory::GetPointer(infoAddr); - // TODO: Writes number of participants and each participating MAC address into infoAddr/gmInfo + if (!Memory::IsValidAddress(infoAddr)) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG, "invalid arg"); + + SceNetAdhocctlGameModeInfo* gmInfo = (SceNetAdhocctlGameModeInfo*)Memory::GetPointer(infoAddr); + // Writes number of participants and each participating MAC address into infoAddr/gmInfo + gmInfo->num = static_cast(gameModeMacs.size()); + int i = 0; + for (auto& mac : gameModeMacs) { + INFO_LOG(SCENET, "GameMode macAddress#%d=%s", i, mac2str(&mac).c_str()); + gmInfo->members[i++] = mac; + if (i >= ADHOCCTL_GAMEMODE_MAX_MEMBERS) + break; + } return 0; } From 115ad97e0f39f8a0b1bc1041ddb723f3b2a571d1 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Sun, 20 Sep 2020 23:50:11 +0700 Subject: [PATCH 737/848] Using REPORT_ONCE to report some of GameMode HLE existance. --- Core/HLE/sceNetAdhoc.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 9b816c14fe..3ea9ee359e 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -36,6 +36,7 @@ // All credit goes to him! #include "Core/Core.h" #include "Core/Host.h" +#include "Core/Reporting.h" #include "Core/MemMapHelpers.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" @@ -57,6 +58,7 @@ #include "Core/HLE/KernelWaitHelpers.h" #include "i18n/i18n.h" + // shared in sceNetAdhoc.h since it need to be used from sceNet.cpp also // TODO: Make accessor functions instead, and throw all this state in a struct. bool netAdhocInited; @@ -2491,7 +2493,7 @@ static int sceNetAdhocctlCreateEnterGameMode(const char * group_name, int game_t char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, game_type, num_members, membersAddr, timeout, flag, currentMIPS->pc); + WARN_LOG_REPORT_ONCE(sceNetAdhocctlCreateEnterGameMode, SCENET, "UNTESTED sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, game_type, num_members, membersAddr, timeout, flag, currentMIPS->pc); return NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); } @@ -2510,7 +2512,7 @@ static int sceNetAdhocctlJoinEnterGameMode(const char * group_name, const char * char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)hostMac).c_str(), timeout, flag, currentMIPS->pc); + WARN_LOG_REPORT_ONCE(sceNetAdhocctlJoinEnterGameMode, SCENET, "UNTESTED sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)hostMac).c_str(), timeout, flag, currentMIPS->pc); if (!netAdhocctlInited) return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); @@ -2546,7 +2548,7 @@ int sceNetAdhocctlCreateEnterGameModeMin(const char *group_name, int game_type, char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", grpName, game_type, min_members, num_members, membersAddr, timeout, flag, currentMIPS->pc); + WARN_LOG_REPORT_ONCE(sceNetAdhocctlCreateEnterGameModeMin, SCENET, "UNTESTED sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", grpName, game_type, min_members, num_members, membersAddr, timeout, flag, currentMIPS->pc); // We don't really need the Minimum User Check return NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag); } From 707e9cf7ac80f6de28b8c9fcbbe1f79d7ce8534c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 20:35:42 +0200 Subject: [PATCH 738/848] Remove some unnecessary function parameters, improve some comments. --- GPU/Common/DrawEngineCommon.cpp | 2 ++ GPU/Common/ShaderCommon.h | 2 +- GPU/Common/TextureCacheCommon.cpp | 6 +----- GPU/Common/TextureCacheCommon.h | 7 +++++-- GPU/D3D11/TextureCacheD3D11.cpp | 9 +++------ GPU/D3D11/TextureCacheD3D11.h | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 8 +++----- GPU/Directx9/TextureCacheDX9.h | 2 +- GPU/GLES/TextureCacheGLES.cpp | 4 +++- GPU/GLES/TextureCacheGLES.h | 6 ++---- GPU/Vulkan/TextureCacheVulkan.cpp | 9 +++------ GPU/Vulkan/TextureCacheVulkan.h | 6 ++---- assets/lang | 2 +- ext/native/thin3d/GLRenderManager.h | 5 +++-- 14 files changed, 31 insertions(+), 39 deletions(-) diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 8285191699..b326a832ad 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -698,6 +698,8 @@ void DrawEngineCommon::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, } *bytesRead = vertexCount * dec_->VertexSize(); + + // Check that we have enough vertices to form the requested primitive. if ((vertexCount < 2 && prim > 0) || (vertexCount < 3 && prim > 2 && prim != GE_PRIM_RECTANGLES)) return; diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index b8827dd03d..3280c765b6 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -104,7 +104,7 @@ enum : uint64_t { // Other dirty elements that aren't uniforms! DIRTY_FRAMEBUF = 1ULL << 40, - DIRTY_TEXTURE_IMAGE = 1ULL << 41, + DIRTY_TEXTURE_IMAGE = 1ULL << 41, // Means that the definition of the texture image has changed (address, stride etc), and we need to look up again. DIRTY_TEXTURE_PARAMS = 1ULL << 42, // Render State diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 369c4c2ea7..c3eaf6703a 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -321,11 +321,7 @@ void TextureCacheCommon::UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode) } } -TexCacheEntry *TextureCacheCommon::SetTexture(bool force) { - if (force) { - InvalidateLastTexture(); - } - +TexCacheEntry *TextureCacheCommon::SetTexture() { u8 level = 0; if (IsFakeMipmapChange()) level = std::max(0, gstate.getTexLevelOffset16() / 16); diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 7ed78e911d..1241476a0a 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -231,7 +231,10 @@ public: void LoadClut(u32 clutAddr, u32 loadBytes); bool GetCurrentClutBuffer(GPUDebugBuffer &buffer); - TexCacheEntry *SetTexture(bool force = false); + // This updates nextTexture_ / nextFramebufferTexture_, which is then used by ApplyTexture. + // TODO: Return stuff directly instead of keeping state. + TexCacheEntry *SetTexture(); + void ApplyTexture(); bool SetOffsetTexture(u32 yOffset); void Invalidate(u32 addr, int size, GPUInvalidationType type); @@ -239,7 +242,7 @@ public: void ClearNextFrame(); virtual void ForgetLastTexture() = 0; - virtual void InvalidateLastTexture(TexCacheEntry *entry = nullptr) = 0; + virtual void InvalidateLastTexture() = 0; virtual void Clear(bool delete_them); virtual void NotifyConfigChanged(); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 78e7327716..5a0f63e600 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -149,10 +149,8 @@ void TextureCacheD3D11::ForgetLastTexture() { context_->PSSetShaderResources(0, 2, nullTex); } -void TextureCacheD3D11::InvalidateLastTexture(TexCacheEntry *entry) { - if (!entry || entry->texturePtr == lastBoundTexture) { - lastBoundTexture = INVALID_TEX; - } +void TextureCacheD3D11::InvalidateLastTexture() { + lastBoundTexture = INVALID_TEX; } void TextureCacheD3D11::StartFrame() { @@ -410,7 +408,6 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(VirtualFramebuffer *framebuffer, gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_FRAGMENTSHADER_STATE); } - void TextureCacheD3D11::BuildTexture(TexCacheEntry *const entry) { entry->status &= ~TexCacheEntry::STATUS_ALPHA_MASK; @@ -736,7 +733,7 @@ void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture & } bool TextureCacheD3D11::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { - SetTexture(false); + SetTexture(); if (!nextTexture_) { if (nextFramebufferTexture_) { VirtualFramebuffer *vfb = nextFramebufferTexture_; diff --git a/GPU/D3D11/TextureCacheD3D11.h b/GPU/D3D11/TextureCacheD3D11.h index 6aa3bcda9e..ceaf64b150 100644 --- a/GPU/D3D11/TextureCacheD3D11.h +++ b/GPU/D3D11/TextureCacheD3D11.h @@ -58,7 +58,7 @@ public: } void ForgetLastTexture() override; - void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override; + void InvalidateLastTexture() override; bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index f2557ab92d..56bd153bef 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -97,10 +97,8 @@ void TextureCacheDX9::ForgetLastTexture() { gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } -void TextureCacheDX9::InvalidateLastTexture(TexCacheEntry *entry) { - if (!entry || entry->texturePtr == lastBoundTexture) { - lastBoundTexture = INVALID_TEX; - } +void TextureCacheDX9::InvalidateLastTexture() { + lastBoundTexture = INVALID_TEX; } D3DFORMAT getClutDestFormat(GEPaletteFormat format) { @@ -690,7 +688,7 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &re } bool TextureCacheDX9::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { - SetTexture(true); + SetTexture(); ApplyTexture(); int w = gstate.getTextureWidth(level); int h = gstate.getTextureHeight(level); diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index 3a0c291586..1ebf3bb5fc 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -50,7 +50,7 @@ public: } void ForgetLastTexture() override; - void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override; + void InvalidateLastTexture() override; bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index de6852d556..ba953676d4 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -730,7 +730,9 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) gstate.texbufwidth[0] = gstate.texbufwidth[level]; } - SetTexture(true); + InvalidateLastTexture(); + SetTexture(); + if (!nextTexture_) { if (nextFramebufferTexture_) { VirtualFramebuffer *vfb = nextFramebufferTexture_; diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index 7564b635b5..e196a358dc 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -57,10 +57,8 @@ public: lastBoundTexture = nullptr; gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } - void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override { - if (!entry || entry->textureName == lastBoundTexture) { - lastBoundTexture = nullptr; - } + void InvalidateLastTexture() override { + lastBoundTexture = nullptr; } bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index c6d9971770..c33e6c73c4 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -509,11 +509,8 @@ void TextureCacheVulkan::UpdateCurrentClut(GEPaletteFormat clutFormat, u32 clutB } void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) { - if (!entry || !entry->vkTex) { - imageView_ = VK_NULL_HANDLE; - curSampler_ = VK_NULL_HANDLE; - return; - } + _assert_(entry); + _assert_(entry->vkTex); entry->vkTex->Touch(); imageView_ = entry->vkTex->GetImageView(); @@ -1114,7 +1111,7 @@ void TextureCacheVulkan::LoadTextureLevel(TexCacheEntry &entry, uint8_t *writePt } bool TextureCacheVulkan::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) { - SetTexture(false); + SetTexture(); if (!nextTexture_) { if (nextFramebufferTexture_) { VirtualFramebuffer *vfb = nextFramebufferTexture_; diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index 7aaa04d56e..8622b5d974 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -88,10 +88,8 @@ public: gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } - void InvalidateLastTexture(TexCacheEntry *entry = nullptr) override { - if (!entry || entry->vkTex == lastBoundTexture) { - lastBoundTexture = nullptr; - } + void InvalidateLastTexture() override { + lastBoundTexture = nullptr; } void NotifyConfigChanged() override; diff --git a/assets/lang b/assets/lang index 1c64b8fbd3..d5a2a51942 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit 1c64b8fbd3cb6bd87935eb53f302f7de6f86e209 +Subproject commit d5a2a51942377820764604d9bb424fa9a879c4bd diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 3e5870507d..d9721bf4ae 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -30,7 +30,8 @@ public: } GLuint texture = 0; - // Could also trust OpenGL defaults I guess.. + + // We don't trust OpenGL defaults - setting wildly off values ensures that we'll end up overwriting these parameters. GLenum target = 0xFFFF; GLenum wrapS = 0xFFFF; GLenum wrapT = 0xFFFF; @@ -63,7 +64,7 @@ public: int width; int height; - GLuint colorDepth; + GLuint colorDepth = 0; bool z_stencil_; }; From bdcf2c5cff4a8b02e3b8eeb2e9dd897fc9a7f94e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 20:42:28 +0200 Subject: [PATCH 739/848] Have to invalidate "lastBoundTexture" when binding framebuffers as texture. Fixes parts of #13431 for D3D11 at least. Will probably soon get rid of this concept, it's only useful in D3D9/11 and those are probably not gonna lose much perf if we remove this minor state caching. --- GPU/Common/TextureCacheCommon.cpp | 1 + GPU/D3D11/TextureCacheD3D11.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index c3eaf6703a..64c687bf1e 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -1588,6 +1588,7 @@ void TextureCacheCommon::ApplyTexture() { // Maybe we bound a framebuffer? if (nextFramebufferTexture_) { bool depth = Memory::IsDepthTexVRAMAddress(gstate.getTextureAddress(0)); + InvalidateLastTexture(); ApplyTextureFramebuffer(nextFramebufferTexture_, gstate.getTextureFormat(), depth ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR); nextFramebufferTexture_ = nullptr; } diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 5a0f63e600..3a9dbda64a 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -145,6 +145,7 @@ void TextureCacheD3D11::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { void TextureCacheD3D11::ForgetLastTexture() { InvalidateLastTexture(); gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); + ID3D11ShaderResourceView *nullTex[2]{}; context_->PSSetShaderResources(0, 2, nullTex); } From 3093b9c7bf49e5ea9d53c184f8a7cf7948be4b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 21:33:06 +0200 Subject: [PATCH 740/848] Share GPUS stats formatting code between the backends (easier to add new stats) --- GPU/Common/TextureCacheCommon.cpp | 3 ++- GPU/D3D11/GPU_D3D11.cpp | 39 ++++++---------------------- GPU/Directx9/GPU_DX9.cpp | 37 +++++---------------------- GPU/GLES/GPU_GLES.cpp | 42 +++++++------------------------ GPU/GPU.h | 5 ++++ GPU/GPUCommon.cpp | 35 ++++++++++++++++++++++++++ GPU/GPUCommon.h | 2 ++ GPU/Vulkan/GPU_Vulkan.cpp | 38 +++++----------------------- 8 files changed, 72 insertions(+), 129 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 64c687bf1e..6cfa2d3f66 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -1759,8 +1759,9 @@ void TextureCacheCommon::Invalidate(u32 addr, int size, GPUInvalidationType type // This is an active signal from the game that something in the texture cache may have changed. gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); } else { - // Do a quick check to see if the current texture is in range. + // Do a quick check to see if the current texture could potentially be in range. const u32 currentAddr = gstate.getTextureAddress(0); + // TODO: This can be made tighter. if (addr_end >= currentAddr && addr < currentAddr + LARGEST_TEXTURE_SIZE) { gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); } diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index f4e8f20db8..c5a8753d06 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -304,38 +304,13 @@ void GPU_D3D11::ExecuteOp(u32 op, u32 diff) { } void GPU_D3D11::GetStats(char *buffer, size_t bufsize) { - float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; - snprintf(buffer, bufsize - 1, - "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" - "Num Tracked Vertex Arrays: %i\n" - "GPU cycles executed: %d (%f per vertex)\n" - "Commands per call level: %i %i %i %i\n" - "Vertices submitted: %i\n" - "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i (evaluations: %d)\n" - "Textures active: %i, decoded: %i invalidated: %i\n" - "Readbacks: %d, uploads: %d\n" - "Vertex, Fragment shaders loaded: %i, %i\n", - gpuStats.msProcessingDisplayLists * 1000.0f, - gpuStats.numDrawCalls, - gpuStats.numFlushes, - gpuStats.numClears, - gpuStats.numCachedDrawCalls, - gpuStats.numTrackedVertexArrays, - gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, - vertexAverageCycles, - gpuStats.gpuCommandsAtCallLevel[0], gpuStats.gpuCommandsAtCallLevel[1], gpuStats.gpuCommandsAtCallLevel[2], gpuStats.gpuCommandsAtCallLevel[3], - gpuStats.numVertsSubmitted, - gpuStats.numCachedVertsDrawn, - gpuStats.numUncachedVertsDrawn, - (int)framebufferManagerD3D11_->NumVFBs(), - gpuStats.numFramebufferEvaluations, - (int)textureCacheD3D11_->NumLoadedTextures(), - gpuStats.numTexturesDecoded, - gpuStats.numTextureInvalidations, - gpuStats.numReadbacks, - gpuStats.numUploads, + size_t offset = FormatGPUStatsCommon(buffer, bufsize); + buffer += offset; + bufsize -= offset; + if ((int)bufsize < 0) + return; + snprintf(buffer, bufsize, + "Vertex, Fragment shaders loaded: %d, %d\n", shaderManagerD3D11_->GetNumVertexShaders(), shaderManagerD3D11_->GetNumFragmentShaders() ); diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 936dcee7a8..ad858ea665 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -344,38 +344,13 @@ void GPU_DX9::ExecuteOp(u32 op, u32 diff) { } void GPU_DX9::GetStats(char *buffer, size_t bufsize) { - float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; - snprintf(buffer, bufsize - 1, - "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" - "Num Tracked Vertex Arrays: %i\n" - "GPU cycles executed: %d (%f per vertex)\n" - "Commands per call level: %i %i %i %i\n" - "Vertices submitted: %i\n" - "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i (evaluations: %d)\n" - "Textures active: %i, decoded: %i invalidated: %i\n" - "Readbacks: %d, uploads: %d\n" + size_t offset = FormatGPUStatsCommon(buffer, bufsize); + buffer += offset; + bufsize -= offset; + if ((int)bufsize < 0) + return; + snprintf(buffer, bufsize, "Vertex, Fragment shaders loaded: %i, %i\n", - gpuStats.msProcessingDisplayLists * 1000.0f, - gpuStats.numDrawCalls, - gpuStats.numFlushes, - gpuStats.numClears, - gpuStats.numCachedDrawCalls, - gpuStats.numTrackedVertexArrays, - gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, - vertexAverageCycles, - gpuStats.gpuCommandsAtCallLevel[0], gpuStats.gpuCommandsAtCallLevel[1], gpuStats.gpuCommandsAtCallLevel[2], gpuStats.gpuCommandsAtCallLevel[3], - gpuStats.numVertsSubmitted, - gpuStats.numCachedVertsDrawn, - gpuStats.numUncachedVertsDrawn, - (int)framebufferManagerDX9_->NumVFBs(), - gpuStats.numFramebufferEvaluations, - (int)textureCacheDX9_->NumLoadedTextures(), - gpuStats.numTexturesDecoded, - gpuStats.numTextureInvalidations, - gpuStats.numReadbacks, - gpuStats.numUploads, shaderManagerDX9_->GetNumVertexShaders(), shaderManagerDX9_->GetNumFragmentShaders() ); diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 2ba4922a2c..062705f8a3 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -445,41 +445,17 @@ void GPU_GLES::ExecuteOp(u32 op, u32 diff) { } void GPU_GLES::GetStats(char *buffer, size_t bufsize) { - float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; - snprintf(buffer, bufsize - 1, - "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" - "Num Tracked Vertex Arrays: %i\n" - "GPU cycles executed: %d (%f per vertex)\n" - "Commands per call level: %i %i %i %i\n" - "Vertices submitted: %i\n" - "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i (evaluations: %d)\n" - "Textures active: %i, decoded: %i invalidated: %i\n" - "Readbacks: %d, uploads: %d\n" - "Vertex, Fragment, Programs loaded: %i, %i, %i\n", - gpuStats.msProcessingDisplayLists * 1000.0f, - gpuStats.numDrawCalls, - gpuStats.numFlushes, - gpuStats.numClears, - gpuStats.numCachedDrawCalls, - gpuStats.numTrackedVertexArrays, - gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, - vertexAverageCycles, - gpuStats.gpuCommandsAtCallLevel[0], gpuStats.gpuCommandsAtCallLevel[1], gpuStats.gpuCommandsAtCallLevel[2], gpuStats.gpuCommandsAtCallLevel[3], - gpuStats.numVertsSubmitted, - gpuStats.numCachedVertsDrawn, - gpuStats.numUncachedVertsDrawn, - (int)framebufferManagerGL_->NumVFBs(), - gpuStats.numFramebufferEvaluations, - (int)textureCacheGL_->NumLoadedTextures(), - gpuStats.numTexturesDecoded, - gpuStats.numTextureInvalidations, - gpuStats.numReadbacks, - gpuStats.numUploads, + size_t offset = FormatGPUStatsCommon(buffer, bufsize); + buffer += offset; + bufsize -= offset; + if ((int)bufsize < 0) + return; + snprintf(buffer, bufsize, + "Vertex, Fragment, Programs loaded: %d, %d, %d\n", shaderManagerGL_->GetNumVertexShaders(), shaderManagerGL_->GetNumFragmentShaders(), - shaderManagerGL_->GetNumPrograms()); + shaderManagerGL_->GetNumPrograms() + ); } void GPU_GLES::ClearCacheNextFrame() { diff --git a/GPU/GPU.h b/GPU/GPU.h index 92785b8de4..0a4fb4f66d 100644 --- a/GPU/GPU.h +++ b/GPU/GPU.h @@ -55,6 +55,7 @@ struct GPUStatistics { // Never add a vtable :) memset(this, 0, sizeof(*this)); } + void ResetFrame() { numDrawCalls = 0; numCachedDrawCalls = 0; @@ -64,7 +65,9 @@ struct GPUStatistics { numTrackedVertexArrays = 0; numTextureInvalidations = 0; numTextureInvalidationsByFramebuffer = 0; + numTexturesHashed = 0; numTextureSwitches = 0; + numTextureDataBytesHashed = 0; numShaderSwitches = 0; numFlushes = 0; numTexturesDecoded = 0; @@ -88,6 +91,8 @@ struct GPUStatistics { int numTrackedVertexArrays; int numTextureInvalidations; int numTextureInvalidationsByFramebuffer; + int numTexturesHashed; + int numTextureDataBytesHashed; int numTextureSwitches; int numShaderSwitches; int numTexturesDecoded; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 32bcb5ec66..620c1b85fc 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -2876,3 +2876,38 @@ bool GPUCommon::FramebufferReallyDirty() { } return true; } + +size_t GPUCommon::FormatGPUStatsCommon(char *buffer, size_t size) { + float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; + return snprintf(buffer, size, + "DL processing time: %0.2f ms\n" + "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" + "Num Tracked Vertex Arrays: %i\n" + "GPU cycles executed: %d (%f per vertex)\n" + "Commands per call level: %i %i %i %i\n" + "Vertices submitted: %i\n" + "Cached, Uncached Vertices Drawn: %i, %i\n" + "FBOs active: %i (evaluations: %d)\n" + "Textures active: %i, decoded: %i invalidated: %i\n" + "Readbacks: %d, uploads: %d\n", + gpuStats.msProcessingDisplayLists * 1000.0f, + gpuStats.numDrawCalls, + gpuStats.numFlushes, + gpuStats.numClears, + gpuStats.numCachedDrawCalls, + gpuStats.numTrackedVertexArrays, + gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, + vertexAverageCycles, + gpuStats.gpuCommandsAtCallLevel[0], gpuStats.gpuCommandsAtCallLevel[1], gpuStats.gpuCommandsAtCallLevel[2], gpuStats.gpuCommandsAtCallLevel[3], + gpuStats.numVertsSubmitted, + gpuStats.numCachedVertsDrawn, + gpuStats.numUncachedVertsDrawn, + (int)framebufferManager_->NumVFBs(), + gpuStats.numFramebufferEvaluations, + (int)textureCache_->NumLoadedTextures(), + gpuStats.numTexturesDecoded, + gpuStats.numTextureInvalidations, + gpuStats.numReadbacks, + gpuStats.numUploads + ); +} diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 2dd4d7da1b..ede1b44720 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -303,6 +303,8 @@ protected: } } + size_t FormatGPUStatsCommon(char *buf, size_t size); + FramebufferManagerCommon *framebufferManager_ = nullptr; TextureCacheCommon *textureCache_ = nullptr; DrawEngineCommon *drawEngineCommon_ = nullptr; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 9c7f36afe7..2b9724f127 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -552,44 +552,18 @@ void GPU_Vulkan::DeviceRestore() { } void GPU_Vulkan::GetStats(char *buffer, size_t bufsize) { + size_t offset = FormatGPUStatsCommon(buffer, bufsize); + buffer += offset; + bufsize -= offset; + if ((int)bufsize < 0) + return; const DrawEngineVulkanStats &drawStats = drawEngine_.GetStats(); char texStats[256]; textureCacheVulkan_->GetStats(texStats, sizeof(texStats)); - float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; - snprintf(buffer, bufsize - 1, - "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" - "Num Tracked Vertex Arrays: %i\n" - "GPU cycles executed: %d (%f per vertex)\n" - "Commands per call level: %i %i %i %i\n" - "Vertices submitted: %i\n" - "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i (evaluations: %d)\n" - "Textures active: %i, decoded: %i invalidated: %d (%d by fb)\n" - "Readbacks: %d, uploads: %d\n" + snprintf(buffer, bufsize, "Vertex, Fragment, Pipelines loaded: %i, %i, %i\n" "Pushbuffer space used: UBO %d, Vtx %d, Idx %d\n" "%s\n", - gpuStats.msProcessingDisplayLists * 1000.0f, - gpuStats.numDrawCalls, - gpuStats.numFlushes, - gpuStats.numClears, - gpuStats.numCachedDrawCalls, - gpuStats.numTrackedVertexArrays, - gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, - vertexAverageCycles, - gpuStats.gpuCommandsAtCallLevel[0], gpuStats.gpuCommandsAtCallLevel[1], gpuStats.gpuCommandsAtCallLevel[2], gpuStats.gpuCommandsAtCallLevel[3], - gpuStats.numVertsSubmitted, - gpuStats.numCachedVertsDrawn, - gpuStats.numUncachedVertsDrawn, - (int)framebufferManager_->NumVFBs(), - gpuStats.numFramebufferEvaluations, - (int)textureCacheVulkan_->NumLoadedTextures(), - gpuStats.numTexturesDecoded, - gpuStats.numTextureInvalidations, - gpuStats.numTextureInvalidationsByFramebuffer, - gpuStats.numReadbacks, - gpuStats.numUploads, shaderManagerVulkan_->GetNumVertexShaders(), shaderManagerVulkan_->GetNumFragmentShaders(), pipelineManager_->GetNumPipelines(), From f288e6467908a744e0b28916ac7bf1d9b4f5741f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 21:46:40 +0200 Subject: [PATCH 741/848] Simplify NotifyFrameBuffer - only needs one call for both "channels" now. --- GPU/Common/FramebufferManagerCommon.cpp | 17 ++++----- GPU/Common/TextureCacheCommon.cpp | 47 +++++++++++++------------ GPU/Common/TextureCacheCommon.h | 2 +- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 5776bc4919..466ce77b76 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -449,8 +449,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { // Notify the texture cache of both the color and depth buffers. - textureCache_->NotifyFramebuffer(v, NOTIFY_FB_DESTROYED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(v, NOTIFY_FB_DESTROYED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(v, NOTIFY_FB_DESTROYED); if (v->fbo) { v->fbo->Release(); v->fbo = nullptr; @@ -497,8 +496,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer DownloadFramebufferOnSwitch(currentRenderVfb_); } - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_CREATED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_CREATED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_CREATED); // Ugly... if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { @@ -512,8 +510,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer void FramebufferManagerCommon::NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged) { if (vfbFormatChanged) { - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED); if (vfb->drawnFormat != vfb->format) { ReformatFramebufferFrom(vfb, vfb->drawnFormat); } @@ -581,8 +578,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe } else { if (vfb->fbo) { // This should only happen very briefly when toggling useBufferedRendering_. - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_DESTROYED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_DESTROYED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_DESTROYED); vfb->fbo->Release(); vfb->fbo = nullptr; } @@ -594,8 +590,7 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe gstate_c.skipDrawReason |= SKIPDRAW_NON_DISPLAYED_FB; } } - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_COLOR); - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED, NOTIFY_FB_DEPTH); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_UPDATED); // ugly... is all this needed? if (gstate_c.curRTWidth != vfb->width || gstate_c.curRTHeight != vfb->height) { @@ -1376,7 +1371,7 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd SetColorUpdated(vfb, 0); char name[64]; snprintf(name, sizeof(name), "%08x_color_RAM", vfb->fb_address); - textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_CREATED, NOTIFY_FB_COLOR); + textureCache_->NotifyFramebuffer(vfb, NOTIFY_FB_CREATED); vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, (Draw::FBColorDepth)vfb->colorDepth, name }); vfbs_.push_back(vfb); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 6cfa2d3f66..13913b21f3 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -737,24 +737,21 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c entry->numFrames = 0; } -void TextureCacheCommon::NotifyFramebuffer(VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel) { - // Mask to ignore the Z memory mirrors if the address is in VRAM. - // These checks are mainly to reduce scanning all textures. - +void TextureCacheCommon::NotifyFramebuffer(VirtualFramebuffer *framebuffer, FramebufferNotification msg) { const u32 mirrorMask = 0x00600000; - const u32 address = channel == NOTIFY_FB_COLOR ? framebuffer->fb_address : framebuffer->z_address; - const u32 addr = Memory::IsVRAMAddress(address) ? (address & ~mirrorMask) : address; - const u32 bpp = (framebuffer->format == GE_FORMAT_8888 && channel == NOTIFY_FB_COLOR) ? 4 : 2; - const u32 stride = channel == NOTIFY_FB_COLOR ? framebuffer->fb_stride : framebuffer->z_stride; + const u32 fb_addr = framebuffer->fb_address; + + const u32 z_addr = framebuffer->z_address & ~mirrorMask; // Probably unnecessary. + + const u32 fb_bpp = framebuffer->format == GE_FORMAT_8888 ? 4 : 2; + const u32 z_bpp = 2; // No other format exists. + const u32 fb_stride = framebuffer->fb_stride; + const u32 z_stride = framebuffer->z_stride; // NOTE: Some games like Burnout massively misdetects the height of some framebuffers, leading to a lot of unnecessary invalidations. // Let's only actually get rid of textures that cover the very start of the framebuffer. - const u32 endAddr = addr + stride * std::min((int)framebuffer->height, 16) * bpp; - - const u64 cacheKey = (u64)addr << 32; - // If it has a clut, those are the low 32 bits, so it'll be inside this range. - // Also, if it's a subsample of the buffer, it'll also be within the FBO. - const u64 cacheKeyEnd = (u64)endAddr << 32; + const u32 fb_endAddr = fb_addr + fb_stride * std::min((int)framebuffer->height, 16) * fb_bpp; + const u32 z_endAddr = z_addr + z_stride * std::min((int)framebuffer->height, 16) * z_bpp; switch (msg) { case NOTIFY_FB_CREATED: @@ -765,16 +762,22 @@ void TextureCacheCommon::NotifyFramebuffer(VirtualFramebuffer *framebuffer, Fram std::vector candidates; - // TODO: Rework this to not try to "apply" all matches, only the best one. - if (channel == FramebufferNotificationChannel::NOTIFY_FB_COLOR) { - // Color - no need to look in the mirrors. - for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { - it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; - gpuStats.numTextureInvalidationsByFramebuffer++; - } - } else { + u64 cacheKey = (u64)fb_addr << 32; + // If it has a clut, those are the low 32 bits, so it'll be inside this range. + // Also, if it's a subsample of the buffer, it'll also be within the FBO. + u64 cacheKeyEnd = (u64)fb_endAddr << 32; + + // Color - no need to look in the mirrors. + for (auto it = cache_.lower_bound(cacheKey), end = cache_.upper_bound(cacheKeyEnd); it != end; ++it) { + it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; + gpuStats.numTextureInvalidationsByFramebuffer++; + } + + if (z_stride != 0) { // Depth. Just look at the range, but in each mirror (0x04200000 and 0x04600000). // Games don't use 0x04400000 as far as I know - it has no swizzle effect so kinda useless. + cacheKey = (u64)z_addr << 32; + cacheKeyEnd = (u64)z_endAddr << 32; for (auto it = cache_.lower_bound(cacheKey | 0x200000), end = cache_.upper_bound(cacheKeyEnd | 0x200000); it != end; ++it) { it->second->status |= TexCacheEntry::STATUS_FRAMEBUFFER_OVERLAP; gpuStats.numTextureInvalidationsByFramebuffer++; diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 1241476a0a..4ae14860f8 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -248,7 +248,7 @@ public: // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to, // so that it can invalidate TexCacheEntries pointed at those addresses. - void NotifyFramebuffer(VirtualFramebuffer *framebuffer, FramebufferNotification msg, FramebufferNotificationChannel channel); + void NotifyFramebuffer(VirtualFramebuffer *framebuffer, FramebufferNotification msg); void NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt); size_t NumLoadedTextures() const { From 277333682f2a20095161dd945bb7bde9be3e81cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 22:03:08 +0200 Subject: [PATCH 742/848] GPU debug stats: Show how many bytes of texture data we hash per frame --- GPU/Common/TextureCacheCommon.h | 2 ++ GPU/GPUCommon.cpp | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 4ae14860f8..1b0300724b 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -313,6 +313,8 @@ protected: const u32 sizeInRAM = (textureBitsPerPixel[format] * bufw * h) / 8; const u32 *checkp = (const u32 *)Memory::GetPointer(addr); + gpuStats.numTextureDataBytesHashed += sizeInRAM; + if (Memory::IsValidAddress(addr + sizeInRAM)) { return DoQuickTexHash(checkp, sizeInRAM); } else { diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 620c1b85fc..1a89c9879a 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -2881,23 +2881,20 @@ size_t GPUCommon::FormatGPUStatsCommon(char *buffer, size_t size) { float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f; return snprintf(buffer, size, "DL processing time: %0.2f ms\n" - "Draw calls: %i, flushes %i, clears %i (cached: %d)\n" - "Num Tracked Vertex Arrays: %i\n" - "GPU cycles executed: %d (%f per vertex)\n" + "Draw calls: %d, flushes %d, clears %d (cached: %d)\n" + "Num Tracked Vertex Arrays: %d\n" "Commands per call level: %i %i %i %i\n" - "Vertices submitted: %i\n" - "Cached, Uncached Vertices Drawn: %i, %i\n" - "FBOs active: %i (evaluations: %d)\n" - "Textures active: %i, decoded: %i invalidated: %i\n" - "Readbacks: %d, uploads: %d\n", + "Vertices: %d cached: %d uncached: %d\n" + "FBOs active: %d (evaluations: %d)\n" + "Textures: %d, dec: %d, invalidated: %d, hashed: %d kB\n" + "Readbacks: %d, uploads: %d\n" + "GPU cycles executed: %d (%f per vertex)\n", gpuStats.msProcessingDisplayLists * 1000.0f, gpuStats.numDrawCalls, gpuStats.numFlushes, gpuStats.numClears, gpuStats.numCachedDrawCalls, gpuStats.numTrackedVertexArrays, - gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, - vertexAverageCycles, gpuStats.gpuCommandsAtCallLevel[0], gpuStats.gpuCommandsAtCallLevel[1], gpuStats.gpuCommandsAtCallLevel[2], gpuStats.gpuCommandsAtCallLevel[3], gpuStats.numVertsSubmitted, gpuStats.numCachedVertsDrawn, @@ -2907,7 +2904,10 @@ size_t GPUCommon::FormatGPUStatsCommon(char *buffer, size_t size) { (int)textureCache_->NumLoadedTextures(), gpuStats.numTexturesDecoded, gpuStats.numTextureInvalidations, + gpuStats.numTextureDataBytesHashed / 1024, gpuStats.numReadbacks, - gpuStats.numUploads + gpuStats.numUploads, + gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, + vertexAverageCycles ); } From a840bf9690621769cb397a43ad205ffe953c49ee Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Mon, 21 Sep 2020 06:42:40 +0700 Subject: [PATCH 743/848] Added alerted flags info on AdhocSocket to be used on PollSocket --- Core/HLE/proAdhoc.h | 1 + Core/HLE/sceNetAdhoc.cpp | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 91c898381b..5a711400d0 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -352,6 +352,7 @@ typedef struct SceNetAdhocPtpStat { typedef struct AdhocSocket { s32_le type; // SOCK_PDP/SOCK_PTP s32_le flags; // Socket Alert Flags + s32_le alerted_flags; // Socket Alerted Flags u32 send_timeout; // default connect timeout u32 recv_timeout; // default accept timeout s32 retry_count; // combined with timeout to be used on keepalive diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 3ea9ee359e..31c3f3f3cf 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -349,6 +349,7 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? sock->flags &= ~ADHOC_F_ALERTRECV; + sock->alerted_flags |= ADHOC_F_ALERTRECV; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { // Try again later @@ -394,6 +395,7 @@ int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTa result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? sock->flags &= ~ADHOC_F_ALERTSEND; + sock->alerted_flags |= ADHOC_F_ALERTSEND; break; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { @@ -440,6 +442,7 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? sock->flags &= ~ADHOC_F_ALERTSEND; + sock->alerted_flags |= ADHOC_F_ALERTSEND; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -487,6 +490,7 @@ int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? sock->flags &= ~ADHOC_F_ALERTRECV; + sock->alerted_flags |= ADHOC_F_ALERTRECV; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -536,6 +540,7 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? sock->flags &= ~ADHOC_F_ALERTACCEPT; + sock->alerted_flags |= ADHOC_F_ALERTACCEPT; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -582,6 +587,7 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? sock->flags &= ~ADHOC_F_ALERTCONNECT; + sock->alerted_flags |= ADHOC_F_ALERTCONNECT; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -615,6 +621,7 @@ int DoBlockingPtpFlush(int uid, AdhocSocketRequest& req, s64& result) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? sock->flags &= ~ADHOC_F_ALERTFLUSH; + sock->alerted_flags |= ADHOC_F_ALERTFLUSH; } else if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; @@ -1595,6 +1602,7 @@ int NetAdhoc_SetSocketAlert(int id, s32_le flag) { s32_le flg = flag & ADHOC_F_ALERTALL; adhocSockets[id - 1]->flags = flg; + adhocSockets[id - 1]->alerted_flags = 0; return 0; } @@ -1630,7 +1638,7 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { } if (fd > maxfd) maxfd = fd; if (sds[i].events & ADHOC_EV_RECV) FD_SET(fd, &readfds); - if (sds[i].events & ADHOC_EV_SEND) FD_SET(fd, &writefds); // Does Data can always be sent regardless of events bitmask? + if (sds[i].events & ADHOC_EV_SEND) FD_SET(fd, &writefds); //if (sds[i].events & ADHOC_EV_ALERT) FD_SET(fd, &exceptfds); // Does Alert can be raised on revents regardless of events bitmask? } @@ -1653,16 +1661,17 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout) { if (FD_ISSET(fd, &readfds)) sds[i].revents |= ADHOC_EV_RECV; if (FD_ISSET(fd, &writefds)) - sds[i].revents |= ADHOC_EV_SEND; // Does Data can always be sent regardless of events bitmask? + sds[i].revents |= ADHOC_EV_SEND; + if (FD_ISSET(fd, &exceptfds) || sock->alerted_flags) + sds[i].revents |= ADHOC_EV_ALERT; sds[i].revents &= sds[i].events; - if (FD_ISSET(fd, &exceptfds)) - sds[i].revents |= ADHOC_EV_ALERT; // Does Alert can be raised on revents regardless of events bitmask? if (sds[i].revents) affectedsockets++; if (sock->flags & ADHOC_F_ALERTPOLL) { affectedsockets = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? sock->flags &= ~ADHOC_F_ALERTPOLL; + sock->alerted_flags |= ADHOC_F_ALERTPOLL; break; } } From b6efc65c94c08f31e7bae09e677cceed4f000e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 22:48:35 +0200 Subject: [PATCH 744/848] Set the texture dirty flags when binding a new framebuffer. --- GPU/Common/FramebufferManagerCommon.cpp | 2 +- GPU/D3D11/DrawEngineD3D11.cpp | 2 +- GPU/Directx9/DrawEngineDX9.cpp | 2 +- GPU/GLES/DrawEngineGLES.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 466ce77b76..e0d57f8222 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -705,7 +705,7 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int pixelsTex->Release(); draw_->InvalidateCachedState(); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); } } diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 0c08c49ae0..fbfd4f820f 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -330,7 +330,7 @@ void DrawEngineD3D11::DoFlush() { int curRenderStepId = draw_->GetCurrentStepId(); if (lastRenderStepId_ != curRenderStepId) { // Dirty everything that has dynamic state that will need re-recording. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); lastRenderStepId_ = curRenderStepId; } diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 9c59f01f20..a0f4a8c743 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -315,7 +315,7 @@ void DrawEngineDX9::DoFlush() { int curRenderStepId = draw_->GetCurrentStepId(); if (lastRenderStepId_ != curRenderStepId) { // Dirty everything that has dynamic state that will need re-recording. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); lastRenderStepId_ = curRenderStepId; } diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index c97bf558de..438bef2638 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -315,7 +315,7 @@ void DrawEngineGLES::DoFlush() { int curRenderStepId = render_->GetCurrentStepId(); if (lastRenderStepId_ != curRenderStepId) { // Dirty everything that has dynamic state that will need re-recording. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); textureCache_->ForgetLastTexture(); lastRenderStepId_ = curRenderStepId; } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index f6c07886b3..8123b1275b 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -603,7 +603,8 @@ void DrawEngineVulkan::DoFlush() { int curRenderStepId = renderManager->GetCurrentStepId(); if (lastRenderStepId_ != curRenderStepId) { // Dirty everything that has dynamic state that will need re-recording. - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_BLEND_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); + textureCache_->ForgetLastTexture(); lastRenderStepId_ = curRenderStepId; } From eaca9d1b591b2a85a33b6a2299fe112666683d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 22:52:01 +0200 Subject: [PATCH 745/848] Remove dirtying of TEXTURE_PARAMS from ForgetLastTexture, not its responsibility. --- GPU/Common/FramebufferManagerCommon.cpp | 1 - GPU/D3D11/TextureCacheD3D11.cpp | 1 - GPU/Directx9/TextureCacheDX9.cpp | 1 - GPU/GLES/TextureCacheGLES.h | 1 - GPU/Vulkan/TextureCacheVulkan.h | 1 - 5 files changed, 5 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index e0d57f8222..3f1d7ba6a8 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1797,7 +1797,6 @@ Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u return it->second.fbo; } - textureCache_->ForgetLastTexture(); bool z_stencil = reason == TempFBO::STENCIL; char name[128]; snprintf(name, sizeof(name), "temp_fbo_%dx%d%s", w, h, z_stencil ? "_depth" : ""); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 3a9dbda64a..ffbf31b6e1 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -144,7 +144,6 @@ void TextureCacheD3D11::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { void TextureCacheD3D11::ForgetLastTexture() { InvalidateLastTexture(); - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); ID3D11ShaderResourceView *nullTex[2]{}; context_->PSSetShaderResources(0, 2, nullTex); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 56bd153bef..c232247f28 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -94,7 +94,6 @@ void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { void TextureCacheDX9::ForgetLastTexture() { InvalidateLastTexture(); - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } void TextureCacheDX9::InvalidateLastTexture() { diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index e196a358dc..81679c8953 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -55,7 +55,6 @@ public: void ForgetLastTexture() override { lastBoundTexture = nullptr; - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } void InvalidateLastTexture() override { lastBoundTexture = nullptr; diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index 8622b5d974..edafdf894a 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -85,7 +85,6 @@ public: void ForgetLastTexture() override { lastBoundTexture = nullptr; - gstate_c.Dirty(DIRTY_TEXTURE_PARAMS); } void InvalidateLastTexture() override { From dcd33a4692bd5af971aad6e35dae6303d51e3386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 23:22:54 +0200 Subject: [PATCH 746/848] Remove redundant bind on GL texture build. Improve dirtying of texture state. --- GPU/Common/TextureCacheCommon.cpp | 1 + GPU/D3D11/StencilBufferD3D11.cpp | 2 +- GPU/Directx9/StencilBufferDX9.cpp | 3 +-- GPU/Directx9/TextureCacheDX9.cpp | 4 ---- GPU/Directx9/TextureCacheDX9.h | 4 +++- GPU/GLES/DepthBufferGLES.cpp | 5 +++-- GPU/GLES/StencilBufferGLES.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 10 ---------- GPU/GLES/TextureCacheGLES.h | 2 +- GPU/Vulkan/StencilBufferVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 3 --- 11 files changed, 12 insertions(+), 26 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 13913b21f3..ff667ca800 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -1644,6 +1644,7 @@ void TextureCacheCommon::ApplyTexture() { if (nextNeedsRebuild_) { _assert_(!entry->texturePtr); BuildTexture(entry); + InvalidateLastTexture(); } entry->lastFrame = gpuStats.numFlips; diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index d4b6dc164e..5c988d7e61 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -199,7 +199,6 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, StencilUpl context_->IASetVertexBuffers(0, 1, &quadBuffer_, &quadStride_, &quadOffset_); context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DClamp); context_->OMSetDepthStencilState(stockD3D11.depthDisabledStencilWrite, 0xFF); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE); for (int i = 1; i < values; i += i) { if (!(usedBits & i)) { @@ -244,5 +243,6 @@ bool FramebufferManagerD3D11::NotifyStencilUpload(u32 addr, int size, StencilUpl tex->Release(); RebindFramebuffer("RebindFramebuffer stencil"); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); return true; } diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 4310a1654e..baa173adeb 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -185,7 +185,6 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa dxstate.colorMask.set(false, false, false, true); dxstate.stencilTest.enable(); dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE); u16 w = dstBuffer->renderWidth; u16 h = dstBuffer->renderHeight; @@ -197,7 +196,6 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa } D3DVIEWPORT9 vp{ 0, 0, w, h, 0.0f, 1.0f }; device_->SetViewport(&vp); - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); float u1 = 1.0f; float v1 = 1.0f; @@ -255,6 +253,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, StencilUploa dxstate.stencilMask.set(0xFF); dxstate.viewport.restore(); RebindFramebuffer("RebindFramebuffer stencil"); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); return true; } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index c232247f28..49b87913a6 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -92,10 +92,6 @@ void TextureCacheDX9::ReleaseTexture(TexCacheEntry *entry, bool delete_them) { } } -void TextureCacheDX9::ForgetLastTexture() { - InvalidateLastTexture(); -} - void TextureCacheDX9::InvalidateLastTexture() { lastBoundTexture = INVALID_TEX; } diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index 1ebf3bb5fc..aa57dcba4b 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -49,7 +49,9 @@ public: shaderManager_ = sm; } - void ForgetLastTexture() override; + void ForgetLastTexture() override { + InvalidateLastTexture(); + } void InvalidateLastTexture() override; bool GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level) override; diff --git a/GPU/GLES/DepthBufferGLES.cpp b/GPU/GLES/DepthBufferGLES.cpp index 13ec48128c..66a83b972f 100644 --- a/GPU/GLES/DepthBufferGLES.cpp +++ b/GPU/GLES/DepthBufferGLES.cpp @@ -129,7 +129,6 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int auto *blitFBO = GetTempFBO(TempFBO::COPY, vfb->renderWidth, vfb->renderHeight, Draw::FBO_8888); draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }, "PackDepthbuffer"); render_->SetViewport({ 0, 0, (float)vfb->renderWidth, (float)vfb->renderHeight, 0.0f, 1.0f }); - textureCacheGL_->ForgetLastTexture(); // We must bind the program after starting the render pass, and set the color mask after clearing. render_->SetScissor({ 0, 0, vfb->renderWidth, vfb->renderHeight }); @@ -156,6 +155,8 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int DrawActiveTexture(x, y, w, h, vfb->renderWidth, vfb->renderHeight, 0.0f, 0.0f, u1, v1, ROTATION_LOCKED_HORIZONTAL, DRAWTEX_NEAREST); draw_->CopyFramebufferToMemorySync(blitFBO, Draw::FB_COLOR_BIT, 0, y, packWidth, h, Draw::DataFormat::R8G8B8A8_UNORM, convBuf_, vfb->z_stride, "PackDepthbuffer"); + + textureCacheGL_->ForgetLastTexture(); // TODO: Use 4444 so we can copy lines directly? format16Bit = true; } else { @@ -197,5 +198,5 @@ void FramebufferManagerGLES::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int } } - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); } diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index d9e7fadbf1..dce997ae81 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -218,7 +218,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, StencilUplo } tex->Release(); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); RebindFramebuffer("RebindFramebuffer - Stencil"); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); return true; } diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index ba953676d4..e3bb89094e 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -47,7 +47,6 @@ TextureCacheGLES::TextureCacheGLES(Draw::DrawContext *draw) : TextureCacheCommon(draw) { timesInvalidatedAllThisFrame_ = 0; - lastBoundTexture = nullptr; render_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); SetupTextureDecoder(); @@ -537,8 +536,6 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) { texelsScaledThisFrame_ += w * h; } } - - lastBoundTexture = entry->textureName; // GLES2 doesn't have support for a "Max lod" which is critical as PSP games often // don't specify mips all the way down. As a result, we either need to manually generate @@ -595,13 +592,6 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry) { } render_->FinalizeTexture(entry->textureName, texMaxLevel, genMips); - - // This will rebind it, but that's okay. - // Need to actually bind it now - it might only have gotten bound in the init phase. - render_->BindTexture(TEX_SLOT_PSP_TEXTURE, entry->textureName); - - SamplerCacheKey samplerKey = GetSamplingParams(entry->maxLevel, entry->addr); - ApplySamplingParams(samplerKey); } Draw::DataFormat TextureCacheGLES::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const { diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index 81679c8953..f148fd3f68 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -85,7 +85,7 @@ private: TextureScalerGLES scaler; - GLRTexture *lastBoundTexture; + GLRTexture *lastBoundTexture = nullptr; FramebufferManagerGLES *framebufferManagerGL_; DepalShaderCacheGLES *depalShaderCache_; diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 5862ece18f..613401545f 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -183,7 +183,6 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp renderManager->BindPipeline(pipeline); renderManager->SetViewport({ 0.0f, 0.0f, (float)w, (float)h, 0.0f, 1.0f }); renderManager->SetScissor({ { 0, 0, },{ (uint32_t)w, (uint32_t)h } }); - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE); draw_->BindTextures(0, 1, &tex); VkImageView drawPixelsImageView = (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE0_IMAGEVIEW); @@ -225,5 +224,6 @@ bool FramebufferManagerVulkan::NotifyStencilUpload(u32 addr, int size, StencilUp tex->Release(); RebindFramebuffer("RebindFramebuffer - NotifyStencilUpload"); + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS); return true; } diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index c33e6c73c4..90c08512f5 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -872,7 +872,6 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { entry->vkTex = nullptr; } } - lastBoundTexture = entry->vkTex; ReplacedTextureDecodeInfo replacedInfo; if (replacer_.Enabled() && !replaced.Valid()) { @@ -997,8 +996,6 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { } entry->vkTex->EndCreate(cmdInit, false, computeUpload ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); } - - gstate_c.SetTextureFullAlpha(entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL); } VkFormat TextureCacheVulkan::GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const { From beb1d3f715dffb7c6218613297ba50402b8a0349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 23:37:44 +0200 Subject: [PATCH 747/848] Cleanups in/around BlitFramebufferDepth --- GPU/Common/FramebufferManagerCommon.cpp | 31 ++++++++++++------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 3f1d7ba6a8..a281bbd5f6 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -469,23 +469,18 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { } void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; + int w = std::min(src->renderWidth, dst->renderWidth); + int h = std::min(src->renderHeight, dst->renderHeight); - // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. - if (matchingDepthBuffer && matchingSize) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // Let's only do this if not clearing depth. - if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); - RebindFramebuffer("BlitFramebufferDepth"); - } else if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) { - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer("BlitFramebufferDepth"); - } - dst->last_frame_depth_updated = gpuStats.numFlips; + // Note: We prefer Blit ahead of Copy here, since at least on GL, Copy will always also copy stencil which we don't want. See #9740. + if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { + draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + } else if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) { + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); } + dst->last_frame_depth_updated = gpuStats.numFlips; } void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) { @@ -546,7 +541,11 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe // If depth wasn't updated, then we're at least "two degrees" away from the data. // This is an optimization: it probably doesn't need to be copied in this case. } else { - BlitFramebufferDepth(prevVfb, vfb); + bool matchingDepthBuffer = prevVfb->z_address == vfb->z_address && prevVfb->z_stride != 0 && vfb->z_stride != 0; + bool matchingSize = prevVfb->width == vfb->width && prevVfb->height == vfb->height; + if (matchingDepthBuffer && matchingSize) { + BlitFramebufferDepth(prevVfb, vfb); + } } } if (vfb->drawnFormat != vfb->format) { From 45f8b2721e3dc645d0665acfbfd1a2992d60626b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 23:46:53 +0200 Subject: [PATCH 748/848] Comment fixes. Minor tweak. --- GPU/Common/TextureCacheCommon.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index ff667ca800..437cf14084 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -338,13 +338,11 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { GETextureFormat format = gstate.getTextureFormat(); if (format >= 11) { - ERROR_LOG_REPORT(G3D, "Unknown texture format %i", format); - // TODO: Better assumption? + // TODO: Better assumption? Doesn't really matter, these are invalid. format = GE_TFMT_5650; } - bool hasClut = gstate.isTextureFormatIndexed(); - // Ignore uncached/kernel when caching. + bool hasClut = gstate.isTextureFormatIndexed(); u32 cluthash; if (hasClut) { if (clutLastFormat_ != gstate.clutformat) { @@ -446,7 +444,6 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { } if (match) { - // TODO: Mark the entry reliable if it's been safe for long enough? // got one! gstate_c.curTextureWidth = w; gstate_c.curTextureHeight = h; @@ -1589,9 +1586,9 @@ void TextureCacheCommon::ApplyTexture() { TexCacheEntry *entry = nextTexture_; if (!entry) { // Maybe we bound a framebuffer? + InvalidateLastTexture(); if (nextFramebufferTexture_) { bool depth = Memory::IsDepthTexVRAMAddress(gstate.getTextureAddress(0)); - InvalidateLastTexture(); ApplyTextureFramebuffer(nextFramebufferTexture_, gstate.getTextureFormat(), depth ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR); nextFramebufferTexture_ = nullptr; } From ea2d2ec434b27e8e9d311118a2fce8502b9a783b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 20 Sep 2020 23:57:43 +0200 Subject: [PATCH 749/848] Remove unused lastBoundTexture from Vulkan --- GPU/Common/TextureCacheCommon.cpp | 1 + GPU/Vulkan/TextureCacheVulkan.h | 11 ++--------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 437cf14084..35b15f97db 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -1589,6 +1589,7 @@ void TextureCacheCommon::ApplyTexture() { InvalidateLastTexture(); if (nextFramebufferTexture_) { bool depth = Memory::IsDepthTexVRAMAddress(gstate.getTextureAddress(0)); + // ApplyTextureFrameBuffer is responsible for setting SetTextureFullAlpha. ApplyTextureFramebuffer(nextFramebufferTexture_, gstate.getTextureFormat(), depth ? NOTIFY_FB_DEPTH : NOTIFY_FB_COLOR); nextFramebufferTexture_ = nullptr; } diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index edafdf894a..d0d9014508 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -83,13 +83,8 @@ public: push_ = push; } - void ForgetLastTexture() override { - lastBoundTexture = nullptr; - } - - void InvalidateLastTexture() override { - lastBoundTexture = nullptr; - } + void ForgetLastTexture() override {} + void InvalidateLastTexture() override {} void NotifyConfigChanged() override; @@ -133,8 +128,6 @@ private: TextureScalerVulkan scaler; - VulkanTexture *lastBoundTexture = nullptr; - int decimationCounter_ = 0; int texelsScaledThisFrame_ = 0; int timesInvalidatedAllThisFrame_ = 0; From 1faa24f82255b5500729ebf95d9fed346e82c6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 21 Sep 2020 09:23:30 +0200 Subject: [PATCH 750/848] Update submodule ffmpeg to master --- ffmpeg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg b/ffmpeg index 55147e5f33..d3e695286c 160000 --- a/ffmpeg +++ b/ffmpeg @@ -1 +1 @@ -Subproject commit 55147e5f33f5ae4904f75ec082af809267122b94 +Subproject commit d3e695286cce346274192c214c00f021c00cd575 From 2d067307620142d4369e5133bff63762b60ffd0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 21 Sep 2020 09:56:52 +0200 Subject: [PATCH 751/848] Fix regression where Gran Turismo ended up recreating the framebuffer on every frame in the menu. Should help #13458 slightly (but there's more to fix). --- Core/Util/BlockAllocator.cpp | 6 +++--- GPU/Common/FramebufferManagerCommon.cpp | 17 ++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Core/Util/BlockAllocator.cpp b/Core/Util/BlockAllocator.cpp index c302d8e91b..7dfa4637ba 100644 --- a/Core/Util/BlockAllocator.cpp +++ b/Core/Util/BlockAllocator.cpp @@ -390,13 +390,13 @@ u32 BlockAllocator::GetBlockSizeFromAddress(u32 addr) const void BlockAllocator::ListBlocks() const { - INFO_LOG(SCEKERNEL,"-----------"); + DEBUG_LOG(SCEKERNEL,"-----------"); for (const Block *bp = bottom_; bp != NULL; bp = bp->next) { const Block &b = *bp; - INFO_LOG(SCEKERNEL, "Block: %08x - %08x size %08x taken=%i tag=%s", b.start, b.start+b.size, b.size, b.taken ? 1:0, b.tag); + DEBUG_LOG(SCEKERNEL, "Block: %08x - %08x size %08x taken=%i tag=%s", b.start, b.start+b.size, b.size, b.taken ? 1:0, b.tag); } - INFO_LOG(SCEKERNEL,"-----------"); + DEBUG_LOG(SCEKERNEL,"-----------"); } u32 BlockAllocator::GetLargestFreeBlockSize() const diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 466ce77b76..39b2652c8a 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -205,6 +205,13 @@ void GetFramebufferHeuristicInputs(FramebufferHeuristicParams *params, const GPU params->z_address = (gstate.getDepthBufRawAddress() & 0x3FFFFFFF) | 0x04000000; params->z_stride = gstate.DepthBufStride(); + if (params->z_address == params->fb_address) { + // Probably indicates that the game doesn't care about Z for this VFB. + // Let's avoid matching it for Z copies and other shenanigans. + params->z_address = 0; + params->z_stride = 0; + } + params->fmt = gstate.FrameBufFormat(); params->isClearingDepth = gstate.isModeClear() && gstate.isClearModeDepthMask(); @@ -265,7 +272,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame vfb->format = params.fmt; } - if (vfb->z_address == 0 && vfb->z_stride == 0) { + if (vfb->z_address == 0 && vfb->z_stride == 0 && params.z_stride != 0) { // Got one that was created by CreateRAMFramebuffer. Since it has no depth buffer, // we just recreate it immediately. ResizeFramebufFBO(vfb, vfb->width, vfb->height, true); @@ -347,14 +354,6 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame vfb->fb_stride = params.fb_stride; vfb->z_address = params.z_address; vfb->z_stride = params.z_stride; - - if (vfb->z_address == vfb->fb_address) { - // Probably indicates that the game doesn't care about Z for this VFB. - // Let's avoid matching it for Z copies. - vfb->z_address = 0; - vfb->z_stride = 0; - } - vfb->width = drawing_width; vfb->height = drawing_height; vfb->newWidth = drawing_width; From 8192f5174c23a129dadfac6ae3d78aad1e583cd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 21 Sep 2020 10:31:14 +0200 Subject: [PATCH 752/848] Quick fix for #13459 --- GPU/Vulkan/VulkanUtil.cpp | 4 +++- GPU/Vulkan/VulkanUtil.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index 9a65aa750c..6d59ba6a1a 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -463,7 +463,9 @@ void VulkanComputeShaderManager::InitDeviceObjects() { void VulkanComputeShaderManager::DestroyDeviceObjects() { for (int i = 0; i < ARRAY_SIZE(frameData_); i++) { - vulkan_->Delete().QueueDeleteDescriptorPool(frameData_[i].descPool); + if (frameData_[i].descPool) { + vulkan_->Delete().QueueDeleteDescriptorPool(frameData_[i].descPool); + } } if (descriptorSetLayout_) { vulkan_->Delete().QueueDeleteDescriptorSetLayout(descriptorSetLayout_); diff --git a/GPU/Vulkan/VulkanUtil.h b/GPU/Vulkan/VulkanUtil.h index 53fd2ff858..44d4cf6be0 100644 --- a/GPU/Vulkan/VulkanUtil.h +++ b/GPU/Vulkan/VulkanUtil.h @@ -163,7 +163,7 @@ private: VkDescriptorPool descPool; int numDescriptors; }; - FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES]; + FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES]{}; struct PipelineKey { VkShaderModule module; From e642f1b846d469a46229f659ebccccd43ad17e07 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 22 Sep 2020 09:50:37 +0700 Subject: [PATCH 753/848] Fixed returned error code of sceNetAdhocctlDisconnect --- Core/HLE/sceNetAdhoc.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 31c3f3f3cf..f96d7839eb 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2063,6 +2063,11 @@ u32 NetAdhocctl_Disconnect() { AdhocctlRequest req = { OPCODE_DISCONNECT, {0} }; WaitAdhocctlState(req, ADHOCCTL_STATE_DISCONNECTED, us, "adhocctl disconnect"); } + else { + // Set Disconnected State + //adhocctlState = ADHOCCTL_STATE_DISCONNECTED; + return ERROR_NET_ADHOCCTL_BUSY; + } } // Free Network Lock @@ -2094,23 +2099,21 @@ u32 NetAdhocctl_Disconnect() { //hleCheckCurrentCallbacks(); // Return Success, some games might ignore returned value and always treat it as success, otherwise repeatedly calling this function - if (adhocctlState == ADHOCCTL_STATE_DISCONNECTED || iResult != SOCKET_ERROR) - hleDelayResult(0, "give time to init/cleanup", us); - return 0; } // Library uninitialized - return 0; //ERROR_NET_ADHOC_NOT_INITIALIZED; // Wipeout Pulse will repeatedly calling this function if returned value is ERROR_NET_ADHOC_NOT_INITIALIZED + return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; } static u32 sceNetAdhocctlDisconnect() { // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? char grpName[9] = { 0 }; memcpy(grpName, parameter.group_name.data, ADHOCCTL_GROUPNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs - INFO_LOG(SCENET, "sceNetAdhocctlDisconnect() at %08x [group=%s]", currentMIPS->pc, grpName); + int ret = NetAdhocctl_Disconnect(); + INFO_LOG(SCENET, "%08x=sceNetAdhocctlDisconnect() at %08x [group=%s]", ret, currentMIPS->pc, grpName); - return NetAdhocctl_Disconnect(); + return ret; } static u32 sceNetAdhocctlDelHandler(u32 handlerID) { From 4881f4f0bd0110af5cceeba8dc70f90d0e8d0978 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Tue, 22 Sep 2020 09:51:59 +0700 Subject: [PATCH 754/848] Fixed PdpStat and PtpStat info --- Core/HLE/proAdhoc.cpp | 14 ++++++++++++-- Core/HLE/proAdhoc.h | 15 ++++++++++----- Core/HLE/sceNetAdhoc.cpp | 29 ++++++++++++----------------- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 1875ff8dd9..a769c81937 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1867,8 +1867,18 @@ uint16_t getLocalPort(int sock) { return ntohs(localAddr.sin_port); } +u_long getAvailToRecv(int sock) { + u_long n = 0; // Typical MTU size is 1500 +#if defined(_WIN32) // May not be available on all platform + ioctlsocket(sock, FIONREAD, &n); +#else + ioctl(sock, FIONREAD, &n); +#endif + return n; +} + int getSockMaxSize(int udpsock) { - int n = 1500; // Typical MTU size as default + int n = PSP_ADHOC_PDP_MTU; // Typical MTU size is 1500 #if defined(SO_MAX_MSG_SIZE) // May not be available on all platform socklen_t m = sizeof(n); getsockopt(udpsock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*)&n, &m); @@ -1877,7 +1887,7 @@ int getSockMaxSize(int udpsock) { } int getSockBufferSize(int sock, int opt) { // opt = SO_RCVBUF/SO_SNDBUF - int n = 16384; + int n = PSP_ADHOC_PDP_MFS; // 16384; socklen_t m = sizeof(n); getsockopt(sock, SOL_SOCKET, opt, (char *)&n, &m); // in linux the value is twice of the value being set using setsockopt return (n/2); diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 5a711400d0..53348b115c 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -329,22 +329,22 @@ typedef struct SceNetAdhocPollSd{ // PDP Socket Status typedef struct SceNetAdhocPdpStat { u32_le next; - s32_le id; + s32_le id; // posix socket id SceNetEtherAddr laddr; u16_le lport; - u32_le rcv_sb_cc; + u32_le rcv_sb_cc; // Obscure The Aftermath will check if this is 0 or not before calling PdpRecv, Might to be number of bytes available to be Received? } PACK SceNetAdhocPdpStat; // PTP Socket Status typedef struct SceNetAdhocPtpStat { u32_le next; // Changed the pointer to u32 - s32_le id; + s32_le id; // posix socket id SceNetEtherAddr laddr; SceNetEtherAddr paddr; u16_le lport; u16_le pport; - s32_le snd_sb_cc; - s32_le rcv_sb_cc; + s32_le snd_sb_cc; // Number of bytes existed in buffer to be sent/flushed? + s32_le rcv_sb_cc; // Number of bytes available in buffer to be received? s32_le state; } PACK SceNetAdhocPtpStat; @@ -1235,6 +1235,11 @@ uint32_t getLocalIp(int sock); */ bool isPrivateIP(uint32_t ip); +/* + * Get Number of bytes available in buffer to be Received + */ +u_long getAvailToRecv(int sock); + /* * Get UDP Socket Max Message Size */ diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index f96d7839eb..2b033b8d00 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1051,9 +1051,9 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u int usocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Valid Socket produced if (usocket != INVALID_SOCKET) { - // Change socket buffer size when necessary - if (getSockBufferSize(usocket, SO_SNDBUF) < bufferSize) setSockBufferSize(usocket, SO_SNDBUF, bufferSize); - if (getSockBufferSize(usocket, SO_RCVBUF) < bufferSize) setSockBufferSize(usocket, SO_RCVBUF, bufferSize); + // Change socket buffer size, unlike TCP, UDP need to be Received in full size to prevent leftover data getting discarded/lost, so we need to use the exact buffer size the game want/expects. + setSockBufferSize(usocket, SO_SNDBUF, bufferSize); + setSockBufferSize(usocket, SO_RCVBUF, bufferSize); // Enable KeepAlive setSockKeepAlive(usocket, true); @@ -1106,7 +1106,6 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u internal->data.pdp.id = usocket; internal->data.pdp.laddr = *saddr; internal->data.pdp.lport = port; //getLocalPort(usocket) - portOffset; - internal->data.pdp.rcv_sb_cc = bufferSize; // Link Socket to Translator ID adhocSockets[i] = internal; @@ -1239,8 +1238,6 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int if (timeout > 0) setSockTimeout(pdpsocket.id, SO_SNDTIMEO, timeout); - int maxlen = getSockMaxSize(pdpsocket.id); - // Single Target if (!isBroadcastMAC(daddr)) { // Fill in Target Structure @@ -2651,6 +2648,9 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { // Fix Client View Socket ID buf[i].id = j + 1; + // Set available bytes to be received + buf[i].rcv_sb_cc = getAvailToRecv(sock->data.pdp.id); + // Write End of List Reference buf[i].next = 0; @@ -2727,6 +2727,9 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Fix Client View Socket ID buf[i].id = j + 1; + + // Set available bytes to be received + buf[i].rcv_sb_cc = getAvailToRecv(sock->data.ptp.id); // Write End of List Reference buf[i].next = 0; @@ -2864,9 +2867,6 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, internal->data.ptp.lport = sport; internal->data.ptp.pport = dport; - // Set Buffer Size - internal->data.ptp.rcv_sb_cc = bufsize; - // Link PTP Socket adhocSockets[i] = internal; @@ -2961,11 +2961,9 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther // Copy Socket Descriptor to Structure internal->data.ptp.id = newsocket; - // Set Buffer Size - if (getSockBufferSize(newsocket, SO_RCVBUF) < ptpsocket.rcv_sb_cc) setSockBufferSize(newsocket, SO_RCVBUF, ptpsocket.rcv_sb_cc); - if (getSockBufferSize(newsocket, SO_SNDBUF) < ptpsocket.snd_sb_cc) setSockBufferSize(newsocket, SO_SNDBUF, ptpsocket.snd_sb_cc); - internal->data.ptp.rcv_sb_cc = ptpsocket.rcv_sb_cc; - internal->data.ptp.snd_sb_cc = ptpsocket.snd_sb_cc; + // Set Default Buffer Size + if (getSockBufferSize(newsocket, SO_RCVBUF) < PSP_ADHOC_PTP_MSS) setSockBufferSize(newsocket, SO_RCVBUF, PSP_ADHOC_PTP_MSS); + if (getSockBufferSize(newsocket, SO_SNDBUF) < PSP_ADHOC_PTP_MSS) setSockBufferSize(newsocket, SO_SNDBUF, PSP_ADHOC_PTP_MSS); // Copy Local Address Data to Structure getLocalMac(&internal->data.ptp.laddr); @@ -3376,9 +3374,6 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Flag Socket as Listener internal->data.ptp.state = ADHOC_PTP_STATE_LISTEN; - // Set Buffer Size - internal->data.ptp.rcv_sb_cc = bufsize; - // Link PTP Socket adhocSockets[i] = internal; From 437818aa450f6362ae016d22c941339574dc6a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 22 Sep 2020 21:12:45 +0200 Subject: [PATCH 755/848] Minor optimization in wrap_text.cpp --- ext/native/util/text/wrap_text.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/native/util/text/wrap_text.cpp b/ext/native/util/text/wrap_text.cpp index c052056034..68ca6d7b5a 100644 --- a/ext/native/util/text/wrap_text.cpp +++ b/ext/native/util/text/wrap_text.cpp @@ -143,6 +143,10 @@ void WordWrapper::Wrap() { // First, let's check if it fits as-is. size_t len = strlen(str_); + + // We know it'll be approximately this size. It's fine if the guess is a little off. + out_.reserve(len + len / 16); + if (MeasureWidth(str_, len) <= maxW_) { // If it fits, we don't need to go through each character. out_ = str_; From 3e3a40da8c804bd0a5f6572878cefff3254fafb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 22 Sep 2020 21:13:30 +0200 Subject: [PATCH 756/848] Mark the PPGe font texture as reliable to avoid hashing it. --- Core/MemMap.h | 4 ++++ GPU/Common/TextureCacheCommon.cpp | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Core/MemMap.h b/Core/MemMap.h index d0cac9f082..7383b719ea 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -261,6 +261,10 @@ inline bool IsVRAMAddress(const u32 address) { inline bool IsDepthTexVRAMAddress(const u32 address) { return ((address & 0x3FE00000) == 0x04200000) || ((address & 0x3FE00000) == 0x04600000); } +inline bool IsKernelAddress(const u32 address) { + return ((address & 0x3F800000) == 0x08000000); +} + bool IsScratchpadAddress(const u32 address); // Used for auto-converted char * parameters, which can sometimes legitimately be null - diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 35b15f97db..6abc0ed30d 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -506,7 +506,10 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { } entry = entryNew; - if (g_Config.bTextureBackoffCache) { + if (Memory::IsKernelAddress(texaddr)) { + // It's the builtin font texture. + entry->status = TexCacheEntry::STATUS_RELIABLE; + } else if (g_Config.bTextureBackoffCache) { entry->status = TexCacheEntry::STATUS_HASHING; } else { entry->status = TexCacheEntry::STATUS_UNRELIABLE; @@ -707,7 +710,8 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c ReleaseTexture(entry, true); entry->status &= ~TexCacheEntry::STATUS_IS_SCALED; } - // Clear the reliable bit if set. + + // Mark as hashing, if marked as reliable. if (entry->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) { entry->SetHashStatus(TexCacheEntry::STATUS_HASHING); } @@ -723,7 +727,6 @@ void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const c } } - entry->status |= TexCacheEntry::STATUS_UNRELIABLE; if (entry->numFrames < TEXCACHE_FRAME_CHANGE_FREQUENT) { if (entry->status & TexCacheEntry::STATUS_FREE_CHANGE) { entry->status &= ~TexCacheEntry::STATUS_FREE_CHANGE; From 5ac6a9b3fdc76277603e43ecf79d484a652e4b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 22 Sep 2020 21:24:16 +0200 Subject: [PATCH 757/848] Fix slowdowns due to careless use of auto --- GPU/Common/TextureCacheCommon.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 6abc0ed30d..56b8508522 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -571,10 +571,9 @@ std::vector TextureCacheCommon::GetFramebufferCandidates(const FramebufferNotificationChannel channel = Memory::IsDepthTexVRAMAddress(entry.addr) ? FramebufferNotificationChannel::NOTIFY_FB_DEPTH : FramebufferNotificationChannel::NOTIFY_FB_COLOR; - auto framebuffers = framebufferManager_->Framebuffers(); + const std::vector &framebuffers = framebufferManager_->Framebuffers(); - for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { - auto framebuffer = framebuffers[i]; + for (VirtualFramebuffer *framebuffer : framebuffers) { FramebufferMatchInfo match = MatchFramebuffer(entry, framebuffer, texAddrOffset, channel); switch (match.match) { case FramebufferMatch::VALID: @@ -1076,9 +1075,8 @@ void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) { static const u32 MAX_CLUT_OFFSET = 4096; clutRenderOffset_ = MAX_CLUT_OFFSET; - auto framebuffers = framebufferManager_->Framebuffers(); - for (size_t i = 0, n = framebuffers.size(); i < n; ++i) { - auto framebuffer = framebuffers[i]; + const std::vector &framebuffers = framebufferManager_->Framebuffers(); + for (VirtualFramebuffer *framebuffer : framebuffers) { const u32 fb_address = framebuffer->fb_address & 0x3FFFFFFF; const u32 bpp = framebuffer->drawnFormat == GE_FORMAT_8888 ? 4 : 2; u32 offset = clutFramebufAddr - fb_address; From cea7c1b6bbec4e31ac856051c6b6e740b53ce103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 22 Sep 2020 21:29:01 +0200 Subject: [PATCH 758/848] Remove an allocation in the word wrapper. --- ext/native/util/text/wrap_text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/native/util/text/wrap_text.cpp b/ext/native/util/text/wrap_text.cpp index 68ca6d7b5a..6f829b4163 100644 --- a/ext/native/util/text/wrap_text.cpp +++ b/ext/native/util/text/wrap_text.cpp @@ -130,8 +130,8 @@ void WordWrapper::AppendWord(int endIndex, bool addNewline) { scanForNewline_ = false; } else { // We may have appended a newline - check. - size_t pos = out_.substr(lastLineStart_).find_last_of("\n"); - if (pos != out_.npos) { + size_t pos = out_.find_last_of("\n"); + if (pos != out_.npos && pos >= lastLineStart_) { lastLineStart_ += pos; } } From b8ab04f53db9c0f5867e474c84b174a5f9923a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 22 Sep 2020 21:57:51 +0200 Subject: [PATCH 759/848] Remove some reporting that's normally just the result of garbage-as-display-list-execution. --- GPU/GPUCommon.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 1a89c9879a..336c359476 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1231,7 +1231,7 @@ void GPUCommon::Execute_Origin(u32 op, u32 diff) { void GPUCommon::Execute_Jump(u32 op, u32 diff) { const u32 target = gstate_c.getRelativeAddress(op & 0x00FFFFFC); if (!Memory::IsValidAddress(target)) { - ERROR_LOG_REPORT(G3D, "JUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); + ERROR_LOG(G3D, "JUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); UpdateState(GPUSTATE_ERROR); return; } @@ -1253,7 +1253,7 @@ void GPUCommon::Execute_BJump(u32 op, u32 diff) { UpdatePC(currentList->pc, target - 4); currentList->pc = target - 4; // pc will be increased after we return, counteract that } else { - ERROR_LOG_REPORT(G3D, "BJUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); + ERROR_LOG(G3D, "BJUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); UpdateState(GPUSTATE_ERROR); } } @@ -1264,7 +1264,7 @@ void GPUCommon::Execute_Call(u32 op, u32 diff) { const u32 target = gstate_c.getRelativeAddress(op & 0x00FFFFFC); if (!Memory::IsValidAddress(target)) { - ERROR_LOG_REPORT(G3D, "CALL to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); + ERROR_LOG(G3D, "CALL to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF); UpdateState(GPUSTATE_ERROR); return; } @@ -1297,7 +1297,7 @@ void GPUCommon::DoExecuteCall(u32 target) { } if (currentList->stackptr == ARRAY_SIZE(currentList->stack)) { - ERROR_LOG_REPORT(G3D, "CALL: Stack full!"); + ERROR_LOG(G3D, "CALL: Stack full!"); } else { auto &stackEntry = currentList->stack[currentList->stackptr++]; stackEntry.pc = retval; @@ -1310,7 +1310,7 @@ void GPUCommon::DoExecuteCall(u32 target) { void GPUCommon::Execute_Ret(u32 op, u32 diff) { if (currentList->stackptr == 0) { - DEBUG_LOG_REPORT(G3D, "RET: Stack empty!"); + DEBUG_LOG(G3D, "RET: Stack empty!"); } else { auto &stackEntry = currentList->stack[--currentList->stackptr]; gstate_c.offsetAddr = stackEntry.offsetAddr; From 4f76f2415d07118f5a7b168bdf2d618df16eb6b8 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 23 Sep 2020 02:10:12 +0700 Subject: [PATCH 760/848] Prevent sceNetGetMallocStat from spamming debug log on some games. --- Core/HLE/sceNet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index a0cd41f6ca..6750c94750 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -712,7 +712,7 @@ static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) { // Write static data since we don't actually manage any memory for sceNet* yet. static int sceNetGetMallocStat(u32 statPtr) { - DEBUG_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x)", statPtr); + VERBOSE_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x)", statPtr); if(Memory::IsValidAddress(statPtr)) Memory::WriteStruct(statPtr, &netMallocStat); else From bd37d3e32c17be06d3c0ca3c2eb61100524de58f Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 23 Sep 2020 02:12:41 +0700 Subject: [PATCH 761/848] Added more info on some sceNet logs --- Core/HLE/sceNetAdhoc.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 2b033b8d00..7440ec828f 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1005,11 +1005,12 @@ int sceNetAdhocctlGetState(u32 ptrToStatus) { if (!Memory::IsValidAddress(ptrToStatus)) return ERROR_NET_ADHOCCTL_INVALID_ARG; - // Return Thread Status - Memory::Write_U32(NetAdhocctl_GetState(), ptrToStatus); - // Return Success - return hleLogSuccessVerboseI(SCENET, 0); + int state = NetAdhocctl_GetState(); + // Output Adhocctl State + Memory::Write_U32(state, ptrToStatus); + // Return Success + return hleLogSuccessVerboseI(SCENET, 0, "state = %d", state); } /** @@ -2603,7 +2604,7 @@ int sceNetAdhocTerm() { } static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { - VERBOSE_LOG(SCENET, "UNTESTED sceNetAdhocGetPdpStat(%08x, %08x) at %08x", structSize, structAddr, currentMIPS->pc); + VERBOSE_LOG(SCENET, "sceNetAdhocGetPdpStat(%08x, %08x) at %08x", structSize, structAddr, currentMIPS->pc); // Library is initialized if (netAdhocInited) @@ -2621,6 +2622,7 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { { // Return Required Size *buflen = sizeof(SceNetAdhocPdpStat) * socketcount; + VERBOSE_LOG(SCENET, "PDP Socket Count: %d", socketcount); // Success return 0; @@ -2658,6 +2660,8 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { if (i > 0) buf[i - 1].next = structAddr + (i * sizeof(SceNetAdhocPdpStat)); + VERBOSE_LOG(SCENET, "PDP Socket Id: %d, LPort: %d, RecvSbCC: %d", buf[i].id, buf[i].lport, buf[i].rcv_sb_cc); + // Increment Counter i++; } @@ -2703,6 +2707,7 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { if (buflen != NULL && buf == NULL) { // Return Required Size *buflen = sizeof(SceNetAdhocPtpStat) * socketcount; + VERBOSE_LOG(SCENET, "PTP Socket Count: %d", socketcount); // Success return 0; @@ -2737,6 +2742,8 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { // Link previous Element to this one if (i > 0) buf[i - 1].next = structAddr + (i * sizeof(SceNetAdhocPtpStat)); + + VERBOSE_LOG(SCENET, "PTP Socket Id: %d, LPort: %d, RecvSbCC: %d", buf[i].id, buf[i].lport, buf[i].rcv_sb_cc); // Increment Counter i++; From e6e7f5d1e733ce5dd906db8792d58173523478ed Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Thu, 24 Sep 2020 01:07:58 +0700 Subject: [PATCH 762/848] Minor fix to sceNetAdhocctlGetPeerInfo --- Core/HLE/sceNetAdhoc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7440ec828f..8cffa0fbff 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2264,7 +2264,7 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { SceNetAdhocctlNickname nickname; truncate_cpy((char*)&nickname.data, ADHOCCTL_NICKNAME_LEN, g_Config.sNickName.c_str()); - //buf->next = 0; + buf->next = 0; buf->nickname = nickname; buf->nickname.data[ADHOCCTL_NICKNAME_LEN - 1] = 0; // last char need to be null-terminated char buf->mac_addr = *maddr; From adab5ff5c9c8ecef61f3b6714342dcb2f6d44158 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 23 Sep 2020 02:18:55 +0700 Subject: [PATCH 763/848] Fixed returned error code on sceNetAdhocctlDelHandler --- Core/HLE/sceNetAdhoc.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 8cffa0fbff..4a2d2c8b97 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -2115,11 +2115,14 @@ static u32 sceNetAdhocctlDisconnect() { } static u32 sceNetAdhocctlDelHandler(u32 handlerID) { + if (!netAdhocctlInited) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "adhocctl not initialized"); + if (adhocctlHandlers.find(handlerID) != adhocctlHandlers.end()) { adhocctlHandlers.erase(handlerID); - WARN_LOG(SCENET, "UNTESTED sceNetAdhocctlDelHandler(%d)", handlerID); + INFO_LOG(SCENET, "sceNetAdhocctlDelHandler(%d)", handlerID); } else { - ERROR_LOG(SCENET, "UNTESTED sceNetAdhocctlDelHandler(%d): Invalid Handler ID", handlerID); + WARN_LOG(SCENET, "sceNetAdhocctlDelHandler(%d): Invalid Handler ID", handlerID); } return 0; From 59f8369cd7fd1d7c906c048b687cf383032e389e Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 23 Sep 2020 04:28:51 +0700 Subject: [PATCH 764/848] An attempt to improve connection stability. --- Core/HLE/sceNetAdhoc.cpp | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 4a2d2c8b97..ca1084145a 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1052,9 +1052,12 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 u int usocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Valid Socket produced if (usocket != INVALID_SOCKET) { - // Change socket buffer size, unlike TCP, UDP need to be Received in full size to prevent leftover data getting discarded/lost, so we need to use the exact buffer size the game want/expects. - setSockBufferSize(usocket, SO_SNDBUF, bufferSize); - setSockBufferSize(usocket, SO_RCVBUF, bufferSize); + // Change socket buffer size. + int pdpbufsize = std::max(bufferSize, PSP_ADHOC_PDP_MFS); //bufferSize*10; + // Send Buffer should be smaller than Recv Buffer to prevent faster device from flooding slower device too much. + setSockBufferSize(usocket, SO_SNDBUF, pdpbufsize); + // Recv Buffer should be equal or larger than Send Buffer. Using larger Recv Buffer might helped reduces dropped packets during a slowdown, but too large may cause slow performance on Warriors Orochi 2. + setSockBufferSize(usocket, SO_RCVBUF, pdpbufsize*10); // Enable KeepAlive setSockKeepAlive(usocket, true); @@ -2653,8 +2656,12 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { // Fix Client View Socket ID buf[i].id = j + 1; - // Set available bytes to be received - buf[i].rcv_sb_cc = getAvailToRecv(sock->data.pdp.id); + // Set available bytes to be received. With FIOREAD There might be lingering 1 byte in recv buffer when remote peer's socket got closed + u32 avail = 0; + if (IsSocketReady(sock->data.pdp.id, true, false) > 0) { + avail = getAvailToRecv(sock->data.pdp.id); + } + buf[i].rcv_sb_cc = avail; // Write End of List Reference buf[i].next = 0; @@ -2811,9 +2818,10 @@ static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, // Valid Socket produced if (tcpsocket > 0) { - // Change socket buffer size when necessary - if (getSockBufferSize(tcpsocket, SO_SNDBUF) < bufsize) setSockBufferSize(tcpsocket, SO_SNDBUF, bufsize); - if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); + // Change socket buffer size to be consistent on all platforms. + int ptpbufsize = std::max(bufsize, PSP_ADHOC_PTP_MSS); + setSockBufferSize(tcpsocket, SO_SNDBUF, ptpbufsize); + setSockBufferSize(tcpsocket, SO_RCVBUF, ptpbufsize*10); // Enable KeepAlive setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); @@ -2972,8 +2980,8 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther internal->data.ptp.id = newsocket; // Set Default Buffer Size - if (getSockBufferSize(newsocket, SO_RCVBUF) < PSP_ADHOC_PTP_MSS) setSockBufferSize(newsocket, SO_RCVBUF, PSP_ADHOC_PTP_MSS); - if (getSockBufferSize(newsocket, SO_SNDBUF) < PSP_ADHOC_PTP_MSS) setSockBufferSize(newsocket, SO_SNDBUF, PSP_ADHOC_PTP_MSS); + setSockBufferSize(newsocket, SO_SNDBUF, PSP_ADHOC_PTP_MSS); + setSockBufferSize(newsocket, SO_RCVBUF, PSP_ADHOC_PTP_MSS*10); // Copy Local Address Data to Structure getLocalMac(&internal->data.ptp.laddr); @@ -3316,9 +3324,10 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int // Valid Socket produced if (tcpsocket > 0) { - // Change socket buffer size when necessary - if (getSockBufferSize(tcpsocket, SO_SNDBUF) < bufsize) setSockBufferSize(tcpsocket, SO_SNDBUF, bufsize); - if (getSockBufferSize(tcpsocket, SO_RCVBUF) < bufsize) setSockBufferSize(tcpsocket, SO_RCVBUF, bufsize); + // Change socket buffer size to be consistent on all platforms. + int ptpbufsize = std::max(bufsize, PSP_ADHOC_PTP_MSS); + setSockBufferSize(tcpsocket, SO_SNDBUF, ptpbufsize); + setSockBufferSize(tcpsocket, SO_RCVBUF, ptpbufsize*10); // Enable KeepAlive setSockKeepAlive(tcpsocket, true, rexmt_int / 1000000L, rexmt_cnt); From 9cdf4941f2b585661e288a4f6353201f3273fef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 00:31:47 +0200 Subject: [PATCH 765/848] Revert a bad optimization in word wrapper --- ext/native/util/text/wrap_text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/native/util/text/wrap_text.cpp b/ext/native/util/text/wrap_text.cpp index 6f829b4163..68ca6d7b5a 100644 --- a/ext/native/util/text/wrap_text.cpp +++ b/ext/native/util/text/wrap_text.cpp @@ -130,8 +130,8 @@ void WordWrapper::AppendWord(int endIndex, bool addNewline) { scanForNewline_ = false; } else { // We may have appended a newline - check. - size_t pos = out_.find_last_of("\n"); - if (pos != out_.npos && pos >= lastLineStart_) { + size_t pos = out_.substr(lastLineStart_).find_last_of("\n"); + if (pos != out_.npos) { lastLineStart_ += pos; } } From a9fef066b5ae2fd64931867d134ef244a921f7dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 00:16:45 +0200 Subject: [PATCH 766/848] Reduce string allocations in Vulkan memory allocator --- Common/Vulkan/VulkanImage.cpp | 3 ++- Common/Vulkan/VulkanImage.h | 4 ++-- Common/Vulkan/VulkanMemory.cpp | 12 ++++++------ Common/Vulkan/VulkanMemory.h | 7 ++++--- GPU/Common/TextureCacheCommon.cpp | 6 +++++- GPU/D3D11/GPU_D3D11.cpp | 1 + 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/Vulkan/VulkanImage.cpp index 2165221668..37a7bead4d 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/Vulkan/VulkanImage.cpp @@ -80,7 +80,8 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, VulkanDeviceAllocator *all if (allocator && !dedicatedAllocation) { allocator_ = allocator; - offset_ = allocator_->Allocate(mem_reqs, &mem_, Tag()); + // ok to use the tag like this, because the lifetime of the VulkanImage exceeds that of the allocation. + offset_ = allocator_->Allocate(mem_reqs, &mem_, Tag().c_str()); if (offset_ == VulkanDeviceAllocator::ALLOCATE_FAILED) { ERROR_LOG(G3D, "Image memory allocation failed (mem_reqs.size=%d, typebits=%08x", (int)mem_reqs.size, (int)mem_reqs.memoryTypeBits); // Destructor will take care of the image. diff --git a/Common/Vulkan/VulkanImage.h b/Common/Vulkan/VulkanImage.h index 91e36dc977..e16ceccc8d 100644 --- a/Common/Vulkan/VulkanImage.h +++ b/Common/Vulkan/VulkanImage.h @@ -30,10 +30,10 @@ public: void Destroy(); - void SetTag(const std::string &tag) { + void SetTag(const char *tag) { tag_ = tag; } - std::string Tag() const { + const std::string &Tag() const { return tag_; } void Touch(); diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 6698c73e2a..74cd1cb660 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -191,7 +191,7 @@ void VulkanDeviceAllocator::Destroy() { destroyed_ = true; } -size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDeviceMemory *deviceMemory, const std::string &tag) { +size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDeviceMemory *deviceMemory, const char *tag) { _assert_(!destroyed_); uint32_t memoryTypeIndex; bool pass = vulkan_->MemoryTypeFromProperties(reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memoryTypeIndex); @@ -244,7 +244,7 @@ size_t VulkanDeviceAllocator::Allocate(const VkMemoryRequirements &reqs, VkDevic return ALLOCATE_FAILED; } -bool VulkanDeviceAllocator::AllocateFromSlab(Slab &slab, size_t &start, size_t blocks, const std::string &tag) { +bool VulkanDeviceAllocator::AllocateFromSlab(Slab &slab, size_t &start, size_t blocks, const char *tag) { _assert_(!destroyed_); bool matched = true; @@ -278,7 +278,7 @@ bool VulkanDeviceAllocator::AllocateFromSlab(Slab &slab, size_t &start, size_t b // Remember the size so we can free. slab.allocSizes[start] = blocks; - slab.tags[start] = { tag, time_now_d(), 0.0 }; + slab.tags[start] = { time_now_d(), 0.0, tag }; slab.totalUsage += blocks; return true; } @@ -442,7 +442,7 @@ void VulkanDeviceAllocator::ReportOldUsage() { const auto &slab = slabs_[i]; bool hasOldAllocs = false; - for (auto it : slab.tags) { + for (auto &it : slab.tags) { const auto info = it.second; double touchedAge = now - info.touched; if (touchedAge >= OLD_AGE) { @@ -453,12 +453,12 @@ void VulkanDeviceAllocator::ReportOldUsage() { if (hasOldAllocs) { NOTICE_LOG(G3D, "Slab %d usage:", (int)i); - for (auto it : slab.tags) { + for (auto &it : slab.tags) { const auto info = it.second; double createAge = now - info.created; double touchedAge = now - info.touched; - NOTICE_LOG(G3D, " * %s (created %fs ago, used %fs ago)", info.tag.c_str(), createAge, touchedAge); + NOTICE_LOG(G3D, " * %s (created %fs ago, used %fs ago)", info.tag, createAge, touchedAge); } } } diff --git a/Common/Vulkan/VulkanMemory.h b/Common/Vulkan/VulkanMemory.h index 31ddc25fa5..54b41aed71 100644 --- a/Common/Vulkan/VulkanMemory.h +++ b/Common/Vulkan/VulkanMemory.h @@ -149,7 +149,8 @@ public: } // May return ALLOCATE_FAILED if the allocation fails. - size_t Allocate(const VkMemoryRequirements &reqs, VkDeviceMemory *deviceMemory, const std::string &tag); + // NOTE: Lifetime of the string tag points to must exceed that of the allocation. + size_t Allocate(const VkMemoryRequirements &reqs, VkDeviceMemory *deviceMemory, const char *tag); // Crashes on a double or misfree. void Free(VkDeviceMemory deviceMemory, size_t offset); @@ -177,9 +178,9 @@ private: static const uint32_t UNDEFINED_MEMORY_TYPE = -1; struct UsageInfo { - std::string tag; double created; double touched; + const char *tag; }; struct Slab { @@ -212,7 +213,7 @@ private: } bool AllocateSlab(VkDeviceSize minBytes, int memoryTypeIndex); - bool AllocateFromSlab(Slab &slab, size_t &start, size_t blocks, const std::string &tag); + bool AllocateFromSlab(Slab &slab, size_t &start, size_t blocks, const char *tag); void Decimate(); void DoTouch(VkDeviceMemory deviceMemory, size_t offset); void ExecuteFree(FreeInfo *userdata); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 56b8508522..1e43e6a0cb 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -1753,6 +1753,9 @@ bool TextureCacheCommon::CheckFullHash(TexCacheEntry *entry, bool &doDelete) { void TextureCacheCommon::Invalidate(u32 addr, int size, GPUInvalidationType type) { // They could invalidate inside the texture, let's just give a bit of leeway. + // TODO: Keep track of the largest texture size in bytes, and use that instead of this + // humongous unrealistic value. + const int LARGEST_TEXTURE_SIZE = 512 * 512 * 4; addr &= 0x3FFFFFFF; @@ -1785,7 +1788,8 @@ void TextureCacheCommon::Invalidate(u32 addr, int size, GPUInvalidationType type u32 texAddr = iter->second->addr; u32 texEnd = iter->second->addr + iter->second->sizeInRAM; - if (texAddr < addr_end && addr < texEnd) { + // Quick check for overlap. Yes the check is right. + if (addr < texEnd && addr_end > texAddr) { if (iter->second->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) { iter->second->SetHashStatus(TexCacheEntry::STATUS_HASHING); } diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index c5a8753d06..48eae62704 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -193,6 +193,7 @@ void GPU_D3D11::BuildReportingInfo() { } void GPU_D3D11::DeviceLost() { + draw_->InvalidateCachedState(); // Simply drop all caches and textures. // FBOs appear to survive? Or no? shaderManagerD3D11_->ClearShaders(); From 6ac9dfe6b5a801034594e910afec15e520ca3438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 00:17:31 +0200 Subject: [PATCH 767/848] Windows debugger: Clean out old remains of multi-cpu support --- Windows/Debugger/CtrlRegisterList.cpp | 7 +--- Windows/Debugger/Debugger_Disasm.cpp | 18 +++----- Windows/Debugger/Debugger_Disasm.h | 17 ++++---- Windows/Debugger/Debugger_Lists.cpp | 25 ++++------- Windows/GEDebugger/CtrlDisplayListView.cpp | 7 +--- Windows/MainWindow.cpp | 48 +++++++++++----------- Windows/MainWindowMenu.cpp | 47 ++++++++++----------- Windows/WindowsHost.cpp | 17 +++----- Windows/main.cpp | 8 ++-- Windows/main.h | 6 +-- 10 files changed, 83 insertions(+), 117 deletions(-) diff --git a/Windows/Debugger/CtrlRegisterList.cpp b/Windows/Debugger/CtrlRegisterList.cpp index 563a2b47f1..05be2dee21 100644 --- a/Windows/Debugger/CtrlRegisterList.cpp +++ b/Windows/Debugger/CtrlRegisterList.cpp @@ -19,8 +19,6 @@ #include "Windows/main.h" -static const int numCPUs = 1; - extern HMENU g_hPopupMenus; enum { REGISTER_PC = 32, REGISTER_HI, REGISTER_LO, REGISTERS_END }; @@ -520,9 +518,8 @@ void CtrlRegisterList::onMouseUp(WPARAM wParam, LPARAM lParam, int button) SendMessage(GetParent(wnd),WM_DEB_GOTOHEXEDIT,val,0); break; case ID_REGLIST_GOTOINDISASM: - for (int i=0; iGoto(val); + if (disasmWindow) + disasmWindow->Goto(val); break; case ID_REGLIST_COPYVALUE: copyRegisterValue(); diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index d519dffa7c..e75a307832 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -31,12 +31,10 @@ #include #include -static const int numCPUs = 1; - // How long (max) to wait for Core to pause before clearing temp breakpoints. -const int TEMP_BREAKPOINT_WAIT_MS = 100; +static const int TEMP_BREAKPOINT_WAIT_MS = 100; -FAR WNDPROC DefGotoEditProc; +static FAR WNDPROC DefGotoEditProc; LRESULT CALLBACK GotoEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { @@ -66,7 +64,7 @@ LRESULT CALLBACK GotoEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa return (LRESULT)CallWindowProc((WNDPROC)DefGotoEditProc,hDlg,message,wParam,lParam); } -FAR WNDPROC DefFuncListProc; +static FAR WNDPROC DefFuncListProc; LRESULT CALLBACK FuncListProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { @@ -94,8 +92,6 @@ LRESULT CALLBACK FuncListProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Dialog((LPCSTR)IDD_DISASM, _hInstance, _hParent) { cpu = _cpu; lastTicks = PSP_IsInited() ? CoreTiming::GetTicks() : 0; - keepStatusBarText = false; - hideBottomTabs = false; SetWindowText(m_hDlg, ConvertUTF8ToWString(_cpu->GetName()).c_str()); @@ -113,8 +109,7 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di // init status bar statusBarWnd = CreateWindowEx(0, STATUSCLASSNAME, L"", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, m_hDlg, (HMENU)IDC_DISASMSTATUSBAR, _hInstance, NULL); - if (g_Config.bDisplayStatusBar == false) - { + if (g_Config.bDisplayStatusBar == false) { ShowWindow(statusBarWnd,SW_HIDE); } @@ -897,9 +892,8 @@ void CDisasm::UpdateDialog(bool _bComplete) SetDlgItemText(m_hDlg, IDC_DEBUG_COUNT, tempTicks); } // Update Register Dialog - for (int i=0; iUpdate(); + if (memoryWindow) + memoryWindow->Update(); // repaint windows at the bottom. only the memory view needs to be forced to // redraw. all others are updated manually diff --git a/Windows/Debugger/Debugger_Disasm.h b/Windows/Debugger/Debugger_Disasm.h index 5639b6e409..1dd8487d33 100644 --- a/Windows/Debugger/Debugger_Disasm.h +++ b/Windows/Debugger/Debugger_Disasm.h @@ -29,8 +29,8 @@ private: TabControl* bottomTabs; std::vector displayedBreakPoints_; std::vector displayedMemChecks_; - bool keepStatusBarText; - bool hideBottomTabs; + bool keepStatusBarText = false; + bool hideBottomTabs = false; BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam); void UpdateSize(WORD width, WORD height); @@ -40,17 +40,14 @@ private: void stepOver(); void stepOut(); void runToLine(); + public: - int index; //helper + int index; CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *cpu); ~CDisasm(); - // - // --- tools --- - // - - virtual void Update() - { + + virtual void Update() { UpdateDialog(true); SetDebugMode(Core_IsStepping(), false); breakpointList->reloadBreakpoints(); @@ -58,7 +55,7 @@ public: void UpdateDialog(bool _bComplete = false); // SetDebugMode void SetDebugMode(bool _bDebug, bool switchPC); - // show dialog + void Goto(u32 addr); void NotifyMapLoaded(); }; diff --git a/Windows/Debugger/Debugger_Lists.cpp b/Windows/Debugger/Debugger_Lists.cpp index 7d08b09ee6..f6c5bd9561 100644 --- a/Windows/Debugger/Debugger_Lists.cpp +++ b/Windows/Debugger/Debugger_Lists.cpp @@ -10,8 +10,6 @@ #include "../../Core/HLE/sceKernelThread.h" #include "util/text/utf8.h" -static const int numCPUs = 1; - enum { TL_NAME, TL_PROGRAMCOUNTER, TL_ENTRYPOINT, TL_PRIORITY, TL_STATE, TL_WAITTYPE, TL_COLUMNCOUNT }; enum { BPL_ENABLED, BPL_TYPE, BPL_OFFSET, BPL_SIZELABEL, BPL_OPCODE, BPL_CONDITION, BPL_HITS, BPL_COLUMNCOUNT }; enum { SF_ENTRY, SF_ENTRYNAME, SF_CURPC, SF_CUROPCODE, SF_CURSP, SF_FRAMESIZE, SF_COLUMNCOUNT }; @@ -375,22 +373,18 @@ void CtrlBreakpointList::toggleEnabled(int itemIndex) void CtrlBreakpointList::gotoBreakpointAddress(int itemIndex) { bool isMemory; - int index = getBreakpointIndex(itemIndex,isMemory); - if (index == -1) return; + int index = getBreakpointIndex(itemIndex, isMemory); + if (index == -1) + return; - if (isMemory) - { + if (isMemory) { u32 address = displayedMemChecks_[index].start; - - for (int i=0; iGoto(address); + if (memoryWindow) + memoryWindow->Goto(address); } else { u32 address = displayedBreakPoints_[index].addr; - - for (int i=0; iGoto(address); + if (disasmWindow) + disasmWindow->Goto(address); } } @@ -413,8 +407,7 @@ void CtrlBreakpointList::removeBreakpoint(int itemIndex) int CtrlBreakpointList::getTotalBreakpointCount() { int count = (int)CBreakPoints::GetMemChecks().size(); - for (size_t i = 0; i < CBreakPoints::GetBreakpoints().size(); i++) - { + for (size_t i = 0; i < CBreakPoints::GetBreakpoints().size(); i++) { if (!displayedBreakPoints_[i].temporary) count++; } diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index 07cc0490db..741ca4b3af 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -9,8 +9,6 @@ #include -static const int numCPUs = 1; - const PTCHAR CtrlDisplayListView::windowClass = _T("CtrlDisplayListView"); const int POPUP_SUBMENU_ID_DISPLAYLISTVIEW = 8; @@ -308,9 +306,8 @@ void CtrlDisplayListView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) switch(TrackPopupMenuEx(GetSubMenu(g_hPopupMenus,POPUP_SUBMENU_ID_DISPLAYLISTVIEW),TPM_RIGHTBUTTON|TPM_RETURNCMD,pt.x,pt.y,wnd,0)) { case ID_DISASM_GOTOINMEMORYVIEW: - for (int i=0; iGoto(curAddress); + if (memoryWindow) + memoryWindow->Goto(curAddress); break; case ID_DISASM_TOGGLEBREAKPOINT: toggleBreakpoint(); diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index bc0c4fe54b..57aa983978 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -536,23 +536,23 @@ namespace MainWindow } void CreateDebugWindows() { - disasmWindow[0] = new CDisasm(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); - DialogManager::AddDlg(disasmWindow[0]); - disasmWindow[0]->Show(g_Config.bShowDebuggerOnLoad); + disasmWindow = new CDisasm(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); + DialogManager::AddDlg(disasmWindow); + disasmWindow->Show(g_Config.bShowDebuggerOnLoad); #if PPSSPP_API(ANY_GL) geDebuggerWindow = new CGEDebugger(MainWindow::GetHInstance(), MainWindow::GetHWND()); DialogManager::AddDlg(geDebuggerWindow); #endif - memoryWindow[0] = new CMemoryDlg(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); - DialogManager::AddDlg(memoryWindow[0]); + memoryWindow = new CMemoryDlg(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); + DialogManager::AddDlg(memoryWindow); } void DestroyDebugWindows() { - DialogManager::RemoveDlg(disasmWindow[0]); - if (disasmWindow[0]) - delete disasmWindow[0]; - disasmWindow[0] = 0; + DialogManager::RemoveDlg(disasmWindow); + if (disasmWindow) + delete disasmWindow; + disasmWindow = 0; #if PPSSPP_API(ANY_GL) DialogManager::RemoveDlg(geDebuggerWindow); @@ -561,10 +561,10 @@ namespace MainWindow geDebuggerWindow = 0; #endif - DialogManager::RemoveDlg(memoryWindow[0]); - if (memoryWindow[0]) - delete memoryWindow[0]; - memoryWindow[0] = 0; + DialogManager::RemoveDlg(memoryWindow); + if (memoryWindow) + delete memoryWindow; + memoryWindow = 0; } LRESULT CALLBACK DisplayProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -678,10 +678,8 @@ namespace MainWindow break; case WM_TOUCH: - { - touchHandler.handleTouchEvent(hWnd, message, wParam, lParam); - return 0; - } + touchHandler.handleTouchEvent(hWnd, message, wParam, lParam); + return 0; default: return DefWindowProc(hWnd, message, wParam, lParam); @@ -725,8 +723,8 @@ namespace MainWindow } if (!noFocusPause && g_Config.bPauseOnLostFocus && GetUIState() == UISTATE_INGAME) { if (pause != Core_IsStepping()) { // != is xor for bools - if (disasmWindow[0]) - SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); + if (disasmWindow) + SendMessage(disasmWindow->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); else Core_EnableStepping(pause); } @@ -928,13 +926,13 @@ namespace MainWindow break; case WM_USER + 1: - if (disasmWindow[0]) - disasmWindow[0]->NotifyMapLoaded(); - if (memoryWindow[0]) - memoryWindow[0]->NotifyMapLoaded(); + if (disasmWindow) + disasmWindow->NotifyMapLoaded(); + if (memoryWindow) + memoryWindow->NotifyMapLoaded(); - if (disasmWindow[0]) - disasmWindow[0]->UpdateDialog(); + if (disasmWindow) + disasmWindow->UpdateDialog(); SetForegroundWindow(hwndMain); break; diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index dc40b0b9cf..ab80ec4cea 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -51,7 +51,6 @@ extern bool g_ShaderNameListChanged; namespace MainWindow { extern HINSTANCE hInst; - static const int numCPUs = 1; // what? extern bool noFocusPause; static W32Util::AsyncBrowseDialog *browseDialog; static W32Util::AsyncBrowseDialog *browseImageDialog; @@ -586,16 +585,16 @@ namespace MainWindow { // Causes hang //NativeMessageReceived("run", ""); - if (disasmWindow[0]) - SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); + if (disasmWindow) + SendMessage(disasmWindow->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); } else if (Core_IsStepping()) { // It is paused, then continue to run. - if (disasmWindow[0]) - SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); + if (disasmWindow) + SendMessage(disasmWindow->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); else Core_EnableStepping(false); } else { - if (disasmWindow[0]) - SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); + if (disasmWindow) + SendMessage(disasmWindow->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0); else Core_EnableStepping(true); } @@ -854,11 +853,11 @@ namespace MainWindow { if (W32Util::BrowseForFileName(true, hWnd, L"Load .ppmap", 0, L"Maps\0*.ppmap\0All files\0*.*\0\0", L"ppmap", fn)) { g_symbolMap->LoadSymbolMap(fn.c_str()); - if (disasmWindow[0]) - disasmWindow[0]->NotifyMapLoaded(); + if (disasmWindow) + disasmWindow->NotifyMapLoaded(); - if (memoryWindow[0]) - memoryWindow[0]->NotifyMapLoaded(); + if (memoryWindow) + memoryWindow->NotifyMapLoaded(); } break; @@ -871,11 +870,11 @@ namespace MainWindow { if (W32Util::BrowseForFileName(true, hWnd, L"Load .sym", 0, L"Symbols\0*.sym\0All files\0*.*\0\0", L"sym", fn)) { g_symbolMap->LoadNocashSym(fn.c_str()); - if (disasmWindow[0]) - disasmWindow[0]->NotifyMapLoaded(); + if (disasmWindow) + disasmWindow->NotifyMapLoaded(); - if (memoryWindow[0]) - memoryWindow[0]->NotifyMapLoaded(); + if (memoryWindow) + memoryWindow->NotifyMapLoaded(); } break; @@ -887,18 +886,16 @@ namespace MainWindow { case ID_DEBUG_RESETSYMBOLTABLE: g_symbolMap->Clear(); - for (int i = 0; i < numCPUs; i++) - if (disasmWindow[i]) - disasmWindow[i]->NotifyMapLoaded(); + if (disasmWindow) + disasmWindow->NotifyMapLoaded(); - for (int i = 0; i < numCPUs; i++) - if (memoryWindow[i]) - memoryWindow[i]->NotifyMapLoaded(); + if (memoryWindow) + memoryWindow->NotifyMapLoaded(); break; case ID_DEBUG_DISASSEMBLY: - if (disasmWindow[0]) - disasmWindow[0]->Show(true); + if (disasmWindow) + disasmWindow->Show(true); break; case ID_DEBUG_GEDEBUGGER: @@ -909,8 +906,8 @@ namespace MainWindow { break; case ID_DEBUG_MEMORYVIEW: - if (memoryWindow[0]) - memoryWindow[0]->Show(true); + if (memoryWindow) + memoryWindow->Show(true); break; case ID_DEBUG_EXTRACTFILE: diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 48b79bde30..e34f744f3b 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -72,8 +72,6 @@ #include "Windows/main.h" #include "UI/OnScreenDisplay.h" -static const int numCPUs = 1; - float g_mouseDeltaX = 0; float g_mouseDeltaY = 0; @@ -201,21 +199,18 @@ void WindowsHost::UpdateUI() { } void WindowsHost::UpdateMemView() { - for (int i = 0; i < numCPUs; i++) - if (memoryWindow[i]) - PostDialogMessage(memoryWindow[i], WM_DEB_UPDATE); + if (memoryWindow) + PostDialogMessage(memoryWindow, WM_DEB_UPDATE); } void WindowsHost::UpdateDisassembly() { - for (int i = 0; i < numCPUs; i++) - if (disasmWindow[i]) - PostDialogMessage(disasmWindow[i], WM_DEB_UPDATE); + if (disasmWindow) + PostDialogMessage(disasmWindow, WM_DEB_UPDATE); } void WindowsHost::SetDebugMode(bool mode) { - for (int i = 0; i < numCPUs; i++) - if (disasmWindow[i]) - PostDialogMessage(disasmWindow[i], WM_DEB_SETDEBUGLPARAM, 0, (LPARAM)mode); + if (disasmWindow) + PostDialogMessage(disasmWindow, WM_DEB_SETDEBUGLPARAM, 0, (LPARAM)mode); } void WindowsHost::PollControllers() { diff --git a/Windows/main.cpp b/Windows/main.cpp index f1617901cb..bf2b74adcc 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -88,11 +88,11 @@ extern "C" { __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } #if PPSSPP_API(ANY_GL) -CGEDebugger* geDebuggerWindow = 0; +CGEDebugger* geDebuggerWindow = nullptr; #endif -CDisasm *disasmWindow[MAX_CPUCOUNT] = {0}; -CMemoryDlg *memoryWindow[MAX_CPUCOUNT] = {0}; +CDisasm *disasmWindow = nullptr; +CMemoryDlg *memoryWindow = nullptr; static std::string langRegion; static std::string osName; @@ -678,7 +678,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin accel = hAccelTable; break; case WINDOW_CPUDEBUGGER: - wnd = disasmWindow[0] ? disasmWindow[0]->GetDlgHandle() : 0; + wnd = disasmWindow ? disasmWindow->GetDlgHandle() : 0; accel = hDebugAccelTable; break; case WINDOW_GEDEBUGGER: diff --git a/Windows/main.h b/Windows/main.h index d25d8ed006..a47bc081b5 100644 --- a/Windows/main.h +++ b/Windows/main.h @@ -22,10 +22,8 @@ #include "Debugger/Debugger_MemoryDlg.h" #include "Common/CommonWindows.h" -#define MAX_CPUCOUNT 1 - -extern CDisasm *disasmWindow[MAX_CPUCOUNT]; -extern CMemoryDlg *memoryWindow[MAX_CPUCOUNT]; +extern CDisasm *disasmWindow; +extern CMemoryDlg *memoryWindow; #if PPSSPP_API(ANY_GL) #include "Windows/GEDebugger/GEDebugger.h" From 84b36d6e615380f19cde320f4f9ee03742d01b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 00:28:09 +0200 Subject: [PATCH 768/848] Speed up game start under Windows by not filling the symbol listbox until the disasm window is opened. --- Windows/Debugger/Debugger_Disasm.cpp | 25 +++++++++++++------ Windows/Debugger/Debugger_Disasm.h | 10 +++++--- Windows/W32Util/DialogManager.cpp | 8 +++--- Windows/W32Util/DialogManager.h | 37 ++++++++++++++-------------- 4 files changed, 47 insertions(+), 33 deletions(-) diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index e75a307832..ecfaca8749 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -848,22 +848,33 @@ void CDisasm::SetDebugMode(bool _bDebug, bool switchPC) } } -void CDisasm::NotifyMapLoaded() -{ - if (g_symbolMap) - g_symbolMap->FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION); - CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); +void CDisasm::Show(bool bShow) { + if (deferredSymbolFill_ && bShow) { + if (g_symbolMap) + g_symbolMap->FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), ST_FUNCTION); + deferredSymbolFill_ = false; + } + Dialog::Show(bShow); +} + +void CDisasm::NotifyMapLoaded() { + if (m_bShowState == SW_SHOW) { + if (g_symbolMap) + g_symbolMap->FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), ST_FUNCTION); + } else { + deferredSymbolFill_ = true; + } + CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg, IDC_DISASMVIEW)); ptr->clearFunctions(); ptr->redraw(); } void CDisasm::Goto(u32 addr) { - CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); + CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg, IDC_DISASMVIEW)); ptr->gotoAddr(addr); SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW)); ptr->redraw(); - } void CDisasm::UpdateDialog(bool _bComplete) diff --git a/Windows/Debugger/Debugger_Disasm.h b/Windows/Debugger/Debugger_Disasm.h index 1dd8487d33..f743538a4f 100644 --- a/Windows/Debugger/Debugger_Disasm.h +++ b/Windows/Debugger/Debugger_Disasm.h @@ -16,7 +16,8 @@ class CDisasm : public Dialog { private: - int minWidth,minHeight; + int minWidth; + int minHeight; DebugInterface *cpu; u64 lastTicks; @@ -31,8 +32,9 @@ private: std::vector displayedMemChecks_; bool keepStatusBarText = false; bool hideBottomTabs = false; + bool deferredSymbolFill_ = false; - BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam); + BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam) override; void UpdateSize(WORD width, WORD height); void SavePosition(); void updateThreadLabel(bool clear); @@ -47,7 +49,9 @@ public: CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *cpu); ~CDisasm(); - virtual void Update() { + void Show(bool bShow) override; + + void Update() override { UpdateDialog(true); SetDebugMode(Core_IsStepping(), false); breakpointList->reloadBreakpoints(); diff --git a/Windows/W32Util/DialogManager.cpp b/Windows/W32Util/DialogManager.cpp index b40563bc00..fdb89ac600 100644 --- a/Windows/W32Util/DialogManager.cpp +++ b/Windows/W32Util/DialogManager.cpp @@ -8,7 +8,7 @@ Dialog::Dialog(LPCSTR res, HINSTANCE _hInstance, HWND _hParent) { m_hInstance = _hInstance; m_hParent = _hParent; - m_hResource=res; + m_hResource = res; m_bValid = true; Create(); } @@ -32,12 +32,12 @@ void Dialog::Destroy() void Dialog::Show(bool _bShow) { - ShowWindow(m_hDlg, _bShow ? SW_NORMAL : SW_HIDE); + m_bShowState = _bShow ? SW_NORMAL : SW_HIDE; + ShowWindow(m_hDlg, m_bShowState); if (_bShow) BringWindowToTop(m_hDlg); } - INT_PTR Dialog::DlgProcStatic(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { Dialog *dis = (Dialog*)GetWindowLongPtr(hdlg, GWLP_USERDATA); @@ -106,4 +106,4 @@ void DialogManager::DestroyAll() for (iter=dialogs.begin(); iter!=dialogs.end(); iter++) delete (*iter); dialogs.clear(); -} \ No newline at end of file +} diff --git a/Windows/W32Util/DialogManager.h b/Windows/W32Util/DialogManager.h index 7203b04603..f1093deb14 100644 --- a/Windows/W32Util/DialogManager.h +++ b/Windows/W32Util/DialogManager.h @@ -4,32 +4,31 @@ class Dialog { +public: + Dialog(LPCSTR res, HINSTANCE _hInstance, HWND _hParent); + virtual ~Dialog(); + + virtual void Show(bool _bShow); + virtual void Update() {} + + HWND GetDlgHandle() { + return m_hDlg; + } protected: - HINSTANCE m_hInstance; + virtual void Create(); + void Destroy(); + HWND m_hParent; HWND m_hDlg; LPCSTR m_hResource; bool m_bValid; + UINT m_bShowState = SW_HIDE; - virtual BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam) - { - MessageBox(0,L"WTF? Pure Call",0,0); - return 0; - } + virtual BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam) = 0; static INT_PTR CALLBACK DlgProcStatic(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); - virtual void Create(); - void Destroy(); -public: - Dialog(LPCSTR res, HINSTANCE _hInstance, HWND _hParent); - virtual ~Dialog(); - void Show(bool _bShow); - virtual void Update() {} - - HWND GetDlgHandle() - { - return m_hDlg; - } +private: + HINSTANCE m_hInstance; }; @@ -42,4 +41,4 @@ public: static void EnableAll(BOOL enable); static void DestroyAll(); static void UpdateAll(); -}; \ No newline at end of file +}; From 1a2597a513f6894a7599a426a9b9e14a85a4c1db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 01:56:20 +0200 Subject: [PATCH 769/848] SSE-optimize IndexGenerator::AddStrip. Shaves about half a percent from GoW. --- GPU/Common/IndexGenerator.cpp | 48 +++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index 4bd0953c47..b0ef2fb0bb 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -17,6 +17,13 @@ #include +#include "CPUDetect.h" +#include "Common.h" + +#ifdef _M_SSE +#include +#endif + #include "IndexGenerator.h" // Points don't need indexing... @@ -82,12 +89,47 @@ void IndexGenerator::AddList(int numVerts, bool clockwise) { } } +inline __m128i mm_set_epi16_backwards(short w0, short w1, short w2, short w3, short w4, short w5, short w6, short w7) { + return _mm_set_epi16(w7, w6, w5, w4, w3, w2, w1, w0); +} + void IndexGenerator::AddStrip(int numVerts, bool clockwise) { int wind = clockwise ? 1 : 2; - const int numTris = numVerts - 2; + int numTris = numVerts - 2; u16 *outInds = inds_; int ibase = index_; - size_t numPairs = numTris / 2; + + int remainingTris = numTris; +#ifdef _M_SSE + // In an SSE2 register we can fit 8 16-bit integers. + // However, we need to output a multiple of 3 indices. + // The first such multiple is 24, which means we'll generate 24 indices per cycle, + // which corresponds to 8 triangles. That's pretty cool. + + int numChunks = numTris / 8; + if (numChunks) { + __m128i ibase8 = _mm_set1_epi16(ibase); + __m128i increment = _mm_set1_epi16(8); + // TODO: Precompute two sets of these depending on wind, and just load directly. + __m128i offsets0 = mm_set_epi16_backwards(0, 0 + wind, (wind ^ 3), /**/ 1, 1 + (wind ^ 3), 1 + wind, /**/ 2, 2 + wind); + __m128i offsets1 = mm_set_epi16_backwards(2 + (wind ^ 3), /**/ 3, 3 + (wind ^ 3), 3 + wind, /**/ 4, 4 + wind, 4 + (wind ^ 3), /**/ 5); + __m128i offsets2 = mm_set_epi16_backwards(5 + (wind ^ 3), 5 + wind, /**/ 6, 6 + wind, 6 + (wind ^ 3), /**/ 7, 7 + (wind ^ 3), 7 + wind); + __m128i *dst = (__m128i *)outInds; + for (int i = 0; i < numChunks; i++) { + _mm_storeu_si128(dst, _mm_add_epi16(ibase8, offsets0)); + _mm_storeu_si128(dst + 1, _mm_add_epi16(ibase8, offsets1)); + _mm_storeu_si128(dst + 2, _mm_add_epi16(ibase8, offsets2)); + ibase8 = _mm_add_epi16(ibase8, increment); + dst += 3; + } + remainingTris -= numChunks * 8; + outInds += numChunks * 24; + ibase += numChunks * 8; + } + // wind doesn't need to be updated, an even number of triangles have been drawn. +#endif + + size_t numPairs = remainingTris / 2; while (numPairs > 0) { *outInds++ = ibase; *outInds++ = ibase + wind; @@ -95,6 +137,8 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { *outInds++ = ibase + 1; *outInds++ = ibase + 1 + (wind ^ 3); *outInds++ = ibase + 1 + wind; + // *outInds++ = ibase + 2; + // *outInds++ = ibase + 2 + wind; ibase += 2; numPairs--; } From df9a5cc0f293a9bf86e1670d6d0d3ae94f8d5d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 02:09:39 +0200 Subject: [PATCH 770/848] Buildfix --- GPU/Common/IndexGenerator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index b0ef2fb0bb..dab1ad6214 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -89,9 +89,11 @@ void IndexGenerator::AddList(int numVerts, bool clockwise) { } } +#ifdef _M_SSE inline __m128i mm_set_epi16_backwards(short w0, short w1, short w2, short w3, short w4, short w5, short w6, short w7) { return _mm_set_epi16(w7, w6, w5, w4, w3, w2, w1, w0); } +#endif void IndexGenerator::AddStrip(int numVerts, bool clockwise) { int wind = clockwise ? 1 : 2; From be54050521dfc68c9f4555a8de251e390e3e1204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 09:24:03 +0200 Subject: [PATCH 771/848] Also optimize IndexGenerator::AddStrip for ARM NEON. --- GPU/Common/DrawEngineCommon.cpp | 2 +- GPU/Common/IndexGenerator.cpp | 61 +++++++++++++++++++++++++++++++-- GPU/Common/IndexGenerator.h | 2 +- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index b326a832ad..994475d718 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -102,7 +102,7 @@ void DrawEngineCommon::DecodeVerts(u8 *dest) { if (indexGen.Prim() < 0) { ERROR_LOG_REPORT(G3D, "DecodeVerts: Failed to deduce prim: %i", indexGen.Prim()); // Force to points (0) - indexGen.AddPrim(GE_PRIM_POINTS, 0); + indexGen.AddPrim(GE_PRIM_POINTS, 0, true); } } diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index dab1ad6214..607bf23e6d 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -17,13 +17,21 @@ #include +#include "ppsspp_config.h" #include "CPUDetect.h" #include "Common.h" #ifdef _M_SSE #include #endif +#if PPSSPP_ARCH(ARM_NEON) +#if defined(_MSC_VER) && PPSSPP_ARCH(ARM64) +#include +#else +#include +#endif +#endif #include "IndexGenerator.h" // Points don't need indexing... @@ -95,6 +103,28 @@ inline __m128i mm_set_epi16_backwards(short w0, short w1, short w2, short w3, sh } #endif +alignas(16) static const u16 offsets_clockwise[24] = { + 0, (u16)(0 + 1), (u16)(0 + 2), + 1, (u16)(1 + 2), (u16)(1 + 1), + 2, (u16)(2 + 1), (u16)(2 + 2), + 3, (u16)(3 + 2), (u16)(3 + 1), + 4, (u16)(4 + 1), (u16)(4 + 2), + 5, (u16)(5 + 2), (u16)(5 + 1), + 6, (u16)(6 + 1), (u16)(6 + 2), + 7, (u16)(7 + 2), (u16)(7 + 1), +}; + +alignas(16) static const uint16_t offsets_counter_clockwise[24] = { + 0, (u16)(0 + 2), (u16)(0 + 1), + 1, (u16)(1 + 1), (u16)(1 + 2), + 2, (u16)(2 + 2), (u16)(2 + 1), + 3, (u16)(3 + 1), (u16)(3 + 2), + 4, (u16)(4 + 2), (u16)(4 + 1), + 5, (u16)(5 + 1), (u16)(5 + 2), + 6, (u16)(6 + 2), (u16)(6 + 1), + 7, (u16)(7 + 1), (u16)(7 + 2), +}; + void IndexGenerator::AddStrip(int numVerts, bool clockwise) { int wind = clockwise ? 1 : 2; int numTris = numVerts - 2; @@ -108,14 +138,16 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { // The first such multiple is 24, which means we'll generate 24 indices per cycle, // which corresponds to 8 triangles. That's pretty cool. + // TODO: Overshooting wouldn't be so bad here - maybe better than entering the narrow loop? int numChunks = numTris / 8; if (numChunks) { __m128i ibase8 = _mm_set1_epi16(ibase); __m128i increment = _mm_set1_epi16(8); + const __m128i *offsets = (const __m128i *)(clockwise ? offsets_clockwise : offsets_counter_clockwise); // TODO: Precompute two sets of these depending on wind, and just load directly. - __m128i offsets0 = mm_set_epi16_backwards(0, 0 + wind, (wind ^ 3), /**/ 1, 1 + (wind ^ 3), 1 + wind, /**/ 2, 2 + wind); - __m128i offsets1 = mm_set_epi16_backwards(2 + (wind ^ 3), /**/ 3, 3 + (wind ^ 3), 3 + wind, /**/ 4, 4 + wind, 4 + (wind ^ 3), /**/ 5); - __m128i offsets2 = mm_set_epi16_backwards(5 + (wind ^ 3), 5 + wind, /**/ 6, 6 + wind, 6 + (wind ^ 3), /**/ 7, 7 + (wind ^ 3), 7 + wind); + __m128i offsets0 = _mm_load_si128(offsets); + __m128i offsets1 = _mm_load_si128(offsets + 1); + __m128i offsets2 = _mm_load_si128(offsets + 2); __m128i *dst = (__m128i *)outInds; for (int i = 0; i < numChunks; i++) { _mm_storeu_si128(dst, _mm_add_epi16(ibase8, offsets0)); @@ -129,6 +161,29 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { ibase += numChunks * 8; } // wind doesn't need to be updated, an even number of triangles have been drawn. +#elif PPSSPP_ARCH(ARM_NEON) + int numChunks = numTris / 8; + if (numChunks) { + uint16x8_t ibase8 = vdupq_n_u16(ibase); + uint16x8_t increment = vdupq_n_u16(8); + const u16 *offsets = clockwise ? offsets_clockwise : offsets_counter_clockwise; + + // TODO: Precompute two sets of these depending on wind, and just load directly. + uint16x8_t offsets0 = vld1q_u16(offsets); + uint16x8_t offsets1 = vld1q_u16(offsets + 8); + uint16x8_t offsets2 = vld1q_u16(offsets + 16); + uint16x8_t *dst = (uint16x8_t *)outInds; + for (int i = 0; i < numChunks; i++) { + vst1q_u16(outInds, vaddq_u16(ibase8, offsets0)); + vst1q_u16(outInds + 8, vaddq_u16(ibase8, offsets1)); + vst1q_u16(outInds + 16, vaddq_u16(ibase8, offsets2)); + ibase8 = vaddq_u16(ibase8, increment); + dst += 3; + outInds += 24; + } + remainingTris -= numChunks * 8; + ibase += numChunks * 8; + } #endif size_t numPairs = remainingTris / 2; diff --git a/GPU/Common/IndexGenerator.h b/GPU/Common/IndexGenerator.h index dd983536f8..05ac01d0f2 100644 --- a/GPU/Common/IndexGenerator.h +++ b/GPU/Common/IndexGenerator.h @@ -48,7 +48,7 @@ public: GEPrimitiveType Prim() const { return prim_; } - void AddPrim(int prim, int vertexCount, bool clockwise = true); + void AddPrim(int prim, int vertexCount, bool clockwise); void TranslatePrim(int prim, int numInds, const u8 *inds, int indexOffset, bool clockwise); void TranslatePrim(int prim, int numInds, const u16_le *inds, int indexOffset, bool clockwise); void TranslatePrim(int prim, int numInds, const u32_le *inds, int indexOffset, bool clockwise); From d8ddef150f91e5c57330b7f4209f8a60b17ca850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 09:36:39 +0200 Subject: [PATCH 772/848] IndexGenerator::AddStrip: Avoid the fallback by writing a few extra indices if necessary. Actually a decent boost. --- GPU/Common/IndexGenerator.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index 607bf23e6d..9a45b343ec 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -138,8 +138,9 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { // The first such multiple is 24, which means we'll generate 24 indices per cycle, // which corresponds to 8 triangles. That's pretty cool. - // TODO: Overshooting wouldn't be so bad here - maybe better than entering the narrow loop? - int numChunks = numTris / 8; + // We allow ourselves to write some extra indices to avoid the fallback loop. + // That's alright as we're appending to a buffer - they will get overwritten anyway. + int numChunks = (numTris + 7) / 8; if (numChunks) { __m128i ibase8 = _mm_set1_epi16(ibase); __m128i increment = _mm_set1_epi16(8); @@ -156,13 +157,11 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { ibase8 = _mm_add_epi16(ibase8, increment); dst += 3; } - remainingTris -= numChunks * 8; - outInds += numChunks * 24; - ibase += numChunks * 8; + outInds += numTris * 3; } // wind doesn't need to be updated, an even number of triangles have been drawn. #elif PPSSPP_ARCH(ARM_NEON) - int numChunks = numTris / 8; + int numChunks = (numTris + 7) / 8; if (numChunks) { uint16x8_t ibase8 = vdupq_n_u16(ibase); uint16x8_t increment = vdupq_n_u16(8); @@ -172,20 +171,18 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { uint16x8_t offsets0 = vld1q_u16(offsets); uint16x8_t offsets1 = vld1q_u16(offsets + 8); uint16x8_t offsets2 = vld1q_u16(offsets + 16); - uint16x8_t *dst = (uint16x8_t *)outInds; + u16 *dst = outInds; for (int i = 0; i < numChunks; i++) { - vst1q_u16(outInds, vaddq_u16(ibase8, offsets0)); - vst1q_u16(outInds + 8, vaddq_u16(ibase8, offsets1)); - vst1q_u16(outInds + 16, vaddq_u16(ibase8, offsets2)); + vst1q_u16(dst, vaddq_u16(ibase8, offsets0)); + vst1q_u16(dst + 8, vaddq_u16(ibase8, offsets1)); + vst1q_u16(dst + 16, vaddq_u16(ibase8, offsets2)); ibase8 = vaddq_u16(ibase8, increment); - dst += 3; - outInds += 24; + dst += 3 * 8; } - remainingTris -= numChunks * 8; - ibase += numChunks * 8; + outInds += numTris * 3; } -#endif - +#else + // Slow fallback loop. size_t numPairs = remainingTris / 2; while (numPairs > 0) { *outInds++ = ibase; @@ -205,6 +202,8 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { wind ^= 3; // toggle between 1 and 2 *outInds++ = ibase + wind; } +#endif + inds_ = outInds; index_ += numVerts; if (numTris > 0) From deedc7a1fe091ddb2645d339c0f2aec9d646e3b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 09:49:28 +0200 Subject: [PATCH 773/848] Cleanup --- GPU/Common/IndexGenerator.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index 9a45b343ec..b33b84f3fc 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -97,12 +97,6 @@ void IndexGenerator::AddList(int numVerts, bool clockwise) { } } -#ifdef _M_SSE -inline __m128i mm_set_epi16_backwards(short w0, short w1, short w2, short w3, short w4, short w5, short w6, short w7) { - return _mm_set_epi16(w7, w6, w5, w4, w3, w2, w1, w0); -} -#endif - alignas(16) static const u16 offsets_clockwise[24] = { 0, (u16)(0 + 1), (u16)(0 + 2), 1, (u16)(1 + 2), (u16)(1 + 1), @@ -145,7 +139,6 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { __m128i ibase8 = _mm_set1_epi16(ibase); __m128i increment = _mm_set1_epi16(8); const __m128i *offsets = (const __m128i *)(clockwise ? offsets_clockwise : offsets_counter_clockwise); - // TODO: Precompute two sets of these depending on wind, and just load directly. __m128i offsets0 = _mm_load_si128(offsets); __m128i offsets1 = _mm_load_si128(offsets + 1); __m128i offsets2 = _mm_load_si128(offsets + 2); @@ -166,8 +159,6 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { uint16x8_t ibase8 = vdupq_n_u16(ibase); uint16x8_t increment = vdupq_n_u16(8); const u16 *offsets = clockwise ? offsets_clockwise : offsets_counter_clockwise; - - // TODO: Precompute two sets of these depending on wind, and just load directly. uint16x8_t offsets0 = vld1q_u16(offsets); uint16x8_t offsets1 = vld1q_u16(offsets + 8); uint16x8_t offsets2 = vld1q_u16(offsets + 16); @@ -191,8 +182,6 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { *outInds++ = ibase + 1; *outInds++ = ibase + 1 + (wind ^ 3); *outInds++ = ibase + 1 + wind; - // *outInds++ = ibase + 2; - // *outInds++ = ibase + 2 + wind; ibase += 2; numPairs--; } From 2a2a4a21d9727d82b42c8b46b8336247ee4c3065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 10:03:07 +0200 Subject: [PATCH 774/848] More cleanup --- GPU/Common/IndexGenerator.cpp | 71 ++++++++++++++++------------------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp index b33b84f3fc..446d7a680e 100644 --- a/GPU/Common/IndexGenerator.cpp +++ b/GPU/Common/IndexGenerator.cpp @@ -120,12 +120,8 @@ alignas(16) static const uint16_t offsets_counter_clockwise[24] = { }; void IndexGenerator::AddStrip(int numVerts, bool clockwise) { - int wind = clockwise ? 1 : 2; int numTris = numVerts - 2; - u16 *outInds = inds_; - int ibase = index_; - int remainingTris = numTris; #ifdef _M_SSE // In an SSE2 register we can fit 8 16-bit integers. // However, we need to output a multiple of 3 indices. @@ -135,46 +131,45 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { // We allow ourselves to write some extra indices to avoid the fallback loop. // That's alright as we're appending to a buffer - they will get overwritten anyway. int numChunks = (numTris + 7) / 8; - if (numChunks) { - __m128i ibase8 = _mm_set1_epi16(ibase); - __m128i increment = _mm_set1_epi16(8); - const __m128i *offsets = (const __m128i *)(clockwise ? offsets_clockwise : offsets_counter_clockwise); - __m128i offsets0 = _mm_load_si128(offsets); - __m128i offsets1 = _mm_load_si128(offsets + 1); - __m128i offsets2 = _mm_load_si128(offsets + 2); - __m128i *dst = (__m128i *)outInds; - for (int i = 0; i < numChunks; i++) { - _mm_storeu_si128(dst, _mm_add_epi16(ibase8, offsets0)); - _mm_storeu_si128(dst + 1, _mm_add_epi16(ibase8, offsets1)); - _mm_storeu_si128(dst + 2, _mm_add_epi16(ibase8, offsets2)); - ibase8 = _mm_add_epi16(ibase8, increment); - dst += 3; - } - outInds += numTris * 3; + __m128i ibase8 = _mm_set1_epi16(index_); + __m128i increment = _mm_set1_epi16(8); + const __m128i *offsets = (const __m128i *)(clockwise ? offsets_clockwise : offsets_counter_clockwise); + __m128i offsets0 = _mm_load_si128(offsets); + __m128i offsets1 = _mm_load_si128(offsets + 1); + __m128i offsets2 = _mm_load_si128(offsets + 2); + __m128i *dst = (__m128i *)inds_; + for (int i = 0; i < numChunks; i++) { + _mm_storeu_si128(dst, _mm_add_epi16(ibase8, offsets0)); + _mm_storeu_si128(dst + 1, _mm_add_epi16(ibase8, offsets1)); + _mm_storeu_si128(dst + 2, _mm_add_epi16(ibase8, offsets2)); + ibase8 = _mm_add_epi16(ibase8, increment); + dst += 3; } + inds_ += numTris * 3; // wind doesn't need to be updated, an even number of triangles have been drawn. #elif PPSSPP_ARCH(ARM_NEON) int numChunks = (numTris + 7) / 8; - if (numChunks) { - uint16x8_t ibase8 = vdupq_n_u16(ibase); - uint16x8_t increment = vdupq_n_u16(8); - const u16 *offsets = clockwise ? offsets_clockwise : offsets_counter_clockwise; - uint16x8_t offsets0 = vld1q_u16(offsets); - uint16x8_t offsets1 = vld1q_u16(offsets + 8); - uint16x8_t offsets2 = vld1q_u16(offsets + 16); - u16 *dst = outInds; - for (int i = 0; i < numChunks; i++) { - vst1q_u16(dst, vaddq_u16(ibase8, offsets0)); - vst1q_u16(dst + 8, vaddq_u16(ibase8, offsets1)); - vst1q_u16(dst + 16, vaddq_u16(ibase8, offsets2)); - ibase8 = vaddq_u16(ibase8, increment); - dst += 3 * 8; - } - outInds += numTris * 3; + uint16x8_t ibase8 = vdupq_n_u16(index_); + uint16x8_t increment = vdupq_n_u16(8); + const u16 *offsets = clockwise ? offsets_clockwise : offsets_counter_clockwise; + uint16x8_t offsets0 = vld1q_u16(offsets); + uint16x8_t offsets1 = vld1q_u16(offsets + 8); + uint16x8_t offsets2 = vld1q_u16(offsets + 16); + u16 *dst = inds_; + for (int i = 0; i < numChunks; i++) { + vst1q_u16(dst, vaddq_u16(ibase8, offsets0)); + vst1q_u16(dst + 8, vaddq_u16(ibase8, offsets1)); + vst1q_u16(dst + 16, vaddq_u16(ibase8, offsets2)); + ibase8 = vaddq_u16(ibase8, increment); + dst += 3 * 8; } + inds_ += numTris * 3; #else // Slow fallback loop. - size_t numPairs = remainingTris / 2; + int wind = clockwise ? 1 : 2; + int ibase = index_; + size_t numPairs = numTris / 2; + u16 *outInds = inds_; while (numPairs > 0) { *outInds++ = ibase; *outInds++ = ibase + wind; @@ -191,9 +186,9 @@ void IndexGenerator::AddStrip(int numVerts, bool clockwise) { wind ^= 3; // toggle between 1 and 2 *outInds++ = ibase + wind; } + inds_ = outInds; #endif - inds_ = outInds; index_ += numVerts; if (numTris > 0) count_ += numTris * 3; From 4cfafb4605c92ce1dbf629f989df0862f8eb91db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 23:00:48 +0200 Subject: [PATCH 775/848] Some GPU code cleanup. Disable some unnecessary reporting. --- GPU/Common/TextureCacheCommon.cpp | 5 ++--- GPU/GPUCommon.cpp | 21 +++++++-------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 1e43e6a0cb..2c47e38170 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -260,10 +260,9 @@ SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth // Kill any mipmapping settings. key.mipEnable = false; - key.minFilt &= 1; - key.mipFilt = 0; - key.magFilt &= 1; + key.mipFilt = false; key.aniso = 0.0; + key.maxLevel = 0.0f; // Often the framebuffer will not match the texture size. We'll wrap/clamp in the shader in that case. int w = gstate.getTextureWidth(0); diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 336c359476..46297ba113 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1584,7 +1584,7 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { } if (!Memory::IsValidAddress(gstate_c.vertexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); + ERROR_LOG(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); return; } @@ -1594,18 +1594,12 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { if ((vertexType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) { u32 indexAddr = gstate_c.indexAddr; if (!Memory::IsValidAddress(indexAddr)) { - ERROR_LOG_REPORT(G3D, "Bad index address %08x!", indexAddr); + ERROR_LOG(G3D, "Bad index address %08x!", indexAddr); return; } inds = Memory::GetPointerUnchecked(indexAddr); } -#ifndef MOBILE_DEVICE - if (prim > GE_PRIM_RECTANGLES) { - ERROR_LOG_REPORT_ONCE(reportPrim, G3D, "Unexpected prim type: %d", prim); - } -#endif - if (gstate_c.dirty & DIRTY_VERTEXSHADER_STATE) { vertexCost_ = EstimatePerVertexCost(); } @@ -1631,9 +1625,8 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { // Optimized submission of sequences of PRIM. Allows us to avoid going through all the mess // above for each one. This can be expanded to support additional games that intersperse - // PRIM commands with other commands. A special case that might be interesting is that game - // that changes culling mode between each prim, we could just change the triangle winding - // right here to still be able to join draw calls. + // PRIM commands with other commands. A special case is Earth Defence Force 2 that changes culling mode + // between each prim, we just change the triangle winding right here to still be able to join draw calls. uint32_t vtypeCheckMask = ~GE_VTYPE_WEIGHTCOUNT_MASK; if (!g_Config.bSoftwareSkinning) @@ -1680,11 +1673,11 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) { break; } case GE_CMD_VADDR: - gstate.cmdmem[data >> 24] = data; + gstate.cmdmem[GE_CMD_VADDR] = data; gstate_c.vertexAddr = gstate_c.getRelativeAddress(data & 0x00FFFFFF); break; case GE_CMD_IADDR: - gstate.cmdmem[data >> 24] = data; + gstate.cmdmem[GE_CMD_IADDR] = data; gstate_c.indexAddr = gstate_c.getRelativeAddress(data & 0x00FFFFFF); break; case GE_CMD_OFFSETADDR: @@ -2351,7 +2344,7 @@ void GPUCommon::FastLoadBoneMatrix(u32 target) { const int num = gstate.boneMatrixNumber & 0x7F; const int mtxNum = num / 12; uint32_t uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum; - if ((num - 12 * mtxNum) != 0) { + if (num != 12 * mtxNum) { uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7); } From c4c7897a26544dca4a6c85ac4cc076978c2c2026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 23:01:49 +0200 Subject: [PATCH 776/848] Enable BlockTransferAllowCreateFB for Burnout Dominator. See #11100. Speeds up the sun effect, but doesn't fix it. It's another game that does truly evil stuff in the border of a 480x272 buffer with stride 512. It downsamples a copy of the region around the sun, texturing from itself, resulting in five fullscreen framebuffer copies. Additionally it renders using color to the depth buffer at some point in the frame.. --- assets/compat.ini | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index b07222ea85..92fdd66323 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -538,6 +538,14 @@ ULJM05049 = true ULKS46027 = true ULAS42019 = true +# Burnout Dominator +ULUS10236 = true +ULES00750 = true +ULJM05242 = true +ULJM05371 = true +NPJH50304 = true +ULES00703 = true + # Test Drive Unlimited ULET00386 = true ULUS10249 = true From 054acf768c979b75b5f8761b4de0200903599c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 24 Sep 2020 23:52:03 +0200 Subject: [PATCH 777/848] Don't cache time in a variable. A little weirdness in the code that has stuck around for a long, long time. It's really not necessary and mostly just confusing. --- Common/TimeUtil.cpp | 23 ++++------------ Common/TimeUtil.h | 13 --------- Core/Core.cpp | 3 --- Core/Dialog/PSPNetconfDialog.cpp | 4 +-- Core/HLE/HLE.cpp | 2 -- Core/HLE/proAdhoc.cpp | 10 +++---- Core/HLE/sceDisplay.cpp | 23 ++++++---------- Core/HLE/sceNetAdhoc.cpp | 36 ++++++++++++------------- Core/HW/StereoResampler.cpp | 4 +-- Core/MIPS/MIPSAnalyst.cpp | 4 +-- Core/SaveState.cpp | 6 ++--- Core/WebServer.cpp | 4 +-- GPU/Common/TextureScalerCommon.cpp | 4 +-- GPU/GLES/ShaderManagerGLES.cpp | 10 +++---- GPU/GPUCommon.cpp | 4 --- SDL/SDLMain.cpp | 2 -- UI/BackgroundAudio.cpp | 4 --- UI/RemoteISOScreen.cpp | 4 +-- UWP/PPSSPP_UWPMain.cpp | 2 -- Windows/MainWindow.cpp | 4 +-- android/jni/app-android.cpp | 2 -- ext/native/profiler/profiler.cpp | 6 ++--- ext/native/thin3d/VulkanQueueRunner.cpp | 4 +-- headless/Headless.cpp | 2 -- ios/ViewController.mm | 1 - unittest/JitHarness.cpp | 6 ++--- unittest/TestVertexJit.cpp | 6 ++--- 27 files changed, 68 insertions(+), 125 deletions(-) diff --git a/Common/TimeUtil.cpp b/Common/TimeUtil.cpp index 7a3f3b6c46..41986021c9 100644 --- a/Common/TimeUtil.cpp +++ b/Common/TimeUtil.cpp @@ -24,7 +24,7 @@ LARGE_INTEGER frequency; double frequencyMult; LARGE_INTEGER startTime; -double real_time_now() { +double time_now_d() { if (frequency.QuadPart == 0) { QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&startTime); @@ -42,7 +42,7 @@ double real_time_now() { uint64_t _frequency = 0; uint64_t _starttime = 0; -double real_time_now() { +double time_now_d() { static time_t start; struct timeval tv; gettimeofday(&tv, NULL); @@ -55,18 +55,6 @@ double real_time_now() { #endif -void time_update() { - curtime = real_time_now(); -} - -double time_now_d() { - return curtime; -} - -int time_now_ms() { - return int(curtime*1000.0); -} - void sleep_ms(int ms) { #ifdef _WIN32 Sleep(ms); @@ -79,7 +67,6 @@ void sleep_ms(int ms) { LoggingDeadline::LoggingDeadline(const char *name, int ms) : name_(name), endCalled_(false) { totalTime_ = (double)ms * 0.001; - time_update(); endTime_ = time_now_d() + totalTime_; } @@ -90,9 +77,9 @@ LoggingDeadline::~LoggingDeadline() { bool LoggingDeadline::End() { endCalled_ = true; - time_update(); - if (time_now_d() > endTime_) { - double late = (time_now_d() - endTime_); + double now = time_now_d(); + if (now > endTime_) { + double late = (now - endTime_); double totalTime = late + totalTime_; ERROR_LOG(SYSTEM, "===== %0.2fms DEADLINE PASSED FOR %s at %0.2fms - %0.2fms late =====", totalTime_ * 1000.0, name_, 1000.0 * totalTime, 1000.0 * late); return false; diff --git a/Common/TimeUtil.h b/Common/TimeUtil.h index 7fa7b1966b..b6362cac4e 100644 --- a/Common/TimeUtil.h +++ b/Common/TimeUtil.h @@ -2,25 +2,12 @@ // http://linux.die.net/man/3/clock_gettime -// This time implementation caches the time for max performance (call time_now_d() as much as you like). -// You need to call time_update() once per frame (or whenever you need the correct time right now). -// Or you can use real_time_now() directly. - -void time_update(); - // Seconds. double time_now_d(); -// Uncached time. Slower than the above cached time functions. Does not update cached time, call time_update for that. -double real_time_now(); - -int time_now_ms(); - - // Sleep. Does not necessarily have millisecond granularity, especially on Windows. void sleep_ms(int ms); - // Can be sprinkled around the code to make sure that thing don't take // unexpectedly long. What that means is up to you. class LoggingDeadline { diff --git a/Core/Core.cpp b/Core/Core.cpp index 6c1952d47e..5e1ad904b1 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -218,12 +218,10 @@ void Core_RunLoop(GraphicsContext *ctx) { while ((GetUIState() != UISTATE_INGAME || !PSP_IsInited()) && GetUIState() != UISTATE_EXIT) { // In case it was pending, we're not in game anymore. We won't get to Core_Run(). Core_StateProcessed(); - time_update(); double startTime = time_now_d(); UpdateRunLoop(); // Simple throttling to not burn the GPU in the menu. - time_update(); double diffTime = time_now_d() - startTime; int sleepTime = (int)(1000.0 / 60.0) - (int)(diffTime * 1000.0); if (sleepTime > 0) @@ -234,7 +232,6 @@ void Core_RunLoop(GraphicsContext *ctx) { } while ((coreState == CORE_RUNNING || coreState == CORE_STEPPING) && GetUIState() == UISTATE_INGAME) { - time_update(); UpdateRunLoop(); if (!windowHidden && !Core_IsStepping()) { ctx->SwapBuffers(); diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 66f2b352f1..976360fb2d 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -91,7 +91,7 @@ int PSPNetconfDialog::Init(u32 paramAddr) { connResult = -1; scanInfosAddr = 0; scanStep = 0; - startTime = (u64)(real_time_now() * 1000000.0); + startTime = (u64)(time_now_d() * 1000000.0); StartFade(true); return 0; @@ -252,7 +252,7 @@ int PSPNetconfDialog::Update(int animSpeed) { UpdateButtons(); auto di = GetI18NCategory("Dialog"); auto err = GetI18NCategory("Error"); - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); // It seems JPCSP doesn't check for NETCONF_STATUS_APNET if (request.netAction == NETCONF_CONNECT_APNET || request.netAction == NETCONF_STATUS_APNET || request.netAction == NETCONF_CONNECT_APNET_LAST) { diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 1634895a40..c77962347d 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -705,7 +705,6 @@ void CallSyscall(MIPSOpcode op) PROFILE_THIS_SCOPE("syscall"); double start = 0.0; // need to initialize to fix the race condition where coreCollectDebugStats is enabled in the middle of this func. if (coreCollectDebugStats) { - time_update(); start = time_now_d(); } @@ -729,7 +728,6 @@ void CallSyscall(MIPSOpcode op) } if (coreCollectDebugStats) { - time_update(); u32 callno = (op >> 6) & 0xFFFFF; //20 bits int funcnum = callno & 0xFFF; int modulenum = (callno & 0xFF000) >> 12; diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a769c81937..a93a64656e 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -578,7 +578,7 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun sibling->state = PSP_ADHOC_MATCHING_PEER_CHILD; // Initialize Ping Timer - sibling->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + sibling->lastping = CoreTiming::GetGlobalTimeUsScaled(); //time_now_d()*1000000.0; // Link Peer sibling->next = context->peerlist; @@ -979,7 +979,7 @@ void handleTimeout(SceNetAdhocMatchingContext * context) // Get Next Pointer (to avoid crash on memory freeing) SceNetAdhocMatchingMemberInternal * next = peer->next; - u64_le now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0 + u64_le now = CoreTiming::GetGlobalTimeUsScaled(); //time_now_d()*1000000.0 // Timeout! if (peer->state != 0 && (now - peer->lastping) > context->timeout) { @@ -1343,7 +1343,7 @@ int friendFinder(){ if (networkInited) { // Ping Server - now = real_time_now() * 1000000.0; // Use real_time_now()*1000000.0 instead of CoreTiming::GetGlobalTimeUsScaled() if the game gets disconnected from AdhocServer too soon when FPS wasn't stable + now = time_now_d() * 1000000.0; // Use time_now_d()*1000000.0 instead of CoreTiming::GetGlobalTimeUsScaled() if the game gets disconnected from AdhocServer too soon when FPS wasn't stable // original code : ((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT) if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { // We may need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet // Prepare Packet @@ -2078,9 +2078,9 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){ errorcode = errno; if (iResult == SOCKET_ERROR && errorcode != EISCONN) { - u64 startTime = (u64)(real_time_now() * 1000.0); + u64 startTime = (u64)(time_now_d() * 1000.0); while (IsSocketReady(metasocket, false, true) <= 0) { - u64 now = (u64)(real_time_now() * 1000.0); + u64 now = (u64)(time_now_d() * 1000.0); if (coreState == CORE_POWERDOWN) return iResult; if (now - startTime > adhocDefaultTimeout) break; sleep_ms(10); diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index a421736d93..f2f55aebf2 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -192,7 +192,7 @@ static void ScheduleLagSync(int over = 0) { over = 0; } CoreTiming::ScheduleEvent(usToCycles(1000 + over), lagSyncEvent, 0); - lastLagSync = real_time_now(); + lastLagSync = time_now_d(); } } @@ -296,7 +296,7 @@ void __DisplayDoState(PointerWrap &p) { Do(p, lagSyncEvent); Do(p, lagSyncScheduled); CoreTiming::RestoreRegisterEvent(lagSyncEvent, "LagSync", &hleLagSync); - lastLagSync = real_time_now(); + lastLagSync = time_now_d(); if (lagSyncScheduled != g_Config.bForceLagSync) { ScheduleLagSync(); } @@ -451,7 +451,6 @@ static bool IsRunningSlow() { } static void CalculateFPS() { - time_update(); double now = time_now_d(); if (now >= lastFpsTime + 1.0) { @@ -580,8 +579,6 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { if (!throttle && !doFrameSkip) return; - time_update(); - float scaledTimestep = timestep; if (fpsLimit > 0 && fpsLimit != 60) { scaledTimestep *= 60.0f / fpsLimit; @@ -636,7 +633,6 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { const double left = nextFrameTime - curFrameTime; usleep((long)(left * 1000000)); #endif - time_update(); } } curFrameTime = time_now_d(); @@ -652,8 +648,6 @@ static void DoFrameIdleTiming() { return; } - time_update(); - double before = time_now_d(); double dist = before - lastFrameTime; // Ignore if the distance is just crazy. May mean wrap or pause. @@ -681,7 +675,6 @@ static void DoFrameIdleTiming() { const double left = goal - time_now_d(); usleep((long)(left * 1000000)); #endif - time_update(); } if (g_Config.bDrawFrameGraph) { @@ -846,7 +839,7 @@ void __DisplayFlip(int cyclesLate) { if (g_Config.bDrawFrameGraph) { // Track how long we sleep (whether vsync or sleep_ms.) - frameSleepHistory[frameSleepPos] += real_time_now() - lastFrameTimeHistory; + frameSleepHistory[frameSleepPos] += time_now_d() - lastFrameTimeHistory; } } else { // Okay, there's no new frame to draw. But audio may be playing, so we need to time still. @@ -894,23 +887,23 @@ void hleLagSync(u64 userdata, int cyclesLate) { } const double goal = lastLagSync + (scale / 1000.0f); - time_update(); double before = time_now_d(); // Don't lag too long ever, if they leave it paused. - while (time_now_d() < goal && goal < time_now_d() + 0.01) { + double now = before; + while (now < goal && goal < now + 0.01) { #ifndef _WIN32 const double left = goal - time_now_d(); usleep((long)(left * 1000000)); #endif - time_update(); + now = time_now_d(); } const int emuOver = (int)cyclesToUs(cyclesLate); - const int over = (int)((time_now_d() - goal) * 1000000); + const int over = (int)((now - goal) * 1000000); ScheduleLagSync(over - emuOver); if (g_Config.bDrawFrameGraph) { - frameSleepHistory[frameTimeHistoryPos] += time_now_d() - before; + frameSleepHistory[frameTimeHistoryPos] += now - before; } } diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index ca1084145a..470b53bb0a 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -243,7 +243,7 @@ static void __AdhocctlNotify(u64 userdata, int cyclesLate) { if (adhocctlState != waitVal && error == 0) { // Detecting Adhocctl Initialization using waitVal < 0 if (waitVal >= 0 || (waitVal < 0 && (g_Config.bEnableWlan && !networkInited))) { - u64 now = (u64)(real_time_now() * 1000.0); + u64 now = (u64)(time_now_d() * 1000.0); if (now - adhocctlStartTime <= adhocDefaultTimeout) { // Try again in another 0.5ms until state matched or timedout. CoreTiming::ScheduleEvent(usToCycles(500) - cyclesLate, adhocctlNotifyEvent, userdata); @@ -275,7 +275,7 @@ int WaitAdhocctlState(AdhocctlRequest request, int state, int usec, const char* adhocctlNotifyEvent = CoreTiming::RegisterEvent("__AdhocctlNotify", __AdhocctlNotify); u64 param = ((u64)__KernelGetCurThread()) << 32 | uid; - adhocctlStartTime = (u64)(real_time_now() * 1000.0); + adhocctlStartTime = (u64)(time_now_d() * 1000.0); adhocctlRequests[uid] = request; CoreTiming::ScheduleEvent(usToCycles(usec), adhocctlNotifyEvent, param); __KernelWaitCurThread(WAITTYPE_NET, uid, state, 0, false, reason); @@ -343,7 +343,7 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { } // On Windows: recvfrom on UDP can get error WSAECONNRESET when previous sendto's destination is unreachable (or destination port is not bound yet), may need to disable SIO_UDP_CONNRESET error else if (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ECONNRESET || sockerr == ETIMEDOUT) { - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); auto sock = adhocSockets[req.id - 1]; if (sock->flags & ADHOC_F_ALERTRECV) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; @@ -390,7 +390,7 @@ int DoBlockingPdpSend(int uid, AdhocSocketRequest& req, s64& result, AdhocSendTa } else { if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); if (sock->flags & ADHOC_F_ALERTSEND) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? @@ -437,7 +437,7 @@ int DoBlockingPtpSend(int uid, AdhocSocketRequest& req, s64& result) { result = 0; } else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); if (sock->flags & ADHOC_F_ALERTSEND) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? @@ -485,7 +485,7 @@ int DoBlockingPtpRecv(int uid, AdhocSocketRequest& req, s64& result) { result = 0; } else if (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT)) { - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); if (sock->flags & ADHOC_F_ALERTRECV) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? @@ -535,7 +535,7 @@ int DoBlockingPtpAccept(int uid, AdhocSocketRequest& req, s64& result) { result = newid; } else if (ret == 0 || (ret == SOCKET_ERROR && (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT))) { - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); if (sock->flags & ADHOC_F_ALERTACCEPT) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? @@ -582,7 +582,7 @@ int DoBlockingPtpConnect(int uid, AdhocSocketRequest& req, s64& result) { } // Timeout else if (ret == 0) { - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); if (sock->flags & ADHOC_F_ALERTCONNECT) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? @@ -616,7 +616,7 @@ int DoBlockingPtpFlush(int uid, AdhocSocketRequest& req, s64& result) { return 0; } else if (sockerr == EAGAIN || sockerr == EWOULDBLOCK || sockerr == ETIMEDOUT) { - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); if (sock->flags & ADHOC_F_ALERTFLUSH) { result = ERROR_NET_ADHOC_SOCKET_ALERTED; // FIXME: Should we clear the flag after alert signaled? @@ -643,7 +643,7 @@ int DoBlockingAdhocPollSocket(int uid, AdhocSocketRequest& req, s64& result) { SceNetAdhocPollSd* sds = (SceNetAdhocPollSd*)req.buffer; int ret = PollAdhocSocket(sds, req.id, 0); if (ret <= 0) { - u64 now = (u64)(real_time_now() * 1000000.0); + u64 now = (u64)(time_now_d() * 1000000.0); if (req.timeout == 0 || now - req.startTime <= req.timeout) { return -1; } @@ -776,7 +776,7 @@ int WaitBlockingAdhocSocket(u64 threadSocketId, int type, int pspSocketId, void* if (tmout > 0) tmout = std::max(tmout, minSocketTimeoutUS); - u64 startTime = (u64)(real_time_now() * 1000000.0); + u64 startTime = (u64)(time_now_d() * 1000000.0); adhocSocketRequests[threadSocketId] = { type, pspSocketId, buffer, len, tmout, startTime, remoteMAC, remotePort }; // Some games (ie. Power Stone Collection) are using as small as 100 usec timeout CoreTiming::ScheduleEvent(usToCycles(100), adhocSocketNotifyEvent, threadSocketId); @@ -2299,7 +2299,7 @@ int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { buf->mac_addr = *maddr; buf->flags = 0x0400; //peer->ip_addr; buf->padding = 0; - buf->last_recv = peer->last_recv; //CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; //(uint64_t)time(NULL); //This timestamp is important issue on Dissidia 012 + buf->last_recv = peer->last_recv; //CoreTiming::GetGlobalTimeUsScaled(); //time_now_d()*1000000.0; //(uint64_t)time(NULL); //This timestamp is important issue on Dissidia 012 // Success retval = 0; @@ -5104,7 +5104,7 @@ void __NetTriggerCallbacks() args[1] = error; // FIXME: When Joining a group, Do we need to wait for group creator's peer data before triggering the callback to make sure the game not to thinks we're the group creator? - u64 now = (u64)(real_time_now() * 1000.0); + u64 now = (u64)(time_now_d() * 1000.0); if ((flags != ADHOCCTL_EVENT_CONNECT && flags != ADHOCCTL_EVENT_GAME) || adhocConnectionType != ADHOC_JOIN || getActivePeerCount() > 0 || now - adhocctlStartTime > adhocDefaultTimeout) { // Since 0 is a valid index to types_ we use -1 to detects if it was loaded from an old save state @@ -5968,7 +5968,7 @@ void actOnPingPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen if (peer != NULL) { // Update Receive Timer - peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //time_now_d()*1000000.0; } } @@ -6020,7 +6020,7 @@ void actOnHelloPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * se peer->state = PSP_ADHOC_MATCHING_PEER_OFFER; // Initialize Ping Timer - peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //time_now_d()*1000000.0; peerlock.lock(); // Link Peer into List @@ -6104,7 +6104,7 @@ void actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen peer->state = PSP_ADHOC_MATCHING_PEER_INCOMING_REQUEST; // Initialize Ping Timer - peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); //time_now_d()*1000000.0; peerlock.lock(); // Link Peer into List @@ -6431,7 +6431,7 @@ void actOnBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * se sibling->state = PSP_ADHOC_MATCHING_PEER_CHILD; // Initialize Ping Timer - sibling->lastping = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + sibling->lastping = CoreTiming::GetGlobalTimeUsScaled(); //time_now_d()*1000000.0; peerlock.lock(); @@ -6701,7 +6701,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi peerlock.unlock(); if (context != NULL) { - now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0; + now = CoreTiming::GetGlobalTimeUsScaled(); //time_now_d()*1000000.0; // Hello Message Sending Context with unoccupied Slots if ((context->mode == PSP_ADHOC_MATCHING_MODE_PARENT && (countChildren(context) < (context->maxpeers - 1))) || (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && findP2P(context) == NULL)) diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index d130079033..c1e9b00049 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -291,7 +291,7 @@ void StereoResampler::PushSamples(const s32 *samples, unsigned int numSamples) { } void StereoResampler::GetAudioDebugStats(char *buf, size_t bufSize) { - double elapsed = real_time_now() - startTime_; + double elapsed = time_now_d() - startTime_; double effective_input_sample_rate = (double)inputSampleCount_ / elapsed; double effective_output_sample_rate = (double)outputSampleCount_ / elapsed; @@ -335,7 +335,7 @@ void StereoResampler::ResetStatCounters() { overrunCountTotal_ = 0; inputSampleCount_ = 0; outputSampleCount_ = 0; - startTime_ = real_time_now(); + startTime_ = time_now_d(); } void StereoResampler::DoState(PointerWrap &p) { diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 10b9720281..6bb213ef05 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -924,13 +924,13 @@ skip: // TODO: Load from cache file if available instead. - double st = real_time_now(); + double st = time_now_d(); for (auto iter = functions.begin(), end = functions.end(); iter != end; iter++) { const AnalyzedFunction &f = *iter; PrecompileFunction(f.start, f.end - f.start + 4); } - double et = real_time_now(); + double et = time_now_d(); NOTICE_LOG(JIT, "Precompiled %d MIPS functions in %0.2f milliseconds", (int)functions.size(), (et - st) * 1000.0); } diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index c0261d2746..c5a960c69d 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -683,12 +683,12 @@ namespace SaveState return; // For fast-forwarding, otherwise they may be useless and too close. - time_update(); - float diff = time_now_d() - rewindLastTime; + double now = time_now_d(); + float diff = now - rewindLastTime; if (diff < rewindMaxWallFrequency) return; - rewindLastTime = time_now_d(); + rewindLastTime = now; DEBUG_LOG(BOOT, "saving rewind state"); rewindStates.Save(); } diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index 4697de3de0..d00753a1d4 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -257,11 +257,11 @@ static void ExecuteWebServer() { g_Config.iRemoteISOPort = http->Port(); RegisterServer(http->Port()); - double lastRegister = real_time_now(); + double lastRegister = time_now_d(); while (RetrieveStatus() == ServerStatus::RUNNING) { http->RunSlice(1.0); - double now = real_time_now(); + double now = time_now_d(); if (now > lastRegister + 540.0) { RegisterServer(http->Port()); lastRegister = now; diff --git a/GPU/Common/TextureScalerCommon.cpp b/GPU/Common/TextureScalerCommon.cpp index 6f4c2d3fc4..c80e713819 100644 --- a/GPU/Common/TextureScalerCommon.cpp +++ b/GPU/Common/TextureScalerCommon.cpp @@ -542,7 +542,7 @@ void TextureScalerCommon::ScaleAlways(u32 *out, u32 *src, u32 &dstFmt, int &widt bool TextureScalerCommon::ScaleInto(u32 *outputBuf, u32 *src, u32 &dstFmt, int &width, int &height, int factor) { #ifdef SCALING_MEASURE_TIME - double t_start = real_time_now(); + double t_start = time_now_d(); #endif bufInput.resize(width*height); // used to store the input image image if it needs to be reformatted @@ -583,7 +583,7 @@ bool TextureScalerCommon::ScaleInto(u32 *outputBuf, u32 *src, u32 &dstFmt, int & #ifdef SCALING_MEASURE_TIME if (width*height > 64 * 64 * factor*factor) { - double t = real_time_now() - t_start; + double t = time_now_d() - t_start; NOTICE_LOG(G3D, "TextureScaler: processed %9d pixels in %6.5lf seconds. (%9.2lf Mpixels/second)", width*height, t, (width*height) / (t * 1000 * 1000)); } diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 58a344b55e..6c1bffa637 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -850,7 +850,6 @@ void ShaderManagerGLES::Load(const std::string &filename) { if (header.magic != CACHE_HEADER_MAGIC || header.version != CACHE_VERSION || header.featureFlags != gstate_c.featureFlags) { return; } - time_update(); diskCachePending_.start = time_now_d(); diskCachePending_.Clear(); @@ -908,12 +907,12 @@ bool ShaderManagerGLES::ContinuePrecompile(float sliceTime) { PSP_SetLoading("Compiling shaders..."); - double start = real_time_now(); + double start = time_now_d(); // Let's try to keep it under sliceTime if possible. double end = start + sliceTime; for (size_t &i = pending.vertPos; i < pending.vert.size(); i++) { - if (real_time_now() >= end) { + if (time_now_d() >= end) { // We'll finish later. return false; } @@ -943,7 +942,7 @@ bool ShaderManagerGLES::ContinuePrecompile(float sliceTime) { } for (size_t &i = pending.fragPos; i < pending.frag.size(); i++) { - if (real_time_now() >= end) { + if (time_now_d() >= end) { // We'll finish later. return false; } @@ -957,7 +956,7 @@ bool ShaderManagerGLES::ContinuePrecompile(float sliceTime) { } for (size_t &i = pending.linkPos; i < pending.link.size(); i++) { - if (real_time_now() >= end) { + if (time_now_d() >= end) { // We'll finish later. return false; } @@ -974,7 +973,6 @@ bool ShaderManagerGLES::ContinuePrecompile(float sliceTime) { } // Okay, finally done. Time to report status. - time_update(); double finish = time_now_d(); NOTICE_LOG(G3D, "Precompile: Compiled and linked %d programs (%d vertex, %d fragment) in %0.1f milliseconds", (int)pending.link.size(), (int)pending.vert.size(), (int)pending.frag.size(), 1000 * (finish - pending.start)); diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 46297ba113..66bfc80fe9 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -928,7 +928,6 @@ u32 GPUCommon::Break(int mode) { void GPUCommon::NotifySteppingEnter() { if (coreCollectDebugStats) { - time_update(); timeSteppingStarted_ = time_now_d(); } } @@ -937,7 +936,6 @@ void GPUCommon::NotifySteppingExit() { if (timeSteppingStarted_ <= 0.0) { ERROR_LOG(G3D, "Mismatched stepping enter/exit."); } - time_update(); timeSpentStepping_ += time_now_d() - timeSteppingStarted_; timeSteppingStarted_ = 0.0; } @@ -947,7 +945,6 @@ bool GPUCommon::InterpretList(DisplayList &list) { // Initialized to avoid a race condition with bShowDebugStats changing. double start = 0.0; if (coreCollectDebugStats) { - time_update(); start = time_now_d(); } @@ -1012,7 +1009,6 @@ bool GPUCommon::InterpretList(DisplayList &list) { list.offsetAddr = gstate_c.offsetAddr; if (coreCollectDebugStats) { - time_update(); double total = time_now_d() - start - timeSpentStepping_; hleSetSteppingTime(timeSpentStepping_); timeSpentStepping_ = 0.0; diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 119ea7419b..19f3075c63 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -1122,7 +1122,6 @@ int main(int argc, char *argv[]) { ToggleFullScreenIfFlagSet(window); // Simple throttling to not burn the GPU in the menu. - time_update(); if (GetUIState() != UISTATE_INGAME || !PSP_IsInited() || renderThreadPaused) { double diffTime = time_now_d() - startTime; int sleepTime = (int)(1000.0 / 60.0) - (int)(diffTime * 1000.0); @@ -1130,7 +1129,6 @@ int main(int argc, char *argv[]) { sleep_ms(sleepTime); } - time_update(); framecount++; } diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 8337d13576..67dc6245c8 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -311,8 +311,6 @@ void BackgroundAudio::Clear(bool hard) { } void BackgroundAudio::SetGame(const std::string &path) { - time_update(); - std::lock_guard lock(mutex_); if (path == bgGamePath_) { // Do nothing @@ -332,8 +330,6 @@ void BackgroundAudio::SetGame(const std::string &path) { } int BackgroundAudio::Play() { - time_update(); - std::lock_guard lock(mutex_); // Immediately stop the sound if it is turned off while playing. diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 93e8410232..e52fa68505 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -427,12 +427,12 @@ void RemoteISOConnectScreen::update() { break; case ScanStatus::FAILED: - nextRetry_ = real_time_now() + 15.0; + nextRetry_ = time_now_d() + 15.0; status_ = ScanStatus::RETRY_SCAN; break; case ScanStatus::RETRY_SCAN: - if (nextRetry_ < real_time_now()) { + if (nextRetry_ < time_now_d()) { status_ = ScanStatus::SCANNING; nextRetry_ = 0.0; diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 0b9d191aa0..ddd6d3fe6b 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -170,10 +170,8 @@ bool PPSSPP_UWPMain::Render() { hasSetThreadName = true; } - time_update(); auto context = m_deviceResources->GetD3DDeviceContext(); - switch (m_deviceResources->ComputeDisplayRotation()) { case DXGI_MODE_ROTATION_IDENTITY: g_display_rotation = DisplayRotation::ROTATE_0; break; case DXGI_MODE_ROTATION_ROTATE90: g_display_rotation = DisplayRotation::ROTATE_90; break; diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 57aa983978..78a60abf28 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -614,14 +614,14 @@ namespace MainWindow // Simulate doubleclick, doesn't work with RawInput enabled static double lastMouseDown; - double now = real_time_now(); + double now = time_now_d(); if ((now - lastMouseDown) < 0.001 * GetDoubleClickTime()) { if (!g_Config.bShowTouchControls && !g_Config.bMouseControl && GetUIState() == UISTATE_INGAME && g_Config.bFullscreenOnDoubleclick) { SendToggleFullscreen(!g_Config.bFullScreen); } lastMouseDown = 0.0; } else { - lastMouseDown = real_time_now(); + lastMouseDown = time_now_d(); } } break; diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index e6531bdd31..bdd2891d30 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -864,7 +864,6 @@ void UpdateRunLoopAndroid(JNIEnv *env) { NativeUpdate(); NativeRender(graphicsContext); - time_update(); std::lock_guard guard(frameCommandLock); if (!nativeActivity) { @@ -1287,7 +1286,6 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J NativeUpdate(); NativeRender(graphicsContext); - time_update(); graphicsContext->SwapBuffers(); diff --git a/ext/native/profiler/profiler.cpp b/ext/native/profiler/profiler.cpp index 2538dbba2e..50b36465c5 100644 --- a/ext/native/profiler/profiler.cpp +++ b/ext/native/profiler/profiler.cpp @@ -140,7 +140,7 @@ int internal_profiler_enter(const char *category_name, int *out_thread_id) { int &depth = profiler.depth[thread_id]; if (profiler.eventStart[thread_id][category] == 0.0f) { - double now = real_time_now(); + double now = time_now_d(); int parent = profiler.parentCategory[thread_id][depth]; // Temporarily suspend the parent on entering a child. if (parent != -1) { @@ -170,7 +170,7 @@ void internal_profiler_leave(int thread_id, int category) { return; } - double now = real_time_now(); + double now = time_now_d(); depth--; _assert_msg_(depth >= 0, "Profiler enter/leave mismatch!"); @@ -191,7 +191,7 @@ void internal_profiler_leave(int thread_id, int category) { void internal_profiler_end_frame() { int thread_id = internal_profiler_find_thread(); _assert_msg_(profiler.depth[thread_id] == 0, "Can't be inside a profiler scope at end of frame!"); - profiler.curFrameStart = real_time_now(); + profiler.curFrameStart = time_now_d(); profiler.historyPos++; profiler.historyPos &= (HISTORY_SIZE - 1); memset(&history[MAX_THREADS * profiler.historyPos], 0, sizeof(CategoryFrame) * MAX_THREADS); diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 991374fb92..c563fc9851 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -479,7 +479,7 @@ void VulkanQueueRunner::PreprocessSteps(std::vector &steps) { void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &steps, QueueProfileContext *profile) { if (profile) - profile->cpuStartTime = real_time_now(); + profile->cpuStartTime = time_now_d(); bool emitLabels = vulkan_->Extensions().EXT_debug_utils; for (size_t i = 0; i < steps.size(); i++) { @@ -528,7 +528,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &st } if (profile) - profile->cpuEndTime = real_time_now(); + profile->cpuEndTime = time_now_d(); } void VulkanQueueRunner::ApplyMGSHack(std::vector &steps) { diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 284f709c02..537cc03c70 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -170,7 +170,6 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool if (autoCompare) headlessHost->SetComparisonScreenshot(ExpectedScreenshotFromFilename(coreParameter.fileToStart)); - time_update(); bool passed = true; // TODO: We must have some kind of stack overflow or we're not following the ABI right. // This gets trashed if it's not static. @@ -194,7 +193,6 @@ bool RunAutoTest(HeadlessHost *headlessHost, CoreParameter &coreParameter, bool coreState = CORE_RUNNING; headlessHost->SwapBuffers(); } - time_update(); if (time_now_d() > deadline) { // Don't compare, print the output at least up to this point, and bail. printf("%s", output.c_str()); diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 4d748b0a88..fb86872c7c 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -249,7 +249,6 @@ static LocationHelper *locationHelper; while (threadEnabled) { NativeUpdate(); NativeRender(graphicsContext); - time_update(); } diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index e2cecf0f88..31899887c7 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -55,7 +55,7 @@ HLEFunction UnitTestFakeSyscalls[] = { double ExecCPUTest() { int blockTicks = 1000000; int total = 0; - double st = real_time_now(); + double st = time_now_d(); do { for (int j = 0; j < 1000; ++j) { currentMIPS->pc = PSP_GetUserMemoryBase(); @@ -67,8 +67,8 @@ double ExecCPUTest() { ++total; } } - while (real_time_now() - st < 0.5); - double elapsed = real_time_now() - st; + while (time_now_d() - st < 0.5); + double elapsed = time_now_d() - st; return total / elapsed; } diff --git a/unittest/TestVertexJit.cpp b/unittest/TestVertexJit.cpp index ac00dfd532..965fcee639 100644 --- a/unittest/TestVertexJit.cpp +++ b/unittest/TestVertexJit.cpp @@ -86,14 +86,14 @@ public: SetupExecute(vtype, useJit); int total = 0; - double st = real_time_now(); + double st = time_now_d(); do { for (int j = 0; j < ROUNDS; ++j) { dec_->DecodeVerts(dst_, src_, indexLowerBound_, indexUpperBound); ++total; } - } while (real_time_now() - st < 0.5); - double elapsed = real_time_now() - st; + } while (time_now_d() - st < 0.5); + double elapsed = time_now_d() - st; return total / elapsed; } From b41d20dd8265b82352a760a56336459dc06ce43f Mon Sep 17 00:00:00 2001 From: barbudreadmon Date: Sun, 27 Sep 2020 15:24:17 +0200 Subject: [PATCH 778/848] glcore context switching --- libretro/CMakeLists.txt | 1 + libretro/LibretroGLContext.h | 2 - libretro/LibretroGLCoreContext.cpp | 36 +++++++++++++++++ libretro/LibretroGLCoreContext.h | 37 +++++++++++++++++ libretro/LibretroGraphicsContext.cpp | 60 +++++++++++++++++++--------- libretro/Makefile.common | 3 +- 6 files changed, 117 insertions(+), 22 deletions(-) create mode 100644 libretro/LibretroGLCoreContext.cpp create mode 100644 libretro/LibretroGLCoreContext.h diff --git a/libretro/CMakeLists.txt b/libretro/CMakeLists.txt index b590cc25df..69efea8980 100644 --- a/libretro/CMakeLists.txt +++ b/libretro/CMakeLists.txt @@ -3,6 +3,7 @@ set(LIBRETRO_SRCS libretro.cpp LibretroGraphicsContext.cpp LibretroGLContext.cpp + LibretroGLCoreContext.cpp LibretroVulkanContext.cpp libretro_vulkan.cpp) diff --git a/libretro/LibretroGLContext.h b/libretro/LibretroGLContext.h index b85c8affb0..73c29701b7 100644 --- a/libretro/LibretroGLContext.h +++ b/libretro/LibretroGLContext.h @@ -9,8 +9,6 @@ public: LibretroGLContext() #ifdef USING_GLES2 : LibretroHWRenderContext(RETRO_HW_CONTEXT_OPENGLES2) -#elif defined(HAVE_OPENGL_CORE) - : LibretroHWRenderContext(RETRO_HW_CONTEXT_OPENGL_CORE, 3, 1) #else : LibretroHWRenderContext(RETRO_HW_CONTEXT_OPENGL) #endif diff --git a/libretro/LibretroGLCoreContext.cpp b/libretro/LibretroGLCoreContext.cpp new file mode 100644 index 0000000000..14c816f1cf --- /dev/null +++ b/libretro/LibretroGLCoreContext.cpp @@ -0,0 +1,36 @@ + +#include "Common/Log.h" +#include "Core/Config.h" +#include "Core/ConfigValues.h" +#include "Core/System.h" +#include "gfx_es2/gpu_features.h" + +#include "libretro/LibretroGLCoreContext.h" + +bool LibretroGLCoreContext::Init() { + if (!LibretroHWRenderContext::Init(true)) + return false; + + g_Config.iGPUBackend = (int)GPUBackend::OPENGL; + return true; +} + +void LibretroGLCoreContext::CreateDrawContext() { + if (!glewInitDone) { +#if !defined(IOS) && !defined(USING_GLES2) + if (glewInit() != GLEW_OK) { + ERROR_LOG(G3D, "glewInit() failed.\n"); + return; + } +#endif + glewInitDone = true; + CheckGLExtensions(); + } + draw_ = Draw::T3DCreateGLContext(); + renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); +} + +void LibretroGLCoreContext::DestroyDrawContext() { + LibretroHWRenderContext::DestroyDrawContext(); + renderManager_ = nullptr; +} diff --git a/libretro/LibretroGLCoreContext.h b/libretro/LibretroGLCoreContext.h new file mode 100644 index 0000000000..7719a867c2 --- /dev/null +++ b/libretro/LibretroGLCoreContext.h @@ -0,0 +1,37 @@ +#pragma once + +#include "gfx/gl_common.h" +#include "libretro/LibretroGraphicsContext.h" +#include "thin3d/GLRenderManager.h" + +class LibretroGLCoreContext : public LibretroHWRenderContext { +public: + LibretroGLCoreContext() + : LibretroHWRenderContext(RETRO_HW_CONTEXT_OPENGL_CORE, 3, 1) + { + hw_render_.bottom_left_origin = true; + } + + bool Init() override; + void CreateDrawContext() override; + void DestroyDrawContext() override; + void SetRenderTarget() override { + extern GLuint g_defaultFBO; + g_defaultFBO = hw_render_.get_current_framebuffer(); + } + + void ThreadStart() override { renderManager_->ThreadStart(draw_); } + bool ThreadFrame() override { return renderManager_->ThreadFrame(); } + void ThreadEnd() override { renderManager_->ThreadEnd(); } + void StopThread() override { + renderManager_->WaitUntilQueueIdle(); + renderManager_->StopThread(); + } + + GPUCore GetGPUCore() override { return GPUCORE_GLES; } + const char *Ident() override { return "OpenGL Core"; } + +private: + GLRenderManager *renderManager_ = nullptr; + bool glewInitDone = false; +}; diff --git a/libretro/LibretroGraphicsContext.cpp b/libretro/LibretroGraphicsContext.cpp index 4facea7683..01ce61068d 100644 --- a/libretro/LibretroGraphicsContext.cpp +++ b/libretro/LibretroGraphicsContext.cpp @@ -1,6 +1,7 @@ #include "libretro/LibretroGraphicsContext.h" #include "libretro/LibretroGLContext.h" +#include "libretro/LibretroGLCoreContext.h" #include "libretro/libretro.h" #include "libretro/LibretroVulkanContext.h" #ifdef _WIN32 @@ -88,34 +89,55 @@ void LibretroGraphicsContext::LostBackbuffer() { draw_->HandleEvent(Draw::Event: LibretroGraphicsContext *LibretroGraphicsContext::CreateGraphicsContext() { LibretroGraphicsContext *ctx; - ctx = new LibretroGLContext(); + retro_hw_context_type preferred; + if (!Libretro::environ_cb(RETRO_ENVIRONMENT_GET_PREFERRED_HW_RENDER, &preferred)) + preferred = RETRO_HW_CONTEXT_DUMMY; - if (ctx->Init()) { - return ctx; +#ifndef USING_GLES2 + if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_OPENGL_CORE) { + ctx = new LibretroGLCoreContext(); + + if (ctx->Init()) { + return ctx; + } + delete ctx; } - delete ctx; +#endif - ctx = new LibretroVulkanContext(); + if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_OPENGL) { + ctx = new LibretroGLContext(); - if (ctx->Init()) { - return ctx; + if (ctx->Init()) { + return ctx; + } + delete ctx; + } + + if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_VULKAN) { + ctx = new LibretroVulkanContext(); + + if (ctx->Init()) { + return ctx; + } + delete ctx; } - delete ctx; #ifdef _WIN32 - ctx = new LibretroD3D11Context(); + if (preferred == RETRO_HW_CONTEXT_DUMMY || preferred == RETRO_HW_CONTEXT_DIRECT3D) { + ctx = new LibretroD3D11Context(); - if (ctx->Init()) { - return ctx; + if (ctx->Init()) { + return ctx; + } + delete ctx; + + ctx = new LibretroD3D9Context(); + + if (ctx->Init()) { + return ctx; + } + delete ctx; } - delete ctx; - - ctx = new LibretroD3D9Context(); - - if (ctx->Init()) { - return ctx; - } - delete ctx; #endif #if 1 diff --git a/libretro/Makefile.common b/libretro/Makefile.common index f5c2ef547f..1aa15ddfad 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -696,7 +696,8 @@ endif SOURCES_CXX += \ $(LIBRETRODIR)/libretro.cpp \ $(LIBRETRODIR)/LibretroGraphicsContext.cpp \ - $(LIBRETRODIR)/LibretroGLContext.cpp + $(LIBRETRODIR)/LibretroGLContext.cpp \ + $(LIBRETRODIR)/LibretroGLCoreContext.cpp ifneq ($(STATIC_LINKING), 1) SOURCES_C += \ From a8dd3ef55346c8eaebe9d67d9406a91058a64cf9 Mon Sep 17 00:00:00 2001 From: barbudreadmon Date: Sun, 27 Sep 2020 16:38:24 +0200 Subject: [PATCH 779/848] fix #13471 --- GPU/Common/PresentationCommon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index f2ce4721da..53c09b9d04 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -210,7 +210,7 @@ static std::string ReadShaderSrc(const std::string &filename) { // Note: called on resize and settings changes. bool PresentationCommon::UpdatePostShader() { std::vector shaderInfo; - if (g_Config.vPostShaderNames[0] != "Off") { + if (!g_Config.vPostShaderNames.empty() && g_Config.vPostShaderNames[0] != "Off") { ReloadAllPostShaderInfo(); shaderInfo = GetFullPostShadersChain(g_Config.vPostShaderNames); } @@ -754,7 +754,7 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u void PresentationCommon::CalculateRenderResolution(int *width, int *height, bool *upscaling, bool *ssaa) { // Check if postprocessing shader is doing upscaling as it requires native resolution std::vector shaderInfo; - if (g_Config.vPostShaderNames[0] != "Off") { + if (!g_Config.vPostShaderNames.empty() && g_Config.vPostShaderNames[0] != "Off") { ReloadAllPostShaderInfo(); shaderInfo = GetFullPostShadersChain(g_Config.vPostShaderNames); } From 2714d59ceb46a595d91bbd0324e4eb2c6eaf4baa Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 27 Sep 2020 12:54:34 -0700 Subject: [PATCH 780/848] Core: Fix memory size check. It can be 93 MB, just not larger. --- Core/MemMap.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 1a60d42b9c..69c23c85e5 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -282,10 +282,9 @@ void MemoryMap_Shutdown(u32 flags) { } bool Init() { - // On some 32 bit platforms, you can only map < 32 megs at a time. - // TODO: Wait, wtf? What platforms are those? This seems bad. + // On some 32 bit platforms (like Android, iOS, etc.), you can only map < 32 megs at a time. const static int MAX_MMAP_SIZE = 31 * 1024 * 1024; - _dbg_assert_msg_(g_MemorySize < MAX_MMAP_SIZE * 3, "ACK - too much memory for three mmap views."); + _dbg_assert_msg_(g_MemorySize <= MAX_MMAP_SIZE * 3, "ACK - too much memory for three mmap views."); for (size_t i = 0; i < ARRAY_SIZE(views); i++) { if (views[i].flags & MV_IS_PRIMARY_RAM) views[i].size = std::min((int)g_MemorySize, MAX_MMAP_SIZE); From ab953603d86c910c7bdb363a37f1103272f6e779 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 27 Sep 2020 12:55:02 -0700 Subject: [PATCH 781/848] SDL: Adjust locale parsing for Ubuntu. Technically, the format of this value is unspecified, but we are just trying to guess the user's locale. See #13042. --- SDL/SDLMain.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 119ea7419b..ada9a5ccf1 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -282,12 +282,19 @@ std::string System_GetProperty(SystemProperty prop) { // Set c and c++ strings back to POSIX std::locale::global(std::locale("POSIX")); if (!locale.empty()) { + // Technically, this is an opaque string, but try to find the locale code. + size_t messagesPos = locale.find("LC_MESSAGES="); + if (messagesPos != std::string::npos) { + messagesPos += strlen("LC_MESSAGES="); + size_t semi = locale.find(';', messagesPos); + locale = locale.substr(messagesPos, semi - messagesPos); + } + if (locale.find("_", 0) != std::string::npos) { if (locale.find(".", 0) != std::string::npos) { return locale.substr(0, locale.find(".",0)); - } else { - return locale; } + return locale; } } return "en_US"; From 0f34a7427b9f762039c25057a891481030b1bead Mon Sep 17 00:00:00 2001 From: RokkumanX <50436544+RokkumanX@users.noreply.github.com> Date: Mon, 28 Sep 2020 09:31:33 +0200 Subject: [PATCH 782/848] Add PSP color shader This adds the PSP color shader ported from RetroArch courtesy from @jdgleaver (https://forums.ppsspp.org/showthread.php?tid=6594&pid=130635#pid130635) to PPSSPP Also updated with up to date changes found here (https://github.com/libretro/glsl-shaders/blob/master/handheld/shaders/color/psp-color.glsl) --- assets/shaders/psp_color.fsh | 58 ++++++++++++++++++++++++++++++++++++ assets/shaders/psp_color.ini | 6 ++++ assets/shaders/psp_color.vsh | 23 ++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 assets/shaders/psp_color.fsh create mode 100644 assets/shaders/psp_color.ini create mode 100644 assets/shaders/psp_color.vsh diff --git a/assets/shaders/psp_color.fsh b/assets/shaders/psp_color.fsh new file mode 100644 index 0000000000..aad99df883 --- /dev/null +++ b/assets/shaders/psp_color.fsh @@ -0,0 +1,58 @@ +/* + psp_color vertex shader + + Original code written by hunterk, modified by Pokefan531 and + released into the public domain + + 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + Notes: This shader replicates the LCD dynamics of the PSP 1000 and PSP 2000 +*/ + +//================ +#ifdef GL_ES +precision mediump float; +precision mediump int; +// For android, use this instead... +//precision highp float; +//precision highp int; +// +#endif + +//================ +#define target_gamma 2.21 +#define display_gamma 2.2 +#define r 0.98 +#define g 0.795 +#define b 0.98 +#define rg 0.04 +#define rb 0.01 +#define gr 0.20 +#define gb 0.01 +#define br -0.18 +#define bg 0.165 + +//================ +uniform sampler2D sampler0; +varying vec2 v_texcoord0; + +//================ +void main() +{ + // Apply colour correction + vec3 screen = pow(texture2D(sampler0, v_texcoord0.xy).rgb, vec3(target_gamma)); + screen = clamp(screen, 0.0, 1.0); + screen = pow( + mat3(r, rg, rb, + gr, g, gb, + br, bg, b) * screen, + vec3(1.0 / display_gamma) + ); + + gl_FragColor = vec4(screen, 1.0); +} diff --git a/assets/shaders/psp_color.ini b/assets/shaders/psp_color.ini new file mode 100644 index 0000000000..73cae04bb2 --- /dev/null +++ b/assets/shaders/psp_color.ini @@ -0,0 +1,6 @@ +[PSP Color] +Name=PSP Color +Author=hunterk, Pokefan531 (ported by jdgleaver) +Fragment=psp_color.fsh +Vertex=psp_color.vsh +OutputResolution=True diff --git a/assets/shaders/psp_color.vsh b/assets/shaders/psp_color.vsh new file mode 100644 index 0000000000..0353e17dae --- /dev/null +++ b/assets/shaders/psp_color.vsh @@ -0,0 +1,23 @@ +/* + psp_color vertex shader + + Original code written by hunterk, modified by Pokefan531 and + released into the public domain + + 'Ported' (i.e. copy/paste) to PPSSPP format by jdgleaver + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. +*/ + +attribute vec4 a_position; +attribute vec2 a_texcoord0; +varying vec2 v_texcoord0; + +void main() +{ + v_texcoord0 = a_texcoord0; // + 0.000001; // HLSL precision workaround (is this needed???) + gl_Position = a_position; +} From 6fb0e92de36bbd89d3e5026cbfad927590f0de30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 00:29:40 +0200 Subject: [PATCH 783/848] Fix issue with duplicate texture dumps. Fixes #13487. --- GPU/Common/TextureCacheCommon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 2c47e38170..b00d783338 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -458,7 +458,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { nextNeedsChange_ = false; // Might need a rebuild if the hash fails, but that will be set later. nextNeedsRebuild_ = false; - VERBOSE_LOG(G3D, "Texture at %08x Found in Cache, applying", texaddr); + VERBOSE_LOG(G3D, "Texture at %08x found in cache, applying", texaddr); return entry; //Done! } else { // Wasn't a match, we will rebuild. @@ -556,7 +556,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { if (nextFramebufferTexture_) { nextFramebufferTexture_ = nullptr; // in case it was accidentally set somehow? } - nextNeedsRehash_ = false; + nextNeedsRehash_ = true; // We still need to rebuild, to allocate a texture. But we'll bail early. nextNeedsRebuild_ = true; return entry; From 5411a40f2a8ce23dbf0cd6a8d64512b724c48ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 25 Sep 2020 09:33:42 +0200 Subject: [PATCH 784/848] TimeUtil.cpp cleanup --- Common/TimeUtil.cpp | 33 +++++---------------------------- Common/TimeUtil.h | 17 ----------------- 2 files changed, 5 insertions(+), 45 deletions(-) diff --git a/Common/TimeUtil.cpp b/Common/TimeUtil.cpp index 41986021c9..5b8a0c2611 100644 --- a/Common/TimeUtil.cpp +++ b/Common/TimeUtil.cpp @@ -20,9 +20,9 @@ static double curtime = 0; #ifdef _WIN32 -LARGE_INTEGER frequency; -double frequencyMult; -LARGE_INTEGER startTime; +static LARGE_INTEGER frequency; +static double frequencyMult; +static LARGE_INTEGER startTime; double time_now_d() { if (frequency.QuadPart == 0) { @@ -39,8 +39,8 @@ double time_now_d() { #else -uint64_t _frequency = 0; -uint64_t _starttime = 0; +static uint64_t _frequency = 0; +static uint64_t _starttime = 0; double time_now_d() { static time_t start; @@ -64,26 +64,3 @@ void sleep_ms(int ms) { usleep(ms * 1000); #endif } - -LoggingDeadline::LoggingDeadline(const char *name, int ms) : name_(name), endCalled_(false) { - totalTime_ = (double)ms * 0.001; - endTime_ = time_now_d() + totalTime_; -} - -LoggingDeadline::~LoggingDeadline() { - if (!endCalled_) - End(); -} - -bool LoggingDeadline::End() { - endCalled_ = true; - double now = time_now_d(); - if (now > endTime_) { - double late = (now - endTime_); - double totalTime = late + totalTime_; - ERROR_LOG(SYSTEM, "===== %0.2fms DEADLINE PASSED FOR %s at %0.2fms - %0.2fms late =====", totalTime_ * 1000.0, name_, 1000.0 * totalTime, 1000.0 * late); - return false; - } - return true; -} - diff --git a/Common/TimeUtil.h b/Common/TimeUtil.h index b6362cac4e..c19e98f5ad 100644 --- a/Common/TimeUtil.h +++ b/Common/TimeUtil.h @@ -1,24 +1,7 @@ #pragma once -// http://linux.die.net/man/3/clock_gettime - // Seconds. double time_now_d(); // Sleep. Does not necessarily have millisecond granularity, especially on Windows. void sleep_ms(int ms); - -// Can be sprinkled around the code to make sure that thing don't take -// unexpectedly long. What that means is up to you. -class LoggingDeadline { -public: - LoggingDeadline(const char *name, int deadline_in_ms); - ~LoggingDeadline(); - bool End(); - -private: - const char *name_; - bool endCalled_; - double totalTime_; - double endTime_; -}; From 204fbe463eb7b5da9239955e28de411c656f85af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 25 Sep 2020 09:33:56 +0200 Subject: [PATCH 785/848] Delete unused backtrace.cpp --- CMakeLists.txt | 2 -- UWP/NativeUWP/NativeUWP.vcxproj | 2 -- UWP/NativeUWP/NativeUWP.vcxproj.filters | 6 ------ ext/native/Android.mk | 1 - ext/native/base/CMakeLists.txt | 2 +- ext/native/base/backtrace.cpp | 22 ---------------------- ext/native/base/backtrace.h | 3 --- ext/native/native.vcxproj | 2 -- ext/native/native.vcxproj.filters | 8 +------- libretro/Makefile.common | 1 - 10 files changed, 2 insertions(+), 47 deletions(-) delete mode 100644 ext/native/base/backtrace.cpp delete mode 100644 ext/native/base/backtrace.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e83e590f44..006843ac21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -939,8 +939,6 @@ endif() add_library(native STATIC ${nativeExtra} - ext/native/base/backtrace.cpp - ext/native/base/backtrace.h ext/native/base/basictypes.h ext/native/base/buffer.cpp ext/native/base/buffer.h diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 0fba453b04..9fe46fd1b6 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -379,7 +379,6 @@ - @@ -473,7 +472,6 @@ - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 8835c898dd..b955c76d5f 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -64,9 +64,6 @@ - - base - base @@ -475,9 +472,6 @@ - - base - base diff --git a/ext/native/Android.mk b/ext/native/Android.mk index d95685387d..75bf2b31be 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -7,7 +7,6 @@ include $(CLEAR_VARS) LOCAL_MODULE := libnative LOCAL_ARM_MODE := arm LOCAL_SRC_FILES :=\ - base/backtrace.cpp \ base/buffer.cpp \ base/display.cpp \ base/colorutil.cpp \ diff --git a/ext/native/base/CMakeLists.txt b/ext/native/base/CMakeLists.txt index 7044873bbe..1e4f0530dd 100644 --- a/ext/native/base/CMakeLists.txt +++ b/ext/native/base/CMakeLists.txt @@ -3,7 +3,7 @@ set(SRCS ../thread/threadutil.cpp display.cpp buffer.cpp - backtrace.cpp) +) add_library(base STATIC ${SRCS}) diff --git a/ext/native/base/backtrace.cpp b/ext/native/base/backtrace.cpp deleted file mode 100644 index 2b5cddb972..0000000000 --- a/ext/native/base/backtrace.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "base/backtrace.h" - -#if (defined(__GLIBC__) && !defined(__UCLIBC__)) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) -#include -#include - -static void *backtrace_buffer[128]; - -void PrintBacktraceToStderr() { - int num_addrs = backtrace(backtrace_buffer, 128); - backtrace_symbols_fd(backtrace_buffer, num_addrs, STDERR_FILENO); -} - -#else - -#include - -void PrintBacktraceToStderr() { - fprintf(stderr, "No backtrace available to print on this platform\n"); -} - -#endif diff --git a/ext/native/base/backtrace.h b/ext/native/base/backtrace.h deleted file mode 100644 index 4ff0917f30..0000000000 --- a/ext/native/base/backtrace.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void PrintBacktraceToStderr(); diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 338f014265..ccd6b2d7f5 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -382,7 +382,6 @@ - @@ -490,7 +489,6 @@ - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 6f6f940372..9363be3e69 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -131,9 +131,6 @@ ui - - base - math @@ -439,9 +436,6 @@ ui - - base - math @@ -907,4 +901,4 @@ {5b740c6f-8dbc-4529-9114-6564b37b3548} - \ No newline at end of file + diff --git a/libretro/Makefile.common b/libretro/Makefile.common index f5c2ef547f..b53cce49a3 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -214,7 +214,6 @@ SOURCES_CXX += \ $(GPUDIR)/GLES/ShaderManagerGLES.cpp \ $(GPUDIR)/GLES/StateMappingGLES.cpp \ $(GPUDIR)/GLES/StencilBufferGLES.cpp \ - $(EXTDIR)/native/base/backtrace.cpp \ $(EXTDIR)/native/base/buffer.cpp \ $(EXTDIR)/native/base/colorutil.cpp \ $(EXTDIR)/native/base/display.cpp \ From 536d881626e39feab4ca252c8e12804abfebed4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 00:35:38 +0200 Subject: [PATCH 786/848] Very minor optimization (divisions by constants are faster unsigned) --- GPU/GPUCommon.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 66bfc80fe9..da92f820c4 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -2337,9 +2337,9 @@ void GPUCommon::Execute_Unknown(u32 op, u32 diff) { } void GPUCommon::FastLoadBoneMatrix(u32 target) { - const int num = gstate.boneMatrixNumber & 0x7F; - const int mtxNum = num / 12; - uint32_t uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum; + const u32 num = gstate.boneMatrixNumber & 0x7F; + const u32 mtxNum = num / 12; + u32 uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum; if (num != 12 * mtxNum) { uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7); } From 30ecde5bc94c95950cc750133c59861a38497d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 00:41:32 +0200 Subject: [PATCH 787/848] Delete some unused string functions --- ext/native/base/stringutil.cpp | 53 ---------------------------------- ext/native/base/stringutil.h | 19 ------------ ext/native/file/ini_file.h | 2 +- ext/native/ui/view.cpp | 3 +- ext/native/ui/viewgroup.cpp | 3 +- 5 files changed, 3 insertions(+), 77 deletions(-) diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp index b3a992c711..965c458040 100644 --- a/ext/native/base/stringutil.cpp +++ b/ext/native/base/stringutil.cpp @@ -34,33 +34,12 @@ std::string LineNumberString(const std::string &str) { return output.str(); } -void StringTrimEndNonAlphaNum(char *str) { - ssize_t n = strlen(str); - while (!isalnum(str[n]) && n >= 0) { - str[n--] = '\0'; - } -} - void SkipSpace(const char **ptr) { while (**ptr && isspace(**ptr)) { (*ptr)++; } } -void StringUpper(char *str) { - while (*str) { - *str = toupper(*str); - str++; - } -} - -void StringUpper(char *str, int len) { - while (len--) { - *str = toupper(*str); - str++; - } -} - void DataToHexString(const uint8_t *data, size_t size, std::string *output) { Buffer buffer; for (size_t i = 0; i < size; i++) { @@ -140,11 +119,6 @@ std::string StringFromInt(int value) return temp; } -std::string StringFromBool(bool value) -{ - return value ? "True" : "False"; -} - // Turns " hej " into "hej". Also handles tabs. std::string StripSpaces(const std::string &str) { @@ -167,27 +141,6 @@ std::string StripQuotes(const std::string& s) return s; } -// For Debugging. Read out an u8 array. -std::string ArrayToString(const uint8_t *data, uint32_t size, int line_len, bool spaces) -{ - std::ostringstream oss; - oss << std::setfill('0') << std::hex; - - for (int line = 0; size; ++data, --size) - { - oss << std::setw(2) << (int)*data; - if (line_len == ++line) - { - oss << '\n'; - line = 0; - } - else if (spaces) - oss << ' '; - } - - return oss.str(); -} - void SplitString(const std::string& str, const char delim, std::vector& output) { size_t next = 0; @@ -243,9 +196,3 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st } return result; } - -int strcmpIgnore(std::string str1, std::string str2, std::string ignorestr1, std::string ignorestr2) { - str1 = ReplaceAll(str1, ignorestr1, ignorestr2); - str2 = ReplaceAll(str2, ignorestr1, ignorestr2); - return strcmp(str1.c_str(),str2.c_str()); -} diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h index 6721930195..3a64058838 100644 --- a/ext/native/base/stringutil.h +++ b/ext/native/base/stringutil.h @@ -13,16 +13,6 @@ #include #endif -// Dumb wrapper around itoa, providing a buffer. Declare this on the stack. -class ITOA { -public: - char buffer[16]; - const char *p(int i) { - sprintf(buffer, "%i", i); - return &buffer[0]; - } -}; - // Useful for shaders with error messages.. std::string LineNumberString(const std::string &str); @@ -62,9 +52,6 @@ inline void StringToHexString(const std::string &data, std::string *output) { std::string StringFromFormat(const char* format, ...); std::string StringFromInt(int value); -std::string StringFromBool(bool value); - -std::string ArrayToString(const uint8_t *data, uint32_t size, int line_len = 20, bool spaces = true); std::string StripSpaces(const std::string &s); std::string StripQuotes(const std::string &s); @@ -75,10 +62,4 @@ void GetQuotedStrings(const std::string& str, std::vector& output); std::string ReplaceAll(std::string input, const std::string& src, const std::string& dest); -// Compare two strings, ignore the difference between the ignorestr1 and the ignorestr2 in str1 and str2. -int strcmpIgnore(std::string str1, std::string str2, std::string ignorestr1, std::string ignorestr2); - -void StringTrimEndNonAlphaNum(char *str); void SkipSpace(const char **ptr); -void StringUpper(char *str); -void StringUpper(char *str, int len); diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h index 41d7bb711f..4c2b65ed4b 100644 --- a/ext/native/file/ini_file.h +++ b/ext/native/file/ini_file.h @@ -52,7 +52,7 @@ public: void Set(const char* key, bool newValue, bool defaultValue); void Set(const char* key, bool newValue) { - Set(key, StringFromBool(newValue).c_str()); + Set(key, newValue ? "True" : "False"); } void Set(const char* key, const std::vector& newValues); diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 849ec8947a..b8e62a5cce 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -162,9 +162,8 @@ void View::PersistData(PersistStatus status, std::string anonId, PersistMap &sto break; } - ITOA stringify; for (int i = 0; i < (int)tweens_.size(); ++i) { - tweens_[i]->PersistData(status, tag + "/" + stringify.p((int)i), storage); + tweens_[i]->PersistData(status, tag + "/" + StringFromInt(i), storage); } } diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index 1a13ac27e9..cd3221f790 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -70,9 +70,8 @@ void ViewGroup::PersistData(PersistStatus status, std::string anonId, PersistMap tag = anonId; } - ITOA stringify; for (size_t i = 0; i < views_.size(); i++) { - views_[i]->PersistData(status, tag + "/" + stringify.p((int)i), storage); + views_[i]->PersistData(status, tag + "/" + StringFromInt((int)i), storage); } } From 1e6c13cb56865e5876c00d33e68e0c7aebe5a5b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 10:07:07 +0200 Subject: [PATCH 788/848] Delete more old detritus --- Core/HLE/sceNetAdhoc.cpp | 2 +- UWP/NativeUWP/NativeUWP.vcxproj | 1 - UWP/NativeUWP/NativeUWP.vcxproj.filters | 3 -- ext/native/data/compression.h | 23 +----------- ext/native/data/listable.h | 49 ------------------------- ext/native/file/chunk_file.cpp | 3 -- ext/native/file/chunk_file.h | 4 +- ext/native/native.vcxproj | 3 +- ext/native/native.vcxproj.filters | 11 +----- 9 files changed, 6 insertions(+), 93 deletions(-) delete mode 100644 ext/native/data/listable.h diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 470b53bb0a..0645f4c707 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -6415,7 +6415,7 @@ void actOnBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * se SceNetEtherAddr mac; memcpy(&mac, context->rxbuf + 1, sizeof(SceNetEtherAddr)); - // Allocate Memory (If this fails... we are fucked.) + // Allocate Memory SceNetAdhocMatchingMemberInternal * sibling = (SceNetAdhocMatchingMemberInternal *)malloc(sizeof(SceNetAdhocMatchingMemberInternal)); // Allocated Memory diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 9fe46fd1b6..70bc7f2a6e 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -390,7 +390,6 @@ - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index b955c76d5f..eed8497fbb 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -712,9 +712,6 @@ data - - data - diff --git a/ext/native/data/compression.h b/ext/native/data/compression.h index e37ff85794..5323b8f549 100644 --- a/ext/native/data/compression.h +++ b/ext/native/data/compression.h @@ -2,27 +2,6 @@ #include +// inflate/deflate convenience wrapper. Uses zlib. bool compress_string(const std::string& str, std::string *dest, int compressionlevel = 9); bool decompress_string(const std::string& str, std::string *dest); - - -// Delta encoding/decoding - many formats benefit from a pass of this before zlibbing. -// WARNING : Do not use these with floating point data, especially not float16... - -template -inline void delta(T *data, int length) { - T prev = data[0]; - for (int i = 1; i < length; i++) { - T temp = data[i] - prev; - prev = data[i]; - data[i] = temp; - } -} - -template -inline void dedelta(T *data, int length) { - for (int i = 1; i < length; i++) { - data[i] += data[i - 1]; - } -} - diff --git a/ext/native/data/listable.h b/ext/native/data/listable.h deleted file mode 100644 index 017cacf1b9..0000000000 --- a/ext/native/data/listable.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include - -class Listable -{ -public: - virtual ~Listable() {} - virtual const char *getItem(size_t i) const = 0; - virtual size_t numItems() const = 0; - - // Returns -1 for not found. - // Child classes are meant to specialize this if they have a faster way - // than brute force search. - virtual int getIndex(const char *text) { - for (size_t i = 0; i < numItems(); i++) { - if (!strcmp(getItem(i), text)) - return i; - } - return -1; - } -}; - -class ArrayListable : public Listable -{ -public: - ArrayListable(const char * const*arr, size_t count) : arr_(arr), count_(count) {} - virtual ~ArrayListable() {} - - virtual const char *getItem(size_t i) const { return arr_[i]; } - virtual size_t numItems() const { return count_; } - -private: - const char *const*arr_; - size_t count_; -}; - -class VectorListable : public Listable -{ - VectorListable(const std::vector &vec) : vec_(vec) {} - virtual ~VectorListable() {} - - virtual const char *getItem(size_t i) const { return vec_[i].c_str(); } - virtual size_t numItems() const { return vec_.size(); } - -private: - const std::vector &vec_; -}; \ No newline at end of file diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index 20553a8657..2dab992913 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -29,7 +29,6 @@ int RIFFReader::ReadInt() { return 0; } -// let's get into the business bool RIFFReader::Descend(uint32_t intoId) { if (depth_ > 30) return false; @@ -83,7 +82,6 @@ bool RIFFReader::Descend(uint32_t intoId) { return true; } -// let's ascend out void RIFFReader::Ascend() { // ascend, and restore information depth_--; @@ -91,7 +89,6 @@ void RIFFReader::Ascend() { eof_ = stack[depth_].parentEOF; } -// read a block void RIFFReader::ReadData(void *what, int count) { memcpy(what, data_ + pos_, count); pos_ += count; diff --git a/ext/native/file/chunk_file.h b/ext/native/file/chunk_file.h index 18d8a80e8b..ebc2db99a4 100644 --- a/ext/native/file/chunk_file.h +++ b/ext/native/file/chunk_file.h @@ -1,7 +1,7 @@ #pragma once -// RIFF file format reader/writer. Very old code, basically a total mess but it still works. -// Has nothing to do with the ChunkFile.h used in Dolphin or PPSSPP. +// Simple RIFF file format reader/writer. +// Unrelated to the ChunkFile.h used in Dolphin and PPSSPP. // TO REMEMBER WHEN USING: diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index ccd6b2d7f5..7e5e759400 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -390,7 +390,6 @@ - @@ -1211,4 +1210,4 @@ - + \ No newline at end of file diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 9363be3e69..a1f06f8607 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -110,12 +110,6 @@ ui - - data - - - base - net @@ -775,9 +769,6 @@ thin3d - - base - gfx @@ -901,4 +892,4 @@ {5b740c6f-8dbc-4529-9114-6564b37b3548} - + \ No newline at end of file From db9cc41a1a5c6817aa65415af554a6049368f7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 10:07:20 +0200 Subject: [PATCH 789/848] Delete unused math code --- CMakeLists.txt | 5 - UWP/NativeUWP/NativeUWP.vcxproj | 4 - UWP/NativeUWP/NativeUWP.vcxproj.filters | 12 --- ext/native/Android.mk | 2 - ext/native/math/CMakeLists.txt | 5 +- ext/native/math/lin/matrix4x4.cpp | 1 - ext/native/math/lin/plane.cpp | 13 --- ext/native/math/lin/plane.h | 41 -------- ext/native/math/lin/quat.cpp | 129 ------------------------ ext/native/math/lin/quat.h | 96 ------------------ ext/native/math/lin/ray.h | 14 --- ext/native/native.vcxproj | 4 - ext/native/native.vcxproj.filters | 15 --- libretro/Makefile.common | 2 - 14 files changed, 2 insertions(+), 341 deletions(-) delete mode 100644 ext/native/math/lin/plane.cpp delete mode 100644 ext/native/math/lin/plane.h delete mode 100644 ext/native/math/lin/quat.cpp delete mode 100644 ext/native/math/lin/quat.h delete mode 100644 ext/native/math/lin/ray.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 006843ac21..b2804099bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1022,11 +1022,6 @@ add_library(native STATIC ext/native/math/expression_parser.h ext/native/math/lin/matrix4x4.cpp ext/native/math/lin/matrix4x4.h - ext/native/math/lin/plane.cpp - ext/native/math/lin/plane.h - ext/native/math/lin/quat.cpp - ext/native/math/lin/quat.h - ext/native/math/lin/ray.h ext/native/math/lin/vec3.cpp ext/native/math/lin/vec3.h ext/native/math/math_util.cpp diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 70bc7f2a6e..0d4f747f02 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -434,8 +434,6 @@ - - @@ -1585,8 +1583,6 @@ - - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index eed8497fbb..a424450ad6 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -166,12 +166,6 @@ math - - math - - - math - math @@ -601,12 +595,6 @@ math - - math - - - math - math diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 75bf2b31be..a922490f88 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -52,8 +52,6 @@ LOCAL_SRC_FILES :=\ math/math_util.cpp \ math/curves.cpp \ math/expression_parser.cpp \ - math/lin/plane.cpp.arm \ - math/lin/quat.cpp.arm \ math/lin/vec3.cpp.arm \ math/lin/matrix4x4.cpp.arm \ net/http_client.cpp \ diff --git a/ext/native/math/CMakeLists.txt b/ext/native/math/CMakeLists.txt index 4093973f06..3d6e0daa52 100644 --- a/ext/native/math/CMakeLists.txt +++ b/ext/native/math/CMakeLists.txt @@ -1,9 +1,8 @@ set(SRCS lin/matrix4x4.cpp lin/vec3.cpp - lin/quat.cpp - curves.cpp - math_util.cpp + curves.cpp + math_util.cpp ) set(SRCS ${SRCS}) diff --git a/ext/native/math/lin/matrix4x4.cpp b/ext/native/math/lin/matrix4x4.cpp index 007b8a8d17..7b4179bfef 100644 --- a/ext/native/math/lin/matrix4x4.cpp +++ b/ext/native/math/lin/matrix4x4.cpp @@ -3,7 +3,6 @@ #include #include "math/lin/vec3.h" -#include "math/lin/quat.h" #include "math/fast/fast_matrix.h" #ifdef _WIN32 diff --git a/ext/native/math/lin/plane.cpp b/ext/native/math/lin/plane.cpp deleted file mode 100644 index d62277889d..0000000000 --- a/ext/native/math/lin/plane.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "math/lin/matrix4x4.h" -#include "math/lin/plane.h" - -namespace Lin { - -void Plane::TransformByIT(const Matrix4x4 &m, Plane *out) { - out->x = x * m.xx + y * m.yx + z * m.zx + d * m.wx; - out->y = x * m.xy + y * m.yy + z * m.zy + d * m.wy; - out->z = x * m.xz + y * m.yz + z * m.zz + d * m.wz; - out->d = x * m.xw + y * m.yw + z * m.zw + d * m.ww; -} - -} // namespace Lin diff --git a/ext/native/math/lin/plane.h b/ext/native/math/lin/plane.h deleted file mode 100644 index 295c3f250a..0000000000 --- a/ext/native/math/lin/plane.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _PLANE_H -#define _PLANE_H - -#include "math/lin/vec3.h" - -namespace Lin { - -class Matrix4x4; - -class Plane { -public: - float x, y, z, d; - Plane() {} - Plane(float x_, float y_, float z_, float d_) - : x(x_), y(y_), z(z_), d(d_) { } - ~Plane() {} - - float Distance(const Vec3 &v) const { - return x * v.x + y * v.y + z * v.z + d; - } - - float Distance(float px, float py, float pz) const { - return x * px + y * py + z * pz + d; - } - - void Normalize() { - float inv_length = sqrtf(x * x + y * y + z * z); - x *= inv_length; - y *= inv_length; - z *= inv_length; - d *= inv_length; - } - - // Matrix is the inverse transpose of the wanted transform. - // out cannot be equal to this. - void TransformByIT(const Matrix4x4 &matrix, Plane *out); -}; - -} // namespace Lin - -#endif diff --git a/ext/native/math/lin/quat.cpp b/ext/native/math/lin/quat.cpp deleted file mode 100644 index f5479a51f5..0000000000 --- a/ext/native/math/lin/quat.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "math/lin/quat.h" -#include "math/lin/matrix4x4.h" - -namespace Lin { - -void Quaternion::toMatrix(Matrix4x4 *out) const { - Matrix4x4 temp; - temp.setIdentity(); - float ww, xx, yy, zz, wx, wy, wz, xy, xz, yz; - ww = w*w; xx = x*x; yy = y*y; zz = z*z; - wx = w*x*2; wy = w*y*2; wz = w*z*2; - xy = x*y*2; xz = x*z*2; yz = y*z*2; - - temp.xx = ww + xx - yy - zz; - temp.xy = xy + wz; - temp.xz = xz - wy; - - temp.yx = xy - wz; - temp.yy = ww - xx + yy - zz; - temp.yz = yz + wx; - - temp.zx = xz + wy; - temp.zy = yz - wx; - temp.zz = ww - xx - yy + zz; - - *out = temp; -} - -Quaternion Quaternion::fromMatrix(Matrix4x4 &m) -{ - // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes - // article "Quaternion Calculus and Fast Animation". - Quaternion q(0,0,0,1); - /* - float fTrace = m[0][0] + m[1][1] + m[2][2]; - float fRoot; - - if( fTrace > 0.0 ) - { - fRoot = sqrtf( fTrace + 1.0f ); - - q.w = 0.5f * fRoot; - - fRoot = 0.5f / fRoot; - - q.x = ( m[2][1] - m[1][2] ) * fRoot; - q.y = ( m[0][2] - m[2][0] ) * fRoot; - q.z = ( m[1][0] - m[0][1] ) * fRoot; - } - else - { - int iNext[3] = { 1, 2, 0 }; - - int i = 0; - if( m[1][1] > m[0][0] ) - i = 1; - - if( m[2][2] > m[i][i] ) - i = 2; - - int j = iNext[i]; - int k = iNext[j]; - - fRoot = sqrtf( m[i][i] - m[j][j] - m[k][k] + 1.0f ); - - float *apfQuat = &q.x; - - apfQuat[i] = 0.5f * fRoot; - - fRoot = 0.5f / fRoot; - - q.w = ( m[k][j] - m[j][k] ) * fRoot; - - apfQuat[j] = ( m[j][i] + m[i][j] ) * fRoot; - apfQuat[k] = ( m[k][i] + m[i][k] ) * fRoot; - } - q.normalize(); */ - return q; -}; - -// TODO: Allegedly, lerp + normalize can achieve almost as good results. -Quaternion Quaternion::slerp(const Quaternion &to, const float a) const { - Quaternion to2; - float angle, cos_angle, scale_from, scale_to, sin_angle; - - cos_angle = (x * to.x) + (y * to.y) + (z * to.z) + (w * to.w); //4D dot product - - if (cos_angle < 0.0f) - { - cos_angle = -cos_angle; - to2.w = -to.w; to2.x = -to.x; to2.y = -to.y; to2.z = -to.z; - } - else - { - to2 = to; - } - - if ((1.0f - fabsf(cos_angle)) > 0.00001f) - { - /* spherical linear interpolation (SLERP) */ - angle = acosf(cos_angle); - sin_angle = sinf(angle); - scale_from = sinf((1.0f - a) * angle) / sin_angle; - scale_to = sinf(a * angle) / sin_angle; - } - else - { - /* to prevent divide-by-zero, resort to linear interpolation */ - // This is okay in 99% of cases anyway, maybe should be the default? - scale_from = 1.0f - a; - scale_to = a; - } - - return Quaternion( - scale_from*x + scale_to*to2.x, - scale_from*y + scale_to*to2.y, - scale_from*z + scale_to*to2.z, - scale_from*w + scale_to*to2.w - ); -} - -Quaternion Quaternion::multiply(const Quaternion &q) const { - return Quaternion((w * q.x) + (x * q.w) + (y * q.z) - (z * q.y), - (w * q.y) + (y * q.w) + (z * q.x) - (x * q.z), - (w * q.z) + (z * q.w) + (x * q.y) - (y * q.x), - (w * q.w) - (x * q.x) - (y * q.y) - (z * q.z)); -} - -} diff --git a/ext/native/math/lin/quat.h b/ext/native/math/lin/quat.h deleted file mode 100644 index 8be9a94f5c..0000000000 --- a/ext/native/math/lin/quat.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef _MATH_LIN_QUAT_H -#define _MATH_LIN_QUAT_H - -#include "math/lin/vec3.h" - -namespace Lin { - -class Matrix4x4; - -class Quaternion -{ -public: - float x,y,z,w; - - Quaternion() { } - Quaternion(const float _x, const float _y, const float _z, const float _w) { - x=_x; y=_y; z=_z; w=_w; - } - void setIdentity() - { - x=y=z=0; w=1.0f; - } - void setXRotation(const float r) { w = cosf(r / 2); x = sinf(r / 2); y = z = 0; } - void setYRotation(const float r) { w = cosf(r / 2); y = sinf(r / 2); x = z = 0; } - void setZRotation(const float r) { w = cosf(r / 2); z = sinf(r / 2); x = y = 0; } - void toMatrix(Matrix4x4 *out) const; - static Quaternion fromMatrix(Matrix4x4 &m); - - Quaternion operator *(Quaternion &q) const - { - return Quaternion( - (w * q.w) - (x * q.x) - (y * q.y) - (z * q.z), - (w * q.x) + (x * q.w) + (y * q.z) - (z * q.y), - (w * q.y) + (y * q.w) + (z * q.x) - (x * q.z), - (w * q.z) + (z * q.w) + (x * q.y) - (y * q.x) - ); - } - Quaternion operator -() - { - return Quaternion(-x,-y,-z,-w); - } - void setRotation(Vec3 axis, float angle) - { - axis /= axis.length(); - angle *= .5f; - float sine = sinf(angle); - w = cosf(angle); - x = sine * axis.x; - y = sine * axis.y; - z = sine * axis.z; - } - void toAxisAngle(Vec3 &v, float &angle) - { - normalize(); - if (w==1.0f && x==0.0f && y==0.0f && z==0.0f) - { - v = Vec3(0,1,0); - angle = 0.0f; - return; - } - float cos_a = w; - angle = acosf(cos_a) * 2; - float sin_a = sqrtf( 1.0f - cos_a * cos_a ); - if (fabsf(sin_a) < 0.00005f) sin_a = 1; - float inv_sin_a=1.0f/sin_a; - v.x = x * inv_sin_a; - v.y = y * inv_sin_a; - v.z = z * inv_sin_a; - } - enum { - QUAT_SHORT, - QUAT_LONG, - QUAT_CW, - QUAT_CCW - }; - Quaternion slerp(const Quaternion &to, const float a) const; - Quaternion multiply(const Quaternion &q) const; - float &operator [] (int i) { - return *((&x) + i); - } - float operator [] (int i) const { - return *((&x) + i); - } - //not sure about this, maybe mag is supposed to sqrt - float magnitude() const { - return x*x + y*y + z*z + w*w; - } - void normalize() { - float f = 1.0f/sqrtf(magnitude()); - x*=f; y*=f; z*=f; w*=f; - } -}; - -} // namespace Lin - -#endif // _MATH_LIN_QUAT_H diff --git a/ext/native/math/lin/ray.h b/ext/native/math/lin/ray.h deleted file mode 100644 index 2287460fbb..0000000000 --- a/ext/native/math/lin/ray.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "vec3.h" - -/* __declspec(align(16)) */ struct Ray -{ - Vec3 origin; - int pad; - Vec3 dir; - int pad2; - Vec3 invdir; - int pad3; -}; - diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 7e5e759400..b6653404d0 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -454,8 +454,6 @@ - - @@ -1169,8 +1167,6 @@ - - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index a1f06f8607..d4ce209515 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -41,9 +41,6 @@ image - - math - math @@ -125,9 +122,6 @@ ui - - math - util @@ -361,9 +355,6 @@ math - - math - math @@ -430,9 +421,6 @@ ui - - math - math @@ -858,9 +846,6 @@ {d5fa3d62-88bf-4dc4-9814-28f3c0444e62} - - {1e85f968-7106-483c-ae7d-77d0ef58d787} - {6a548b3d-3a4c-4114-aa2f-0b42bf7bf2ce} diff --git a/libretro/Makefile.common b/libretro/Makefile.common index b53cce49a3..87fc689e03 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -301,8 +301,6 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/math/curves.cpp \ $(NATIVEDIR)/math/expression_parser.cpp \ $(NATIVEDIR)/math/lin/matrix4x4.cpp \ - $(NATIVEDIR)/math/lin/plane.cpp \ - $(NATIVEDIR)/math/lin/quat.cpp \ $(NATIVEDIR)/math/lin/vec3.cpp \ $(NATIVEDIR)/net/http_client.cpp \ $(NATIVEDIR)/net/resolve.cpp \ From ec7458b6a939b8ec2c73f6a2126d5f57c3fa0ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 10:13:27 +0200 Subject: [PATCH 790/848] Delete more useless math code --- ext/native/math/lin/matrix4x4.cpp | 158 ------------------------------ ext/native/math/lin/matrix4x4.h | 54 +--------- ext/native/math/lin/vec3.cpp | 12 --- ext/native/math/lin/vec3.h | 6 -- ext/native/math/math_util.h | 42 -------- 5 files changed, 2 insertions(+), 270 deletions(-) diff --git a/ext/native/math/lin/matrix4x4.cpp b/ext/native/math/lin/matrix4x4.cpp index 7b4179bfef..b514714573 100644 --- a/ext/native/math/lin/matrix4x4.cpp +++ b/ext/native/math/lin/matrix4x4.cpp @@ -15,32 +15,6 @@ namespace Lin { -Matrix4x4 Matrix4x4::simpleInverse() const { - Matrix4x4 out; - out.xx = xx; - out.xy = yx; - out.xz = zx; - - out.yx = xy; - out.yy = yy; - out.yz = zy; - - out.zx = xz; - out.zy = yz; - out.zz = zz; - - out.wx = -(xx * wx + xy * wy + xz * wz); - out.wy = -(yx * wx + yy * wy + yz * wz); - out.wz = -(zx * wx + zy * wy + zz * wz); - - out.xw = 0.0f; - out.yw = 0.0f; - out.zw = 0.0f; - out.ww = 1.0f; - - return out; -} - Matrix4x4 Matrix4x4::transpose() const { Matrix4x4 out; @@ -58,100 +32,6 @@ Matrix4x4 Matrix4x4::operator * (const Matrix4x4 &other) const return temp; } -Matrix4x4 Matrix4x4::inverse() const { - Matrix4x4 temp; - float dW = 1.0f / (xx*(yy*zz - yz*zy) - xy*(yx*zz - yz*zx) - xz*(yy*zx - yx*zy)); - - temp.xx = (yy*zz - yz*zy) * dW; - temp.xy = (xz*zy - xy*zz) * dW; - temp.xz = (xy*yz - xz*yy) * dW; - temp.xw = xw; - - temp.yx = (yz*zx - yx*zz) * dW; - temp.yy = (xx*zz - xz*zx) * dW; - temp.yz = (xz*yx - xx*zx) * dW; - temp.yw = yw; - - temp.zx = (yx*zy - yy*zx) * dW; - temp.zy = (xy*zx - xx*zy) * dW; - temp.zz = (xx*yy - xy*yx) * dW; - temp.zw = zw; - - temp.wx = (yy*(zx*wz - zz*wx) + yz*(zy*wx - zx*wy) - yx*(zy*wz - zz*wy)) * dW; - temp.wy = (xx*(zy*wz - zz*wy) + xy*(zz*wx - zx*wz) + xz*(zx*wy - zy*wx)) * dW; - temp.wz = (xy*(yx*wz - yz*wx) + xz*(yy*wx - yx*wy) - xx*(yy*wz - yz*wy)) * dW; - temp.ww = ww; - - return temp; -} - -void Matrix4x4::setViewLookAt(const Vec3 &vFrom, const Vec3 &vAt, const Vec3 &vWorldUp) { - Vec3 vView = vFrom - vAt; // OpenGL, sigh... - vView.normalize(); - float DotProduct = vWorldUp * vView; - Vec3 vUp = vWorldUp - vView * DotProduct; - float Length = vUp.length(); - - if (1e-6f > Length) { - // EMERGENCY - vUp = Vec3(0.0f, 1.0f, 0.0f) - vView * vView.y; - // If we still have near-zero length, resort to a different axis. - Length = vUp.length(); - if (1e-6f > Length) - { - vUp = Vec3(0.0f, 0.0f, 1.0f) - vView * vView.z; - Length = vUp.length(); - if (1e-6f > Length) - return; - } - } - vUp.normalize(); - Vec3 vRight = vUp % vView; - empty(); - - xx = vRight.x; xy = vUp.x; xz=vView.x; - yx = vRight.y; yy = vUp.y; yz=vView.y; - zx = vRight.z; zy = vUp.z; zz=vView.z; - - wx = -vFrom * vRight; - wy = -vFrom * vUp; - wz = -vFrom * vView; - ww = 1.0f; -} - -void Matrix4x4::setViewLookAtD3D(const Vec3 &vFrom, const Vec3 &vAt, const Vec3 &vWorldUp) { - Vec3 vView = vAt - vFrom; - vView.normalize(); - float DotProduct = vWorldUp * vView; - Vec3 vUp = vWorldUp - vView * DotProduct; - float Length = vUp.length(); - - if (1e-6f > Length) { - vUp = Vec3(0.0f, 1.0f, 0.0f) - vView * vView.y; - // If we still have near-zero length, resort to a different axis. - Length = vUp.length(); - if (1e-6f > Length) - { - vUp = Vec3(0.0f, 0.0f, 1.0f) - vView * vView.z; - Length = vUp.length(); - if (1e-6f > Length) - return; - } - } - vUp.normalize(); - Vec3 vRight = vUp % vView; - empty(); - - xx = vRight.x; xy = vUp.x; xz=vView.x; - yx = vRight.y; yy = vUp.y; yz=vView.y; - zx = vRight.z; zy = vUp.z; zz=vView.z; - - wx = -vFrom * vRight; - wy = -vFrom * vUp; - wz = -vFrom * vView; - ww = 1.0f; -} - void Matrix4x4::setViewFrame(const Vec3 &pos, const Vec3 &vRight, const Vec3 &vView, const Vec3 &vUp) { xx = vRight.x; xy = vUp.x; xz=vView.x; xw = 0.0f; yx = vRight.y; yy = vUp.y; yz=vView.y; yw = 0.0f; @@ -163,44 +43,6 @@ void Matrix4x4::setViewFrame(const Vec3 &pos, const Vec3 &vRight, const Vec3 &vV ww = 1.0f; } -//YXZ euler angles -void Matrix4x4::setRotation(float x,float y, float z) -{ - setRotationY(y); - Matrix4x4 temp; - temp.setRotationX(x); - *this *= temp; - temp.setRotationZ(z); - *this *= temp; -} - -void Matrix4x4::setProjection(float near, float far, float fov_horiz, float aspect) { - // Now OpenGL style. - empty(); - - float xFac = tanf(fov_horiz * 3.14f/360); - float yFac = xFac * aspect; - xx = 1.0f / xFac; - yy = 1.0f / yFac; - zz = -(far+near)/(far-near); - zw = -1.0f; - wz = -(2*far*near)/(far-near); -} - -void Matrix4x4::setProjectionD3D(float near_plane, float far_plane, float fov_horiz, float aspect) { - empty(); - float Q, f; - - f = fov_horiz*0.5f; - Q = far_plane / (far_plane - near_plane); - - xx = (float)(1.0f / tanf(f));; - yy = (float)(1.0f / tanf(f*aspect)); - zz = Q; - wz = -Q * near_plane; - zw = 1.0f; -} - void Matrix4x4::setOrtho(float left, float right, float bottom, float top, float near, float far) { empty(); xx = 2.0f / (right - left); diff --git a/ext/native/math/lin/matrix4x4.h b/ext/native/math/lin/matrix4x4.h index a9e312de70..70644a80f6 100644 --- a/ext/native/math/lin/matrix4x4.h +++ b/ext/native/math/lin/matrix4x4.h @@ -24,19 +24,6 @@ public: const Vec3 front() const {return Vec3(zx, zy, zz);} const Vec3 move() const {return Vec3(wx, wy, wz);} - void setRight(const Vec3 &v) { - xx = v.x; xy = v.y; xz = v.z; - } - void setUp(const Vec3 &v) { - yx = v.x; yy = v.y; yz = v.z; - } - void setFront(const Vec3 &v) { - zx = v.x; zy = v.y; zz = v.z; - } - void setMove(const Vec3 &v) { - wx = v.x; wy = v.y; wz = v.z; - } - const float &operator[](int i) const { return *(((const float *)this) + i); } @@ -53,17 +40,14 @@ public: void empty() { memset(this, 0, 16 * sizeof(float)); } - void setScaling(const float f) { - empty(); - xx=yy=zz=f; ww=1.0f; - } static Matrix4x4 identity() { Matrix4x4 id; id.setIdentity(); return id; } void setIdentity() { - setScaling(1.0f); + empty(); + xx = yy = zz = ww = 1.0f; } void setTranslation(const Vec3 &trans) { setIdentity(); @@ -72,37 +56,8 @@ public: wz = trans.z; } - Matrix4x4 inverse() const; - Matrix4x4 simpleInverse() const; Matrix4x4 transpose() const; - void setRotationX(const float a) { - empty(); - float c = cosf(a); - float s = sinf(a); - xx = 1.0f; - yy = c; yz = s; - zy = -s; zz = c; - ww = 1.0f; - } - void setRotationY(const float a) { - empty(); - float c = cosf(a); - float s = sinf(a); - xx = c; xz = -s; - yy = 1.0f; - zx = s; zz = c; - ww = 1.0f; - } - void setRotationZ(const float a) { - empty(); - float c = cosf(a); - float s = sinf(a); - xx = c; xy = s; - yx = -s; yy = c; - zz = 1.0f; - ww = 1.0f; - } // Exact angles to avoid any artifacts. void setRotationZ90() { empty(); @@ -132,15 +87,10 @@ public: ww = 1.0f; } - void setRotation(float x,float y, float z); - void setProjection(float near_plane, float far_plane, float fov_horiz, float aspect = 0.75f); - void setProjectionD3D(float near_plane, float far_plane, float fov_horiz, float aspect = 0.75f); void setOrtho(float left, float right, float bottom, float top, float near, float far); void setOrthoD3D(float left, float right, float bottom, float top, float near, float far); void setOrthoVulkan(float left, float right, float top, float bottom, float near, float far); - void setViewLookAt(const Vec3 &from, const Vec3 &at, const Vec3 &worldup); - void setViewLookAtD3D(const Vec3 &from, const Vec3 &at, const Vec3 &worldup); void setViewFrame(const Vec3 &pos, const Vec3 &right, const Vec3 &forward, const Vec3 &up); void toText(char *buffer, int len) const; void print() const; diff --git a/ext/native/math/lin/vec3.cpp b/ext/native/math/lin/vec3.cpp index 95c2469fc3..7c66339cda 100644 --- a/ext/native/math/lin/vec3.cpp +++ b/ext/native/math/lin/vec3.cpp @@ -10,18 +10,6 @@ Vec3 Vec3::operator *(const Matrix4x4 &m) const { x*m.xy + y*m.yy + z*m.zy + m.wy, x*m.xz + y*m.yz + z*m.zz + m.wz); } -Vec4 Vec3::multiply4D(const Matrix4x4 &m) const { - return Vec4(x*m.xx + y*m.yx + z*m.zx + m.wx, - x*m.xy + y*m.yy + z*m.zy + m.wy, - x*m.xz + y*m.yz + z*m.zz + m.wz, - x*m.xw + y*m.yw + z*m.zw + m.ww); -} -Vec4 Vec4::multiply4D(Matrix4x4 &m) const { - return Vec4(x*m.xx + y*m.yx + z*m.zx + w*m.wx, - x*m.xy + y*m.yy + z*m.zy + w*m.wy, - x*m.xz + y*m.yz + z*m.zz + w*m.wz, - x*m.xw + y*m.yw + z*m.zw + w*m.ww); -} Vec3 Vec3::rotatedBy(const Matrix4x4 &m) const { return Vec3(x*m.xx + y*m.yx + z*m.zx, diff --git a/ext/native/math/lin/vec3.h b/ext/native/math/lin/vec3.h index 10096153d7..988a2d08b5 100644 --- a/ext/native/math/lin/vec3.h +++ b/ext/native/math/lin/vec3.h @@ -14,7 +14,6 @@ public: float x,y,z,w; Vec4(){} Vec4(float a, float b, float c, float d) {x=a;y=b;z=c;w=d;} - Vec4 multiply4D(Matrix4x4 &m) const; }; class Vec3 { @@ -80,7 +79,6 @@ public: void operator *=(const Matrix4x4 &m) { *this = *this * m; } - Vec4 multiply4D(const Matrix4x4 &m) const; Vec3 rotatedBy(const Matrix4x4 &m) const; Vec3 operator %(const Vec3 &v) const { return Vec3(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); @@ -134,10 +132,6 @@ inline Vec3 cross(const Vec3 &a, const Vec3 &b) { return a % b; } -inline float sqr(const Vec3 &v) { - return dot(v, v); -} - class AABBox { public: Vec3 min; diff --git a/ext/native/math/math_util.h b/ext/native/math/math_util.h index 4d30d080c6..12147a6f64 100644 --- a/ext/native/math/math_util.h +++ b/ext/native/math/math_util.h @@ -8,9 +8,6 @@ #include "base/basictypes.h" -inline float sqr(float f) {return f*f;} -inline float sqr_signed(float f) {return f<0 ? -f*f : f*f;} - typedef unsigned short float16; // This ain't a 1.5.10 float16, it's a stupid hack format where we chop 16 bits off a float. @@ -56,33 +53,6 @@ inline uint32_t log2i(uint32_t val) { #define M_PI 3.141592653589793f #endif -// Calculate pseudo-random 32 bit number based on linear congruential method. -void SetSeed(unsigned int seed); -unsigned int GenerateRandomNumber(); -inline float GenerateRandomFloat01() { - return (float)((double)GenerateRandomNumber() / 0xFFFFFFFF); -} -inline float GenerateRandomSignedFloat() { - return (float)((double)GenerateRandomNumber() / 0x80000000) - 1.0f; -} - - -inline float GaussRand() -{ - float R1 = GenerateRandomFloat01(); - float R2 = GenerateRandomFloat01(); - - float X = sqrtf(-2.0f * logf(R1)) * cosf(2.0f * PI * R2); - if (X > 4.0f) X = 4.0f; - if (X < -4.0f) X = -4.0f; - return X; -} - -// Accuracy unknown -inline double atan_fast(double x) { - return (x / (1.0 + 0.28 * (x * x))); -} - template inline T clamp_value(T val, T floor, T cap) { if (val > cap) @@ -93,18 +63,6 @@ inline T clamp_value(T val, T floor, T cap) { return val; } -// linear -> dB conversion -inline float lin2dB(float lin) { - const float LOG_2_DB = 8.6858896380650365530225783783321f; // 20 / ln( 10 ) - return logf(lin) * LOG_2_DB; -} - -// dB -> linear conversion -inline float dB2lin(float dB) { - const float DB_2_LOG = 0.11512925464970228420089957273422f; // ln( 10 ) / 20 - return expf(dB * DB_2_LOG); -} - union FP32 { uint32_t u; float f; From 51e2e7f8d5497633625668043c4f6faae467ea5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 10:24:41 +0200 Subject: [PATCH 791/848] Remove our usage of ssize_t --- Core/HLE/sceIo.cpp | 4 ++-- ext/native/base/basictypes.h | 2 -- ext/native/base/buffer.cpp | 8 ++++---- ext/native/base/buffer.h | 3 +-- ext/native/base/stringutil.h | 3 --- ext/native/file/fd_util.cpp | 10 +++++----- ext/native/file/fd_util.h | 15 ++++++--------- 7 files changed, 18 insertions(+), 27 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index e9b76785b9..9fd546d131 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -967,8 +967,8 @@ static u32 npdrmRead(FileNode *f, u8 *data, int size) { block = pgd->file_offset/pgd->block_size; offset = pgd->file_offset%pgd->block_size; - if (size > pgd->data_size) - size = pgd->data_size; + if (size > (int)pgd->data_size) + size = (int)pgd->data_size; remain_size = size; while(remain_size){ diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h index 2f9c7d0321..b104506eaa 100644 --- a/ext/native/base/basictypes.h +++ b/ext/native/base/basictypes.h @@ -30,8 +30,6 @@ #ifdef _WIN32 -typedef intptr_t ssize_t; - #include #endif // _WIN32 diff --git a/ext/native/base/buffer.cpp b/ext/native/base/buffer.cpp index 86ccd22480..9598dcbe00 100644 --- a/ext/native/base/buffer.cpp +++ b/ext/native/base/buffer.cpp @@ -26,7 +26,7 @@ Buffer::Buffer() { } Buffer::~Buffer() { } -char *Buffer::Append(ssize_t length) { +char *Buffer::Append(size_t length) { if (length > 0) { size_t old_size = data_.size(); data_.resize(old_size + length); @@ -120,8 +120,8 @@ void Buffer::Printf(const char *fmt, ...) { char buffer[2048]; va_list vl; va_start(vl, fmt); - ssize_t retval = vsnprintf(buffer, sizeof(buffer), fmt, vl); - if (retval >= (ssize_t)sizeof(buffer)) { + size_t retval = vsnprintf(buffer, sizeof(buffer), fmt, vl); + if ((int)retval >= (int)sizeof(buffer)) { // Output was truncated. TODO: Do something. ERROR_LOG(IO, "Buffer::Printf truncated output"); } @@ -135,7 +135,7 @@ void Buffer::Printf(const char *fmt, ...) { bool Buffer::Flush(int fd) { // Look into using send() directly. - bool success = (ssize_t)data_.size() == fd_util::WriteLine(fd, &data_[0], data_.size()); + bool success = data_.size() == fd_util::WriteLine(fd, &data_[0], data_.size()); if (success) { data_.resize(0); } diff --git a/ext/native/base/buffer.h b/ext/native/base/buffer.h index 96abfbbd3f..63ab44b907 100644 --- a/ext/native/base/buffer.h +++ b/ext/native/base/buffer.h @@ -16,8 +16,7 @@ class Buffer { // Write max [length] bytes to the returned pointer. // Any other operation on this Buffer invalidates the pointer. - char *Append(ssize_t length); - char *Append(size_t length) { return Append((ssize_t)length); } + char *Append(size_t length); // These work pretty much like you'd expect. void Append(const char *str); // str null-terminated. The null is not copied. diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h index 3a64058838..0e293a0f43 100644 --- a/ext/native/base/stringutil.h +++ b/ext/native/base/stringutil.h @@ -46,9 +46,6 @@ inline bool endsWithNoCase(const std::string &str, const std::string &what) { void DataToHexString(const uint8_t *data, size_t size, std::string *output); void DataToHexString(const char* prefix, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output); -inline void StringToHexString(const std::string &data, std::string *output) { - DataToHexString((uint8_t *)(&data[0]), data.size(), output); -} std::string StringFromFormat(const char* format, ...); std::string StringFromInt(int value); diff --git a/ext/native/file/fd_util.cpp b/ext/native/file/fd_util.cpp index 1b47c215fc..e7726392d4 100644 --- a/ext/native/file/fd_util.cpp +++ b/ext/native/file/fd_util.cpp @@ -25,12 +25,12 @@ namespace fd_util { // Slow as hell and should only be used for prototyping. // Reads from a socket, up to an '\n'. This means that if the line ends // with '\r', the '\r' will be returned. -ssize_t ReadLine(int fd, char *vptr, size_t buf_size) { +size_t ReadLine(int fd, char *vptr, size_t buf_size) { char *buffer = vptr; size_t n; for (n = 1; n < buf_size; n++) { char c; - ssize_t rc; + size_t rc; if ((rc = read(fd, &c, 1)) == 1) { *buffer++ = c; if (c == '\n') @@ -54,7 +54,7 @@ ssize_t ReadLine(int fd, char *vptr, size_t buf_size) { } // Misnamed, it just writes raw data in a retry loop. -ssize_t WriteLine(int fd, const char *vptr, size_t n) { +size_t WriteLine(int fd, const char *vptr, size_t n) { const char *buffer = vptr; size_t nleft = n; @@ -73,11 +73,11 @@ ssize_t WriteLine(int fd, const char *vptr, size_t n) { return n; } -ssize_t WriteLine(int fd, const char *buffer) { +size_t WriteLine(int fd, const char *buffer) { return WriteLine(fd, buffer, strlen(buffer)); } -ssize_t Write(int fd, const std::string &str) { +size_t Write(int fd, const std::string &str) { return WriteLine(fd, str.c_str(), str.size()); } diff --git a/ext/native/file/fd_util.h b/ext/native/file/fd_util.h index 922a50eb70..5160c4e157 100644 --- a/ext/native/file/fd_util.h +++ b/ext/native/file/fd_util.h @@ -1,7 +1,6 @@ -#ifndef _FD_UTIL -#define _FD_UTIL +#pragma once -#include +#include #include #include "base/basictypes.h" @@ -9,12 +8,12 @@ namespace fd_util { // Slow as hell and should only be used for prototyping. -ssize_t ReadLine(int fd, char *buffer, size_t buf_size); +size_t ReadLine(int fd, char *buffer, size_t buf_size); // Decently fast. -ssize_t WriteLine(int fd, const char *buffer, size_t buf_size); -ssize_t WriteLine(int fd, const char *buffer); -ssize_t Write(int fd, const std::string &str); +size_t WriteLine(int fd, const char *buffer, size_t buf_size); +size_t WriteLine(int fd, const char *buffer); +size_t Write(int fd, const std::string &str); // Returns true if the fd became ready, false if it didn't or // if there was another error. @@ -25,5 +24,3 @@ void SetNonBlocking(int fd, bool non_blocking); std::string GetLocalIP(int sock); } // fd_util - -#endif // _FD_UTIL From ecceeaa810eddddcd0f0d8c16b9d08d15c50cfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 10:25:26 +0200 Subject: [PATCH 792/848] We no longer use TCHAR. --- ext/native/base/basictypes.h | 12 ------------ headless/WindowsHeadlessHost.cpp | 4 ++-- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h index b104506eaa..feb9abfb13 100644 --- a/ext/native/base/basictypes.h +++ b/ext/native/base/basictypes.h @@ -28,12 +28,6 @@ } #endif -#ifdef _WIN32 - -#include - -#endif // _WIN32 - // Byteswapping #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) @@ -71,9 +65,3 @@ inline uint64_t swap64(const uint8_t* _pData) {return swap64(*(const uint64_t*)_ #else #define __THREAD __thread #endif - -// For really basic windows code compat -#ifndef _TCHAR_DEFINED -typedef char TCHAR; -#endif - diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index 5d5e79dfc7..c5b9ef9594 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -56,13 +56,13 @@ HWND CreateHiddenWindow() { LoadCursor(NULL, IDC_ARROW), (HBRUSH) GetStockObject(BLACK_BRUSH), NULL, - _T("PPSSPPHeadless"), + L"PPSSPPHeadless", NULL, }; RegisterClassEx(&wndClass); DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP; - return CreateWindowEx(0, _T("PPSSPPHeadless"), _T("PPSSPPHeadless"), style, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, NULL, NULL); + return CreateWindowEx(0, L"PPSSPPHeadless", L"PPSSPPHeadless", style, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, NULL, NULL); } void WindowsHeadlessHost::LoadNativeAssets() From 656adf1fcdfdd7bfe3b2f7c5ecb030b8a32c0c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 10:28:27 +0200 Subject: [PATCH 793/848] Remove old define for thread local storage --- ext/native/base/basictypes.h | 7 ------- ext/native/thread/threadutil.cpp | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h index feb9abfb13..3334cea629 100644 --- a/ext/native/base/basictypes.h +++ b/ext/native/base/basictypes.h @@ -58,10 +58,3 @@ inline uint64_t swap64(uint64_t data) {return ((uint64_t)swap32(data) << 32) | s inline uint16_t swap16(const uint8_t* _pData) {return swap16(*(const uint16_t*)_pData);} inline uint32_t swap32(const uint8_t* _pData) {return swap32(*(const uint32_t*)_pData);} inline uint64_t swap64(const uint8_t* _pData) {return swap64(*(const uint64_t*)_pData);} - -// Thread local storage -#ifdef _MSC_VER -#define __THREAD __declspec( thread ) -#else -#define __THREAD __thread -#endif diff --git a/ext/native/thread/threadutil.cpp b/ext/native/thread/threadutil.cpp index a47286b96f..9971293685 100644 --- a/ext/native/thread/threadutil.cpp +++ b/ext/native/thread/threadutil.cpp @@ -20,7 +20,7 @@ #endif #ifdef TLS_SUPPORTED -static __THREAD const char *curThreadName; +static thread_local const char *curThreadName; #endif #ifdef __MINGW32__ From ed88761ecc1d1a2dd023a89189c1b6fdca65b033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 12:19:22 +0200 Subject: [PATCH 794/848] Merge ext/native/stringutil.cpp/h into Common/StringUtils.cpp/h. --- CMakeLists.txt | 3 - Common/ConsoleListener.cpp | 5 +- Common/KeyMap.cpp | 2 +- Common/Misc.cpp | 6 +- Common/StringUtils.cpp | 203 ++++++++++++++++++ Common/StringUtils.h | 60 +++++- Core/Debugger/WebSocket/DisasmSubscriber.cpp | 4 +- Core/Debugger/WebSocket/HLESubscriber.cpp | 2 +- .../Debugger/WebSocket/SteppingSubscriber.cpp | 2 +- Core/Dialog/PSPSaveDialog.cpp | 2 +- Core/FileLoaders/HTTPFileLoader.cpp | 2 +- Core/FileSystems/DirectoryFileSystem.cpp | 3 +- Core/HLE/sceKernelModule.cpp | 1 - Core/HLE/sceKernelThread.cpp | 1 + Core/Loaders.cpp | 2 +- Core/Reporting.cpp | 9 +- Core/SaveState.cpp | 2 +- Core/TextureReplacer.cpp | 3 +- Core/Util/PPGeDraw.cpp | 2 +- Core/WebServer.cpp | 6 +- GPU/Common/PostShader.cpp | 1 + GPU/Common/ShaderTranslation.cpp | 3 +- GPU/D3D11/D3D11Util.cpp | 7 +- GPU/Debugger/Record.cpp | 4 +- GPU/Directx9/ShaderManagerDX9.cpp | 3 +- GPU/Directx9/VertexShaderGeneratorDX9.cpp | 4 +- GPU/GLES/VertexShaderGeneratorGLES.cpp | 2 +- GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 1 + GPU/Vulkan/VertexShaderGeneratorVulkan.cpp | 2 +- GPU/Vulkan/VulkanUtil.cpp | 3 +- UI/ComboKeyMappingScreen.cpp | 10 +- UI/CwCheatScreen.cpp | 2 +- UI/DevScreens.cpp | 2 +- UI/GameInfoCache.cpp | 1 - UI/GameSettingsScreen.cpp | 4 +- UI/MainScreen.cpp | 2 +- UI/NativeApp.cpp | 4 +- UI/PauseScreen.cpp | 4 +- UI/RemoteISOScreen.cpp | 3 +- UI/ReportScreen.cpp | 2 +- UI/SavedataScreen.cpp | 2 +- UWP/NativeUWP/NativeUWP.vcxproj | 2 - UWP/NativeUWP/NativeUWP.vcxproj.filters | 6 - Windows/Debugger/Debugger_Disasm.cpp | 3 +- Windows/GEDebugger/GEDebugger.cpp | 2 +- Windows/GPU/WindowsVulkanContext.cpp | 1 - Windows/MainWindow.cpp | 2 +- Windows/MainWindowMenu.cpp | 2 +- Windows/main.cpp | 2 +- android/jni/app-android.cpp | 3 +- ext/native/Android.mk | 1 - ext/native/base/basictypes.h | 2 - ext/native/base/stringutil.cpp | 198 ----------------- ext/native/base/stringutil.h | 62 ------ ext/native/file/file_util.cpp | 19 +- ext/native/file/file_util.h | 1 - ext/native/file/ini_file.cpp | 19 +- ext/native/file/ini_file.h | 17 +- ext/native/file/path.cpp | 4 +- ext/native/gfx_es2/draw_buffer.cpp | 2 +- ext/native/gfx_es2/draw_text.cpp | 1 - ext/native/gfx_es2/draw_text_android.cpp | 1 - ext/native/gfx_es2/draw_text_qt.cpp | 1 - ext/native/gfx_es2/draw_text_uwp.cpp | 1 - ext/native/gfx_es2/draw_text_win.cpp | 2 +- ext/native/gfx_es2/gpu_features.cpp | 2 +- ext/native/i18n/i18n.cpp | 3 +- ext/native/native.vcxproj | 2 - ext/native/native.vcxproj.filters | 6 - ext/native/net/http_client.cpp | 3 +- ext/native/net/http_headers.cpp | 2 +- ext/native/net/url.cpp | 2 +- ext/native/net/websocket_server.cpp | 2 +- ext/native/thin3d/GLQueueRunner.cpp | 2 +- ext/native/thin3d/VulkanRenderManager.cpp | 1 + ext/native/thin3d/VulkanRenderManager.h | 1 - ext/native/thin3d/thin3d_vulkan.cpp | 2 +- ext/native/ui/ui_screen.cpp | 2 +- ext/native/ui/view.cpp | 2 +- ext/native/ui/viewgroup.cpp | 2 +- ext/native/util/text/parsers.cpp | 3 +- libretro/Makefile.common | 1 - 83 files changed, 381 insertions(+), 399 deletions(-) delete mode 100644 ext/native/base/stringutil.cpp delete mode 100644 ext/native/base/stringutil.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b2804099bd..e61c638d9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -946,9 +946,6 @@ add_library(native STATIC ext/native/base/colorutil.h ext/native/base/display.cpp ext/native/base/display.h - ext/native/base/linked_ptr.h - ext/native/base/stringutil.cpp - ext/native/base/stringutil.h ext/native/data/base64.cpp ext/native/data/base64.h ext/native/data/compression.cpp diff --git a/Common/ConsoleListener.cpp b/Common/ConsoleListener.cpp index 7eab9980c9..da44073795 100644 --- a/Common/ConsoleListener.cpp +++ b/Common/ConsoleListener.cpp @@ -34,8 +34,9 @@ #include "ppsspp_config.h" #include "thread/threadutil.h" #include "util/text/utf8.h" -#include "Common.h" -#include "ConsoleListener.h" // Common +#include "Common/Common.h" +#include "Common/ConsoleListener.h" +#include "Common/StringUtils.h" #if defined(USING_WIN_UI) const int LOG_PENDING_MAX = 120 * 10000; diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 19b93711df..99d3bf4f05 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -24,7 +24,6 @@ #include "CommonWindows.h" #endif -#include "base/stringutil.h" #include "base/NativeApp.h" #include "file/ini_file.h" #include "input/input_state.h" @@ -32,6 +31,7 @@ #include "Common/Log.h" #include "Common/KeyMap.h" +#include "Common/StringUtils.h" #include "Core/HLE/sceUtility.h" #include "Core/Config.h" diff --git a/Common/Misc.cpp b/Common/Misc.cpp index af573729b9..a13924b1bf 100644 --- a/Common/Misc.cpp +++ b/Common/Misc.cpp @@ -43,16 +43,16 @@ const char *GetLastErrorMsg() const char *GetStringErrorMsg(int errCode) { static const size_t buff_size = 1023; #ifdef _WIN32 - static __THREAD wchar_t err_strw[buff_size] = {}; + static thread_local wchar_t err_strw[buff_size] = {}; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_strw, buff_size, NULL); - static __THREAD char err_str[buff_size] = {}; + static thread_local char err_str[buff_size] = {}; snprintf(err_str, buff_size, "%s", ConvertWStringToUTF8(err_strw).c_str()); #else - static __thread char err_str[buff_size] = {}; + static thread_local char err_str[buff_size] = {}; // Thread safe (XSI-compliant) if (strerror_r(errCode, err_str, buff_size) == 0) { diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index 58d721a1e4..b5a2d3b987 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -16,6 +16,33 @@ // http://code.google.com/p/dolphin-emu/ #include + +#include "ppsspp_config.h" + +#ifdef _WIN32 +#include +#undef min +#undef max +#endif + +#if PPSSPP_PLATFORM(SWITCH) +#define _GNU_SOURCE +#include +#endif + +#include + +#include + +#include +#include +#include + +#include +#include + +#include "base/buffer.h" + #include "Common.h" #include "StringUtils.h" @@ -114,3 +141,179 @@ std::string GetFilenameFromPath(std::string full_path) { // No directory components, just return the full path. return full_path; } + +std::string LineNumberString(const std::string &str) { + std::stringstream input(str); + std::stringstream output; + std::string line; + + int lineNumber = 1; + while (std::getline(input, line)) { + output << std::setw(4) << lineNumber++ << ": " << line << std::endl; + } + + return output.str(); +} + +void SkipSpace(const char **ptr) { + while (**ptr && isspace(**ptr)) { + (*ptr)++; + } +} + +void DataToHexString(const uint8_t *data, size_t size, std::string *output) { + Buffer buffer; + for (size_t i = 0; i < size; i++) { + if (i && !(i & 15)) + buffer.Printf("\n"); + buffer.Printf("%02x ", data[i]); + } + buffer.TakeAll(output); +} + +void DataToHexString(const char* prefix, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output) { + Buffer buffer; + size_t i = 0; + for (; i < size; i++) { + if (i && !(i & 15)) { + buffer.Printf(" "); + for (size_t j = i - 16; j < i; j++) { + buffer.Printf("%c", ((data[j] < 0x20) || (data[j] > 0x7e)) ? 0x2e : data[j]); + } + buffer.Printf("\n"); + } + if (!(i & 15)) + buffer.Printf("%s%08x ", prefix, startAddr + i); + buffer.Printf("%02x ", data[i]); + } + if (size & 15) { + size_t padded_size = ((size - 1) | 15) + 1; + for (size_t j = size; j < padded_size; j++) { + buffer.Printf(" "); + } + buffer.Printf(" "); + for (size_t j = size & ~UINT64_C(0xF); j < size; j++) { + buffer.Printf("%c", ((data[j] < 0x20) || (data[j] > 0x7e)) ? 0x2e : data[j]); + } + } + buffer.TakeAll(output); +} + +std::string StringFromFormat(const char* format, ...) +{ + va_list args; + std::string temp = ""; +#ifdef _WIN32 + int required = 0; + + va_start(args, format); + required = _vscprintf(format, args); + // Using + 2 to be safe between MSVC versions. + // In MSVC 2015 and later, vsnprintf counts the trailing zero (per c++11.) + temp.resize(required + 2); + if (vsnprintf(&temp[0], required + 1, format, args) < 0) { + temp.resize(0); + } else { + temp.resize(required); + } + va_end(args); +#else + char *buf = nullptr; + + va_start(args, format); + if (vasprintf(&buf, format, args) < 0) + buf = nullptr; + va_end(args); + + if (buf != nullptr) { + temp = buf; + free(buf); + } +#endif + return temp; +} + +std::string StringFromInt(int value) +{ + char temp[16]; + sprintf(temp, "%i", value); + return temp; +} + +// Turns " hej " into "hej". Also handles tabs. +std::string StripSpaces(const std::string &str) +{ + const size_t s = str.find_first_not_of(" \t\r\n"); + + if (str.npos != s) + return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); + else + return ""; +} + +// "\"hello\"" is turned to "hello" +// This one assumes that the string has already been space stripped in both +// ends, as done by StripSpaces above, for example. +std::string StripQuotes(const std::string& s) +{ + if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) + return s.substr(1, s.size() - 2); + else + return s; +} + +void SplitString(const std::string& str, const char delim, std::vector& output) +{ + size_t next = 0; + for (size_t pos = 0, len = str.length(); pos < len; ++pos) { + if (str[pos] == delim) { + output.push_back(str.substr(next, pos - next)); + // Skip the delimiter itself. + next = pos + 1; + } + } + + if (next == 0) { + output.push_back(str); + } else if (next < str.length()) { + output.push_back(str.substr(next)); + } +} + +void GetQuotedStrings(const std::string& str, std::vector& output) +{ + size_t next = 0; + bool even = 0; + for (size_t pos = 0, len = str.length(); pos < len; ++pos) { + if (str[pos] == '\"' || str[pos] == '\'') { + if (even) { + //quoted text + output.push_back(str.substr(next, pos - next)); + even = 0; + } else { + //non quoted text + even = 1; + } + // Skip the delimiter itself. + next = pos + 1; + } + } +} + +std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) +{ + size_t pos = 0; + + if (src == dest) + return result; + + while (1) + { + pos = result.find(src, pos); + if (pos == result.npos) + break; + result.replace(pos, src.size(), dest); + pos += dest.size(); + } + return result; +} diff --git a/Common/StringUtils.h b/Common/StringUtils.h index 58d433697c..0cc81c6cd3 100644 --- a/Common/StringUtils.h +++ b/Common/StringUtils.h @@ -17,10 +17,66 @@ #pragma once -#include - #include "Common.h" +#include +#include + +#ifdef _MSC_VER +#pragma warning (disable:4996) +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#else +#include +#endif + +// Useful for shaders with error messages.. +std::string LineNumberString(const std::string &str); + +// Other simple string utilities. + +inline bool startsWith(const std::string &str, const std::string &what) { + if (str.size() < what.size()) + return false; + return str.substr(0, what.size()) == what; +} + +inline bool endsWith(const std::string &str, const std::string &what) { + if (str.size() < what.size()) + return false; + return str.substr(str.size() - what.size()) == what; +} + +// Only use on strings where you're only concerned about ASCII. +inline bool startsWithNoCase(const std::string &str, const std::string &what) { + if (str.size() < what.size()) + return false; + return strncasecmp(str.c_str(), what.c_str(), what.size()) == 0; +} + +inline bool endsWithNoCase(const std::string &str, const std::string &what) { + if (str.size() < what.size()) + return false; + const size_t offset = str.size() - what.size(); + return strncasecmp(str.c_str() + offset, what.c_str(), what.size()) == 0; +} + +void DataToHexString(const uint8_t *data, size_t size, std::string *output); +void DataToHexString(const char* prefix, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output); + +std::string StringFromFormat(const char* format, ...); +std::string StringFromInt(int value); + +std::string StripSpaces(const std::string &s); +std::string StripQuotes(const std::string &s); + +void SplitString(const std::string& str, const char delim, std::vector& output); + +void GetQuotedStrings(const std::string& str, std::vector& output); + +std::string ReplaceAll(std::string input, const std::string& src, const std::string& dest); + +void SkipSpace(const char **ptr); void truncate_cpy(char *dest, size_t destSize, const char *src); template diff --git a/Core/Debugger/WebSocket/DisasmSubscriber.cpp b/Core/Debugger/WebSocket/DisasmSubscriber.cpp index 6d2f76d746..e84596b849 100644 --- a/Core/Debugger/WebSocket/DisasmSubscriber.cpp +++ b/Core/Debugger/WebSocket/DisasmSubscriber.cpp @@ -17,8 +17,10 @@ #include #include -#include "base/stringutil.h" + #include "util/text/utf8.h" + +#include "Common/StringUtils.h" #include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/DisassemblyManager.h" #include "Core/Debugger/WebSocket/DisasmSubscriber.h" diff --git a/Core/Debugger/WebSocket/HLESubscriber.cpp b/Core/Debugger/WebSocket/HLESubscriber.cpp index ae65e692fa..cbdb5df051 100644 --- a/Core/Debugger/WebSocket/HLESubscriber.cpp +++ b/Core/Debugger/WebSocket/HLESubscriber.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/stringutil.h" +#include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Core.h" #include "Core/Debugger/DisassemblyManager.h" diff --git a/Core/Debugger/WebSocket/SteppingSubscriber.cpp b/Core/Debugger/WebSocket/SteppingSubscriber.cpp index d3422b48f9..19c545de86 100644 --- a/Core/Debugger/WebSocket/SteppingSubscriber.cpp +++ b/Core/Debugger/WebSocket/SteppingSubscriber.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/stringutil.h" +#include "Common/StringUtils.h" #include "Core/Debugger/Breakpoints.h" #include "Core/Debugger/DisassemblyManager.h" #include "Core/Debugger/WebSocket/SteppingSubscriber.h" diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 23e1303780..8328ae34f5 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -21,13 +21,13 @@ #include -#include "base/stringutil.h" #include "i18n/i18n.h" #include "thread/threadutil.h" #include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" +#include "Common/StringUtils.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" diff --git a/Core/FileLoaders/HTTPFileLoader.cpp b/Core/FileLoaders/HTTPFileLoader.cpp index 7d710dbe52..094e78e639 100644 --- a/Core/FileLoaders/HTTPFileLoader.cpp +++ b/Core/FileLoaders/HTTPFileLoader.cpp @@ -17,8 +17,8 @@ #include -#include "base/stringutil.h" #include "Common/Common.h" +#include "Common/StringUtils.h" #include "Core/FileLoaders/HTTPFileLoader.h" HTTPFileLoader::HTTPFileLoader(const std::string &filename) diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 45dc902f04..ccb4365323 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -19,13 +19,14 @@ #include #include -#include "base/stringutil.h" + #include "file/free.h" #include "file/zip_read.h" #include "i18n/i18n.h" #include "util/text/utf8.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" +#include "Common/StringUtils.h" #include "Common/FileUtil.h" #include "Core/FileSystems/DirectoryFileSystem.h" #include "Core/FileSystems/ISOFileSystem.h" diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 34b3a9bc3c..601b01f166 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -21,7 +21,6 @@ #include "zlib.h" -#include "base/stringutil.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeSet.h" diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 6bd3d2d434..da89ff34bb 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -23,6 +23,7 @@ #include "Common/CommonTypes.h" #include "Common/LogManager.h" +#include "Common/StringUtils.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeList.h" diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index 97eca751ee..6054eed875 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -18,9 +18,9 @@ #include #include -#include "base/stringutil.h" #include "file/file_util.h" #include "Common/FileUtil.h" +#include "Common/StringUtils.h" #include "Core/FileLoaders/CachingFileLoader.h" #include "Core/FileLoaders/DiskCachingFileLoader.h" diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 1829fd8a97..36bac97703 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -19,12 +19,16 @@ #include #include #include +#include +#include +#include #include "Core/Reporting.h" #include "Common/CPUDetect.h" #include "Common/FileUtil.h" #include "Common/Serialize/SerializeFuncs.h" +#include "Common/StringUtils.h" #include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/Config.h" @@ -44,15 +48,10 @@ #include "net/resolve.h" #include "net/url.h" -#include "base/stringutil.h" #include "base/buffer.h" #include "thread/threadutil.h" #include "file/zip_read.h" -#include -#include -#include - namespace Reporting { const int DEFAULT_PORT = 80; diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index c5a960c69d..26c4a6f512 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -20,7 +20,6 @@ #include #include -#include "base/stringutil.h" #include "i18n/i18n.h" #include "thread/threadutil.h" #include "util/text/parsers.h" @@ -28,6 +27,7 @@ #include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" +#include "Common/StringUtils.h" #include "Common/TimeUtil.h" #include "Core/SaveState.h" diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 7cdb34c23a..32e49b0a6c 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -22,13 +22,14 @@ #endif #include -#include "base/stringutil.h" + #include "i18n/i18n.h" #include "ext/xxhash.h" #include "file/ini_file.h" #include "util/text/parsers.h" #include "Common/ColorConv.h" #include "Common/FileUtil.h" +#include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Host.h" #include "Core/System.h" diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 05484bd8af..c724c0b37e 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -18,7 +18,6 @@ #include #include "base/colorutil.h" -#include "base/stringutil.h" #include "file/vfs.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_text.h" @@ -28,6 +27,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" +#include "Common/StringUtils.h" #include "Core/HDRemaster.h" #include "Core/Host.h" #include "GPU/ge_constants.h" diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index d00753a1d4..222ab247de 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -18,16 +18,16 @@ #include #include #include -#include -#include "base/stringutil.h" + #include "file/fd_util.h" #include "net/http_client.h" #include "net/http_server.h" #include "net/sinks.h" #include "thread/threadutil.h" +#include "Common/Log.h" #include "Common/FileUtil.h" #include "Common/TimeUtil.h" -#include "Common/Log.h" +#include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Debugger/WebSocket.h" #include "Core/WebServer.h" diff --git a/GPU/Common/PostShader.cpp b/GPU/Common/PostShader.cpp index d0d9ec8963..3a91e60695 100644 --- a/GPU/Common/PostShader.cpp +++ b/GPU/Common/PostShader.cpp @@ -27,6 +27,7 @@ #include "file/vfs.h" #include "gfx_es2/gpu_features.h" +#include "Common/StringUtils.h" #include "Core/Config.h" #include "GPU/Common/PostShader.h" diff --git a/GPU/Common/ShaderTranslation.cpp b/GPU/Common/ShaderTranslation.cpp index e0b58908fc..c38d2420b1 100644 --- a/GPU/Common/ShaderTranslation.cpp +++ b/GPU/Common/ShaderTranslation.cpp @@ -35,8 +35,9 @@ #endif #include "base/basictypes.h" -#include "base/stringutil.h" #include "Common/Log.h" +#include "Common/StringUtils.h" + #include "GPU/Common/ShaderTranslation.h" #include "ext/glslang/SPIRV/GlslangToSpv.h" #include "thin3d/thin3d.h" diff --git a/GPU/D3D11/D3D11Util.cpp b/GPU/D3D11/D3D11Util.cpp index add974eb75..27fcc093dd 100644 --- a/GPU/D3D11/D3D11Util.cpp +++ b/GPU/D3D11/D3D11Util.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -12,10 +13,10 @@ #include "thin3d/d3d11_loader.h" #endif -#include "base/stringutil.h" - #include "Common/CommonFuncs.h" #include "Common/Log.h" +#include "Common/StringUtils.h" + #include "D3D11Util.h" static std::vector CompileShaderToBytecode(const char *code, size_t codeSize, const char *target, UINT flags) { @@ -126,7 +127,7 @@ void StockObjectsD3D11::Create(ID3D11Device *device) { sampler_desc.MinLOD = -FLT_MAX; sampler_desc.MaxLOD = FLT_MAX; sampler_desc.MipLODBias = 0.0f; - sampler_desc.MaxAnisotropy = 1.0f; + sampler_desc.MaxAnisotropy = 1; ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerPoint2DWrap)); sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; ASSERT_SUCCESS(device->CreateSamplerState(&sampler_desc, &samplerLinear2DWrap)); diff --git a/GPU/Debugger/Record.cpp b/GPU/Debugger/Record.cpp index 32455e3c1a..05ad3b2ff1 100644 --- a/GPU/Debugger/Record.cpp +++ b/GPU/Debugger/Record.cpp @@ -21,10 +21,12 @@ #include #include #include -#include "base/stringutil.h" + #include "Common/Common.h" #include "Common/FileUtil.h" #include "Common/Log.h" +#include "Common/StringUtils.h" + #include "Core/Core.h" #include "Core/ELF/ParamSFO.h" #include "Core/HLE/sceDisplay.h" diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index fd64cb4570..a7129030a3 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -23,7 +23,6 @@ #include #include "gfx/d3d9_shader.h" -#include "base/stringutil.h" #include "i18n/i18n.h" #include "math/lin/matrix4x4.h" #include "math/math_util.h" @@ -33,6 +32,8 @@ #include "Common/Common.h" #include "Common/Log.h" +#include "Common/StringUtils.h" + #include "Core/Config.h" #include "Core/Host.h" #include "Core/Reporting.h" diff --git a/GPU/Directx9/VertexShaderGeneratorDX9.cpp b/GPU/Directx9/VertexShaderGeneratorDX9.cpp index a0f29a985f..cdc3cdbff7 100644 --- a/GPU/Directx9/VertexShaderGeneratorDX9.cpp +++ b/GPU/Directx9/VertexShaderGeneratorDX9.cpp @@ -15,14 +15,14 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include +#include #include #if defined(_WIN32) && defined(_DEBUG) #include "Common/CommonWindows.h" #endif -#include "base/stringutil.h" +#include "Common/StringUtils.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" #include "Core/Config.h" diff --git a/GPU/GLES/VertexShaderGeneratorGLES.cpp b/GPU/GLES/VertexShaderGeneratorGLES.cpp index b2e57be7bf..c3f3a0b716 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.cpp +++ b/GPU/GLES/VertexShaderGeneratorGLES.cpp @@ -25,7 +25,7 @@ #include "Common/CommonWindows.h" #endif -#include "base/stringutil.h" +#include "Common/StringUtils.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" #include "Core/Config.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index c3d937049f..a1ec302265 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -19,7 +19,6 @@ //#define SHADERLOG #endif -#include "base/stringutil.h" #include "math/lin/matrix4x4.h" #include "math/math_util.h" #include "math/dataconv.h" @@ -27,6 +26,7 @@ #include "thin3d/thin3d.h" #include "util/text/utf8.h" +#include "Common/StringUtils.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanMemory.h" #include "Common/Log.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 90c08512f5..d84827b698 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -27,6 +27,7 @@ #include "thin3d/VulkanRenderManager.h" #include "Common/ColorConv.h" +#include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Host.h" #include "Core/MemMap.h" diff --git a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp index b63bac2c1d..ca732d23e9 100644 --- a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp @@ -25,7 +25,7 @@ #include "Common/CommonWindows.h" #endif -#include "base/stringutil.h" +#include "Common/StringUtils.h" #include "Common/Vulkan/VulkanLoader.h" #include "Core/Config.h" #include "GPU/ge_constants.h" diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index 6d59ba6a1a..0e52abc314 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -15,9 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/basictypes.h" -#include "base/stringutil.h" #include "Common/Log.h" +#include "Common/StringUtils.h" #include "Common/Vulkan/VulkanContext.h" #include "GPU/Vulkan/VulkanUtil.h" diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index 8741168179..3ccc55c824 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -15,10 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "TouchControlVisibilityScreen.h" -#include "UI/ComboKeyMappingScreen.h" - -#include "Core/Config.h" #include "i18n/i18n.h" #include "base/colorutil.h" #include "base/display.h" @@ -26,12 +22,16 @@ #include "gfx_es2/draw_buffer.h" #include "gfx/texture_atlas.h" #include "math/curves.h" -#include "base/stringutil.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" +#include "Core/Config.h" + +#include "TouchControlVisibilityScreen.h" +#include "UI/ComboKeyMappingScreen.h" void ComboKeyScreen::CreateViews() { using namespace UI; diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index a5c040d029..b0d2bfc5f2 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -15,13 +15,13 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/stringutil.h" #include "ext/xxhash.h" #include "i18n/i18n.h" #include "ui/ui.h" #include "util/text/utf8.h" #include "Common/FileUtil.h" +#include "Common/StringUtils.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/CwCheat.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 86d6c9b71a..022f157ed6 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -19,7 +19,6 @@ #include "ppsspp_config.h" #include "base/display.h" -#include "base/stringutil.h" #include "gfx_es2/gpu_features.h" #include "i18n/i18n.h" #include "ui/ui_context.h" @@ -30,6 +29,7 @@ #include "Common/LogManager.h" #include "Common/CPUDetect.h" +#include "Common/StringUtils.h" #include "Core/MemMap.h" #include "Core/Config.h" diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index a88130091a..807448c8ad 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -22,7 +22,6 @@ #include #include -#include "base/stringutil.h" #include "file/file_util.h" #include "file/zip_read.h" #include "thin3d/thin3d.h" diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 229cb4e8c9..5d8d04ff1c 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -22,8 +22,6 @@ #include "base/display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres #include "base/colorutil.h" -#include "base/stringutil.h" -#include "Common/TimeUtil.h" #include "math/curves.h" #include "net/resolve.h" #include "gfx_es2/gpu_features.h" @@ -54,6 +52,8 @@ #include "Common/KeyMap.h" #include "Common/FileUtil.h" #include "Common/OSVersion.h" +#include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Host.h" diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index ca03869cd8..319c8b860e 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -25,7 +25,6 @@ #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" #include "math/curves.h" -#include "base/stringutil.h" #include "ui/root.h" #include "ui/ui_context.h" #include "ui/view.h" @@ -34,6 +33,7 @@ #include "Common/FileUtil.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Core/System.h" #include "Core/Host.h" #include "Core/Reporting.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index b783140809..57cfbea75d 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -44,8 +44,6 @@ #endif #include "base/display.h" -#include "base/stringutil.h" -#include "Common/TimeUtil.h" #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" @@ -71,6 +69,8 @@ #include "Common/CPUDetect.h" #include "Common/FileUtil.h" +#include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Common/KeyMap.h" #include "Common/LogManager.h" #include "Common/MemArena.h" diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index df694192f4..ee36bba3ba 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -17,7 +17,7 @@ #include #include -#include "base/stringutil.h" + #include "i18n/i18n.h" #include "gfx_es2/draw_buffer.h" #include "ui/view.h" @@ -26,6 +26,8 @@ #include "ui/ui_screen.h" #include "thin3d/thin3d.h" +#include "Common/StringUtils.h" + #include "Core/Reporting.h" #include "Core/SaveState.h" #include "Core/System.h" diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index e52fa68505..e0c5a4c990 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -25,7 +25,6 @@ #include #endif -#include "base/stringutil.h" #include "file/path.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" @@ -34,8 +33,10 @@ #include "net/http_client.h" #include "net/resolve.h" #include "net/url.h" + #include "Common/Common.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/WebServer.h" #include "UI/RemoteISOScreen.h" diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index f214ba9dfd..ae7a8909a9 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -18,7 +18,6 @@ #include #include "base/display.h" -#include "base/stringutil.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" @@ -33,6 +32,7 @@ #include "Core/System.h" #include "Common/FileUtil.h" #include "Common/Log.h" +#include "Common/StringUtils.h" using namespace UI; diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 45e951c419..9714b689a0 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -19,7 +19,6 @@ #include #include "base/colorutil.h" -#include "base/stringutil.h" #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" #include "math/curves.h" @@ -35,6 +34,7 @@ #include "Common/FileUtil.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Core/Host.h" #include "Core/Config.h" #include "Core/Loaders.h" diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 0d4f747f02..51fc5b92b4 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -387,7 +387,6 @@ - @@ -472,7 +471,6 @@ - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index a424450ad6..add1237be7 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -73,9 +73,6 @@ base - - base - thin3d @@ -487,9 +484,6 @@ base - - base - thin3d diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index ecfaca8749..f5d80c6e77 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -24,10 +24,11 @@ #include "Core/CoreTiming.h" #include "Core/MIPS/MIPSAnalyst.h" -#include "base/stringutil.h" #include "util/text/utf8.h" #include "Common/CommonWindows.h" +#include "Common/StringUtils.h" + #include #include diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 5fb0fcb72b..c22b00b554 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -20,9 +20,9 @@ #include #include -#include "base/stringutil.h" #include "util/text/parsers.h" #include "Common/ColorConv.h" +#include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Screenshot.h" #include "Windows/GEDebugger/GEDebugger.h" diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 7b10b5e7c8..38b7623352 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -55,7 +55,6 @@ #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanContext.h" -#include "base/stringutil.h" #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" #include "thin3d/VulkanRenderManager.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 78a60abf28..14fc10cdf8 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -34,8 +34,8 @@ #include "base/display.h" #include "base/NativeApp.h" -#include "base/stringutil.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "i18n/i18n.h" #include "input/input_state.h" #include "input/keycodes.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index ab80ec4cea..d054c50741 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -7,7 +7,6 @@ #include "resource.h" -#include "base/stringutil.h" #include "i18n/i18n.h" #include "util/text/utf8.h" #include "base/NativeApp.h" @@ -19,6 +18,7 @@ #include "Common/ConsoleListener.h" #include "Common/OSVersion.h" #include "Common/Vulkan/VulkanLoader.h" +#include "Common/StringUtils.h" #if PPSSPP_API(ANY_GL) #include "GPU/GLES/TextureScalerGLES.h" #include "GPU/GLES/TextureCacheGLES.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index bf2b74adcc..2fdfc565d8 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -32,7 +32,6 @@ #include #include "base/display.h" -#include "base/stringutil.h" #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" @@ -51,6 +50,7 @@ #include "Common/LogManager.h" #include "Common/ConsoleListener.h" +#include "Common/StringUtils.h" #include "Commctrl.h" diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index bdd2891d30..bba710d3f0 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -50,7 +50,6 @@ struct JNIEnv {}; #endif #include "base/basictypes.h" -#include "base/stringutil.h" #include "base/display.h" #include "base/NativeApp.h" #include "thread/threadutil.h" @@ -67,7 +66,9 @@ struct JNIEnv {}; #include "Common/Log.h" #include "Common/GraphicsContext.h" +#include "Common/StringUtils.h" #include "Common/TimeUtil.h" + #include "AndroidGraphicsContext.h" #include "AndroidVulkanContext.h" #include "AndroidEGLContext.h" diff --git a/ext/native/Android.mk b/ext/native/Android.mk index a922490f88..fc41991fd9 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -10,7 +10,6 @@ LOCAL_SRC_FILES :=\ base/buffer.cpp \ base/display.cpp \ base/colorutil.cpp \ - base/stringutil.cpp \ data/base64.cpp \ data/compression.cpp \ ext/cityhash/city.cpp \ diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h index 3334cea629..f2e53d2d1e 100644 --- a/ext/native/base/basictypes.h +++ b/ext/native/base/basictypes.h @@ -33,8 +33,6 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #endif -inline uint8_t swap8(uint8_t _data) {return _data;} - // Just in case this has been defined by platform #undef swap16 #undef swap32 diff --git a/ext/native/base/stringutil.cpp b/ext/native/base/stringutil.cpp deleted file mode 100644 index 965c458040..0000000000 --- a/ext/native/base/stringutil.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include "ppsspp_config.h" -#ifdef _WIN32 -#include -#undef min -#undef max -#endif -#if PPSSPP_PLATFORM(SWITCH) -#define _GNU_SOURCE -#include -#endif -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "base/buffer.h" -#include "base/stringutil.h" - -std::string LineNumberString(const std::string &str) { - std::stringstream input(str); - std::stringstream output; - std::string line; - - int lineNumber = 1; - while (std::getline(input, line)) { - output << std::setw(4) << lineNumber++ << ": " << line << std::endl; - } - - return output.str(); -} - -void SkipSpace(const char **ptr) { - while (**ptr && isspace(**ptr)) { - (*ptr)++; - } -} - -void DataToHexString(const uint8_t *data, size_t size, std::string *output) { - Buffer buffer; - for (size_t i = 0; i < size; i++) { - if (i && !(i & 15)) - buffer.Printf("\n"); - buffer.Printf("%02x ", data[i]); - } - buffer.TakeAll(output); -} - -void DataToHexString(const char* prefix, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output) { - Buffer buffer; - size_t i = 0; - for (; i < size; i++) { - if (i && !(i & 15)) { - buffer.Printf(" "); - for (size_t j = i - 16; j < i; j++) { - buffer.Printf("%c", ((data[j] < 0x20) || (data[j] > 0x7e)) ? 0x2e : data[j]); - } - buffer.Printf("\n"); - } - if (!(i & 15)) - buffer.Printf("%s%08x ", prefix, startAddr + i); - buffer.Printf("%02x ", data[i]); - } - if (size & 15) { - size_t padded_size = ((size-1) | 15) + 1; - for (size_t j = size; j < padded_size; j++) { - buffer.Printf(" "); - } - buffer.Printf(" "); - for (size_t j = size & ~UINT64_C(0xF); j < size; j++) { - buffer.Printf("%c", ((data[j] < 0x20) || (data[j] > 0x7e)) ? 0x2e : data[j]); - } - } - buffer.TakeAll(output); -} - -std::string StringFromFormat(const char* format, ...) -{ - va_list args; - std::string temp = ""; -#ifdef _WIN32 - int required = 0; - - va_start(args, format); - required = _vscprintf(format, args); - // Using + 2 to be safe between MSVC versions. - // In MSVC 2015 and later, vsnprintf counts the trailing zero (per c++11.) - temp.resize(required + 2); - if (vsnprintf(&temp[0], required + 1, format, args) < 0) { - temp.resize(0); - } else { - temp.resize(required); - } - va_end(args); -#else - char *buf = nullptr; - - va_start(args, format); - if (vasprintf(&buf, format, args) < 0) - buf = nullptr; - va_end(args); - - if (buf != nullptr) { - temp = buf; - free(buf); - } -#endif - return temp; -} - -std::string StringFromInt(int value) -{ - char temp[16]; - sprintf(temp, "%i", value); - return temp; -} - -// Turns " hej " into "hej". Also handles tabs. -std::string StripSpaces(const std::string &str) -{ - const size_t s = str.find_first_not_of(" \t\r\n"); - - if (str.npos != s) - return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); - else - return ""; -} - -// "\"hello\"" is turned to "hello" -// This one assumes that the string has already been space stripped in both -// ends, as done by StripSpaces above, for example. -std::string StripQuotes(const std::string& s) -{ - if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) - return s.substr(1, s.size() - 2); - else - return s; -} - -void SplitString(const std::string& str, const char delim, std::vector& output) -{ - size_t next = 0; - for (size_t pos = 0, len = str.length(); pos < len; ++pos) { - if (str[pos] == delim) { - output.push_back(str.substr(next, pos - next)); - // Skip the delimiter itself. - next = pos + 1; - } - } - - if (next == 0) { - output.push_back(str); - } else if (next < str.length()) { - output.push_back(str.substr(next)); - } -} - -void GetQuotedStrings(const std::string& str, std::vector& output) -{ - size_t next = 0; - bool even = 0; - for (size_t pos = 0, len = str.length(); pos < len; ++pos) { - if (str[pos] == '\"' || str[pos] == '\'') { - if (even) { - //quoted text - output.push_back(str.substr(next, pos - next)); - even = 0; - } else { - //non quoted text - even = 1; - } - // Skip the delimiter itself. - next = pos + 1; - } - } -} - -std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) -{ - size_t pos = 0; - - if (src == dest) - return result; - - while(1) - { - pos = result.find(src, pos); - if (pos == result.npos) - break; - result.replace(pos, src.size(), dest); - pos += dest.size(); - } - return result; -} diff --git a/ext/native/base/stringutil.h b/ext/native/base/stringutil.h deleted file mode 100644 index 0e293a0f43..0000000000 --- a/ext/native/base/stringutil.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include -#include - -#include "base/basictypes.h" - -#ifdef _MSC_VER -#pragma warning (disable:4996) -#define strncasecmp _strnicmp -#define strcasecmp _stricmp -#else -#include -#endif - -// Useful for shaders with error messages.. -std::string LineNumberString(const std::string &str); - -// Other simple string utilities. - -inline bool startsWith(const std::string &str, const std::string &what) { - if (str.size() < what.size()) - return false; - return str.substr(0, what.size()) == what; -} - -inline bool endsWith(const std::string &str, const std::string &what) { - if (str.size() < what.size()) - return false; - return str.substr(str.size() - what.size()) == what; -} - -// Only use on strings where you're only concerned about ASCII. -inline bool startsWithNoCase(const std::string &str, const std::string &what) { - if (str.size() < what.size()) - return false; - return strncasecmp(str.c_str(), what.c_str(), what.size()) == 0; -} - -inline bool endsWithNoCase(const std::string &str, const std::string &what) { - if (str.size() < what.size()) - return false; - const size_t offset = str.size() - what.size(); - return strncasecmp(str.c_str() + offset, what.c_str(), what.size()) == 0; -} - -void DataToHexString(const uint8_t *data, size_t size, std::string *output); -void DataToHexString(const char* prefix, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output); - -std::string StringFromFormat(const char* format, ...); -std::string StringFromInt(int value); - -std::string StripSpaces(const std::string &s); -std::string StripQuotes(const std::string &s); - -void SplitString(const std::string& str, const char delim, std::vector& output); - -void GetQuotedStrings(const std::string& str, std::vector& output); - -std::string ReplaceAll(std::string input, const std::string& src, const std::string& dest); - -void SkipSpace(const char **ptr); diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index 7206c36e3c..9ef63d5462 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -19,10 +19,11 @@ #include #include "base/basictypes.h" -#include "base/stringutil.h" #include "file/file_util.h" #include "util/text/utf8.h" +#include "Common/StringUtils.h" + #if !defined(__linux__) && !defined(_WIN32) && !defined(__QNX__) #define stat64 stat #endif @@ -126,22 +127,6 @@ bool readFileToString(bool text_file, const char *filename, std::string &str) return true; } - -bool readDataFromFile(bool text_file, unsigned char* &data, const unsigned int size, const char *filename) -{ - FILE *f = openCFile(filename, text_file ? "r" : "rb"); - if (!f) - return false; - size_t len = (size_t)GetSize(f); - if(len < size) { - fclose(f); - return false; - } - data[fread(data, 1, size, f)] = 0; - fclose(f); - return true; -} - // Returns true if filename is a directory bool isDirectory(const std::string &filename) { FileInfo info; diff --git a/ext/native/file/file_util.h b/ext/native/file/file_util.h index b6c414139b..e194f3f2b2 100644 --- a/ext/native/file/file_util.h +++ b/ext/native/file/file_util.h @@ -12,7 +12,6 @@ bool writeStringToFile(bool text_file, const std::string &str, const char *filen bool readFileToString(bool text_file, const char *filename, std::string &str); bool writeDataToFile(bool text_file, const void* data, const unsigned int size, const char *filename); -bool readDataFromFile(bool text_file, unsigned char* &data, const unsigned int size, const char *filename); // Beginnings of a directory utility system. TODO: Improve. diff --git a/ext/native/file/ini_file.cpp b/ext/native/file/ini_file.cpp index c4c1b7934e..b6dcf0d977 100644 --- a/ext/native/file/ini_file.cpp +++ b/ext/native/file/ini_file.cpp @@ -16,7 +16,6 @@ #include #include -#include "base/stringutil.h" #include "file/ini_file.h" #include "file/vfs.h" #include "util/text/parsers.h" @@ -25,6 +24,8 @@ #include "util/text/utf8.h" #endif +#include "Common/StringUtils.h" + static bool ParseLineKey(const std::string &line, size_t &pos, std::string *keyOut) { std::string key = ""; @@ -164,6 +165,22 @@ std::string* Section::GetLine(const char* key, std::string* valueOut, std::strin return 0; } +void Section::Set(const char* key, uint32_t newValue) { + Set(key, StringFromFormat("0x%08x", newValue).c_str()); +} + +void Section::Set(const char* key, float newValue) { + Set(key, StringFromFormat("%f", newValue).c_str()); +} + +void Section::Set(const char* key, double newValue) { + Set(key, StringFromFormat("%f", newValue).c_str()); +} + +void Section::Set(const char* key, int newValue) { + Set(key, StringFromInt(newValue).c_str()); +} + void Section::Set(const char* key, const char* newValue) { std::string value, commented; diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h index 4c2b65ed4b..5d65045033 100644 --- a/ext/native/file/ini_file.h +++ b/ext/native/file/ini_file.h @@ -8,7 +8,6 @@ #include #include #include -#include "base/stringutil.h" class Section { @@ -34,21 +33,13 @@ public: } bool Get(const char* key, std::string* value, const char* defaultValue); - void Set(const char* key, uint32_t newValue) { - Set(key, StringFromFormat("0x%08x", newValue).c_str()); - } - void Set(const char* key, float newValue) { - Set(key, StringFromFormat("%f", newValue).c_str()); - } + void Set(const char* key, uint32_t newValue); + void Set(const char* key, float newValue); void Set(const char* key, const float newValue, const float defaultValue); - void Set(const char* key, double newValue) { - Set(key, StringFromFormat("%f", newValue).c_str()); - } + void Set(const char* key, double newValue); void Set(const char* key, int newValue, int defaultValue); - void Set(const char* key, int newValue) { - Set(key, StringFromInt(newValue).c_str()); - } + void Set(const char* key, int newValue); void Set(const char* key, bool newValue, bool defaultValue); void Set(const char* key, bool newValue) { diff --git a/ext/native/file/path.cpp b/ext/native/file/path.cpp index 8025878c02..5be7b326c4 100644 --- a/ext/native/file/path.cpp +++ b/ext/native/file/path.cpp @@ -1,8 +1,10 @@ #include #include #include -#include "base/stringutil.h" + +#include "Common/StringUtils.h" #include "Common/TimeUtil.h" + #include "file/path.h" #include "net/http_client.h" #include "net/url.h" diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index da23c142cb..12307755f8 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -4,7 +4,6 @@ #include #include "base/display.h" -#include "base/stringutil.h" #include "math/math_util.h" #include "gfx/texture_atlas.h" #include "gfx/gl_debug_log.h" @@ -14,6 +13,7 @@ #include "util/text/wrap_text.h" #include "Common/Log.h" +#include "Common/StringUtils.h" enum { // Enough? diff --git a/ext/native/gfx_es2/draw_text.cpp b/ext/native/gfx_es2/draw_text.cpp index a205fbca61..581ea31274 100644 --- a/ext/native/gfx_es2/draw_text.cpp +++ b/ext/native/gfx_es2/draw_text.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" #include "util/text/wrap_text.h" diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index 34e4295bd3..dc1ec66f8a 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" #include "util/text/wrap_text.h" diff --git a/ext/native/gfx_es2/draw_text_qt.cpp b/ext/native/gfx_es2/draw_text_qt.cpp index 39b4ac95eb..877e218ce7 100644 --- a/ext/native/gfx_es2/draw_text_qt.cpp +++ b/ext/native/gfx_es2/draw_text_qt.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" #include "util/text/wrap_text.h" diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index 0e741b0077..b58af57ae2 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" #include "util/text/wrap_text.h" diff --git a/ext/native/gfx_es2/draw_text_win.cpp b/ext/native/gfx_es2/draw_text_win.cpp index 1d08616131..48315e5152 100644 --- a/ext/native/gfx_es2/draw_text_win.cpp +++ b/ext/native/gfx_es2/draw_text_win.cpp @@ -1,5 +1,4 @@ #include "base/display.h" -#include "base/stringutil.h" #include "thin3d/thin3d.h" #include "util/hash/hash.h" #include "util/text/wrap_text.h" @@ -8,6 +7,7 @@ #include "gfx_es2/draw_text_win.h" #include "Common/Log.h" +#include "Common/StringUtils.h" #if defined(_WIN32) && !defined(USING_QT_UI) && !PPSSPP_PLATFORM(UWP) diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index 930a489aae..f8b29909f3 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -3,7 +3,7 @@ #include #include -#include "base/stringutil.h" +#include "Common/StringUtils.h" #if PPSSPP_API(ANY_GL) #include "gfx/gl_common.h" diff --git a/ext/native/i18n/i18n.cpp b/ext/native/i18n/i18n.cpp index bbafbd9534..72ec1f949f 100644 --- a/ext/native/i18n/i18n.cpp +++ b/ext/native/i18n/i18n.cpp @@ -1,8 +1,9 @@ -#include "base/stringutil.h" #include "i18n/i18n.h" #include "file/ini_file.h" #include "file/vfs.h" +#include "Common/StringUtils.h" + I18NRepo i18nrepo; I18NRepo::~I18NRepo() { diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index b6653404d0..caee297bd3 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -387,7 +387,6 @@ - @@ -509,7 +508,6 @@ true true - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index d4ce209515..0c847988b1 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -80,9 +80,6 @@ input - - base - ext @@ -412,9 +409,6 @@ file - - base - net diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index a8658b2ad2..4169c97123 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -1,5 +1,7 @@ #include "net/http_client.h" + #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #ifndef _WIN32 #include @@ -19,7 +21,6 @@ #include #include "base/buffer.h" -#include "base/stringutil.h" #include "data/compression.h" #include "file/fd_util.h" #include "net/resolve.h" diff --git a/ext/native/net/http_headers.cpp b/ext/native/net/http_headers.cpp index e568c7c5c8..ca370dad9c 100644 --- a/ext/native/net/http_headers.cpp +++ b/ext/native/net/http_headers.cpp @@ -4,11 +4,11 @@ #include #include -#include "base/stringutil.h" #include "file/fd_util.h" #include "net/sinks.h" #include "Common/Log.h" +#include "Common/StringUtils.h" namespace http { diff --git a/ext/native/net/url.cpp b/ext/native/net/url.cpp index 943ed4e3eb..b3aa5ff25d 100644 --- a/ext/native/net/url.cpp +++ b/ext/native/net/url.cpp @@ -1,7 +1,7 @@ -#include "base/stringutil.h" #include "net/url.h" #include "Common/Log.h" +#include "Common/StringUtils.h" const char *UrlEncoder::unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"; const char *UrlEncoder::hexChars = "0123456789ABCDEF"; diff --git a/ext/native/net/websocket_server.cpp b/ext/native/net/websocket_server.cpp index c45b266222..b769219f9c 100644 --- a/ext/native/net/websocket_server.cpp +++ b/ext/native/net/websocket_server.cpp @@ -15,7 +15,6 @@ #include #endif -#include "base/stringutil.h" #include "data/base64.h" #include "net/http_server.h" #include "net/sinks.h" @@ -23,6 +22,7 @@ #include "Common/Crypto/sha1.h" #include "Common/Log.h" +#include "Common/StringUtils.h" static const char *const WEBSOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index c5da0e4c21..aec9acb5d1 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -1,6 +1,5 @@ #include -#include "base/stringutil.h" #include "gfx/gl_common.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/gpu_features.h" @@ -10,6 +9,7 @@ #include "Common/Log.h" #include "Common/MemoryUtil.h" +#include "Common/StringUtils.h" #include "Core/Reporting.h" #include "GLQueueRunner.h" diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index 825a437681..e929b89018 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -4,6 +4,7 @@ #include #include "Common/Log.h" +#include "Common/StringUtils.h" #include "Common/Vulkan/VulkanContext.h" #include "thin3d/VulkanRenderManager.h" diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 50657051ef..57b1e78ec7 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -11,7 +11,6 @@ #include #include "base/display.h" -#include "base/stringutil.h" #include "Common/Vulkan/VulkanContext.h" #include "math/dataconv.h" #include "math/math_util.h" diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 3308c7f657..855f80c7c8 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -21,7 +21,6 @@ #include #include "base/display.h" -#include "base/stringutil.h" #include "image/zim_load.h" #include "math/lin/matrix4x4.h" #include "math/dataconv.h" @@ -29,6 +28,7 @@ #include "thin3d/VulkanRenderManager.h" #include "Common/Log.h" +#include "Common/StringUtils.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanImage.h" #include "Common/Vulkan/VulkanMemory.h" diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index ca36957b62..e46344a41a 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -3,7 +3,6 @@ #include #include "base/display.h" -#include "base/stringutil.h" #include "input/input_state.h" #include "input/keycodes.h" #include "math/curves.h" @@ -15,6 +14,7 @@ #include "gfx_es2/draw_buffer.h" #include "Common/Log.h" +#include "Common/StringUtils.h" static const bool ClickDebug = false; diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index b8e62a5cce..ce79dfc516 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -1,7 +1,6 @@ #include #include -#include "base/stringutil.h" #include "input/input_state.h" #include "input/keycodes.h" #include "gfx_es2/draw_buffer.h" @@ -16,6 +15,7 @@ #include "base/NativeApp.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" namespace UI { diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index cd3221f790..ecec7a1019 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -3,7 +3,6 @@ #include #include -#include "base/stringutil.h" #include "input/keycodes.h" #include "math/curves.h" #include "ui/ui_context.h" @@ -15,6 +14,7 @@ #include "Common/Log.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" namespace UI { diff --git a/ext/native/util/text/parsers.cpp b/ext/native/util/text/parsers.cpp index e762ec4232..f36f3ff33d 100644 --- a/ext/native/util/text/parsers.cpp +++ b/ext/native/util/text/parsers.cpp @@ -2,9 +2,10 @@ #include #include -#include "base/stringutil.h" #include "util/text/parsers.h" +#include "Common/StringUtils.h" + bool Version::ParseVersionString(std::string str) { if (str.empty()) return false; diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 87fc689e03..eb0472bcbb 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -217,7 +217,6 @@ SOURCES_CXX += \ $(EXTDIR)/native/base/buffer.cpp \ $(EXTDIR)/native/base/colorutil.cpp \ $(EXTDIR)/native/base/display.cpp \ - $(EXTDIR)/native/base/stringutil.cpp \ $(EXTDIR)/native/data/compression.cpp \ $(EXTDIR)/native/json/json_reader.cpp \ $(EXTDIR)/glslang/OGLCompilersDLL/InitializeDll.cpp \ From 3162f301581dc034a0b0c26dea0fb82a180f83e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 12:44:47 +0200 Subject: [PATCH 795/848] Merge base/basictypes.h into Common/Common.h (mostly). --- Common/Arm64Emitter.cpp | 7 ++---- Common/CPUDetect.cpp | 1 - Common/Common.h | 22 +++++++++++++++++- Common/TimeUtil.cpp | 1 - Common/Vulkan/VulkanContext.cpp | 1 - Common/Vulkan/VulkanLoader.cpp | 1 - Core/CwCheat.h | 1 - Core/FileSystems/FileSystem.h | 2 +- Core/HDRemaster.cpp | 2 +- Core/HLE/ReplaceTables.cpp | 2 +- Core/HLE/sceSas.cpp | 1 - Core/HW/SasAudio.cpp | 1 - Core/HW/SasReverb.cpp | 1 - Core/HW/SimpleAudioDec.h | 1 - Core/MIPS/IR/IRPassSimplify.cpp | 1 + Core/MIPS/x86/CompALU.cpp | 3 +++ GPU/Common/PresentationCommon.h | 1 - GPU/Common/ShaderId.h | 3 ++- GPU/Common/ShaderTranslation.cpp | 1 - GPU/Common/TextureScalerCommon.cpp | 5 ---- GPU/Common/TransformCommon.h | 1 - GPU/Common/VertexDecoderCommon.cpp | 2 +- GPU/Common/VertexDecoderCommon.h | 4 ++-- GPU/D3D11/DepalettizeShaderD3D11.cpp | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 2 +- GPU/D3D11/ShaderManagerD3D11.h | 2 +- GPU/Debugger/Breakpoints.cpp | 1 - GPU/Directx9/ShaderManagerDX9.h | 2 +- GPU/Directx9/TextureScalerDX9.cpp | 8 +------ GPU/GLES/ShaderManagerGLES.h | 1 - GPU/GLES/TextureScalerGLES.cpp | 5 ---- GPU/Software/Rasterizer.cpp | 1 - GPU/Software/RasterizerRectangle.cpp | 1 - GPU/Vulkan/ShaderManagerVulkan.h | 2 +- GPU/Vulkan/TextureScalerVulkan.cpp | 6 +---- UI/OnScreenDisplay.h | 3 --- UI/Store.cpp | 2 +- UWP/PPSSPP_UWPMain.cpp | 2 +- Windows/GEDebugger/TabState.cpp | 2 +- Windows/GEDebugger/TabVertices.cpp | 2 +- android/jni/TestRunner.cpp | 1 - ext/disarm.cpp | 7 +++--- ext/native/base/basictypes.h | 29 ------------------------ ext/native/base/buffer.h | 2 -- ext/native/base/colorutil.h | 2 +- ext/native/file/fd_util.cpp | 1 + ext/native/file/fd_util.h | 2 -- ext/native/file/file_util.cpp | 1 - ext/native/file/free.cpp | 1 - ext/native/file/free.h | 2 +- ext/native/file/vfs.h | 3 ++- ext/native/file/zip_read.cpp | 7 +++++- ext/native/file/zip_read.h | 6 +---- ext/native/gfx_es2/draw_buffer.h | 2 +- ext/native/gfx_es2/draw_text.h | 14 +++--------- ext/native/i18n/i18n.h | 2 +- ext/native/image/zim_load.h | 2 +- ext/native/image/zim_save.cpp | 7 +++--- ext/native/image/zim_save.h | 5 ++-- ext/native/input/input_state.h | 1 - ext/native/json/json_reader.h | 2 +- ext/native/math/curves.cpp | 4 +++- ext/native/math/curves.h | 3 --- ext/native/math/expression_parser.h | 2 +- ext/native/math/math_util.h | 5 ++-- ext/native/net/http_client.h | 2 +- ext/native/net/url.h | 7 +++--- ext/native/thread/prioritizedworkqueue.h | 3 ++- ext/native/thread/threadutil.cpp | 2 +- ext/native/tools/zimtool.cpp | 3 +++ ext/native/ui/screen.h | 3 ++- ext/native/ui/ui_context.h | 2 +- ext/native/ui/view.h | 3 ++- ext/native/util/hash/hash.cpp | 2 +- ext/native/util/random/rng.h | 2 +- ext/native/util/text/parsers.h | 3 +-- ext/native/util/text/shiftjis.h | 4 ++-- ext/native/util/text/utf16.h | 1 + ext/native/util/text/utf8.cpp | 10 ++++---- ext/native/util/text/utf8.h | 2 +- ext/snappy/snappy-stubs-public.h | 1 - 81 files changed, 107 insertions(+), 165 deletions(-) diff --git a/Common/Arm64Emitter.cpp b/Common/Arm64Emitter.cpp index 531c2ddb79..928ef5803f 100644 --- a/Common/Arm64Emitter.cpp +++ b/Common/Arm64Emitter.cpp @@ -5,15 +5,12 @@ #include "ppsspp_config.h" #include -#include #include #include #include -#include -#include - -#include "base/basictypes.h" +#include +#include #include "Arm64Emitter.h" #include "MathUtil.h" diff --git a/Common/CPUDetect.cpp b/Common/CPUDetect.cpp index ce3ad48a81..1acbb1c680 100644 --- a/Common/CPUDetect.cpp +++ b/Common/CPUDetect.cpp @@ -29,7 +29,6 @@ #include #include -#include "base/basictypes.h" #include "file/file_util.h" #include "Common/Common.h" diff --git a/Common/Common.h b/Common/Common.h index 471bef4bdf..42a7846746 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -23,7 +23,9 @@ #include #ifdef _MSC_VER -#pragma warning (disable:4100) +#pragma warning(disable:4100) +#pragma warning(disable:4244) +#pragma warning(disable:4996) #endif #include "Log.h" @@ -36,6 +38,24 @@ void operator =(const t &other) = delete; #endif +#ifndef ENUM_CLASS_BITOPS +#define ENUM_CLASS_BITOPS(T) \ + static inline T operator |(const T &lhs, const T &rhs) { \ + return T((int)lhs | (int)rhs); \ + } \ + static inline T &operator |= (T &lhs, const T &rhs) { \ + lhs = lhs | rhs; \ + return lhs; \ + } \ + static inline bool operator &(const T &lhs, const T &rhs) { \ + return ((int)lhs & (int)rhs) != 0; \ + } +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +#endif + #if defined(_WIN32) // Memory leak checks diff --git a/Common/TimeUtil.cpp b/Common/TimeUtil.cpp index 5b8a0c2611..d0466353e8 100644 --- a/Common/TimeUtil.cpp +++ b/Common/TimeUtil.cpp @@ -1,6 +1,5 @@ #include -#include "base/basictypes.h" #include "Common/TimeUtil.h" #ifdef _WIN32 diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index b659681a73..17fe8bb496 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -5,7 +5,6 @@ #include #include -#include "base/basictypes.h" #include "base/display.h" #include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index 4a6ef8a249..b70259c610 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -21,7 +21,6 @@ #include #include "Common/Log.h" -#include "base/basictypes.h" #include "base/NativeApp.h" #ifndef _WIN32 diff --git a/Core/CwCheat.h b/Core/CwCheat.h index 578ffe7b98..686694e769 100644 --- a/Core/CwCheat.h +++ b/Core/CwCheat.h @@ -8,7 +8,6 @@ #include #include -#include "base/basictypes.h" #include "Core/MemMap.h" class PointerWrap; diff --git a/Core/FileSystems/FileSystem.h b/Core/FileSystems/FileSystem.h index 6c069efe0d..46cd7a6dbc 100644 --- a/Core/FileSystems/FileSystem.h +++ b/Core/FileSystems/FileSystem.h @@ -20,8 +20,8 @@ #include #include #include -#include "base/basictypes.h" +#include "Common.h" #include "Core/HLE/sceKernel.h" enum FileAccess { diff --git a/Core/HDRemaster.cpp b/Core/HDRemaster.cpp index 33a9798279..d3d0ff16b9 100644 --- a/Core/HDRemaster.cpp +++ b/Core/HDRemaster.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/basictypes.h" +#include "Common.h" #include "Core/HDRemaster.h" bool g_RemasterMode; diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 359b76e23c..16b8ca7fe8 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -19,7 +19,7 @@ #include #include -#include "base/basictypes.h" +#include "Common/Common.h" #include "Common/Log.h" #include "Core/Config.h" #include "Core/Debugger/Breakpoints.h" diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index a79e511ae7..285fee2b37 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -32,7 +32,6 @@ #include #include -#include "base/basictypes.h" #include "profiler/profiler.h" #include "thread/threadutil.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 913c6948cf..90f408b619 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -17,7 +17,6 @@ #include -#include "base/basictypes.h" #include "profiler/profiler.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/HW/SasReverb.cpp b/Core/HW/SasReverb.cpp index 7dfb429f8b..14dbc06248 100644 --- a/Core/HW/SasReverb.cpp +++ b/Core/HW/SasReverb.cpp @@ -18,7 +18,6 @@ #include #include -#include "base/basictypes.h" #include "Core/HW/SasReverb.h" #include "Core/Util/AudioFormat.h" diff --git a/Core/HW/SimpleAudioDec.h b/Core/HW/SimpleAudioDec.h index 5a21bfe330..d7bcfc7b03 100644 --- a/Core/HW/SimpleAudioDec.h +++ b/Core/HW/SimpleAudioDec.h @@ -19,7 +19,6 @@ #include -#include "base/basictypes.h" #include "Core/HW/MediaEngine.h" #include "Core/HLE/sceAudio.h" diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index fa7481aeff..13b74ab8bf 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -2,6 +2,7 @@ #include #include +#include "base/basictypes.h" #include "Common/Log.h" #include "Core/MIPS/IR/IRInterpreter.h" #include "Core/MIPS/IR/IRPassSimplify.h" diff --git a/Core/MIPS/x86/CompALU.cpp b/Core/MIPS/x86/CompALU.cpp index 456695b575..e038bad6be 100644 --- a/Core/MIPS/x86/CompALU.cpp +++ b/Core/MIPS/x86/CompALU.cpp @@ -18,6 +18,9 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) +#include "base/basictypes.h" + +#include "Common/Common.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/x86/Jit.h" #include "Core/MIPS/x86/RegCache.h" diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index 29f9517f53..7acce4083a 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -17,7 +17,6 @@ #pragma once -#include "base/basictypes.h" #include "GPU/Common/ShaderCommon.h" struct CardboardSettings { diff --git a/GPU/Common/ShaderId.h b/GPU/Common/ShaderId.h index f117341e7d..3adc7f4c2b 100644 --- a/GPU/Common/ShaderId.h +++ b/GPU/Common/ShaderId.h @@ -3,7 +3,8 @@ #include #include #include -#include "base/basictypes.h" + +#include "Common/Common.h" // TODO: There will be additional bits, indicating that groups of these will be // sent to the shader and processed there. This will cut down the number of shaders ("ubershader approach") diff --git a/GPU/Common/ShaderTranslation.cpp b/GPU/Common/ShaderTranslation.cpp index c38d2420b1..b93df766e5 100644 --- a/GPU/Common/ShaderTranslation.cpp +++ b/GPU/Common/ShaderTranslation.cpp @@ -34,7 +34,6 @@ #undef free #endif -#include "base/basictypes.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/GPU/Common/TextureScalerCommon.cpp b/GPU/Common/TextureScalerCommon.cpp index c80e713819..3214b42306 100644 --- a/GPU/Common/TextureScalerCommon.cpp +++ b/GPU/Common/TextureScalerCommon.cpp @@ -15,11 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#if _MSC_VER == 1700 -// Has to be included before TextureScaler.h, else we get those std::bind errors in VS2012.. -#include "../native/base/basictypes.h" -#endif - #include #include #include diff --git a/GPU/Common/TransformCommon.h b/GPU/Common/TransformCommon.h index d3b78dd663..0a97975d26 100644 --- a/GPU/Common/TransformCommon.h +++ b/GPU/Common/TransformCommon.h @@ -19,7 +19,6 @@ #include -#include "base/basictypes.h" #include "Common/CommonTypes.h" #include "Core/Reporting.h" #include "GPU/ge_constants.h" diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index 0491105465..d0cdbb5b29 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -19,11 +19,11 @@ #include #include "ppsspp_config.h" -#include "base/basictypes.h" #include "Common/Log.h" #include "Common/CPUDetect.h" #include "Common/ColorConv.h" +#include "Common/Common.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/MemMap.h" diff --git a/GPU/Common/VertexDecoderCommon.h b/GPU/Common/VertexDecoderCommon.h index 333f2b1c36..0d451465b8 100644 --- a/GPU/Common/VertexDecoderCommon.h +++ b/GPU/Common/VertexDecoderCommon.h @@ -20,10 +20,10 @@ #include #include "ppsspp_config.h" -#include "base/basictypes.h" + +#include "Common/Common.h" #include "Common/Hashmaps.h" #include "Common/Log.h" -#include "Common/CommonTypes.h" #include "Core/Reporting.h" #include "GPU/ge_constants.h" #include "GPU/Common/ShaderCommon.h" diff --git a/GPU/D3D11/DepalettizeShaderD3D11.cpp b/GPU/D3D11/DepalettizeShaderD3D11.cpp index c67ce845f0..faf6c22de2 100644 --- a/GPU/D3D11/DepalettizeShaderD3D11.cpp +++ b/GPU/D3D11/DepalettizeShaderD3D11.cpp @@ -18,7 +18,7 @@ #include #include -#include "base/basictypes.h" +#include "Common/Common.h" #include "Common/Log.h" #include "Common/ColorConv.h" #include "Common/StringUtils.h" diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 4440ebf4b3..b48d67529b 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -22,8 +22,8 @@ #include "base/display.h" #include "math/lin/matrix4x4.h" #include "ext/native/thin3d/thin3d.h" -#include "base/basictypes.h" +#include "Common/Common.h" #include "Common/ColorConv.h" #include "Common/MathUtil.h" #include "Core/MemMap.h" diff --git a/GPU/D3D11/ShaderManagerD3D11.h b/GPU/D3D11/ShaderManagerD3D11.h index fd90d57d6b..abb867a613 100644 --- a/GPU/D3D11/ShaderManagerD3D11.h +++ b/GPU/D3D11/ShaderManagerD3D11.h @@ -21,7 +21,7 @@ #include -#include "base/basictypes.h" +#include "Common/Common.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/ShaderId.h" #include "GPU/Common/ShaderUniforms.h" diff --git a/GPU/Debugger/Breakpoints.cpp b/GPU/Debugger/Breakpoints.cpp index 9d1f7049f8..90bd76c524 100644 --- a/GPU/Debugger/Breakpoints.cpp +++ b/GPU/Debugger/Breakpoints.cpp @@ -19,7 +19,6 @@ #include #include -#include "base/basictypes.h" #include "GPU/Debugger/Breakpoints.h" #include "GPU/GPUState.h" diff --git a/GPU/Directx9/ShaderManagerDX9.h b/GPU/Directx9/ShaderManagerDX9.h index 7fa9818129..fac559e642 100644 --- a/GPU/Directx9/ShaderManagerDX9.h +++ b/GPU/Directx9/ShaderManagerDX9.h @@ -20,7 +20,7 @@ #include #include -#include "base/basictypes.h" +#include "Common/Common.h" #include "GPU/Directx9/VertexShaderGeneratorDX9.h" #include "GPU/Directx9/PixelShaderGeneratorDX9.h" #include "GPU/Common/ShaderCommon.h" diff --git a/GPU/Directx9/TextureScalerDX9.cpp b/GPU/Directx9/TextureScalerDX9.cpp index a31dbd3af4..bbf732a08d 100644 --- a/GPU/Directx9/TextureScalerDX9.cpp +++ b/GPU/Directx9/TextureScalerDX9.cpp @@ -15,15 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -// On Visual Studio 2012, include this before anything else so -// _VARIADIC_MAX gets set to 10, to avoid std::bind compile errors. -// See header file for reasons why. -#if defined(_WIN32) && _MSC_VER == 1700 -#include "../native/base/basictypes.h" -#endif - #include +#include "Common/Common.h" #include "Common/ColorConv.h" #include "Common/ThreadPools.h" #include "GPU/Common/TextureScalerCommon.h" diff --git a/GPU/GLES/ShaderManagerGLES.h b/GPU/GLES/ShaderManagerGLES.h index 3ee0e8e002..0c10d3ad73 100644 --- a/GPU/GLES/ShaderManagerGLES.h +++ b/GPU/GLES/ShaderManagerGLES.h @@ -19,7 +19,6 @@ #include -#include "base/basictypes.h" #include "Common/Hashmaps.h" #include "thin3d/GLRenderManager.h" #include "GPU/Common/ShaderCommon.h" diff --git a/GPU/GLES/TextureScalerGLES.cpp b/GPU/GLES/TextureScalerGLES.cpp index 73c1b849a7..d05e12c95b 100644 --- a/GPU/GLES/TextureScalerGLES.cpp +++ b/GPU/GLES/TextureScalerGLES.cpp @@ -15,11 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#if _MSC_VER == 1700 -// Has to be included before TextureScaler.h, else we get those std::bind errors in VS2012.. -#include "../native/base/basictypes.h" -#endif - #include #include "gfx/gl_common.h" diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 545de958d1..519d5b2e7c 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -18,7 +18,6 @@ #include #include -#include "base/basictypes.h" #include "profiler/profiler.h" #include "Common/ThreadPools.h" diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index 8ec1992084..be2d042692 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -3,7 +3,6 @@ #include #include -#include "base/basictypes.h" #include "profiler/profiler.h" #include "Core/System.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index bf5404acf9..e626e84152 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -18,8 +18,8 @@ #pragma once #include +#include -#include "base/basictypes.h" #include "Common/Hashmaps.h" #include "Common/Vulkan/VulkanMemory.h" #include "GPU/Common/ShaderCommon.h" diff --git a/GPU/Vulkan/TextureScalerVulkan.cpp b/GPU/Vulkan/TextureScalerVulkan.cpp index 27f43bcdaf..8b903df905 100644 --- a/GPU/Vulkan/TextureScalerVulkan.cpp +++ b/GPU/Vulkan/TextureScalerVulkan.cpp @@ -15,13 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#if _MSC_VER == 1700 -// Has to be included before TextureScaler.h, else we get those std::bind errors in VS2012.. -#include "../native/base/basictypes.h" -#endif - #include +#include "Common/Common.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/ColorConv.h" #include "Common/Log.h" diff --git a/UI/OnScreenDisplay.h b/UI/OnScreenDisplay.h index 6fbf093e55..cfd245edb8 100644 --- a/UI/OnScreenDisplay.h +++ b/UI/OnScreenDisplay.h @@ -4,9 +4,7 @@ #include #include -#include "base/basictypes.h" #include "math/geom2d.h" - #include "ui/view.h" class DrawBuffer; @@ -37,7 +35,6 @@ public: const std::list &Messages() { return messages_; } private: - std::list messages_; std::mutex mutex_; }; diff --git a/UI/Store.cpp b/UI/Store.cpp index fd27021106..846161711b 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -17,7 +17,6 @@ #include -#include "base/basictypes.h" #include "json/json_reader.h" #include "i18n/i18n.h" @@ -26,6 +25,7 @@ #include "ui/viewgroup.h" #include "gfx_es2/draw_buffer.h" +#include "Common/Common.h" #include "Common/Log.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index ddd6d3fe6b..14b4cf2169 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -3,7 +3,6 @@ #include -#include "base/basictypes.h" #include "base/NativeApp.h" #include "input/input_state.h" #include "file/vfs.h" @@ -16,6 +15,7 @@ #include "thin3d/thin3d_create.h" #include "util/text/utf8.h" +#include "Common/Common.h" #include "Common/DirectXHelper.h" #include "Common/FileUtil.h" #include "Common/Log.h" diff --git a/Windows/GEDebugger/TabState.cpp b/Windows/GEDebugger/TabState.cpp index 3b3241b947..b72ed126a8 100644 --- a/Windows/GEDebugger/TabState.cpp +++ b/Windows/GEDebugger/TabState.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/basictypes.h" +#include "Common/Common.h" #include "Windows/resource.h" #include "Windows/main.h" #include "Windows/InputBox.h" diff --git a/Windows/GEDebugger/TabVertices.cpp b/Windows/GEDebugger/TabVertices.cpp index bd65e87999..55eb23cc4b 100644 --- a/Windows/GEDebugger/TabVertices.cpp +++ b/Windows/GEDebugger/TabVertices.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/basictypes.h" +#include "Common/Common.h" #include "Core/System.h" #include "Windows/resource.h" #include "Windows/GEDebugger/GEDebugger.h" diff --git a/android/jni/TestRunner.cpp b/android/jni/TestRunner.cpp index f3db153a6e..b7ca679ed5 100644 --- a/android/jni/TestRunner.cpp +++ b/android/jni/TestRunner.cpp @@ -26,7 +26,6 @@ #include #include "ppsspp_config.h" -#include "base/basictypes.h" #include "base/display.h" #include "Common/FileUtil.h" diff --git a/ext/disarm.cpp b/ext/disarm.cpp index ece10410f4..57b34b0b53 100644 --- a/ext/disarm.cpp +++ b/ext/disarm.cpp @@ -66,11 +66,10 @@ #pragma GCC diagnostic ignored "-Wstring-plus-int" #endif -#include -#include -#include +#include +#include +#include -#include "base/basictypes.h" #include "Common/ArmEmitter.h" #include "ext/disarm.h" diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h index f2e53d2d1e..8a52f1b6c7 100644 --- a/ext/native/base/basictypes.h +++ b/ext/native/base/basictypes.h @@ -3,36 +3,7 @@ #include #include // for byte swapping -#ifdef _WIN32 -#pragma warning(disable:4244) -#pragma warning(disable:4996) -#endif - -#ifndef DISALLOW_COPY_AND_ASSIGN -#define DISALLOW_COPY_AND_ASSIGN(t) \ - t(const t &other) = delete; \ - void operator =(const t &other) = delete; -#endif - -#ifndef ENUM_CLASS_BITOPS -#define ENUM_CLASS_BITOPS(T) \ - static inline T operator |(const T &lhs, const T &rhs) { \ - return T((int)lhs | (int)rhs); \ - } \ - static inline T &operator |= (T &lhs, const T &rhs) { \ - lhs = lhs | rhs; \ - return lhs; \ - } \ - static inline bool operator &(const T &lhs, const T &rhs) { \ - return ((int)lhs & (int)rhs) != 0; \ - } -#endif - // Byteswapping -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) -#endif - // Just in case this has been defined by platform #undef swap16 #undef swap32 diff --git a/ext/native/base/buffer.h b/ext/native/base/buffer.h index 63ab44b907..3fad61d549 100644 --- a/ext/native/base/buffer.h +++ b/ext/native/base/buffer.h @@ -3,8 +3,6 @@ #include #include -#include "base/basictypes.h" - #include "Common/Common.h" // Acts as a queue. Intended to be as fast as possible for most uses. diff --git a/ext/native/base/colorutil.h b/ext/native/base/colorutil.h index f79c4a214b..0f9fa33b7a 100644 --- a/ext/native/base/colorutil.h +++ b/ext/native/base/colorutil.h @@ -1,6 +1,6 @@ #pragma once -#include "base/basictypes.h" +#include uint32_t whiteAlpha(float alpha); uint32_t blackAlpha(float alpha); diff --git a/ext/native/file/fd_util.cpp b/ext/native/file/fd_util.cpp index e7726392d4..9851d655b6 100644 --- a/ext/native/file/fd_util.cpp +++ b/ext/native/file/fd_util.cpp @@ -18,6 +18,7 @@ #endif #include +#include "Common/Common.h" #include "Common/Log.h" namespace fd_util { diff --git a/ext/native/file/fd_util.h b/ext/native/file/fd_util.h index 5160c4e157..230cba88f1 100644 --- a/ext/native/file/fd_util.h +++ b/ext/native/file/fd_util.h @@ -3,8 +3,6 @@ #include #include -#include "base/basictypes.h" - namespace fd_util { // Slow as hell and should only be used for prototyping. diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index 9ef63d5462..bc677e65c0 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -18,7 +18,6 @@ #include #include -#include "base/basictypes.h" #include "file/file_util.h" #include "util/text/utf8.h" diff --git a/ext/native/file/free.cpp b/ext/native/file/free.cpp index 3948008057..fd458ae428 100644 --- a/ext/native/file/free.cpp +++ b/ext/native/file/free.cpp @@ -17,7 +17,6 @@ #include #endif -#include "base/basictypes.h" #include "util/text/utf8.h" bool free_disk_space(const std::string &dir, uint64_t &space) { diff --git a/ext/native/file/free.h b/ext/native/file/free.h index 1c5690737e..df671fa3ed 100644 --- a/ext/native/file/free.h +++ b/ext/native/file/free.h @@ -1,6 +1,6 @@ #pragma once #include -#include "base/basictypes.h" +#include bool free_disk_space(const std::string &dir, uint64_t &space); diff --git a/ext/native/file/vfs.h b/ext/native/file/vfs.h index ce1023b635..b823519865 100644 --- a/ext/native/file/vfs.h +++ b/ext/native/file/vfs.h @@ -1,7 +1,8 @@ #pragma once -#include "base/basictypes.h" +#include #include "file/file_util.h" + // Basic virtual file system. Used to manage assets on Android, where we have to // read them manually out of the APK zipfile, while being able to run on other // platforms as well with the appropriate directory set-up. diff --git a/ext/native/file/zip_read.cpp b/ext/native/file/zip_read.cpp index 7efcab7255..45acc56f9b 100644 --- a/ext/native/file/zip_read.cpp +++ b/ext/native/file/zip_read.cpp @@ -7,9 +7,9 @@ #include #endif -#include "base/basictypes.h" #include "file/zip_read.h" +#include "Common/Common.h" #include "Common/Log.h" #ifdef __ANDROID__ @@ -201,6 +201,11 @@ bool ZipAssetReader::GetFileInfo(const char *path, FileInfo *info) { #endif +DirectoryAssetReader::DirectoryAssetReader(const char *path) { + strncpy(path_, path, ARRAY_SIZE(path_)); + path_[ARRAY_SIZE(path_) - 1] = '\0'; +} + uint8_t *DirectoryAssetReader::ReadAsset(const char *path, size_t *size) { char new_path[2048]; new_path[0] = '\0'; diff --git a/ext/native/file/zip_read.h b/ext/native/file/zip_read.h index 750a71a154..086fc43775 100644 --- a/ext/native/file/zip_read.h +++ b/ext/native/file/zip_read.h @@ -8,7 +8,6 @@ #include #include -#include "base/basictypes.h" #include "file/vfs.h" #include "file/file_util.h" @@ -48,10 +47,7 @@ private: class DirectoryAssetReader : public AssetReader { public: - explicit DirectoryAssetReader(const char *path) { - strncpy(path_, path, ARRAY_SIZE(path_)); - path_[ARRAY_SIZE(path_) - 1] = '\0'; - } + explicit DirectoryAssetReader(const char *path); // use delete[] virtual uint8_t *ReadAsset(const char *path, size_t *size); virtual bool GetFileListing(const char *path, std::vector *listing, const char *filter); diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h index a702fd6693..9b1e5d7e8d 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/ext/native/gfx_es2/draw_buffer.h @@ -3,8 +3,8 @@ // "Immediate mode"-lookalike buffered drawing. Very fast way to draw 2D. #include +#include -#include "base/basictypes.h" #include "base/colorutil.h" #include "gfx/texture_atlas.h" #include "math/geom2d.h" diff --git a/ext/native/gfx_es2/draw_text.h b/ext/native/gfx_es2/draw_text.h index f6bf8e3e34..094ccdd28d 100644 --- a/ext/native/gfx_es2/draw_text.h +++ b/ext/native/gfx_es2/draw_text.h @@ -10,10 +10,9 @@ #include "ppsspp_config.h" -#include #include +#include -#include "base/basictypes.h" #include "gfx_es2/draw_buffer.h" #include "util/text/wrap_text.h" @@ -41,12 +40,6 @@ struct TextMeasureEntry { int lastUsedFrame; }; -// Not yet functional -enum { - FONTSTYLE_BOLD = 1, - FONTSTYLE_ITALIC = 2, -}; - class TextDrawer { public: virtual ~TextDrawer(); @@ -99,11 +92,10 @@ protected: bool ignoreGlobalDpi_ = false; }; - class TextDrawerWordWrapper : public WordWrapper { public: - TextDrawerWordWrapper(TextDrawer *drawer, const char *str, float maxW, int flags) : WordWrapper(str, maxW, flags), drawer_(drawer) { - } + TextDrawerWordWrapper(TextDrawer *drawer, const char *str, float maxW, int flags) + : WordWrapper(str, maxW, flags), drawer_(drawer) {} protected: float MeasureWidth(const char *str, size_t bytes) override; diff --git a/ext/native/i18n/i18n.h b/ext/native/i18n/i18n.h index a973ea2f8f..f8493d1b99 100644 --- a/ext/native/i18n/i18n.h +++ b/ext/native/i18n/i18n.h @@ -14,7 +14,7 @@ #include #include -#include "base/basictypes.h" +#include "Common/Common.h" // Reasonably thread safe. diff --git a/ext/native/image/zim_load.h b/ext/native/image/zim_load.h index ccec2d71b9..18354bc6d6 100644 --- a/ext/native/image/zim_load.h +++ b/ext/native/image/zim_load.h @@ -1,6 +1,6 @@ #pragma once -#include "base/basictypes.h" +#include // LoadZIM's responsibility: // * Parse the ZIM format diff --git a/ext/native/image/zim_save.cpp b/ext/native/image/zim_save.cpp index b62ba3adb8..f46ca72ef7 100644 --- a/ext/native/image/zim_save.cpp +++ b/ext/native/image/zim_save.cpp @@ -2,6 +2,7 @@ #include #include +#include "image/zim_load.h" #include "image/zim_save.h" #include "zlib.h" @@ -77,8 +78,6 @@ bool ispowerof2 (int x) { return true; } - - void Convert(const uint8_t *image_data, int width, int height, int pitch, int flags, uint8_t **data, int *data_size) { // For 4444 and 565. Ordered dither matrix. looks really surprisingly good on cell phone screens at 4444. @@ -157,10 +156,10 @@ uint8_t *DownsampleBy2(const uint8_t *image, int width, int height, int pitch) { int degamma[256]; int gamma[32768]; for (int i =0; i < 256; i++) { - degamma[i] = powf((float)i / 255.0f, 1.0f/2.2f) * 8191.0f; + degamma[i] = (int)(powf((float)i / 255.0f, 1.0f/2.2f) * 8191.0f); } for (int i = 0; i < 32768; i++) { - gamma[i] = powf((float)i / 32764.0f, 2.2f) * 255.0f; + gamma[i] = (int)(powf((float)i / 32764.0f, 2.2f) * 255.0f); } // Really stupid mipmap downsampling - at least it does gamma though. diff --git a/ext/native/image/zim_save.h b/ext/native/image/zim_save.h index 3fe5c2f68a..c8938a91e9 100644 --- a/ext/native/image/zim_save.h +++ b/ext/native/image/zim_save.h @@ -1,9 +1,10 @@ #pragma once #include +#include -#include "base/basictypes.h" -#include "image/zim_load.h" +// For the type enums etc. +#include "zim_load.h" // SaveZIM's responsibility: // * Write the ZIM format diff --git a/ext/native/input/input_state.h b/ext/native/input/input_state.h index c648612e34..2ce502f860 100644 --- a/ext/native/input/input_state.h +++ b/ext/native/input/input_state.h @@ -8,7 +8,6 @@ #include #include "math/lin/vec3.h" -#include "base/basictypes.h" #include "input/keycodes.h" // Default device IDs diff --git a/ext/native/json/json_reader.h b/ext/native/json/json_reader.h index 612a7f9d2f..60cc78cfb9 100644 --- a/ext/native/json/json_reader.h +++ b/ext/native/json/json_reader.h @@ -2,8 +2,8 @@ #include #include -#include "base/basictypes.h" #include "ext/gason/gason.h" +#include "Common/Common.h" #include "Common/Log.h" namespace json { diff --git a/ext/native/math/curves.cpp b/ext/native/math/curves.cpp index ae5ad95ee7..65dae53f5e 100644 --- a/ext/native/math/curves.cpp +++ b/ext/native/math/curves.cpp @@ -1,9 +1,11 @@ -#include +#include #include "math/math_util.h" #include "curves.h" +#include "Common/Common.h" + float linearInOut(int t, int fadeInLength, int solidLength, int fadeOutLength) { if (t < 0) return 0; if (t < fadeInLength) { diff --git a/ext/native/math/curves.h b/ext/native/math/curves.h index 8799a0cf82..8a2004e012 100644 --- a/ext/native/math/curves.h +++ b/ext/native/math/curves.h @@ -1,10 +1,7 @@ #pragma once -#include "base/basictypes.h" - // Easy curve computation for fades etc. - // output range: [0.0, 1.0] float linearInOut(int t, int fadeInLength, int solidLength, int fadeOutLength); float linearIn(int t, int fadeInLength); diff --git a/ext/native/math/expression_parser.h b/ext/native/math/expression_parser.h index 306075c9c9..3d39340a42 100644 --- a/ext/native/math/expression_parser.h +++ b/ext/native/math/expression_parser.h @@ -1,6 +1,6 @@ #pragma once -#include "../base/basictypes.h" +#include #include typedef std::pair ExpressionPair; diff --git a/ext/native/math/math_util.h b/ext/native/math/math_util.h index 12147a6f64..0cf1101321 100644 --- a/ext/native/math/math_util.h +++ b/ext/native/math/math_util.h @@ -5,8 +5,7 @@ #include #include - -#include "base/basictypes.h" +#include typedef unsigned short float16; @@ -101,7 +100,7 @@ inline int is_even(float d) { // Rounds *.5 to closest even number inline double round_ieee_754(double d) { - float i = floor(d); + float i = (float)floor(d); d -= i; if (d < 0.5f) return i; diff --git a/ext/native/net/http_client.h b/ext/native/net/http_client.h index 9c935858fa..be71cedcff 100644 --- a/ext/native/net/http_client.h +++ b/ext/native/net/http_client.h @@ -3,8 +3,8 @@ #include #include #include +#include -#include "base/basictypes.h" #include "base/buffer.h" #include "net/resolve.h" diff --git a/ext/native/net/url.h b/ext/native/net/url.h index a46564d642..1a8a91677b 100644 --- a/ext/native/net/url.h +++ b/ext/native/net/url.h @@ -1,13 +1,12 @@ #pragma once #include -#include -#include +#include +#include #include +#include #include -#include "base/basictypes.h" - #if defined(_MSC_VER) && _MSC_VER < 1900 #undef snprintf #define snprintf _snprintf diff --git a/ext/native/thread/prioritizedworkqueue.h b/ext/native/thread/prioritizedworkqueue.h index 032e6a9694..83848d2c65 100644 --- a/ext/native/thread/prioritizedworkqueue.h +++ b/ext/native/thread/prioritizedworkqueue.h @@ -5,9 +5,10 @@ #include #include -#include "base/basictypes.h" #include "thread/threadutil.h" +#include "Common/Common.h" + // Priorities can change dynamically. // Try to make priority() fast, it will be called a lot. diff --git a/ext/native/thread/threadutil.cpp b/ext/native/thread/threadutil.cpp index 9971293685..8b9d32bc52 100644 --- a/ext/native/thread/threadutil.cpp +++ b/ext/native/thread/threadutil.cpp @@ -9,8 +9,8 @@ #endif #include +#include -#include "base/basictypes.h" #include "thread/threadutil.h" #include "Common/Log.h" diff --git a/ext/native/tools/zimtool.cpp b/ext/native/tools/zimtool.cpp index 7fadb4218b..9e3fe3b813 100644 --- a/ext/native/tools/zimtool.cpp +++ b/ext/native/tools/zimtool.cpp @@ -3,8 +3,11 @@ #include #include "image/png_load.h" +#include "image/zim_load.h" #include "image/zim_save.h" +#include "Common/Common.h" + char magic[5] = "ZIMG"; bool FLAGS_flip = false; diff --git a/ext/native/ui/screen.h b/ext/native/ui/screen.h index d269995880..f0c696a6de 100644 --- a/ext/native/ui/screen.h +++ b/ext/native/ui/screen.h @@ -16,10 +16,11 @@ #include #include -#include "base/basictypes.h" #include "base/NativeApp.h" #include "input/input_state.h" +#include "Common/Common.h" + namespace UI { class View; } diff --git a/ext/native/ui/ui_context.h b/ext/native/ui/ui_context.h index b6d9dd3e43..03130d29b9 100644 --- a/ext/native/ui/ui_context.h +++ b/ext/native/ui/ui_context.h @@ -2,8 +2,8 @@ #include #include +#include -#include "base/basictypes.h" #include "math/geom2d.h" #include "math/lin/vec3.h" #include "gfx/texture_atlas.h" diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index b21d82076d..379456301f 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -15,12 +15,13 @@ #include #include -#include "base/basictypes.h" #include "gfx/texture_atlas.h" #include "math/lin/matrix4x4.h" #include "math/math_util.h" #include "math/geom2d.h" +#include "Common/Common.h" + #undef small struct KeyInput; diff --git a/ext/native/util/hash/hash.cpp b/ext/native/util/hash/hash.cpp index 3bb840f84d..5af7728d0d 100644 --- a/ext/native/util/hash/hash.cpp +++ b/ext/native/util/hash/hash.cpp @@ -1,4 +1,4 @@ -#include "base/basictypes.h" +#include #include "util/hash/hash.h" namespace hash { diff --git a/ext/native/util/random/rng.h b/ext/native/util/random/rng.h index 0a5960fa70..50ec4ea60e 100644 --- a/ext/native/util/random/rng.h +++ b/ext/native/util/random/rng.h @@ -1,6 +1,6 @@ #pragma once -#include "base/basictypes.h" +#include // George Marsaglia-style random number generator. class GMRng { diff --git a/ext/native/util/text/parsers.h b/ext/native/util/text/parsers.h index a2bf62dfd4..909e667178 100644 --- a/ext/native/util/text/parsers.h +++ b/ext/native/util/text/parsers.h @@ -2,8 +2,7 @@ #include #include - -#include "base/basictypes.h" +#include #undef major #undef minor diff --git a/ext/native/util/text/shiftjis.h b/ext/native/util/text/shiftjis.h index e92df04db6..5f77f7665d 100644 --- a/ext/native/util/text/shiftjis.h +++ b/ext/native/util/text/shiftjis.h @@ -1,6 +1,6 @@ #pragma once -#include "base/basictypes.h" +#include // Warning: decodes/encodes JIS, not Unicode. // Use a table to map. @@ -137,4 +137,4 @@ struct ShiftJIS { private: const char *c_; int index_; -}; \ No newline at end of file +}; diff --git a/ext/native/util/text/utf16.h b/ext/native/util/text/utf16.h index 830eac2c51..c23a554856 100644 --- a/ext/native/util/text/utf16.h +++ b/ext/native/util/text/utf16.h @@ -1,5 +1,6 @@ #pragma once +#include #include "base/basictypes.h" // Should optimize out. diff --git a/ext/native/util/text/utf8.cpp b/ext/native/util/text/utf8.cpp index 5c24b761af..a847feef96 100644 --- a/ext/native/util/text/utf8.cpp +++ b/ext/native/util/text/utf8.cpp @@ -18,15 +18,15 @@ #undef max #endif -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include -#include "base/basictypes.h" #include "utf8.h" #include "utf16.h" diff --git a/ext/native/util/text/utf8.h b/ext/native/util/text/utf8.h index fd6ddf64e7..9d04a788a0 100644 --- a/ext/native/util/text/utf8.h +++ b/ext/native/util/text/utf8.h @@ -16,7 +16,7 @@ #pragma once -#include "base/basictypes.h" +#include #include uint32_t u8_nextchar(const char *s, int *i); diff --git a/ext/snappy/snappy-stubs-public.h b/ext/snappy/snappy-stubs-public.h index 50d501324d..fddafbc8c7 100644 --- a/ext/snappy/snappy-stubs-public.h +++ b/ext/snappy/snappy-stubs-public.h @@ -35,7 +35,6 @@ #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_STUBS_PUBLIC_H_ -#include "base/basictypes.h" #include namespace snappy { From 40ec0d83585d6e233d10baaaaee0c98ffc98ca51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 12:53:18 +0200 Subject: [PATCH 796/848] Finish getting rid of basictypes.h --- CMakeLists.txt | 19 +++++++++++----- Common/ByteSwap.h | 29 +++++++++++++++++++++++++ Common/Common.vcxproj | 1 + Common/Common.vcxproj.filters | 1 + Common/FakeCPUDetect.cpp | 4 ++-- Core/MIPS/IR/IRPassSimplify.cpp | 2 +- Core/MIPS/MIPSAsm.cpp | 2 -- Core/MIPS/x86/CompALU.cpp | 4 ++-- UWP/CommonUWP/CommonUWP.vcxproj | 2 ++ UWP/CommonUWP/CommonUWP.vcxproj.filters | 2 ++ UWP/NativeUWP/NativeUWP.vcxproj | 1 - UWP/NativeUWP/NativeUWP.vcxproj.filters | 3 --- android/jni/app-android.cpp | 1 - ext/native/base/basictypes.h | 29 ------------------------- ext/native/native.vcxproj | 1 - ext/native/native.vcxproj.filters | 3 --- ext/native/util/hash/hash.h | 6 +---- ext/native/util/text/utf16.h | 3 ++- 18 files changed, 57 insertions(+), 56 deletions(-) create mode 100644 Common/ByteSwap.h delete mode 100644 ext/native/base/basictypes.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e61c638d9e..c19c0da939 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -427,8 +427,6 @@ add_library(Common STATIC ${CommonFake} ${CommonWindows} ${CommonVulkan} - Common/ColorConv.cpp - Common/ColorConv.h Common/Serialize/Serializer.cpp Common/Serialize/Serializer.h Common/Serialize/SerializeDeque.h @@ -436,14 +434,26 @@ add_library(Common STATIC Common/Serialize/SerializeList.h Common/Serialize/SerializeMap.h Common/Serialize/SerializeSet.h - Common/ConsoleListener.cpp - Common/ConsoleListener.h Common/Crypto/md5.cpp Common/Crypto/md5.h Common/Crypto/sha1.cpp Common/Crypto/sha1.h Common/Crypto/sha256.cpp Common/Crypto/sha256.h + Common/BitScan.h + Common/BitSet.h + Common/ByteSwap.h + Common/CodeBlock.h + Common/ColorConv.cpp + Common/ColorConv.h + Common/Common.h + Common/CommonFuncs.h + Common/CommonTypes.h + Common/ConsoleListener.cpp + Common/ConsoleListener.h + Common/DbgNew.h + Common/FakeEmitter.h + Common/FixedSizeQueue.h Common/ExceptionHandlerSetup.cpp Common/ExceptionHandlerSetup.h Common/FileUtil.cpp @@ -939,7 +949,6 @@ endif() add_library(native STATIC ${nativeExtra} - ext/native/base/basictypes.h ext/native/base/buffer.cpp ext/native/base/buffer.h ext/native/base/colorutil.cpp diff --git a/Common/ByteSwap.h b/Common/ByteSwap.h new file mode 100644 index 0000000000..21274cd7d1 --- /dev/null +++ b/Common/ByteSwap.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include // for byte swapping + +// Byteswapping +// Just in case this has been defined by platform +#undef swap16 +#undef swap32 +#undef swap64 + +#ifdef _WIN32 +inline uint16_t swap16(uint16_t _data) { return _byteswap_ushort(_data); } +inline uint32_t swap32(uint32_t _data) { return _byteswap_ulong(_data); } +inline uint64_t swap64(uint64_t _data) { return _byteswap_uint64(_data); } +#elif defined(__GNUC__) +inline uint16_t swap16(uint16_t _data) { return __builtin_bswap16(_data); } +inline uint32_t swap32(uint32_t _data) { return __builtin_bswap32(_data); } +inline uint64_t swap64(uint64_t _data) { return __builtin_bswap64(_data); } +#else +// Slow generic implementation. Hopefully this never hits +inline uint16_t swap16(uint16_t data) { return (data >> 8) | (data << 8); } +inline uint32_t swap32(uint32_t data) { return (swap16(data) << 16) | swap16(data >> 16); } +inline uint64_t swap64(uint64_t data) { return ((uint64_t)swap32(data) << 32) | swap32(data >> 32); } +#endif + +inline uint16_t swap16(const uint8_t* _pData) { return swap16(*(const uint16_t*)_pData); } +inline uint32_t swap32(const uint8_t* _pData) { return swap32(*(const uint32_t*)_pData); } +inline uint64_t swap64(const uint8_t* _pData) { return swap64(*(const uint64_t*)_pData); } diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 62f72077cd..ca391d93ad 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -354,6 +354,7 @@ + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 6cd39fb4f3..404207aacb 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -94,6 +94,7 @@ + diff --git a/Common/FakeCPUDetect.cpp b/Common/FakeCPUDetect.cpp index d314afe773..a75490160f 100644 --- a/Common/FakeCPUDetect.cpp +++ b/Common/FakeCPUDetect.cpp @@ -15,9 +15,9 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include +#include -#include -#include "base/basictypes.h" #include "Common.h" #include "CPUDetect.h" #include "StringUtils.h" diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index 13b74ab8bf..d6f96876d2 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -2,7 +2,7 @@ #include #include -#include "base/basictypes.h" +#include "Common/ByteSwap.h" #include "Common/Log.h" #include "Core/MIPS/IR/IRInterpreter.h" #include "Core/MIPS/IR/IRPassSimplify.h" diff --git a/Core/MIPS/MIPSAsm.cpp b/Core/MIPS/MIPSAsm.cpp index 08965b4fc2..37914016e6 100644 --- a/Core/MIPS/MIPSAsm.cpp +++ b/Core/MIPS/MIPSAsm.cpp @@ -7,8 +7,6 @@ #include #include "Common/CommonTypes.h" - -// This has to be before basictypes to avoid a define conflict. #include "ext/armips/Core/Assembler.h" #include "util/text/utf8.h" diff --git a/Core/MIPS/x86/CompALU.cpp b/Core/MIPS/x86/CompALU.cpp index e038bad6be..06ee0e9231 100644 --- a/Core/MIPS/x86/CompALU.cpp +++ b/Core/MIPS/x86/CompALU.cpp @@ -18,13 +18,13 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) -#include "base/basictypes.h" +#include +#include "Common/ByteSwap.h" #include "Common/Common.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/x86/Jit.h" #include "Core/MIPS/x86/RegCache.h" -#include using namespace MIPSAnalyst; diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index b6a8a7b933..1424c98b62 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -383,7 +383,9 @@ + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 50626b680e..62ed966957 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -56,6 +56,8 @@ + + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 51fc5b92b4..717123ab72 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -379,7 +379,6 @@ - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index add1237be7..0f9d862f10 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -463,9 +463,6 @@ - - base - base diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index bba710d3f0..7204b85aed 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -49,7 +49,6 @@ struct JNIEnv {}; #define JNI_VERSION_1_6 16 #endif -#include "base/basictypes.h" #include "base/display.h" #include "base/NativeApp.h" #include "thread/threadutil.h" diff --git a/ext/native/base/basictypes.h b/ext/native/base/basictypes.h deleted file mode 100644 index 8a52f1b6c7..0000000000 --- a/ext/native/base/basictypes.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include // for byte swapping - -// Byteswapping -// Just in case this has been defined by platform -#undef swap16 -#undef swap32 -#undef swap64 - -#ifdef _WIN32 -inline uint16_t swap16(uint16_t _data) {return _byteswap_ushort(_data);} -inline uint32_t swap32(uint32_t _data) {return _byteswap_ulong (_data);} -inline uint64_t swap64(uint64_t _data) {return _byteswap_uint64(_data);} -#elif defined(__GNUC__) -inline uint16_t swap16(uint16_t _data) {return __builtin_bswap16(_data);} -inline uint32_t swap32(uint32_t _data) {return __builtin_bswap32(_data);} -inline uint64_t swap64(uint64_t _data) {return __builtin_bswap64(_data);} -#else -// Slow generic implementation. Hopefully this never hits -inline uint16_t swap16(uint16_t data) {return (data >> 8) | (data << 8);} -inline uint32_t swap32(uint32_t data) {return (swap16(data) << 16) | swap16(data >> 16);} -inline uint64_t swap64(uint64_t data) {return ((uint64_t)swap32(data) << 32) | swap32(data >> 32);} -#endif - -inline uint16_t swap16(const uint8_t* _pData) {return swap16(*(const uint16_t*)_pData);} -inline uint32_t swap32(const uint8_t* _pData) {return swap32(*(const uint32_t*)_pData);} -inline uint64_t swap64(const uint8_t* _pData) {return swap64(*(const uint64_t*)_pData);} diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index caee297bd3..87ca54c357 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -382,7 +382,6 @@ - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 0c847988b1..272e10769e 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -68,9 +68,6 @@ file - - base - gfx diff --git a/ext/native/util/hash/hash.h b/ext/native/util/hash/hash.h index 2f7e4305b6..cd4a194a46 100644 --- a/ext/native/util/hash/hash.h +++ b/ext/native/util/hash/hash.h @@ -1,10 +1,7 @@ -#ifndef _UTIL_HASH_HASH_H -#define _UTIL_HASH_HASH_H +#pragma once #include -#include "base/basictypes.h" - namespace hash { // Fairly decent function for hashing strings. @@ -12,4 +9,3 @@ uint32_t Adler32(const uint8_t *data, size_t len); } // namespace hash -#endif diff --git a/ext/native/util/text/utf16.h b/ext/native/util/text/utf16.h index c23a554856..542b1e94a6 100644 --- a/ext/native/util/text/utf16.h +++ b/ext/native/util/text/utf16.h @@ -1,7 +1,8 @@ #pragma once #include -#include "base/basictypes.h" + +#include "Common/ByteSwap.h" // Should optimize out. #define UTF16_IS_LITTLE_ENDIAN (*(const uint16_t *)"\0\xff" >= 0x100) From 17a9767585db80916fe6b6bfeddbc4a63e83a136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 13:46:43 +0200 Subject: [PATCH 797/848] Buildfixes --- Common/TimeUtil.cpp | 1 + Core/MIPS/MIPSInt.cpp | 1 + ext/native/math/expression_parser.cpp | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Common/TimeUtil.cpp b/Common/TimeUtil.cpp index d0466353e8..106f761b74 100644 --- a/Common/TimeUtil.cpp +++ b/Common/TimeUtil.cpp @@ -1,4 +1,5 @@ #include +#include #include "Common/TimeUtil.h" diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index d43cd130d3..a48887f935 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -19,6 +19,7 @@ #include "math/math_util.h" +#include "Common/ByteSwap.h" #include "Common/Common.h" #include "Common/BitScan.h" #include "Core/Config.h" diff --git a/ext/native/math/expression_parser.cpp b/ext/native/math/expression_parser.cpp index f4aa82ff56..5d71182242 100644 --- a/ext/native/math/expression_parser.cpp +++ b/ext/native/math/expression_parser.cpp @@ -1,7 +1,8 @@ #include "expression_parser.h" #include -#include -#include +#include +#include +#include typedef enum { EXOP_BRACKETL, EXOP_BRACKETR, EXOP_MEML, EXOP_MEMR, EXOP_MEMSIZE, EXOP_SIGNPLUS, EXOP_SIGNMINUS, From 311fe431d0ac36f22bdc7d16ae4de190b9e6c91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 13:02:02 +0200 Subject: [PATCH 798/848] Move buffer.cpp/h from base to Common --- CMakeLists.txt | 4 ++-- ext/native/base/buffer.cpp => Common/Buffer.cpp | 4 ++-- ext/native/base/buffer.h => Common/Buffer.h | 0 Common/Common.vcxproj | 2 ++ Common/Common.vcxproj.filters | 2 ++ Common/StringUtils.cpp | 7 +++---- Core/Reporting.cpp | 1 - android/jni/Android.mk | 1 + ext/native/Android.mk | 1 - ext/native/native.vcxproj | 2 -- ext/native/native.vcxproj.filters | 6 ------ ext/native/net/http_client.cpp | 6 +++--- ext/native/net/http_client.h | 3 ++- ext/native/net/http_headers.h | 8 +++----- ext/native/net/http_server.cpp | 2 +- ext/native/net/http_server.h | 6 +----- libretro/Makefile.common | 2 +- 17 files changed, 23 insertions(+), 34 deletions(-) rename ext/native/base/buffer.cpp => Common/Buffer.cpp (99%) rename ext/native/base/buffer.h => Common/Buffer.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c19c0da939..960d4b3a2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -442,6 +442,8 @@ add_library(Common STATIC Common/Crypto/sha256.h Common/BitScan.h Common/BitSet.h + Common/Buffer.h + Common/Buffer.cpp Common/ByteSwap.h Common/CodeBlock.h Common/ColorConv.cpp @@ -949,8 +951,6 @@ endif() add_library(native STATIC ${nativeExtra} - ext/native/base/buffer.cpp - ext/native/base/buffer.h ext/native/base/colorutil.cpp ext/native/base/colorutil.h ext/native/base/display.cpp diff --git a/ext/native/base/buffer.cpp b/Common/Buffer.cpp similarity index 99% rename from ext/native/base/buffer.cpp rename to Common/Buffer.cpp index 9598dcbe00..78302f60fe 100644 --- a/ext/native/base/buffer.cpp +++ b/Common/Buffer.cpp @@ -1,4 +1,3 @@ -#include "base/buffer.h" #include #include @@ -18,9 +17,10 @@ #define MSG_NOSIGNAL 0x00 #endif -#include "Common/TimeUtil.h" #include "file/fd_util.h" +#include "Common/TimeUtil.h" +#include "Common/Buffer.h" #include "Common/Log.h" Buffer::Buffer() { } diff --git a/ext/native/base/buffer.h b/Common/Buffer.h similarity index 100% rename from ext/native/base/buffer.h rename to Common/Buffer.h diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index ca391d93ad..7be07259f0 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -354,6 +354,7 @@ + @@ -441,6 +442,7 @@ false + true true diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 404207aacb..2e61356786 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -95,6 +95,7 @@ + @@ -162,6 +163,7 @@ + diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index b5a2d3b987..e812bad1b6 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -41,10 +41,9 @@ #include #include -#include "base/buffer.h" - -#include "Common.h" -#include "StringUtils.h" +#include "Common/Common.h" +#include "Common/Buffer.h" +#include "Common/StringUtils.h" void truncate_cpy(char *dest, size_t destSize, const char *src) { size_t len = strlen(src); diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 36bac97703..6d6e364834 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -48,7 +48,6 @@ #include "net/resolve.h" #include "net/url.h" -#include "base/buffer.h" #include "thread/threadutil.h" #include "file/zip_read.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index a87e755684..3060d22e87 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -204,6 +204,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/ext/udis86/udis86.c \ $(SRC)/ext/xbrz/xbrz.cpp \ $(SRC)/ext/xxhash.c \ + $(SRC)/Common/Buffer.cpp \ $(SRC)/Common/Crypto/md5.cpp \ $(SRC)/Common/Crypto/sha1.cpp \ $(SRC)/Common/Crypto/sha256.cpp \ diff --git a/ext/native/Android.mk b/ext/native/Android.mk index fc41991fd9..754edf4b69 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -7,7 +7,6 @@ include $(CLEAR_VARS) LOCAL_MODULE := libnative LOCAL_ARM_MODE := arm LOCAL_SRC_FILES :=\ - base/buffer.cpp \ base/display.cpp \ base/colorutil.cpp \ data/base64.cpp \ diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 87ca54c357..275ac87058 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -382,7 +382,6 @@ - @@ -484,7 +483,6 @@ - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 272e10769e..1542972251 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -104,9 +104,6 @@ net - - base - file @@ -400,9 +397,6 @@ net - - base - file diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index 4169c97123..24d93ed0c3 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -17,16 +17,16 @@ #endif #include -#include -#include +#include +#include -#include "base/buffer.h" #include "data/compression.h" #include "file/fd_util.h" #include "net/resolve.h" #include "net/url.h" #include "thread/threadutil.h" +#include "Common/Buffer.h" #include "Common/Log.h" namespace net { diff --git a/ext/native/net/http_client.h b/ext/native/net/http_client.h index be71cedcff..32490dc40b 100644 --- a/ext/native/net/http_client.h +++ b/ext/native/net/http_client.h @@ -5,7 +5,6 @@ #include #include -#include "base/buffer.h" #include "net/resolve.h" #ifdef _WIN32 @@ -21,6 +20,8 @@ #include #endif +#include "Common/Buffer.h" + namespace net { class Connection { diff --git a/ext/native/net/http_headers.h b/ext/native/net/http_headers.h index 470f589972..0ee0b1b751 100644 --- a/ext/native/net/http_headers.h +++ b/ext/native/net/http_headers.h @@ -1,9 +1,9 @@ -#ifndef _NET_HTTP_HTTP_HEADERS -#define _NET_HTTP_HTTP_HEADERS +#pragma once #include #include -#include "base/buffer.h" + +#include "Common/Buffer.h" namespace net { class InputSink; @@ -48,5 +48,3 @@ class RequestHeader { }; } // namespace http - -#endif diff --git a/ext/native/net/http_server.cpp b/ext/native/net/http_server.cpp index e509ee7c0b..738b536f87 100644 --- a/ext/native/net/http_server.cpp +++ b/ext/native/net/http_server.cpp @@ -34,12 +34,12 @@ #include #include -#include "base/buffer.h" #include "file/fd_util.h" #include "net/http_server.h" #include "net/sinks.h" #include "thread/executor.h" +#include "Common/Buffer.h" #include "Common/Log.h" namespace http { diff --git a/ext/native/net/http_server.h b/ext/native/net/http_server.h index 0b5dfbe668..5a8151b77d 100644 --- a/ext/native/net/http_server.h +++ b/ext/native/net/http_server.h @@ -1,10 +1,8 @@ -#ifndef _HTTP_SERVER_H -#define _HTTP_SERVER_H +#pragma once #include #include -#include "base/buffer.h" #include "net/http_headers.h" #include "net/resolve.h" #include "thread/executor.h" @@ -114,5 +112,3 @@ private: }; } // namespace http - -#endif // _HTTP_SERVER_H diff --git a/libretro/Makefile.common b/libretro/Makefile.common index eb0472bcbb..1d61dd6fcd 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -144,6 +144,7 @@ SOURCES_CXX += \ SOURCES_CXX += \ $(COMMONDIR)/Serialize/Serializer.cpp \ + $(COMMONDIR)/Common/Buffer.cpp \ $(COMMONDIR)/ConsoleListener.cpp \ $(COMMONDIR)/ExceptionHandlerSetup.cpp \ $(COMMONDIR)/FileUtil.cpp \ @@ -214,7 +215,6 @@ SOURCES_CXX += \ $(GPUDIR)/GLES/ShaderManagerGLES.cpp \ $(GPUDIR)/GLES/StateMappingGLES.cpp \ $(GPUDIR)/GLES/StencilBufferGLES.cpp \ - $(EXTDIR)/native/base/buffer.cpp \ $(EXTDIR)/native/base/colorutil.cpp \ $(EXTDIR)/native/base/display.cpp \ $(EXTDIR)/native/data/compression.cpp \ From 835b819faaeefc590ce7972e100359a37f110877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 13:06:26 +0200 Subject: [PATCH 799/848] Remove some color util functions --- ext/native/base/colorutil.cpp | 51 +---------------------------------- ext/native/base/colorutil.h | 8 ------ 2 files changed, 1 insertion(+), 58 deletions(-) diff --git a/ext/native/base/colorutil.cpp b/ext/native/base/colorutil.cpp index bdb4bdbcb1..6074dd9be0 100644 --- a/ext/native/base/colorutil.cpp +++ b/ext/native/base/colorutil.cpp @@ -46,7 +46,7 @@ uint32_t colorBlend(uint32_t rgb1, uint32_t rgb2, float alpha) { uint32_t alphaMul(uint32_t color, float alphaMul) { uint32_t rgb = color & 0xFFFFFF; int32_t alpha = color >> 24; - alpha *= alphaMul; + alpha = (int32_t)(alpha * alphaMul); if (alpha < 0) alpha = 0; if (alpha > 255) alpha = 255; return (alpha << 24) | (rgb & 0xFFFFFF); @@ -63,52 +63,3 @@ uint32_t rgba(float r, float g, float b, float alpha) { uint32_t rgba_clamp(float r, float g, float b, float a) { return rgba(clamp(r, 0.0f, 1.0f), clamp(g, 0.0f, 1.0f), clamp(b, 0.0f, 1.0f), clamp(a, 0.0f, 1.0f)); } - -/* hsv2rgb.c -* Convert Hue Saturation Value to Red Green Blue -* -* P.J. 08-Aug-98 -* -* Reference: -* D. F. Rogers -* Procedural Elements for Computer Graphics -* McGraw Hill 1985 -*/ -uint32_t hsva(float H, float S, float V, float alpha) { - /* - * Purpose: - * Convert HSV values to RGB values - * All values are in the range [0.0 .. 1.0] - */ - float F, M, N, K; - int I; - if ( S == 0.0 ) { - // Achromatic case, set level of grey - return rgba(V, V, V, alpha); - } else { - /* - * Determine levels of primary colours. - */ - if (H >= 1.0) { - H = 0.0; - } else { - H = H * 6; - } - I = (int) H; /* should be in the range 0..5 */ - F = H - I; /* fractional part */ - - M = V * (1 - S); - N = V * (1 - S * F); - K = V * (1 - S * (1 - F)); - - float r, g, b; - if (I == 0) { r = V; g = K; b = M; } - else if (I == 1) { r = N; g = V; b = M; } - else if (I == 2) { r = M; g = V; b = K; } - else if (I == 3) { r = M; g = N; b = V; } - else if (I == 4) { r = K; g = M; b = V; } - else if (I == 5) { r = V; g = M; b = N; } - else return 0; - return rgba(r, g, b, alpha); - } -} diff --git a/ext/native/base/colorutil.h b/ext/native/base/colorutil.h index 0f9fa33b7a..9e8128bae1 100644 --- a/ext/native/base/colorutil.h +++ b/ext/native/base/colorutil.h @@ -9,7 +9,6 @@ uint32_t colorBlend(uint32_t color, uint32_t color2, float alpha); uint32_t alphaMul(uint32_t color, float alphaMul); uint32_t rgba(float r, float g, float b, float alpha); uint32_t rgba_clamp(float r, float g, float b, float alpha); -uint32_t hsva(float h, float s, float v, float alpha); typedef unsigned int Color; @@ -17,10 +16,3 @@ typedef unsigned int Color; inline Color darkenColor(Color color) { return (color & 0xFF000000) | ((color >> 1) & 0x7F7F7F); } -inline Color whitenColor(Color color) { - return ((color & 0xFF000000) | ((color >> 1) & 0x7F7F7F)) + 0x7F7F7F; -} -inline Color colorInterpol(Color x, Color y, int n) { - // TODO - return x; -} From d9edc6896615c5ab9908be56865e526407a80902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 15:45:51 +0200 Subject: [PATCH 800/848] Remove unnecessary use of thread local storage --- CMakeLists.txt | 3 ++- Common/Common.vcxproj | 3 ++- Common/Common.vcxproj.filters | 3 ++- Common/CommonFuncs.h | 8 -------- Common/{Misc.cpp => SysError.cpp} | 27 +++++++++++-------------- Common/SysError.h | 10 +++++++++ Core/MIPS/ARM64/Arm64CompALU.cpp | 3 ++- UWP/CommonUWP/CommonUWP.vcxproj | 3 ++- UWP/CommonUWP/CommonUWP.vcxproj.filters | 3 ++- android/jni/Android.mk | 2 +- libretro/Makefile.common | 2 +- 11 files changed, 36 insertions(+), 31 deletions(-) rename Common/{Misc.cpp => SysError.cpp} (82%) create mode 100644 Common/SysError.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 960d4b3a2d..01467f9b11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -475,11 +475,12 @@ add_library(Common STATIC Common/MemArena.h Common/MemoryUtil.cpp Common/MemoryUtil.h - Common/Misc.cpp Common/OSVersion.cpp Common/OSVersion.h Common/StringUtils.cpp Common/StringUtils.h + Common/SysError.h + Common/SysError.cpp Common/ThreadPools.cpp Common/ThreadPools.h Common/ThreadSafeList.h diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 7be07259f0..7d48de5757 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -415,6 +415,7 @@ + @@ -501,7 +502,7 @@ - + Create diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 2e61356786..981ac5d5a3 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -96,6 +96,7 @@ + @@ -105,7 +106,6 @@ - @@ -164,6 +164,7 @@ + diff --git a/Common/CommonFuncs.h b/Common/CommonFuncs.h index 4e5adc8beb..72cf14356f 100644 --- a/Common/CommonFuncs.h +++ b/Common/CommonFuncs.h @@ -78,11 +78,3 @@ inline u64 __rotr64(u64 x, unsigned int shift){ #endif #define Crash() {__debugbreak();} #endif // WIN32 ndef - -// Generic function to get last error message. -// Call directly after the command or use the error num. -// This function might change the error code. -// Defined in Misc.cpp. -const char *GetLastErrorMsg(); -const char *GetStringErrorMsg(int errCode); - diff --git a/Common/Misc.cpp b/Common/SysError.cpp similarity index 82% rename from Common/Misc.cpp rename to Common/SysError.cpp index a13924b1bf..c3f900ed67 100644 --- a/Common/Misc.cpp +++ b/Common/SysError.cpp @@ -15,14 +15,11 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include +#include + #include "util/text/utf8.h" -#include "Common.h" - -#include - -#if defined(__APPLE__) -#define __thread -#endif +#include "SysError.h" #ifdef _WIN32 #include "CommonWindows.h" @@ -31,8 +28,7 @@ // Generic function to get last error message. // Call directly after the command or use the error num. // This function might change the error code. -const char *GetLastErrorMsg() -{ +std::string GetLastErrorMsg() { #ifdef _WIN32 return GetStringErrorMsg(GetLastError()); #else @@ -40,25 +36,26 @@ const char *GetLastErrorMsg() #endif } -const char *GetStringErrorMsg(int errCode) { +std::string GetStringErrorMsg(int errCode) { static const size_t buff_size = 1023; + #ifdef _WIN32 - static thread_local wchar_t err_strw[buff_size] = {}; + wchar_t err_strw[buff_size] = {}; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_strw, buff_size, NULL); - static thread_local char err_str[buff_size] = {}; + char err_str[buff_size] = {}; snprintf(err_str, buff_size, "%s", ConvertWStringToUTF8(err_strw).c_str()); + return std::string(err_str); #else - static thread_local char err_str[buff_size] = {}; + char err_str[buff_size] = {}; // Thread safe (XSI-compliant) if (strerror_r(errCode, err_str, buff_size) == 0) { return "Unknown error"; } -#endif - return err_str; +#endif } diff --git a/Common/SysError.h b/Common/SysError.h new file mode 100644 index 0000000000..b425b34fdc --- /dev/null +++ b/Common/SysError.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +// Generic function to get last error message. +// Call directly after the command or use the error num. +// This function might change the error code. +// Defined in Misc.cpp. +std::string GetLastErrorMsg(); +std::string GetStringErrorMsg(int errCode); diff --git a/Core/MIPS/ARM64/Arm64CompALU.cpp b/Core/MIPS/ARM64/Arm64CompALU.cpp index f97ba0dee7..df195209f6 100644 --- a/Core/MIPS/ARM64/Arm64CompALU.cpp +++ b/Core/MIPS/ARM64/Arm64CompALU.cpp @@ -20,11 +20,12 @@ #include +#include "Common/ByteSwap.h" +#include "Common/CPUDetect.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/ARM64/Arm64Jit.h" #include "Core/MIPS/ARM64/Arm64RegCache.h" -#include "Common/CPUDetect.h" using namespace MIPSAnalyst; diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 1424c98b62..7cc5e4fe86 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -420,6 +420,7 @@ + @@ -455,7 +456,7 @@ - + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 62ed966957..ece02a7b10 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -28,7 +28,7 @@ - + @@ -89,6 +89,7 @@ + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 3060d22e87..71b73e9c60 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -221,10 +221,10 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/MemoryUtil.cpp \ $(SRC)/Common/FileUtil.cpp \ $(SRC)/Common/StringUtils.cpp \ + $(SRC)/Common/SysError.cpp \ $(SRC)/Common/ThreadPools.cpp \ $(SRC)/Common/Timer.cpp \ $(SRC)/Common/TimeUtil.cpp \ - $(SRC)/Common/Misc.cpp \ $(SRC)/GPU/Math3D.cpp \ $(SRC)/GPU/GPU.cpp \ $(SRC)/GPU/GPUCommon.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 1d61dd6fcd..ef385e1e5a 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -153,7 +153,7 @@ SOURCES_CXX += \ $(COMMONDIR)/LogManager.cpp \ $(COMMONDIR)/OSVersion.cpp \ $(COMMONDIR)/MemoryUtil.cpp \ - $(COMMONDIR)/Misc.cpp \ + $(COMMONDIR)/SysError.cpp \ $(COMMONDIR)/StringUtils.cpp \ $(COMMONDIR)/Timer.cpp \ $(COMMONDIR)/TimeUtil.cpp \ From 11ab77b995a5403531b2d5c7834799d4a89a3542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 15:50:16 +0200 Subject: [PATCH 801/848] Remove some TLS. --- Common/FileUtil.cpp | 37 ++++++++++++++++------------------ Common/MemoryUtil.cpp | 7 ++++--- Windows/RawInput.cpp | 5 +++-- Windows/TouchInputHandler.cpp | 5 +++-- Windows/W32Util/Misc.cpp | 2 +- ext/native/gfx/d3d9_shader.cpp | 1 + 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index d18ccecad4..185e970d93 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -26,8 +26,10 @@ #include #include -#include "FileUtil.h" -#include "StringUtils.h" + +#include "Common/FileUtil.h" +#include "Common/StringUtils.h" +#include "Common/SysError.h" #ifdef _WIN32 #include "CommonWindows.h" @@ -245,8 +247,7 @@ bool IsDirectory(const std::string &filename) struct stat file_info; int result = stat(copy.c_str(), &file_info); if (result < 0) { - WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", - fn.c_str(), GetLastErrorMsg()); + WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", fn.c_str(), GetLastErrorMsg().c_str()); return false; } return S_ISDIR(file_info.st_mode); @@ -273,14 +274,13 @@ bool Delete(const std::string &filename) { #ifdef _WIN32 if (!DeleteFile(ConvertUTF8ToWString(filename).c_str())) { - WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", - filename.c_str(), GetLastErrorMsg()); + WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", filename.c_str(), GetLastErrorMsg().c_str()); return false; } #else if (unlink(filename.c_str()) == -1) { WARN_LOG(COMMON, "Delete: unlink failed on %s: %s", - filename.c_str(), GetLastErrorMsg()); + filename.c_str(), GetLastErrorMsg().c_str()); return false; } #endif @@ -389,7 +389,7 @@ bool DeleteDir(const std::string &filename) if (rmdir(filename.c_str()) == 0) return true; #endif - ERROR_LOG(COMMON, "DeleteDir: %s: %s", filename.c_str(), GetLastErrorMsg()); + ERROR_LOG(COMMON, "DeleteDir: %s: %s", filename.c_str(), GetLastErrorMsg().c_str()); return false; } @@ -409,7 +409,7 @@ bool Rename(const std::string &srcFilename, const std::string &destFilename) return true; #endif ERROR_LOG(COMMON, "Rename: failed %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg().c_str()); return false; } @@ -428,7 +428,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) return true; #endif ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg().c_str()); return false; #else @@ -442,7 +442,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) if (!input) { ERROR_LOG(COMMON, "Copy: input failed %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg().c_str()); return false; } @@ -452,7 +452,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) { fclose(input); ERROR_LOG(COMMON, "Copy: output failed %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg().c_str()); return false; } @@ -467,7 +467,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) { ERROR_LOG(COMMON, "Copy: failed reading from source, %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg().c_str()); fclose(input); fclose(output); return false; @@ -480,7 +480,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) { ERROR_LOG(COMMON, "Copy: failed writing to output, %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg().c_str()); fclose(input); fclose(output); return false; @@ -622,14 +622,12 @@ u64 GetFileSize(FILE *f) { // can't use off_t here because it can be 32-bit u64 pos = ftello(f); if (fseeko(f, 0, SEEK_END) != 0) { - ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", - f, GetLastErrorMsg()); + ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", f, GetLastErrorMsg().c_str()); return 0; } u64 size = ftello(f); if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { - ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", - f, GetLastErrorMsg()); + ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", f, GetLastErrorMsg().c_str()); return 0; } return size; @@ -642,8 +640,7 @@ bool CreateEmptyFile(const std::string &filename) FILE *pFile = OpenCFile(filename, "wb"); if (!pFile) { - ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s", - filename.c_str(), GetLastErrorMsg()); + ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s", filename.c_str(), GetLastErrorMsg().c_str()); return false; } fclose(pFile); diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index c834444563..a6f5d5e919 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -23,6 +23,7 @@ #include "Common/Log.h" #include "Common/MemoryUtil.h" #include "Common/StringUtils.h" +#include "Common/SysError.h" #ifdef _WIN32 #include "Common/CommonWindows.h" @@ -257,7 +258,7 @@ void FreeMemoryPages(void *ptr, size_t size) { size = (size + page_size - 1) & (~(page_size - 1)); #ifdef _WIN32 if (!VirtualFree(ptr, 0, MEM_RELEASE)) { - ERROR_LOG(MEMMAP, "FreeMemoryPages failed!\n%s", GetLastErrorMsg()); + ERROR_LOG(MEMMAP, "FreeMemoryPages failed!\n%s", GetLastErrorMsg().c_str()); } #else munmap(ptr, size); @@ -302,13 +303,13 @@ bool ProtectMemoryPages(const void* ptr, size_t size, uint32_t memProtFlags) { #if PPSSPP_PLATFORM(UWP) DWORD oldValue; if (!VirtualProtectFromApp((void *)ptr, size, protect, &oldValue)) { - ERROR_LOG(MEMMAP, "WriteProtectMemory failed!\n%s", GetLastErrorMsg()); + ERROR_LOG(MEMMAP, "WriteProtectMemory failed!\n%s", GetLastErrorMsg().c_str()); return false; } #else DWORD oldValue; if (!VirtualProtect((void *)ptr, size, protect, &oldValue)) { - ERROR_LOG(MEMMAP, "WriteProtectMemory failed!\n%s", GetLastErrorMsg()); + ERROR_LOG(MEMMAP, "WriteProtectMemory failed!\n%s", GetLastErrorMsg().c_str()); return false; } #endif diff --git a/Windows/RawInput.cpp b/Windows/RawInput.cpp index 36d639a4ba..861fa393cd 100644 --- a/Windows/RawInput.cpp +++ b/Windows/RawInput.cpp @@ -27,6 +27,7 @@ #include "Windows/MainWindow.h" #include "Windows/WindowsHost.h" #include "Common/CommonFuncs.h" +#include "Common/SysError.h" #include "Core/Config.h" #ifndef HID_USAGE_PAGE_GENERIC @@ -194,7 +195,7 @@ namespace WindowsRawInput { dev[2].dwFlags = 0; if (!RegisterRawInputDevices(dev, 3, sizeof(RAWINPUTDEVICE))) { - WARN_LOG(SYSTEM, "Unable to register raw input devices: %s", GetLastErrorMsg()); + WARN_LOG(SYSTEM, "Unable to register raw input devices: %s", GetLastErrorMsg().c_str()); } } @@ -283,7 +284,7 @@ namespace WindowsRawInput { LRESULT ProcessChar(HWND hWnd, WPARAM wParam, LPARAM lParam) { KeyInput key; - key.keyCode = wParam; // Note that this is NOT a NKCODE but a Unicode character! + key.keyCode = (int)wParam; // Note that this is NOT a NKCODE but a Unicode character! key.flags = KEY_CHAR; key.deviceId = DEVICE_ID_KEYBOARD; NativeKey(key); diff --git a/Windows/TouchInputHandler.cpp b/Windows/TouchInputHandler.cpp index b4f4bd38c7..3622dac160 100644 --- a/Windows/TouchInputHandler.cpp +++ b/Windows/TouchInputHandler.cpp @@ -5,10 +5,11 @@ #include #include "base/display.h" +#include "base/NativeApp.h" #include "Common/CommonWindows.h" #include "Common/CommonFuncs.h" #include "Common/Log.h" -#include "base/NativeApp.h" +#include "Common/SysError.h" #include "Windows/MainWindow.h" TouchInputHandler::TouchInputHandler() { @@ -95,7 +96,7 @@ void TouchInputHandler::handleTouchEvent(HWND hWnd, UINT message, WPARAM wParam, } closeTouch(touchInputData); } else { - WARN_LOG(SYSTEM, "Failed to read input data: %s", GetLastErrorMsg()); + WARN_LOG(SYSTEM, "Failed to read input data: %s", GetLastErrorMsg().c_str()); } delete [] inputs; } diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index c4f9ec1310..aa3e9e432b 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -201,7 +201,7 @@ GenericListControl::GenericListControl(HWND hwnd, const GenericListViewDef& def) int totalListSize = rect.right-rect.left; for (int i = 0; i < columnCount; i++) { - lvc.cx = columns[i].size * totalListSize; + lvc.cx = (int)(columns[i].size * totalListSize); lvc.pszText = (LPTSTR)columns[i].name; if (columns[i].flags & GLVC_CENTERED) diff --git a/ext/native/gfx/d3d9_shader.cpp b/ext/native/gfx/d3d9_shader.cpp index 2fdec6c41f..bdc0b252e7 100644 --- a/ext/native/gfx/d3d9_shader.cpp +++ b/ext/native/gfx/d3d9_shader.cpp @@ -3,6 +3,7 @@ #include "ppsspp_config.h" #include "d3d9_shader.h" #include "Common/CommonFuncs.h" +#include "Common/SysError.h" #if PPSSPP_API(D3DX9) #include "thin3d/d3dx9_loader.h" From 5e976ff842db210826e27af8fd21eb230d0b773e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 18:36:59 +0200 Subject: [PATCH 802/848] Buildfixes --- Common/FileUtil.cpp | 2 +- Common/SysError.cpp | 2 ++ Core/MIPS/ARM/ArmCompALU.cpp | 2 ++ ext/native/file/file_util.cpp | 2 +- ext/native/gfx_es2/draw_buffer.h | 6 ------ ext/native/gfx_es2/draw_text_android.cpp | 1 + ext/native/gfx_es2/draw_text_uwp.cpp | 1 + ext/native/math/expression_parser.cpp | 4 ++-- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index 185e970d93..d99be4d46a 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -802,7 +802,7 @@ const std::string &GetExeDirectory() sz = GetModuleFileName(nullptr, &program_path[0], (DWORD)program_path.size()); } while (sz >= program_path.size()); - TCHAR *last_slash = _tcsrchr(&program_path[0], '\\'); + const wchar_t *last_slash = wcsrchr(&program_path[0], '\\'); if (last_slash != nullptr) program_path.resize(last_slash - &program_path[0] + 1); else diff --git a/Common/SysError.cpp b/Common/SysError.cpp index c3f900ed67..841655bfbe 100644 --- a/Common/SysError.cpp +++ b/Common/SysError.cpp @@ -23,6 +23,8 @@ #ifdef _WIN32 #include "CommonWindows.h" +#else +#include #endif // Generic function to get last error message. diff --git a/Core/MIPS/ARM/ArmCompALU.cpp b/Core/MIPS/ARM/ArmCompALU.cpp index 66d12ed8a9..67e5a70600 100644 --- a/Core/MIPS/ARM/ArmCompALU.cpp +++ b/Core/MIPS/ARM/ArmCompALU.cpp @@ -19,11 +19,13 @@ #if PPSSPP_ARCH(ARM) #include + #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/ARM/ArmJit.h" #include "Core/MIPS/ARM/ArmRegCache.h" #include "Common/CPUDetect.h" +#include "Common/ByteSwap.h" using namespace MIPSAnalyst; diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index bc677e65c0..56f211bd57 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -318,7 +318,7 @@ std::vector getWindowsDrives() std::vector drives; const DWORD buffsize = GetLogicalDriveStrings(0, NULL); - std::vector buff(buffsize); + std::vector buff(buffsize); if (GetLogicalDriveStrings(buffsize, buff.data()) == buffsize - 1) { auto drive = buff.data(); diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h index 9b1e5d7e8d..001a91cd57 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/ext/native/gfx_es2/draw_buffer.h @@ -46,11 +46,6 @@ namespace Draw { class Pipeline; } -enum DrawBufferPrimitiveMode { - DBMODE_NORMAL = 0, - DBMODE_LINES = 1 -}; - struct GradientStop { float t; uint32_t color; @@ -190,7 +185,6 @@ private: Vertex *verts_; int count_; - DrawBufferPrimitiveMode mode_; const Atlas *atlas; bool inited_; diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index dc1ec66f8a..8a61ce8cb2 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -9,6 +9,7 @@ #include "android/jni/app-android.h" #include "Common/Log.h" +#include "Common/StringUtils.h" #if PPSSPP_PLATFORM(ANDROID) && !defined(__LIBRETRO__) diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index b58af57ae2..3968767ee3 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -7,6 +7,7 @@ #include "gfx_es2/draw_text_uwp.h" #include "Common/Log.h" +#include "Common/StringUtils.h" #if PPSSPP_PLATFORM(UWP) diff --git a/ext/native/math/expression_parser.cpp b/ext/native/math/expression_parser.cpp index 5d71182242..2c277c000a 100644 --- a/ext/native/math/expression_parser.cpp +++ b/ext/native/math/expression_parser.cpp @@ -458,11 +458,11 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, valueStack.push_back(val); } break; - case EXOP_SIGNPLUS: // keine aktion nötig + case EXOP_SIGNPLUS: // keine aktion nötig break; case EXOP_SIGNMINUS: // -0 if (useFloat) - valueStack.push_back(0.0-fArg[0]); + valueStack.push_back(0.0 - fArg[0]); else valueStack.push_back(0-arg[0]); break; From e8ff54645792b41986763ab652c61af21cb5163f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 20:42:08 +0200 Subject: [PATCH 803/848] retro buildfix --- Common/FakeCPUDetect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/FakeCPUDetect.cpp b/Common/FakeCPUDetect.cpp index a75490160f..d6244a9ee5 100644 --- a/Common/FakeCPUDetect.cpp +++ b/Common/FakeCPUDetect.cpp @@ -15,7 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include +#include #include #include "Common.h" From 800be8ad6d3877953a07efa469a4507129b97f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 20:44:59 +0200 Subject: [PATCH 804/848] UWP buildfix --- UWP/CommonUWP/CommonUWP.vcxproj | 2 ++ UWP/NativeUWP/NativeUWP.vcxproj | 5 ----- UWP/NativeUWP/NativeUWP.vcxproj.filters | 12 ------------ 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 7cc5e4fe86..21f6880a58 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -385,6 +385,7 @@ + @@ -436,6 +437,7 @@ + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 717123ab72..ae64fb1ea7 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -379,13 +379,9 @@ - - - - @@ -467,7 +463,6 @@ - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 0f9d862f10..e9dfd60c68 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -64,9 +64,6 @@ - - base - base @@ -463,21 +460,12 @@ - - base - base base - - base - - - base - base From 63c8b0ffd57d27f76df3f5cd3de2fb924a1da99b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 21:58:58 +0200 Subject: [PATCH 805/848] Additional UWP buildfix --- UWP/PPSSPP_UWPMain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 14b4cf2169..4915c4ffa3 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -21,6 +21,7 @@ #include "Common/Log.h" #include "Common/LogManager.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Core/System.h" #include "Core/Loaders.h" From 4d3ec20082a78fd6da3834846053c9592017e6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 30 Sep 2020 00:06:51 +0200 Subject: [PATCH 806/848] ByteSwap.h results in a file name collision on some systems with byteswap.h. Fix this by merging it into BitSet.h. --- CMakeLists.txt | 1 - Common/BitSet.h | 27 +++++++++++++++++++++++ Common/ByteSwap.h | 29 ------------------------- Common/Common.vcxproj | 3 +-- Common/Common.vcxproj.filters | 3 +-- Core/MIPS/ARM/ArmCompALU.cpp | 2 +- Core/MIPS/ARM64/Arm64CompALU.cpp | 2 +- Core/MIPS/IR/IRPassSimplify.cpp | 2 +- Core/MIPS/MIPSInt.cpp | 4 ++-- Core/MIPS/x86/CompALU.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 1 - UWP/CommonUWP/CommonUWP.vcxproj.filters | 1 - ext/native/util/text/utf16.h | 2 +- 13 files changed, 36 insertions(+), 43 deletions(-) delete mode 100644 Common/ByteSwap.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 01467f9b11..12f85e629d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -444,7 +444,6 @@ add_library(Common STATIC Common/BitSet.h Common/Buffer.h Common/Buffer.cpp - Common/ByteSwap.h Common/CodeBlock.h Common/ColorConv.cpp Common/ColorConv.h diff --git a/Common/BitSet.h b/Common/BitSet.h index 2fbc80011b..caf7951509 100644 --- a/Common/BitSet.h +++ b/Common/BitSet.h @@ -2,6 +2,8 @@ #pragma once +#include +#include // for byte swapping #include #include "CommonTypes.h" @@ -39,3 +41,28 @@ inline int CountSetBits(u64 val) { return __builtin_popcountll(val); } inline int LeastSignificantSetBit(u32 val) { return __builtin_ctz(val); } inline int LeastSignificantSetBit(u64 val) { return __builtin_ctzll(val); } #endif + +// Byteswapping +// Just in case this has been defined by platform +#undef swap16 +#undef swap32 +#undef swap64 + +#ifdef _WIN32 +inline uint16_t swap16(uint16_t _data) { return _byteswap_ushort(_data); } +inline uint32_t swap32(uint32_t _data) { return _byteswap_ulong(_data); } +inline uint64_t swap64(uint64_t _data) { return _byteswap_uint64(_data); } +#elif defined(__GNUC__) +inline uint16_t swap16(uint16_t _data) { return __builtin_bswap16(_data); } +inline uint32_t swap32(uint32_t _data) { return __builtin_bswap32(_data); } +inline uint64_t swap64(uint64_t _data) { return __builtin_bswap64(_data); } +#else +// Slow generic implementation. Hopefully this never hits +inline uint16_t swap16(uint16_t data) { return (data >> 8) | (data << 8); } +inline uint32_t swap32(uint32_t data) { return (swap16(data) << 16) | swap16(data >> 16); } +inline uint64_t swap64(uint64_t data) { return ((uint64_t)swap32(data) << 32) | swap32(data >> 32); } +#endif + +inline uint16_t swap16(const uint8_t* _pData) { return swap16(*(const uint16_t*)_pData); } +inline uint32_t swap32(const uint8_t* _pData) { return swap32(*(const uint32_t*)_pData); } +inline uint64_t swap64(const uint8_t* _pData) { return swap64(*(const uint64_t*)_pData); } diff --git a/Common/ByteSwap.h b/Common/ByteSwap.h deleted file mode 100644 index 21274cd7d1..0000000000 --- a/Common/ByteSwap.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include // for byte swapping - -// Byteswapping -// Just in case this has been defined by platform -#undef swap16 -#undef swap32 -#undef swap64 - -#ifdef _WIN32 -inline uint16_t swap16(uint16_t _data) { return _byteswap_ushort(_data); } -inline uint32_t swap32(uint32_t _data) { return _byteswap_ulong(_data); } -inline uint64_t swap64(uint64_t _data) { return _byteswap_uint64(_data); } -#elif defined(__GNUC__) -inline uint16_t swap16(uint16_t _data) { return __builtin_bswap16(_data); } -inline uint32_t swap32(uint32_t _data) { return __builtin_bswap32(_data); } -inline uint64_t swap64(uint64_t _data) { return __builtin_bswap64(_data); } -#else -// Slow generic implementation. Hopefully this never hits -inline uint16_t swap16(uint16_t data) { return (data >> 8) | (data << 8); } -inline uint32_t swap32(uint32_t data) { return (swap16(data) << 16) | swap16(data >> 16); } -inline uint64_t swap64(uint64_t data) { return ((uint64_t)swap32(data) << 32) | swap32(data >> 32); } -#endif - -inline uint16_t swap16(const uint8_t* _pData) { return swap16(*(const uint16_t*)_pData); } -inline uint32_t swap32(const uint8_t* _pData) { return swap32(*(const uint32_t*)_pData); } -inline uint64_t swap64(const uint8_t* _pData) { return swap64(*(const uint64_t*)_pData); } diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 7d48de5757..94af9b6ce9 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -355,7 +355,6 @@ - @@ -535,4 +534,4 @@ - \ No newline at end of file + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 981ac5d5a3..4f8646bace 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -94,7 +94,6 @@ - @@ -183,4 +182,4 @@ {7be79ad5-3520-46a1-a370-dce2a943978c} - \ No newline at end of file + diff --git a/Core/MIPS/ARM/ArmCompALU.cpp b/Core/MIPS/ARM/ArmCompALU.cpp index 67e5a70600..471b3e0dc2 100644 --- a/Core/MIPS/ARM/ArmCompALU.cpp +++ b/Core/MIPS/ARM/ArmCompALU.cpp @@ -25,7 +25,7 @@ #include "Core/MIPS/ARM/ArmJit.h" #include "Core/MIPS/ARM/ArmRegCache.h" #include "Common/CPUDetect.h" -#include "Common/ByteSwap.h" +#include "Common/BitSet.h" using namespace MIPSAnalyst; diff --git a/Core/MIPS/ARM64/Arm64CompALU.cpp b/Core/MIPS/ARM64/Arm64CompALU.cpp index df195209f6..a4e5ea25e9 100644 --- a/Core/MIPS/ARM64/Arm64CompALU.cpp +++ b/Core/MIPS/ARM64/Arm64CompALU.cpp @@ -20,7 +20,7 @@ #include -#include "Common/ByteSwap.h" +#include "Common/BitSet.h" #include "Common/CPUDetect.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSCodeUtils.h" diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index d6f96876d2..d7f8195c98 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -2,7 +2,7 @@ #include #include -#include "Common/ByteSwap.h" +#include "Common/BitSet.h" #include "Common/Log.h" #include "Core/MIPS/IR/IRInterpreter.h" #include "Core/MIPS/IR/IRPassSimplify.h" diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index a48887f935..49847dc4a5 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -19,9 +19,9 @@ #include "math/math_util.h" -#include "Common/ByteSwap.h" -#include "Common/Common.h" +#include "Common/BitSet.h" #include "Common/BitScan.h" +#include "Common/Common.h" #include "Core/Config.h" #include "Core/Core.h" #include "Core/Host.h" diff --git a/Core/MIPS/x86/CompALU.cpp b/Core/MIPS/x86/CompALU.cpp index 06ee0e9231..4c262cf1a4 100644 --- a/Core/MIPS/x86/CompALU.cpp +++ b/Core/MIPS/x86/CompALU.cpp @@ -20,7 +20,7 @@ #include -#include "Common/ByteSwap.h" +#include "Common/BitSet.h" #include "Common/Common.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/x86/Jit.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 21f6880a58..f4c80840cd 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -386,7 +386,6 @@ - diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index ece02a7b10..a4cbb48402 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -57,7 +57,6 @@ - diff --git a/ext/native/util/text/utf16.h b/ext/native/util/text/utf16.h index 542b1e94a6..a04949ed35 100644 --- a/ext/native/util/text/utf16.h +++ b/ext/native/util/text/utf16.h @@ -2,7 +2,7 @@ #include -#include "Common/ByteSwap.h" +#include "Common/BitSet.h" // Should optimize out. #define UTF16_IS_LITTLE_ENDIAN (*(const uint16_t *)"\0\xff" >= 0x100) From 65617889dd2ece7047ecfe89a86d4b7bdea7a28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 29 Sep 2020 23:59:05 +0200 Subject: [PATCH 807/848] Merge ext/native/ext/... directly into ext. --- .ycm_extra_conf.py | 2 +- CMakeLists.txt | 189 +- Common/Common.vcxproj | 221 +- Common/Common.vcxproj.filters | 82 +- Common/stdafx.cpp | 11 - Common/stdafx.h | 42 - Core/Core.vcxproj | 92 +- Core/Core.vcxproj.filters | 239 ++ Core/MIPS/MIPSAsm.cpp | 3 - UI/UI.vcxproj | 18 +- UWP/CommonUWP/CommonUWP.vcxproj | 93 +- UWP/CommonUWP/CommonUWP.vcxproj.filters | 98 +- UWP/CoreUWP/CoreUWP.vcxproj | 2091 ++++++++++++++++- UWP/CoreUWP/CoreUWP.vcxproj.filters | 215 ++ UWP/GPU_UWP/GPU_UWP.vcxproj | 24 +- UWP/NativeUWP/NativeUWP.vcxproj | 1013 +------- UWP/NativeUWP/NativeUWP.vcxproj.filters | 296 +-- UWP/UI_UWP/UI_UWP.vcxproj | 24 +- Windows/PPSSPP.sln | 1 + Windows/W32Util/Misc.cpp | 1 - android/ab.sh | 2 +- android/custom_rules.xml | 4 +- android/jni/Android.mk | 63 +- ext/{native/ext => }/cityhash/COPYING | 0 ext/{native/ext => }/cityhash/README | 0 ext/{native/ext => }/cityhash/city.cpp | 0 ext/{native/ext => }/cityhash/city.h | 0 ext/{native/ext => }/cityhash/citycrc.h | 0 ext/{native/ext => }/gason/LICENSE | 0 ext/{native/ext => }/gason/gason.cpp | 0 ext/{native/ext => }/gason/gason.h | 0 ext/{native/ext => }/jpge/jpgd.cpp | 0 ext/{native/ext => }/jpge/jpgd.h | 0 ext/{native/ext => }/jpge/jpge.cpp | 0 ext/{native/ext => }/jpge/jpge.h | 0 ext/{native/ext => }/jpge/publicdomain.txt | 0 ext/{native/ext => }/libpng17/CMakeLists.txt | 0 ext/{native/ext => }/libpng17/png.c | 0 ext/{native/ext => }/libpng17/png.h | 0 ext/{native/ext => }/libpng17/pngconf.h | 0 ext/{native/ext => }/libpng17/pngdebug.h | 0 ext/{native/ext => }/libpng17/pngerror.c | 0 ext/{native/ext => }/libpng17/pngget.c | 0 ext/{native/ext => }/libpng17/pnginfo.h | 0 ext/{native/ext => }/libpng17/pnglibconf.h | 0 ext/{native/ext => }/libpng17/pngmem.c | 0 ext/{native/ext => }/libpng17/pngpread.c | 0 ext/{native/ext => }/libpng17/pngpriv.h | 0 ext/{native/ext => }/libpng17/pngread.c | 0 ext/{native/ext => }/libpng17/pngrio.c | 0 ext/{native/ext => }/libpng17/pngrtran.c | 0 ext/{native/ext => }/libpng17/pngrutil.c | 0 ext/{native/ext => }/libpng17/pngset.c | 0 ext/{native/ext => }/libpng17/pngstruct.h | 0 ext/{native/ext => }/libpng17/pngtest.c | 0 ext/{native/ext => }/libpng17/pngtrans.c | 0 ext/{native/ext => }/libpng17/pngwio.c | 0 ext/{native/ext => }/libpng17/pngwrite.c | 0 ext/{native/ext => }/libpng17/pngwtran.c | 0 ext/{native/ext => }/libpng17/pngwutil.c | 0 ext/{native/ext => }/libzip/Android.mk | 0 ext/{native/ext => }/libzip/CMakeLists.txt | 0 ext/{native/ext => }/libzip/config.h | 0 ext/{native/ext => }/libzip/libzip.la | 0 ext/{native/ext => }/libzip/mkstemp.c | 0 ext/{native/ext => }/libzip/zip.h | 0 ext/{native/ext => }/libzip/zip_add.c | 0 ext/{native/ext => }/libzip/zip_add_dir.c | 0 ext/{native/ext => }/libzip/zip_close.c | 0 ext/{native/ext => }/libzip/zip_delete.c | 0 ext/{native/ext => }/libzip/zip_dirent.c | 0 ext/{native/ext => }/libzip/zip_entry_free.c | 0 ext/{native/ext => }/libzip/zip_entry_new.c | 0 ext/{native/ext => }/libzip/zip_err_str.c | 0 ext/{native/ext => }/libzip/zip_error.c | 0 ext/{native/ext => }/libzip/zip_error_clear.c | 0 ext/{native/ext => }/libzip/zip_error_get.c | 0 .../ext => }/libzip/zip_error_get_sys_type.c | 0 .../ext => }/libzip/zip_error_strerror.c | 0 .../ext => }/libzip/zip_error_to_str.c | 0 ext/{native/ext => }/libzip/zip_fclose.c | 0 .../ext => }/libzip/zip_file_error_clear.c | 0 .../ext => }/libzip/zip_file_error_get.c | 0 .../ext => }/libzip/zip_file_get_offset.c | 0 .../ext => }/libzip/zip_file_strerror.c | 0 .../ext => }/libzip/zip_filerange_crc.c | 0 ext/{native/ext => }/libzip/zip_fopen.c | 0 ext/{native/ext => }/libzip/zip_fopen_index.c | 0 ext/{native/ext => }/libzip/zip_fread.c | 0 ext/{native/ext => }/libzip/zip_free.c | 0 .../ext => }/libzip/zip_get_archive_comment.c | 0 .../ext => }/libzip/zip_get_archive_flag.c | 0 .../ext => }/libzip/zip_get_file_comment.c | 0 ext/{native/ext => }/libzip/zip_get_name.c | 0 .../ext => }/libzip/zip_get_num_files.c | 0 ext/{native/ext => }/libzip/zip_memdup.c | 0 ext/{native/ext => }/libzip/zip_name_locate.c | 0 ext/{native/ext => }/libzip/zip_new.c | 0 ext/{native/ext => }/libzip/zip_open.c | 0 ext/{native/ext => }/libzip/zip_rename.c | 0 ext/{native/ext => }/libzip/zip_replace.c | 0 .../ext => }/libzip/zip_set_archive_comment.c | 0 .../ext => }/libzip/zip_set_archive_flag.c | 0 .../ext => }/libzip/zip_set_file_comment.c | 0 ext/{native/ext => }/libzip/zip_set_name.c | 0 .../ext => }/libzip/zip_source_buffer.c | 0 ext/{native/ext => }/libzip/zip_source_file.c | 0 .../ext => }/libzip/zip_source_filep.c | 0 ext/{native/ext => }/libzip/zip_source_free.c | 0 .../ext => }/libzip/zip_source_function.c | 0 ext/{native/ext => }/libzip/zip_source_zip.c | 0 ext/{native/ext => }/libzip/zip_stat.c | 0 ext/{native/ext => }/libzip/zip_stat_index.c | 0 ext/{native/ext => }/libzip/zip_stat_init.c | 0 ext/{native/ext => }/libzip/zip_strerror.c | 0 ext/{native/ext => }/libzip/zip_unchange.c | 0 .../ext => }/libzip/zip_unchange_all.c | 0 .../ext => }/libzip/zip_unchange_archive.c | 0 .../ext => }/libzip/zip_unchange_data.c | 0 ext/{native/ext => }/libzip/zipint.h | 0 ext/native/Android.mk | 21 - ext/native/ext/libpng17/arm/arm_init.c | 133 -- ext/native/ext/libpng17/arm/filter_neon.S | 246 -- .../ext/libpng17/arm/filter_neon_intrinsics.c | 376 --- ext/native/native.vcxproj | 637 +---- ext/native/native.vcxproj.filters | 291 --- ext/native/tools/atlastool.cpp | 2 +- ext/{native/ext => }/sha1/CMakeLists.txt | 0 ext/{native/ext => }/sha1/sha1.cpp | 0 ext/{native/ext => }/sha1/sha1.h | 0 libretro/Makefile.common | 162 +- 131 files changed, 3297 insertions(+), 3395 deletions(-) delete mode 100644 Common/stdafx.cpp delete mode 100644 Common/stdafx.h rename ext/{native/ext => }/cityhash/COPYING (100%) rename ext/{native/ext => }/cityhash/README (100%) rename ext/{native/ext => }/cityhash/city.cpp (100%) rename ext/{native/ext => }/cityhash/city.h (100%) rename ext/{native/ext => }/cityhash/citycrc.h (100%) rename ext/{native/ext => }/gason/LICENSE (100%) rename ext/{native/ext => }/gason/gason.cpp (100%) rename ext/{native/ext => }/gason/gason.h (100%) rename ext/{native/ext => }/jpge/jpgd.cpp (100%) rename ext/{native/ext => }/jpge/jpgd.h (100%) rename ext/{native/ext => }/jpge/jpge.cpp (100%) rename ext/{native/ext => }/jpge/jpge.h (100%) rename ext/{native/ext => }/jpge/publicdomain.txt (100%) rename ext/{native/ext => }/libpng17/CMakeLists.txt (100%) rename ext/{native/ext => }/libpng17/png.c (100%) rename ext/{native/ext => }/libpng17/png.h (100%) rename ext/{native/ext => }/libpng17/pngconf.h (100%) rename ext/{native/ext => }/libpng17/pngdebug.h (100%) rename ext/{native/ext => }/libpng17/pngerror.c (100%) rename ext/{native/ext => }/libpng17/pngget.c (100%) rename ext/{native/ext => }/libpng17/pnginfo.h (100%) rename ext/{native/ext => }/libpng17/pnglibconf.h (100%) rename ext/{native/ext => }/libpng17/pngmem.c (100%) rename ext/{native/ext => }/libpng17/pngpread.c (100%) rename ext/{native/ext => }/libpng17/pngpriv.h (100%) rename ext/{native/ext => }/libpng17/pngread.c (100%) rename ext/{native/ext => }/libpng17/pngrio.c (100%) rename ext/{native/ext => }/libpng17/pngrtran.c (100%) rename ext/{native/ext => }/libpng17/pngrutil.c (100%) rename ext/{native/ext => }/libpng17/pngset.c (100%) rename ext/{native/ext => }/libpng17/pngstruct.h (100%) rename ext/{native/ext => }/libpng17/pngtest.c (100%) rename ext/{native/ext => }/libpng17/pngtrans.c (100%) rename ext/{native/ext => }/libpng17/pngwio.c (100%) rename ext/{native/ext => }/libpng17/pngwrite.c (100%) rename ext/{native/ext => }/libpng17/pngwtran.c (100%) rename ext/{native/ext => }/libpng17/pngwutil.c (100%) rename ext/{native/ext => }/libzip/Android.mk (100%) rename ext/{native/ext => }/libzip/CMakeLists.txt (100%) rename ext/{native/ext => }/libzip/config.h (100%) rename ext/{native/ext => }/libzip/libzip.la (100%) rename ext/{native/ext => }/libzip/mkstemp.c (100%) rename ext/{native/ext => }/libzip/zip.h (100%) rename ext/{native/ext => }/libzip/zip_add.c (100%) rename ext/{native/ext => }/libzip/zip_add_dir.c (100%) rename ext/{native/ext => }/libzip/zip_close.c (100%) rename ext/{native/ext => }/libzip/zip_delete.c (100%) rename ext/{native/ext => }/libzip/zip_dirent.c (100%) rename ext/{native/ext => }/libzip/zip_entry_free.c (100%) rename ext/{native/ext => }/libzip/zip_entry_new.c (100%) rename ext/{native/ext => }/libzip/zip_err_str.c (100%) rename ext/{native/ext => }/libzip/zip_error.c (100%) rename ext/{native/ext => }/libzip/zip_error_clear.c (100%) rename ext/{native/ext => }/libzip/zip_error_get.c (100%) rename ext/{native/ext => }/libzip/zip_error_get_sys_type.c (100%) rename ext/{native/ext => }/libzip/zip_error_strerror.c (100%) rename ext/{native/ext => }/libzip/zip_error_to_str.c (100%) rename ext/{native/ext => }/libzip/zip_fclose.c (100%) rename ext/{native/ext => }/libzip/zip_file_error_clear.c (100%) rename ext/{native/ext => }/libzip/zip_file_error_get.c (100%) rename ext/{native/ext => }/libzip/zip_file_get_offset.c (100%) rename ext/{native/ext => }/libzip/zip_file_strerror.c (100%) rename ext/{native/ext => }/libzip/zip_filerange_crc.c (100%) rename ext/{native/ext => }/libzip/zip_fopen.c (100%) rename ext/{native/ext => }/libzip/zip_fopen_index.c (100%) rename ext/{native/ext => }/libzip/zip_fread.c (100%) rename ext/{native/ext => }/libzip/zip_free.c (100%) rename ext/{native/ext => }/libzip/zip_get_archive_comment.c (100%) rename ext/{native/ext => }/libzip/zip_get_archive_flag.c (100%) rename ext/{native/ext => }/libzip/zip_get_file_comment.c (100%) rename ext/{native/ext => }/libzip/zip_get_name.c (100%) rename ext/{native/ext => }/libzip/zip_get_num_files.c (100%) rename ext/{native/ext => }/libzip/zip_memdup.c (100%) rename ext/{native/ext => }/libzip/zip_name_locate.c (100%) rename ext/{native/ext => }/libzip/zip_new.c (100%) rename ext/{native/ext => }/libzip/zip_open.c (100%) rename ext/{native/ext => }/libzip/zip_rename.c (100%) rename ext/{native/ext => }/libzip/zip_replace.c (100%) rename ext/{native/ext => }/libzip/zip_set_archive_comment.c (100%) rename ext/{native/ext => }/libzip/zip_set_archive_flag.c (100%) rename ext/{native/ext => }/libzip/zip_set_file_comment.c (100%) rename ext/{native/ext => }/libzip/zip_set_name.c (100%) rename ext/{native/ext => }/libzip/zip_source_buffer.c (100%) rename ext/{native/ext => }/libzip/zip_source_file.c (100%) rename ext/{native/ext => }/libzip/zip_source_filep.c (100%) rename ext/{native/ext => }/libzip/zip_source_free.c (100%) rename ext/{native/ext => }/libzip/zip_source_function.c (100%) rename ext/{native/ext => }/libzip/zip_source_zip.c (100%) rename ext/{native/ext => }/libzip/zip_stat.c (100%) rename ext/{native/ext => }/libzip/zip_stat_index.c (100%) rename ext/{native/ext => }/libzip/zip_stat_init.c (100%) rename ext/{native/ext => }/libzip/zip_strerror.c (100%) rename ext/{native/ext => }/libzip/zip_unchange.c (100%) rename ext/{native/ext => }/libzip/zip_unchange_all.c (100%) rename ext/{native/ext => }/libzip/zip_unchange_archive.c (100%) rename ext/{native/ext => }/libzip/zip_unchange_data.c (100%) rename ext/{native/ext => }/libzip/zipint.h (100%) delete mode 100644 ext/native/ext/libpng17/arm/arm_init.c delete mode 100644 ext/native/ext/libpng17/arm/filter_neon.S delete mode 100644 ext/native/ext/libpng17/arm/filter_neon_intrinsics.c rename ext/{native/ext => }/sha1/CMakeLists.txt (100%) rename ext/{native/ext => }/sha1/sha1.cpp (100%) rename ext/{native/ext => }/sha1/sha1.h (100%) diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py index cbda75bb1f..67405088b5 100644 --- a/.ycm_extra_conf.py +++ b/.ycm_extra_conf.py @@ -41,7 +41,7 @@ flags = [ '-fexceptions', '-DNDEBUG', '-Iext/native', -'-Iext/native/ext', +'-Iext', '-Iext/glew', '-ICommon', # THIS IS IMPORTANT! Without a "-std=" flag, clang won't know which diff --git a/CMakeLists.txt b/CMakeLists.txt index 12f85e629d..c323f8885b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -400,12 +400,6 @@ if(NOT (X86 OR ARM OR MIPS)) source_group(Fake FILES ${CommonFake}) endif() -set(CommonWindows - Common/stdafx.cpp - Common/stdafx.h -) -source_group(Windows FILES ${CommonWindows}) - set(CommonVulkan ${CommonExtra} Common/Vulkan/VulkanDebug.cpp Common/Vulkan/VulkanDebug.h @@ -425,7 +419,6 @@ add_library(Common STATIC ${CommonARM64} ${CommonMIPS} ${CommonFake} - ${CommonWindows} ${CommonVulkan} Common/Serialize/Serializer.cpp Common/Serialize/Serializer.h @@ -518,8 +511,8 @@ if(USING_GLES2 OR (USING_EGL AND NOT USING_FBDEV)) endif() add_library(gason STATIC - ext/native/ext/gason/gason.cpp - ext/native/ext/gason/gason.h + ext/gason/gason.cpp + ext/gason/gason.h ) if(USE_FFMPEG) @@ -610,9 +603,9 @@ else() endif() add_library(cityhash STATIC - ext/native/ext/cityhash/city.cpp - ext/native/ext/cityhash/city.h - ext/native/ext/cityhash/citycrc.h + ext/cityhash/city.cpp + ext/cityhash/city.h + ext/cityhash/citycrc.h ) include_directories(ext/cityhash) @@ -631,64 +624,64 @@ if(LIBZIP_FOUND AND USE_SYSTEM_LIBZIP) add_definitions(-DSHARED_LIBZIP) else() add_library(libzip STATIC - ext/native/ext/libzip/zip.h - ext/native/ext/libzip/mkstemp.c - ext/native/ext/libzip/zip_add.c - ext/native/ext/libzip/zip_add_dir.c - ext/native/ext/libzip/zip_close.c - ext/native/ext/libzip/zip_delete.c - ext/native/ext/libzip/zip_dirent.c - ext/native/ext/libzip/zip_entry_free.c - ext/native/ext/libzip/zip_entry_new.c - ext/native/ext/libzip/zip_err_str.c - ext/native/ext/libzip/zip_error.c - ext/native/ext/libzip/zip_error_clear.c - ext/native/ext/libzip/zip_error_get.c - ext/native/ext/libzip/zip_error_get_sys_type.c - ext/native/ext/libzip/zip_error_strerror.c - ext/native/ext/libzip/zip_error_to_str.c - ext/native/ext/libzip/zip_fclose.c - ext/native/ext/libzip/zip_file_error_clear.c - ext/native/ext/libzip/zip_file_error_get.c - ext/native/ext/libzip/zip_file_get_offset.c - ext/native/ext/libzip/zip_file_strerror.c - ext/native/ext/libzip/zip_filerange_crc.c - ext/native/ext/libzip/zip_fopen.c - ext/native/ext/libzip/zip_fopen_index.c - ext/native/ext/libzip/zip_fread.c - ext/native/ext/libzip/zip_free.c - ext/native/ext/libzip/zip_get_archive_comment.c - ext/native/ext/libzip/zip_get_archive_flag.c - ext/native/ext/libzip/zip_get_file_comment.c - ext/native/ext/libzip/zip_get_name.c - ext/native/ext/libzip/zip_get_num_files.c - ext/native/ext/libzip/zip_memdup.c - ext/native/ext/libzip/zip_name_locate.c - ext/native/ext/libzip/zip_new.c - ext/native/ext/libzip/zip_open.c - ext/native/ext/libzip/zip_rename.c - ext/native/ext/libzip/zip_replace.c - ext/native/ext/libzip/zip_set_archive_comment.c - ext/native/ext/libzip/zip_set_archive_flag.c - ext/native/ext/libzip/zip_set_file_comment.c - ext/native/ext/libzip/zip_set_name.c - ext/native/ext/libzip/zip_source_buffer.c - ext/native/ext/libzip/zip_source_file.c - ext/native/ext/libzip/zip_source_filep.c - ext/native/ext/libzip/zip_source_free.c - ext/native/ext/libzip/zip_source_function.c - ext/native/ext/libzip/zip_source_zip.c - ext/native/ext/libzip/zip_stat.c - ext/native/ext/libzip/zip_stat_index.c - ext/native/ext/libzip/zip_stat_init.c - ext/native/ext/libzip/zip_strerror.c - ext/native/ext/libzip/zip_unchange.c - ext/native/ext/libzip/zip_unchange_all.c - ext/native/ext/libzip/zip_unchange_archive.c - ext/native/ext/libzip/zip_unchange_data.c + ext/libzip/zip.h + ext/libzip/mkstemp.c + ext/libzip/zip_add.c + ext/libzip/zip_add_dir.c + ext/libzip/zip_close.c + ext/libzip/zip_delete.c + ext/libzip/zip_dirent.c + ext/libzip/zip_entry_free.c + ext/libzip/zip_entry_new.c + ext/libzip/zip_err_str.c + ext/libzip/zip_error.c + ext/libzip/zip_error_clear.c + ext/libzip/zip_error_get.c + ext/libzip/zip_error_get_sys_type.c + ext/libzip/zip_error_strerror.c + ext/libzip/zip_error_to_str.c + ext/libzip/zip_fclose.c + ext/libzip/zip_file_error_clear.c + ext/libzip/zip_file_error_get.c + ext/libzip/zip_file_get_offset.c + ext/libzip/zip_file_strerror.c + ext/libzip/zip_filerange_crc.c + ext/libzip/zip_fopen.c + ext/libzip/zip_fopen_index.c + ext/libzip/zip_fread.c + ext/libzip/zip_free.c + ext/libzip/zip_get_archive_comment.c + ext/libzip/zip_get_archive_flag.c + ext/libzip/zip_get_file_comment.c + ext/libzip/zip_get_name.c + ext/libzip/zip_get_num_files.c + ext/libzip/zip_memdup.c + ext/libzip/zip_name_locate.c + ext/libzip/zip_new.c + ext/libzip/zip_open.c + ext/libzip/zip_rename.c + ext/libzip/zip_replace.c + ext/libzip/zip_set_archive_comment.c + ext/libzip/zip_set_archive_flag.c + ext/libzip/zip_set_file_comment.c + ext/libzip/zip_set_name.c + ext/libzip/zip_source_buffer.c + ext/libzip/zip_source_file.c + ext/libzip/zip_source_filep.c + ext/libzip/zip_source_free.c + ext/libzip/zip_source_function.c + ext/libzip/zip_source_zip.c + ext/libzip/zip_stat.c + ext/libzip/zip_stat_index.c + ext/libzip/zip_stat_init.c + ext/libzip/zip_strerror.c + ext/libzip/zip_unchange.c + ext/libzip/zip_unchange_all.c + ext/libzip/zip_unchange_archive.c + ext/libzip/zip_unchange_data.c ) target_link_libraries(libzip) - include_directories(ext/native/ext/libzip) + include_directories(ext/libzip) set(LIBZIP_LIBRARY libzip) endif() @@ -705,38 +698,38 @@ if(PNG_FOUND) else() if(ARM) set(PNG_ARM_INCLUDES - ext/native/ext/libpng17/arm/arm_init.c - ext/native/ext/libpng17/arm/filter_neon.S - ext/native/ext/libpng17/arm/filter_neon_intrinsics.c + ext/libpng17/arm/arm_init.c + ext/libpng17/arm/filter_neon.S + ext/libpng17/arm/filter_neon_intrinsics.c ) endif() add_library(png17 STATIC - ext/native/ext/libpng17/pngconf.h - ext/native/ext/libpng17/pngdebug.h - ext/native/ext/libpng17/png.c - ext/native/ext/libpng17/png.h - ext/native/ext/libpng17/pngerror.c - ext/native/ext/libpng17/pngget.c - ext/native/ext/libpng17/pnginfo.h - ext/native/ext/libpng17/pnglibconf.h - ext/native/ext/libpng17/pngmem.c - ext/native/ext/libpng17/pngpread.c - ext/native/ext/libpng17/pngpriv.h - ext/native/ext/libpng17/pngread.c - ext/native/ext/libpng17/pngrio.c - ext/native/ext/libpng17/pngrtran.c - ext/native/ext/libpng17/pngrutil.c - ext/native/ext/libpng17/pngset.c - ext/native/ext/libpng17/pngstruct.h - ext/native/ext/libpng17/pngtrans.c - ext/native/ext/libpng17/pngwio.c - ext/native/ext/libpng17/pngwrite.c - ext/native/ext/libpng17/pngwtran.c - ext/native/ext/libpng17/pngwutil.c + ext/libpng17/pngconf.h + ext/libpng17/pngdebug.h + ext/libpng17/png.c + ext/libpng17/png.h + ext/libpng17/pngerror.c + ext/libpng17/pngget.c + ext/libpng17/pnginfo.h + ext/libpng17/pnglibconf.h + ext/libpng17/pngmem.c + ext/libpng17/pngpread.c + ext/libpng17/pngpriv.h + ext/libpng17/pngread.c + ext/libpng17/pngrio.c + ext/libpng17/pngrtran.c + ext/libpng17/pngrutil.c + ext/libpng17/pngset.c + ext/libpng17/pngstruct.h + ext/libpng17/pngtrans.c + ext/libpng17/pngwio.c + ext/libpng17/pngwrite.c + ext/libpng17/pngwtran.c + ext/libpng17/pngwutil.c ${PNG_ARM_INCLUDES} ) set(PNG_LIBRARIES png17) - include_directories(ext/native/ext/libpng17) + include_directories(ext/libpng17) endif() set(nativeExtra) @@ -1087,10 +1080,10 @@ add_library(native STATIC ext/native/util/text/wrap_text.cpp ext/native/util/const_map.h ext/native/util/tiny_set.h - ext/native/ext/jpge/jpgd.cpp - ext/native/ext/jpge/jpgd.h - ext/native/ext/jpge/jpge.cpp - ext/native/ext/jpge/jpge.h + ext/jpge/jpgd.cpp + ext/jpge/jpgd.h + ext/jpge/jpge.cpp + ext/jpge/jpge.h ) include_directories(ext/native) diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 94af9b6ce9..aceea2b7fc 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -132,12 +132,11 @@ - Use Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - stdafx.h;Common/DbgNew.h + Common/DbgNew.h MultiThreadedDebug - ../ext/native;../ext/snappy;../ext/glslang;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. StreamingSIMDExtensions2 Precise true @@ -155,12 +154,11 @@ - Use Level3 - stdafx.h;Common/DbgNew.h + Common/DbgNew.h MultiThreadedDebug _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;../ext/glslang;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. NotSet Precise false @@ -179,12 +177,11 @@ - Use Level3 - stdafx.h;Common/DbgNew.h + Common/DbgNew.h MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. NotSet Precise false @@ -203,12 +200,12 @@ - Use Level3 - stdafx.h + + MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. NotSet Precise false @@ -228,16 +225,16 @@ Level3 - Use MaxSpeed true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - stdafx.h + + false StreamingSIMDExtensions2 Precise - ../ext/native;../ext/snappy;../ext/glslang;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. Speed true false @@ -257,13 +254,13 @@ Level3 - Use MaxSpeed true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - stdafx.h - ../ext/native;../ext/snappy;../ext/glslang;.. + + + ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. false NotSet Precise @@ -288,13 +285,13 @@ Level3 - Use MaxSpeed true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - stdafx.h - ../ext/native;../ext/snappy;../ext/glslang;.. + + + ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. false NotSet Precise @@ -319,13 +316,13 @@ Level3 - Use MaxSpeed true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - stdafx.h - ../ext/native;../ext/snappy;../ext/glslang;.. + + + ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. false NotSet Precise @@ -348,6 +345,13 @@ + + + + + + + @@ -411,7 +415,6 @@ - @@ -429,6 +432,157 @@ + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + @@ -503,16 +657,6 @@ - - Create - Create - Create - Create - Create - Create - Create - Create - @@ -527,8 +671,11 @@ - - {c4df647e-80ea-4111-a0a8-218b1b711e18} + + + + + {f761046e-6c38-4428-a5f1-38391a37bb34} diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 4f8646bace..1322c5858d 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -1,7 +1,6 @@  - @@ -96,9 +95,29 @@ + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + - @@ -164,6 +183,54 @@ + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + @@ -181,5 +248,16 @@ {7be79ad5-3520-46a1-a370-dce2a943978c} + + {b2685193-5954-4ab6-af7c-d6064f63e278} + + + {1d04f87f-73a2-4027-a6ff-e998e92e7d3c} + + + + + ext\libpng17 + diff --git a/Common/stdafx.cpp b/Common/stdafx.cpp deleted file mode 100644 index 0348c60f8d..0000000000 --- a/Common/stdafx.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// Common.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#ifdef _WIN32 - -#include "stdafx.h" - -#endif -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/Common/stdafx.h b/Common/stdafx.h deleted file mode 100644 index 1f18c24ec4..0000000000 --- a/Common/stdafx.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#pragma once - -#ifdef _WIN32 -#ifndef _WIN32_WINNT - -#if defined(_MSC_VER) && _MSC_VER < 1700 -#error You need a newer version of Visual Studio. -#else -#define _WIN32_WINNT 0x601 -#endif - -#endif // #ifndef _WIN32_WINNT - -#undef WINVER -#define WINVER _WIN32_WINNT -#ifndef _WIN32_IE -#define _WIN32_IE 0x0600 // Default value is 0x0400 -#endif - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - -#include "CommonWindows.h" -#include -#include -#endif diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 22276dc688..d1cb94b914 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -138,7 +138,7 @@ Level3 - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) StreamingSIMDExtensions2 Precise @@ -161,7 +161,7 @@ Level3 - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) NotSet Precise @@ -185,7 +185,7 @@ Level3 - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotSet Precise @@ -209,7 +209,7 @@ Level3 - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotSet Precise @@ -237,7 +237,7 @@ MaxSpeed true true - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext false StreamingSIMDExtensions2 Precise @@ -268,7 +268,7 @@ MaxSpeed true true - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext NotSet Precise false @@ -299,7 +299,7 @@ MaxSpeed true true - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext NotSet Precise false @@ -330,7 +330,7 @@ MaxSpeed true true - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/native/ext/libpng17;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext NotSet Precise false @@ -356,8 +356,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -885,11 +944,20 @@ + + + + + + + + + @@ -1197,6 +1265,10 @@ + + + + @@ -1220,6 +1292,10 @@ {f761046e-6c38-4428-a5f1-38391a37bb34} + + + + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index b9c3ce66be..611c164009 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -73,6 +73,21 @@ {c21d9bb5-614d-451b-8c0b-3078b29122d8} + + {db010645-6b26-41a7-8d44-c53cb0533d7d} + + + {cf1a59fe-8509-48f0-84d0-27c71cb10dc3} + + + {d8c48d88-2e34-4a98-aa88-4277a3b8afea} + + + {6c6e0188-fabf-4203-aaa2-896c42be2c20} + + + {0201ff27-4fa8-4cf3-bbb9-accfdc0c7046} + @@ -767,6 +782,183 @@ Ext\Snappy + + Ext\gason + + + Ext\city + + + Ext\sha1 + + + Ext\jpge + + + Ext\jpge + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + @@ -1418,10 +1610,57 @@ HLE + + Ext\gason + + + Ext\city + + + Ext\city + + + Ext\sha1 + + + Ext\jpge + + + Ext\jpge + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\gason + + + Ext\city + + + Ext\city + + + Ext\libzip + + + + + Ext\sha1 + + + Ext\libzip + \ No newline at end of file diff --git a/Core/MIPS/MIPSAsm.cpp b/Core/MIPS/MIPSAsm.cpp index 37914016e6..a6ed1261ac 100644 --- a/Core/MIPS/MIPSAsm.cpp +++ b/Core/MIPS/MIPSAsm.cpp @@ -1,6 +1,3 @@ -#ifdef _WIN32 -#include "stdafx.h" -#endif #include #include #include diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index 132b9b9640..8c621c2f4e 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -207,7 +207,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_32=1;WIN32;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext true false false @@ -227,7 +227,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_64=1;WIN32;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext true false false @@ -248,7 +248,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_64=1;WIN32;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext true false false @@ -269,7 +269,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_32=1;WIN32;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext true false false @@ -294,7 +294,7 @@ true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_32=1;WIN32;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext false Size true @@ -319,7 +319,7 @@ true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_64=1;WIN32;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext false true false @@ -346,7 +346,7 @@ true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_64=1;WIN32;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext false true false @@ -373,7 +373,7 @@ true true USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;_ARCH_32=1;WIN32;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext/native/ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/zlib;../ext false true false @@ -394,4 +394,4 @@ - \ No newline at end of file + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index f4c80840cd..3febada63d 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -200,12 +200,12 @@ - Use false true pch.h - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NotUsing Console @@ -215,12 +215,12 @@ - Use false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h + NotUsing Console @@ -230,12 +230,12 @@ - Use false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h + NotUsing Console @@ -245,12 +245,12 @@ - Use false true pch.h - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NotUsing Console @@ -260,12 +260,12 @@ - Use false true pch.h - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NotUsing Console @@ -275,12 +275,12 @@ - Use false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h + NotUsing Console @@ -290,12 +290,12 @@ - Use false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h + NotUsing Console @@ -305,12 +305,12 @@ - Use false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h + NotUsing Console @@ -320,12 +320,12 @@ - Use false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h + NotUsing Console @@ -335,12 +335,12 @@ - Use false true pch.h - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NotUsing Console @@ -350,12 +350,12 @@ - Use false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h + NotUsing Console @@ -365,12 +365,12 @@ - Use false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h + NotUsing Console @@ -417,7 +417,6 @@ - @@ -428,7 +427,13 @@ - + + + + + + + @@ -459,7 +464,6 @@ - @@ -467,22 +471,27 @@ - - Create - Create - Create - Create - Create - Create - Create - Create - Create - Create - Create - Create - + + + + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index a4cbb48402..8df0d99656 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -4,9 +4,14 @@ {da855697-f7aa-49bf-b969-7a90c5b4d259} + + {c2303262-a4f0-4400-8dd7-35ad6ac5f443} + + + {b0ac485c-3153-4708-b098-f5a518a95b79} + - @@ -30,7 +35,6 @@ - @@ -47,9 +51,57 @@ Crypto + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + - @@ -58,11 +110,6 @@ - - - - - @@ -85,7 +132,6 @@ - @@ -105,5 +151,37 @@ Crypto + + + + + + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + + + ext\libpng17 + - + + + ext\libpng17 + + + \ No newline at end of file diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 166da83a30..a860f0886c 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -204,7 +204,7 @@ false true pch.h - ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -219,7 +219,7 @@ false true pch.h - ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -234,7 +234,7 @@ false true pch.h - ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x86/include;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -249,7 +249,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -264,7 +264,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -279,7 +279,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -294,7 +294,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -309,7 +309,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -324,7 +324,7 @@ false true pch.h - ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/ARM64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -339,7 +339,7 @@ false true pch.h - ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -354,7 +354,7 @@ false true pch.h - ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -369,7 +369,7 @@ false true pch.h - ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/native/ext/libpng17;../../Common;../../ext/zlib;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../../ffmpeg/Windows10/x64/include;../../ffmpeg/WindowsInclude;../..;../../ext/native;../../ext/snappy;../../ext/libpng17;../../Common;../../ext/zlib;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) USE_FFMPEG;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -576,7 +576,15 @@ + + + + + + + + @@ -819,7 +827,2063 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + + + + + + + + + + + + + + + + + + + + NotUsing NotUsing @@ -960,6 +3024,9 @@ {d31fd4f0-53eb-477c-9dc7-149796f628e2} + + + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 944ccc3509..8283fb162e 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -71,6 +71,18 @@ {3b1039f9-72dc-4c7f-bd4e-25791be20df7} + + {613b4e2e-264b-4ae8-9b23-bc15590ffa11} + + + {e20f358f-a614-47ff-a5b7-164c82e613a9} + + + {69359915-04ac-4d1f-a7ba-25b282c26ae9} + + + {1ad7ee67-c496-4709-bf98-cad322fe5d97} + @@ -724,6 +736,180 @@ Util + + Ext\gason + + + Ext\cityhash + + + Ext\jpge + + + Ext\jpge + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + @@ -1330,5 +1516,34 @@ Util + + Ext\gason + + + Ext\cityhash + + + Ext\cityhash + + + Ext\jpge + + + Ext\jpge + + + Ext\libzip + + + Ext\libzip + + + Ext\libzip + + + + + Ext\gason + \ No newline at end of file diff --git a/UWP/GPU_UWP/GPU_UWP.vcxproj b/UWP/GPU_UWP/GPU_UWP.vcxproj index 248d1c6a2b..be5fdc1a1f 100644 --- a/UWP/GPU_UWP/GPU_UWP.vcxproj +++ b/UWP/GPU_UWP/GPU_UWP.vcxproj @@ -204,7 +204,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -219,7 +219,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -234,7 +234,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -249,7 +249,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -264,7 +264,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -279,7 +279,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -294,7 +294,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -309,7 +309,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -324,7 +324,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -339,7 +339,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -354,7 +354,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -369,7 +369,7 @@ false true pch.h - ../..;../../ext/snappy;../../ext/native;../../Common;../../ext/native/ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/snappy;../../ext/native;../../Common;../../ext;../../ext/glslang;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index ae64fb1ea7..54654bc7cc 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -204,7 +204,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -219,7 +219,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -234,7 +234,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -249,7 +249,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -264,7 +264,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -279,7 +279,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -294,7 +294,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -309,7 +309,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -324,7 +324,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -339,7 +339,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -354,7 +354,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -369,7 +369,7 @@ false true pch.h - ../..;../../ext/native/ext;../..;../../ext/native;../../ext/zlib;../../ext/native/ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -384,22 +384,6 @@ - - - - - - - - - - - - - - - - @@ -467,977 +451,6 @@ - - - - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - @@ -1625,4 +638,4 @@ - + \ No newline at end of file diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index e9dfd60c68..7b5e91cae6 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -34,33 +34,12 @@ {a522f449-7873-4af7-908e-7cc91eb8bfc0} - - {2be24387-0b6a-4253-97fa-b8b6f75a8a4c} - - - {1a486fc4-bac0-4b33-9139-262272690c74} - - - {f3b2701a-3ddc-4604-a867-2ee9a0600dab} - - - {34445680-c1be-4aec-a716-1e118ef48906} - {96ac6deb-ad00-4ee4-9f0d-515d78d1886b} - - {3ffe0470-9652-4d89-a3d1-7eb989d266ab} - {4d23e7d3-0b9b-4dbe-95df-6ab250782a66} - - {fb517d8e-e6c4-4eaf-a579-9970daa96541} - - - {b68fe6a0-b55f-4411-91f4-63ab1eaf47a3} - @@ -202,219 +181,6 @@ i18n - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\jpge - - - ext\jpge - gfx @@ -424,29 +190,17 @@ image - - ext\cityhash - gfx data - - base - math - - ext\gason - - - ext\sha1 - net @@ -622,42 +376,6 @@ i18n - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\jpge - - - ext\jpge - gfx @@ -667,12 +385,6 @@ image - - ext\cityhash - - - ext\cityhash - gfx @@ -681,12 +393,6 @@ - - ext\gason - - - ext\sha1 - net @@ -697,4 +403,4 @@ gfx - + \ No newline at end of file diff --git a/UWP/UI_UWP/UI_UWP.vcxproj b/UWP/UI_UWP/UI_UWP.vcxproj index 9db7ab4ac7..dd4037f7e0 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj +++ b/UWP/UI_UWP/UI_UWP.vcxproj @@ -204,7 +204,7 @@ false true NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -219,7 +219,7 @@ false true NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -234,7 +234,7 @@ false true GOLD;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -249,7 +249,7 @@ false true NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -264,7 +264,7 @@ false true NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -279,7 +279,7 @@ false true NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -294,7 +294,7 @@ false true NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -309,7 +309,7 @@ false true GOLD;NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -324,7 +324,7 @@ false true GOLD;NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -339,7 +339,7 @@ false true NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -354,7 +354,7 @@ false true NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h @@ -369,7 +369,7 @@ false true GOLD;NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../..;../../ext/native;../../Common;../../ext/native/ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../Common;../../ext;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) pch.h diff --git a/Windows/PPSSPP.sln b/Windows/PPSSPP.sln index a0bacf19db..942e26be29 100644 --- a/Windows/PPSSPP.sln +++ b/Windows/PPSSPP.sln @@ -16,6 +16,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPPWindows", "PPSSPP.vcx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\Common\Common.vcxproj", "{3FCDBAE2-5103-4350-9A8E-848CE9C73195}" ProjectSection(ProjectDependencies) = postProject + {F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34} {C4DF647E-80EA-4111-A0A8-218B1B711E18} = {C4DF647E-80EA-4111-A0A8-218B1B711E18} EndProjectSection EndProject diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index aa3e9e432b..b4544d08a9 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -1,4 +1,3 @@ -#include "stdafx.h" #include "ppsspp_config.h" #include "CommonWindows.h" diff --git a/android/ab.sh b/android/ab.sh index 25ed476eb2..08520d1a28 100755 --- a/android/ab.sh +++ b/android/ab.sh @@ -5,4 +5,4 @@ cp ../assets/langregion.ini assets/langregion.ini cp ../assets/compat.ini assets/compat.ini cp ../assets/Roboto-Condensed.ttf assets/Roboto-Condensed.ttf cp ../assets/*.png assets/ -NDK_MODULE_PATH=../ext:../ext/native/ext $NDK/ndk-build -j3 $* +NDK_MODULE_PATH=../ext $NDK/ndk-build -j3 $* diff --git a/android/custom_rules.xml b/android/custom_rules.xml index e7edd4ff7e..292a376101 100644 --- a/android/custom_rules.xml +++ b/android/custom_rules.xml @@ -7,13 +7,13 @@ - + - + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 71b73e9c60..4e5d42436a 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -156,11 +156,55 @@ SPIRV_CROSS_FILES := \ $(SRC)/ext/SPIRV-Cross/spirv_parser.cpp \ $(SRC)/ext/SPIRV-Cross/spirv_cross_parsed_ir.cpp +EXT_FILES := \ + $(SRC)/ext/cityhash/city.cpp \ + $(SRC)/ext/libpng17/png.c \ + $(SRC)/ext/libpng17/pngerror.c \ + $(SRC)/ext/libpng17/pngget.c \ + $(SRC)/ext/libpng17/pngmem.c \ + $(SRC)/ext/libpng17/pngpread.c \ + $(SRC)/ext/libpng17/pngread.c \ + $(SRC)/ext/libpng17/pngrio.c \ + $(SRC)/ext/libpng17/pngrtran.c \ + $(SRC)/ext/libpng17/pngrutil.c \ + $(SRC)/ext/libpng17/pngset.c \ + $(SRC)/ext/libpng17/pngtest.c \ + $(SRC)/ext/libpng17/pngtrans.c \ + $(SRC)/ext/libpng17/pngwio.c \ + $(SRC)/ext/libpng17/pngwrite.c \ + $(SRC)/ext/libpng17/pngwtran.c \ + $(SRC)/ext/libpng17/pngwutil.c \ + $(SRC)/ext/jpge/jpgd.cpp \ + $(SRC)/ext/jpge/jpge.cpp \ + $(SRC)/ext/sha1/sha1.cpp \ + $(SRC)/ext/gason/gason.cpp \ + $(SRC)/ext/libkirk/AES.c \ + $(SRC)/ext/libkirk/amctrl.c \ + $(SRC)/ext/libkirk/SHA1.c \ + $(SRC)/ext/libkirk/bn.c \ + $(SRC)/ext/libkirk/ec.c \ + $(SRC)/ext/libkirk/kirk_engine.c \ + $(SRC)/ext/sfmt19937/SFMT.c \ + $(SRC)/ext/snappy/snappy-c.cpp \ + $(SRC)/ext/snappy/snappy-sinksource.cpp \ + $(SRC)/ext/snappy/snappy-stubs-internal.cpp \ + $(SRC)/ext/snappy/snappy.cpp \ + $(SRC)/ext/udis86/decode.c \ + $(SRC)/ext/udis86/itab.c \ + $(SRC)/ext/udis86/syn-att.c \ + $(SRC)/ext/udis86/syn-intel.c \ + $(SRC)/ext/udis86/syn.c \ + $(SRC)/ext/udis86/udis86.c \ + $(SRC)/ext/xbrz/xbrz.cpp \ + $(SRC)/ext/xxhash.c \ + + EXEC_AND_LIB_FILES := \ $(ARCH_FILES) \ $(EGL_FILES) \ $(VULKAN_FILES) \ $(SPIRV_CROSS_FILES) \ + $(EXT_FILES) \ TestRunner.cpp \ $(SRC)/Core/MIPS/MIPS.cpp.arm \ $(SRC)/Core/MIPS/MIPSAnalyst.cpp \ @@ -185,25 +229,6 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/MIPS/IR/IRInterpreter.cpp \ $(SRC)/Core/MIPS/IR/IRPassSimplify.cpp \ $(SRC)/Core/MIPS/IR/IRRegCache.cpp \ - $(SRC)/ext/libkirk/AES.c \ - $(SRC)/ext/libkirk/amctrl.c \ - $(SRC)/ext/libkirk/SHA1.c \ - $(SRC)/ext/libkirk/bn.c \ - $(SRC)/ext/libkirk/ec.c \ - $(SRC)/ext/libkirk/kirk_engine.c \ - $(SRC)/ext/sfmt19937/SFMT.c \ - $(SRC)/ext/snappy/snappy-c.cpp \ - $(SRC)/ext/snappy/snappy-sinksource.cpp \ - $(SRC)/ext/snappy/snappy-stubs-internal.cpp \ - $(SRC)/ext/snappy/snappy.cpp \ - $(SRC)/ext/udis86/decode.c \ - $(SRC)/ext/udis86/itab.c \ - $(SRC)/ext/udis86/syn-att.c \ - $(SRC)/ext/udis86/syn-intel.c \ - $(SRC)/ext/udis86/syn.c \ - $(SRC)/ext/udis86/udis86.c \ - $(SRC)/ext/xbrz/xbrz.cpp \ - $(SRC)/ext/xxhash.c \ $(SRC)/Common/Buffer.cpp \ $(SRC)/Common/Crypto/md5.cpp \ $(SRC)/Common/Crypto/sha1.cpp \ diff --git a/ext/native/ext/cityhash/COPYING b/ext/cityhash/COPYING similarity index 100% rename from ext/native/ext/cityhash/COPYING rename to ext/cityhash/COPYING diff --git a/ext/native/ext/cityhash/README b/ext/cityhash/README similarity index 100% rename from ext/native/ext/cityhash/README rename to ext/cityhash/README diff --git a/ext/native/ext/cityhash/city.cpp b/ext/cityhash/city.cpp similarity index 100% rename from ext/native/ext/cityhash/city.cpp rename to ext/cityhash/city.cpp diff --git a/ext/native/ext/cityhash/city.h b/ext/cityhash/city.h similarity index 100% rename from ext/native/ext/cityhash/city.h rename to ext/cityhash/city.h diff --git a/ext/native/ext/cityhash/citycrc.h b/ext/cityhash/citycrc.h similarity index 100% rename from ext/native/ext/cityhash/citycrc.h rename to ext/cityhash/citycrc.h diff --git a/ext/native/ext/gason/LICENSE b/ext/gason/LICENSE similarity index 100% rename from ext/native/ext/gason/LICENSE rename to ext/gason/LICENSE diff --git a/ext/native/ext/gason/gason.cpp b/ext/gason/gason.cpp similarity index 100% rename from ext/native/ext/gason/gason.cpp rename to ext/gason/gason.cpp diff --git a/ext/native/ext/gason/gason.h b/ext/gason/gason.h similarity index 100% rename from ext/native/ext/gason/gason.h rename to ext/gason/gason.h diff --git a/ext/native/ext/jpge/jpgd.cpp b/ext/jpge/jpgd.cpp similarity index 100% rename from ext/native/ext/jpge/jpgd.cpp rename to ext/jpge/jpgd.cpp diff --git a/ext/native/ext/jpge/jpgd.h b/ext/jpge/jpgd.h similarity index 100% rename from ext/native/ext/jpge/jpgd.h rename to ext/jpge/jpgd.h diff --git a/ext/native/ext/jpge/jpge.cpp b/ext/jpge/jpge.cpp similarity index 100% rename from ext/native/ext/jpge/jpge.cpp rename to ext/jpge/jpge.cpp diff --git a/ext/native/ext/jpge/jpge.h b/ext/jpge/jpge.h similarity index 100% rename from ext/native/ext/jpge/jpge.h rename to ext/jpge/jpge.h diff --git a/ext/native/ext/jpge/publicdomain.txt b/ext/jpge/publicdomain.txt similarity index 100% rename from ext/native/ext/jpge/publicdomain.txt rename to ext/jpge/publicdomain.txt diff --git a/ext/native/ext/libpng17/CMakeLists.txt b/ext/libpng17/CMakeLists.txt similarity index 100% rename from ext/native/ext/libpng17/CMakeLists.txt rename to ext/libpng17/CMakeLists.txt diff --git a/ext/native/ext/libpng17/png.c b/ext/libpng17/png.c similarity index 100% rename from ext/native/ext/libpng17/png.c rename to ext/libpng17/png.c diff --git a/ext/native/ext/libpng17/png.h b/ext/libpng17/png.h similarity index 100% rename from ext/native/ext/libpng17/png.h rename to ext/libpng17/png.h diff --git a/ext/native/ext/libpng17/pngconf.h b/ext/libpng17/pngconf.h similarity index 100% rename from ext/native/ext/libpng17/pngconf.h rename to ext/libpng17/pngconf.h diff --git a/ext/native/ext/libpng17/pngdebug.h b/ext/libpng17/pngdebug.h similarity index 100% rename from ext/native/ext/libpng17/pngdebug.h rename to ext/libpng17/pngdebug.h diff --git a/ext/native/ext/libpng17/pngerror.c b/ext/libpng17/pngerror.c similarity index 100% rename from ext/native/ext/libpng17/pngerror.c rename to ext/libpng17/pngerror.c diff --git a/ext/native/ext/libpng17/pngget.c b/ext/libpng17/pngget.c similarity index 100% rename from ext/native/ext/libpng17/pngget.c rename to ext/libpng17/pngget.c diff --git a/ext/native/ext/libpng17/pnginfo.h b/ext/libpng17/pnginfo.h similarity index 100% rename from ext/native/ext/libpng17/pnginfo.h rename to ext/libpng17/pnginfo.h diff --git a/ext/native/ext/libpng17/pnglibconf.h b/ext/libpng17/pnglibconf.h similarity index 100% rename from ext/native/ext/libpng17/pnglibconf.h rename to ext/libpng17/pnglibconf.h diff --git a/ext/native/ext/libpng17/pngmem.c b/ext/libpng17/pngmem.c similarity index 100% rename from ext/native/ext/libpng17/pngmem.c rename to ext/libpng17/pngmem.c diff --git a/ext/native/ext/libpng17/pngpread.c b/ext/libpng17/pngpread.c similarity index 100% rename from ext/native/ext/libpng17/pngpread.c rename to ext/libpng17/pngpread.c diff --git a/ext/native/ext/libpng17/pngpriv.h b/ext/libpng17/pngpriv.h similarity index 100% rename from ext/native/ext/libpng17/pngpriv.h rename to ext/libpng17/pngpriv.h diff --git a/ext/native/ext/libpng17/pngread.c b/ext/libpng17/pngread.c similarity index 100% rename from ext/native/ext/libpng17/pngread.c rename to ext/libpng17/pngread.c diff --git a/ext/native/ext/libpng17/pngrio.c b/ext/libpng17/pngrio.c similarity index 100% rename from ext/native/ext/libpng17/pngrio.c rename to ext/libpng17/pngrio.c diff --git a/ext/native/ext/libpng17/pngrtran.c b/ext/libpng17/pngrtran.c similarity index 100% rename from ext/native/ext/libpng17/pngrtran.c rename to ext/libpng17/pngrtran.c diff --git a/ext/native/ext/libpng17/pngrutil.c b/ext/libpng17/pngrutil.c similarity index 100% rename from ext/native/ext/libpng17/pngrutil.c rename to ext/libpng17/pngrutil.c diff --git a/ext/native/ext/libpng17/pngset.c b/ext/libpng17/pngset.c similarity index 100% rename from ext/native/ext/libpng17/pngset.c rename to ext/libpng17/pngset.c diff --git a/ext/native/ext/libpng17/pngstruct.h b/ext/libpng17/pngstruct.h similarity index 100% rename from ext/native/ext/libpng17/pngstruct.h rename to ext/libpng17/pngstruct.h diff --git a/ext/native/ext/libpng17/pngtest.c b/ext/libpng17/pngtest.c similarity index 100% rename from ext/native/ext/libpng17/pngtest.c rename to ext/libpng17/pngtest.c diff --git a/ext/native/ext/libpng17/pngtrans.c b/ext/libpng17/pngtrans.c similarity index 100% rename from ext/native/ext/libpng17/pngtrans.c rename to ext/libpng17/pngtrans.c diff --git a/ext/native/ext/libpng17/pngwio.c b/ext/libpng17/pngwio.c similarity index 100% rename from ext/native/ext/libpng17/pngwio.c rename to ext/libpng17/pngwio.c diff --git a/ext/native/ext/libpng17/pngwrite.c b/ext/libpng17/pngwrite.c similarity index 100% rename from ext/native/ext/libpng17/pngwrite.c rename to ext/libpng17/pngwrite.c diff --git a/ext/native/ext/libpng17/pngwtran.c b/ext/libpng17/pngwtran.c similarity index 100% rename from ext/native/ext/libpng17/pngwtran.c rename to ext/libpng17/pngwtran.c diff --git a/ext/native/ext/libpng17/pngwutil.c b/ext/libpng17/pngwutil.c similarity index 100% rename from ext/native/ext/libpng17/pngwutil.c rename to ext/libpng17/pngwutil.c diff --git a/ext/native/ext/libzip/Android.mk b/ext/libzip/Android.mk similarity index 100% rename from ext/native/ext/libzip/Android.mk rename to ext/libzip/Android.mk diff --git a/ext/native/ext/libzip/CMakeLists.txt b/ext/libzip/CMakeLists.txt similarity index 100% rename from ext/native/ext/libzip/CMakeLists.txt rename to ext/libzip/CMakeLists.txt diff --git a/ext/native/ext/libzip/config.h b/ext/libzip/config.h similarity index 100% rename from ext/native/ext/libzip/config.h rename to ext/libzip/config.h diff --git a/ext/native/ext/libzip/libzip.la b/ext/libzip/libzip.la similarity index 100% rename from ext/native/ext/libzip/libzip.la rename to ext/libzip/libzip.la diff --git a/ext/native/ext/libzip/mkstemp.c b/ext/libzip/mkstemp.c similarity index 100% rename from ext/native/ext/libzip/mkstemp.c rename to ext/libzip/mkstemp.c diff --git a/ext/native/ext/libzip/zip.h b/ext/libzip/zip.h similarity index 100% rename from ext/native/ext/libzip/zip.h rename to ext/libzip/zip.h diff --git a/ext/native/ext/libzip/zip_add.c b/ext/libzip/zip_add.c similarity index 100% rename from ext/native/ext/libzip/zip_add.c rename to ext/libzip/zip_add.c diff --git a/ext/native/ext/libzip/zip_add_dir.c b/ext/libzip/zip_add_dir.c similarity index 100% rename from ext/native/ext/libzip/zip_add_dir.c rename to ext/libzip/zip_add_dir.c diff --git a/ext/native/ext/libzip/zip_close.c b/ext/libzip/zip_close.c similarity index 100% rename from ext/native/ext/libzip/zip_close.c rename to ext/libzip/zip_close.c diff --git a/ext/native/ext/libzip/zip_delete.c b/ext/libzip/zip_delete.c similarity index 100% rename from ext/native/ext/libzip/zip_delete.c rename to ext/libzip/zip_delete.c diff --git a/ext/native/ext/libzip/zip_dirent.c b/ext/libzip/zip_dirent.c similarity index 100% rename from ext/native/ext/libzip/zip_dirent.c rename to ext/libzip/zip_dirent.c diff --git a/ext/native/ext/libzip/zip_entry_free.c b/ext/libzip/zip_entry_free.c similarity index 100% rename from ext/native/ext/libzip/zip_entry_free.c rename to ext/libzip/zip_entry_free.c diff --git a/ext/native/ext/libzip/zip_entry_new.c b/ext/libzip/zip_entry_new.c similarity index 100% rename from ext/native/ext/libzip/zip_entry_new.c rename to ext/libzip/zip_entry_new.c diff --git a/ext/native/ext/libzip/zip_err_str.c b/ext/libzip/zip_err_str.c similarity index 100% rename from ext/native/ext/libzip/zip_err_str.c rename to ext/libzip/zip_err_str.c diff --git a/ext/native/ext/libzip/zip_error.c b/ext/libzip/zip_error.c similarity index 100% rename from ext/native/ext/libzip/zip_error.c rename to ext/libzip/zip_error.c diff --git a/ext/native/ext/libzip/zip_error_clear.c b/ext/libzip/zip_error_clear.c similarity index 100% rename from ext/native/ext/libzip/zip_error_clear.c rename to ext/libzip/zip_error_clear.c diff --git a/ext/native/ext/libzip/zip_error_get.c b/ext/libzip/zip_error_get.c similarity index 100% rename from ext/native/ext/libzip/zip_error_get.c rename to ext/libzip/zip_error_get.c diff --git a/ext/native/ext/libzip/zip_error_get_sys_type.c b/ext/libzip/zip_error_get_sys_type.c similarity index 100% rename from ext/native/ext/libzip/zip_error_get_sys_type.c rename to ext/libzip/zip_error_get_sys_type.c diff --git a/ext/native/ext/libzip/zip_error_strerror.c b/ext/libzip/zip_error_strerror.c similarity index 100% rename from ext/native/ext/libzip/zip_error_strerror.c rename to ext/libzip/zip_error_strerror.c diff --git a/ext/native/ext/libzip/zip_error_to_str.c b/ext/libzip/zip_error_to_str.c similarity index 100% rename from ext/native/ext/libzip/zip_error_to_str.c rename to ext/libzip/zip_error_to_str.c diff --git a/ext/native/ext/libzip/zip_fclose.c b/ext/libzip/zip_fclose.c similarity index 100% rename from ext/native/ext/libzip/zip_fclose.c rename to ext/libzip/zip_fclose.c diff --git a/ext/native/ext/libzip/zip_file_error_clear.c b/ext/libzip/zip_file_error_clear.c similarity index 100% rename from ext/native/ext/libzip/zip_file_error_clear.c rename to ext/libzip/zip_file_error_clear.c diff --git a/ext/native/ext/libzip/zip_file_error_get.c b/ext/libzip/zip_file_error_get.c similarity index 100% rename from ext/native/ext/libzip/zip_file_error_get.c rename to ext/libzip/zip_file_error_get.c diff --git a/ext/native/ext/libzip/zip_file_get_offset.c b/ext/libzip/zip_file_get_offset.c similarity index 100% rename from ext/native/ext/libzip/zip_file_get_offset.c rename to ext/libzip/zip_file_get_offset.c diff --git a/ext/native/ext/libzip/zip_file_strerror.c b/ext/libzip/zip_file_strerror.c similarity index 100% rename from ext/native/ext/libzip/zip_file_strerror.c rename to ext/libzip/zip_file_strerror.c diff --git a/ext/native/ext/libzip/zip_filerange_crc.c b/ext/libzip/zip_filerange_crc.c similarity index 100% rename from ext/native/ext/libzip/zip_filerange_crc.c rename to ext/libzip/zip_filerange_crc.c diff --git a/ext/native/ext/libzip/zip_fopen.c b/ext/libzip/zip_fopen.c similarity index 100% rename from ext/native/ext/libzip/zip_fopen.c rename to ext/libzip/zip_fopen.c diff --git a/ext/native/ext/libzip/zip_fopen_index.c b/ext/libzip/zip_fopen_index.c similarity index 100% rename from ext/native/ext/libzip/zip_fopen_index.c rename to ext/libzip/zip_fopen_index.c diff --git a/ext/native/ext/libzip/zip_fread.c b/ext/libzip/zip_fread.c similarity index 100% rename from ext/native/ext/libzip/zip_fread.c rename to ext/libzip/zip_fread.c diff --git a/ext/native/ext/libzip/zip_free.c b/ext/libzip/zip_free.c similarity index 100% rename from ext/native/ext/libzip/zip_free.c rename to ext/libzip/zip_free.c diff --git a/ext/native/ext/libzip/zip_get_archive_comment.c b/ext/libzip/zip_get_archive_comment.c similarity index 100% rename from ext/native/ext/libzip/zip_get_archive_comment.c rename to ext/libzip/zip_get_archive_comment.c diff --git a/ext/native/ext/libzip/zip_get_archive_flag.c b/ext/libzip/zip_get_archive_flag.c similarity index 100% rename from ext/native/ext/libzip/zip_get_archive_flag.c rename to ext/libzip/zip_get_archive_flag.c diff --git a/ext/native/ext/libzip/zip_get_file_comment.c b/ext/libzip/zip_get_file_comment.c similarity index 100% rename from ext/native/ext/libzip/zip_get_file_comment.c rename to ext/libzip/zip_get_file_comment.c diff --git a/ext/native/ext/libzip/zip_get_name.c b/ext/libzip/zip_get_name.c similarity index 100% rename from ext/native/ext/libzip/zip_get_name.c rename to ext/libzip/zip_get_name.c diff --git a/ext/native/ext/libzip/zip_get_num_files.c b/ext/libzip/zip_get_num_files.c similarity index 100% rename from ext/native/ext/libzip/zip_get_num_files.c rename to ext/libzip/zip_get_num_files.c diff --git a/ext/native/ext/libzip/zip_memdup.c b/ext/libzip/zip_memdup.c similarity index 100% rename from ext/native/ext/libzip/zip_memdup.c rename to ext/libzip/zip_memdup.c diff --git a/ext/native/ext/libzip/zip_name_locate.c b/ext/libzip/zip_name_locate.c similarity index 100% rename from ext/native/ext/libzip/zip_name_locate.c rename to ext/libzip/zip_name_locate.c diff --git a/ext/native/ext/libzip/zip_new.c b/ext/libzip/zip_new.c similarity index 100% rename from ext/native/ext/libzip/zip_new.c rename to ext/libzip/zip_new.c diff --git a/ext/native/ext/libzip/zip_open.c b/ext/libzip/zip_open.c similarity index 100% rename from ext/native/ext/libzip/zip_open.c rename to ext/libzip/zip_open.c diff --git a/ext/native/ext/libzip/zip_rename.c b/ext/libzip/zip_rename.c similarity index 100% rename from ext/native/ext/libzip/zip_rename.c rename to ext/libzip/zip_rename.c diff --git a/ext/native/ext/libzip/zip_replace.c b/ext/libzip/zip_replace.c similarity index 100% rename from ext/native/ext/libzip/zip_replace.c rename to ext/libzip/zip_replace.c diff --git a/ext/native/ext/libzip/zip_set_archive_comment.c b/ext/libzip/zip_set_archive_comment.c similarity index 100% rename from ext/native/ext/libzip/zip_set_archive_comment.c rename to ext/libzip/zip_set_archive_comment.c diff --git a/ext/native/ext/libzip/zip_set_archive_flag.c b/ext/libzip/zip_set_archive_flag.c similarity index 100% rename from ext/native/ext/libzip/zip_set_archive_flag.c rename to ext/libzip/zip_set_archive_flag.c diff --git a/ext/native/ext/libzip/zip_set_file_comment.c b/ext/libzip/zip_set_file_comment.c similarity index 100% rename from ext/native/ext/libzip/zip_set_file_comment.c rename to ext/libzip/zip_set_file_comment.c diff --git a/ext/native/ext/libzip/zip_set_name.c b/ext/libzip/zip_set_name.c similarity index 100% rename from ext/native/ext/libzip/zip_set_name.c rename to ext/libzip/zip_set_name.c diff --git a/ext/native/ext/libzip/zip_source_buffer.c b/ext/libzip/zip_source_buffer.c similarity index 100% rename from ext/native/ext/libzip/zip_source_buffer.c rename to ext/libzip/zip_source_buffer.c diff --git a/ext/native/ext/libzip/zip_source_file.c b/ext/libzip/zip_source_file.c similarity index 100% rename from ext/native/ext/libzip/zip_source_file.c rename to ext/libzip/zip_source_file.c diff --git a/ext/native/ext/libzip/zip_source_filep.c b/ext/libzip/zip_source_filep.c similarity index 100% rename from ext/native/ext/libzip/zip_source_filep.c rename to ext/libzip/zip_source_filep.c diff --git a/ext/native/ext/libzip/zip_source_free.c b/ext/libzip/zip_source_free.c similarity index 100% rename from ext/native/ext/libzip/zip_source_free.c rename to ext/libzip/zip_source_free.c diff --git a/ext/native/ext/libzip/zip_source_function.c b/ext/libzip/zip_source_function.c similarity index 100% rename from ext/native/ext/libzip/zip_source_function.c rename to ext/libzip/zip_source_function.c diff --git a/ext/native/ext/libzip/zip_source_zip.c b/ext/libzip/zip_source_zip.c similarity index 100% rename from ext/native/ext/libzip/zip_source_zip.c rename to ext/libzip/zip_source_zip.c diff --git a/ext/native/ext/libzip/zip_stat.c b/ext/libzip/zip_stat.c similarity index 100% rename from ext/native/ext/libzip/zip_stat.c rename to ext/libzip/zip_stat.c diff --git a/ext/native/ext/libzip/zip_stat_index.c b/ext/libzip/zip_stat_index.c similarity index 100% rename from ext/native/ext/libzip/zip_stat_index.c rename to ext/libzip/zip_stat_index.c diff --git a/ext/native/ext/libzip/zip_stat_init.c b/ext/libzip/zip_stat_init.c similarity index 100% rename from ext/native/ext/libzip/zip_stat_init.c rename to ext/libzip/zip_stat_init.c diff --git a/ext/native/ext/libzip/zip_strerror.c b/ext/libzip/zip_strerror.c similarity index 100% rename from ext/native/ext/libzip/zip_strerror.c rename to ext/libzip/zip_strerror.c diff --git a/ext/native/ext/libzip/zip_unchange.c b/ext/libzip/zip_unchange.c similarity index 100% rename from ext/native/ext/libzip/zip_unchange.c rename to ext/libzip/zip_unchange.c diff --git a/ext/native/ext/libzip/zip_unchange_all.c b/ext/libzip/zip_unchange_all.c similarity index 100% rename from ext/native/ext/libzip/zip_unchange_all.c rename to ext/libzip/zip_unchange_all.c diff --git a/ext/native/ext/libzip/zip_unchange_archive.c b/ext/libzip/zip_unchange_archive.c similarity index 100% rename from ext/native/ext/libzip/zip_unchange_archive.c rename to ext/libzip/zip_unchange_archive.c diff --git a/ext/native/ext/libzip/zip_unchange_data.c b/ext/libzip/zip_unchange_data.c similarity index 100% rename from ext/native/ext/libzip/zip_unchange_data.c rename to ext/libzip/zip_unchange_data.c diff --git a/ext/native/ext/libzip/zipint.h b/ext/libzip/zipint.h similarity index 100% rename from ext/native/ext/libzip/zipint.h rename to ext/libzip/zipint.h diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 754edf4b69..9248ca0d5a 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -11,27 +11,6 @@ LOCAL_SRC_FILES :=\ base/colorutil.cpp \ data/base64.cpp \ data/compression.cpp \ - ext/cityhash/city.cpp \ - ext/libpng17/png.c \ - ext/libpng17/pngerror.c \ - ext/libpng17/pngget.c \ - ext/libpng17/pngmem.c \ - ext/libpng17/pngpread.c \ - ext/libpng17/pngread.c \ - ext/libpng17/pngrio.c \ - ext/libpng17/pngrtran.c \ - ext/libpng17/pngrutil.c \ - ext/libpng17/pngset.c \ - ext/libpng17/pngtest.c \ - ext/libpng17/pngtrans.c \ - ext/libpng17/pngwio.c \ - ext/libpng17/pngwrite.c \ - ext/libpng17/pngwtran.c \ - ext/libpng17/pngwutil.c \ - ext/jpge/jpgd.cpp \ - ext/jpge/jpge.cpp \ - ext/sha1/sha1.cpp \ - ext/gason/gason.cpp \ file/fd_util.cpp \ file/chunk_file.cpp \ file/file_util.cpp \ diff --git a/ext/native/ext/libpng17/arm/arm_init.c b/ext/native/ext/libpng17/arm/arm_init.c deleted file mode 100644 index a672eaebb5..0000000000 --- a/ext/native/ext/libpng17/arm/arm_init.c +++ /dev/null @@ -1,133 +0,0 @@ - -/* arm_init.c - NEON optimised filter functions - * - * Copyright (c) 2014 Glenn Randers-Pehrson - * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.6.10 [(PENDING RELEASE)] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ -/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are - * called. - */ -#define _POSIX_SOURCE 1 - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED -#if PNG_ARM_NEON_OPT > 0 -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ -/* WARNING: it is strongly recommended that you do not build libpng with - * run-time checks for CPU features if at all possible. In the case of the ARM - * NEON instructions there is no processor-specific way of detecting the - * presence of the required support, therefore run-time detection is extremely - * OS specific. - * - * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing - * a fragment of C source code which defines the png_have_neon function. There - * are a number of implementations in contrib/arm-neon, but the only one that - * has partial support is contrib/arm-neon/linux.c - a generic Linux - * implementation which reads /proc/cpufino. - */ -#ifndef PNG_ARM_NEON_FILE -# ifdef __linux__ -# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" -# endif -#endif - -#ifdef PNG_ARM_NEON_FILE - -#include /* for sig_atomic_t */ -static int png_have_neon(png_structp png_ptr); -#include PNG_ARM_NEON_FILE - -#else /* PNG_ARM_NEON_FILE */ -# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks" -#endif /* PNG_ARM_NEON_FILE */ -#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ - -#ifndef PNG_ALIGNED_MEMORY_SUPPORTED -# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" -#endif - -void -png_init_filter_functions_neon(png_structp pp, unsigned int bpp) -{ - /* The switch statement is compiled in for ARM_NEON_API, the call to - * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined - * the check is only performed if the API has not set the NEON option on - * or off explicitly. In this case the check controls what happens. - * - * If the CHECK is not compiled in and the option is UNSET the behavior prior - * to 1.6.7 was to use the NEON code - this was a bug caused by having the - * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, - * as documented in png.h - */ -#ifdef PNG_ARM_NEON_API_SUPPORTED - switch ((pp->options >> PNG_ARM_NEON) & 3) - { - case PNG_OPTION_UNSET: - /* Allow the run-time check to execute if it has been enabled - - * thus both API and CHECK can be turned on. If it isn't supported - * this case will fall through to the 'default' below, which just - * returns. - */ -#endif /* PNG_ARM_NEON_API_SUPPORTED */ -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED - { - static volatile sig_atomic_t no_neon = -1; /* not checked */ - - if (no_neon < 0) - no_neon = !png_have_neon(pp); - - if (no_neon) - return; - } -#ifdef PNG_ARM_NEON_API_SUPPORTED - break; -#endif -#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ - -#ifdef PNG_ARM_NEON_API_SUPPORTED - default: /* OFF or INVALID */ - return; - - case PNG_OPTION_ON: - /* Option turned on */ - break; - } -#endif - - /* IMPORTANT: any new external functions used here must be declared using - * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the - * 'prefix' option to configure works: - * - * ./configure --with-libpng-prefix=foobar_ - * - * Verify you have got this right by running the above command, doing a build - * and examining pngprefix.h; it must contain a #define for every external - * function you add. (Notice that this happens automatically for the - * initialization function.) - */ - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; - - if (bpp == 3) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth3_neon; - } - - else if (bpp == 4) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth4_neon; - } -} -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_READ_SUPPORTED */ diff --git a/ext/native/ext/libpng17/arm/filter_neon.S b/ext/native/ext/libpng17/arm/filter_neon.S deleted file mode 100644 index 40d97775d6..0000000000 --- a/ext/native/ext/libpng17/arm/filter_neon.S +++ /dev/null @@ -1,246 +0,0 @@ - -/* filter_neon.S - NEON optimised filter functions - * - * Copyright (c) 2013 Glenn Randers-Pehrson - * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.6.8 [December 19, 2013] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* This is required to get the symbol renames, which are #defines, and also - * includes the definition (or not) of PNG_ARM_NEON_OPT and - * PNG_ARM_NEON_IMPLEMENTATION. - */ -#define PNG_VERSION_INFO_ONLY -#include "../pngpriv.h" - -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ -#endif - -/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for - * ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it - * only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h - * for the logic which sets PNG_USE_ARM_NEON_ASM: - */ -#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */ - -#ifdef PNG_READ_SUPPORTED -#if PNG_ARM_NEON_OPT > 0 - -#ifdef __ELF__ -# define ELF -#else -# define ELF @ -#endif - - .arch armv7-a - .fpu neon - -.macro func name, export=0 - .macro endfunc -ELF .size \name, . - \name - .endfunc - .purgem endfunc - .endm - .text - .if \export - .global \name - .endif -ELF .type \name, STT_FUNC - .func \name -\name: -.endm - -func png_read_filter_row_sub4_neon, export=1 - ldr r3, [r0, #4] @ rowbytes - vmov.i8 d3, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vadd.u8 d0, d3, d4 - vadd.u8 d1, d0, d5 - vadd.u8 d2, d1, d6 - vadd.u8 d3, d2, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r3, r3, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_sub3_neon, export=1 - ldr r3, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - mov r0, r1 - mov r2, #3 - mov r12, #12 - vld1.8 {q11}, [r0], r12 -1: - vext.8 d5, d22, d23, #3 - vadd.u8 d0, d3, d22 - vext.8 d6, d22, d23, #6 - vadd.u8 d1, d0, d5 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], r12 - vst1.32 {d0[0]}, [r1,:32], r2 - vadd.u8 d2, d1, d6 - vst1.32 {d1[0]}, [r1], r2 - vadd.u8 d3, d2, d7 - vst1.32 {d2[0]}, [r1], r2 - vst1.32 {d3[0]}, [r1], r2 - subs r3, r3, #12 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_up_neon, export=1 - ldr r3, [r0, #4] @ rowbytes -1: - vld1.8 {q0}, [r1,:128] - vld1.8 {q1}, [r2,:128]! - vadd.u8 q0, q0, q1 - vst1.8 {q0}, [r1,:128]! - subs r3, r3, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_avg4_neon, export=1 - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! - vhadd.u8 d0, d3, d16 - vadd.u8 d0, d0, d4 - vhadd.u8 d1, d0, d17 - vadd.u8 d1, d1, d5 - vhadd.u8 d2, d1, d18 - vadd.u8 d2, d2, d6 - vhadd.u8 d3, d2, d19 - vadd.u8 d3, d3, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r12, r12, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_avg3_neon, export=1 - push {r4,lr} - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - mov r0, r1 - mov r4, #3 - mov lr, #12 - vld1.8 {q11}, [r0], lr -1: - vld1.8 {q10}, [r2], lr - vext.8 d5, d22, d23, #3 - vhadd.u8 d0, d3, d20 - vext.8 d17, d20, d21, #3 - vadd.u8 d0, d0, d22 - vext.8 d6, d22, d23, #6 - vhadd.u8 d1, d0, d17 - vext.8 d18, d20, d21, #6 - vadd.u8 d1, d1, d5 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], lr - vst1.32 {d0[0]}, [r1,:32], r4 - vhadd.u8 d2, d1, d18 - vst1.32 {d1[0]}, [r1], r4 - vext.8 d19, d21, d21, #1 - vadd.u8 d2, d2, d6 - vhadd.u8 d3, d2, d19 - vst1.32 {d2[0]}, [r1], r4 - vadd.u8 d3, d3, d7 - vst1.32 {d3[0]}, [r1], r4 - subs r12, r12, #12 - bgt 1b - - pop {r4,pc} -endfunc - -.macro paeth rx, ra, rb, rc - vaddl.u8 q12, \ra, \rb @ a + b - vaddl.u8 q15, \rc, \rc @ 2*c - vabdl.u8 q13, \rb, \rc @ pa - vabdl.u8 q14, \ra, \rc @ pb - vabd.u16 q15, q12, q15 @ pc - vcle.u16 q12, q13, q14 @ pa <= pb - vcle.u16 q13, q13, q15 @ pa <= pc - vcle.u16 q14, q14, q15 @ pb <= pc - vand q12, q12, q13 @ pa <= pb && pa <= pc - vmovn.u16 d28, q14 - vmovn.u16 \rx, q12 - vbsl d28, \rb, \rc - vbsl \rx, \ra, d28 -.endm - -func png_read_filter_row_paeth4_neon, export=1 - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - vmov.i8 d20, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! - paeth d0, d3, d16, d20 - vadd.u8 d0, d0, d4 - paeth d1, d0, d17, d16 - vadd.u8 d1, d1, d5 - paeth d2, d1, d18, d17 - vadd.u8 d2, d2, d6 - paeth d3, d2, d19, d18 - vmov d20, d19 - vadd.u8 d3, d3, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r12, r12, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_paeth3_neon, export=1 - push {r4,lr} - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - vmov.i8 d4, #0 - mov r0, r1 - mov r4, #3 - mov lr, #12 - vld1.8 {q11}, [r0], lr -1: - vld1.8 {q10}, [r2], lr - paeth d0, d3, d20, d4 - vext.8 d5, d22, d23, #3 - vadd.u8 d0, d0, d22 - vext.8 d17, d20, d21, #3 - paeth d1, d0, d17, d20 - vst1.32 {d0[0]}, [r1,:32], r4 - vext.8 d6, d22, d23, #6 - vadd.u8 d1, d1, d5 - vext.8 d18, d20, d21, #6 - paeth d2, d1, d18, d17 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], lr - vst1.32 {d1[0]}, [r1], r4 - vadd.u8 d2, d2, d6 - vext.8 d19, d21, d21, #1 - paeth d3, d2, d19, d18 - vst1.32 {d2[0]}, [r1], r4 - vmov d4, d19 - vadd.u8 d3, d3, d7 - vst1.32 {d3[0]}, [r1], r4 - subs r12, r12, #12 - bgt 1b - - pop {r4,pc} -endfunc -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_READ_SUPPORTED */ -#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */ diff --git a/ext/native/ext/libpng17/arm/filter_neon_intrinsics.c b/ext/native/ext/libpng17/arm/filter_neon_intrinsics.c deleted file mode 100644 index 09c2516a60..0000000000 --- a/ext/native/ext/libpng17/arm/filter_neon_intrinsics.c +++ /dev/null @@ -1,376 +0,0 @@ - -/* filter_neon_intrinsics.c - NEON optimised filter functions - * - * Copyright (c) 2013 Glenn Randers-Pehrson - * Written by James Yu , October 2013. - * Based on filter_neon.S, written by Mans Rullgard, 2011. - * - * Last changed in libpng 1.6.8 [December 19, 2013] - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -/* This code requires -mfpu=neon on the command line: */ -#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ - -#if defined(_MSC_VER) && defined(_M_ARM64) -#include -#else -#include -#endif - -/* libpng row pointers are not necessarily aligned to any particular boundary, - * however this code will only work with appropriate alignment. arm/arm_init.c - * checks for this (and will not compile unless it is done). This code uses - * variants of png_aligncast to avoid compiler warnings. - */ -#define png_ptr(type,pointer) png_aligncast(type *,pointer) -#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) - -/* The following relies on a variable 'temp_pointer' being declared with type - * 'type'. This is written this way just to hide the GCC strict aliasing - * warning; note that the code is safe because there never is an alias between - * the input and output pointers. - */ -#define png_ldr(type,pointer)\ - (temp_pointer = png_ptr(type,pointer), *temp_pointer) - -#ifdef PNG_READ_SUPPORTED -#if PNG_ARM_NEON_OPT > 0 - -void -png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint8x16_t qrp, qpp; - - qrp = vld1q_u8(rp); - qpp = vld1q_u8(pp); - qrp = vaddq_u8(qrp, qpp); - vst1q_u8(rp, qrp); - } -} - -void -png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp = vld1q_u8(rp); - uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); - uint8x8x2_t vrp = *vrpt; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - for (; rp < rp_stop;) - { - uint8x8_t vtmp1, vtmp2; - uint32x2_t *temp_pointer; - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); - vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); - vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); - - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); - vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t, &vtmp); - vrp = *vrpt; - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } - - PNG_UNUSED(prev_row) -} - -void -png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - for (; rp < rp_stop; rp += 16) - { - uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); - uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); - uint8x8x4_t vrp = *vrpt; - uint32x2x4_t *temp_pointer; - - vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); - vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); - vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); - } - - PNG_UNUSED(prev_row) -} - -void -png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp; - uint8x8x2_t *vrpt; - uint8x8x2_t vrp; - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - vtmp = vld1q_u8(rp); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - for (; rp < rp_stop; pp += 12) - { - uint8x8_t vtmp1, vtmp2, vtmp3; - - uint8x8x2_t *vppt; - uint8x8x2_t vpp; - - uint32x2_t *temp_pointer; - - vtmp = vld1q_u8(pp); - vppt = png_ptr(uint8x8x2_t,&vtmp); - vpp = *vppt; - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); - vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); - vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); - vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); - - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); - vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); - - vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); - - vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); - vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } -} - -void -png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint32x2x4_t vtmp; - uint8x8x4_t *vrpt, *vppt; - uint8x8x4_t vrp, vpp; - uint32x2x4_t *temp_pointer; - - vtmp = vld4_u32(png_ptr(uint32_t,rp)); - vrpt = png_ptr(uint8x8x4_t,&vtmp); - vrp = *vrpt; - vtmp = vld4_u32(png_ptrc(uint32_t,pp)); - vppt = png_ptr(uint8x8x4_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); - vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); - vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); - vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); - vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); - vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); - } -} - -static uint8x8_t -paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) -{ - uint8x8_t d, e; - uint16x8_t p1, pa, pb, pc; - - p1 = vaddl_u8(a, b); /* a + b */ - pc = vaddl_u8(c, c); /* c * 2 */ - pa = vabdl_u8(b, c); /* pa */ - pb = vabdl_u8(a, c); /* pb */ - pc = vabdq_u16(p1, pc); /* pc */ - - p1 = vcleq_u16(pa, pb); /* pa <= pb */ - pa = vcleq_u16(pa, pc); /* pa <= pc */ - pb = vcleq_u16(pb, pc); /* pb <= pc */ - - p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ - - d = vmovn_u16(pb); - e = vmovn_u16(p1); - - d = vbsl_u8(d, b, c); - e = vbsl_u8(e, a, d); - - return e; -} - -void -png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp; - uint8x8x2_t *vrpt; - uint8x8x2_t vrp; - uint8x8_t vlast = vdup_n_u8(0); - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - vtmp = vld1q_u8(rp); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - for (; rp < rp_stop; pp += 12) - { - uint8x8x2_t *vppt; - uint8x8x2_t vpp; - uint8x8_t vtmp1, vtmp2, vtmp3; - uint32x2_t *temp_pointer; - - vtmp = vld1q_u8(pp); - vppt = png_ptr(uint8x8x2_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); - vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); - vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); - vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); - vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); - - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); - vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); - - vlast = vtmp2; - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } -} - -void -png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - uint8x8_t vlast = vdup_n_u8(0); - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint32x2x4_t vtmp; - uint8x8x4_t *vrpt, *vppt; - uint8x8x4_t vrp, vpp; - uint32x2x4_t *temp_pointer; - - vtmp = vld4_u32(png_ptr(uint32_t,rp)); - vrpt = png_ptr(uint8x8x4_t,&vtmp); - vrp = *vrpt; - vtmp = vld4_u32(png_ptrc(uint32_t,pp)); - vppt = png_ptr(uint8x8x4_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); - vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); - vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); - vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); - vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - - vlast = vpp.val[3]; - - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); - } -} - -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_READ_SUPPORTED */ -#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 275ac87058..a55298b1f6 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -156,7 +156,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) true false false @@ -178,7 +178,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) true false false @@ -201,7 +201,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) true false false @@ -224,7 +224,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) true false false @@ -251,7 +251,7 @@ true true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) StreamingSIMDExtensions2 Precise true @@ -279,7 +279,7 @@ true true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) NotSet Precise true @@ -309,7 +309,7 @@ true true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) Precise true false @@ -338,7 +338,7 @@ true true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\native\ext\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;..\native\ext;%(AdditionalIncludeDirectories); + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) NotSet Precise true @@ -372,8 +372,6 @@ - - @@ -387,22 +385,6 @@ - - - - - - - - - - - - - - - - @@ -507,609 +489,6 @@ - - AnySuitable - true - Speed - AnySuitable - Speed - AnySuitable - AnySuitable - AnySuitable - true - true - true - Speed - Speed - Speed - false - false - false - AnySuitable - AnySuitable - AnySuitable - Speed - Speed - Speed - false - false - false - StreamingSIMDExtensions2 - Precise - StreamingSIMDExtensions2 - StreamingSIMDExtensions2 - StreamingSIMDExtensions2 - Precise - Precise - Precise - MaxSpeed - MaxSpeed - MaxSpeed - MaxSpeed - Default - Default - Default - Default - - - - - - - - - - - - - - - - - - - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 1542972251..059d1df547 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -9,18 +9,12 @@ base - - ext - tools ui - - ext\libzip - math\fast @@ -77,9 +71,6 @@ input - - ext - base @@ -128,12 +119,6 @@ util - - ext - - - ext - thread @@ -173,45 +158,9 @@ gfx - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libzip - - - ext\libzip - - - ext\libzip - util - - ext\jpge - - - ext\jpge - gfx @@ -305,9 +254,6 @@ thin3d - - ext\gason - json @@ -370,9 +316,6 @@ input - - ext - base @@ -418,9 +361,6 @@ util - - ext - thread @@ -463,222 +403,9 @@ util - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libpng17 - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - - - ext\libzip - util - - ext\jpge - - - ext\jpge - gfx @@ -772,9 +499,6 @@ thin3d - - ext\gason - json @@ -804,9 +528,6 @@ {f3f83007-7c3b-473f-a2f7-423c5087fbfa} - - {5c54b5e2-1bb2-4783-9df6-de4ff7105570} - {c57b41dd-cc33-46ac-b479-19676455ae54} @@ -843,23 +564,11 @@ {02e8ef95-82c7-4420-b029-a189a5e0fcbd} - - {aa8b9b49-2ff8-4961-b6cc-9c33ea674130} - - - {6c47ee5b-0375-40f0-ab2a-402d001cc9c7} - - - {3721adbc-1a4a-4017-bc1d-893c7e86bc22} - {5ce64c0e-98e4-4411-86cc-aacaf2f60b21} {06c6305a-a646-485b-85b9-645a24dd6553} - - {5b740c6f-8dbc-4529-9114-6564b37b3548} - \ No newline at end of file diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp index 05c111f59f..4464861805 100644 --- a/ext/native/tools/atlastool.cpp +++ b/ext/native/tools/atlastool.cpp @@ -354,7 +354,7 @@ inline vector merge(const vector &a, const vector &ranges, float *metrics_height, Bucket *bucket) { - FT_Library freetype; + FT_Library freetype = 0; assert(FT_Init_FreeType(&freetype) == 0); vector fonts; diff --git a/ext/native/ext/sha1/CMakeLists.txt b/ext/sha1/CMakeLists.txt similarity index 100% rename from ext/native/ext/sha1/CMakeLists.txt rename to ext/sha1/CMakeLists.txt diff --git a/ext/native/ext/sha1/sha1.cpp b/ext/sha1/sha1.cpp similarity index 100% rename from ext/native/ext/sha1/sha1.cpp rename to ext/sha1/sha1.cpp diff --git a/ext/native/ext/sha1/sha1.h b/ext/sha1/sha1.h similarity index 100% rename from ext/native/ext/sha1/sha1.h rename to ext/sha1/sha1.h diff --git a/libretro/Makefile.common b/libretro/Makefile.common index ef385e1e5a..8d52cd110a 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -23,71 +23,71 @@ INCFLAGS += \ $(FFMPEGINCFLAGS) \ -I$(EXTDIR)/cityhash \ -I$(EXTDIR)/armips \ - -I$(NATIVEDIR)/ext \ + -I$(EXTDIR) \ -I$(NATIVEDIR) \ - -I$(NATIVEDIR)/ext/libpng17 \ + -I$(EXTDIR)/libpng17 \ -I$(EXTDIR)/libkirk \ -I$(EXTDIR)/xbrz \ -I$(EXTDIR)/xxhash \ -I$(EXTDIR)/glew ifeq ($(PLATFORM_EXT), android) - INCFLAGS += -I$(NATIVEDIR)/ext/libzip + INCFLAGS += -I$(EXTDIR)/libzip SOURCES_C += \ - $(NATIVEDIR)/ext/libzip/mkstemp.c \ - $(NATIVEDIR)/ext/libzip/zip_add.c \ - $(NATIVEDIR)/ext/libzip/zip_add_dir.c \ - $(NATIVEDIR)/ext/libzip/zip_close.c \ - $(NATIVEDIR)/ext/libzip/zip_delete.c \ - $(NATIVEDIR)/ext/libzip/zip_dirent.c \ - $(NATIVEDIR)/ext/libzip/zip_entry_free.c \ - $(NATIVEDIR)/ext/libzip/zip_entry_new.c \ - $(NATIVEDIR)/ext/libzip/zip_err_str.c \ - $(NATIVEDIR)/ext/libzip/zip_error.c \ - $(NATIVEDIR)/ext/libzip/zip_error_clear.c \ - $(NATIVEDIR)/ext/libzip/zip_error_get.c \ - $(NATIVEDIR)/ext/libzip/zip_error_get_sys_type.c \ - $(NATIVEDIR)/ext/libzip/zip_error_strerror.c \ - $(NATIVEDIR)/ext/libzip/zip_error_to_str.c \ - $(NATIVEDIR)/ext/libzip/zip_fclose.c \ - $(NATIVEDIR)/ext/libzip/zip_file_error_clear.c \ - $(NATIVEDIR)/ext/libzip/zip_file_error_get.c \ - $(NATIVEDIR)/ext/libzip/zip_file_get_offset.c \ - $(NATIVEDIR)/ext/libzip/zip_file_strerror.c \ - $(NATIVEDIR)/ext/libzip/zip_filerange_crc.c \ - $(NATIVEDIR)/ext/libzip/zip_fopen.c \ - $(NATIVEDIR)/ext/libzip/zip_fopen_index.c \ - $(NATIVEDIR)/ext/libzip/zip_fread.c \ - $(NATIVEDIR)/ext/libzip/zip_free.c \ - $(NATIVEDIR)/ext/libzip/zip_get_archive_comment.c \ - $(NATIVEDIR)/ext/libzip/zip_get_archive_flag.c \ - $(NATIVEDIR)/ext/libzip/zip_get_file_comment.c \ - $(NATIVEDIR)/ext/libzip/zip_get_name.c \ - $(NATIVEDIR)/ext/libzip/zip_get_num_files.c \ - $(NATIVEDIR)/ext/libzip/zip_memdup.c \ - $(NATIVEDIR)/ext/libzip/zip_name_locate.c \ - $(NATIVEDIR)/ext/libzip/zip_new.c \ - $(NATIVEDIR)/ext/libzip/zip_open.c \ - $(NATIVEDIR)/ext/libzip/zip_rename.c \ - $(NATIVEDIR)/ext/libzip/zip_replace.c \ - $(NATIVEDIR)/ext/libzip/zip_set_archive_comment.c \ - $(NATIVEDIR)/ext/libzip/zip_set_archive_flag.c \ - $(NATIVEDIR)/ext/libzip/zip_set_file_comment.c \ - $(NATIVEDIR)/ext/libzip/zip_set_name.c \ - $(NATIVEDIR)/ext/libzip/zip_source_buffer.c \ - $(NATIVEDIR)/ext/libzip/zip_source_file.c \ - $(NATIVEDIR)/ext/libzip/zip_source_filep.c \ - $(NATIVEDIR)/ext/libzip/zip_source_free.c \ - $(NATIVEDIR)/ext/libzip/zip_source_function.c \ - $(NATIVEDIR)/ext/libzip/zip_source_zip.c \ - $(NATIVEDIR)/ext/libzip/zip_stat.c \ - $(NATIVEDIR)/ext/libzip/zip_stat_index.c \ - $(NATIVEDIR)/ext/libzip/zip_stat_init.c \ - $(NATIVEDIR)/ext/libzip/zip_strerror.c \ - $(NATIVEDIR)/ext/libzip/zip_unchange.c \ - $(NATIVEDIR)/ext/libzip/zip_unchange_all.c \ - $(NATIVEDIR)/ext/libzip/zip_unchange_archive.c \ - $(NATIVEDIR)/ext/libzip/zip_unchange_data.c + $(EXTDIR)/libzip/mkstemp.c \ + $(EXTDIR)/libzip/zip_add.c \ + $(EXTDIR)/libzip/zip_add_dir.c \ + $(EXTDIR)/libzip/zip_close.c \ + $(EXTDIR)/libzip/zip_delete.c \ + $(EXTDIR)/libzip/zip_dirent.c \ + $(EXTDIR)/libzip/zip_entry_free.c \ + $(EXTDIR)/libzip/zip_entry_new.c \ + $(EXTDIR)/libzip/zip_err_str.c \ + $(EXTDIR)/libzip/zip_error.c \ + $(EXTDIR)/libzip/zip_error_clear.c \ + $(EXTDIR)/libzip/zip_error_get.c \ + $(EXTDIR)/libzip/zip_error_get_sys_type.c \ + $(EXTDIR)/libzip/zip_error_strerror.c \ + $(EXTDIR)/libzip/zip_error_to_str.c \ + $(EXTDIR)/libzip/zip_fclose.c \ + $(EXTDIR)/libzip/zip_file_error_clear.c \ + $(EXTDIR)/libzip/zip_file_error_get.c \ + $(EXTDIR)/libzip/zip_file_get_offset.c \ + $(EXTDIR)/libzip/zip_file_strerror.c \ + $(EXTDIR)/libzip/zip_filerange_crc.c \ + $(EXTDIR)/libzip/zip_fopen.c \ + $(EXTDIR)/libzip/zip_fopen_index.c \ + $(EXTDIR)/libzip/zip_fread.c \ + $(EXTDIR)/libzip/zip_free.c \ + $(EXTDIR)/libzip/zip_get_archive_comment.c \ + $(EXTDIR)/libzip/zip_get_archive_flag.c \ + $(EXTDIR)/libzip/zip_get_file_comment.c \ + $(EXTDIR)/libzip/zip_get_name.c \ + $(EXTDIR)/libzip/zip_get_num_files.c \ + $(EXTDIR)/libzip/zip_memdup.c \ + $(EXTDIR)/libzip/zip_name_locate.c \ + $(EXTDIR)/libzip/zip_new.c \ + $(EXTDIR)/libzip/zip_open.c \ + $(EXTDIR)/libzip/zip_rename.c \ + $(EXTDIR)/libzip/zip_replace.c \ + $(EXTDIR)/libzip/zip_set_archive_comment.c \ + $(EXTDIR)/libzip/zip_set_archive_flag.c \ + $(EXTDIR)/libzip/zip_set_file_comment.c \ + $(EXTDIR)/libzip/zip_set_name.c \ + $(EXTDIR)/libzip/zip_source_buffer.c \ + $(EXTDIR)/libzip/zip_source_file.c \ + $(EXTDIR)/libzip/zip_source_filep.c \ + $(EXTDIR)/libzip/zip_source_free.c \ + $(EXTDIR)/libzip/zip_source_function.c \ + $(EXTDIR)/libzip/zip_source_zip.c \ + $(EXTDIR)/libzip/zip_stat.c \ + $(EXTDIR)/libzip/zip_stat_index.c \ + $(EXTDIR)/libzip/zip_stat_init.c \ + $(EXTDIR)/libzip/zip_strerror.c \ + $(EXTDIR)/libzip/zip_unchange.c \ + $(EXTDIR)/libzip/zip_unchange_all.c \ + $(EXTDIR)/libzip/zip_unchange_archive.c \ + $(EXTDIR)/libzip/zip_unchange_data.c SOURCES_C +=\ $(NATIVEDIR)/gfx_es2/gl3stub.c \ @@ -106,20 +106,20 @@ SOURCES_C += \ $(EXTDIR)/libkirk/kirk_engine.c SOURCES_C += \ - $(NATIVEDIR)/ext/libpng17/png.c \ - $(NATIVEDIR)/ext/libpng17/pngerror.c \ - $(NATIVEDIR)/ext/libpng17/pngget.c \ - $(NATIVEDIR)/ext/libpng17/pngmem.c \ - $(NATIVEDIR)/ext/libpng17/pngread.c \ - $(NATIVEDIR)/ext/libpng17/pngrio.c \ - $(NATIVEDIR)/ext/libpng17/pngrtran.c \ - $(NATIVEDIR)/ext/libpng17/pngrutil.c \ - $(NATIVEDIR)/ext/libpng17/pngset.c \ - $(NATIVEDIR)/ext/libpng17/pngtrans.c \ - $(NATIVEDIR)/ext/libpng17/pngwio.c \ - $(NATIVEDIR)/ext/libpng17/pngwrite.c \ - $(NATIVEDIR)/ext/libpng17/pngwtran.c \ - $(NATIVEDIR)/ext/libpng17/pngwutil.c + $(EXTDIR)/libpng17/png.c \ + $(EXTDIR)/libpng17/pngerror.c \ + $(EXTDIR)/libpng17/pngget.c \ + $(EXTDIR)/libpng17/pngmem.c \ + $(EXTDIR)/libpng17/pngread.c \ + $(EXTDIR)/libpng17/pngrio.c \ + $(EXTDIR)/libpng17/pngrtran.c \ + $(EXTDIR)/libpng17/pngrutil.c \ + $(EXTDIR)/libpng17/pngset.c \ + $(EXTDIR)/libpng17/pngtrans.c \ + $(EXTDIR)/libpng17/pngwio.c \ + $(EXTDIR)/libpng17/pngwrite.c \ + $(EXTDIR)/libpng17/pngwtran.c \ + $(EXTDIR)/libpng17/pngwutil.c SOURCES_C += $(EXTDIR)/sfmt19937/SFMT.c SOURCES_C += $(EXTDIR)/xxhash.c @@ -133,9 +133,9 @@ SOURCES_CXX += \ SOURCES_CXX += $(EXTDIR)/xbrz/xbrz.cpp SOURCES_CXX += \ - $(NATIVEDIR)/ext/gason/gason.cpp + $(EXTDIR)/gason/gason.cpp -SOURCES_CXX += $(NATIVEDIR)/ext/cityhash/city.cpp +SOURCES_CXX += $(EXTDIR)/cityhash/city.cpp SOURCES_CXX += \ $(COMMONDIR)/Crypto/md5.cpp \ @@ -324,8 +324,8 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/util/text/utf8.cpp \ $(NATIVEDIR)/util/text/parsers.cpp \ $(NATIVEDIR)/util/text/wrap_text.cpp \ - $(NATIVEDIR)/ext/jpge/jpgd.cpp \ - $(NATIVEDIR)/ext/jpge/jpge.cpp \ + $(EXTDIR)/jpge/jpgd.cpp \ + $(EXTDIR)/jpge/jpge.cpp \ $(COREDIR)/AVIDump.cpp \ $(COREDIR)/Config.cpp \ $(COREDIR)/TextureReplacer.cpp \ @@ -519,10 +519,10 @@ ifeq ($(WITH_DYNAREC),1) $(COMMONDIR)/ColorConvNEON.cpp \ $(GPUDIR)/Common/TextureDecoderNEON.cpp - SOURCES_C += $(NATIVEDIR)/ext/libpng17/arm/arm_init.c \ - $(NATIVEDIR)/ext/libpng17/arm/filter_neon_intrinsics.c + SOURCES_C += $(EXTDIR)/libpng17/arm/arm_init.c \ + $(EXTDIR)/libpng17/arm/filter_neon_intrinsics.c ASMFILES += $(NATIVEDIR)/math/fast/fast_matrix_neon.S \ - $(NATIVEDIR)/ext/libpng17/arm/filter_neon.S + $(EXTDIR)/libpng17/arm/filter_neon.S endif else ifeq ($(TARGET_ARCH),arm64) DYNAFLAGS += -D_ARCH_64 @@ -549,10 +549,10 @@ ifeq ($(WITH_DYNAREC),1) $(COMMONDIR)/ColorConvNEON.cpp \ $(GPUDIR)/Common/TextureDecoderNEON.cpp - SOURCES_C += $(NATIVEDIR)/ext/libpng17/arm/arm_init.c \ - $(NATIVEDIR)/ext/libpng17/arm/filter_neon_intrinsics.c + SOURCES_C += $(EXTDIR)/libpng17/arm/arm_init.c \ + $(EXTDIR)/libpng17/arm/filter_neon_intrinsics.c ASMFILES += $(NATIVEDIR)/math/fast/fast_matrix_neon.S \ - $(NATIVEDIR)/ext/libpng17/arm/filter_neon.S + $(EXTDIR)/libpng17/arm/filter_neon.S endif else ifneq (,$(findstring msvc,$(platform))) From af57eb582cefbef65b7706e414c7cad2b58c4eb9 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 29 Sep 2020 22:41:43 -0700 Subject: [PATCH 808/848] Global: Add back arm files for libpng. --- ext/libpng17/arm/arm_init.c | 133 ++++++++ ext/libpng17/arm/filter_neon.S | 246 ++++++++++++++ ext/libpng17/arm/filter_neon_intrinsics.c | 376 ++++++++++++++++++++++ 3 files changed, 755 insertions(+) create mode 100644 ext/libpng17/arm/arm_init.c create mode 100644 ext/libpng17/arm/filter_neon.S create mode 100644 ext/libpng17/arm/filter_neon_intrinsics.c diff --git a/ext/libpng17/arm/arm_init.c b/ext/libpng17/arm/arm_init.c new file mode 100644 index 0000000000..a672eaebb5 --- /dev/null +++ b/ext/libpng17/arm/arm_init.c @@ -0,0 +1,133 @@ + +/* arm_init.c - NEON optimised filter functions + * + * Copyright (c) 2014 Glenn Randers-Pehrson + * Written by Mans Rullgard, 2011. + * Last changed in libpng 1.6.10 [(PENDING RELEASE)] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ +/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are + * called. + */ +#define _POSIX_SOURCE 1 + +#include "../pngpriv.h" + +#ifdef PNG_READ_SUPPORTED +#if PNG_ARM_NEON_OPT > 0 +#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ +/* WARNING: it is strongly recommended that you do not build libpng with + * run-time checks for CPU features if at all possible. In the case of the ARM + * NEON instructions there is no processor-specific way of detecting the + * presence of the required support, therefore run-time detection is extremely + * OS specific. + * + * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing + * a fragment of C source code which defines the png_have_neon function. There + * are a number of implementations in contrib/arm-neon, but the only one that + * has partial support is contrib/arm-neon/linux.c - a generic Linux + * implementation which reads /proc/cpufino. + */ +#ifndef PNG_ARM_NEON_FILE +# ifdef __linux__ +# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" +# endif +#endif + +#ifdef PNG_ARM_NEON_FILE + +#include /* for sig_atomic_t */ +static int png_have_neon(png_structp png_ptr); +#include PNG_ARM_NEON_FILE + +#else /* PNG_ARM_NEON_FILE */ +# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks" +#endif /* PNG_ARM_NEON_FILE */ +#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ + +#ifndef PNG_ALIGNED_MEMORY_SUPPORTED +# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" +#endif + +void +png_init_filter_functions_neon(png_structp pp, unsigned int bpp) +{ + /* The switch statement is compiled in for ARM_NEON_API, the call to + * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined + * the check is only performed if the API has not set the NEON option on + * or off explicitly. In this case the check controls what happens. + * + * If the CHECK is not compiled in and the option is UNSET the behavior prior + * to 1.6.7 was to use the NEON code - this was a bug caused by having the + * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, + * as documented in png.h + */ +#ifdef PNG_ARM_NEON_API_SUPPORTED + switch ((pp->options >> PNG_ARM_NEON) & 3) + { + case PNG_OPTION_UNSET: + /* Allow the run-time check to execute if it has been enabled - + * thus both API and CHECK can be turned on. If it isn't supported + * this case will fall through to the 'default' below, which just + * returns. + */ +#endif /* PNG_ARM_NEON_API_SUPPORTED */ +#ifdef PNG_ARM_NEON_CHECK_SUPPORTED + { + static volatile sig_atomic_t no_neon = -1; /* not checked */ + + if (no_neon < 0) + no_neon = !png_have_neon(pp); + + if (no_neon) + return; + } +#ifdef PNG_ARM_NEON_API_SUPPORTED + break; +#endif +#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ + +#ifdef PNG_ARM_NEON_API_SUPPORTED + default: /* OFF or INVALID */ + return; + + case PNG_OPTION_ON: + /* Option turned on */ + break; + } +#endif + + /* IMPORTANT: any new external functions used here must be declared using + * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the + * 'prefix' option to configure works: + * + * ./configure --with-libpng-prefix=foobar_ + * + * Verify you have got this right by running the above command, doing a build + * and examining pngprefix.h; it must contain a #define for every external + * function you add. (Notice that this happens automatically for the + * initialization function.) + */ + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; + + if (bpp == 3) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth3_neon; + } + + else if (bpp == 4) + { + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth4_neon; + } +} +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/ext/libpng17/arm/filter_neon.S b/ext/libpng17/arm/filter_neon.S new file mode 100644 index 0000000000..40d97775d6 --- /dev/null +++ b/ext/libpng17/arm/filter_neon.S @@ -0,0 +1,246 @@ + +/* filter_neon.S - NEON optimised filter functions + * + * Copyright (c) 2013 Glenn Randers-Pehrson + * Written by Mans Rullgard, 2011. + * Last changed in libpng 1.6.8 [December 19, 2013] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +/* This is required to get the symbol renames, which are #defines, and also + * includes the definition (or not) of PNG_ARM_NEON_OPT and + * PNG_ARM_NEON_IMPLEMENTATION. + */ +#define PNG_VERSION_INFO_ONLY +#include "../pngpriv.h" + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ +#endif + +/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for + * ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it + * only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h + * for the logic which sets PNG_USE_ARM_NEON_ASM: + */ +#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */ + +#ifdef PNG_READ_SUPPORTED +#if PNG_ARM_NEON_OPT > 0 + +#ifdef __ELF__ +# define ELF +#else +# define ELF @ +#endif + + .arch armv7-a + .fpu neon + +.macro func name, export=0 + .macro endfunc +ELF .size \name, . - \name + .endfunc + .purgem endfunc + .endm + .text + .if \export + .global \name + .endif +ELF .type \name, STT_FUNC + .func \name +\name: +.endm + +func png_read_filter_row_sub4_neon, export=1 + ldr r3, [r0, #4] @ rowbytes + vmov.i8 d3, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vadd.u8 d0, d3, d4 + vadd.u8 d1, d0, d5 + vadd.u8 d2, d1, d6 + vadd.u8 d3, d2, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r3, r3, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_sub3_neon, export=1 + ldr r3, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + mov r0, r1 + mov r2, #3 + mov r12, #12 + vld1.8 {q11}, [r0], r12 +1: + vext.8 d5, d22, d23, #3 + vadd.u8 d0, d3, d22 + vext.8 d6, d22, d23, #6 + vadd.u8 d1, d0, d5 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], r12 + vst1.32 {d0[0]}, [r1,:32], r2 + vadd.u8 d2, d1, d6 + vst1.32 {d1[0]}, [r1], r2 + vadd.u8 d3, d2, d7 + vst1.32 {d2[0]}, [r1], r2 + vst1.32 {d3[0]}, [r1], r2 + subs r3, r3, #12 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_up_neon, export=1 + ldr r3, [r0, #4] @ rowbytes +1: + vld1.8 {q0}, [r1,:128] + vld1.8 {q1}, [r2,:128]! + vadd.u8 q0, q0, q1 + vst1.8 {q0}, [r1,:128]! + subs r3, r3, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_avg4_neon, export=1 + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! + vhadd.u8 d0, d3, d16 + vadd.u8 d0, d0, d4 + vhadd.u8 d1, d0, d17 + vadd.u8 d1, d1, d5 + vhadd.u8 d2, d1, d18 + vadd.u8 d2, d2, d6 + vhadd.u8 d3, d2, d19 + vadd.u8 d3, d3, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r12, r12, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_avg3_neon, export=1 + push {r4,lr} + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + mov r0, r1 + mov r4, #3 + mov lr, #12 + vld1.8 {q11}, [r0], lr +1: + vld1.8 {q10}, [r2], lr + vext.8 d5, d22, d23, #3 + vhadd.u8 d0, d3, d20 + vext.8 d17, d20, d21, #3 + vadd.u8 d0, d0, d22 + vext.8 d6, d22, d23, #6 + vhadd.u8 d1, d0, d17 + vext.8 d18, d20, d21, #6 + vadd.u8 d1, d1, d5 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], lr + vst1.32 {d0[0]}, [r1,:32], r4 + vhadd.u8 d2, d1, d18 + vst1.32 {d1[0]}, [r1], r4 + vext.8 d19, d21, d21, #1 + vadd.u8 d2, d2, d6 + vhadd.u8 d3, d2, d19 + vst1.32 {d2[0]}, [r1], r4 + vadd.u8 d3, d3, d7 + vst1.32 {d3[0]}, [r1], r4 + subs r12, r12, #12 + bgt 1b + + pop {r4,pc} +endfunc + +.macro paeth rx, ra, rb, rc + vaddl.u8 q12, \ra, \rb @ a + b + vaddl.u8 q15, \rc, \rc @ 2*c + vabdl.u8 q13, \rb, \rc @ pa + vabdl.u8 q14, \ra, \rc @ pb + vabd.u16 q15, q12, q15 @ pc + vcle.u16 q12, q13, q14 @ pa <= pb + vcle.u16 q13, q13, q15 @ pa <= pc + vcle.u16 q14, q14, q15 @ pb <= pc + vand q12, q12, q13 @ pa <= pb && pa <= pc + vmovn.u16 d28, q14 + vmovn.u16 \rx, q12 + vbsl d28, \rb, \rc + vbsl \rx, \ra, d28 +.endm + +func png_read_filter_row_paeth4_neon, export=1 + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + vmov.i8 d20, #0 +1: + vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] + vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! + paeth d0, d3, d16, d20 + vadd.u8 d0, d0, d4 + paeth d1, d0, d17, d16 + vadd.u8 d1, d1, d5 + paeth d2, d1, d18, d17 + vadd.u8 d2, d2, d6 + paeth d3, d2, d19, d18 + vmov d20, d19 + vadd.u8 d3, d3, d7 + vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! + subs r12, r12, #16 + bgt 1b + + bx lr +endfunc + +func png_read_filter_row_paeth3_neon, export=1 + push {r4,lr} + ldr r12, [r0, #4] @ rowbytes + vmov.i8 d3, #0 + vmov.i8 d4, #0 + mov r0, r1 + mov r4, #3 + mov lr, #12 + vld1.8 {q11}, [r0], lr +1: + vld1.8 {q10}, [r2], lr + paeth d0, d3, d20, d4 + vext.8 d5, d22, d23, #3 + vadd.u8 d0, d0, d22 + vext.8 d17, d20, d21, #3 + paeth d1, d0, d17, d20 + vst1.32 {d0[0]}, [r1,:32], r4 + vext.8 d6, d22, d23, #6 + vadd.u8 d1, d1, d5 + vext.8 d18, d20, d21, #6 + paeth d2, d1, d18, d17 + vext.8 d7, d23, d23, #1 + vld1.8 {q11}, [r0], lr + vst1.32 {d1[0]}, [r1], r4 + vadd.u8 d2, d2, d6 + vext.8 d19, d21, d21, #1 + paeth d3, d2, d19, d18 + vst1.32 {d2[0]}, [r1], r4 + vmov d4, d19 + vadd.u8 d3, d3, d7 + vst1.32 {d3[0]}, [r1], r4 + subs r12, r12, #12 + bgt 1b + + pop {r4,pc} +endfunc +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */ diff --git a/ext/libpng17/arm/filter_neon_intrinsics.c b/ext/libpng17/arm/filter_neon_intrinsics.c new file mode 100644 index 0000000000..09c2516a60 --- /dev/null +++ b/ext/libpng17/arm/filter_neon_intrinsics.c @@ -0,0 +1,376 @@ + +/* filter_neon_intrinsics.c - NEON optimised filter functions + * + * Copyright (c) 2013 Glenn Randers-Pehrson + * Written by James Yu , October 2013. + * Based on filter_neon.S, written by Mans Rullgard, 2011. + * + * Last changed in libpng 1.6.8 [December 19, 2013] + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include "../pngpriv.h" + +/* This code requires -mfpu=neon on the command line: */ +#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ + +#if defined(_MSC_VER) && defined(_M_ARM64) +#include +#else +#include +#endif + +/* libpng row pointers are not necessarily aligned to any particular boundary, + * however this code will only work with appropriate alignment. arm/arm_init.c + * checks for this (and will not compile unless it is done). This code uses + * variants of png_aligncast to avoid compiler warnings. + */ +#define png_ptr(type,pointer) png_aligncast(type *,pointer) +#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) + +/* The following relies on a variable 'temp_pointer' being declared with type + * 'type'. This is written this way just to hide the GCC strict aliasing + * warning; note that the code is safe because there never is an alias between + * the input and output pointers. + */ +#define png_ldr(type,pointer)\ + (temp_pointer = png_ptr(type,pointer), *temp_pointer) + +#ifdef PNG_READ_SUPPORTED +#if PNG_ARM_NEON_OPT > 0 + +void +png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint8x16_t qrp, qpp; + + qrp = vld1q_u8(rp); + qpp = vld1q_u8(pp); + qrp = vaddq_u8(qrp, qpp); + vst1q_u8(rp, qrp); + } +} + +void +png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp = vld1q_u8(rp); + uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); + uint8x8x2_t vrp = *vrpt; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + for (; rp < rp_stop;) + { + uint8x8_t vtmp1, vtmp2; + uint32x2_t *temp_pointer; + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); + vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); + vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); + + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); + vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t, &vtmp); + vrp = *vrpt; + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } + + PNG_UNUSED(prev_row) +} + +void +png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + for (; rp < rp_stop; rp += 16) + { + uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); + uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); + uint8x8x4_t vrp = *vrpt; + uint32x2x4_t *temp_pointer; + + vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); + vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); + vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); + vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + } + + PNG_UNUSED(prev_row) +} + +void +png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_const_bytep pp = prev_row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp; + uint8x8x2_t *vrpt; + uint8x8x2_t vrp; + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + vtmp = vld1q_u8(rp); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + for (; rp < rp_stop; pp += 12) + { + uint8x8_t vtmp1, vtmp2, vtmp3; + + uint8x8x2_t *vppt; + uint8x8x2_t vpp; + + uint32x2_t *temp_pointer; + + vtmp = vld1q_u8(pp); + vppt = png_ptr(uint8x8x2_t,&vtmp); + vpp = *vppt; + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); + vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); + vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); + vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); + + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); + vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); + + vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); + + vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); + vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } +} + +void +png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint32x2x4_t vtmp; + uint8x8x4_t *vrpt, *vppt; + uint8x8x4_t vrp, vpp; + uint32x2x4_t *temp_pointer; + + vtmp = vld4_u32(png_ptr(uint32_t,rp)); + vrpt = png_ptr(uint8x8x4_t,&vtmp); + vrp = *vrpt; + vtmp = vld4_u32(png_ptrc(uint32_t,pp)); + vppt = png_ptr(uint8x8x4_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); + vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); + vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); + vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); + vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); + vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); + + vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + } +} + +static uint8x8_t +paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) +{ + uint8x8_t d, e; + uint16x8_t p1, pa, pb, pc; + + p1 = vaddl_u8(a, b); /* a + b */ + pc = vaddl_u8(c, c); /* c * 2 */ + pa = vabdl_u8(b, c); /* pa */ + pb = vabdl_u8(a, c); /* pb */ + pc = vabdq_u16(p1, pc); /* pc */ + + p1 = vcleq_u16(pa, pb); /* pa <= pb */ + pa = vcleq_u16(pa, pc); /* pa <= pc */ + pb = vcleq_u16(pb, pc); /* pb <= pc */ + + p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ + + d = vmovn_u16(pb); + e = vmovn_u16(p1); + + d = vbsl_u8(d, b, c); + e = vbsl_u8(e, a, d); + + return e; +} + +void +png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_const_bytep pp = prev_row; + png_bytep rp_stop = row + row_info->rowbytes; + + uint8x16_t vtmp; + uint8x8x2_t *vrpt; + uint8x8x2_t vrp; + uint8x8_t vlast = vdup_n_u8(0); + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + vtmp = vld1q_u8(rp); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + for (; rp < rp_stop; pp += 12) + { + uint8x8x2_t *vppt; + uint8x8x2_t vpp; + uint8x8_t vtmp1, vtmp2, vtmp3; + uint32x2_t *temp_pointer; + + vtmp = vld1q_u8(pp); + vppt = png_ptr(uint8x8x2_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); + vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); + vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); + + vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); + vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); + vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); + vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); + + vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); + vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); + + vtmp = vld1q_u8(rp + 12); + vrpt = png_ptr(uint8x8x2_t,&vtmp); + vrp = *vrpt; + + vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); + vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); + + vlast = vtmp2; + + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); + rp += 3; + vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); + rp += 3; + } +} + +void +png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, + png_const_bytep prev_row) +{ + png_bytep rp = row; + png_bytep rp_stop = row + row_info->rowbytes; + png_const_bytep pp = prev_row; + + uint8x8_t vlast = vdup_n_u8(0); + uint8x8x4_t vdest; + vdest.val[3] = vdup_n_u8(0); + + for (; rp < rp_stop; rp += 16, pp += 16) + { + uint32x2x4_t vtmp; + uint8x8x4_t *vrpt, *vppt; + uint8x8x4_t vrp, vpp; + uint32x2x4_t *temp_pointer; + + vtmp = vld4_u32(png_ptr(uint32_t,rp)); + vrpt = png_ptr(uint8x8x4_t,&vtmp); + vrp = *vrpt; + vtmp = vld4_u32(png_ptrc(uint32_t,pp)); + vppt = png_ptr(uint8x8x4_t,&vtmp); + vpp = *vppt; + + vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); + vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); + vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); + vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); + vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); + vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); + vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); + vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); + + vlast = vpp.val[3]; + + vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + } +} + +#endif /* PNG_ARM_NEON_OPT > 0 */ +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ From af307d05e2c7eb7576dbab46fe0f83964bc9ff54 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 29 Sep 2020 22:42:19 -0700 Subject: [PATCH 809/848] Android: Fix include paths. --- android/jni/Locals.mk | 5 ++--- ext/native/Android.mk | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/android/jni/Locals.mk b/android/jni/Locals.mk index 6e851d5d13..3984fad081 100644 --- a/android/jni/Locals.mk +++ b/android/jni/Locals.mk @@ -14,9 +14,8 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/../../ext/miniupnp \ $(LOCAL_PATH)/../../ext/miniupnp-build \ $(LOCAL_PATH)/$(NATIVE)/base \ - $(LOCAL_PATH)/$(NATIVE)/ext \ - $(LOCAL_PATH)/$(NATIVE)/ext/libpng17 \ - $(LOCAL_PATH)/$(NATIVE)/ext/libzip \ + $(LOCAL_PATH)/../../ext/libpng17 \ + $(LOCAL_PATH)/../../ext/libzip \ $(LOCAL_PATH)/$(NATIVE) \ $(LOCAL_PATH) diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 9248ca0d5a..a64ee0821e 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -77,7 +77,7 @@ LOCAL_SRC_FILES :=\ LOCAL_CFLAGS := -O3 -DUSING_GLES2 -fsigned-char -fno-strict-aliasing -Wall -Wno-multichar -D__STDC_CONSTANT_MACROS LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder -LOCAL_C_INCLUDES := $(LOCAL_PATH)/ext $(LOCAL_PATH)/ext/libpng17 $(LOCAL_PATH)/ext/libzip $(LOCAL_PATH)/ext/glslang .. +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../ext $(LOCAL_PATH)/../../ext/libpng17 $(LOCAL_PATH)/../../ext/libzip $(LOCAL_PATH)/../../ext/glslang .. #Portable native and separate code on android in future is easy you needs add files #by ($(target_arch_ABI),arquitecture (armeabi-v7a , armeabi , x86 , MIPS) From 137f03c71d31074bc2fd7e84a1efc25254c4092f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 29 Sep 2020 23:04:30 -0700 Subject: [PATCH 810/848] Adnroid: Add back arm32 files for libpng. --- ext/native/Android.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/native/Android.mk b/ext/native/Android.mk index a64ee0821e..44fe5405b4 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -86,9 +86,9 @@ ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ math/fast/fast_matrix_neon.S.neon \ - ext/libpng17/arm/arm_init.c \ - ext/libpng17/arm/filter_neon_intrinsics.c \ - ext/libpng17/arm/filter_neon.S.neon + ../../ext/libpng17/arm/arm_init.c \ + ../../ext/libpng17/arm/filter_neon_intrinsics.c \ + ../../ext/libpng17/arm/filter_neon.S.neon else ifeq ($(TARGET_ARCH_ABI),armeabi) LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 From f8391103a97261fa8826d3574c1abee17670c17d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 29 Sep 2020 23:25:22 -0700 Subject: [PATCH 811/848] Windows: Correct some stdafx.h paths. --- Windows/Debugger/Debugger_MemoryDlg.cpp | 2 +- Windows/W32Util/PropertySheet.cpp | 4 ++-- Windows/W32Util/ShellUtil.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Windows/Debugger/Debugger_MemoryDlg.cpp b/Windows/Debugger/Debugger_MemoryDlg.cpp index c2bcd0d18f..7e76443bfa 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.cpp +++ b/Windows/Debugger/Debugger_MemoryDlg.cpp @@ -1,6 +1,6 @@ // NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003. -#include "stdafx.h" +#include "Windows/stdafx.h" #include #include "..\resource.h" diff --git a/Windows/W32Util/PropertySheet.cpp b/Windows/W32Util/PropertySheet.cpp index 0ca68dcedd..dc2407dc1d 100644 --- a/Windows/W32Util/PropertySheet.cpp +++ b/Windows/W32Util/PropertySheet.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "Windows/stdafx.h" #include "Misc.h" #include "PropertySheet.h" #include "util/text/utf8.h" @@ -184,4 +184,4 @@ namespace W32Util } return 0; } -} \ No newline at end of file +} diff --git a/Windows/W32Util/ShellUtil.cpp b/Windows/W32Util/ShellUtil.cpp index 39938b3fc0..e53ad9f43f 100644 --- a/Windows/W32Util/ShellUtil.cpp +++ b/Windows/W32Util/ShellUtil.cpp @@ -2,7 +2,7 @@ #pragma warning(disable:4091) // workaround bug in VS2015 headers -#include "stdafx.h" +#include "Windows/stdafx.h" #include #include From 97df3148ebb1f7de60a746890a11a10c46b306d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 30 Sep 2020 08:39:39 +0200 Subject: [PATCH 812/848] Libretro buildfix --- libretro/Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index ef385e1e5a..036d47987e 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -144,7 +144,7 @@ SOURCES_CXX += \ SOURCES_CXX += \ $(COMMONDIR)/Serialize/Serializer.cpp \ - $(COMMONDIR)/Common/Buffer.cpp \ + $(COMMONDIR)/Buffer.cpp \ $(COMMONDIR)/ConsoleListener.cpp \ $(COMMONDIR)/ExceptionHandlerSetup.cpp \ $(COMMONDIR)/FileUtil.cpp \ From 925944d5b228cd22ed9564b55c70a6f65fe20ce8 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Thu, 1 Oct 2020 00:39:14 +0800 Subject: [PATCH 813/848] Savedata:Improves the deleting functions. --- Core/Dialog/PSPSaveDialog.cpp | 61 ++++++++++++++++++++++++++--------- Core/Dialog/SavedataParam.cpp | 8 +++-- Core/Dialog/SavedataParam.h | 6 ++-- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 8328ae34f5..9385da9832 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -174,7 +174,8 @@ int PSPSaveDialog::Init(int paramAddr) DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); display = DS_SAVE_LIST_CHOICE; break; - case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE: + case SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE: + // TODO:Should displays all saves like a PSP? DEBUG_LOG(SCEUTILITY, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if(param.GetFilenameCount() == 0) display = DS_DELETE_NODATA; @@ -185,7 +186,6 @@ int PSPSaveDialog::Init(int paramAddr) case SCE_UTILITY_SAVEDATA_TYPE_LIST: case SCE_UTILITY_SAVEDATA_TYPE_FILES: case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE: - case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE: case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE: case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE: @@ -196,8 +196,26 @@ int PSPSaveDialog::Init(int paramAddr) display = DS_NONE; break; - case SCE_UTILITY_SAVEDATA_TYPE_DELETE: // When run on a PSP, displays a list of all saves on the PSP. Weird. (Not really, it's to let you free up space) - display = DS_DELETE_LIST_CHOICE; + case SCE_UTILITY_SAVEDATA_TYPE_DELETE: + DEBUG_LOG(SCEUTILITY, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); + if (param.GetFileInfo(0).size != 0) { + yesnoChoice = 0; + display = DS_DELETE_CONFIRM; + } else + display = DS_DELETE_NODATA; + break; + + case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE: + DEBUG_LOG(SCEUTILITY, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); + display = DS_NONE; + break; + + case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE: + DEBUG_LOG(SCEUTILITY, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); + if (param.GetFilenameCount() == 0) + display = DS_DELETE_NODATA; + else + display = DS_DELETE_LIST_CHOICE; break; default: { @@ -261,6 +279,8 @@ const std::string PSPSaveDialog::GetSelectedSaveDirName() const case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: case SCE_UTILITY_SAVEDATA_TYPE_SAVE: case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: + case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE: + case SCE_UTILITY_SAVEDATA_TYPE_DELETE: return param.GetSaveDirName(param.GetPspParam()); case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE: @@ -274,8 +294,6 @@ const std::string PSPSaveDialog::GetSelectedSaveDirName() const case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA: return param.GetSaveDirName(param.GetPspParam()); - // TODO: Maybe also SINGLEDELETE/etc? - // SIZES ignores saveName it seems. default: @@ -882,15 +900,16 @@ int PSPSaveDialog::Update(int animSpeed) DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL); DisplayBanner(DB_DELETE); - if (IsButtonPressed(cancelButtonFlag)) - display = DS_DELETE_LIST_CHOICE; - else if (IsButtonPressed(okButtonFlag)) { - if (yesnoChoice == 0) + if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) { + if(param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE || param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE) display = DS_DELETE_LIST_CHOICE; else { + param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; + StartFade(false); + } + } else if (IsButtonPressed(okButtonFlag)) { display = DS_DELETE_DELETING; StartIOThread(); - } } EndDraw(); @@ -938,8 +957,12 @@ int PSPSaveDialog::Update(int animSpeed) if (IsButtonPressed(cancelButtonFlag)) { if (param.GetFilenameCount() == 0) display = DS_DELETE_NODATA; - else + else if (param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE || param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE) { display = DS_DELETE_LIST_CHOICE; + } else { + param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS; + StartFade(false); + } } EndDraw(); @@ -1058,10 +1081,14 @@ void PSPSaveDialog::ExecuteNotVisibleIOAction() { break; case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA: DEBUG_LOG(SCEUTILITY, "sceUtilitySavedata DELETEDATA: %s", param.GetPspParam()->saveName); - result = param.DeleteData(param.GetPspParam()); + if (param.Delete(param.GetPspParam(), param.GetSelectedSave())) { + result = 0; + } else { + result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; + } break; - //case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE: - case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE: + case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE: + case SCE_UTILITY_SAVEDATA_TYPE_DELETE: if (param.Delete(param.GetPspParam(), param.GetSelectedSave())) { result = 0; } else { @@ -1092,6 +1119,10 @@ void PSPSaveDialog::ExecuteNotVisibleIOAction() { result = SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND; } break; + case SCE_UTILITY_SAVEDATA_TYPE_ERASE: + case SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE: + result = param.DeleteData(param.GetPspParam()); + break; default: break; } diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 46940fb9db..472a51f761 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -343,10 +343,10 @@ bool SavedataParam::Delete(SceUtilitySavedataParam* param, int saveId) { int SavedataParam::DeleteData(SceUtilitySavedataParam* param) { if (!param) { - return SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA; + return SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND; } if (param->fileName[0] == '\0') { - return SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA; + return 0; } std::string subFolder = GetGameName(param) + GetSaveName(param); @@ -359,6 +359,8 @@ int SavedataParam::DeleteData(SceUtilitySavedataParam* param) { PSPFileInfo info = pspFileSystem.GetFileInfo(filename); if (info.exists) { pspFileSystem.RemoveFile(filename); + } else { + return SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND; } return 0; } @@ -1736,6 +1738,8 @@ bool SavedataParam::wouldHasMultiSaveName(SceUtilitySavedataParam* param) { case SCE_UTILITY_SAVEDATA_TYPE_READDATA: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA: + case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE: + case SCE_UTILITY_SAVEDATA_TYPE_DELETE: case SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE: case SCE_UTILITY_SAVEDATA_TYPE_ERASE: case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA: diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h index ba5c442222..33239bae56 100644 --- a/Core/Dialog/SavedataParam.h +++ b/Core/Dialog/SavedataParam.h @@ -39,11 +39,11 @@ enum SceUtilitySavedataType SCE_UTILITY_SAVEDATA_TYPE_SAVE = 3, SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD = 4, SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE = 5, - SCE_UTILITY_SAVEDATA_TYPE_DELETE = 6, - SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE = 7, + SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE = 6, + SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE = 7,// When run on a PSP, displays a list of all saves on the PSP. Weird. (Not really, it's to let you free up space) SCE_UTILITY_SAVEDATA_TYPE_SIZES = 8, SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE = 9, - SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE = 10, + SCE_UTILITY_SAVEDATA_TYPE_DELETE = 10, SCE_UTILITY_SAVEDATA_TYPE_LIST = 11, SCE_UTILITY_SAVEDATA_TYPE_FILES = 12, SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE = 13, From b8c1845e3ab069ff882ef6060dd41a0d5df2175a Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Thu, 1 Oct 2020 10:03:30 +0800 Subject: [PATCH 814/848] Savedata:Supports empty file name for save/load/delete. --- Core/Dialog/SavedataParam.cpp | 62 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 472a51f761..7c5cbaa253 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -507,7 +507,8 @@ int SavedataParam::Save(SceUtilitySavedataParam* param, const std::string &saveD if(param->dataBuf.IsValid()) // Can launch save without save data in mode 13 { - std::string filePath = dirPath+"/"+GetFileName(param); + std::string fileName = GetFileName(param); + std::string filePath = dirPath + "/" + fileName; u8 *data_ = 0; SceSize saveSize = 0; if(cryptedData == 0) // Save decrypted data @@ -529,13 +530,16 @@ int SavedataParam::Save(SceUtilitySavedataParam* param, const std::string &saveD // copy back save name in request strncpy(param->saveName, saveDirName.c_str(), 20); - if (!WritePSPFile(filePath, data_, saveSize)) - { - ERROR_LOG(SCEUTILITY,"Error writing file %s",filePath.c_str()); + if (fileName == "") { delete[] cryptedData; - return SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE; - } - delete[] cryptedData; + } else { + if (!WritePSPFile(filePath, data_, saveSize)) { + ERROR_LOG(SCEUTILITY, "Error writing file %s", filePath.c_str()); + delete[] cryptedData; + return SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE; + } + delete[] cryptedData; + } } @@ -574,14 +578,6 @@ int SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveD } std::string dirPath = GetSaveFilePath(param, GetSaveDir(param, saveDirName)); - std::string filePath = dirPath + "/" + GetFileName(param); - if (!pspFileSystem.GetFileInfo(filePath).exists) { - return SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; - } - - int result = LoadSaveData(param, saveDirName, dirPath, secureMode); - if (result != 0) - return result; LoadSFO(param, dirPath); // Load sfo @@ -599,6 +595,20 @@ int SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveD // Load SND0.AT3 LoadFile(dirPath, SND0_FILENAME, ¶m->snd0FileData); + std::string fileName = GetFileName(param); + if (fileName == "") { + // Don't load savedata but return success. + return 0; + } + std::string filePath = dirPath + "/" + fileName; + if (!pspFileSystem.GetFileInfo(filePath).exists) { + return SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; + } + + int result = LoadSaveData(param, saveDirName, dirPath, secureMode); + if (result != 0) + return result; + return 0; } @@ -1443,19 +1453,15 @@ int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) const std::string thisSaveName = FixedToString(saveNameListData[i], ARRAY_SIZE(saveNameListData[i])); DEBUG_LOG(SCEUTILITY, "Name : %s", thisSaveName.c_str()); - std::string fileDataPath = savePath + GetGameName(param) + thisSaveName + "/" + GetFileName(param); - PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath); - if (info.exists) - { + std::string fileDataDir = savePath + GetGameName(param) + thisSaveName; + PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataDir); + if (info.exists) { SetFileInfo(realCount, info, thisSaveName); - DEBUG_LOG(SCEUTILITY,"%s Exist",fileDataPath.c_str()); + DEBUG_LOG(SCEUTILITY,"%s Exist",fileDataDir.c_str()); realCount++; - } - else - { - if (listEmptyFile) - { + } else { + if (listEmptyFile) { ClearFileInfo(saveDataList[realCount], thisSaveName); DEBUG_LOG(SCEUTILITY,"Don't Exist"); realCount++; @@ -1476,13 +1482,13 @@ int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) // get and stock file info for each file DEBUG_LOG(SCEUTILITY,"Name : %s",GetSaveName(param).c_str()); - std::string fileDataPath = savePath + GetGameName(param) + GetSaveName(param) + "/" + GetFileName(param); - PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataPath); + std::string fileDataDir = savePath + GetGameName(param) + GetSaveName(param); + PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataDir); if (info.exists) { SetFileInfo(0, info, GetSaveName(param)); - DEBUG_LOG(SCEUTILITY,"%s Exist",fileDataPath.c_str()); + DEBUG_LOG(SCEUTILITY,"%s Exist",fileDataDir.c_str()); saveNameListDataCount = 1; } else From 15382d5f94e7fa957514e6bbce9fc52585b11ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 1 Oct 2020 09:27:25 +0200 Subject: [PATCH 815/848] Move threading utils from native to Common --- CMakeLists.txt | 16 +++++----- Common/Common.vcxproj | 10 ++++++- Common/Common.vcxproj.filters | 29 ++++++++++++++++++- Common/ConsoleListener.cpp | 2 +- Common/ExceptionHandlerSetup.cpp | 5 ++-- .../Thread/Executor.cpp | 2 +- .../executor.h => Common/Thread/Executor.h | 0 .../Thread/PrioritizedWorkQueue.cpp | 2 +- .../Thread/PrioritizedWorkQueue.h | 2 +- .../Thread/ThreadPool.cpp | 4 +-- .../Thread/ThreadPool.h | 0 .../Thread/ThreadUtil.cpp | 3 +- .../Thread/ThreadUtil.h | 0 Common/ThreadPools.h | 2 +- Core/Core.cpp | 2 +- Core/Debugger/WebSocket.cpp | 2 +- Core/Dialog/PSPSaveDialog.cpp | 2 +- Core/FileLoaders/CachingFileLoader.cpp | 2 +- Core/FileLoaders/RamCachingFileLoader.cpp | 2 +- Core/HLE/proAdhoc.cpp | 2 +- Core/HLE/proAdhocServer.cpp | 2 +- Core/HLE/sceIo.cpp | 2 +- Core/HLE/sceNetAdhoc.cpp | 2 +- Core/HLE/sceSas.cpp | 2 +- Core/HW/Camera.h | 2 +- Core/PSPLoaders.cpp | 2 +- Core/Reporting.cpp | 2 +- Core/SaveState.cpp | 2 +- Core/System.cpp | 2 +- Core/Util/PortManager.cpp | 2 +- Core/WebServer.cpp | 2 +- Qt/QtMain.cpp | 2 +- SDL/SDLMain.cpp | 2 +- UI/GameInfoCache.cpp | 2 +- UI/SavedataScreen.cpp | 2 +- UWP/NativeUWP/NativeUWP.vcxproj | 10 +------ UWP/NativeUWP/NativeUWP.vcxproj.filters | 26 +---------------- UWP/PPSSPP_UWPMain.cpp | 2 +- UWP/StorageFileLoader.cpp | 2 +- UWP/StorageFolderBrowser.cpp | 2 +- UWP/XAudioSoundStream.cpp | 2 +- Windows/CaptureDevice.cpp | 2 +- Windows/DSoundStream.cpp | 2 +- Windows/EmuThread.cpp | 2 +- Windows/InputDevice.cpp | 2 +- Windows/MainWindow.cpp | 2 +- Windows/WASAPIStream.cpp | 2 +- Windows/main.cpp | 2 +- android/jni/Android.mk | 4 +++ android/jni/app-android.cpp | 2 +- ext/native/Android.mk | 4 --- ext/native/file/path.cpp | 2 +- ext/native/native.vcxproj | 8 ----- ext/native/native.vcxproj.filters | 27 ----------------- ext/native/net/http_client.cpp | 2 +- ext/native/net/http_server.cpp | 2 +- ext/native/net/http_server.h | 2 +- ext/native/thin3d/GLRenderManager.cpp | 2 +- ext/native/thin3d/VulkanRenderManager.cpp | 2 +- libretro/Makefile.common | 7 +++-- libretro/libretro.cpp | 2 +- 61 files changed, 105 insertions(+), 138 deletions(-) rename ext/native/thread/executor.cpp => Common/Thread/Executor.cpp (91%) rename ext/native/thread/executor.h => Common/Thread/Executor.h (100%) rename ext/native/thread/prioritizedworkqueue.cpp => Common/Thread/PrioritizedWorkQueue.cpp (98%) rename ext/native/thread/prioritizedworkqueue.h => Common/Thread/PrioritizedWorkQueue.h (97%) rename ext/native/thread/threadpool.cpp => Common/Thread/ThreadPool.cpp (97%) rename ext/native/thread/threadpool.h => Common/Thread/ThreadPool.h (100%) rename ext/native/thread/threadutil.cpp => Common/Thread/ThreadUtil.cpp (98%) rename ext/native/thread/threadutil.h => Common/Thread/ThreadUtil.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c323f8885b..568dbb1f51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,6 +433,14 @@ add_library(Common STATIC Common/Crypto/sha1.h Common/Crypto/sha256.cpp Common/Crypto/sha256.h + Common/Thread/Executor.cpp + Common/Thread/Executor.h + Common/Thread/PrioritizedWorkQueue.cpp + Common/Thread/PrioritizedWorkQueue.h + Common/Thread/ThreadUtil.cpp + Common/Thread/ThreadUtil.h + Common/Thread/ThreadPool.cpp + Common/Thread/ThreadPool.h Common/BitScan.h Common/BitSet.h Common/Buffer.h @@ -1045,14 +1053,6 @@ add_library(native STATIC ext/native/thin3d/thin3d.h ext/native/thin3d/thin3d_create.h ${THIN3D_PLATFORMS} - ext/native/thread/executor.cpp - ext/native/thread/executor.h - ext/native/thread/prioritizedworkqueue.cpp - ext/native/thread/prioritizedworkqueue.h - ext/native/thread/threadutil.cpp - ext/native/thread/threadutil.h - ext/native/thread/threadpool.cpp - ext/native/thread/threadpool.h ext/native/ui/root.cpp ext/native/ui/root.h ext/native/ui/screen.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index aceea2b7fc..d631d484a8 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -420,6 +420,10 @@ + + + + @@ -659,6 +663,10 @@ + + + + @@ -681,4 +689,4 @@ - + \ No newline at end of file diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 1322c5858d..a021e84b0c 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -116,6 +116,18 @@ ext\libpng17 + + Thread + + + Thread + + + Thread + + + Thread + @@ -231,6 +243,18 @@ ext\libpng17 + + Thread + + + Thread + + + Thread + + + Thread + @@ -254,10 +278,13 @@ {1d04f87f-73a2-4027-a6ff-e998e92e7d3c} + + {41bcd391-8641-432c-ae4a-ab03812df762} + ext\libpng17 - + \ No newline at end of file diff --git a/Common/ConsoleListener.cpp b/Common/ConsoleListener.cpp index da44073795..ce3cc1f1b7 100644 --- a/Common/ConsoleListener.cpp +++ b/Common/ConsoleListener.cpp @@ -32,7 +32,7 @@ #endif #include "ppsspp_config.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "util/text/utf8.h" #include "Common/Common.h" #include "Common/ConsoleListener.h" diff --git a/Common/ExceptionHandlerSetup.cpp b/Common/ExceptionHandlerSetup.cpp index 0b8f8ac7f0..8232b4ba9e 100644 --- a/Common/ExceptionHandlerSetup.cpp +++ b/Common/ExceptionHandlerSetup.cpp @@ -6,7 +6,6 @@ #include "ppsspp_config.h" -#include "Common/ExceptionHandlerSetup.h" #include #include #include @@ -16,9 +15,9 @@ #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" #include "Common/Log.h" -#include "ext/native/thread/threadutil.h" - +#include "Common/Thread/ThreadUtil.h" #include "Common/MachineContext.h" +#include "Common/ExceptionHandlerSetup.h" static BadAccessHandler g_badAccessHandler; static void *altStack = nullptr; diff --git a/ext/native/thread/executor.cpp b/Common/Thread/Executor.cpp similarity index 91% rename from ext/native/thread/executor.cpp rename to Common/Thread/Executor.cpp index 0ae2b41b64..6f9c689103 100644 --- a/ext/native/thread/executor.cpp +++ b/Common/Thread/Executor.cpp @@ -1,4 +1,4 @@ -#include "thread/executor.h" +#include "Common/Thread/Executor.h" #include #include diff --git a/ext/native/thread/executor.h b/Common/Thread/Executor.h similarity index 100% rename from ext/native/thread/executor.h rename to Common/Thread/Executor.h diff --git a/ext/native/thread/prioritizedworkqueue.cpp b/Common/Thread/PrioritizedWorkQueue.cpp similarity index 98% rename from ext/native/thread/prioritizedworkqueue.cpp rename to Common/Thread/PrioritizedWorkQueue.cpp index 24a51c7c70..d80ad80c41 100644 --- a/ext/native/thread/prioritizedworkqueue.cpp +++ b/Common/Thread/PrioritizedWorkQueue.cpp @@ -2,7 +2,7 @@ #include #include "Common/TimeUtil.h" -#include "thread/prioritizedworkqueue.h" +#include "Common/Thread/PrioritizedWorkQueue.h" #include "Common/Log.h" diff --git a/ext/native/thread/prioritizedworkqueue.h b/Common/Thread/PrioritizedWorkQueue.h similarity index 97% rename from ext/native/thread/prioritizedworkqueue.h rename to Common/Thread/PrioritizedWorkQueue.h index 83848d2c65..59231f48b1 100644 --- a/ext/native/thread/prioritizedworkqueue.h +++ b/Common/Thread/PrioritizedWorkQueue.h @@ -5,7 +5,7 @@ #include #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/Common.h" diff --git a/ext/native/thread/threadpool.cpp b/Common/Thread/ThreadPool.cpp similarity index 97% rename from ext/native/thread/threadpool.cpp rename to Common/Thread/ThreadPool.cpp index 6f5a83d255..e64d1c8786 100644 --- a/ext/native/thread/threadpool.cpp +++ b/Common/Thread/ThreadPool.cpp @@ -1,5 +1,5 @@ -#include "thread/threadpool.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadPool.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" #include "Common/MakeUnique.h" diff --git a/ext/native/thread/threadpool.h b/Common/Thread/ThreadPool.h similarity index 100% rename from ext/native/thread/threadpool.h rename to Common/Thread/ThreadPool.h diff --git a/ext/native/thread/threadutil.cpp b/Common/Thread/ThreadUtil.cpp similarity index 98% rename from ext/native/thread/threadutil.cpp rename to Common/Thread/ThreadUtil.cpp index 8b9d32bc52..b7c807e61b 100644 --- a/ext/native/thread/threadutil.cpp +++ b/Common/Thread/ThreadUtil.cpp @@ -11,9 +11,8 @@ #include #include -#include "thread/threadutil.h" - #include "Common/Log.h" +#include "Common/Thread/ThreadUtil.h" #if defined(__ANDROID__) || defined(__APPLE__) || (defined(__GLIBC__) && defined(_GNU_SOURCE)) #include diff --git a/ext/native/thread/threadutil.h b/Common/Thread/ThreadUtil.h similarity index 100% rename from ext/native/thread/threadutil.h rename to Common/Thread/ThreadUtil.h diff --git a/Common/ThreadPools.h b/Common/ThreadPools.h index e04303a9d2..350d56da1e 100644 --- a/Common/ThreadPools.h +++ b/Common/ThreadPools.h @@ -1,6 +1,6 @@ #pragma once -#include "thread/threadpool.h" +#include "Common/Thread/ThreadPool.h" class GlobalThreadPool { public: diff --git a/Core/Core.cpp b/Core/Core.cpp index 5e1ad904b1..73d9ea35a2 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -25,7 +25,7 @@ #include "base/NativeApp.h" #include "base/display.h" #include "Common/TimeUtil.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "profiler/profiler.h" #include "Common/GraphicsContext.h" diff --git a/Core/Debugger/WebSocket.cpp b/Core/Debugger/WebSocket.cpp index 62d1879cda..418c81188d 100644 --- a/Core/Debugger/WebSocket.cpp +++ b/Core/Debugger/WebSocket.cpp @@ -17,7 +17,7 @@ #include #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Core/Debugger/WebSocket.h" #include "Core/Debugger/WebSocket/WebSocketUtils.h" #include "Core/MemMap.h" diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 8328ae34f5..637ddfdff4 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -22,7 +22,7 @@ #include #include "i18n/i18n.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/FileLoaders/CachingFileLoader.cpp b/Core/FileLoaders/CachingFileLoader.cpp index 4902af5a33..c4029d01e5 100644 --- a/Core/FileLoaders/CachingFileLoader.cpp +++ b/Core/FileLoaders/CachingFileLoader.cpp @@ -19,7 +19,7 @@ #include #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/TimeUtil.h" #include "Core/FileLoaders/CachingFileLoader.h" diff --git a/Core/FileLoaders/RamCachingFileLoader.cpp b/Core/FileLoaders/RamCachingFileLoader.cpp index e575b21b72..73e0151b91 100644 --- a/Core/FileLoaders/RamCachingFileLoader.cpp +++ b/Core/FileLoaders/RamCachingFileLoader.cpp @@ -20,7 +20,7 @@ #include #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/TimeUtil.h" #include "Core/FileLoaders/RamCachingFileLoader.h" diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index a93a64656e..4c39013bf5 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -38,7 +38,7 @@ #include #include "i18n/i18n.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "util/text/parsers.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 32fea38db0..a345ab0b50 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -50,7 +50,7 @@ #endif #include "i18n/i18n.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/FileUtil.h" #include "Common/TimeUtil.h" diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 9fd546d131..4f1185fffd 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -19,7 +19,7 @@ #include #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "profiler/profiler.h" #include "Common/FileUtil.h" diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 0645f4c707..614b9f1d1b 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -29,7 +29,7 @@ #endif #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" // sceNetAdhoc // This is a direct port of Coldbird's code from http://code.google.com/p/aemu/ diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index 285fee2b37..5205c9d22d 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -33,7 +33,7 @@ #include #include "profiler/profiler.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Log.h" #include "Core/Config.h" diff --git a/Core/HW/Camera.h b/Core/HW/Camera.h index 4e36fbd296..c23290915f 100644 --- a/Core/HW/Camera.h +++ b/Core/HW/Camera.h @@ -57,7 +57,7 @@ void __cameraDummyImage(int width, int height, unsigned char** outData, int* out #include #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" typedef struct { void *start; diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 53bdc35722..26ad3572ec 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -19,7 +19,7 @@ #include "file/file_util.h" #include "util/text/utf8.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 6d6e364834..86d73612ed 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -48,7 +48,7 @@ #include "net/resolve.h" #include "net/url.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "file/zip_read.h" namespace Reporting diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 26c4a6f512..a2ed973231 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -21,7 +21,7 @@ #include #include "i18n/i18n.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "util/text/parsers.h" #include "Common/FileUtil.h" diff --git a/Core/System.cpp b/Core/System.cpp index ebf3eaaaa2..ceaf38c076 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -34,7 +34,7 @@ #include "base/NativeApp.h" #include "math/math_util.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "util/text/utf8.h" #include "Common/FileUtil.h" diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index bc6b18ace2..0e2fb75c28 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -32,7 +32,7 @@ #include "Common/TimeUtil.h" #include "i18n/i18n.h" #include "net/resolve.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" #include "Core/System.h" #include "Core/Host.h" diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index 222ab247de..ce7519a47c 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -23,7 +23,7 @@ #include "net/http_client.h" #include "net/http_server.h" #include "net/sinks.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" #include "Common/FileUtil.h" #include "Common/TimeUtil.h" diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 2ba3a2e630..0010db1920 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -34,7 +34,7 @@ #include "gfx_es2/gpu_features.h" #include "i18n/i18n.h" #include "math/math_util.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "util/text/utf8.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 22a5fa9524..348162d9d3 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -32,7 +32,7 @@ SDLJoystick *joystick = NULL; #include "util/text/utf8.h" #include "math/math_util.h" #include "thin3d/GLRenderManager.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "math.h" #include "SDL_syswm.h" diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 807448c8ad..08699e24c1 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -25,7 +25,7 @@ #include "file/file_util.h" #include "file/zip_read.h" #include "thin3d/thin3d.h" -#include "thread/prioritizedworkqueue.h" +#include "Common/Thread/PrioritizedWorkQueue.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 9714b689a0..bb28391c79 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -22,7 +22,7 @@ #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" #include "math/curves.h" -#include "thread/prioritizedworkqueue.h" +#include "Common/Thread/PrioritizedWorkQueue.h" #include "util/text/utf8.h" #include "ui/ui_context.h" #include "ui/view.h" diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 54654bc7cc..808814c28c 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -423,10 +423,6 @@ - - - - @@ -599,10 +595,6 @@ - - - - @@ -638,4 +630,4 @@ - \ No newline at end of file + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 7b5e91cae6..cd0b7803cb 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -55,18 +55,6 @@ thin3d - - thread - - - thread - - - thread - - - thread - util @@ -226,18 +214,6 @@ thin3d - - thread - - - thread - - - thread - - - thread - util @@ -403,4 +379,4 @@ gfx - \ No newline at end of file + diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 4915c4ffa3..8777ced8a7 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -11,7 +11,7 @@ #include "net/http_client.h" #include "net/resolve.h" #include "base/display.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "thin3d/thin3d_create.h" #include "util/text/utf8.h" diff --git a/UWP/StorageFileLoader.cpp b/UWP/StorageFileLoader.cpp index dcdbdcff76..2797e9fe2c 100644 --- a/UWP/StorageFileLoader.cpp +++ b/UWP/StorageFileLoader.cpp @@ -1,7 +1,7 @@ #include "pch.h" #include "ppltasks.h" #include "file/file_util.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "StorageFileLoader.h" #include "Common/Log.h" #include "UWPUtil.h" diff --git a/UWP/StorageFolderBrowser.cpp b/UWP/StorageFolderBrowser.cpp index 3744b3e6dd..4e86ed079f 100644 --- a/UWP/StorageFolderBrowser.cpp +++ b/UWP/StorageFolderBrowser.cpp @@ -1,7 +1,7 @@ #include "pch.h" #include "ppltasks.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "StorageFolderBrowser.h" #include "UWPUtil.h" diff --git a/UWP/XAudioSoundStream.cpp b/UWP/XAudioSoundStream.cpp index 8932b298a0..fa4bc4dd29 100644 --- a/UWP/XAudioSoundStream.cpp +++ b/UWP/XAudioSoundStream.cpp @@ -3,7 +3,7 @@ #include #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "XAudioSoundStream.h" #include diff --git a/Windows/CaptureDevice.cpp b/Windows/CaptureDevice.cpp index a475901137..f697670992 100644 --- a/Windows/CaptureDevice.cpp +++ b/Windows/CaptureDevice.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "CaptureDevice.h" #include "BufferLock.h" #include "ext/jpge/jpge.h" diff --git a/Windows/DSoundStream.cpp b/Windows/DSoundStream.cpp index 89111c8067..bd375d025e 100644 --- a/Windows/DSoundStream.cpp +++ b/Windows/DSoundStream.cpp @@ -10,7 +10,7 @@ #undef __null #endif -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" #include "Common/OSVersion.h" #include "Core/ConfigValues.h" diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 32af670d4a..80ac516978 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -23,7 +23,7 @@ #include "Core/System.h" #include "Core/Config.h" #include "Core/ConfigValues.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" enum class EmuThreadState { DISABLED, diff --git a/Windows/InputDevice.cpp b/Windows/InputDevice.cpp index 70d4a6ff48..57b571bce3 100644 --- a/Windows/InputDevice.cpp +++ b/Windows/InputDevice.cpp @@ -20,7 +20,7 @@ #include #include "input/input_state.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Core/Config.h" #include "Core/Host.h" #include "Windows/InputDevice.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 14fc10cdf8..fe1d1ee828 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -39,7 +39,7 @@ #include "i18n/i18n.h" #include "input/input_state.h" #include "input/keycodes.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "util/text/utf8.h" #include "Core/Core.h" diff --git a/Windows/WASAPIStream.cpp b/Windows/WASAPIStream.cpp index 17be143334..9e11d558c5 100644 --- a/Windows/WASAPIStream.cpp +++ b/Windows/WASAPIStream.cpp @@ -6,7 +6,7 @@ #include "Core/Reporting.h" #include "Core/Util/AudioFormat.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include #include diff --git a/Windows/main.cpp b/Windows/main.cpp index 2fdfc565d8..04713ef2e9 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -37,7 +37,7 @@ #include "file/zip_read.h" #include "i18n/i18n.h" #include "profiler/profiler.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "util/text/utf8.h" #include "net/resolve.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 4e5d42436a..bb51dbe08b 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -233,6 +233,10 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Crypto/md5.cpp \ $(SRC)/Common/Crypto/sha1.cpp \ $(SRC)/Common/Crypto/sha256.cpp \ + $(SRC)/Common/Thread/Executor.cpp \ + $(SRC)/Common/Thread/PrioritizedWorkQueue.cpp \ + $(SRC)/Common/Thread/ThreadPool.cpp \ + $(SRC)/Common/Thread/ThreadUtil.cpp \ $(SRC)/Common/Serialize/Serializer.cpp \ $(SRC)/Common/ColorConv.cpp \ $(SRC)/Common/ExceptionHandlerSetup.cpp \ diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 7204b85aed..b665eedee3 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -51,7 +51,7 @@ struct JNIEnv {}; #include "base/display.h" #include "base/NativeApp.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "file/zip_read.h" #include "input/input_state.h" #include "input/keycodes.h" diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 44fe5405b4..59a328aa0d 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -39,10 +39,6 @@ LOCAL_SRC_FILES :=\ net/url.cpp \ net/websocket_server.cpp \ profiler/profiler.cpp \ - thread/executor.cpp \ - thread/threadutil.cpp \ - thread/prioritizedworkqueue.cpp \ - thread/threadpool.cpp \ gfx_es2/glsl_program.cpp \ gfx_es2/gpu_features.cpp \ gfx_es2/gl3stub.c \ diff --git a/ext/native/file/path.cpp b/ext/native/file/path.cpp index 5be7b326c4..e7be80c609 100644 --- a/ext/native/file/path.cpp +++ b/ext/native/file/path.cpp @@ -8,7 +8,7 @@ #include "file/path.h" #include "net/http_client.h" #include "net/url.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" bool LoadRemoteFileList(const std::string &url, bool *cancel, std::vector &files) { http::Client http; diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index a55298b1f6..5395a1ffc2 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -446,10 +446,6 @@ - - - - @@ -562,10 +558,6 @@ - - - - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 059d1df547..f06b11c078 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -119,21 +119,12 @@ util - - thread - - - thread - i18n file - - thread - ui @@ -188,9 +179,6 @@ net - - thread - gfx @@ -361,21 +349,12 @@ util - - thread - - - thread - i18n file - - thread - ui @@ -436,9 +415,6 @@ net - - thread - base @@ -558,9 +534,6 @@ {4515306f-4664-46bf-a89b-abfec5520a15} - - {caa41117-1d90-47cc-9fba-f7e670e315a3} - {02e8ef95-82c7-4420-b029-a189a5e0fcbd} diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index 24d93ed0c3..f5a80ec17f 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -24,7 +24,7 @@ #include "file/fd_util.h" #include "net/resolve.h" #include "net/url.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/Buffer.h" #include "Common/Log.h" diff --git a/ext/native/net/http_server.cpp b/ext/native/net/http_server.cpp index 738b536f87..5569923cd3 100644 --- a/ext/native/net/http_server.cpp +++ b/ext/native/net/http_server.cpp @@ -37,7 +37,7 @@ #include "file/fd_util.h" #include "net/http_server.h" #include "net/sinks.h" -#include "thread/executor.h" +#include "Common/Thread/Executor.h" #include "Common/Buffer.h" #include "Common/Log.h" diff --git a/ext/native/net/http_server.h b/ext/native/net/http_server.h index 5a8151b77d..7102f963b2 100644 --- a/ext/native/net/http_server.h +++ b/ext/native/net/http_server.h @@ -5,7 +5,7 @@ #include "net/http_headers.h" #include "net/resolve.h" -#include "thread/executor.h" +#include "Common/Thread/Executor.h" namespace net { class InputSink; diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index bc2e9a9a3c..1aa1d25949 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -1,7 +1,7 @@ #include "GLRenderManager.h" #include "gfx_es2/gpu_features.h" #include "thin3d/thin3d.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" #include "Common/MemoryUtil.h" diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index e929b89018..ecd776b2a7 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -8,7 +8,7 @@ #include "Common/Vulkan/VulkanContext.h" #include "thin3d/VulkanRenderManager.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #if 0 // def _DEBUG #define VLOG(...) INFO_LOG(G3D, __VA_ARGS__) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index c6d808017e..dfb91b445c 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -144,6 +144,10 @@ SOURCES_CXX += \ SOURCES_CXX += \ $(COMMONDIR)/Serialize/Serializer.cpp \ + $(COMMONDIR)/Thread/Executor.cpp \ + $(COMMONDIR)/Thread/ThreadUtil.cpp \ + $(COMMONDIR)/Thread/ThreadPool.cpp \ + $(COMMONDIR)/Thread/PrioritizedWorkQueue.cpp \ $(COMMONDIR)/Buffer.cpp \ $(COMMONDIR)/ConsoleListener.cpp \ $(COMMONDIR)/ExceptionHandlerSetup.cpp \ @@ -309,9 +313,6 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/thin3d/GLRenderManager.cpp \ $(NATIVEDIR)/thin3d/GLQueueRunner.cpp \ $(NATIVEDIR)/thin3d/DataFormatGL.cpp \ - $(NATIVEDIR)/thread/threadutil.cpp \ - $(NATIVEDIR)/thread/threadpool.cpp \ - $(NATIVEDIR)/thread/prioritizedworkqueue.cpp \ $(NATIVEDIR)/ui/root.cpp \ $(NATIVEDIR)/ui/screen.cpp \ $(NATIVEDIR)/ui/ui.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 13f4f2c8a4..6f5ba59245 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -29,7 +29,7 @@ #include "GPU/Common/TextureScalerCommon.h" #include "input/input_state.h" #include "base/NativeApp.h" -#include "thread/threadutil.h" +#include "Common/Thread/ThreadUtil.h" #include "libretro/libretro.h" #include "libretro/LibretroGraphicsContext.h" From c84f9542d782803a8b7f32d7a04b61ec7ec76735 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Thu, 1 Oct 2020 15:41:27 +0800 Subject: [PATCH 816/848] Savedata:Corrects the performances when the data is broken. --- Core/Dialog/PSPSaveDialog.cpp | 41 ++++++++++------- Core/Dialog/PSPSaveDialog.h | 1 + Core/Dialog/SavedataParam.cpp | 86 ++++++++++++++++++++++++++--------- Core/Dialog/SavedataParam.h | 4 +- 4 files changed, 94 insertions(+), 38 deletions(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 9385da9832..a5159e1c0c 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -136,9 +136,14 @@ int PSPSaveDialog::Init(int paramAddr) { case SCE_UTILITY_SAVEDATA_TYPE_LOAD: DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); - if (param.GetFileInfo(0).size != 0) - display = DS_LOAD_CONFIRM; - else + if (param.GetFileInfo(0).size != 0) { + if (param.GetFileInfo(0).broken) { + param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN; + display = DS_LOAD_FAILED; + } else { + display = DS_LOAD_CONFIRM; + } + } else display = DS_LOAD_NODATA; break; case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: @@ -461,7 +466,11 @@ void PSPSaveDialog::DisplaySaveDataInfo1() { std::lock_guard guard(paramLock); const SaveFileInfo &saveInfo = param.GetFileInfo(currentSelectedSave); - if (saveInfo.size == 0) { + if (saveInfo.broken) { + auto di = GetI18NCategory("Dialog"); + PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f); + PPGeDrawText(di->T("Corrupted Data"), 180, 136, textStyle); + } else if (saveInfo.size == 0) { auto di = GetI18NCategory("Dialog"); PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f); PPGeDrawText(di->T("NEW DATA"), 180, 136, textStyle); @@ -811,7 +820,7 @@ int PSPSaveDialog::Update(int animSpeed) DisplaySaveIcon(true); DisplaySaveDataInfo2(); - DisplayMessage(di->T("LoadingFailed", "Unable to load data.")); + DisplayMessage(di->T("LoadingFailed", "Load failed\nThe data is corrupted.")); DisplayButtons(DS_BUTTON_CANCEL); DisplayBanner(DB_LOAD); @@ -821,7 +830,6 @@ int PSPSaveDialog::Update(int animSpeed) if (param.GetPspParam()->mode != SCE_UTILITY_SAVEDATA_TYPE_LOAD) { display = DS_LOAD_LIST_CHOICE; } else { - param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; StartFade(false); } } @@ -937,7 +945,10 @@ int PSPSaveDialog::Update(int animSpeed) DisplayBanner(DB_DELETE); if (IsButtonPressed(cancelButtonFlag)) { - display = DS_DELETE_LIST_CHOICE; + if (param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE || param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE) + display = DS_DELETE_LIST_CHOICE; + else + StartFade(false); } EndDraw(); @@ -1009,10 +1020,12 @@ int PSPSaveDialog::Update(int animSpeed) } void PSPSaveDialog::ExecuteIOAction() { + auto &result = param.GetPspParam()->common.result; std::lock_guard guard(paramLock); switch (display) { case DS_LOAD_LOADING: - if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave) == 0) { + result = param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave); + if (result == 0) { display = DS_LOAD_DONE; } else { display = DS_LOAD_FAILED; @@ -1027,8 +1040,10 @@ void PSPSaveDialog::ExecuteIOAction() { break; case DS_DELETE_DELETING: if (param.Delete(param.GetPspParam(),currentSelectedSave)) { + result = 0; display = DS_DELETE_DONE; } else { + //result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA;// What the result should be? display = DS_DELETE_FAILED; } break; @@ -1109,15 +1124,9 @@ void PSPSaveDialog::ExecuteNotVisibleIOAction() { break; case SCE_UTILITY_SAVEDATA_TYPE_READDATA: case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE: - if (!param.IsSaveDirectoryExist(param.GetPspParam())){ + result = param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE); + if(result == SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA) result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; - } else if (!param.IsSfoFileExist(param.GetPspParam())) { - result = SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN; - } else if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE) == 0) { - result = 0; - } else { - result = SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND; - } break; case SCE_UTILITY_SAVEDATA_TYPE_ERASE: case SCE_UTILITY_SAVEDATA_TYPE_ERASESECURE: diff --git a/Core/Dialog/PSPSaveDialog.h b/Core/Dialog/PSPSaveDialog.h index 888cc63d6e..fd1efa88d5 100644 --- a/Core/Dialog/PSPSaveDialog.h +++ b/Core/Dialog/PSPSaveDialog.h @@ -31,6 +31,7 @@ #define SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN (0x80110306) #define SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA (0x80110307) #define SCE_UTILITY_SAVEDATA_ERROR_LOAD_PARAM (0x80110308) +#define SCE_UTILITY_SAVEDATA_ERROR_LOAD_FILE_NOT_FOUND (0x80110309) #define SCE_UTILITY_SAVEDATA_ERROR_LOAD_INTERNAL (0x8011030b) #define SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK (0x80110321) diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 7c5cbaa253..783b4770a0 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -341,27 +341,39 @@ bool SavedataParam::Delete(SceUtilitySavedataParam* param, int saveId) { return true; } -int SavedataParam::DeleteData(SceUtilitySavedataParam* param) { +int SavedataParam::DeleteData(SceUtilitySavedataParam* param) { if (!param) { return SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND; } - if (param->fileName[0] == '\0') { - return 0; - } std::string subFolder = GetGameName(param) + GetSaveName(param); - std::string filename = savePath + subFolder + "/" + GetFileName(param); - if (!subFolder.size()) { - ERROR_LOG(SCEUTILITY, "Bad subfolder, ignoring delete of %s", filename.c_str()); + std::string fileName = GetFileName(param); + std::string dirPath = savePath + subFolder; + std::string filePath = dirPath + "/" + fileName; + std::string sfoPath = dirPath + "/" + SFO_FILENAME; + + if (!pspFileSystem.GetFileInfo(dirPath).exists) { + return SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; + } + + if (!pspFileSystem.GetFileInfo(sfoPath).exists) + return SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN; + + if (fileName != "" && !pspFileSystem.GetFileInfo(filePath).exists) { + return SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND; + } + + if (fileName == "") { return 0; } - PSPFileInfo info = pspFileSystem.GetFileInfo(filename); - if (info.exists) { - pspFileSystem.RemoveFile(filename); - } else { - return SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND; + if (!subFolder.size()) { + ERROR_LOG(SCEUTILITY, "Bad subfolder, ignoring delete of %s", filePath.c_str()); + return 0; } + + pspFileSystem.RemoveFile(filePath); + return 0; } @@ -577,7 +589,23 @@ int SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveD return SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; } + bool isRWMode = param->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATA || param->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE; + std::string dirPath = GetSaveFilePath(param, GetSaveDir(param, saveDirName)); + std::string fileName = GetFileName(param); + std::string filePath = dirPath + "/" + fileName; + std::string sfoPath = dirPath + "/" + SFO_FILENAME; + + if (!pspFileSystem.GetFileInfo(dirPath).exists) { + return isRWMode ? SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA : SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; + } + + if (!pspFileSystem.GetFileInfo(sfoPath).exists) + return isRWMode ? SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN : SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN; + + if (fileName != "" && !pspFileSystem.GetFileInfo(filePath).exists) { + return isRWMode ? SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND : SCE_UTILITY_SAVEDATA_ERROR_LOAD_FILE_NOT_FOUND; + } LoadSFO(param, dirPath); // Load sfo @@ -595,15 +623,10 @@ int SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveD // Load SND0.AT3 LoadFile(dirPath, SND0_FILENAME, ¶m->snd0FileData); - std::string fileName = GetFileName(param); if (fileName == "") { // Don't load savedata but return success. return 0; } - std::string filePath = dirPath + "/" + fileName; - if (!pspFileSystem.GetFileInfo(filePath).exists) { - return SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; - } int result = LoadSaveData(param, saveDirName, dirPath, secureMode); if (result != 0) @@ -1456,6 +1479,16 @@ int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) std::string fileDataDir = savePath + GetGameName(param) + thisSaveName; PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataDir); if (info.exists) { + auto allFiles = pspFileSystem.GetDirListing(fileDataDir); + bool firstFile = true; + for (auto file : allFiles) { + if (firstFile) { + // Use a file in save directory to determine the directory info. + info = file; + firstFile = false; + } else + info.size += file.size; + } SetFileInfo(realCount, info, thisSaveName); DEBUG_LOG(SCEUTILITY,"%s Exist",fileDataDir.c_str()); @@ -1486,6 +1519,16 @@ int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataDir); if (info.exists) { + auto allFiles = pspFileSystem.GetDirListing(fileDataDir); + bool firstFile = true; + for (auto file : allFiles) { + if (firstFile) { + // Use a file in save directory to determine the directory info. + info = file; + firstFile = false; + } else + info.size += file.size; + } SetFileInfo(0, info, GetSaveName(param)); DEBUG_LOG(SCEUTILITY,"%s Exist",fileDataDir.c_str()); @@ -1533,17 +1576,17 @@ void SavedataParam::SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, std:: // Load info in PARAM.SFO fileDataPath2 = savePath + GetGameName(pspParam) + saveName + "/" + SFO_FILENAME; info2 = pspFileSystem.GetFileInfo(fileDataPath2); - if (info2.exists) - { + if (info2.exists) { std::vector sfoData; pspFileSystem.ReadEntireFile(fileDataPath2, sfoData); ParamSFOData sfoFile; - if (sfoFile.ReadSFO(sfoData)) - { + if (sfoFile.ReadSFO(sfoData)) { SetStringFromSFO(sfoFile, "TITLE", saveInfo.title, sizeof(saveInfo.title)); SetStringFromSFO(sfoFile, "SAVEDATA_TITLE", saveInfo.saveTitle, sizeof(saveInfo.saveTitle)); SetStringFromSFO(sfoFile, "SAVEDATA_DETAIL", saveInfo.saveDetail, sizeof(saveInfo.saveDetail)); } + } else { + saveInfo.broken = true; } } @@ -1557,6 +1600,7 @@ void SavedataParam::ClearFileInfo(SaveFileInfo &saveInfo, const std::string &sav saveInfo.size = 0; saveInfo.saveName = saveName; saveInfo.idx = 0; + saveInfo.broken = false; if (saveInfo.texture != NULL) { if (!noSaveIcon || saveInfo.texture != noSaveIcon->texture) { delete saveInfo.texture; diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h index 33239bae56..af00261a40 100644 --- a/Core/Dialog/SavedataParam.h +++ b/Core/Dialog/SavedataParam.h @@ -279,11 +279,13 @@ struct SaveFileInfo char saveTitle[128]; char saveDetail[1024]; + bool broken; + tm modif_time; PPGeImage *texture; - SaveFileInfo() : size(0), saveName(""), idx(0), texture(NULL) + SaveFileInfo() : size(0), saveName(""), idx(0), texture(NULL), broken(false) { memset(title, 0, 128); memset(saveTitle, 0, 128); From 342ed97291eacc4c01626ba11c6b6c3a1cfee3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 1 Oct 2020 09:36:43 +0200 Subject: [PATCH 817/848] Move input utilities from native to Common/Input. --- CMakeLists.txt | 10 ++--- Common/Common.vcxproj | 5 +++ Common/Common.vcxproj.filters | 18 ++++++++ .../Input/GestureDetector.cpp | 2 +- .../Input/GestureDetector.h | 2 +- .../Input/InputState.cpp | 4 +- .../Input/InputState.h | 2 +- .../keycodes.h => Common/Input/KeyCodes.h | 0 Common/KeyMap.cpp | 2 +- Common/KeyMap.h | 4 +- Qt/QtMain.h | 4 +- SDL/SDLJoystick.h | 4 +- SDL/SDLMain.cpp | 4 +- UI/ControlMappingScreen.cpp | 4 +- UI/EmuScreen.cpp | 2 +- UI/EmuScreen.h | 2 +- UI/GamepadEmu.h | 2 +- UI/NativeApp.cpp | 2 +- UWP/App.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 13 ++++++ UWP/CommonUWP/CommonUWP.vcxproj.filters | 45 +++++++++++++++++++ UWP/NKCodeFromWindowsSystem.h | 2 +- UWP/NativeUWP/NativeUWP.vcxproj | 5 --- UWP/NativeUWP/NativeUWP.vcxproj.filters | 15 ------- UWP/PPSSPP_UWPMain.cpp | 2 +- UWP/PPSSPP_UWPMain.h | 2 +- UWP/UWPHost.cpp | 2 +- Windows/DinputDevice.cpp | 4 +- Windows/EmuThread.cpp | 2 +- Windows/InputDevice.cpp | 2 +- Windows/MainWindow.cpp | 4 +- Windows/RawInput.cpp | 2 +- Windows/WindowsHost.cpp | 4 +- Windows/XinputDevice.cpp | 4 +- android/jni/Android.mk | 2 + android/jni/app-android.cpp | 4 +- ext/native/Android.mk | 2 - ext/native/base/NativeApp.h | 2 +- ext/native/input/CMakeLists.txt | 13 ------ ext/native/native.vcxproj | 5 --- ext/native/native.vcxproj.filters | 18 -------- ext/native/ui/root.h | 2 +- ext/native/ui/screen.cpp | 2 +- ext/native/ui/screen.h | 2 +- ext/native/ui/ui.h | 2 +- ext/native/ui/ui_screen.cpp | 4 +- ext/native/ui/view.cpp | 4 +- ext/native/ui/viewgroup.cpp | 2 +- ext/native/ui/viewgroup.h | 2 +- ios/PPSSPPUIApplication.mm | 4 +- ios/SmartKeyboardMap.cpp | 2 +- ios/ViewController.mm | 4 +- libretro/Makefile.common | 4 +- libretro/libretro.cpp | 2 +- unittest/UnitTest.cpp | 2 +- 55 files changed, 146 insertions(+), 121 deletions(-) rename ext/native/input/gesture_detector.cpp => Common/Input/GestureDetector.cpp (98%) rename ext/native/input/gesture_detector.h => Common/Input/GestureDetector.h (96%) rename ext/native/input/input_state.cpp => Common/Input/InputState.cpp (96%) rename ext/native/input/input_state.h => Common/Input/InputState.h (99%) rename ext/native/input/keycodes.h => Common/Input/KeyCodes.h (100%) delete mode 100644 ext/native/input/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 568dbb1f51..29d2a45cc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,6 +433,11 @@ add_library(Common STATIC Common/Crypto/sha1.h Common/Crypto/sha256.cpp Common/Crypto/sha256.h + Common/Input/GestureDetector.cpp + Common/Input/GestureDetector.h + Common/Input/KeyCodes.h + Common/Input/InputState.cpp + Common/Input/InputState.h Common/Thread/Executor.cpp Common/Thread/Executor.h Common/Thread/PrioritizedWorkQueue.cpp @@ -1008,11 +1013,6 @@ add_library(native STATIC ext/native/image/zim_load.h ext/native/image/zim_save.cpp ext/native/image/zim_save.h - ext/native/input/gesture_detector.cpp - ext/native/input/gesture_detector.h - ext/native/input/keycodes.h - ext/native/input/input_state.h - ext/native/input/input_state.cpp ext/native/json/json_reader.h ext/native/json/json_reader.cpp ext/native/json/json_writer.h diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index d631d484a8..8f64506e1f 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -360,6 +360,9 @@ + + + @@ -611,6 +614,8 @@ false false + + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index a021e84b0c..b32b1da778 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -128,6 +128,15 @@ Thread + + Input + + + Input + + + Input + @@ -255,6 +264,12 @@ Thread + + Input + + + Input + @@ -281,6 +296,9 @@ {41bcd391-8641-432c-ae4a-ab03812df762} + + {fd0bac4f-e3e2-4201-8902-2d19b50d5bf7} + diff --git a/ext/native/input/gesture_detector.cpp b/Common/Input/GestureDetector.cpp similarity index 98% rename from ext/native/input/gesture_detector.cpp rename to Common/Input/GestureDetector.cpp index d73f4f9090..cab29e1b1a 100644 --- a/ext/native/input/gesture_detector.cpp +++ b/Common/Input/GestureDetector.cpp @@ -3,7 +3,7 @@ // Zoom gesture a la http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-6-implementing-the-pinch-zoom-gesture/1847 #include "Common/TimeUtil.h" -#include "input/gesture_detector.h" +#include "Common/Input/GestureDetector.h" const float estimatedInertiaDamping = 0.75f; diff --git a/ext/native/input/gesture_detector.h b/Common/Input/GestureDetector.h similarity index 96% rename from ext/native/input/gesture_detector.h rename to Common/Input/GestureDetector.h index 783843cee3..908f960769 100644 --- a/ext/native/input/gesture_detector.h +++ b/Common/Input/GestureDetector.h @@ -1,4 +1,4 @@ -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "math/geom2d.h" // Mainly for detecting (multi-)touch gestures but also useable for left button mouse dragging etc. diff --git a/ext/native/input/input_state.cpp b/Common/Input/InputState.cpp similarity index 96% rename from ext/native/input/input_state.cpp rename to Common/Input/InputState.cpp index 8c28473f1d..90fc9b6a1a 100644 --- a/ext/native/input/input_state.cpp +++ b/Common/Input/InputState.cpp @@ -1,5 +1,5 @@ -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include const char *GetDeviceName(int deviceId) { diff --git a/ext/native/input/input_state.h b/Common/Input/InputState.h similarity index 99% rename from ext/native/input/input_state.h rename to Common/Input/InputState.h index 2ce502f860..175d6786df 100644 --- a/ext/native/input/input_state.h +++ b/Common/Input/InputState.h @@ -8,7 +8,7 @@ #include #include "math/lin/vec3.h" -#include "input/keycodes.h" +#include "Common/Input/KeyCodes.h" // Default device IDs diff --git a/ext/native/input/keycodes.h b/Common/Input/KeyCodes.h similarity index 100% rename from ext/native/input/keycodes.h rename to Common/Input/KeyCodes.h diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 99d3bf4f05..2a3fb0bb81 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -26,7 +26,7 @@ #include "base/NativeApp.h" #include "file/ini_file.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "ppsspp_config.h" #include "Common/Log.h" diff --git a/Common/KeyMap.h b/Common/KeyMap.h index 86883a9e98..a0afd74797 100644 --- a/Common/KeyMap.h +++ b/Common/KeyMap.h @@ -21,8 +21,8 @@ #include #include #include -#include "input/input_state.h" // KeyDef -#include "input/keycodes.h" // keyboard keys +#include "Common/Input/InputState.h" // KeyDef +#include "Common/Input/KeyCodes.h" // keyboard keys #include "../Core/HLE/sceCtrl.h" // psp keys #define KEYMAP_ERROR_KEY_ALREADY_USED -1 diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 50e0396734..82123fc990 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -27,8 +27,8 @@ QTM_USE_NAMESPACE #include "file/zip_read.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "thin3d/thin3d.h" #include "base/NativeApp.h" #include "net/resolve.h" diff --git a/SDL/SDLJoystick.h b/SDL/SDLJoystick.h index 970b105199..5b4d67f1ab 100644 --- a/SDL/SDLJoystick.h +++ b/SDL/SDLJoystick.h @@ -7,8 +7,8 @@ #include "SDL_thread.h" #endif -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "net/resolve.h" #include "base/NativeApp.h" diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 348162d9d3..f0ab1df43a 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -24,8 +24,8 @@ SDLJoystick *joystick = NULL; #include "Common/TimeUtil.h" #include "ext/glslang/glslang/Public/ShaderLang.h" #include "image/png_load.h" -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "net/resolve.h" #include "NKCodeFromSDL.h" #include "util/const_map.h" diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 1cf93ebb44..07205f10ea 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -23,8 +23,8 @@ #include "base/display.h" #include "gfx/texture_atlas.h" #include "i18n/i18n.h" -#include "input/keycodes.h" -#include "input/input_state.h" +#include "Common/Input/KeyCodes.h" +#include "Common/Input/InputState.h" #include "ui/root.h" #include "ui/ui.h" #include "ui/ui_context.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index ba3cd45976..48c45e557f 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -26,7 +26,7 @@ #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_text.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "math/curves.h" #include "ui/root.h" #include "ui/ui.h" diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 9279944c6e..b4504e611c 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -21,7 +21,7 @@ #include #include -#include "input/keycodes.h" +#include "Common/Input/KeyCodes.h" #include "ui/screen.h" #include "ui/ui_screen.h" #include "ui/ui_tween.h" diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 57c2c41ecb..fd2fe9c7d3 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -17,7 +17,7 @@ #pragma once -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "gfx_es2/draw_buffer.h" #include "ui/view.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 57cfbea75d..dd11226078 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -53,7 +53,7 @@ #include "gfx_es2/draw_text.h" #include "gfx_es2/gpu_features.h" #include "i18n/i18n.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "math/fast/fast_math.h" #include "math/math_util.h" #include "math/lin/matrix4x4.h" diff --git a/UWP/App.cpp b/UWP/App.cpp index 586d679581..ee26dd40a0 100644 --- a/UWP/App.cpp +++ b/UWP/App.cpp @@ -5,8 +5,8 @@ #include -#include "input/input_state.h" #include "base/NativeApp.h" +#include "Common/Input/InputState.h" #include "Core/System.h" #include "Core/Core.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 3febada63d..c57672cdde 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -386,6 +386,9 @@ + + + @@ -422,6 +425,10 @@ + + + + @@ -442,6 +449,8 @@ + + @@ -466,6 +475,10 @@ + + + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 8df0d99656..1d396b672e 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -10,6 +10,12 @@ {b0ac485c-3153-4708-b098-f5a518a95b79} + + {819c6967-1ed6-4fec-8415-a018ae524180} + + + {7368a8e7-cf29-49e9-87be-f1e69771555e} + @@ -100,6 +106,24 @@ ext\libpng17 + + Input + + + Input + + + Thread + + + Thread + + + Thread + + + Thread + @@ -178,6 +202,27 @@ ext\libpng17 + + Input + + + Input + + + Input + + + Thread + + + Thread + + + Thread + + + Thread + diff --git a/UWP/NKCodeFromWindowsSystem.h b/UWP/NKCodeFromWindowsSystem.h index 470a72456a..94905fb699 100644 --- a/UWP/NKCodeFromWindowsSystem.h +++ b/UWP/NKCodeFromWindowsSystem.h @@ -2,6 +2,6 @@ #include -#include "input/keycodes.h" +#include "Common/Input/KeyCodes.h" extern std::map virtualKeyCodeToNKCode; \ No newline at end of file diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 808814c28c..d622fc813c 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -402,9 +402,6 @@ - - - @@ -464,8 +461,6 @@ - - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index cd0b7803cb..66c9bf1ea3 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -94,12 +94,6 @@ file - - input - - - input - ui @@ -268,15 +262,6 @@ file - - input - - - input - - - input - ui diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 8777ced8a7..8ddddcce9a 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -4,7 +4,7 @@ #include #include "base/NativeApp.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "file/vfs.h" #include "file/zip_read.h" #include "file/file_util.h" diff --git a/UWP/PPSSPP_UWPMain.h b/UWP/PPSSPP_UWPMain.h index 3b38deeb3d..ed720e8a98 100644 --- a/UWP/PPSSPP_UWPMain.h +++ b/UWP/PPSSPP_UWPMain.h @@ -3,7 +3,7 @@ #include #include "thin3d/thin3d.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "Common/GraphicsContext.h" #include "Common/DeviceResources.h" diff --git a/UWP/UWPHost.cpp b/UWP/UWPHost.cpp index b78e8ac055..d7526a9e2c 100644 --- a/UWP/UWPHost.cpp +++ b/UWP/UWPHost.cpp @@ -21,7 +21,7 @@ #include "file/file_util.h" #include "base/NativeApp.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "Common/StringUtils.h" #include "Core/Core.h" diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 5d89e4ab54..8d57cd19c5 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -23,9 +23,9 @@ #include "Core/HLE/sceCtrl.h" #include "DinputDevice.h" #include "Core/Config.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "base/NativeApp.h" -#include "input/keycodes.h" +#include "Common/Input/KeyCodes.h" #include "Core/Reporting.h" #include "Xinput.h" #pragma comment(lib,"dinput8.lib") diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 80ac516978..7c3a878435 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -4,7 +4,7 @@ #include "base/NativeApp.h" #include "i18n/i18n.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "util/text/utf8.h" #include "Common/Log.h" diff --git a/Windows/InputDevice.cpp b/Windows/InputDevice.cpp index 57b571bce3..28e6c2d379 100644 --- a/Windows/InputDevice.cpp +++ b/Windows/InputDevice.cpp @@ -19,7 +19,7 @@ #include #include -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "Common/Thread/ThreadUtil.h" #include "Core/Config.h" #include "Core/Host.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index fe1d1ee828..2f3545d5d7 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -37,8 +37,8 @@ #include "Common/TimeUtil.h" #include "Common/StringUtils.h" #include "i18n/i18n.h" -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "Common/Thread/ThreadUtil.h" #include "util/text/utf8.h" diff --git a/Windows/RawInput.cpp b/Windows/RawInput.cpp index 861fa393cd..9d7f9ba79a 100644 --- a/Windows/RawInput.cpp +++ b/Windows/RawInput.cpp @@ -21,7 +21,7 @@ #include "base/NativeApp.h" #include "base/display.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "Common/Log.h" #include "Windows/RawInput.h" #include "Windows/MainWindow.h" diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index e34f744f3b..4442fd4d19 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -35,8 +35,8 @@ #include "base/display.h" #include "base/NativeApp.h" #include "file/file_util.h" -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "util/text/utf8.h" #include "Common/StringUtils.h" diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 4693dd6e24..17f8da078d 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -8,8 +8,8 @@ #include "Common/CommonWindows.h" #include "Common/KeyMap.h" #include "Common/Log.h" -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "XinputDevice.h" #include "Core/Core.h" #include "Core/HLE/sceCtrl.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index bb51dbe08b..00b311b8a8 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -237,6 +237,8 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Thread/PrioritizedWorkQueue.cpp \ $(SRC)/Common/Thread/ThreadPool.cpp \ $(SRC)/Common/Thread/ThreadUtil.cpp \ + $(SRC)/Common/Input/GestureDetector.cpp \ + $(SRC)/Common/Input/InputState.cpp \ $(SRC)/Common/Serialize/Serializer.cpp \ $(SRC)/Common/ColorConv.cpp \ $(SRC)/Common/ExceptionHandlerSetup.cpp \ diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index b665eedee3..981f1ec979 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -53,8 +53,8 @@ struct JNIEnv {}; #include "base/NativeApp.h" #include "Common/Thread/ThreadUtil.h" #include "file/zip_read.h" -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "profiler/profiler.h" #include "math/math_util.h" #include "net/resolve.h" diff --git a/ext/native/Android.mk b/ext/native/Android.mk index 59a328aa0d..7469bb066a 100644 --- a/ext/native/Android.mk +++ b/ext/native/Android.mk @@ -21,8 +21,6 @@ LOCAL_SRC_FILES :=\ json/json_reader.cpp \ json/json_writer.cpp \ i18n/i18n.cpp \ - input/gesture_detector.cpp \ - input/input_state.cpp \ math/fast/fast_math.c \ math/fast/fast_matrix.c \ math/dataconv.cpp \ diff --git a/ext/native/base/NativeApp.h b/ext/native/base/NativeApp.h index d109d1138c..3242bfa019 100644 --- a/ext/native/base/NativeApp.h +++ b/ext/native/base/NativeApp.h @@ -10,7 +10,7 @@ // from the framework, which exposes the native JNI api which is a bit // more complicated. -// These are defined in input/input_state.h. +// These are defined in Common/Input/InputState.cpp struct TouchInput; struct KeyInput; struct AxisInput; diff --git a/ext/native/input/CMakeLists.txt b/ext/native/input/CMakeLists.txt deleted file mode 100644 index 266cff4ba7..0000000000 --- a/ext/native/input/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(SRCS - input_state.cpp - gesture_detector.cpp) - -set(SRCS ${SRCS}) - -add_library(input STATIC ${SRCS}) -target_link_libraries(input general gfx) -target_link_libraries(input general file) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 5395a1ffc2..3bf1ea67e9 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -424,9 +424,6 @@ - - - @@ -531,8 +528,6 @@ - - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index f06b11c078..44381c85cb 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -50,9 +50,6 @@ profiler - - input - file @@ -68,9 +65,6 @@ math - - input - base @@ -182,9 +176,6 @@ gfx - - input - file @@ -301,9 +292,6 @@ gfx - - input - base @@ -373,9 +361,6 @@ math - - input - gfx @@ -507,9 +492,6 @@ {c57b41dd-cc33-46ac-b479-19676455ae54} - - {4ba4474c-b80f-40da-95e8-2de57eb1b327} - {49afd06e-eb44-41ac-b038-e109e444a834} diff --git a/ext/native/ui/root.h b/ext/native/ui/root.h index 0944373e27..052ced4f33 100644 --- a/ext/native/ui/root.h +++ b/ext/native/ui/root.h @@ -3,7 +3,7 @@ #include #include "ui/ui_context.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" namespace UI { diff --git a/ext/native/ui/screen.cpp b/ext/native/ui/screen.cpp index 696d1986b6..86b1dc02c4 100644 --- a/ext/native/ui/screen.cpp +++ b/ext/native/ui/screen.cpp @@ -1,5 +1,5 @@ #include "base/display.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "ui/root.h" #include "ui/screen.h" #include "ui/ui.h" diff --git a/ext/native/ui/screen.h b/ext/native/ui/screen.h index f0c696a6de..e6a1ae33d1 100644 --- a/ext/native/ui/screen.h +++ b/ext/native/ui/screen.h @@ -17,7 +17,7 @@ #include #include "base/NativeApp.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "Common/Common.h" diff --git a/ext/native/ui/ui.h b/ext/native/ui/ui.h index f3e2ff327f..3e891a9a28 100644 --- a/ext/native/ui/ui.h +++ b/ext/native/ui/ui.h @@ -27,7 +27,7 @@ #include #include "gfx_es2/draw_buffer.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" class UIContext; diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index e46344a41a..7a692f9bc2 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -3,8 +3,8 @@ #include #include "base/display.h" -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "math/curves.h" #include "ui/ui_screen.h" #include "ui/ui_context.h" diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index ce79dfc516..7e261a5c7d 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -1,8 +1,8 @@ #include #include -#include "input/input_state.h" -#include "input/keycodes.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" #include "gfx_es2/draw_buffer.h" #include "gfx/texture_atlas.h" #include "util/text/utf8.h" diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index ecec7a1019..2ceae3146a 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -3,7 +3,7 @@ #include #include -#include "input/keycodes.h" +#include "Common/Input/KeyCodes.h" #include "math/curves.h" #include "ui/ui_context.h" #include "ui/ui_tween.h" diff --git a/ext/native/ui/viewgroup.h b/ext/native/ui/viewgroup.h index 0eb3f39328..d61305b2e9 100644 --- a/ext/native/ui/viewgroup.h +++ b/ext/native/ui/viewgroup.h @@ -6,7 +6,7 @@ #include #include "math/geom2d.h" -#include "input/gesture_detector.h" +#include "Common/Input/GestureDetector.h" #include "ui/view.h" namespace UI { diff --git a/ios/PPSSPPUIApplication.mm b/ios/PPSSPPUIApplication.mm index c410c8156d..14576fdc95 100644 --- a/ios/PPSSPPUIApplication.mm +++ b/ios/PPSSPPUIApplication.mm @@ -15,11 +15,11 @@ #include "base/display.h" #include "Common/TimeUtil.h" #include "file/zip_read.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "net/resolve.h" #include "ui/screen.h" #include "thin3d/thin3d.h" -#include "input/keycodes.h" +#include "Common/Input/KeyCodes.h" #include "gfx_es2/gpu_features.h" #import "ios/AppDelegate.h" diff --git a/ios/SmartKeyboardMap.cpp b/ios/SmartKeyboardMap.cpp index 785e8fafad..43d8e5b46e 100644 --- a/ios/SmartKeyboardMap.cpp +++ b/ios/SmartKeyboardMap.cpp @@ -7,7 +7,7 @@ // #include "SmartKeyboardMap.hpp" -#include "input/keycodes.h" +#include "Common/Input/KeyCodes.h" int getSmartKeyboardMap(int keycode) { switch(keycode) { diff --git a/ios/ViewController.mm b/ios/ViewController.mm index fb86872c7c..769c9d53a5 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -15,13 +15,13 @@ #include "base/display.h" #include "Common/TimeUtil.h" #include "file/zip_read.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "net/resolve.h" #include "ui/screen.h" #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" #include "thin3d/GLRenderManager.h" -#include "input/keycodes.h" +#include "Common/Input/KeyCodes.h" #include "gfx_es2/gpu_features.h" #include "Core/Config.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index dfb91b445c..d561afe40e 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -148,6 +148,8 @@ SOURCES_CXX += \ $(COMMONDIR)/Thread/ThreadUtil.cpp \ $(COMMONDIR)/Thread/ThreadPool.cpp \ $(COMMONDIR)/Thread/PrioritizedWorkQueue.cpp \ + $(COMMONDIR)/Input/GestureDetector.cpp \ + $(COMMONDIR)/Input/InputState.cpp \ $(COMMONDIR)/Buffer.cpp \ $(COMMONDIR)/ConsoleListener.cpp \ $(COMMONDIR)/ExceptionHandlerSetup.cpp \ @@ -299,8 +301,6 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/i18n/i18n.cpp \ $(NATIVEDIR)/image/zim_load.cpp \ $(NATIVEDIR)/image/png_load.cpp \ - $(NATIVEDIR)/input/gesture_detector.cpp \ - $(NATIVEDIR)/input/input_state.cpp \ $(NATIVEDIR)/math/curves.cpp \ $(NATIVEDIR)/math/expression_parser.cpp \ $(NATIVEDIR)/math/lin/matrix4x4.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 6f5ba59245..4e71ad7000 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -27,7 +27,7 @@ #include "GPU/GPUInterface.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureScalerCommon.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "base/NativeApp.h" #include "Common/Thread/ThreadUtil.h" diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 57225020da..74ce2a2dc1 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -35,7 +35,7 @@ #include "ppsspp_config.h" #include "base/NativeApp.h" -#include "input/input_state.h" +#include "Common/Input/InputState.h" #include "ext/disarm.h" #include "math/math_util.h" #include "util/text/parsers.h" From 826656a8401e88a7b1495cba7dbf9506b3624be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Burdukiewicz?= Date: Fri, 2 Oct 2020 14:06:00 +0200 Subject: [PATCH 818/848] Fixed missing cstring include. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: BartÅ‚omiej Burdukiewicz --- Common/FakeCPUDetect.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Common/FakeCPUDetect.cpp b/Common/FakeCPUDetect.cpp index d6244a9ee5..e110f0cdc0 100644 --- a/Common/FakeCPUDetect.cpp +++ b/Common/FakeCPUDetect.cpp @@ -15,8 +15,9 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include #include +#include +#include #include "Common.h" #include "CPUDetect.h" From ff8148dd92ad7ea1923b5a6260cdf971cc83887c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 1 Oct 2020 13:05:04 +0200 Subject: [PATCH 819/848] Move native/util, native/data and native/i18 to Common/Data. Also move colorutil.cpp/h linking build fix experiment Delete a bunch of unused CMakeLists.txt files CMakeLists.txt linking fix Don't include NativeApp.h from any headers. Android.mk buildfix Half of the UWP fix Buildfix Minor project file cleanup Buildfixes Guess what? More buildfixes! --- .gitignore | 3 + CMakeLists.txt | 42 +++---- Common/ArmCPUDetect.cpp | 2 +- Common/Common.vcxproj | 21 ++++ Common/Common.vcxproj.filters | 84 +++++++++++++ Common/ConsoleListener.cpp | 2 +- .../Data/Collections/ConstMap.h | 0 .../Data/Collections/TinySet.h | 0 .../Data/Color/RGBAUtil.cpp | 2 +- .../Data/Color/RGBAUtil.h | 0 .../Data/Encoding/Base64.cpp | 2 +- .../base64.h => Common/Data/Encoding/Base64.h | 0 .../Data/Encoding/Compression.cpp | 0 .../Data/Encoding/Compression.h | 0 .../Data/Encoding/Shiftjis.h | 0 .../utf16.h => Common/Data/Encoding/Utf16.h | 0 .../utf8.cpp => Common/Data/Encoding/Utf8.cpp | 4 +- .../utf8.h => Common/Data/Encoding/Utf8.h | 0 .../hash.cpp => Common/Data/Hash/Hash.cpp | 2 +- .../hash/hash.h => Common/Data/Hash/Hash.h | 0 .../random/rng.h => Common/Data/Random/Rng.h | 0 .../i18n.cpp => Common/Data/Text/I18n.cpp | 2 +- .../i18n/i18n.h => Common/Data/Text/I18n.h | 0 .../Data/Text/Parsers.cpp | 2 +- .../parsers.h => Common/Data/Text/Parsers.h | 0 .../Data/Text/WrapText.cpp | 4 +- .../Data/Text/WrapText.h | 0 Common/FileUtil.cpp | 2 +- Common/KeyMap.cpp | 4 +- Common/Log.cpp | 2 +- Common/LogManager.cpp | 2 +- Common/SysError.cpp | 2 +- Core/Config.cpp | 4 +- Core/CwCheat.cpp | 4 +- Core/Debugger/SymbolMap.cpp | 2 +- Core/Debugger/WebSocket/DisasmSubscriber.cpp | 2 +- .../WebSocket/GPUBufferSubscriber.cpp | 2 +- .../WebSocket/GPURecordSubscriber.cpp | 2 +- Core/Debugger/WebSocket/WebSocketUtils.cpp | 2 +- Core/Dialog/PSPDialog.cpp | 2 +- Core/Dialog/PSPMsgDialog.cpp | 4 +- Core/Dialog/PSPNetconfDialog.cpp | 4 +- Core/Dialog/PSPOskDialog.cpp | 4 +- Core/Dialog/PSPSaveDialog.cpp | 2 +- Core/Dialog/SavedataParam.cpp | 2 +- Core/FileLoaders/DiskCachingFileLoader.cpp | 2 +- Core/FileLoaders/LocalFileLoader.cpp | 2 +- Core/FileSystems/BlockDevices.cpp | 3 +- Core/FileSystems/DirectoryFileSystem.cpp | 4 +- Core/FileSystems/VirtualDiscFileSystem.cpp | 2 +- Core/HLE/proAdhoc.cpp | 4 +- Core/HLE/proAdhocServer.cpp | 2 +- Core/HLE/sceCcc.cpp | 6 +- Core/HLE/sceDisplay.cpp | 3 +- Core/HLE/sceNet.cpp | 2 +- Core/HLE/sceNetAdhoc.cpp | 2 +- Core/HLE/sceUsb.cpp | 1 - Core/HLE/sceUsbCam.cpp | 3 +- Core/HLE/sceUsbMic.cpp | 1 - Core/MIPS/MIPS.h | 2 +- Core/MIPS/MIPSAsm.cpp | 2 +- Core/PSPLoaders.cpp | 2 +- Core/SaveState.cpp | 4 +- Core/System.cpp | 2 +- Core/TextureReplacer.cpp | 4 +- Core/Util/GameManager.cpp | 4 +- Core/Util/PPGeDraw.cpp | 4 +- Core/Util/PortManager.cpp | 2 +- GPU/Common/FramebufferManagerCommon.cpp | 2 +- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/D3D11/ShaderManagerD3D11.cpp | 2 +- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/Directx9/ShaderManagerDX9.cpp | 4 +- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GLES/ShaderManagerGLES.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 2 +- GPU/GPUCommon.h | 1 - GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 2 +- Qt/NKCodeFromQt.h | 2 +- Qt/QtMain.cpp | 9 +- Qt/QtMain.h | 1 - Qt/mainwindow.h | 1 + SDL/NKCodeFromSDL.h | 2 +- SDL/SDLJoystick.cpp | 12 +- SDL/SDLJoystick.h | 1 - SDL/SDLMain.cpp | 16 +-- SDL/SDLVulkanGraphicsContext.cpp | 2 +- UI/ChatScreen.cpp | 9 +- UI/ComboKeyMappingScreen.cpp | 4 +- UI/ControlMappingScreen.cpp | 13 +- UI/ControlMappingScreen.h | 2 +- UI/CwCheatScreen.cpp | 5 +- UI/DevScreens.cpp | 3 +- UI/DevScreens.h | 2 +- UI/DiscordIntegration.cpp | 2 +- UI/DisplayLayoutScreen.cpp | 7 +- UI/EmuScreen.cpp | 5 +- UI/GPUDriverTestScreen.cpp | 2 +- UI/GameScreen.cpp | 7 +- UI/GameSettingsScreen.cpp | 7 +- UI/GamepadEmu.cpp | 2 +- UI/InstallZipScreen.cpp | 2 +- UI/MainScreen.cpp | 7 +- UI/MiscScreens.cpp | 7 +- UI/NativeApp.cpp | 4 +- UI/OnScreenDisplay.cpp | 2 +- UI/PauseScreen.cpp | 3 +- UI/RemoteISOScreen.cpp | 3 +- UI/ReportScreen.cpp | 9 +- UI/SavedataScreen.cpp | 6 +- UI/Store.cpp | 2 +- UI/TextureUtil.cpp | 2 +- UI/TiltAnalogSettingsScreen.cpp | 2 +- UI/TouchControlLayoutScreen.cpp | 4 +- UI/TouchControlVisibilityScreen.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 21 ++++ UWP/CommonUWP/CommonUWP.vcxproj.filters | 84 +++++++++++++ UWP/NativeUWP/NativeUWP.vcxproj | 20 ---- UWP/NativeUWP/NativeUWP.vcxproj.filters | 69 ----------- UWP/PPSSPP_UWPMain.cpp | 2 +- UWP/UWPUtil.h | 2 +- Windows/Debugger/BreakpointWindow.cpp | 2 +- Windows/Debugger/CtrlDisAsmView.cpp | 2 +- Windows/Debugger/CtrlRegisterList.cpp | 2 +- Windows/Debugger/DebuggerShared.cpp | 2 +- Windows/Debugger/Debugger_Disasm.cpp | 2 +- Windows/Debugger/Debugger_Lists.cpp | 2 +- Windows/Debugger/Debugger_MemoryDlg.cpp | 2 +- Windows/Debugger/Debugger_VFPUDlg.cpp | 2 +- Windows/Debugger/DumpMemoryWindow.cpp | 2 +- Windows/EmuThread.cpp | 4 +- Windows/GEDebugger/GEDebugger.cpp | 2 +- Windows/GPU/D3D11Context.cpp | 4 +- Windows/GPU/D3D9Context.cpp | 4 +- Windows/GPU/WindowsGLContext.cpp | 4 +- Windows/GPU/WindowsVulkanContext.cpp | 2 +- Windows/InputBox.cpp | 2 +- Windows/MainWindow.cpp | 4 +- Windows/MainWindowMenu.cpp | 4 +- Windows/W32Util/Misc.cpp | 2 +- Windows/W32Util/PropertySheet.cpp | 2 +- Windows/W32Util/ShellUtil.cpp | 2 +- Windows/WindowsHost.cpp | 2 +- Windows/main.cpp | 4 +- android/jni/Android.mk | 111 ++++++++++++++---- android/jni/AndroidVulkanContext.cpp | 2 +- android/jni/Locals.mk | 2 +- android/jni/app-android.cpp | 2 +- ext/native/Android.mk | 99 ---------------- ext/native/base/CMakeLists.txt | 12 -- ext/native/base/linked_ptr.h | 60 ---------- ext/native/file/CMakeLists.txt | 14 --- ext/native/file/file_util.cpp | 2 +- ext/native/file/free.cpp | 2 +- ext/native/file/ini_file.cpp | 4 +- ext/native/gfx/CMakeLists.txt | 12 -- ext/native/gfx_es2/CMakeLists.txt | 16 --- ext/native/gfx_es2/draw_buffer.cpp | 4 +- ext/native/gfx_es2/draw_buffer.h | 2 +- ext/native/gfx_es2/draw_text.cpp | 6 +- ext/native/gfx_es2/draw_text.h | 2 +- ext/native/gfx_es2/draw_text_android.cpp | 6 +- ext/native/gfx_es2/draw_text_qt.cpp | 6 +- ext/native/gfx_es2/draw_text_uwp.cpp | 6 +- ext/native/gfx_es2/draw_text_win.cpp | 6 +- ext/native/gfx_es2/gpu_features.h | 1 - ext/native/image/CMakeLists.txt | 14 --- ext/native/json/CMakeLists.txt | 15 --- ext/native/json/json_writer_test.cpp | 25 ---- ext/native/math/CMakeLists.txt | 14 --- ext/native/native.vcxproj | 23 ---- ext/native/native.vcxproj.filters | 76 ------------ ext/native/net/CMakeLists.txt | 11 -- ext/native/net/http_client.cpp | 4 +- ext/native/net/websocket_server.cpp | 2 +- ext/native/profiler/CMakeLists.txt | 11 -- ext/native/thin3d/GLQueueRunner.h | 2 +- ext/native/thin3d/VulkanQueueRunner.h | 2 +- ext/native/thin3d/thin3d_d3d11.cpp | 2 +- ext/native/tools/atlastool.cpp | 2 +- ext/native/ui/CMakeLists.txt | 17 --- ext/native/ui/screen.h | 5 +- ext/native/ui/ui.cpp | 2 +- ext/native/ui/ui_screen.cpp | 2 +- ext/native/ui/ui_tween.cpp | 2 +- ext/native/ui/view.cpp | 2 +- ext/native/util/CMakeLists.txt | 14 --- libretro/LibretroVulkanContext.cpp | 2 +- libretro/Makefile.common | 17 +-- unittest/UnitTest.cpp | 2 +- 191 files changed, 583 insertions(+), 797 deletions(-) rename ext/native/util/const_map.h => Common/Data/Collections/ConstMap.h (100%) rename ext/native/util/tiny_set.h => Common/Data/Collections/TinySet.h (100%) rename ext/native/base/colorutil.cpp => Common/Data/Color/RGBAUtil.cpp (97%) rename ext/native/base/colorutil.h => Common/Data/Color/RGBAUtil.h (100%) rename ext/native/data/base64.cpp => Common/Data/Encoding/Base64.cpp (95%) rename ext/native/data/base64.h => Common/Data/Encoding/Base64.h (100%) rename ext/native/data/compression.cpp => Common/Data/Encoding/Compression.cpp (100%) rename ext/native/data/compression.h => Common/Data/Encoding/Compression.h (100%) rename ext/native/util/text/shiftjis.h => Common/Data/Encoding/Shiftjis.h (100%) rename ext/native/util/text/utf16.h => Common/Data/Encoding/Utf16.h (100%) rename ext/native/util/text/utf8.cpp => Common/Data/Encoding/Utf8.cpp (99%) rename ext/native/util/text/utf8.h => Common/Data/Encoding/Utf8.h (100%) rename ext/native/util/hash/hash.cpp => Common/Data/Hash/Hash.cpp (95%) rename ext/native/util/hash/hash.h => Common/Data/Hash/Hash.h (100%) rename ext/native/util/random/rng.h => Common/Data/Random/Rng.h (100%) rename ext/native/i18n/i18n.cpp => Common/Data/Text/I18n.cpp (99%) rename ext/native/i18n/i18n.h => Common/Data/Text/I18n.h (100%) rename ext/native/util/text/parsers.cpp => Common/Data/Text/Parsers.cpp (98%) rename ext/native/util/text/parsers.h => Common/Data/Text/Parsers.h (100%) rename ext/native/util/text/wrap_text.cpp => Common/Data/Text/WrapText.cpp (98%) rename ext/native/util/text/wrap_text.h => Common/Data/Text/WrapText.h (100%) delete mode 100644 ext/native/Android.mk delete mode 100644 ext/native/base/CMakeLists.txt delete mode 100644 ext/native/base/linked_ptr.h delete mode 100644 ext/native/file/CMakeLists.txt delete mode 100644 ext/native/gfx/CMakeLists.txt delete mode 100644 ext/native/gfx_es2/CMakeLists.txt delete mode 100644 ext/native/image/CMakeLists.txt delete mode 100644 ext/native/json/CMakeLists.txt delete mode 100644 ext/native/json/json_writer_test.cpp delete mode 100644 ext/native/math/CMakeLists.txt delete mode 100644 ext/native/net/CMakeLists.txt delete mode 100644 ext/native/profiler/CMakeLists.txt delete mode 100644 ext/native/ui/CMakeLists.txt delete mode 100644 ext/native/util/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 07b897f328..818e0a459a 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,6 @@ debian/ppsspp/ # RenderDoc *.rdc + +# bad output from libretro. don't want to accidentally add it +nul diff --git a/CMakeLists.txt b/CMakeLists.txt index 29d2a45cc6..acbbbe43ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,6 +433,27 @@ add_library(Common STATIC Common/Crypto/sha1.h Common/Crypto/sha256.cpp Common/Crypto/sha256.h + Common/Data/Collections/ConstMap.h + Common/Data/Collections/TinySet.h + Common/Data/Color/RGBAUtil.cpp + Common/Data/Color/RGBAUtil.h + Common/Data/Encoding/Base64.cpp + Common/Data/Encoding/Base64.h + Common/Data/Encoding/Compression.cpp + Common/Data/Encoding/Compression.h + Common/Data/Encoding/Shiftjis.h + Common/Data/Encoding/Utf8.cpp + Common/Data/Encoding/Utf8.h + Common/Data/Encoding/Utf16.h + Common/Data/Hash/Hash.cpp + Common/Data/Hash/Hash.h + Common/Data/Text/I18n.cpp + Common/Data/Text/I18n.h + Common/Data/Text/Parsers.cpp + Common/Data/Text/Parsers.h + Common/Data/Text/WrapText.cpp + Common/Data/Text/WrapText.h + Common/Data/Random/Rng.h Common/Input/GestureDetector.cpp Common/Input/GestureDetector.h Common/Input/KeyCodes.h @@ -957,14 +978,8 @@ endif() add_library(native STATIC ${nativeExtra} - ext/native/base/colorutil.cpp - ext/native/base/colorutil.h ext/native/base/display.cpp ext/native/base/display.h - ext/native/data/base64.cpp - ext/native/data/base64.h - ext/native/data/compression.cpp - ext/native/data/compression.h ext/native/file/chunk_file.cpp ext/native/file/chunk_file.h ext/native/file/fd_util.cpp @@ -1005,8 +1020,6 @@ add_library(native STATIC ext/native/gfx_es2/glsl_program.h ext/native/gfx_es2/gl3stub.c ext/native/gfx_es2/gl3stub.h - ext/native/i18n/i18n.cpp - ext/native/i18n/i18n.h ext/native/image/png_load.cpp ext/native/image/png_load.h ext/native/image/zim_load.cpp @@ -1069,17 +1082,6 @@ add_library(native STATIC ext/native/ui/view.h ext/native/ui/viewgroup.cpp ext/native/ui/viewgroup.h - ext/native/util/hash/hash.cpp - ext/native/util/hash/hash.h - ext/native/util/random/rng.h - ext/native/util/text/utf8.h - ext/native/util/text/utf8.cpp - ext/native/util/text/parsers.h - ext/native/util/text/parsers.cpp - ext/native/util/text/wrap_text.h - ext/native/util/text/wrap_text.cpp - ext/native/util/const_map.h - ext/native/util/tiny_set.h ext/jpge/jpgd.cpp ext/jpge/jpgd.h ext/jpge/jpge.cpp @@ -1096,7 +1098,7 @@ if(ANDROID) set(ATOMIC_LIB atomic) endif() -target_link_libraries(native ${LIBZIP_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARY} gason udis86 ${RT_LIB} ${nativeExtraLibs} ${ATOMIC_LIB}) +target_link_libraries(native ${LIBZIP_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARY} gason udis86 ${RT_LIB} ${nativeExtraLibs} ${ATOMIC_LIB} Common) if(TARGET Ext::GLEW) target_link_libraries(native Ext::GLEW) endif() diff --git a/Common/ArmCPUDetect.cpp b/Common/ArmCPUDetect.cpp index 90aeaf8433..5a1d53fc4a 100644 --- a/Common/ArmCPUDetect.cpp +++ b/Common/ArmCPUDetect.cpp @@ -26,7 +26,7 @@ #include "CPUDetect.h" #include "StringUtils.h" #include "FileUtil.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #if PPSSPP_PLATFORM(WINDOWS) #if PPSSPP_PLATFORM(UWP) diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 8f64506e1f..5a4aef7e51 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -359,6 +359,19 @@ + + + + + + + + + + + + + @@ -614,6 +627,14 @@ false false + + + + + + + + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index b32b1da778..6408cd9512 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -137,6 +137,45 @@ Input + + Data\Random + + + Data\Text + + + Data\Text + + + Data\Text + + + Data\Encoding + + + Data\Encoding + + + Data\Encoding + + + Data\Encoding + + + Data\Encoding + + + Data\Hash + + + Data\Collections + + + Data\Collections + + + Data\Color + @@ -270,6 +309,30 @@ Input + + Data\Text + + + Data\Text + + + Data\Text + + + Data\Encoding + + + Data\Encoding + + + Data\Encoding + + + Data\Hash + + + Data\Color + @@ -299,6 +362,27 @@ {fd0bac4f-e3e2-4201-8902-2d19b50d5bf7} + + {072c36eb-a283-40b2-b8b1-02ec57d3bbae} + + + {a162915f-e53a-4f42-a222-e863235a2d37} + + + {891eae07-622d-46d5-9fc6-a4c320649eb9} + + + {0bd9bfae-7d4e-4f54-9aae-8fb11ab8c999} + + + {16fc7858-b6db-4eb2-bd4c-1354ffacda5f} + + + {c2d25b54-23fc-4e80-8d9b-5d7e94fe557e} + + + {1ada1f0f-6f1c-4bf2-8450-1fc63d77da17} + diff --git a/Common/ConsoleListener.cpp b/Common/ConsoleListener.cpp index ce3cc1f1b7..e5625c4f0f 100644 --- a/Common/ConsoleListener.cpp +++ b/Common/ConsoleListener.cpp @@ -33,7 +33,7 @@ #include "ppsspp_config.h" #include "Common/Thread/ThreadUtil.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Common.h" #include "Common/ConsoleListener.h" #include "Common/StringUtils.h" diff --git a/ext/native/util/const_map.h b/Common/Data/Collections/ConstMap.h similarity index 100% rename from ext/native/util/const_map.h rename to Common/Data/Collections/ConstMap.h diff --git a/ext/native/util/tiny_set.h b/Common/Data/Collections/TinySet.h similarity index 100% rename from ext/native/util/tiny_set.h rename to Common/Data/Collections/TinySet.h diff --git a/ext/native/base/colorutil.cpp b/Common/Data/Color/RGBAUtil.cpp similarity index 97% rename from ext/native/base/colorutil.cpp rename to Common/Data/Color/RGBAUtil.cpp index 6074dd9be0..8b93a0fc96 100644 --- a/ext/native/base/colorutil.cpp +++ b/Common/Data/Color/RGBAUtil.cpp @@ -1,4 +1,4 @@ -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" template static T clamp(T f, T low, T high) { diff --git a/ext/native/base/colorutil.h b/Common/Data/Color/RGBAUtil.h similarity index 100% rename from ext/native/base/colorutil.h rename to Common/Data/Color/RGBAUtil.h diff --git a/ext/native/data/base64.cpp b/Common/Data/Encoding/Base64.cpp similarity index 95% rename from ext/native/data/base64.cpp rename to Common/Data/Encoding/Base64.cpp index 8df7abaa1e..50dbc465a5 100644 --- a/ext/native/data/base64.cpp +++ b/Common/Data/Encoding/Base64.cpp @@ -1,4 +1,4 @@ -#include "data/base64.h" +#include "Common/Data/Encoding/Base64.h" // TODO: This is a simple but not very efficient implementation. std::string Base64Encode(const uint8_t *p, size_t sz) { diff --git a/ext/native/data/base64.h b/Common/Data/Encoding/Base64.h similarity index 100% rename from ext/native/data/base64.h rename to Common/Data/Encoding/Base64.h diff --git a/ext/native/data/compression.cpp b/Common/Data/Encoding/Compression.cpp similarity index 100% rename from ext/native/data/compression.cpp rename to Common/Data/Encoding/Compression.cpp diff --git a/ext/native/data/compression.h b/Common/Data/Encoding/Compression.h similarity index 100% rename from ext/native/data/compression.h rename to Common/Data/Encoding/Compression.h diff --git a/ext/native/util/text/shiftjis.h b/Common/Data/Encoding/Shiftjis.h similarity index 100% rename from ext/native/util/text/shiftjis.h rename to Common/Data/Encoding/Shiftjis.h diff --git a/ext/native/util/text/utf16.h b/Common/Data/Encoding/Utf16.h similarity index 100% rename from ext/native/util/text/utf16.h rename to Common/Data/Encoding/Utf16.h diff --git a/ext/native/util/text/utf8.cpp b/Common/Data/Encoding/Utf8.cpp similarity index 99% rename from ext/native/util/text/utf8.cpp rename to Common/Data/Encoding/Utf8.cpp index a847feef96..8e3bb0f05d 100644 --- a/ext/native/util/text/utf8.cpp +++ b/Common/Data/Encoding/Utf8.cpp @@ -27,8 +27,8 @@ #include #include -#include "utf8.h" -#include "utf16.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Encoding/Utf16.h" // is start of UTF sequence inline bool isutf(char c) { diff --git a/ext/native/util/text/utf8.h b/Common/Data/Encoding/Utf8.h similarity index 100% rename from ext/native/util/text/utf8.h rename to Common/Data/Encoding/Utf8.h diff --git a/ext/native/util/hash/hash.cpp b/Common/Data/Hash/Hash.cpp similarity index 95% rename from ext/native/util/hash/hash.cpp rename to Common/Data/Hash/Hash.cpp index 5af7728d0d..d19e1a1e00 100644 --- a/ext/native/util/hash/hash.cpp +++ b/Common/Data/Hash/Hash.cpp @@ -1,5 +1,5 @@ #include -#include "util/hash/hash.h" +#include "Common/Data/Hash/Hash.h" namespace hash { diff --git a/ext/native/util/hash/hash.h b/Common/Data/Hash/Hash.h similarity index 100% rename from ext/native/util/hash/hash.h rename to Common/Data/Hash/Hash.h diff --git a/ext/native/util/random/rng.h b/Common/Data/Random/Rng.h similarity index 100% rename from ext/native/util/random/rng.h rename to Common/Data/Random/Rng.h diff --git a/ext/native/i18n/i18n.cpp b/Common/Data/Text/I18n.cpp similarity index 99% rename from ext/native/i18n/i18n.cpp rename to Common/Data/Text/I18n.cpp index 72ec1f949f..e0bd685049 100644 --- a/ext/native/i18n/i18n.cpp +++ b/Common/Data/Text/I18n.cpp @@ -1,4 +1,4 @@ -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "file/ini_file.h" #include "file/vfs.h" diff --git a/ext/native/i18n/i18n.h b/Common/Data/Text/I18n.h similarity index 100% rename from ext/native/i18n/i18n.h rename to Common/Data/Text/I18n.h diff --git a/ext/native/util/text/parsers.cpp b/Common/Data/Text/Parsers.cpp similarity index 98% rename from ext/native/util/text/parsers.cpp rename to Common/Data/Text/Parsers.cpp index f36f3ff33d..ab7c057339 100644 --- a/ext/native/util/text/parsers.cpp +++ b/Common/Data/Text/Parsers.cpp @@ -2,7 +2,7 @@ #include #include -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Common/StringUtils.h" diff --git a/ext/native/util/text/parsers.h b/Common/Data/Text/Parsers.h similarity index 100% rename from ext/native/util/text/parsers.h rename to Common/Data/Text/Parsers.h diff --git a/ext/native/util/text/wrap_text.cpp b/Common/Data/Text/WrapText.cpp similarity index 98% rename from ext/native/util/text/wrap_text.cpp rename to Common/Data/Text/WrapText.cpp index 68ca6d7b5a..c46688c50e 100644 --- a/ext/native/util/text/wrap_text.cpp +++ b/Common/Data/Text/WrapText.cpp @@ -1,7 +1,7 @@ #include #include "gfx_es2/draw_buffer.h" -#include "util/text/utf8.h" -#include "util/text/wrap_text.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Text/WrapText.h" bool WordWrapper::IsCJK(uint32_t c) { if (c < 0x1000) { diff --git a/ext/native/util/text/wrap_text.h b/Common/Data/Text/WrapText.h similarity index 100% rename from ext/native/util/text/wrap_text.h rename to Common/Data/Text/WrapText.h diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index d99be4d46a..f7d78334b6 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -60,7 +60,7 @@ #endif // !defined(IOS) #endif // __APPLE__ -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index 2a3fb0bb81..408e8a3124 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -24,11 +24,11 @@ #include "CommonWindows.h" #endif +#include "ppsspp_config.h" + #include "base/NativeApp.h" #include "file/ini_file.h" #include "Common/Input/InputState.h" -#include "ppsspp_config.h" - #include "Common/Log.h" #include "Common/KeyMap.h" #include "Common/StringUtils.h" diff --git a/Common/Log.cpp b/Common/Log.cpp index dd0802ad86..1d3b1ba56c 100644 --- a/Common/Log.cpp +++ b/Common/Log.cpp @@ -22,7 +22,7 @@ #include "Common.h" #include "Common/Log.h" #include "StringUtils.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #if PPSSPP_PLATFORM(ANDROID) #include diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index aa090315ac..66c85c70b8 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -20,7 +20,7 @@ #include #include -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/LogManager.h" #include "Common/ConsoleListener.h" diff --git a/Common/SysError.cpp b/Common/SysError.cpp index 841655bfbe..2bf17740aa 100644 --- a/Common/SysError.cpp +++ b/Common/SysError.cpp @@ -18,7 +18,7 @@ #include #include -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "SysError.h" #ifdef _WIN32 diff --git a/Core/Config.cpp b/Core/Config.cpp index c5e36508f9..8f56969908 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -26,11 +26,11 @@ #include "base/display.h" #include "base/NativeApp.h" #include "file/ini_file.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "json/json_reader.h" #include "gfx_es2/gpu_features.h" #include "net/http_client.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "net/url.h" #include "Common/CPUDetect.h" diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 38b70abd77..5feb26a353 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/StringUtils.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" @@ -19,7 +19,7 @@ #include "GPU/Common/PostShader.h" #ifdef _WIN32 -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #endif static int CheatEvent = -1; diff --git a/Core/Debugger/SymbolMap.cpp b/Core/Debugger/SymbolMap.cpp index 5786898624..bc5dc32e2a 100644 --- a/Core/Debugger/SymbolMap.cpp +++ b/Core/Debugger/SymbolMap.cpp @@ -31,7 +31,7 @@ #include #include -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "zlib.h" #include "Common/CommonTypes.h" #include "Common/FileUtil.h" diff --git a/Core/Debugger/WebSocket/DisasmSubscriber.cpp b/Core/Debugger/WebSocket/DisasmSubscriber.cpp index e84596b849..172abf5f57 100644 --- a/Core/Debugger/WebSocket/DisasmSubscriber.cpp +++ b/Core/Debugger/WebSocket/DisasmSubscriber.cpp @@ -18,7 +18,7 @@ #include #include -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/StringUtils.h" #include "Core/Debugger/Breakpoints.h" diff --git a/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp b/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp index 7e6d03966e..155d70c70e 100644 --- a/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp +++ b/Core/Debugger/WebSocket/GPUBufferSubscriber.cpp @@ -20,7 +20,7 @@ #include #include #endif -#include "data/base64.h" +#include "Common/Data/Encoding/Base64.h" #include "Common/StringUtils.h" #include "Core/Debugger/WebSocket/GPUBufferSubscriber.h" #include "Core/Debugger/WebSocket/WebSocketUtils.h" diff --git a/Core/Debugger/WebSocket/GPURecordSubscriber.cpp b/Core/Debugger/WebSocket/GPURecordSubscriber.cpp index 961a4d0d04..7e62ef4700 100644 --- a/Core/Debugger/WebSocket/GPURecordSubscriber.cpp +++ b/Core/Debugger/WebSocket/GPURecordSubscriber.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "data/base64.h" +#include "Common/Data/Encoding/Base64.h" #include "Common/FileUtil.h" #include "Core/Debugger/WebSocket/GPURecordSubscriber.h" #include "Core/Debugger/WebSocket/WebSocketUtils.h" diff --git a/Core/Debugger/WebSocket/WebSocketUtils.cpp b/Core/Debugger/WebSocket/WebSocketUtils.cpp index 013121ff80..1f34621ee1 100644 --- a/Core/Debugger/WebSocket/WebSocketUtils.cpp +++ b/Core/Debugger/WebSocket/WebSocketUtils.cpp @@ -17,7 +17,7 @@ #include #include -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Common/StringUtils.h" #include "Core/Debugger/WebSocket/WebSocketUtils.h" diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp index fd01a96d4f..2a65cb03a7 100644 --- a/Core/Dialog/PSPDialog.cpp +++ b/Core/Dialog/PSPDialog.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index 292c213558..d68abaa9b5 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -25,8 +25,8 @@ #include "Core/HLE/sceCtrl.h" #include "Core/MemMapHelpers.h" #include "Core/Reporting.h" -#include "i18n/i18n.h" -#include "util/text/utf8.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Encoding/Utf8.h" static const float FONT_SCALE = 0.65f; diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 976360fb2d..3dfb8d45c7 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -19,7 +19,7 @@ #include "Common/CommonWindows.h" #endif #include -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" @@ -31,7 +31,7 @@ #include "Core/HLE/sceNet.h" #include "Core/HLE/sceNetAdhoc.h" #include "Core/Dialog/PSPNetconfDialog.h" -#include "ext/native/util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #define NETCONF_CONNECT_APNET 0 diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 60bcb6d6f5..cf52cd9fe0 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -17,9 +17,9 @@ #include #include "base/NativeApp.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "math/math_util.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/Dialog/PSPOskDialog.h" diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 637ddfdff4..3a3166b7c8 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -21,7 +21,7 @@ #include -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Thread/ThreadUtil.h" #include "Common/FileUtil.h" diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 46940fb9db..82b79e9c4c 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/FileLoaders/DiskCachingFileLoader.cpp b/Core/FileLoaders/DiskCachingFileLoader.cpp index 4b8888c802..fc2991b399 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.cpp +++ b/Core/FileLoaders/DiskCachingFileLoader.cpp @@ -24,7 +24,7 @@ #include "ppsspp_config.h" #include "file/file_util.h" #include "file/free.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/FileUtil.h" #include "Common/CommonWindows.h" #include "Core/FileLoaders/DiskCachingFileLoader.h" diff --git a/Core/FileLoaders/LocalFileLoader.cpp b/Core/FileLoaders/LocalFileLoader.cpp index 8e757b3315..fc91550059 100644 --- a/Core/FileLoaders/LocalFileLoader.cpp +++ b/Core/FileLoaders/LocalFileLoader.cpp @@ -18,7 +18,7 @@ #include #include "ppsspp_config.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "file/file_util.h" #include "Common/FileUtil.h" #include "Core/FileLoaders/LocalFileLoader.h" diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index b8f2b4432b..a890926cac 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -18,7 +18,8 @@ #include #include #include -#include "i18n/i18n.h" + +#include "Common/Data/Text/I18n.h" #include "Common/FileUtil.h" #include "Common/Swap.h" #include "Core/Loaders.h" diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index ccb4365323..b4c3ca2260 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -22,8 +22,8 @@ #include "file/free.h" #include "file/zip_read.h" -#include "i18n/i18n.h" -#include "util/text/utf8.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index df3375fffb..c713d9965c 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -26,7 +26,7 @@ #include "Core/HLE/sceKernel.h" #include "Core/Reporting.h" #include "file/zip_read.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #ifdef _WIN32 #include "Common/CommonWindows.h" diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 4c39013bf5..425bb63413 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -37,9 +37,9 @@ #include -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Thread/ThreadUtil.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/TimeUtil.h" diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index a345ab0b50..52b84febb1 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -49,7 +49,7 @@ #define MSG_NOSIGNAL 0x00 #endif -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Thread/ThreadUtil.h" #include "Common/FileUtil.h" diff --git a/Core/HLE/sceCcc.cpp b/Core/HLE/sceCcc.cpp index 2dba0143cd..51da548291 100644 --- a/Core/HLE/sceCcc.cpp +++ b/Core/HLE/sceCcc.cpp @@ -15,9 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "util/text/utf8.h" -#include "util/text/utf16.h" -#include "util/text/shiftjis.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Encoding/Utf16.h" +#include "Common/Data/Encoding/Shiftjis.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index f2f55aebf2..390d8f2621 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -26,9 +26,10 @@ #include #endif -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "profiler/profiler.h" +#include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 6750c94750..629a9766c8 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -23,7 +23,7 @@ #endif #include "net/resolve.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 614b9f1d1b..770302556f 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -56,7 +56,7 @@ #include "Core/HLE/sceNet.h" #include "Core/HLE/proAdhocServer.h" #include "Core/HLE/KernelWaitHelpers.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" // shared in sceNetAdhoc.h since it need to be used from sceNet.cpp also diff --git a/Core/HLE/sceUsb.cpp b/Core/HLE/sceUsb.cpp index 60622c9cf0..520b057826 100644 --- a/Core/HLE/sceUsb.cpp +++ b/Core/HLE/sceUsb.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/NativeApp.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index 7f0a20a68e..7de78168ee 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -18,8 +18,9 @@ #include #include -#include "base/NativeApp.h" #include "ppsspp_config.h" + +#include "base/NativeApp.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceUsbMic.cpp b/Core/HLE/sceUsbMic.cpp index 30035f1584..91855a0804 100644 --- a/Core/HLE/sceUsbMic.cpp +++ b/Core/HLE/sceUsbMic.cpp @@ -17,7 +17,6 @@ #include -#include "base/NativeApp.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" diff --git a/Core/MIPS/MIPS.h b/Core/MIPS/MIPS.h index bcc9910358..31df9d8baf 100644 --- a/Core/MIPS/MIPS.h +++ b/Core/MIPS/MIPS.h @@ -21,7 +21,7 @@ #include -#include "util/random/rng.h" +#include "Common/Data/Random/Rng.h" #include "Common/Common.h" #include "Common/CommonTypes.h" // #include "Core/CoreParameter.h" diff --git a/Core/MIPS/MIPSAsm.cpp b/Core/MIPS/MIPSAsm.cpp index a6ed1261ac..0e59e62da1 100644 --- a/Core/MIPS/MIPSAsm.cpp +++ b/Core/MIPS/MIPSAsm.cpp @@ -6,7 +6,7 @@ #include "Common/CommonTypes.h" #include "ext/armips/Core/Assembler.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Core/Debugger/SymbolMap.h" #include "Core/MemMapHelpers.h" #include "Core/MIPS/JitCommon/JitCommon.h" diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 26ad3572ec..09eabf4dc3 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -18,7 +18,7 @@ #include #include "file/file_util.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Thread/ThreadUtil.h" #include "Common/FileUtil.h" diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index a2ed973231..e354cdc3f7 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -20,9 +20,9 @@ #include #include -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Thread/ThreadUtil.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/System.cpp b/Core/System.cpp index ceaf38c076..e812043278 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -35,7 +35,7 @@ #include "base/NativeApp.h" #include "math/math_util.h" #include "Common/Thread/ThreadUtil.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/FileUtil.h" #include "Common/TimeUtil.h" diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 32e49b0a6c..56a3f743f9 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -23,10 +23,10 @@ #include -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "ext/xxhash.h" #include "file/ini_file.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Common/ColorConv.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 19f8c67009..3c943bda9a 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -29,7 +29,7 @@ #else #include "ext/libzip/zip.h" #endif -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "file/ini_file.h" #include "Common/Log.h" @@ -42,7 +42,7 @@ #include "Core/System.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/Util/GameManager.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" GameManager g_GameManager; diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index c724c0b37e..17881b5204 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -17,13 +17,13 @@ #include -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "file/vfs.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_text.h" #include "image/zim_load.h" #include "image/png_load.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index 0e2fb75c28..63bfd5baa7 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -30,7 +30,7 @@ #include #include #include "Common/TimeUtil.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "net/resolve.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 7ff1c477f7..4accc058c5 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -22,7 +22,7 @@ #include "ext/native/thin3d/thin3d.h" #include "gfx_es2/gpu_features.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/ColorConv.h" #include "Common/Common.h" #include "Core/Config.h" diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 48eae62704..27db9fd389 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -41,7 +41,7 @@ #include "Common/GraphicsContext.h" #include "base/NativeApp.h" #include "profiler/profiler.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Core/Debugger/Breakpoints.h" #include "Core/MemMapHelpers.h" #include "Core/MIPS/MIPS.h" diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index 7ca95da1fb..81b093f11d 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -26,7 +26,7 @@ #include "math/math_util.h" #include "math/dataconv.h" #include "thin3d/thin3d.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Log.h" #include "Common/Common.h" #include "Core/Config.h" diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index ad858ea665..07aae4fadf 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -21,7 +21,7 @@ #include "Common/GraphicsContext.h" #include "base/NativeApp.h" #include "profiler/profiler.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Core/Debugger/Breakpoints.h" #include "Core/MemMapHelpers.h" #include "Core/MIPS/MIPS.h" diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index a7129030a3..2a359f0ef5 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -23,12 +23,12 @@ #include #include "gfx/d3d9_shader.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "math/lin/matrix4x4.h" #include "math/math_util.h" #include "math/dataconv.h" #include "thin3d/thin3d.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Common.h" #include "Common/Log.h" diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 062705f8a3..0623af9e33 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "profiler/profiler.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Log.h" #include "Common/Serialize/Serializer.h" diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 6c1bffa637..76eb5a0393 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -26,7 +26,7 @@ #include "math/dataconv.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/gpu_features.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "math/math_util.h" #include "math/lin/matrix4x4.h" #include "profiler/profiler.h" diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index e3bb89094e..cfa92a0296 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -20,7 +20,7 @@ #include "ext/xxhash.h" #include "gfx/gl_debug_log.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "math/math_util.h" #include "profiler/profiler.h" #include "thin3d/GLRenderManager.h" diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index ede1b44720..f5ff5b87c4 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -365,7 +365,6 @@ private: // Debug stats. double timeSteppingStarted_; double timeSpentStepping_; - int lastVsync_ = -1; }; diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index a1ec302265..6e62cd1338 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -24,7 +24,7 @@ #include "math/dataconv.h" #include "profiler/profiler.h" #include "thin3d/thin3d.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/StringUtils.h" #include "Common/Vulkan/VulkanContext.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index d84827b698..e160116cd1 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -20,7 +20,7 @@ #include "ext/xxhash.h" #include "file/vfs.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "math/math_util.h" #include "profiler/profiler.h" #include "thin3d/thin3d.h" diff --git a/Qt/NKCodeFromQt.h b/Qt/NKCodeFromQt.h index 2a87141720..b53b09ffff 100644 --- a/Qt/NKCodeFromQt.h +++ b/Qt/NKCodeFromQt.h @@ -1,6 +1,6 @@ #pragma once -#include "util/const_map.h" +#include "Common/Data/Collections/ConstMap.h" #include // TODO: Add any missing keys diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 0010db1920..af33f80668 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -30,12 +30,15 @@ #include "SDL/SDLJoystick.h" #include "SDL_audio.h" #endif -#include "QtMain.h" + +#include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" -#include "i18n/i18n.h" #include "math/math_util.h" + +#include "QtMain.h" +#include "Common/Data/Text/I18n.h" #include "Common/Thread/ThreadUtil.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/HW/Camera.h" diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 82123fc990..2fce102089 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -30,7 +30,6 @@ QTM_USE_NAMESPACE #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "thin3d/thin3d.h" -#include "base/NativeApp.h" #include "net/resolve.h" #include "NKCodeFromQt.h" diff --git a/Qt/mainwindow.h b/Qt/mainwindow.h index 150fc53471..6334bc4aca 100644 --- a/Qt/mainwindow.h +++ b/Qt/mainwindow.h @@ -8,6 +8,7 @@ #include #include +#include "base/NativeApp.h" #include "ConsoleListener.h" #include "Core/Core.h" #include "Core/Config.h" diff --git a/SDL/NKCodeFromSDL.h b/SDL/NKCodeFromSDL.h index d71654c945..bd184eef01 100644 --- a/SDL/NKCodeFromSDL.h +++ b/SDL/NKCodeFromSDL.h @@ -1,6 +1,6 @@ #pragma once -#include "util/const_map.h" +#include "Common/Data/Collections/ConstMap.h" #include // TODO: Add any missing keys diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp index 72254a1534..ecb94e25a1 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -1,11 +1,13 @@ -#include "SDL/SDLJoystick.h" -#include "Core/Config.h" -#include "Common/FileUtil.h" -#include "file/vfs.h" - #include #include +#include "base/NativeApp.h" +#include "file/vfs.h" + +#include "Common/FileUtil.h" +#include "Core/Config.h" +#include "SDL/SDLJoystick.h" + using namespace std; static int SDLJoystickEventHandlerWrapper(void* userdata, SDL_Event* event) diff --git a/SDL/SDLJoystick.h b/SDL/SDLJoystick.h index 5b4d67f1ab..ea14076d64 100644 --- a/SDL/SDLJoystick.h +++ b/SDL/SDLJoystick.h @@ -10,7 +10,6 @@ #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "net/resolve.h" -#include "base/NativeApp.h" class SDLJoystick{ public: diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index f0ab1df43a..3f50a032cb 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -21,19 +21,13 @@ SDLJoystick *joystick = NULL; #include #include "base/display.h" -#include "Common/TimeUtil.h" +#include "base/NativeApp.h" #include "ext/glslang/glslang/Public/ShaderLang.h" #include "image/png_load.h" -#include "Common/Input/InputState.h" -#include "Common/Input/KeyCodes.h" #include "net/resolve.h" #include "NKCodeFromSDL.h" -#include "util/const_map.h" -#include "util/text/utf8.h" #include "math/math_util.h" #include "thin3d/GLRenderManager.h" -#include "Common/Thread/ThreadUtil.h" -#include "math.h" #include "SDL_syswm.h" @@ -46,11 +40,17 @@ SDLJoystick *joystick = NULL; #include #endif +#include "Common/GraphicsContext.h" +#include "Common/TimeUtil.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" +#include "Common/Data/Collections/ConstMap.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Thread/ThreadUtil.h" #include "Core/System.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/ConfigValues.h" -#include "Common/GraphicsContext.h" #include "SDLGLGraphicsContext.h" #include "SDLVulkanGraphicsContext.h" diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 76361240ce..9bc9bf925b 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -5,7 +5,7 @@ #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" #include "thin3d/VulkanRenderManager.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Core/System.h" #include "SDLVulkanGraphicsContext.h" diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 5430945518..b7e4b33819 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -1,12 +1,15 @@ #include #include "ppsspp_config.h" -#include "i18n/i18n.h" + +#include "base/NativeApp.h" #include "ui/root.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "ui/ui.h" -#include "util/text/utf8.h" + +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Encoding/Utf8.h" #include "Core/Config.h" #include "Core/System.h" #include "Core/HLE/proAdhoc.h" @@ -21,7 +24,7 @@ void ChatMenu::CreatePopupContents(UI::ViewGroup *parent) { #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(SDL) chatEdit_ = bottom->Add(new TextEdit("", n->T("Chat Here"), new LinearLayoutParams(1.0))); #if defined(USING_WIN_UI) - //freeze the ui when using ctrl + C hotkey need workaround + // freeze the ui when using ctrl + C hotkey need workaround if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen) { System_InputBoxGetString(n->T("Chat"), n->T("Chat Here"), [](bool result, const std::string &value) { if (result) { diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index 3ccc55c824..971780ac91 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "i18n/i18n.h" -#include "base/colorutil.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Color/RGBAUtil.h" #include "base/display.h" #include "file/path.h" #include "gfx_es2/draw_buffer.h" diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 07205f10ea..f60f25285f 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -19,23 +19,24 @@ #include #include -#include "base/colorutil.h" #include "base/display.h" +#include "base/NativeApp.h" #include "gfx/texture_atlas.h" -#include "i18n/i18n.h" -#include "Common/Input/KeyCodes.h" -#include "Common/Input/InputState.h" #include "ui/root.h" #include "ui/ui.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" +#include "Common/Data/Color/RGBAUtil.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Input/KeyCodes.h" +#include "Common/Input/InputState.h" +#include "Common/Log.h" +#include "Common/KeyMap.h" #include "Core/Host.h" #include "Core/HLE/sceCtrl.h" #include "Core/System.h" -#include "Common/Log.h" -#include "Common/KeyMap.h" #include "Core/Config.h" #include "UI/ControlMappingScreen.h" #include "UI/GameSettingsScreen.h" diff --git a/UI/ControlMappingScreen.h b/UI/ControlMappingScreen.h index 3d7b6879e5..3f548c2f66 100644 --- a/UI/ControlMappingScreen.h +++ b/UI/ControlMappingScreen.h @@ -22,10 +22,10 @@ #include #include -#include "i18n/i18n.h" #include "ui/view.h" #include "ui/ui_screen.h" +#include "Common/Data/Text/I18n.h" #include "UI/MiscScreens.h" class ControlMapper; diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index b0d2bfc5f2..eb67a666b8 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -15,11 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "base/NativeApp.h" #include "ext/xxhash.h" -#include "i18n/i18n.h" #include "ui/ui.h" -#include "util/text/utf8.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Core.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 022f157ed6..a577639e2a 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -19,8 +19,9 @@ #include "ppsspp_config.h" #include "base/display.h" +#include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" diff --git a/UI/DevScreens.h b/UI/DevScreens.h index 7b71ad6f13..0d32460d4e 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -24,7 +24,7 @@ #include #include "file/file_util.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "ui/ui_screen.h" #include "UI/MiscScreens.h" diff --git a/UI/DiscordIntegration.cpp b/UI/DiscordIntegration.cpp index ccc2a16e7a..f5838fc72c 100644 --- a/UI/DiscordIntegration.cpp +++ b/UI/DiscordIntegration.cpp @@ -5,7 +5,7 @@ #include "Common/Log.h" #include "Core/Config.h" #include "DiscordIntegration.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #if (PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(LINUX)) && !PPSSPP_PLATFORM(ANDROID) && !PPSSPP_PLATFORM(UWP) diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 7dba4e28ed..4ae30dd4ad 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -18,15 +18,16 @@ #include #include -#include "base/colorutil.h" #include "base/display.h" +#include "base/NativeApp.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" -#include "i18n/i18n.h" #include "ui/ui_context.h" #include "ui/view.h" -#include "DisplayLayoutScreen.h" +#include "Common/Data/Color/RGBAUtil.h" +#include "Common/Data/Text/I18n.h" +#include "UI/DisplayLayoutScreen.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 48c45e557f..0c816c817f 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -20,21 +20,22 @@ #include #include "base/display.h" +#include "base/NativeApp.h" #include "profiler/profiler.h" #include "gfx/texture_atlas.h" #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_text.h" -#include "Common/Input/InputState.h" #include "math/curves.h" #include "ui/root.h" #include "ui/ui.h" #include "ui/ui_context.h" #include "ui/ui_tween.h" #include "ui/view.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Input/InputState.h" #include "Common/KeyMap.h" #include "Common/Log.h" #include "Common/TimeUtil.h" diff --git a/UI/GPUDriverTestScreen.cpp b/UI/GPUDriverTestScreen.cpp index 87018d8399..c23517066b 100644 --- a/UI/GPUDriverTestScreen.cpp +++ b/UI/GPUDriverTestScreen.cpp @@ -1,5 +1,5 @@ #include "GPUDriverTestScreen.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "ui/view.h" static const std::vector fsDiscard = { diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 6b4f0b05e1..81b5c585d1 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -18,12 +18,15 @@ #include #include "ppsspp_config.h" + +#include "base/NativeApp.h" #include "gfx_es2/draw_buffer.h" -#include "i18n/i18n.h" -#include "util/text/utf8.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" + +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/FileUtil.h" #include "Core/Host.h" #include "Core/Config.h" diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 5d8d04ff1c..472aa840f0 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -20,14 +20,15 @@ #include #include "base/display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres +#include "base/NativeApp.h" -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "math/curves.h" #include "net/resolve.h" #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_buffer.h" -#include "i18n/i18n.h" -#include "util/text/utf8.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Encoding/Utf8.h" #include "ui/root.h" #include "ui/view.h" #include "ui/viewgroup.h" diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index ade3f154a1..d43bac8a08 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -17,7 +17,7 @@ #include -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "base/display.h" #include "base/NativeApp.h" #include "gfx/texture_atlas.h" diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index 3a586b776b..a8fc7f5038 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "ui/ui.h" #include "ui/view.h" #include "ui/viewgroup.h" diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 319c8b860e..14394a18d3 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -19,8 +19,8 @@ #include #include "ppsspp_config.h" -#include "base/colorutil.h" #include "base/display.h" +#include "base/NativeApp.h" #include "file/path.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" @@ -29,8 +29,9 @@ #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" -#include "util/text/utf8.h" +#include "Common/Data/Color/RGBAUtil.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/FileUtil.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" @@ -56,7 +57,7 @@ #include "Core/Config.h" #include "Core/Loaders.h" #include "GPU/GPUInterface.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Core/HLE/sceDisplay.h" #include "Core/HLE/sceUmd.h" diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 00b3f02b9e..9f8044613c 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -20,18 +20,19 @@ #include #include -#include "base/colorutil.h" +#include "base/NativeApp.h" #include "base/display.h" #include "gfx_es2/draw_buffer.h" #include "math/curves.h" -#include "i18n/i18n.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "ui/ui.h" -#include "util/random/rng.h" #include "file/vfs.h" +#include "Common/Data/Color/RGBAUtil.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Random/Rng.h" #include "Common/TimeUtil.h" #include "Common/FileUtil.h" #include "Core/Config.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index dd11226078..7b4fd4bff9 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -52,7 +52,7 @@ #include "gfx/texture_atlas.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/gpu_features.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" #include "math/fast/fast_math.h" #include "math/math_util.h" @@ -63,7 +63,7 @@ #include "ui/screen.h" #include "ui/ui_context.h" #include "ui/view.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "android/jni/app-android.h" diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index f45fb125d8..38f8549e7b 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -1,6 +1,6 @@ #include "UI/OnScreenDisplay.h" -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index ee36bba3ba..f2ec060b2a 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -18,7 +18,7 @@ #include #include -#include "i18n/i18n.h" +#include "base/NativeApp.h" #include "gfx_es2/draw_buffer.h" #include "ui/view.h" #include "ui/viewgroup.h" @@ -26,6 +26,7 @@ #include "ui/ui_screen.h" #include "thin3d/thin3d.h" +#include "Common/Data/Text/I18n.h" #include "Common/StringUtils.h" #include "Core/Reporting.h" diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index e0c5a4c990..680ba3b47c 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -25,15 +25,16 @@ #include #endif +#include "base/NativeApp.h" #include "file/path.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" -#include "i18n/i18n.h" #include "json/json_reader.h" #include "net/http_client.h" #include "net/resolve.h" #include "net/url.h" +#include "Common/Data/Text/I18n.h" #include "Common/Common.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index ae7a8909a9..59765847f0 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -18,21 +18,22 @@ #include #include "base/display.h" +#include "base/NativeApp.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" -#include "i18n/i18n.h" #include "thin3d/thin3d.h" #include "ui/ui_context.h" #include "UI/PauseScreen.h" #include "UI/ReportScreen.h" +#include "Common/Data/Text/I18n.h" +#include "Common/FileUtil.h" +#include "Common/Log.h" +#include "Common/StringUtils.h" #include "Core/Core.h" #include "Core/Reporting.h" #include "Core/Screenshot.h" #include "Core/System.h" -#include "Common/FileUtil.h" -#include "Common/Log.h" -#include "Common/StringUtils.h" using namespace UI; diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index bb28391c79..0521f830e5 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -18,12 +18,12 @@ #include #include -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "gfx_es2/draw_buffer.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "math/curves.h" #include "Common/Thread/PrioritizedWorkQueue.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" diff --git a/UI/Store.cpp b/UI/Store.cpp index 846161711b..f07a95d868 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -19,7 +19,7 @@ #include "json/json_reader.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "ui/screen.h" #include "ui/ui_context.h" #include "ui/viewgroup.h" diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index 7fac93cc5c..0ca4228be2 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -1,6 +1,6 @@ #include -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "thin3d/thin3d.h" #include "image/zim_load.h" #include "image/png_load.h" diff --git a/UI/TiltAnalogSettingsScreen.cpp b/UI/TiltAnalogSettingsScreen.cpp index 1281c5658f..e4379606e7 100644 --- a/UI/TiltAnalogSettingsScreen.cpp +++ b/UI/TiltAnalogSettingsScreen.cpp @@ -18,7 +18,7 @@ #include "TiltAnalogSettingsScreen.h" #include "Core/Config.h" #include "Core/System.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" void TiltAnalogSettingsScreen::CreateViews() { using namespace UI; diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index f8835f1e74..46b4c49eae 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -18,9 +18,9 @@ #include #include -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "gfx_es2/draw_buffer.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "math/math_util.h" #include "ui/ui_context.h" diff --git a/UI/TouchControlVisibilityScreen.cpp b/UI/TouchControlVisibilityScreen.cpp index 1e3b1fd63d..d04cf4e95c 100644 --- a/UI/TouchControlVisibilityScreen.cpp +++ b/UI/TouchControlVisibilityScreen.cpp @@ -19,7 +19,7 @@ #include "TouchControlVisibilityScreen.h" #include "Core/Config.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" static const int leftColumnWidth = 140; diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index c57672cdde..92edcd468f 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -386,6 +386,19 @@ + + + + + + + + + + + + + @@ -449,6 +462,14 @@ + + + + + + + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 1d396b672e..7edd0a7f0e 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -16,6 +16,27 @@ {7368a8e7-cf29-49e9-87be-f1e69771555e} + + {93937cf8-9cc6-4ea5-a9c8-bdc186aa0317} + + + {ad268930-1885-451c-969d-39871232244a} + + + {553115bf-c2fa-4c7d-a1db-587b2337c73f} + + + {4451d43c-69ec-42d2-8f0f-09032a1c46f1} + + + {c6e1a659-b5d9-4015-93b4-9e383959b19c} + + + {99f1fb79-2a8c-4ac0-8cba-57d9b2f87d32} + + + {7277c320-2c19-40d0-81a4-2f6cbb20790c} + @@ -124,6 +145,30 @@ Thread + + Data\Encoding + + + Data\Encoding + + + Data\Encoding + + + Data\Color + + + Data\Hash + + + Data\Text + + + Data\Text + + + Data\Text + @@ -223,6 +268,45 @@ Thread + + Data\Collections + + + Data\Collections + + + Data\Random + + + Data\Encoding + + + Data\Encoding + + + Data\Encoding + + + Data\Encoding + + + Data\Encoding + + + Data\Color + + + Data\Hash + + + Data\Text + + + Data\Text + + + Data\Text + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index d622fc813c..115cd1d8f1 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -379,11 +379,8 @@ - - - @@ -399,7 +396,6 @@ - @@ -428,22 +424,11 @@ - - - - - - - - - - - @@ -458,7 +443,6 @@ - @@ -598,10 +582,6 @@ - - - - Create Create diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 66c9bf1ea3..63749eb6bf 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -10,9 +10,6 @@ {63177c91-8ebd-4e87-ad4e-e6b8b52879c8} - - {58d2f6cf-2448-4095-8479-9fe5d765b573} - {8a254b8c-46f2-4ff1-bc53-deea7e614276} @@ -31,21 +28,12 @@ {d8c0dd74-7ad2-440a-a3e0-5dbf3435a2fc} - - {a522f449-7873-4af7-908e-7cc91eb8bfc0} - {96ac6deb-ad00-4ee4-9f0d-515d78d1886b} - - {4d23e7d3-0b9b-4dbe-95df-6ab250782a66} - - - base - base @@ -55,18 +43,6 @@ thin3d - - util - - - util - - - util - - - util - gfx @@ -160,9 +136,6 @@ net - - i18n - gfx @@ -175,9 +148,6 @@ gfx - - data - math @@ -186,9 +156,6 @@ net - - data - gfx @@ -196,9 +163,6 @@ - - base - base @@ -208,30 +172,6 @@ thin3d - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - gfx @@ -334,9 +274,6 @@ net - - i18n - gfx @@ -349,17 +286,11 @@ gfx - - data - net - - data - gfx diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 8ddddcce9a..b66c452f59 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -13,7 +13,7 @@ #include "base/display.h" #include "Common/Thread/ThreadUtil.h" #include "thin3d/thin3d_create.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Common.h" #include "Common/DirectXHelper.h" diff --git a/UWP/UWPUtil.h b/UWP/UWPUtil.h index de80bba6a7..685ebc396e 100644 --- a/UWP/UWPUtil.h +++ b/UWP/UWPUtil.h @@ -1,6 +1,6 @@ #pragma once -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" inline Platform::String ^ToPlatformString(std::string str) { return ref new Platform::String(ConvertUTF8ToWString(str).c_str()); diff --git a/Windows/Debugger/BreakpointWindow.cpp b/Windows/Debugger/BreakpointWindow.cpp index b00da57324..60ed43195e 100644 --- a/Windows/Debugger/BreakpointWindow.cpp +++ b/Windows/Debugger/BreakpointWindow.cpp @@ -1,6 +1,6 @@ #include -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "BreakpointWindow.h" #include "../resource.h" diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 7717503399..c37127f0dc 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -20,7 +20,7 @@ #include "Windows/main.h" #include "Common/CommonWindows.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "ext/xxhash.h" #include "base/display.h" diff --git a/Windows/Debugger/CtrlRegisterList.cpp b/Windows/Debugger/CtrlRegisterList.cpp index 05be2dee21..791838cdd3 100644 --- a/Windows/Debugger/CtrlRegisterList.cpp +++ b/Windows/Debugger/CtrlRegisterList.cpp @@ -4,7 +4,7 @@ #include #include "base/display.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Windows/resource.h" #include "Core/MemMap.h" #include "Windows/W32Util/Misc.h" diff --git a/Windows/Debugger/DebuggerShared.cpp b/Windows/Debugger/DebuggerShared.cpp index 7771edb5f2..9f3bc64313 100644 --- a/Windows/Debugger/DebuggerShared.cpp +++ b/Windows/Debugger/DebuggerShared.cpp @@ -1,4 +1,4 @@ -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "DebuggerShared.h" #include "../InputBox.h" diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index f5d80c6e77..39d29e7f62 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -24,7 +24,7 @@ #include "Core/CoreTiming.h" #include "Core/MIPS/MIPSAnalyst.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/CommonWindows.h" #include "Common/StringUtils.h" diff --git a/Windows/Debugger/Debugger_Lists.cpp b/Windows/Debugger/Debugger_Lists.cpp index f6c5bd9561..4463678dda 100644 --- a/Windows/Debugger/Debugger_Lists.cpp +++ b/Windows/Debugger/Debugger_Lists.cpp @@ -8,7 +8,7 @@ #include "Windows/main.h" #include "BreakpointWindow.h" #include "../../Core/HLE/sceKernelThread.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" enum { TL_NAME, TL_PROGRAMCOUNTER, TL_ENTRYPOINT, TL_PRIORITY, TL_STATE, TL_WAITTYPE, TL_COLUMNCOUNT }; enum { BPL_ENABLED, BPL_TYPE, BPL_OFFSET, BPL_SIZELABEL, BPL_OPCODE, BPL_CONDITION, BPL_HITS, BPL_COLUMNCOUNT }; diff --git a/Windows/Debugger/Debugger_MemoryDlg.cpp b/Windows/Debugger/Debugger_MemoryDlg.cpp index 7e76443bfa..9604616f01 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.cpp +++ b/Windows/Debugger/Debugger_MemoryDlg.cpp @@ -5,7 +5,7 @@ #include "..\resource.h" #include "base/display.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Core/Debugger/SymbolMap.h" #include "Core/MIPS/MIPSDebugInterface.h" // BAD diff --git a/Windows/Debugger/Debugger_VFPUDlg.cpp b/Windows/Debugger/Debugger_VFPUDlg.cpp index beb8caf41e..8851afd62e 100644 --- a/Windows/Debugger/Debugger_VFPUDlg.cpp +++ b/Windows/Debugger/Debugger_VFPUDlg.cpp @@ -4,7 +4,7 @@ #include #include #include "Windows/resource.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Core/Debugger/SymbolMap.h" #include "Windows/Debugger/Debugger_VFPUDlg.h" diff --git a/Windows/Debugger/DumpMemoryWindow.cpp b/Windows/Debugger/DumpMemoryWindow.cpp index 1fdb549486..3676307420 100644 --- a/Windows/Debugger/DumpMemoryWindow.cpp +++ b/Windows/Debugger/DumpMemoryWindow.cpp @@ -1,6 +1,6 @@ #include #include -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Core/Core.h" #include "Core/MemMap.h" #include "Windows/Debugger/DumpMemoryWindow.h" diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 7c3a878435..bfb2df00c6 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -3,9 +3,9 @@ #include #include "base/NativeApp.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index c22b00b554..61ca7784a2 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -20,7 +20,7 @@ #include #include -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Common/ColorConv.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 74f3b9b67b..9ced64d60c 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -6,8 +6,8 @@ #include "Common/Log.h" #include "base/display.h" -#include "util/text/utf8.h" -#include "i18n/i18n.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Text/I18n.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index 0014c31121..be91557b47 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -6,8 +6,8 @@ #include "gfx/d3d9_state.h" #include "base/display.h" -#include "util/text/utf8.h" -#include "i18n/i18n.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Text/I18n.h" #include "Common/Log.h" #include "Core/Config.h" diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index 01933b2701..57b4a51cd7 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -27,8 +27,8 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Core.h" -#include "util/text/utf8.h" -#include "i18n/i18n.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Text/I18n.h" #include "UI/OnScreenDisplay.h" #include "ext/glslang/glslang/Public/ShaderLang.h" diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 38b7623352..1c6557b2e3 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -58,7 +58,7 @@ #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" #include "thin3d/VulkanRenderManager.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Windows/GPU/WindowsVulkanContext.h" #ifdef _DEBUG diff --git a/Windows/InputBox.cpp b/Windows/InputBox.cpp index d661e39a9c..314aac514c 100644 --- a/Windows/InputBox.cpp +++ b/Windows/InputBox.cpp @@ -2,7 +2,7 @@ #include "Common/CommonWindows.h" #include "Windows/InputBox.h" #include "Windows/resource.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" static std::wstring textBoxContents; static std::wstring out; diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 2f3545d5d7..f4d2be55bf 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -36,11 +36,11 @@ #include "base/NativeApp.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "Common/Thread/ThreadUtil.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Core/Core.h" #include "Core/Config.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index d054c50741..310be72aa3 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -7,8 +7,8 @@ #include "resource.h" -#include "i18n/i18n.h" -#include "util/text/utf8.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Encoding/Utf8.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index b4544d08a9..d646302986 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -6,7 +6,7 @@ #include #include "Misc.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" bool KeyDownAsync(int vkey) { #if PPSSPP_PLATFORM(UWP) diff --git a/Windows/W32Util/PropertySheet.cpp b/Windows/W32Util/PropertySheet.cpp index dc2407dc1d..be56607b5f 100644 --- a/Windows/W32Util/PropertySheet.cpp +++ b/Windows/W32Util/PropertySheet.cpp @@ -1,7 +1,7 @@ #include "Windows/stdafx.h" #include "Misc.h" #include "PropertySheet.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include diff --git a/Windows/W32Util/ShellUtil.cpp b/Windows/W32Util/ShellUtil.cpp index e53ad9f43f..c6d3a2bc49 100644 --- a/Windows/W32Util/ShellUtil.cpp +++ b/Windows/W32Util/ShellUtil.cpp @@ -7,7 +7,7 @@ #include #include -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "ShellUtil.h" #include diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 4442fd4d19..3269917f10 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -37,7 +37,7 @@ #include "file/file_util.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/StringUtils.h" #include "Core/Core.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index 04713ef2e9..33843554dd 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -35,10 +35,10 @@ #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "profiler/profiler.h" #include "Common/Thread/ThreadUtil.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "net/resolve.h" #include "Core/Config.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 00b311b8a8..34309d62b9 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -101,25 +101,60 @@ ARCH_FILES := \ Arm64EmitterTest.cpp endif -ifeq ($(TARGET_ARCH_ABI),armeabi) -ARCH_FILES := \ - $(SRC)/Common/ArmEmitter.cpp \ - $(SRC)/Common/ArmCPUDetect.cpp \ - $(SRC)/Core/MIPS/ARM/ArmCompALU.cpp \ - $(SRC)/Core/MIPS/ARM/ArmCompBranch.cpp \ - $(SRC)/Core/MIPS/ARM/ArmCompFPU.cpp \ - $(SRC)/Core/MIPS/ARM/ArmCompLoadStore.cpp \ - $(SRC)/Core/MIPS/ARM/ArmCompVFPU.cpp \ - $(SRC)/Core/MIPS/ARM/ArmCompVFPUNEON.cpp \ - $(SRC)/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp \ - $(SRC)/Core/MIPS/ARM/ArmCompReplace.cpp \ - $(SRC)/Core/MIPS/ARM/ArmAsm.cpp \ - $(SRC)/Core/MIPS/ARM/ArmJit.cpp \ - $(SRC)/Core/MIPS/ARM/ArmRegCache.cpp \ - $(SRC)/Core/MIPS/ARM/ArmRegCacheFPU.cpp \ - $(SRC)/GPU/Common/VertexDecoderArm.cpp \ - ArmEmitterTest.cpp -endif +NATIVE_FILES :=\ + $(SRC)/ext/native/base/display.cpp \ + $(SRC)/ext/native/file/fd_util.cpp \ + $(SRC)/ext/native/file/chunk_file.cpp \ + $(SRC)/ext/native/file/file_util.cpp \ + $(SRC)/ext/native/file/free.cpp \ + $(SRC)/ext/native/file/path.cpp \ + $(SRC)/ext/native/file/ini_file.cpp \ + $(SRC)/ext/native/file/zip_read.cpp \ + $(SRC)/ext/native/json/json_reader.cpp \ + $(SRC)/ext/native/json/json_writer.cpp \ + $(SRC)/ext/native/math/fast/fast_math.c \ + $(SRC)/ext/native/math/fast/fast_matrix.c \ + $(SRC)/ext/native/math/dataconv.cpp \ + $(SRC)/ext/native/math/math_util.cpp \ + $(SRC)/ext/native/math/curves.cpp \ + $(SRC)/ext/native/math/expression_parser.cpp \ + $(SRC)/ext/native/math/lin/vec3.cpp.arm \ + $(SRC)/ext/native/math/lin/matrix4x4.cpp.arm \ + $(SRC)/ext/native/net/http_client.cpp \ + $(SRC)/ext/native/net/http_server.cpp \ + $(SRC)/ext/native/net/http_headers.cpp \ + $(SRC)/ext/native/net/resolve.cpp \ + $(SRC)/ext/native/net/sinks.cpp \ + $(SRC)/ext/native/net/url.cpp \ + $(SRC)/ext/native/net/websocket_server.cpp \ + $(SRC)/ext/native/profiler/profiler.cpp \ + $(SRC)/ext/native/gfx_es2/glsl_program.cpp \ + $(SRC)/ext/native/gfx_es2/gpu_features.cpp \ + $(SRC)/ext/native/gfx_es2/gl3stub.c \ + $(SRC)/ext/native/gfx_es2/draw_buffer.cpp.arm \ + $(SRC)/ext/native/gfx_es2/draw_text.cpp.arm \ + $(SRC)/ext/native/gfx_es2/draw_text_android.cpp.arm \ + $(SRC)/ext/native/gfx/gl_debug_log.cpp \ + $(SRC)/ext/native/gfx/texture_atlas.cpp \ + $(SRC)/ext/native/image/zim_load.cpp \ + $(SRC)/ext/native/image/zim_save.cpp \ + $(SRC)/ext/native/image/png_load.cpp \ + $(SRC)/ext/native/thin3d/thin3d.cpp \ + $(SRC)/ext/native/thin3d/thin3d_gl.cpp \ + $(SRC)/ext/native/thin3d/thin3d_vulkan.cpp \ + $(SRC)/ext/native/thin3d/GLRenderManager.cpp \ + $(SRC)/ext/native/thin3d/GLQueueRunner.cpp \ + $(SRC)/ext/native/thin3d/VulkanRenderManager.cpp \ + $(SRC)/ext/native/thin3d/VulkanQueueRunner.cpp \ + $(SRC)/ext/native/thin3d/DataFormatGL.cpp \ + $(SRC)/ext/native/ui/root.cpp \ + $(SRC)/ext/native/ui/view.cpp \ + $(SRC)/ext/native/ui/viewgroup.cpp \ + $(SRC)/ext/native/ui/ui.cpp \ + $(SRC)/ext/native/ui/ui_screen.cpp \ + $(SRC)/ext/native/ui/ui_tween.cpp \ + $(SRC)/ext/native/ui/ui_context.cpp \ + $(SRC)/ext/native/ui/screen.cpp EGL_FILES := \ $(SRC)/Common/GL/GLInterface/EGL.cpp \ @@ -205,6 +240,7 @@ EXEC_AND_LIB_FILES := \ $(VULKAN_FILES) \ $(SPIRV_CROSS_FILES) \ $(EXT_FILES) \ + $(NATIVE_FILES) \ TestRunner.cpp \ $(SRC)/Core/MIPS/MIPS.cpp.arm \ $(SRC)/Core/MIPS/MIPSAnalyst.cpp \ @@ -233,6 +269,14 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Crypto/md5.cpp \ $(SRC)/Common/Crypto/sha1.cpp \ $(SRC)/Common/Crypto/sha256.cpp \ + $(SRC)/Common/Data/Color/RGBAUtil.cpp \ + $(SRC)/Common/Data/Encoding/Base64.cpp \ + $(SRC)/Common/Data/Encoding/Compression.cpp \ + $(SRC)/Common/Data/Encoding/Utf8.cpp \ + $(SRC)/Common/Data/Hash/Hash.cpp \ + $(SRC)/Common/Data/Text/I18n.cpp \ + $(SRC)/Common/Data/Text/Parsers.cpp \ + $(SRC)/Common/Data/Text/WrapText.cpp \ $(SRC)/Common/Thread/Executor.cpp \ $(SRC)/Common/Thread/PrioritizedWorkQueue.cpp \ $(SRC)/Common/Thread/ThreadPool.cpp \ @@ -571,6 +615,34 @@ LOCAL_SRC_FILES := \ $(SRC)/UI/TextureUtil.cpp \ $(SRC)/UI/ComboKeyMappingScreen.cpp +#NATIVE +#LOCAL_CFLAGS := -O3 -DUSING_GLES2 -fsigned-char -fno-strict-aliasing -Wall -Wno-multichar -D__STDC_CONSTANT_MACROS +#LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder +#LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../ext $(LOCAL_PATH)/../../ext/libpng17 $(LOCAL_PATH)/../../ext/libzip $(LOCAL_PATH)/../../ext/glslang .. + +#Portable native and separate code on android in future is easy you needs add files +#by ($(target_arch_ABI),arquitecture (armeabi-v7a , armeabi , x86 , MIPS) +# ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) +ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + $(SRC)/ext/native/math/fast/fast_matrix_neon.S.neon \ + ../../ext/libpng17/arm/arm_init.c \ + ../../ext/libpng17/arm/filter_neon_intrinsics.c \ + ../../ext/libpng17/arm/filter_neon.S.neon + +else ifeq ($(TARGET_ARCH_ABI),armeabi) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 +else ifeq ($(TARGET_ARCH_ABI),x86) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86 +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + $(SRC)/ext/native/math/fast/fast_matrix_sse.c +else ifeq ($(TARGET_ARCH_ABI),x86_64) +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_X64 +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + $(SRC)/ext/native/math/fast/fast_matrix_sse.c +endif + ifneq ($(SKIPAPP),1) include $(BUILD_SHARED_LIBRARY) endif @@ -630,7 +702,6 @@ ifeq ($(UNITTEST),1) endif $(call import-module,libzip) -$(call import-module,native) $(call import-module,glslang-build) $(call import-module,miniupnp-build) diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index c3d490e3b1..49eb548c2d 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -7,7 +7,7 @@ #include "Common/Vulkan/VulkanLoader.h" #include "thin3d/VulkanRenderManager.h" #include "thin3d/thin3d_create.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" diff --git a/android/jni/Locals.mk b/android/jni/Locals.mk index 3984fad081..d18d5d6e85 100644 --- a/android/jni/Locals.mk +++ b/android/jni/Locals.mk @@ -19,7 +19,7 @@ LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/$(NATIVE) \ $(LOCAL_PATH) -LOCAL_STATIC_LIBRARIES := native libzip glslang-build miniupnp-build +LOCAL_STATIC_LIBRARIES := libzip glslang-build miniupnp-build LOCAL_LDLIBS := -lz -landroid -lGLESv2 -lOpenSLES -lEGL -ldl -llog -latomic ifneq ($(NDK_DEBUG),1) # Prettier stack traces are nice on other platforms. diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 981f1ec979..3813fbb44a 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -58,7 +58,7 @@ struct JNIEnv {}; #include "profiler/profiler.h" #include "math/math_util.h" #include "net/resolve.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "android/jni/AndroidAudio.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" diff --git a/ext/native/Android.mk b/ext/native/Android.mk deleted file mode 100644 index 7469bb066a..0000000000 --- a/ext/native/Android.mk +++ /dev/null @@ -1,99 +0,0 @@ -# Basic Android.mk for libnative - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := libnative -LOCAL_ARM_MODE := arm -LOCAL_SRC_FILES :=\ - base/display.cpp \ - base/colorutil.cpp \ - data/base64.cpp \ - data/compression.cpp \ - file/fd_util.cpp \ - file/chunk_file.cpp \ - file/file_util.cpp \ - file/free.cpp \ - file/path.cpp \ - file/ini_file.cpp \ - file/zip_read.cpp \ - json/json_reader.cpp \ - json/json_writer.cpp \ - i18n/i18n.cpp \ - math/fast/fast_math.c \ - math/fast/fast_matrix.c \ - math/dataconv.cpp \ - math/math_util.cpp \ - math/curves.cpp \ - math/expression_parser.cpp \ - math/lin/vec3.cpp.arm \ - math/lin/matrix4x4.cpp.arm \ - net/http_client.cpp \ - net/http_server.cpp \ - net/http_headers.cpp \ - net/resolve.cpp \ - net/sinks.cpp \ - net/url.cpp \ - net/websocket_server.cpp \ - profiler/profiler.cpp \ - gfx_es2/glsl_program.cpp \ - gfx_es2/gpu_features.cpp \ - gfx_es2/gl3stub.c \ - gfx_es2/draw_buffer.cpp.arm \ - gfx_es2/draw_text.cpp.arm \ - gfx_es2/draw_text_android.cpp.arm \ - gfx/gl_debug_log.cpp \ - gfx/texture_atlas.cpp \ - image/zim_load.cpp \ - image/zim_save.cpp \ - image/png_load.cpp \ - thin3d/thin3d.cpp \ - thin3d/thin3d_gl.cpp \ - thin3d/thin3d_vulkan.cpp \ - thin3d/GLRenderManager.cpp \ - thin3d/GLQueueRunner.cpp \ - thin3d/VulkanRenderManager.cpp \ - thin3d/VulkanQueueRunner.cpp \ - thin3d/DataFormatGL.cpp \ - ui/root.cpp \ - ui/view.cpp \ - ui/viewgroup.cpp \ - ui/ui.cpp \ - ui/ui_screen.cpp \ - ui/ui_tween.cpp \ - ui/ui_context.cpp \ - ui/screen.cpp \ - util/text/utf8.cpp \ - util/text/parsers.cpp \ - util/text/wrap_text.cpp \ - util/hash/hash.cpp - -LOCAL_CFLAGS := -O3 -DUSING_GLES2 -fsigned-char -fno-strict-aliasing -Wall -Wno-multichar -D__STDC_CONSTANT_MACROS -LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder -LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../ext $(LOCAL_PATH)/../../ext/libpng17 $(LOCAL_PATH)/../../ext/libzip $(LOCAL_PATH)/../../ext/glslang .. - -#Portable native and separate code on android in future is easy you needs add files -#by ($(target_arch_ABI),arquitecture (armeabi-v7a , armeabi , x86 , MIPS) -# ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) -ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A -LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - math/fast/fast_matrix_neon.S.neon \ - ../../ext/libpng17/arm/arm_init.c \ - ../../ext/libpng17/arm/filter_neon_intrinsics.c \ - ../../ext/libpng17/arm/filter_neon.S.neon - -else ifeq ($(TARGET_ARCH_ABI),armeabi) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 -else ifeq ($(TARGET_ARCH_ABI),x86) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86 -LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - math/fast/fast_matrix_sse.c -else ifeq ($(TARGET_ARCH_ABI),x86_64) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_X64 -LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - math/fast/fast_matrix_sse.c -endif - -include $(BUILD_STATIC_LIBRARY) diff --git a/ext/native/base/CMakeLists.txt b/ext/native/base/CMakeLists.txt deleted file mode 100644 index 1e4f0530dd..0000000000 --- a/ext/native/base/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(SRCS - colorutil.cpp - ../thread/threadutil.cpp - display.cpp - buffer.cpp -) - -add_library(base STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/base/linked_ptr.h b/ext/native/base/linked_ptr.h deleted file mode 100644 index 7eec84eed6..0000000000 --- a/ext/native/base/linked_ptr.h +++ /dev/null @@ -1,60 +0,0 @@ -// From http://ootips.org/yonat/4dev/linked_ptr.h - -/* -* linked_ptr - simple reference linked pointer -* (like reference counting, just using a linked list of the references -* instead of their count.) -* -* The implementation stores three pointers for every linked_ptr, but -* does not allocate anything on the free store. -*/ - -#pragma once - -template class linked_ptr -{ -public: - explicit linked_ptr(X* p = 0) throw() : itsPtr(p) {itsPrev = itsNext = this;} - ~linked_ptr() {release();} - linked_ptr(const linked_ptr& r) throw() {acquire(r);} - - linked_ptr& operator=(const linked_ptr& r) - { - if (this != &r) { - release(); - acquire(r); - } - return *this; - } - - X& operator*() const throw() {return *itsPtr;} - X* operator->() const throw() {return itsPtr;} - X* get() const throw() {return itsPtr;} - bool unique() const throw() {return itsPrev ? itsPrev==this : true;} - -private: - X* itsPtr; - mutable const linked_ptr* itsPrev; - mutable const linked_ptr* itsNext; - - void acquire(const linked_ptr& r) throw() - { // insert this to the list - itsPtr = r.itsPtr; - itsNext = r.itsNext; - itsNext->itsPrev = this; - itsPrev = &r; - r.itsNext = this; - } - - void release() - { // erase this from the list, delete if unique - if (unique()) delete itsPtr; - else { - itsPrev->itsNext = itsNext; - itsNext->itsPrev = itsPrev; - itsPrev = itsNext = 0; - } - itsPtr = 0; - } -}; - diff --git a/ext/native/file/CMakeLists.txt b/ext/native/file/CMakeLists.txt deleted file mode 100644 index 6cb73d143a..0000000000 --- a/ext/native/file/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(SRCS - chunk_file.cpp - zip_read.cpp - file_util.cpp - free.cpp) - -set(SRCS ${SRCS}) - -add_library(file STATIC ${SRCS}) -target_link_libraries(file general zip) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index 56f211bd57..0453cd5a88 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -19,7 +19,7 @@ #include #include "file/file_util.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/StringUtils.h" diff --git a/ext/native/file/free.cpp b/ext/native/file/free.cpp index fd458ae428..7c571d4a3d 100644 --- a/ext/native/file/free.cpp +++ b/ext/native/file/free.cpp @@ -17,7 +17,7 @@ #include #endif -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" bool free_disk_space(const std::string &dir, uint64_t &space) { #ifdef _WIN32 diff --git a/ext/native/file/ini_file.cpp b/ext/native/file/ini_file.cpp index b6dcf0d977..d0a5c71bf9 100644 --- a/ext/native/file/ini_file.cpp +++ b/ext/native/file/ini_file.cpp @@ -18,10 +18,10 @@ #include "file/ini_file.h" #include "file/vfs.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #ifdef _WIN32 -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #endif #include "Common/StringUtils.h" diff --git a/ext/native/gfx/CMakeLists.txt b/ext/native/gfx/CMakeLists.txt deleted file mode 100644 index 19b9e236ed..0000000000 --- a/ext/native/gfx/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(SRCS - gl_debug_log.cpp - #gl_lost_manager.cpp - texture_atlas.cpp) - -set(SRCS ${SRCS}) - -add_library(gfx STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/gfx_es2/CMakeLists.txt b/ext/native/gfx_es2/CMakeLists.txt deleted file mode 100644 index 75fbdd6ea8..0000000000 --- a/ext/native/gfx_es2/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(SRCS - draw_buffer.cpp - draw_text.cpp - glsl_program.cpp - gpu_features.cpp - gl_state.cpp) - -set(SRCS ${SRCS}) - -add_library(gfx_es2 STATIC ${SRCS}) -target_link_libraries(gfx_es2 general gfx) -target_link_libraries(gfx_es2 general file) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index 12307755f8..15ea08c217 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -9,8 +9,8 @@ #include "gfx/gl_debug_log.h" #include "gfx_es2/draw_buffer.h" #include "gfx_es2/draw_text.h" -#include "util/text/utf8.h" -#include "util/text/wrap_text.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Text/WrapText.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h index 001a91cd57..97edf9f3ca 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/ext/native/gfx_es2/draw_buffer.h @@ -5,7 +5,7 @@ #include #include -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "gfx/texture_atlas.h" #include "math/geom2d.h" #include "math/lin/matrix4x4.h" diff --git a/ext/native/gfx_es2/draw_text.cpp b/ext/native/gfx_es2/draw_text.cpp index 581ea31274..c8d5d374d1 100644 --- a/ext/native/gfx_es2/draw_text.cpp +++ b/ext/native/gfx_es2/draw_text.cpp @@ -1,8 +1,8 @@ #include "base/display.h" #include "thin3d/thin3d.h" -#include "util/hash/hash.h" -#include "util/text/wrap_text.h" -#include "util/text/utf8.h" +#include "Common/Data/Hash/Hash.h" +#include "Common/Data/Text/WrapText.h" +#include "Common/Data/Encoding/Utf8.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_text_win.h" #include "gfx_es2/draw_text_uwp.h" diff --git a/ext/native/gfx_es2/draw_text.h b/ext/native/gfx_es2/draw_text.h index 094ccdd28d..7ee06aad5f 100644 --- a/ext/native/gfx_es2/draw_text.h +++ b/ext/native/gfx_es2/draw_text.h @@ -14,7 +14,7 @@ #include #include "gfx_es2/draw_buffer.h" -#include "util/text/wrap_text.h" +#include "Common/Data/Text/WrapText.h" namespace Draw { class DrawContext; diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index 8a61ce8cb2..c824c0cd48 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -1,8 +1,8 @@ #include "base/display.h" #include "thin3d/thin3d.h" -#include "util/hash/hash.h" -#include "util/text/wrap_text.h" -#include "util/text/utf8.h" +#include "Common/Data/Hash/Hash.h" +#include "Common/Data/Text/WrapText.h" +#include "Common/Data/Encoding/Utf8.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_text_android.h" diff --git a/ext/native/gfx_es2/draw_text_qt.cpp b/ext/native/gfx_es2/draw_text_qt.cpp index 877e218ce7..f522e2c993 100644 --- a/ext/native/gfx_es2/draw_text_qt.cpp +++ b/ext/native/gfx_es2/draw_text_qt.cpp @@ -1,8 +1,8 @@ #include "base/display.h" #include "thin3d/thin3d.h" -#include "util/hash/hash.h" -#include "util/text/wrap_text.h" -#include "util/text/utf8.h" +#include "Common/Data/Hash/Hash.h" +#include "Common/Data/Text/WrapText.h" +#include "Common/Data/Encoding/Utf8.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_text_qt.h" diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index 3968767ee3..3171b01608 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -1,8 +1,8 @@ #include "base/display.h" #include "thin3d/thin3d.h" -#include "util/hash/hash.h" -#include "util/text/wrap_text.h" -#include "util/text/utf8.h" +#include "Common/Data/Hash/Hash.h" +#include "Common/Data/Text/WrapText.h" +#include "Common/Data/Encoding/Utf8.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_text_uwp.h" diff --git a/ext/native/gfx_es2/draw_text_win.cpp b/ext/native/gfx_es2/draw_text_win.cpp index 48315e5152..320d2968f3 100644 --- a/ext/native/gfx_es2/draw_text_win.cpp +++ b/ext/native/gfx_es2/draw_text_win.cpp @@ -1,8 +1,8 @@ #include "base/display.h" #include "thin3d/thin3d.h" -#include "util/hash/hash.h" -#include "util/text/wrap_text.h" -#include "util/text/utf8.h" +#include "Common/Data/Hash/Hash.h" +#include "Common/Data/Text/WrapText.h" +#include "Common/Data/Encoding/Utf8.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_text_win.h" diff --git a/ext/native/gfx_es2/gpu_features.h b/ext/native/gfx_es2/gpu_features.h index 4617e544a4..6f7dd50f54 100644 --- a/ext/native/gfx_es2/gpu_features.h +++ b/ext/native/gfx_es2/gpu_features.h @@ -5,7 +5,6 @@ #pragma once #include -#include "base/NativeApp.h" enum { GPU_VENDOR_NVIDIA = 1, diff --git a/ext/native/image/CMakeLists.txt b/ext/native/image/CMakeLists.txt deleted file mode 100644 index c835ef7134..0000000000 --- a/ext/native/image/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(SRCS - png_load.cpp - zim_load.cpp - zim_save.cpp -) - -set(SRCS ${SRCS}) - -add_library(image STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) - diff --git a/ext/native/json/CMakeLists.txt b/ext/native/json/CMakeLists.txt deleted file mode 100644 index 9c3ec2f57f..0000000000 --- a/ext/native/json/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(SRCS - json_writer.cpp) - -set(SRCS ${SRCS}) - -add_library(jsonwriter STATIC ${SRCS}) - - - -add_executable(json_writer_test json_writer_test.cpp) -target_link_libraries(json_writer_test jsonwriter) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/json/json_writer_test.cpp b/ext/native/json/json_writer_test.cpp deleted file mode 100644 index 46875ac12b..0000000000 --- a/ext/native/json/json_writer_test.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "json/json_writer.h" -#include - -int main() { - JsonWriter j; - j.begin(); - j.pushDict("settings"); - j.writeInt("volume", 50); - j.writeInt("sound", 60); - j.pop(); - j.pushDict("user"); - j.writeFloat("level", 1.5); - j.writeString("name", "hello"); - j.pop(); - j.writeInt("outer", 3); - j.pushArray("ints"); - j.writeInt(3); - j.writeInt(4); - j.writeInt(6); - j.pop(); - j.writeString("yo!", "yo"); - j.end(); - std::cout << j.str(); - return 0; -} diff --git a/ext/native/math/CMakeLists.txt b/ext/native/math/CMakeLists.txt deleted file mode 100644 index 3d6e0daa52..0000000000 --- a/ext/native/math/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(SRCS - lin/matrix4x4.cpp - lin/vec3.cpp - curves.cpp - math_util.cpp - ) - -set(SRCS ${SRCS}) - -add_library(lin STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 3bf1ea67e9..b5b4fe78b1 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -371,20 +371,13 @@ true - - - - - - - @@ -414,13 +407,11 @@ - - @@ -450,15 +441,8 @@ - - - - - - - true @@ -480,8 +464,6 @@ true true - - @@ -509,7 +491,6 @@ - @@ -524,7 +505,6 @@ - @@ -560,9 +540,6 @@ - - - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 44381c85cb..cfb2d16ef1 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -1,20 +1,10 @@  - - file - - - - base - tools - - ui - math\fast @@ -65,9 +55,6 @@ math - - base - json @@ -98,9 +85,6 @@ ui - - util - math @@ -110,12 +94,6 @@ gfx - - util - - - i18n - file @@ -134,18 +112,12 @@ ui - - data - math gfx - - util - gfx @@ -155,12 +127,6 @@ math\fast - - util - - - util - thin3d @@ -185,9 +151,6 @@ net - - util - gfx @@ -239,18 +202,12 @@ net - - data - thin3d ui - - util - gfx @@ -292,9 +249,6 @@ gfx - - base - json @@ -334,12 +288,6 @@ gfx - - util - - - i18n - file @@ -355,21 +303,12 @@ ui - - data - math gfx - - util - - - util - gfx @@ -415,9 +354,6 @@ net - - util - thin3d @@ -466,9 +402,6 @@ net - - data - thin3d @@ -504,21 +437,12 @@ {d738c2d1-749d-4b60-b98f-f3da0bbbf40c} - - {e36ca540-863c-496b-b0f4-b1ece3e72feb} - - - {d5fa3d62-88bf-4dc4-9814-28f3c0444e62} - {6a548b3d-3a4c-4114-aa2f-0b42bf7bf2ce} {4515306f-4664-46bf-a89b-abfec5520a15} - - {02e8ef95-82c7-4420-b029-a189a5e0fcbd} - {5ce64c0e-98e4-4411-86cc-aacaf2f60b21} diff --git a/ext/native/net/CMakeLists.txt b/ext/native/net/CMakeLists.txt deleted file mode 100644 index 10d69f4d51..0000000000 --- a/ext/native/net/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -set(SRCS - http_client.cpp - resolve.cpp) - -set(SRCS ${SRCS}) - -add_library(net STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/net/http_client.cpp b/ext/native/net/http_client.cpp index f5a80ec17f..60c1ca8a90 100644 --- a/ext/native/net/http_client.cpp +++ b/ext/native/net/http_client.cpp @@ -20,12 +20,12 @@ #include #include -#include "data/compression.h" #include "file/fd_util.h" #include "net/resolve.h" #include "net/url.h" -#include "Common/Thread/ThreadUtil.h" +#include "Common/Thread/ThreadUtil.h" +#include "Common/Data/Encoding/Compression.h" #include "Common/Buffer.h" #include "Common/Log.h" diff --git a/ext/native/net/websocket_server.cpp b/ext/native/net/websocket_server.cpp index b769219f9c..60f41c2290 100644 --- a/ext/native/net/websocket_server.cpp +++ b/ext/native/net/websocket_server.cpp @@ -15,7 +15,7 @@ #include #endif -#include "data/base64.h" +#include "Common/Data/Encoding/Base64.h" #include "net/http_server.h" #include "net/sinks.h" #include "net/websocket_server.h" diff --git a/ext/native/profiler/CMakeLists.txt b/ext/native/profiler/CMakeLists.txt deleted file mode 100644 index f3f9673dac..0000000000 --- a/ext/native/profiler/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -set(SRCS - profiler.cpp -) - -# LGUIFileList.cpp - -add_library(profiler STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index 031c17b06f..3737d13412 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -6,7 +6,7 @@ #include "gfx/gl_common.h" #include "thin3d/DataFormat.h" -#include "util/tiny_set.h" +#include "Common/Data/Collections/TinySet.h" struct GLRViewport { float x, y, w, h, minZ, maxZ; diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index e8daa6d599..d46efdb42d 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -6,7 +6,7 @@ #include "Common/Vulkan/VulkanContext.h" #include "math/dataconv.h" #include "thin3d/DataFormat.h" -#include "util/tiny_set.h" +#include "Common/Data/Collections/TinySet.h" class VKRFramebuffer; struct VKRImage; diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 1457e79af1..1a5bc12d85 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -8,7 +8,7 @@ #endif #include "base/display.h" #include "math/dataconv.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/ColorConv.h" diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp index 4464861805..7207fcc093 100644 --- a/ext/native/tools/atlastool.cpp +++ b/ext/native/tools/atlastool.cpp @@ -46,7 +46,7 @@ // add kanjiFilter Array with KANJI_LEARNING_ORDER_ADDTIONAL. #define USE_KANJI KANJI_LEARNING_ORDER_ALL -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" using namespace std; static int global_id; diff --git a/ext/native/ui/CMakeLists.txt b/ext/native/ui/CMakeLists.txt deleted file mode 100644 index 016db5350c..0000000000 --- a/ext/native/ui/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(SRCS - ui.cpp - ui_context.cpp - view.cpp - viewgroup.cpp - screen.cpp - root.cpp -) - -set(SRCS ${SRCS}) - -add_library(ui STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) - diff --git a/ext/native/ui/screen.h b/ext/native/ui/screen.h index e6a1ae33d1..46f7261ddb 100644 --- a/ext/native/ui/screen.h +++ b/ext/native/ui/screen.h @@ -15,11 +15,10 @@ #include #include - -#include "base/NativeApp.h" -#include "Common/Input/InputState.h" +#include #include "Common/Common.h" +#include "Common/Input/InputState.h" namespace UI { class View; diff --git a/ext/native/ui/ui.cpp b/ext/native/ui/ui.cpp index f8ea4f574a..659aa5af5d 100644 --- a/ext/native/ui/ui.cpp +++ b/ext/native/ui/ui.cpp @@ -5,7 +5,7 @@ #include #include -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "ui/ui.h" #include "ui/ui_context.h" #include "gfx/texture_atlas.h" diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 7a692f9bc2..0406ed271d 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -10,7 +10,7 @@ #include "ui/ui_context.h" #include "ui/screen.h" #include "ui/root.h" -#include "i18n/i18n.h" +#include "Common/Data/Text/I18n.h" #include "gfx_es2/draw_buffer.h" #include "Common/Log.h" diff --git a/ext/native/ui/ui_tween.cpp b/ext/native/ui/ui_tween.cpp index 4c3194d309..3263c0da70 100644 --- a/ext/native/ui/ui_tween.cpp +++ b/ext/native/ui/ui_tween.cpp @@ -1,4 +1,4 @@ -#include "base/colorutil.h" +#include "Common/Data/Color/RGBAUtil.h" #include "ui/ui_tween.h" #include "ui/view.h" #include "ui/viewgroup.h" diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 7e261a5c7d..1f807d6b53 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -5,7 +5,7 @@ #include "Common/Input/KeyCodes.h" #include "gfx_es2/draw_buffer.h" #include "gfx/texture_atlas.h" -#include "util/text/utf8.h" +#include "Common/Data/Encoding/Utf8.h" #include "ui/ui.h" #include "ui/view.h" #include "ui/ui_context.h" diff --git a/ext/native/util/CMakeLists.txt b/ext/native/util/CMakeLists.txt deleted file mode 100644 index 9d632a0ad9..0000000000 --- a/ext/native/util/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -set(SRCS - hash/hash.cpp - text/utf8.cpp - text/wrap_text.cpp -) - -set(SRCS ${SRCS}) - -add_library(util STATIC ${SRCS}) - -if(UNIX) - add_definitions(-fPIC) -endif(UNIX) - diff --git a/libretro/LibretroVulkanContext.cpp b/libretro/LibretroVulkanContext.cpp index 906d8550cd..0f978e99b3 100644 --- a/libretro/LibretroVulkanContext.cpp +++ b/libretro/LibretroVulkanContext.cpp @@ -7,7 +7,7 @@ #include "Core/ConfigValues.h" #include "Core/System.h" #include "GPU/GPUInterface.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "libretro/LibretroVulkanContext.h" #include "libretro/libretro_vulkan.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 9a0f2ee842..145be50d2e 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -142,6 +142,16 @@ SOURCES_CXX += \ $(COMMONDIR)/Crypto/sha1.cpp \ $(COMMONDIR)/Crypto/sha256.cpp +SOURCES_CXX += \ + $(COMMONDIR)/Data/Color/RGBAUtil.cpp \ + $(COMMONDIR)/Data/Encoding/Base64.cpp \ + $(COMMONDIR)/Data/Encoding/Compression.cpp \ + $(COMMONDIR)/Data/Encoding/Utf8.cpp \ + $(COMMONDIR)/Data/Hash/Hash.cpp \ + $(COMMONDIR)/Data/Text/I18n.cpp \ + $(COMMONDIR)/Data/Text/Parsers.cpp \ + $(COMMONDIR)/Data/Text/WrapText.cpp \ + SOURCES_CXX += \ $(COMMONDIR)/Serialize/Serializer.cpp \ $(COMMONDIR)/Thread/Executor.cpp \ @@ -221,9 +231,7 @@ SOURCES_CXX += \ $(GPUDIR)/GLES/ShaderManagerGLES.cpp \ $(GPUDIR)/GLES/StateMappingGLES.cpp \ $(GPUDIR)/GLES/StencilBufferGLES.cpp \ - $(EXTDIR)/native/base/colorutil.cpp \ $(EXTDIR)/native/base/display.cpp \ - $(EXTDIR)/native/data/compression.cpp \ $(EXTDIR)/native/json/json_reader.cpp \ $(EXTDIR)/glslang/OGLCompilersDLL/InitializeDll.cpp \ $(EXTDIR)/glslang/glslang/GenericCodeGen/CodeGen.cpp \ @@ -298,7 +306,6 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/gfx_es2/draw_text.cpp \ $(NATIVEDIR)/gfx_es2/gpu_features.cpp \ $(NATIVEDIR)/gfx_es2/glsl_program.cpp \ - $(NATIVEDIR)/i18n/i18n.cpp \ $(NATIVEDIR)/image/zim_load.cpp \ $(NATIVEDIR)/image/png_load.cpp \ $(NATIVEDIR)/math/curves.cpp \ @@ -321,10 +328,6 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/ui/ui_tween.cpp \ $(NATIVEDIR)/ui/view.cpp \ $(NATIVEDIR)/ui/viewgroup.cpp \ - $(NATIVEDIR)/util/hash/hash.cpp \ - $(NATIVEDIR)/util/text/utf8.cpp \ - $(NATIVEDIR)/util/text/parsers.cpp \ - $(NATIVEDIR)/util/text/wrap_text.cpp \ $(EXTDIR)/jpge/jpgd.cpp \ $(EXTDIR)/jpge/jpge.cpp \ $(COREDIR)/AVIDump.cpp \ diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 74ce2a2dc1..43e947fe95 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -38,7 +38,7 @@ #include "Common/Input/InputState.h" #include "ext/disarm.h" #include "math/math_util.h" -#include "util/text/parsers.h" +#include "Common/Data/Text/Parsers.h" #include "Common/ArmEmitter.h" #include "Common/BitScan.h" From de3b46077abe79c551e1fd68874029d6faa1fffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 08:25:11 +0200 Subject: [PATCH 820/848] iOS buildfix attempt --- ios/PPSSPPUIApplication.mm | 1 + ios/ViewController.mm | 1 + 2 files changed, 2 insertions(+) diff --git a/ios/PPSSPPUIApplication.mm b/ios/PPSSPPUIApplication.mm index 14576fdc95..65a24d3c64 100644 --- a/ios/PPSSPPUIApplication.mm +++ b/ios/PPSSPPUIApplication.mm @@ -13,6 +13,7 @@ #import #include "base/display.h" +#include "base/NativeApp.h" #include "Common/TimeUtil.h" #include "file/zip_read.h" #include "Common/Input/InputState.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 769c9d53a5..774e0381ee 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -13,6 +13,7 @@ #include #include "base/display.h" +#include "base/NativeApp.h" #include "Common/TimeUtil.h" #include "file/zip_read.h" #include "Common/Input/InputState.h" From 9e41fafd0d7fd2d8b90c592faacb76f4eeb995cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 00:25:21 +0200 Subject: [PATCH 821/848] Move math and some file and data conversion files out from native to Common. Buildfixing Move some file util files Buildfix Move KeyMap.cpp/h to Core where they belong better. libretro buildfix attempt Move ini_file More buildfixes --- CMakeLists.txt | 59 +++---- Common/Common.vcxproj | 36 ++++- Common/Common.vcxproj.filters | 121 ++++++++++++++- Common/CommonTypes.h | 8 - .../Data/Convert/SmallDataConvert.cpp | 2 +- .../Data/Convert/SmallDataConvert.h | 0 .../Data/Format/IniFile.cpp | 4 +- .../Data/Format/IniFile.h | 0 .../Data/Format/RIFF.cpp | 5 +- .../chunk_file.h => Common/Data/Format/RIFF.h | 2 +- Common/Data/Text/I18n.cpp | 4 +- .../file/free.cpp => Common/File/DiskFree.cpp | 0 .../file/free.h => Common/File/DiskFree.h | 0 .../path.cpp => Common/File/PathBrowser.cpp | 8 +- .../file/path.h => Common/File/PathBrowser.h | 4 +- .../File/VFS/AssetReader.cpp | 146 +----------------- .../File/VFS/AssetReader.h | 2 +- Common/File/VFS/VFS.cpp | 118 ++++++++++++++ .../file/vfs.h => Common/File/VFS/VFS.h | 0 Common/FileUtil.h | 1 + Common/Input/GestureDetector.h | 2 +- Common/Input/InputState.h | 2 +- Common/LogManager.h | 2 +- {ext/native/math => Common/Math}/curves.cpp | 2 +- {ext/native/math => Common/Math}/curves.h | 0 .../Math}/expression_parser.cpp | 24 +-- .../math => Common/Math}/expression_parser.h | 0 .../math => Common/Math}/fast/fast_math.c | 0 .../math => Common/Math}/fast/fast_math.h | 0 .../math => Common/Math}/fast/fast_matrix.c | 0 .../math => Common/Math}/fast/fast_matrix.h | 0 .../Math}/fast/fast_matrix_neon.S | 0 .../Math}/fast/fast_matrix_sse.c | 0 {ext/native/math => Common/Math}/geom2d.h | 0 .../math => Common/Math}/lin/matrix4x4.cpp | 6 +- .../math => Common/Math}/lin/matrix4x4.h | 2 +- .../math => Common/Math}/lin/matrix_neon.s | 0 {ext/native/math => Common/Math}/lin/vec3.cpp | 4 +- {ext/native/math => Common/Math}/lin/vec3.h | 0 .../native/math => Common/Math}/math_util.cpp | 2 +- {ext/native/math => Common/Math}/math_util.h | 0 Common/Vulkan/VulkanMemory.cpp | 2 +- Core/Compatibility.cpp | 3 +- Core/Config.cpp | 4 +- Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 6 + Core/Debugger/DebugInterface.h | 2 +- Core/Dialog/PSPOskDialog.cpp | 2 +- Core/FileLoaders/DiskCachingFileLoader.cpp | 2 +- Core/FileSystems/DirectoryFileSystem.cpp | 4 +- Core/FileSystems/VirtualDiscFileSystem.cpp | 1 - Core/HLE/Plugins.cpp | 2 +- Core/HLE/sceJpeg.cpp | 12 +- Core/HLE/sceUtility.cpp | 2 +- {Common => Core}/KeyMap.cpp | 4 +- {Common => Core}/KeyMap.h | 0 Core/MIPS/ARM/ArmCompVFPU.cpp | 2 +- Core/MIPS/ARM/ArmCompVFPUNEON.cpp | 2 +- Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp | 2 +- Core/MIPS/ARM64/Arm64CompVFPU.cpp | 2 +- Core/MIPS/IR/IRCompVFPU.cpp | 2 +- Core/MIPS/IR/IRInterpreter.cpp | 2 +- Core/MIPS/MIPS.cpp | 2 +- Core/MIPS/MIPSInt.cpp | 2 +- Core/MIPS/MIPSIntVFPU.cpp | 2 +- Core/MIPS/x86/Asm.cpp | 2 +- Core/MIPS/x86/CompVFPU.cpp | 2 +- Core/MIPS/x86/Jit.cpp | 2 +- Core/Reporting.cpp | 5 +- Core/System.cpp | 2 +- Core/TextureReplacer.cpp | 2 +- Core/Util/GameManager.cpp | 2 +- Core/Util/PPGeDraw.cpp | 2 +- GPU/Common/PostShader.cpp | 4 +- GPU/Common/PostShader.h | 2 +- GPU/Common/PresentationCommon.cpp | 4 +- GPU/Common/ShaderUniforms.cpp | 8 +- GPU/Common/SoftwareTransformCommon.cpp | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 2 +- GPU/D3D11/ShaderManagerD3D11.cpp | 6 +- GPU/D3D11/StateMappingD3D11.cpp | 2 +- GPU/D3D11/TextureCacheD3D11.cpp | 2 +- GPU/Directx9/FramebufferManagerDX9.cpp | 2 +- GPU/Directx9/ShaderManagerDX9.cpp | 6 +- GPU/Directx9/ShaderManagerDX9.h | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GLES/ShaderManagerGLES.cpp | 6 +- GPU/GLES/TextureCacheGLES.cpp | 2 +- GPU/Math3D.h | 2 +- GPU/Software/TransformUnit.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 2 +- GPU/Vulkan/FramebufferManagerVulkan.cpp | 4 +- GPU/Vulkan/ShaderManagerVulkan.cpp | 6 +- GPU/Vulkan/ShaderManagerVulkan.h | 2 +- GPU/Vulkan/StateMappingVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 4 +- Qt/QtMain.cpp | 2 +- SDL/SDLJoystick.cpp | 2 +- SDL/SDLMain.cpp | 2 +- UI/BackgroundAudio.cpp | 4 +- UI/ComboKeyMappingScreen.cpp | 8 +- UI/ControlMappingScreen.cpp | 2 +- UI/EmuScreen.cpp | 4 +- UI/EmuScreen.h | 2 +- UI/GameInfoCache.cpp | 3 +- UI/GameSettingsScreen.cpp | 4 +- UI/GamepadEmu.cpp | 2 +- UI/MainScreen.cpp | 5 +- UI/MainScreen.h | 2 +- UI/MiscScreens.cpp | 4 +- UI/NativeApp.cpp | 14 +- UI/OnScreenDisplay.h | 2 +- UI/RemoteISOScreen.cpp | 2 +- UI/SavedataScreen.cpp | 2 +- UI/TextureUtil.cpp | 6 +- UI/TouchControlLayoutScreen.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 36 ++++- UWP/CommonUWP/CommonUWP.vcxproj.filters | 121 ++++++++++++++- UWP/CoreUWP/CoreUWP.vcxproj | 2 + UWP/CoreUWP/CoreUWP.vcxproj.filters | 2 + UWP/NativeUWP/NativeUWP.vcxproj | 143 +---------------- UWP/NativeUWP/NativeUWP.vcxproj.filters | 101 +----------- UWP/PPSSPP_UWPMain.cpp | 10 +- Windows/GEDebugger/SimpleGLWindow.cpp | 2 +- Windows/GEDebugger/VertexPreview.cpp | 2 +- Windows/MainWindow.cpp | 2 +- Windows/MainWindowMenu.cpp | 1 + Windows/MainWindowMenu.h | 1 - Windows/TouchInputHandler.cpp | 2 + Windows/XinputDevice.cpp | 2 +- Windows/main.cpp | 4 +- android/jni/Android.mk | 42 ++--- android/jni/app-android.cpp | 5 +- ext/native/base/display.cpp | 2 +- ext/native/base/display.h | 2 +- ext/native/file/file_util.cpp | 28 ++++ ext/native/file/file_util.h | 6 +- ext/native/gfx_es2/draw_buffer.cpp | 2 +- ext/native/gfx_es2/draw_buffer.h | 4 +- ext/native/gfx_es2/glsl_program.cpp | 4 +- ext/native/image/zim_load.cpp | 4 +- ext/native/json/json_reader.cpp | 3 +- ext/native/native.vcxproj | 34 ---- ext/native/native.vcxproj.filters | 96 ------------ ext/native/thin3d/GLQueueRunner.cpp | 4 +- ext/native/thin3d/GLRenderManager.h | 2 +- ext/native/thin3d/VulkanQueueRunner.h | 2 +- ext/native/thin3d/VulkanRenderManager.h | 4 +- ext/native/thin3d/thin3d_d3d11.cpp | 2 +- ext/native/thin3d/thin3d_d3d9.cpp | 2 +- ext/native/thin3d/thin3d_gl.cpp | 6 +- ext/native/thin3d/thin3d_vulkan.cpp | 4 +- ext/native/ui/ui_context.h | 4 +- ext/native/ui/ui_screen.cpp | 2 +- ext/native/ui/ui_screen.h | 2 +- ext/native/ui/view.h | 6 +- ext/native/ui/viewgroup.cpp | 2 +- ext/native/ui/viewgroup.h | 2 +- headless/SDLHeadlessHost.cpp | 2 +- headless/WindowsHeadlessHost.cpp | 4 +- libretro/Makefile.common | 13 +- libretro/libretro.cpp | 2 +- 162 files changed, 739 insertions(+), 790 deletions(-) rename ext/native/math/dataconv.cpp => Common/Data/Convert/SmallDataConvert.cpp (68%) rename ext/native/math/dataconv.h => Common/Data/Convert/SmallDataConvert.h (100%) rename ext/native/file/ini_file.cpp => Common/Data/Format/IniFile.cpp (99%) rename ext/native/file/ini_file.h => Common/Data/Format/IniFile.h (100%) rename ext/native/file/chunk_file.cpp => Common/Data/Format/RIFF.cpp (96%) rename ext/native/file/chunk_file.h => Common/Data/Format/RIFF.h (94%) rename ext/native/file/free.cpp => Common/File/DiskFree.cpp (100%) rename ext/native/file/free.h => Common/File/DiskFree.h (100%) rename ext/native/file/path.cpp => Common/File/PathBrowser.cpp (99%) rename ext/native/file/path.h => Common/File/PathBrowser.h (93%) rename ext/native/file/zip_read.cpp => Common/File/VFS/AssetReader.cpp (60%) rename ext/native/file/zip_read.h => Common/File/VFS/AssetReader.h (98%) create mode 100644 Common/File/VFS/VFS.cpp rename ext/native/file/vfs.h => Common/File/VFS/VFS.h (100%) rename {ext/native/math => Common/Math}/curves.cpp (98%) rename {ext/native/math => Common/Math}/curves.h (100%) rename {ext/native/math => Common/Math}/expression_parser.cpp (92%) rename {ext/native/math => Common/Math}/expression_parser.h (100%) rename {ext/native/math => Common/Math}/fast/fast_math.c (100%) rename {ext/native/math => Common/Math}/fast/fast_math.h (100%) rename {ext/native/math => Common/Math}/fast/fast_matrix.c (100%) rename {ext/native/math => Common/Math}/fast/fast_matrix.h (100%) rename {ext/native/math => Common/Math}/fast/fast_matrix_neon.S (100%) rename {ext/native/math => Common/Math}/fast/fast_matrix_sse.c (100%) rename {ext/native/math => Common/Math}/geom2d.h (100%) rename {ext/native/math => Common/Math}/lin/matrix4x4.cpp (95%) rename {ext/native/math => Common/Math}/lin/matrix4x4.h (98%) rename {ext/native/math => Common/Math}/lin/matrix_neon.s (100%) rename {ext/native/math => Common/Math}/lin/vec3.cpp (83%) rename {ext/native/math => Common/Math}/lin/vec3.h (100%) rename {ext/native/math => Common/Math}/math_util.cpp (96%) rename {ext/native/math => Common/Math}/math_util.h (100%) rename {Common => Core}/KeyMap.cpp (99%) rename {Common => Core}/KeyMap.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index acbbbe43ac..6bafe8c74b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -437,6 +437,8 @@ add_library(Common STATIC Common/Data/Collections/TinySet.h Common/Data/Color/RGBAUtil.cpp Common/Data/Color/RGBAUtil.h + Common/Data/Convert/SmallDataConvert.cpp + Common/Data/Convert/SmallDataConvert.h Common/Data/Encoding/Base64.cpp Common/Data/Encoding/Base64.h Common/Data/Encoding/Compression.cpp @@ -445,6 +447,10 @@ add_library(Common STATIC Common/Data/Encoding/Utf8.cpp Common/Data/Encoding/Utf8.h Common/Data/Encoding/Utf16.h + Common/Data/Format/RIFF.cpp + Common/Data/Format/RIFF.h + Common/Data/Format/IniFile.cpp + Common/Data/Format/IniFile.h Common/Data/Hash/Hash.cpp Common/Data/Hash/Hash.h Common/Data/Text/I18n.cpp @@ -454,11 +460,33 @@ add_library(Common STATIC Common/Data/Text/WrapText.cpp Common/Data/Text/WrapText.h Common/Data/Random/Rng.h + Common/File/VFS/VFS.h + Common/File/VFS/VFS.cpp + Common/File/VFS/AssetReader.cpp + Common/File/VFS/AssetReader.h + Common/File/DiskFree.h + Common/File/DiskFree.cpp + Common/File/PathBrowser.h + Common/File/PathBrowser.cpp Common/Input/GestureDetector.cpp Common/Input/GestureDetector.h Common/Input/KeyCodes.h Common/Input/InputState.cpp Common/Input/InputState.h + Common/Math/fast/fast_math.c + Common/Math/fast/fast_matrix.c + Common/Math/fast/fast_matrix_neon.S + Common/Math/fast/fast_matrix_sse.c + Common/Math/curves.cpp + Common/Math/curves.h + Common/Math/expression_parser.cpp + Common/Math/expression_parser.h + Common/Math/lin/matrix4x4.cpp + Common/Math/lin/matrix4x4.h + Common/Math/lin/vec3.cpp + Common/Math/lin/vec3.h + Common/Math/math_util.cpp + Common/Math/math_util.h Common/Thread/Executor.cpp Common/Thread/Executor.h Common/Thread/PrioritizedWorkQueue.cpp @@ -486,8 +514,6 @@ add_library(Common STATIC Common/ExceptionHandlerSetup.h Common/FileUtil.cpp Common/FileUtil.h - Common/KeyMap.cpp - Common/KeyMap.h Common/Hashmaps.h Common/Log.h Common/Log.cpp @@ -980,21 +1006,10 @@ add_library(native STATIC ${nativeExtra} ext/native/base/display.cpp ext/native/base/display.h - ext/native/file/chunk_file.cpp - ext/native/file/chunk_file.h ext/native/file/fd_util.cpp ext/native/file/fd_util.h ext/native/file/file_util.cpp ext/native/file/file_util.h - ext/native/file/free.cpp - ext/native/file/free.h - ext/native/file/ini_file.cpp - ext/native/file/ini_file.h - ext/native/file/path.cpp - ext/native/file/path.h - ext/native/file/vfs.h - ext/native/file/zip_read.cpp - ext/native/file/zip_read.h ext/native/gfx/gl_common.h ext/native/gfx/gl_debug_log.cpp ext/native/gfx/gl_debug_log.h @@ -1030,22 +1045,6 @@ add_library(native STATIC ext/native/json/json_reader.cpp ext/native/json/json_writer.h ext/native/json/json_writer.cpp - ext/native/math/fast/fast_math.c - ext/native/math/fast/fast_matrix.c - ext/native/math/fast/fast_matrix_neon.S - ext/native/math/fast/fast_matrix_sse.c - ext/native/math/dataconv.cpp - ext/native/math/dataconv.h - ext/native/math/curves.cpp - ext/native/math/curves.h - ext/native/math/expression_parser.cpp - ext/native/math/expression_parser.h - ext/native/math/lin/matrix4x4.cpp - ext/native/math/lin/matrix4x4.h - ext/native/math/lin/vec3.cpp - ext/native/math/lin/vec3.h - ext/native/math/math_util.cpp - ext/native/math/math_util.h ext/native/net/http_client.cpp ext/native/net/http_client.h ext/native/net/http_headers.cpp @@ -1465,6 +1464,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/HDRemaster.h Core/Instance.cpp Core/Instance.h + Core/KeyMap.cpp + Core/KeyMap.h Core/ThreadEventQueue.h Core/WebServer.cpp Core/WebServer.h diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 5a4aef7e51..d914911c40 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -362,20 +362,35 @@ + + + + + + + + + + + + + + + @@ -420,7 +435,6 @@ - @@ -628,16 +642,31 @@ false + + + + + + + + + + + + + + + @@ -677,7 +706,6 @@ true true - @@ -712,6 +740,10 @@ {f761046e-6c38-4428-a5f1-38391a37bb34} + + + + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 6408cd9512..ae66327176 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -23,7 +23,6 @@ Crypto - @@ -176,6 +175,51 @@ Data\Color + + Data\Convert + + + Math + + + Math + + + Math + + + Math + + + Math\lin + + + Math\lin + + + Math\fast + + + Math\fast + + + Data\Format + + + File + + + File + + + File\VFS + + + File\VFS + + + Data\Format + @@ -195,7 +239,6 @@ Crypto - Crypto @@ -333,6 +376,51 @@ Data\Color + + Data\Convert + + + Math + + + Math + + + Math + + + Math\lin + + + Math\lin + + + Math\fast + + + Math\fast + + + Math\fast + + + Data\Format + + + File + + + File + + + File\VFS + + + File\VFS + + + Data\Format + @@ -383,10 +471,39 @@ {1ada1f0f-6f1c-4bf2-8450-1fc63d77da17} + + {9f70c234-1671-49db-aa45-1a6a75698a40} + + + {98967255-542c-490d-9183-a4b21c074703} + + + {aa083b68-34ed-4679-a8de-1797a00a1772} + + + {ffa5052d-e78f-4c47-a43e-e3537c5e7ad0} + + + {3eebbd6c-0c35-4dac-9869-5d38419432a6} + + + {d9e60709-9bf4-4bc7-b902-742219df7ffb} + + + {b10822cf-4cc0-4bc3-91a9-b20cb66e5cbd} + ext\libpng17 + + + Math\lin + + + Math\fast + + \ No newline at end of file diff --git a/Common/CommonTypes.h b/Common/CommonTypes.h index 93a0c8cb30..ab2b7145af 100644 --- a/Common/CommonTypes.h +++ b/Common/CommonTypes.h @@ -22,14 +22,6 @@ #pragma once -struct u24_be { - unsigned char value[3]; - - operator unsigned int(){ - return 0x00000000 | (value[0] << 16) | (value[1] << 8) | (value[2] << 0); - } -}; - #if defined(_MSC_VER) typedef unsigned __int8 u8; diff --git a/ext/native/math/dataconv.cpp b/Common/Data/Convert/SmallDataConvert.cpp similarity index 68% rename from ext/native/math/dataconv.cpp rename to Common/Data/Convert/SmallDataConvert.cpp index 2fcc339c90..4f0d65ea11 100644 --- a/ext/native/math/dataconv.cpp +++ b/Common/Data/Convert/SmallDataConvert.cpp @@ -1,3 +1,3 @@ -#include "dataconv.h" +#include "Common/Data/Convert/SmallDataConvert.h" alignas(16) const float one_over_255_x4[4] = { 1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f, }; diff --git a/ext/native/math/dataconv.h b/Common/Data/Convert/SmallDataConvert.h similarity index 100% rename from ext/native/math/dataconv.h rename to Common/Data/Convert/SmallDataConvert.h diff --git a/ext/native/file/ini_file.cpp b/Common/Data/Format/IniFile.cpp similarity index 99% rename from ext/native/file/ini_file.cpp rename to Common/Data/Format/IniFile.cpp index d0a5c71bf9..8e001f802d 100644 --- a/ext/native/file/ini_file.cpp +++ b/Common/Data/Format/IniFile.cpp @@ -16,8 +16,8 @@ #include #include -#include "file/ini_file.h" -#include "file/vfs.h" +#include "Common/Data/Format/IniFile.h" +#include "Common/File/VFS/VFS.h" #include "Common/Data/Text/Parsers.h" #ifdef _WIN32 diff --git a/ext/native/file/ini_file.h b/Common/Data/Format/IniFile.h similarity index 100% rename from ext/native/file/ini_file.h rename to Common/Data/Format/IniFile.h diff --git a/ext/native/file/chunk_file.cpp b/Common/Data/Format/RIFF.cpp similarity index 96% rename from ext/native/file/chunk_file.cpp rename to Common/Data/Format/RIFF.cpp index 2dab992913..2ef0576fde 100644 --- a/ext/native/file/chunk_file.cpp +++ b/Common/Data/Format/RIFF.cpp @@ -1,8 +1,5 @@ -#include "file/chunk_file.h" -#include "file/zip_read.h" -#include "file/file_util.h" - #include "Common/Log.h" +#include "Common/Data/Format/RIFF.h" inline uint32_t flipID(uint32_t id) { return ((id >> 24) & 0xFF) | ((id >> 8) & 0xFF00) | ((id << 8) & 0xFF0000) | ((id << 24) & 0xFF000000); diff --git a/ext/native/file/chunk_file.h b/Common/Data/Format/RIFF.h similarity index 94% rename from ext/native/file/chunk_file.h rename to Common/Data/Format/RIFF.h index ebc2db99a4..ab1b5c020f 100644 --- a/ext/native/file/chunk_file.h +++ b/Common/Data/Format/RIFF.h @@ -1,6 +1,6 @@ #pragma once -// Simple RIFF file format reader/writer. +// Simple RIFF file format reader. // Unrelated to the ChunkFile.h used in Dolphin and PPSSPP. // TO REMEMBER WHEN USING: diff --git a/Common/Data/Text/I18n.cpp b/Common/Data/Text/I18n.cpp index e0bd685049..72e16a6eb6 100644 --- a/Common/Data/Text/I18n.cpp +++ b/Common/Data/Text/I18n.cpp @@ -1,6 +1,6 @@ #include "Common/Data/Text/I18n.h" -#include "file/ini_file.h" -#include "file/vfs.h" +#include "Common/Data/Format/IniFile.h" +#include "Common/File/VFS/VFS.h" #include "Common/StringUtils.h" diff --git a/ext/native/file/free.cpp b/Common/File/DiskFree.cpp similarity index 100% rename from ext/native/file/free.cpp rename to Common/File/DiskFree.cpp diff --git a/ext/native/file/free.h b/Common/File/DiskFree.h similarity index 100% rename from ext/native/file/free.h rename to Common/File/DiskFree.h diff --git a/ext/native/file/path.cpp b/Common/File/PathBrowser.cpp similarity index 99% rename from ext/native/file/path.cpp rename to Common/File/PathBrowser.cpp index e7be80c609..0e02907b46 100644 --- a/ext/native/file/path.cpp +++ b/Common/File/PathBrowser.cpp @@ -2,12 +2,12 @@ #include #include -#include "Common/StringUtils.h" -#include "Common/TimeUtil.h" - -#include "file/path.h" #include "net/http_client.h" #include "net/url.h" + +#include "Common/File/PathBrowser.h" +#include "Common/StringUtils.h" +#include "Common/TimeUtil.h" #include "Common/Thread/ThreadUtil.h" bool LoadRemoteFileList(const std::string &url, bool *cancel, std::vector &files) { diff --git a/ext/native/file/path.h b/Common/File/PathBrowser.h similarity index 93% rename from ext/native/file/path.h rename to Common/File/PathBrowser.h index ed14962156..bdbce21250 100644 --- a/ext/native/file/path.h +++ b/Common/File/PathBrowser.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include @@ -36,7 +36,7 @@ public: // Do nothing #elif defined(__linux) char *home = getenv("HOME"); - if (home != NULL && !strncmp(str.c_str(), home, strlen(home))) { + if (home != nullptr && !strncmp(str.c_str(), home, strlen(home))) { str = str.substr(strlen(home)); str.insert(0, 1, '~'); } diff --git a/ext/native/file/zip_read.cpp b/Common/File/VFS/AssetReader.cpp similarity index 60% rename from ext/native/file/zip_read.cpp rename to Common/File/VFS/AssetReader.cpp index 45acc56f9b..1fec28922b 100644 --- a/ext/native/file/zip_read.cpp +++ b/Common/File/VFS/AssetReader.cpp @@ -7,10 +7,9 @@ #include #endif -#include "file/zip_read.h" - #include "Common/Common.h" #include "Common/Log.h" +#include "Common/File/VFS/AssetReader.h" #ifdef __ANDROID__ uint8_t *ReadFromZip(zip *archive, const char* filename, size_t *size) { @@ -34,34 +33,6 @@ uint8_t *ReadFromZip(zip *archive, const char* filename, size_t *size) { #endif -// The return is non-const because - why not? -uint8_t *ReadLocalFile(const char *filename, size_t *size) { - FILE *file = openCFile(filename, "rb"); - if (!file) { - *size = 0; - return nullptr; - } - fseek(file, 0, SEEK_END); - size_t f_size = ftell(file); - if ((long)f_size < 0) { - *size = 0; - fclose(file); - return nullptr; - } - fseek(file, 0, SEEK_SET); - uint8_t *contents = new uint8_t[f_size+1]; - if (fread(contents, 1, f_size, file) != f_size) { - delete [] contents; - contents = nullptr; - *size = 0; - } else { - contents[f_size] = 0; - *size = f_size; - } - fclose(file); - return contents; -} - #ifdef __ANDROID__ ZipAssetReader::ZipAssetReader(const char *zip_file, const char *in_zip_path) { @@ -258,118 +229,3 @@ bool DirectoryAssetReader::GetFileInfo(const char *path, FileInfo *info) strcat(new_path, path); return getFileInfo(new_path, info); } - -struct VFSEntry { - const char *prefix; - AssetReader *reader; -}; - -static VFSEntry entries[16]; -static int num_entries = 0; - -void VFSRegister(const char *prefix, AssetReader *reader) { - entries[num_entries].prefix = prefix; - entries[num_entries].reader = reader; - DEBUG_LOG(IO, "Registered VFS for prefix %s: %s", prefix, reader->toString().c_str()); - num_entries++; -} - -void VFSShutdown() { - for (int i = 0; i < num_entries; i++) { - delete entries[i].reader; - } - num_entries = 0; -} - -static bool IsLocalPath(const char *path) { - bool isUnixLocal = path[0] == '/'; -#ifdef _WIN32 - bool isWindowsLocal = isalpha(path[0]) && path[1] == ':'; -#else - bool isWindowsLocal = false; -#endif - return isUnixLocal || isWindowsLocal; -} - -// The returned data should be free'd with delete[]. -uint8_t *VFSReadFile(const char *filename, size_t *size) { - if (IsLocalPath(filename)) { - // Local path, not VFS. - // INFO_LOG(IO, "Not a VFS path: %s . Reading local file.", filename); - return ReadLocalFile(filename, size); - } - - int fn_len = (int)strlen(filename); - bool fileSystemFound = false; - for (int i = 0; i < num_entries; i++) { - int prefix_len = (int)strlen(entries[i].prefix); - if (prefix_len >= fn_len) continue; - if (0 == memcmp(filename, entries[i].prefix, prefix_len)) { - fileSystemFound = true; - // INFO_LOG(IO, "Prefix match: %s (%s) -> %s", entries[i].prefix, filename, filename + prefix_len); - uint8_t *data = entries[i].reader->ReadAsset(filename + prefix_len, size); - if (data) - return data; - else - continue; - // Else try the other registered file systems. - } - } - if (!fileSystemFound) { - ERROR_LOG(IO, "Missing filesystem for '%s'", filename); - } // Otherwise, the file was just missing. No need to log. - return 0; -} - -bool VFSGetFileListing(const char *path, std::vector *listing, const char *filter) { - if (IsLocalPath(path)) { - // Local path, not VFS. - // INFO_LOG(IO, "Not a VFS path: %s . Reading local directory.", path); - getFilesInDir(path, listing, filter); - return true; - } - - int fn_len = (int)strlen(path); - bool fileSystemFound = false; - for (int i = 0; i < num_entries; i++) { - int prefix_len = (int)strlen(entries[i].prefix); - if (prefix_len >= fn_len) continue; - if (0 == memcmp(path, entries[i].prefix, prefix_len)) { - fileSystemFound = true; - if (entries[i].reader->GetFileListing(path + prefix_len, listing, filter)) { - return true; - } - } - } - - if (!fileSystemFound) { - ERROR_LOG(IO, "Missing filesystem for %s", path); - } // Otherwise, the file was just missing. No need to log. - return false; -} - -bool VFSGetFileInfo(const char *path, FileInfo *info) { - if (IsLocalPath(path)) { - // Local path, not VFS. - // INFO_LOG(IO, "Not a VFS path: %s . Getting local file info.", path); - return getFileInfo(path, info); - } - - bool fileSystemFound = false; - int fn_len = (int)strlen(path); - for (int i = 0; i < num_entries; i++) { - int prefix_len = (int)strlen(entries[i].prefix); - if (prefix_len >= fn_len) continue; - if (0 == memcmp(path, entries[i].prefix, prefix_len)) { - fileSystemFound = true; - if (entries[i].reader->GetFileInfo(path + prefix_len, info)) - return true; - else - continue; - } - } - if (!fileSystemFound) { - ERROR_LOG(IO, "Missing filesystem for %s", path); - } // Otherwise, the file was just missing. No need to log. - return false; -} diff --git a/ext/native/file/zip_read.h b/Common/File/VFS/AssetReader.h similarity index 98% rename from ext/native/file/zip_read.h rename to Common/File/VFS/AssetReader.h index 086fc43775..76b5a31439 100644 --- a/ext/native/file/zip_read.h +++ b/Common/File/VFS/AssetReader.h @@ -8,7 +8,7 @@ #include #include -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "file/file_util.h" // Direct readers. deallocate using delete []. diff --git a/Common/File/VFS/VFS.cpp b/Common/File/VFS/VFS.cpp new file mode 100644 index 0000000000..0353169d79 --- /dev/null +++ b/Common/File/VFS/VFS.cpp @@ -0,0 +1,118 @@ +#include "Common/Log.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" + +struct VFSEntry { + const char *prefix; + AssetReader *reader; +}; + +static VFSEntry entries[16]; +static int num_entries = 0; + +void VFSRegister(const char *prefix, AssetReader *reader) { + entries[num_entries].prefix = prefix; + entries[num_entries].reader = reader; + DEBUG_LOG(IO, "Registered VFS for prefix %s: %s", prefix, reader->toString().c_str()); + num_entries++; +} + +void VFSShutdown() { + for (int i = 0; i < num_entries; i++) { + delete entries[i].reader; + } + num_entries = 0; +} + +static bool IsLocalPath(const char *path) { + bool isUnixLocal = path[0] == '/'; +#ifdef _WIN32 + bool isWindowsLocal = isalpha(path[0]) && path[1] == ':'; +#else + bool isWindowsLocal = false; +#endif + return isUnixLocal || isWindowsLocal; +} + +// The returned data should be free'd with delete[]. +uint8_t *VFSReadFile(const char *filename, size_t *size) { + if (IsLocalPath(filename)) { + // Local path, not VFS. + // INFO_LOG(IO, "Not a VFS path: %s . Reading local file.", filename); + return ReadLocalFile(filename, size); + } + + int fn_len = (int)strlen(filename); + bool fileSystemFound = false; + for (int i = 0; i < num_entries; i++) { + int prefix_len = (int)strlen(entries[i].prefix); + if (prefix_len >= fn_len) continue; + if (0 == memcmp(filename, entries[i].prefix, prefix_len)) { + fileSystemFound = true; + // INFO_LOG(IO, "Prefix match: %s (%s) -> %s", entries[i].prefix, filename, filename + prefix_len); + uint8_t *data = entries[i].reader->ReadAsset(filename + prefix_len, size); + if (data) + return data; + else + continue; + // Else try the other registered file systems. + } + } + if (!fileSystemFound) { + ERROR_LOG(IO, "Missing filesystem for '%s'", filename); + } // Otherwise, the file was just missing. No need to log. + return 0; +} + +bool VFSGetFileListing(const char *path, std::vector *listing, const char *filter) { + if (IsLocalPath(path)) { + // Local path, not VFS. + // INFO_LOG(IO, "Not a VFS path: %s . Reading local directory.", path); + getFilesInDir(path, listing, filter); + return true; + } + + int fn_len = (int)strlen(path); + bool fileSystemFound = false; + for (int i = 0; i < num_entries; i++) { + int prefix_len = (int)strlen(entries[i].prefix); + if (prefix_len >= fn_len) continue; + if (0 == memcmp(path, entries[i].prefix, prefix_len)) { + fileSystemFound = true; + if (entries[i].reader->GetFileListing(path + prefix_len, listing, filter)) { + return true; + } + } + } + + if (!fileSystemFound) { + ERROR_LOG(IO, "Missing filesystem for %s", path); + } // Otherwise, the file was just missing. No need to log. + return false; +} + +bool VFSGetFileInfo(const char *path, FileInfo *info) { + if (IsLocalPath(path)) { + // Local path, not VFS. + // INFO_LOG(IO, "Not a VFS path: %s . Getting local file info.", path); + return getFileInfo(path, info); + } + + bool fileSystemFound = false; + int fn_len = (int)strlen(path); + for (int i = 0; i < num_entries; i++) { + int prefix_len = (int)strlen(entries[i].prefix); + if (prefix_len >= fn_len) continue; + if (0 == memcmp(path, entries[i].prefix, prefix_len)) { + fileSystemFound = true; + if (entries[i].reader->GetFileInfo(path + prefix_len, info)) + return true; + else + continue; + } + } + if (!fileSystemFound) { + ERROR_LOG(IO, "Missing filesystem for %s", path); + } // Otherwise, the file was just missing. No need to log. + return false; +} diff --git a/ext/native/file/vfs.h b/Common/File/VFS/VFS.h similarity index 100% rename from ext/native/file/vfs.h rename to Common/File/VFS/VFS.h diff --git a/Common/FileUtil.h b/Common/FileUtil.h index f9f86433a7..59552d56a5 100644 --- a/Common/FileUtil.h +++ b/Common/FileUtil.h @@ -114,6 +114,7 @@ bool SetCurrentDir(const std::string &directory); const std::string &GetExeDirectory(); + // simple wrapper for cstdlib file functions to // hopefully will make error checking easier // and make forgetting an fclose() harder diff --git a/Common/Input/GestureDetector.h b/Common/Input/GestureDetector.h index 908f960769..5d4e54f36e 100644 --- a/Common/Input/GestureDetector.h +++ b/Common/Input/GestureDetector.h @@ -1,5 +1,5 @@ #include "Common/Input/InputState.h" -#include "math/geom2d.h" +#include "Common/Math/geom2d.h" // Mainly for detecting (multi-)touch gestures but also useable for left button mouse dragging etc. // Currently only supports simple scroll-drags with inertia. diff --git a/Common/Input/InputState.h b/Common/Input/InputState.h index 175d6786df..59a0a6e057 100644 --- a/Common/Input/InputState.h +++ b/Common/Input/InputState.h @@ -7,7 +7,7 @@ #include #include -#include "math/lin/vec3.h" +#include "Common/Math/lin/vec3.h" #include "Common/Input/KeyCodes.h" // Default device IDs diff --git a/Common/LogManager.h b/Common/LogManager.h index 346561430f..9fcff28d80 100644 --- a/Common/LogManager.h +++ b/Common/LogManager.h @@ -23,7 +23,7 @@ #include #include -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" #include "Common/CommonFuncs.h" #include "Common/Log.h" diff --git a/ext/native/math/curves.cpp b/Common/Math/curves.cpp similarity index 98% rename from ext/native/math/curves.cpp rename to Common/Math/curves.cpp index 65dae53f5e..2488ba5c30 100644 --- a/ext/native/math/curves.cpp +++ b/Common/Math/curves.cpp @@ -1,7 +1,7 @@ #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "curves.h" #include "Common/Common.h" diff --git a/ext/native/math/curves.h b/Common/Math/curves.h similarity index 100% rename from ext/native/math/curves.h rename to Common/Math/curves.h diff --git a/ext/native/math/expression_parser.cpp b/Common/Math/expression_parser.cpp similarity index 92% rename from ext/native/math/expression_parser.cpp rename to Common/Math/expression_parser.cpp index 2c277c000a..9499cce7e0 100644 --- a/ext/native/math/expression_parser.cpp +++ b/Common/Math/expression_parser.cpp @@ -244,7 +244,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf isFloat = true; else if (parseNumber(subStr,16,subPos,value) == false) { - sprintf(expressionError,"Invalid number \"%s\"",subStr); + snprintf(expressionError, sizeof(expressionError), "Invalid number \"%s\"",subStr); return false; } @@ -273,14 +273,14 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf continue; } - sprintf(expressionError,"Invalid symbol \"%s\"",subStr); + snprintf(expressionError, sizeof(expressionError), "Invalid symbol \"%s\"",subStr); return false; } else { int len; ExpressionOpcodeType type = getExpressionOpcode(&infix[infixPos],len,lastOpcode); if (type == EXOP_NONE) { - sprintf(expressionError,"Invalid operator at \"%s\"",&infix[infixPos]); + snprintf(expressionError, sizeof(expressionError), "Invalid operator at \"%s\"",&infix[infixPos]); return false; } @@ -295,7 +295,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf { if (opcodeStack.empty()) { - sprintf(expressionError,"Closing parenthesis without opening one"); + snprintf(expressionError, sizeof(expressionError), "Closing parenthesis without opening one"); return false; } ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; @@ -309,7 +309,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf { if (opcodeStack.empty()) { - sprintf(expressionError,"Closing bracket without opening one"); + snprintf(expressionError, sizeof(expressionError), "Closing bracket without opening one"); return false; } ExpressionOpcodeType t = opcodeStack[opcodeStack.size()-1]; @@ -362,7 +362,7 @@ bool initPostfixExpression(const char* infix, IExpressionFunctions* funcs, Postf if (t == EXOP_BRACKETL) // opening bracket without closing one { - sprintf(expressionError,"Parenthesis not closed"); + snprintf(expressionError, sizeof(expressionError), "Parenthesis not closed"); return false; } dest.push_back(ExpressionPair(EXCOMM_OP,t)); @@ -421,7 +421,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, opcode = exp[num++].second; if (valueStack.size() < ExpressionOpcodes[opcode].args) { - sprintf(expressionError,"Not enough arguments"); + snprintf(expressionError, sizeof(expressionError), "Not enough arguments"); return false; } for (int l = 0; l < ExpressionOpcodes[opcode].args; l++) @@ -437,7 +437,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_MEMSIZE: // must be followed by EXOP_MEM if (exp[num++].second != EXOP_MEM) { - sprintf(expressionError,"Invalid memsize operator"); + snprintf(expressionError, sizeof(expressionError), "Invalid memsize operator"); return false; } @@ -481,7 +481,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_DIV: // a/b if (arg[0] == 0) { - sprintf(expressionError,"Division by zero"); + snprintf(expressionError, sizeof(expressionError), "Division by zero"); return false; } if (useFloat) @@ -492,7 +492,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_MOD: // a%b if (arg[0] == 0) { - sprintf(expressionError,"Modulo by zero"); + snprintf(expressionError, sizeof(expressionError), "Modulo by zero"); return false; } valueStack.push_back(arg[1]%arg[0]); @@ -565,7 +565,7 @@ bool parsePostfixExpression(PostfixExpression& exp, IExpressionFunctions* funcs, case EXOP_TERTELSE: // exp ? exp : exp, else muss zuerst kommen! if (exp[num++].second != EXOP_TERTIF) { - sprintf(expressionError,"Invalid tertiary operator"); + snprintf(expressionError, sizeof(expressionError), "Invalid tertiary operator"); return false; } valueStack.push_back(arg[2]?arg[1]:arg[0]); @@ -589,6 +589,6 @@ bool parseExpression(char* exp, IExpressionFunctions* funcs, uint32_t& dest) const char* getExpressionError() { - if (expressionError[0] == 0) strcpy(expressionError,"Invalid expression"); + if (expressionError[0] == 0) snprintf(expressionError, sizeof(expressionError), "Invalid expression"); return expressionError; } diff --git a/ext/native/math/expression_parser.h b/Common/Math/expression_parser.h similarity index 100% rename from ext/native/math/expression_parser.h rename to Common/Math/expression_parser.h diff --git a/ext/native/math/fast/fast_math.c b/Common/Math/fast/fast_math.c similarity index 100% rename from ext/native/math/fast/fast_math.c rename to Common/Math/fast/fast_math.c diff --git a/ext/native/math/fast/fast_math.h b/Common/Math/fast/fast_math.h similarity index 100% rename from ext/native/math/fast/fast_math.h rename to Common/Math/fast/fast_math.h diff --git a/ext/native/math/fast/fast_matrix.c b/Common/Math/fast/fast_matrix.c similarity index 100% rename from ext/native/math/fast/fast_matrix.c rename to Common/Math/fast/fast_matrix.c diff --git a/ext/native/math/fast/fast_matrix.h b/Common/Math/fast/fast_matrix.h similarity index 100% rename from ext/native/math/fast/fast_matrix.h rename to Common/Math/fast/fast_matrix.h diff --git a/ext/native/math/fast/fast_matrix_neon.S b/Common/Math/fast/fast_matrix_neon.S similarity index 100% rename from ext/native/math/fast/fast_matrix_neon.S rename to Common/Math/fast/fast_matrix_neon.S diff --git a/ext/native/math/fast/fast_matrix_sse.c b/Common/Math/fast/fast_matrix_sse.c similarity index 100% rename from ext/native/math/fast/fast_matrix_sse.c rename to Common/Math/fast/fast_matrix_sse.c diff --git a/ext/native/math/geom2d.h b/Common/Math/geom2d.h similarity index 100% rename from ext/native/math/geom2d.h rename to Common/Math/geom2d.h diff --git a/ext/native/math/lin/matrix4x4.cpp b/Common/Math/lin/matrix4x4.cpp similarity index 95% rename from ext/native/math/lin/matrix4x4.cpp rename to Common/Math/lin/matrix4x4.cpp index b514714573..e341210cee 100644 --- a/ext/native/math/lin/matrix4x4.cpp +++ b/Common/Math/lin/matrix4x4.cpp @@ -1,9 +1,9 @@ -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" #include -#include "math/lin/vec3.h" -#include "math/fast/fast_matrix.h" +#include "Common/Math/lin/vec3.h" +#include "Common/Math/fast/fast_matrix.h" #ifdef _WIN32 #undef far diff --git a/ext/native/math/lin/matrix4x4.h b/Common/Math/lin/matrix4x4.h similarity index 98% rename from ext/native/math/lin/matrix4x4.h rename to Common/Math/lin/matrix4x4.h index 70644a80f6..575b6a61d4 100644 --- a/ext/native/math/lin/matrix4x4.h +++ b/Common/Math/lin/matrix4x4.h @@ -1,7 +1,7 @@ #ifndef _MATH_LIN_MATRIX4X4_H #define _MATH_LIN_MATRIX4X4_H -#include "math/lin/vec3.h" +#include "Common/Math/lin/vec3.h" namespace Lin { diff --git a/ext/native/math/lin/matrix_neon.s b/Common/Math/lin/matrix_neon.s similarity index 100% rename from ext/native/math/lin/matrix_neon.s rename to Common/Math/lin/matrix_neon.s diff --git a/ext/native/math/lin/vec3.cpp b/Common/Math/lin/vec3.cpp similarity index 83% rename from ext/native/math/lin/vec3.cpp rename to Common/Math/lin/vec3.cpp index 7c66339cda..8329e2191e 100644 --- a/ext/native/math/lin/vec3.cpp +++ b/Common/Math/lin/vec3.cpp @@ -1,7 +1,7 @@ #include -#include "math/lin/vec3.h" -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/vec3.h" +#include "Common/Math/lin/matrix4x4.h" namespace Lin { diff --git a/ext/native/math/lin/vec3.h b/Common/Math/lin/vec3.h similarity index 100% rename from ext/native/math/lin/vec3.h rename to Common/Math/lin/vec3.h diff --git a/ext/native/math/math_util.cpp b/Common/Math/math_util.cpp similarity index 96% rename from ext/native/math/math_util.cpp rename to Common/Math/math_util.cpp index 11eb15b215..9b1a59a755 100644 --- a/ext/native/math/math_util.cpp +++ b/Common/Math/math_util.cpp @@ -1,4 +1,4 @@ -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include // QNX can only use RunFast mode and it is already the default. diff --git a/ext/native/math/math_util.h b/Common/Math/math_util.h similarity index 100% rename from ext/native/math/math_util.h rename to Common/Math/math_util.h diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index 74cd1cb660..9674fb702a 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -18,7 +18,7 @@ // Additionally, Common/Vulkan/* , including this file, are also licensed // under the public domain. -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/Log.h" #include "Common/TimeUtil.h" diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 547ebb5925..bd7c044c8b 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -16,7 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "file/ini_file.h" + +#include "Common/Data/Format/IniFile.h" #include "Core/Compatibility.h" #include "Core/System.h" diff --git a/Core/Config.cpp b/Core/Config.cpp index 8f56969908..98a70cfab6 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -25,7 +25,7 @@ #include "ppsspp_config.h" #include "base/display.h" #include "base/NativeApp.h" -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" #include "Common/Data/Text/I18n.h" #include "json/json_reader.h" #include "gfx_es2/gpu_features.h" @@ -35,7 +35,6 @@ #include "Common/CPUDetect.h" #include "Common/FileUtil.h" -#include "Common/KeyMap.h" #include "Common/LogManager.h" #include "Common/OSVersion.h" #include "Common/StringUtils.h" @@ -43,6 +42,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Loaders.h" +#include "Core/KeyMap.h" #include "Core/HLE/sceUtility.h" #include "Core/Instance.h" #include "GPU/Common/FramebufferManagerCommon.h" diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index d1cb94b914..2fc9e33ae1 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -453,6 +453,7 @@ + @@ -996,6 +997,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 611c164009..f59875b48c 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -959,6 +959,9 @@ Ext\libzip + + Core + @@ -1637,6 +1640,9 @@ Ext\libzip + + Core + diff --git a/Core/Debugger/DebugInterface.h b/Core/Debugger/DebugInterface.h index 0b98e1d512..6f48c7db0f 100644 --- a/Core/Debugger/DebugInterface.h +++ b/Core/Debugger/DebugInterface.h @@ -19,7 +19,7 @@ #include #include #include "Common/CommonTypes.h" -#include "math/expression_parser.h" +#include "Common/Math/expression_parser.h" struct MemMap; diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index cf52cd9fe0..add21d1cdd 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -18,7 +18,7 @@ #include #include "base/NativeApp.h" #include "Common/Data/Text/I18n.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/FileLoaders/DiskCachingFileLoader.cpp b/Core/FileLoaders/DiskCachingFileLoader.cpp index fc2991b399..ee028f662d 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.cpp +++ b/Core/FileLoaders/DiskCachingFileLoader.cpp @@ -23,8 +23,8 @@ #include "ppsspp_config.h" #include "file/file_util.h" -#include "file/free.h" #include "Common/Data/Encoding/Utf8.h" +#include "Common/File/DiskFree.h" #include "Common/FileUtil.h" #include "Common/CommonWindows.h" #include "Core/FileLoaders/DiskCachingFileLoader.h" diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index b4c3ca2260..0389244e0f 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -20,14 +20,14 @@ #include #include -#include "file/free.h" -#include "file/zip_read.h" #include "Common/Data/Text/I18n.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" #include "Common/FileUtil.h" +#include "Common/File/DiskFree.h" +#include "Common/File/VFS/VFS.h" #include "Core/FileSystems/DirectoryFileSystem.h" #include "Core/FileSystems/ISOFileSystem.h" #include "Core/HLE/sceKernel.h" diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index c713d9965c..7aaef4327c 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -25,7 +25,6 @@ #include "Core/FileSystems/ISOFileSystem.h" #include "Core/HLE/sceKernel.h" #include "Core/Reporting.h" -#include "file/zip_read.h" #include "Common/Data/Encoding/Utf8.h" #ifdef _WIN32 diff --git a/Core/HLE/Plugins.cpp b/Core/HLE/Plugins.cpp index 5f22e9fc37..9572d6e5ea 100644 --- a/Core/HLE/Plugins.cpp +++ b/Core/HLE/Plugins.cpp @@ -17,7 +17,7 @@ #include #include "file/file_util.h" -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" #include "Common/FileUtil.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" diff --git a/Core/HLE/sceJpeg.cpp b/Core/HLE/sceJpeg.cpp index aa6d554ded..4230675599 100644 --- a/Core/HLE/sceJpeg.cpp +++ b/Core/HLE/sceJpeg.cpp @@ -29,12 +29,20 @@ #include "Core/MemMap.h" #include "Core/Reporting.h" -//Uncomment if you want to dump JPEGs loaded through sceJpeg to a file -//#define JPEG_DEBUG +// Uncomment if you want to dump JPEGs loaded through sceJpeg to a file +// #define JPEG_DEBUG #ifdef JPEG_DEBUG #include "ext/xxhash.h" #endif +struct u24_be { + unsigned char value[3]; + + operator unsigned int() { + return 0x00000000 | (value[0] << 16) | (value[1] << 8) | (value[2] << 0); + } +}; + static int mjpegWidth, mjpegHeight; void __JpegInit() { diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index bc738beebb..966ed2d6c1 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -18,7 +18,7 @@ #include #include -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Common/KeyMap.cpp b/Core/KeyMap.cpp similarity index 99% rename from Common/KeyMap.cpp rename to Core/KeyMap.cpp index 408e8a3124..20d04b9599 100644 --- a/Common/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -27,13 +27,13 @@ #include "ppsspp_config.h" #include "base/NativeApp.h" -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" #include "Common/Input/InputState.h" #include "Common/Log.h" -#include "Common/KeyMap.h" #include "Common/StringUtils.h" #include "Core/HLE/sceUtility.h" #include "Core/Config.h" +#include "Core/KeyMap.h" namespace KeyMap { diff --git a/Common/KeyMap.h b/Core/KeyMap.h similarity index 100% rename from Common/KeyMap.h rename to Core/KeyMap.h diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index 979baedfaa..4291f694f2 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -19,7 +19,7 @@ #if PPSSPP_ARCH(ARM) #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Core/Compatibility.h" #include "Core/Config.h" diff --git a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp index 990e36e293..34bd76f055 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEON.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEON.cpp @@ -30,7 +30,7 @@ #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/CPUDetect.h" #include "Core/MemMap.h" diff --git a/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp b/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp index 7fada69a92..5a6f727456 100644 --- a/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp +++ b/Core/MIPS/ARM/ArmCompVFPUNEONUtil.cpp @@ -30,7 +30,7 @@ #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/CPUDetect.h" #include "Core/MemMap.h" diff --git a/Core/MIPS/ARM64/Arm64CompVFPU.cpp b/Core/MIPS/ARM64/Arm64CompVFPU.cpp index b297f139e4..6b6e26eca7 100644 --- a/Core/MIPS/ARM64/Arm64CompVFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompVFPU.cpp @@ -19,7 +19,7 @@ #if PPSSPP_ARCH(ARM64) #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Core/Compatibility.h" #include "Core/Config.h" diff --git a/Core/MIPS/IR/IRCompVFPU.cpp b/Core/MIPS/IR/IRCompVFPU.cpp index 13fa39b2c2..054594f4c5 100644 --- a/Core/MIPS/IR/IRCompVFPU.cpp +++ b/Core/MIPS/IR/IRCompVFPU.cpp @@ -17,7 +17,7 @@ #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/CPUDetect.h" #include "Core/Compatibility.h" diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index 63a1d57189..aa962dbb5e 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -2,7 +2,7 @@ #include #include "ppsspp_config.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/Common.h" #include "Common/BitScan.h" diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index a85e5a9999..37210c8c5d 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -18,7 +18,7 @@ #include #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index 49847dc4a5..b49dab057f 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -17,7 +17,7 @@ #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/BitSet.h" #include "Common/BitScan.h" diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index bc8d698c59..a9c3b66832 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -21,7 +21,7 @@ #include #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Core/Compatibility.h" #include "Core/Core.h" diff --git a/Core/MIPS/x86/Asm.cpp b/Core/MIPS/x86/Asm.cpp index a70a414049..a099e1044b 100644 --- a/Core/MIPS/x86/Asm.cpp +++ b/Core/MIPS/x86/Asm.cpp @@ -18,7 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "ABI.h" #include "x64Emitter.h" diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index de23b3b2d2..f2cd64fd45 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -25,7 +25,7 @@ #include #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/CPUDetect.h" #include "Common/Log.h" diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index fb4ec02292..21e57bf525 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -21,7 +21,7 @@ #include #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "profiler/profiler.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 86d73612ed..449070cf6a 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -24,7 +24,7 @@ #include #include "Core/Reporting.h" - +#include "Common/File/VFS/VFS.h" #include "Common/CPUDetect.h" #include "Common/FileUtil.h" #include "Common/Serialize/SerializeFuncs.h" @@ -47,9 +47,8 @@ #include "net/http_client.h" #include "net/resolve.h" #include "net/url.h" - +#include "file/file_util.h" #include "Common/Thread/ThreadUtil.h" -#include "file/zip_read.h" namespace Reporting { diff --git a/Core/System.cpp b/Core/System.cpp index e812043278..a9f68c324b 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -33,7 +33,7 @@ #include #include "base/NativeApp.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 56a3f743f9..c2f8a15533 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -25,7 +25,7 @@ #include "Common/Data/Text/I18n.h" #include "ext/xxhash.h" -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" #include "Common/Data/Text/Parsers.h" #include "Common/ColorConv.h" #include "Common/FileUtil.h" diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 3c943bda9a..c0e6b5eb0e 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -30,7 +30,7 @@ #include "ext/libzip/zip.h" #endif #include "Common/Data/Encoding/Utf8.h" -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" #include "Common/Log.h" #include "Common/FileUtil.h" diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 17881b5204..61507801cb 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -18,7 +18,7 @@ #include #include "Common/Data/Color/RGBAUtil.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_text.h" #include "image/zim_load.h" diff --git a/GPU/Common/PostShader.cpp b/GPU/Common/PostShader.cpp index 3a91e60695..1e650b9db1 100644 --- a/GPU/Common/PostShader.cpp +++ b/GPU/Common/PostShader.cpp @@ -22,9 +22,9 @@ #include #include -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" #include "file/file_util.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "gfx_es2/gpu_features.h" #include "Common/StringUtils.h" diff --git a/GPU/Common/PostShader.h b/GPU/Common/PostShader.h index 3ad0d50485..42aa30d4bc 100644 --- a/GPU/Common/PostShader.h +++ b/GPU/Common/PostShader.h @@ -22,7 +22,7 @@ #include #include -#include "file/ini_file.h" +#include "Common/Data/Format/IniFile.h" struct ShaderInfo { std::string iniFile; // which ini file was this definition in? So we can write settings back later diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 53c09b9d04..7c8266624b 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -21,9 +21,9 @@ #include "base/display.h" #include "base/NativeApp.h" -#include "file/vfs.h" -#include "file/zip_read.h" #include "thin3d/thin3d.h" + +#include "Common/File/VFS/VFS.h" #include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 352ae43ddc..f266721050 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -3,10 +3,10 @@ #include "ShaderUniforms.h" #include "base/display.h" -#include "math/dataconv.h" -#include "math/lin/matrix4x4.h" -#include "math/math_util.h" -#include "math/lin/vec3.h" +#include "Common/Data/Convert/SmallDataConvert.h" +#include "Common/Math/lin/matrix4x4.h" +#include "Common/Math/math_util.h" +#include "Common/Math/lin/vec3.h" #include "GPU/GPUState.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/GPUStateUtils.h" diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 92d570019a..2f68d891e0 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -17,7 +17,7 @@ #include #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "gfx_es2/gpu_features.h" #include "Core/Config.h" diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index b48d67529b..83a2beab65 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -20,7 +20,7 @@ #include #include "base/display.h" -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" #include "ext/native/thin3d/thin3d.h" #include "Common/Common.h" diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index 81b093f11d..a6c23e1c9d 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -22,9 +22,9 @@ #include -#include "math/lin/matrix4x4.h" -#include "math/math_util.h" -#include "math/dataconv.h" +#include "Common/Math/lin/matrix4x4.h" +#include "Common/Math/math_util.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "thin3d/thin3d.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Log.h" diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index fc2fd6971e..8ef3d2c574 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -20,7 +20,7 @@ #include -#include "math/dataconv.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index ffbf31b6e1..5dd5e50bf4 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -36,7 +36,7 @@ #include "Core/Host.h" #include "ext/xxhash.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #define INVALID_TEX (ID3D11ShaderResourceView *)(-1LL) diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index be7f751eda..21cfa45c99 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" #include "ext/native/thin3d/thin3d.h" #include "Common/ColorConv.h" diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 2a359f0ef5..e292f185c4 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -24,9 +24,9 @@ #include "gfx/d3d9_shader.h" #include "Common/Data/Text/I18n.h" -#include "math/lin/matrix4x4.h" -#include "math/math_util.h" -#include "math/dataconv.h" +#include "Common/Math/lin/matrix4x4.h" +#include "Common/Math/math_util.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "thin3d/thin3d.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/GPU/Directx9/ShaderManagerDX9.h b/GPU/Directx9/ShaderManagerDX9.h index fac559e642..31458e1fee 100644 --- a/GPU/Directx9/ShaderManagerDX9.h +++ b/GPU/Directx9/ShaderManagerDX9.h @@ -26,7 +26,7 @@ #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/ShaderId.h" #include "thin3d/d3dx9_loader.h" -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" namespace DX9 { diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 49b87913a6..06e2a34b5a 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -34,7 +34,7 @@ #include "Core/Host.h" #include "ext/xxhash.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" namespace DX9 { diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 76eb5a0393..68c7c6a5d1 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -23,12 +23,12 @@ #include #include -#include "math/dataconv.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/gpu_features.h" #include "Common/Data/Text/I18n.h" -#include "math/math_util.h" -#include "math/lin/matrix4x4.h" +#include "Common/Math/math_util.h" +#include "Common/Math/lin/matrix4x4.h" #include "profiler/profiler.h" #include "thin3d/thin3d.h" #include "thin3d/GLRenderManager.h" diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index cfa92a0296..d700ff17ff 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -21,7 +21,7 @@ #include "ext/xxhash.h" #include "gfx/gl_debug_log.h" #include "Common/Data/Text/I18n.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "profiler/profiler.h" #include "thin3d/GLRenderManager.h" diff --git a/GPU/Math3D.h b/GPU/Math3D.h index ada1a6931e..873119613d 100644 --- a/GPU/Math3D.h +++ b/GPU/Math3D.h @@ -21,7 +21,7 @@ #include "Common/Common.h" #include "Core/Util/AudioFormat.h" // for clamp_u8 -#include "math/fast/fast_matrix.h" +#include "Common/Math/fast/fast_matrix.h" #if defined(_M_SSE) #include diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 6a5819bdfa..501e369e52 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -18,7 +18,7 @@ #include #include -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/MemoryUtil.h" #include "Core/Config.h" #include "GPU/GPUState.h" diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 8123b1275b..52880e958a 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -17,7 +17,7 @@ #include -#include "math/dataconv.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "profiler/profiler.h" #include "thin3d/VulkanRenderManager.h" diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 293ff77be5..092f314514 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -20,8 +20,8 @@ #include "profiler/profiler.h" #include "base/display.h" -#include "math/lin/matrix4x4.h" -#include "math/dataconv.h" +#include "Common/Math/lin/matrix4x4.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "ext/native/thin3d/thin3d.h" #include "Common/Vulkan/VulkanContext.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 6e62cd1338..2c277d7266 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -19,9 +19,9 @@ //#define SHADERLOG #endif -#include "math/lin/matrix4x4.h" -#include "math/math_util.h" -#include "math/dataconv.h" +#include "Common/Math/lin/matrix4x4.h" +#include "Common/Math/math_util.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "profiler/profiler.h" #include "thin3d/thin3d.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index e626e84152..6e6a297ee2 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -27,7 +27,7 @@ #include "GPU/Vulkan/VertexShaderGeneratorVulkan.h" #include "GPU/Vulkan/FragmentShaderGeneratorVulkan.h" #include "GPU/Vulkan/VulkanUtil.h" -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" #include "GPU/Common/ShaderUniforms.h" class VulkanContext; diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index c97bd380be..b35c2114ee 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -20,7 +20,7 @@ #include "Common/Vulkan/VulkanLoader.h" #include "thin3d/VulkanRenderManager.h" -#include "math/dataconv.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index e160116cd1..0ff3400c1f 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -19,9 +19,9 @@ #include #include "ext/xxhash.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "Common/Data/Text/I18n.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "profiler/profiler.h" #include "thin3d/thin3d.h" #include "thin3d/VulkanRenderManager.h" diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index af33f80668..7f46133c19 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -33,7 +33,7 @@ #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "QtMain.h" #include "Common/Data/Text/I18n.h" diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp index ecb94e25a1..53ed2cc921 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -2,7 +2,7 @@ #include #include "base/NativeApp.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "Common/FileUtil.h" #include "Core/Config.h" diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 3f50a032cb..ffa534c3af 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -26,7 +26,7 @@ SDLJoystick *joystick = NULL; #include "image/png_load.h" #include "net/resolve.h" #include "NKCodeFromSDL.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "thin3d/GLRenderManager.h" #include "SDL_syswm.h" diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 67dc6245c8..4d60afcaa3 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -1,11 +1,11 @@ #include #include -#include "file/chunk_file.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "ui/root.h" #include "Common/CommonTypes.h" +#include "Common/Data/Format/RIFF.h" #include "Common/Log.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/TimeUtil.h" diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index 971780ac91..e407df4625 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -15,17 +15,17 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/Data/Text/I18n.h" -#include "Common/Data/Color/RGBAUtil.h" #include "base/display.h" -#include "file/path.h" #include "gfx_es2/draw_buffer.h" #include "gfx/texture_atlas.h" -#include "math/curves.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Color/RGBAUtil.h" +#include "Common/File/PathBrowser.h" +#include "Common/Math/curves.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index f60f25285f..542a542f38 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -33,7 +33,7 @@ #include "Common/Input/KeyCodes.h" #include "Common/Input/InputState.h" #include "Common/Log.h" -#include "Common/KeyMap.h" +#include "Core/KeyMap.h" #include "Core/Host.h" #include "Core/HLE/sceCtrl.h" #include "Core/System.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 0c816c817f..aa201f9a13 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -27,7 +27,7 @@ #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_text.h" -#include "math/curves.h" +#include "Common/Math/curves.h" #include "ui/root.h" #include "ui/ui.h" #include "ui/ui_context.h" @@ -36,7 +36,6 @@ #include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" -#include "Common/KeyMap.h" #include "Common/Log.h" #include "Common/TimeUtil.h" @@ -49,6 +48,7 @@ #include "Core/CoreParameter.h" #include "Core/Core.h" #include "Core/Host.h" +#include "Core/KeyMap.h" #include "Core/Reporting.h" #include "Core/System.h" #include "GPU/GPUState.h" diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index b4504e611c..0f2c33563d 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -22,10 +22,10 @@ #include #include "Common/Input/KeyCodes.h" +#include "Core/KeyMap.h" #include "ui/screen.h" #include "ui/ui_screen.h" #include "ui/ui_tween.h" -#include "Common/KeyMap.h" struct AxisInput; diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 08699e24c1..c297ca6125 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -23,10 +23,9 @@ #include #include "file/file_util.h" -#include "file/zip_read.h" #include "thin3d/thin3d.h" #include "Common/Thread/PrioritizedWorkQueue.h" - +#include "Common/File/VFS/VFS.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Common/TimeUtil.h" diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 472aa840f0..9804387f7e 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -23,7 +23,7 @@ #include "base/NativeApp.h" #include "Common/Data/Color/RGBAUtil.h" -#include "math/curves.h" +#include "Common/Math/curves.h" #include "net/resolve.h" #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_buffer.h" @@ -50,7 +50,6 @@ #include "UI/ComboKeyMappingScreen.h" #include "UI/GPUDriverTestScreen.h" -#include "Common/KeyMap.h" #include "Common/FileUtil.h" #include "Common/OSVersion.h" #include "Common/TimeUtil.h" @@ -58,6 +57,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Host.h" +#include "Core/KeyMap.h" #include "Core/Instance.h" #include "Core/System.h" #include "Core/Reporting.h" diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index d43bac8a08..0277c34592 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -21,7 +21,7 @@ #include "base/display.h" #include "base/NativeApp.h" #include "gfx/texture_atlas.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "ui/ui_context.h" #include "Common/Log.h" diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 14394a18d3..645a4255cd 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -19,12 +19,11 @@ #include #include "ppsspp_config.h" + #include "base/display.h" #include "base/NativeApp.h" -#include "file/path.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" -#include "math/curves.h" #include "ui/root.h" #include "ui/ui_context.h" #include "ui/view.h" @@ -32,6 +31,8 @@ #include "Common/Data/Color/RGBAUtil.h" #include "Common/Data/Encoding/Utf8.h" +#include "Common/File/PathBrowser.h" +#include "Common/Math/curves.h" #include "Common/FileUtil.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" diff --git a/UI/MainScreen.h b/UI/MainScreen.h index fe1b09ad4b..a4aed944d4 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -19,10 +19,10 @@ #include -#include "file/path.h" #include "ui/ui_screen.h" #include "ui/viewgroup.h" #include "UI/MiscScreens.h" +#include "Common/File/PathBrowser.h" enum GameBrowserFlags { FLAG_HOMEBREWSTOREBUTTON = 1 diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 9f8044613c..5a861c3d58 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -23,12 +23,12 @@ #include "base/NativeApp.h" #include "base/display.h" #include "gfx_es2/draw_buffer.h" -#include "math/curves.h" +#include "Common/Math/curves.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "ui/ui.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "Common/Data/Color/RGBAUtil.h" #include "Common/Data/Text/I18n.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 7b4fd4bff9..2642576e7c 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -45,8 +45,6 @@ #include "base/display.h" #include "base/NativeApp.h" -#include "file/vfs.h" -#include "file/zip_read.h" #include "net/http_client.h" #include "net/resolve.h" #include "gfx/texture_atlas.h" @@ -54,24 +52,25 @@ #include "gfx_es2/gpu_features.h" #include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" -#include "math/fast/fast_math.h" -#include "math/math_util.h" -#include "math/lin/matrix4x4.h" +#include "Common/Math/fast/fast_math.h" +#include "Common/Math/math_util.h" +#include "Common/Math/lin/matrix4x4.h" #include "profiler/profiler.h" #include "thin3d/thin3d.h" #include "ui/ui.h" #include "ui/screen.h" #include "ui/ui_context.h" #include "ui/view.h" -#include "Common/Data/Encoding/Utf8.h" #include "android/jni/app-android.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" #include "Common/CPUDetect.h" #include "Common/FileUtil.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" -#include "Common/KeyMap.h" #include "Common/LogManager.h" #include "Common/MemArena.h" #include "Common/GraphicsContext.h" @@ -82,6 +81,7 @@ #include "Core/Core.h" #include "Core/FileLoaders/DiskCachingFileLoader.h" #include "Core/Host.h" +#include "Core/KeyMap.h" #include "Core/Reporting.h" #include "Core/SaveState.h" #include "Core/Screenshot.h" diff --git a/UI/OnScreenDisplay.h b/UI/OnScreenDisplay.h index cfd245edb8..381fcf274e 100644 --- a/UI/OnScreenDisplay.h +++ b/UI/OnScreenDisplay.h @@ -4,7 +4,7 @@ #include #include -#include "math/geom2d.h" +#include "Common/Math/geom2d.h" #include "ui/view.h" class DrawBuffer; diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 680ba3b47c..d8e184da56 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -26,7 +26,6 @@ #endif #include "base/NativeApp.h" -#include "file/path.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" #include "json/json_reader.h" @@ -34,6 +33,7 @@ #include "net/resolve.h" #include "net/url.h" +#include "Common/File/PathBrowser.h" #include "Common/Data/Text/I18n.h" #include "Common/Common.h" #include "Common/TimeUtil.h" diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 0521f830e5..0069f73ae8 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -21,7 +21,7 @@ #include "Common/Data/Color/RGBAUtil.h" #include "gfx_es2/draw_buffer.h" #include "Common/Data/Text/I18n.h" -#include "math/curves.h" +#include "Common/Math/curves.h" #include "Common/Thread/PrioritizedWorkQueue.h" #include "Common/Data/Encoding/Utf8.h" #include "ui/ui_context.h" diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index 0ca4228be2..c05be29263 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -4,9 +4,9 @@ #include "thin3d/thin3d.h" #include "image/zim_load.h" #include "image/png_load.h" -#include "math/math_util.h" -#include "math/curves.h" -#include "file/vfs.h" +#include "Common/Math/math_util.h" +#include "Common/Math/curves.h" +#include "Common/File/VFS/VFS.h" #include "ext/jpge/jpgd.h" #include "ui/view.h" #include "ui/ui_context.h" diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 46b4c49eae..0cba83a89f 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -21,7 +21,7 @@ #include "Common/Data/Color/RGBAUtil.h" #include "gfx_es2/draw_buffer.h" #include "Common/Data/Text/I18n.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "ui/ui_context.h" #include "Common/Common.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 92edcd468f..cc008945d9 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -389,19 +389,34 @@ + + + + + + + + + + + + + + + @@ -425,7 +440,6 @@ - @@ -463,15 +477,30 @@ + + + + + + + + + + + + + + + @@ -482,7 +511,6 @@ - @@ -525,6 +553,10 @@ + + + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 7edd0a7f0e..9f5f440125 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -37,6 +37,27 @@ {7277c320-2c19-40d0-81a4-2f6cbb20790c} + + {f924399b-932d-4aeb-b4e1-1da72f1fd2e3} + + + {211cb745-2675-4667-b0aa-964f33fc67dd} + + + {6f1f3b4e-8efd-4f39-b5a9-50d7c75b4616} + + + {56599f1d-b05b-4b55-b664-e6738d5edafc} + + + {4841c76f-fc06-41b0-9fbf-4d73bd591ce5} + + + {98e1f400-451f-497f-bbbc-e88c74c9aab0} + + + {b23bdba1-6007-4edb-ac75-a04cf8c5e172} + @@ -50,7 +71,6 @@ - @@ -169,6 +189,51 @@ Data\Text + + Data\Convert + + + Math + + + Math + + + Math + + + Math\fast + + + Math\fast + + + Math\fast + + + Math\lin + + + Math\lin + + + File + + + File + + + Data\Format + + + File\VFS + + + File\VFS + + + Data\Format + @@ -193,7 +258,6 @@ - @@ -307,10 +371,63 @@ Data\Text + + Data\Convert + + + Math + + + Math + + + Math + + + Math + + + Math\fast + + + Math\fast + + + Math\lin + + + Math\lin + + + File + + + File + + + Data\Format + + + File\VFS + + + File\VFS + + + Data\Format + ext\libpng17 + + + Math\fast + + + Math\lin + + \ No newline at end of file diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index a860f0886c..1ee0d6c4b8 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -520,6 +520,7 @@ + @@ -745,6 +746,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 8283fb162e..11ff8c7a08 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -910,6 +910,7 @@ Ext\libzip + @@ -1540,6 +1541,7 @@ Ext\libzip + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 115cd1d8f1..cebd2c1d40 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -381,14 +381,8 @@ - - - - - - @@ -398,16 +392,6 @@ - - - - - - - - - - @@ -429,13 +413,8 @@ - - - - - @@ -445,126 +424,6 @@ - - - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - - - - - - - - - - - - - - - - - - - - - - - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - - - - - - - - - - - - - - - - - - - - - - - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -605,4 +464,4 @@ - + \ No newline at end of file diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 63749eb6bf..8a588b0d57 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -7,24 +7,15 @@ {98343696-3517-451a-9b47-94d462263e3e} - - {63177c91-8ebd-4e87-ad4e-e6b8b52879c8} - {8a254b8c-46f2-4ff1-bc53-deea7e614276} {244992ec-8dcf-49f4-b63c-cae6ac437c58} - - {6f098c49-cf71-466b-9b1e-c4287681ab26} - {9d02a269-6cdd-4726-ab58-34c012e37d37} - - {8292cb5c-02c9-46a4-a8d5-ea5e8f362688} - {d8c0dd74-7ad2-440a-a3e0-5dbf3435a2fc} @@ -49,27 +40,12 @@ gfx - - file - file file - - file - - - file - - - file - - - file - ui @@ -94,30 +70,6 @@ ui - - math - - - math - - - math - - - math - - - math - - - math - - - math - - - math - net @@ -148,9 +100,6 @@ gfx - - math - @@ -178,30 +127,12 @@ gfx - - file - file file - - file - - - file - - - file - - - file - - - file - ui @@ -226,36 +157,6 @@ ui - - math - - - math - - - math - - - math - - - math - - - math - - - math - - - math - - - math - - - math - net @@ -295,4 +196,4 @@ gfx - + \ No newline at end of file diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index b66c452f59..6188606368 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -4,18 +4,18 @@ #include #include "base/NativeApp.h" -#include "Common/Input/InputState.h" -#include "file/vfs.h" -#include "file/zip_read.h" #include "file/file_util.h" #include "net/http_client.h" #include "net/resolve.h" #include "base/display.h" -#include "Common/Thread/ThreadUtil.h" #include "thin3d/thin3d_create.h" -#include "Common/Data/Encoding/Utf8.h" #include "Common/Common.h" +#include "Common/Input/InputState.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" +#include "Common/Thread/ThreadUtil.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/DirectXHelper.h" #include "Common/FileUtil.h" #include "Common/Log.h" diff --git a/Windows/GEDebugger/SimpleGLWindow.cpp b/Windows/GEDebugger/SimpleGLWindow.cpp index 4586ab566b..3416bc17df 100644 --- a/Windows/GEDebugger/SimpleGLWindow.cpp +++ b/Windows/GEDebugger/SimpleGLWindow.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" #include "gfx_es2/glsl_program.h" #include "gfx_es2/gpu_features.h" #include "Common/Common.h" diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index 271302237b..aefddc7088 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" #include "gfx_es2/glsl_program.h" #include "gfx_es2/gpu_features.h" #include "Windows/GEDebugger/GEDebugger.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index f4d2be55bf..3178e1adfe 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -22,7 +22,6 @@ // It's improving slowly, though. :) #include "stdafx.h" #include "Common/CommonWindows.h" -#include "Common/KeyMap.h" #include "Common/OSVersion.h" #include "ppsspp_config.h" @@ -47,6 +46,7 @@ #include "Core/ConfigValues.h" #include "Core/Debugger/SymbolMap.h" #include "Core/Instance.h" +#include "Core/KeyMap.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Windows/InputBox.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 310be72aa3..fab9c450cc 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -33,6 +33,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/FileSystems/MetaFileSystem.h" +#include "Core/KeyMap.h" #include "UI/OnScreenDisplay.h" #include "Windows/MainWindowMenu.h" #include "Windows/MainWindow.h" diff --git a/Windows/MainWindowMenu.h b/Windows/MainWindowMenu.h index 673681a292..26bdfc608e 100644 --- a/Windows/MainWindowMenu.h +++ b/Windows/MainWindowMenu.h @@ -1,7 +1,6 @@ #pragma once #include "Common/CommonWindows.h" -#include "Common/KeyMap.h" #include namespace MainWindow { diff --git a/Windows/TouchInputHandler.cpp b/Windows/TouchInputHandler.cpp index 3622dac160..b052ed3fa9 100644 --- a/Windows/TouchInputHandler.cpp +++ b/Windows/TouchInputHandler.cpp @@ -6,8 +6,10 @@ #include "base/display.h" #include "base/NativeApp.h" + #include "Common/CommonWindows.h" #include "Common/CommonFuncs.h" +#include "Common/Input/InputState.h" #include "Common/Log.h" #include "Common/SysError.h" #include "Windows/MainWindow.h" diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 17f8da078d..3151a61935 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -6,12 +6,12 @@ #include "base/NativeApp.h" #include "Core/Config.h" #include "Common/CommonWindows.h" -#include "Common/KeyMap.h" #include "Common/Log.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "XinputDevice.h" #include "Core/Core.h" +#include "Core/KeyMap.h" #include "Core/HLE/sceCtrl.h" #include "Common/Timer.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index 33843554dd..40e4acdc34 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -33,8 +33,8 @@ #include "base/display.h" #include "base/NativeApp.h" -#include "file/vfs.h" -#include "file/zip_read.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" #include "Common/Data/Text/I18n.h" #include "profiler/profiler.h" #include "Common/Thread/ThreadUtil.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 34309d62b9..b97043f228 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -270,13 +270,26 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Crypto/sha1.cpp \ $(SRC)/Common/Crypto/sha256.cpp \ $(SRC)/Common/Data/Color/RGBAUtil.cpp \ + $(SRC)/Common/Data/Convert/SmallDataConvert.cpp \ $(SRC)/Common/Data/Encoding/Base64.cpp \ $(SRC)/Common/Data/Encoding/Compression.cpp \ $(SRC)/Common/Data/Encoding/Utf8.cpp \ + $(SRC)/Common/Data/Format/RIFF.cpp \ $(SRC)/Common/Data/Hash/Hash.cpp \ $(SRC)/Common/Data/Text/I18n.cpp \ $(SRC)/Common/Data/Text/Parsers.cpp \ $(SRC)/Common/Data/Text/WrapText.cpp \ + $(SRC)/Common/File/VFS/VFS.cpp \ + $(SRC)/Common/File/VFS/AssetReader.cpp \ + $(SRC)/Common/File/DiskFree.cpp \ + $(SRC)/Common/File/PathBrowser.cpp \ + $(SRC)/Common/Math/fast/fast_math.c \ + $(SRC)/Common/Math/fast/fast_matrix.c \ + $(SRC)/Common/Math/math_util.cpp \ + $(SRC)/Common/Math/curves.cpp \ + $(SRC)/Common/Math/expression_parser.cpp \ + $(SRC)/Common/Math/lin/vec3.cpp.arm \ + $(SRC)/Common/Math/lin/matrix4x4.cpp.arm \ $(SRC)/Common/Thread/Executor.cpp \ $(SRC)/Common/Thread/PrioritizedWorkQueue.cpp \ $(SRC)/Common/Thread/ThreadPool.cpp \ @@ -286,7 +299,6 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Serialize/Serializer.cpp \ $(SRC)/Common/ColorConv.cpp \ $(SRC)/Common/ExceptionHandlerSetup.cpp \ - $(SRC)/Common/KeyMap.cpp \ $(SRC)/Common/Log.cpp \ $(SRC)/Common/LogManager.cpp \ $(SRC)/Common/MemArenaAndroid.cpp \ @@ -373,6 +385,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/CwCheat.cpp \ $(SRC)/Core/HDRemaster.cpp \ $(SRC)/Core/Instance.cpp \ + $(SRC)/Core/KeyMap.cpp \ $(SRC)/Core/Host.cpp \ $(SRC)/Core/Loaders.cpp \ $(SRC)/Core/PSPLoaders.cpp \ @@ -615,39 +628,26 @@ LOCAL_SRC_FILES := \ $(SRC)/UI/TextureUtil.cpp \ $(SRC)/UI/ComboKeyMappingScreen.cpp -#NATIVE -#LOCAL_CFLAGS := -O3 -DUSING_GLES2 -fsigned-char -fno-strict-aliasing -Wall -Wno-multichar -D__STDC_CONSTANT_MACROS -#LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder -#LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../ext $(LOCAL_PATH)/../../ext/libpng17 $(LOCAL_PATH)/../../ext/libzip $(LOCAL_PATH)/../../ext/glslang .. - -#Portable native and separate code on android in future is easy you needs add files -#by ($(target_arch_ABI),arquitecture (armeabi-v7a , armeabi , x86 , MIPS) -# ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) ifeq ($(findstring armeabi-v7a,$(TARGET_ARCH_ABI)),armeabi-v7a) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI_V7A +LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - $(SRC)/ext/native/math/fast/fast_matrix_neon.S.neon \ - ../../ext/libpng17/arm/arm_init.c \ - ../../ext/libpng17/arm/filter_neon_intrinsics.c \ - ../../ext/libpng17/arm/filter_neon.S.neon + $(SRC)/Common/Math/fast/fast_matrix_neon.S.neon \ + $(SRC)/ext/libpng17/arm/arm_init.c \ + $(SRC)/ext/libpng17/arm/filter_neon_intrinsics.c \ + $(SRC)/ext/libpng17/arm/filter_neon.S.neon -else ifeq ($(TARGET_ARCH_ABI),armeabi) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -DARM -DARMEABI -march=armv6 else ifeq ($(TARGET_ARCH_ABI),x86) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_IX86 LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - $(SRC)/ext/native/math/fast/fast_matrix_sse.c + $(SRC)/Common/Math/fast/fast_matrix_sse.c else ifeq ($(TARGET_ARCH_ABI),x86_64) -LOCAL_CFLAGS := $(LOCAL_CFLAGS) -D_M_X64 LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ - $(SRC)/ext/native/math/fast/fast_matrix_sse.c + $(SRC)/Common/Math/fast/fast_matrix_sse.c endif ifneq ($(SKIPAPP),1) include $(BUILD_SHARED_LIBRARY) endif - ifeq ($(HEADLESS),1) include $(CLEAR_VARS) include $(LOCAL_PATH)/Locals.mk diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 3813fbb44a..b25ff4fdcd 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -52,11 +52,12 @@ struct JNIEnv {}; #include "base/display.h" #include "base/NativeApp.h" #include "Common/Thread/ThreadUtil.h" -#include "file/zip_read.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "profiler/profiler.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "net/resolve.h" #include "Common/Data/Text/Parsers.h" #include "android/jni/AndroidAudio.h" diff --git a/ext/native/base/display.cpp b/ext/native/base/display.cpp index 28a482aa06..f90784b819 100644 --- a/ext/native/base/display.cpp +++ b/ext/native/base/display.cpp @@ -1,5 +1,5 @@ #include "base/display.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" int dp_xres; int dp_yres; diff --git a/ext/native/base/display.h b/ext/native/base/display.h index d91e426931..586c346f77 100644 --- a/ext/native/base/display.h +++ b/ext/native/base/display.h @@ -1,6 +1,6 @@ #pragma once -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" // This is meant to be a framework for handling DPI scaling etc. // For now, it just consists of these ugly globals. diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp index 0453cd5a88..55c31bb677 100644 --- a/ext/native/file/file_util.cpp +++ b/ext/native/file/file_util.cpp @@ -126,6 +126,34 @@ bool readFileToString(bool text_file, const char *filename, std::string &str) return true; } +uint8_t *ReadLocalFile(const char *filename, size_t *size) { + FILE *file = openCFile(filename, "rb"); + if (!file) { + *size = 0; + return nullptr; + } + fseek(file, 0, SEEK_END); + size_t f_size = ftell(file); + if ((long)f_size < 0) { + *size = 0; + fclose(file); + return nullptr; + } + fseek(file, 0, SEEK_SET); + uint8_t *contents = new uint8_t[f_size + 1]; + if (fread(contents, 1, f_size, file) != f_size) { + delete[] contents; + contents = nullptr; + *size = 0; + } else { + contents[f_size] = 0; + *size = f_size; + } + fclose(file); + return contents; +} + + // Returns true if filename is a directory bool isDirectory(const std::string &filename) { FileInfo info; diff --git a/ext/native/file/file_util.h b/ext/native/file/file_util.h index e194f3f2b2..3b2fb8ac6a 100644 --- a/ext/native/file/file_util.h +++ b/ext/native/file/file_util.h @@ -9,10 +9,12 @@ // Whole-file reading/writing bool writeStringToFile(bool text_file, const std::string &str, const char *filename); -bool readFileToString(bool text_file, const char *filename, std::string &str); - bool writeDataToFile(bool text_file, const void* data, const unsigned int size, const char *filename); +bool readFileToString(bool text_file, const char *filename, std::string &str); +// Return value must be delete[]-d. +uint8_t *ReadLocalFile(const char *filename, size_t *size); + // Beginnings of a directory utility system. TODO: Improve. struct FileInfo { diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index 15ea08c217..a5c0e5a7a6 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -4,7 +4,7 @@ #include #include "base/display.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "gfx/texture_atlas.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/draw_buffer.h" diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h index 97edf9f3ca..bfcd756010 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/ext/native/gfx_es2/draw_buffer.h @@ -7,8 +7,8 @@ #include "Common/Data/Color/RGBAUtil.h" #include "gfx/texture_atlas.h" -#include "math/geom2d.h" -#include "math/lin/matrix4x4.h" +#include "Common/Math/geom2d.h" +#include "Common/Math/lin/matrix4x4.h" #include "thin3d/thin3d.h" struct Atlas; diff --git a/ext/native/gfx_es2/glsl_program.cpp b/ext/native/gfx_es2/glsl_program.cpp index 3400b381b3..0578cd2cfe 100644 --- a/ext/native/gfx_es2/glsl_program.cpp +++ b/ext/native/gfx_es2/glsl_program.cpp @@ -4,8 +4,8 @@ #include #include -#include "file/vfs.h" -#include "file/zip_read.h" +#include "Common/File/VFS/VFS.h" +//#include "file/zip_read.h" #include "glsl_program.h" #include "Common/Log.h" diff --git a/ext/native/image/zim_load.cpp b/ext/native/image/zim_load.cpp index 86d2627f0c..80ed88d3c2 100644 --- a/ext/native/image/zim_load.cpp +++ b/ext/native/image/zim_load.cpp @@ -4,8 +4,8 @@ #include "zlib.h" #include "image/zim_load.h" -#include "math/math_util.h" -#include "file/vfs.h" +#include "Common/Math/math_util.h" +#include "Common/File/VFS/VFS.h" #include "Common/Log.h" diff --git a/ext/native/json/json_reader.cpp b/ext/native/json/json_reader.cpp index c0d1f1213a..2f95f082d8 100644 --- a/ext/native/json/json_reader.cpp +++ b/ext/native/json/json_reader.cpp @@ -1,5 +1,4 @@ -#include "file/zip_read.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "json/json_reader.h" namespace json { diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index b5b4fe78b1..55cab0400b 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -372,20 +372,13 @@ - - - - - - - @@ -416,15 +409,6 @@ - - - - - - - - - @@ -464,13 +448,8 @@ true true - - - - - @@ -480,7 +459,6 @@ - @@ -509,18 +487,6 @@ - - - - - - - - - AssemblyAndSourceCode - AssemblyAndSourceCode - AssemblyAndSourceCode - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index cfb2d16ef1..49e559580a 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -5,9 +5,6 @@ tools - - math\fast - base @@ -25,12 +22,6 @@ image - - math - - - math - gfx @@ -40,30 +31,15 @@ profiler - - file - - - file - - - file - gfx - - math - json file - - file - base @@ -85,48 +61,30 @@ ui - - math - ui gfx - - file - ui ui - - math - net ui - - math - gfx gfx - - math\fast - - - math\fast - thin3d @@ -142,12 +100,6 @@ gfx - - file - - - math - net @@ -225,12 +177,6 @@ image - - math - - - math - gfx @@ -240,12 +186,6 @@ profiler - - file - - - file - gfx @@ -255,18 +195,12 @@ file - - file - base ui - - math - net @@ -279,18 +213,12 @@ ui - - math - ui gfx - - file - ui @@ -303,24 +231,12 @@ ui - - math - gfx gfx - - math\fast - - - math\fast - - - math\fast - thin3d @@ -345,9 +261,6 @@ base - - file - thin3d @@ -375,9 +288,6 @@ gfx - - math - thin3d @@ -419,9 +329,6 @@ {828bddaf-63e5-4311-985b-bf377f86ff00} - - {f3f83007-7c3b-473f-a2f7-423c5087fbfa} - {c57b41dd-cc33-46ac-b479-19676455ae54} @@ -443,9 +350,6 @@ {4515306f-4664-46bf-a89b-abfec5520a15} - - {5ce64c0e-98e4-4411-86cc-aacaf2f60b21} - {06c6305a-a646-485b-85b9-645a24dd6553} diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index aec9acb5d1..6ce2682804 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -4,12 +4,12 @@ #include "gfx/gl_debug_log.h" #include "gfx_es2/gpu_features.h" #include "thin3d/DataFormatGL.h" -#include "math/dataconv.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/Log.h" #include "Common/MemoryUtil.h" #include "Common/StringUtils.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Core/Reporting.h" #include "GLQueueRunner.h" diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index d9721bf4ae..9fb0bc1847 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -10,7 +10,7 @@ #include #include "gfx/gl_common.h" -#include "math/dataconv.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Log.h" #include "GLQueueRunner.h" diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/ext/native/thin3d/VulkanQueueRunner.h index d46efdb42d..1bad9619ce 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/ext/native/thin3d/VulkanQueueRunner.h @@ -4,7 +4,7 @@ #include "Common/Hashmaps.h" #include "Common/Vulkan/VulkanContext.h" -#include "math/dataconv.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "thin3d/DataFormat.h" #include "Common/Data/Collections/TinySet.h" diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 57b1e78ec7..60a99d4cc3 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -12,8 +12,8 @@ #include "base/display.h" #include "Common/Vulkan/VulkanContext.h" -#include "math/dataconv.h" -#include "math/math_util.h" +#include "Common/Data/Convert/SmallDataConvert.h" +#include "Common/Math/math_util.h" #include "thin3d/DataFormat.h" #include "thin3d/VulkanQueueRunner.h" diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index 1a5bc12d85..d111f75461 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -7,7 +7,7 @@ #include "thin3d/d3d11_loader.h" #endif #include "base/display.h" -#include "math/dataconv.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/ColorConv.h" diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 8a97cbd26e..464da5c08d 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -33,7 +33,7 @@ #define D3DXERR_INVALIDDATA 0x88760b59 #endif -#include "math/lin/matrix4x4.h" +#include "Common/Math/lin/matrix4x4.h" #include "thin3d/thin3d.h" #include "gfx/d3d9_state.h" diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index abcf53dc3e..222b918a16 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -4,9 +4,9 @@ #include #include -#include "math/dataconv.h" -#include "math/math_util.h" -#include "math/lin/matrix4x4.h" +#include "Common/Data/Convert/SmallDataConvert.h" +#include "Common/Math/math_util.h" +#include "Common/Math/lin/matrix4x4.h" #include "thin3d/thin3d.h" #include "thin3d/DataFormatGL.h" #include "gfx/gl_common.h" diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 855f80c7c8..7195bc7bf4 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -22,8 +22,8 @@ #include "base/display.h" #include "image/zim_load.h" -#include "math/lin/matrix4x4.h" -#include "math/dataconv.h" +#include "Common/Math/lin/matrix4x4.h" +#include "Common/Data/Convert/SmallDataConvert.h" #include "thin3d/thin3d.h" #include "thin3d/VulkanRenderManager.h" diff --git a/ext/native/ui/ui_context.h b/ext/native/ui/ui_context.h index 03130d29b9..696e8b6bb8 100644 --- a/ext/native/ui/ui_context.h +++ b/ext/native/ui/ui_context.h @@ -4,8 +4,8 @@ #include #include -#include "math/geom2d.h" -#include "math/lin/vec3.h" +#include "Common/Math/geom2d.h" +#include "Common/Math/lin/vec3.h" #include "gfx/texture_atlas.h" // Everything you need to draw a UI collected into a single unit that can be passed around. diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 0406ed271d..3e96d79c39 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -5,7 +5,7 @@ #include "base/display.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" -#include "math/curves.h" +#include "Common/Math/curves.h" #include "ui/ui_screen.h" #include "ui/ui_context.h" #include "ui/screen.h" diff --git a/ext/native/ui/ui_screen.h b/ext/native/ui/ui_screen.h index 14d9472750..3184b03d09 100644 --- a/ext/native/ui/ui_screen.h +++ b/ext/native/ui/ui_screen.h @@ -2,7 +2,7 @@ #include -#include "math/lin/vec3.h" +#include "Common/Math/lin/vec3.h" #include "ui/screen.h" #include "ui/viewgroup.h" diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index 379456301f..8c46ff9060 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -16,9 +16,9 @@ #include #include "gfx/texture_atlas.h" -#include "math/lin/matrix4x4.h" -#include "math/math_util.h" -#include "math/geom2d.h" +#include "Common/Math/lin/matrix4x4.h" +#include "Common/Math/math_util.h" +#include "Common/Math/geom2d.h" #include "Common/Common.h" diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index 2ceae3146a..c48f1d22f2 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -4,7 +4,7 @@ #include #include "Common/Input/KeyCodes.h" -#include "math/curves.h" +#include "Common/Math/curves.h" #include "ui/ui_context.h" #include "ui/ui_tween.h" #include "ui/root.h" diff --git a/ext/native/ui/viewgroup.h b/ext/native/ui/viewgroup.h index d61305b2e9..7b2ec02fb0 100644 --- a/ext/native/ui/viewgroup.h +++ b/ext/native/ui/viewgroup.h @@ -5,7 +5,7 @@ #include #include -#include "math/geom2d.h" +#include "Common/Math/geom2d.h" #include "Common/Input/GestureDetector.h" #include "ui/view.h" diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index 56e6ddc9d2..baf2da955d 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -23,7 +23,7 @@ #include "headless/SDLHeadlessHost.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "file/zip_read.h" #include "thin3d/thin3d_create.h" #include "thin3d/GLRenderManager.h" diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index c5b9ef9594..64d22cc57b 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -21,8 +21,8 @@ #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" -#include "file/vfs.h" -#include "file/zip_read.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" #include "Common/CommonWindows.h" #include "Common/Log.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 145be50d2e..8f7588e532 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -144,14 +144,23 @@ SOURCES_CXX += \ SOURCES_CXX += \ $(COMMONDIR)/Data/Color/RGBAUtil.cpp \ + $(COMMONDIR)/Data/Convert/SmallDataConvert.cpp \ $(COMMONDIR)/Data/Encoding/Base64.cpp \ $(COMMONDIR)/Data/Encoding/Compression.cpp \ $(COMMONDIR)/Data/Encoding/Utf8.cpp \ + $(COMMONDIR)/Data/Format/RIFF.cpp \ + $(COMMONDIR)/Data/Format/IniFile.cpp \ $(COMMONDIR)/Data/Hash/Hash.cpp \ $(COMMONDIR)/Data/Text/I18n.cpp \ $(COMMONDIR)/Data/Text/Parsers.cpp \ $(COMMONDIR)/Data/Text/WrapText.cpp \ +SOURCES_CXX += \ + $(COMMONDIR)/File/VFS/VFS.cpp \ + $(COMMONDIR)/File/VFS/AssetReader.cpp \ + $(COMMONDIR)/File/DiskFree.cpp \ + $(COMMONDIR)/File/PathBrowser.cpp + SOURCES_CXX += \ $(COMMONDIR)/Serialize/Serializer.cpp \ $(COMMONDIR)/Thread/Executor.cpp \ @@ -176,7 +185,6 @@ SOURCES_CXX += \ $(COMMONDIR)/ThreadPools.cpp - SOURCES_CXX += \ $(GPUCOMMONDIR)/VertexDecoderCommon.cpp \ $(GPUCOMMONDIR)/GPUStateUtils.cpp \ @@ -295,9 +303,6 @@ endif SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/file/fd_util.cpp \ $(NATIVEDIR)/file/file_util.cpp \ - $(NATIVEDIR)/file/ini_file.cpp \ - $(NATIVEDIR)/file/free.cpp \ - $(NATIVEDIR)/file/zip_read.cpp \ $(NATIVEDIR)/gfx/gl_debug_log.cpp \ $(NATIVEDIR)/gfx/texture_atlas.cpp \ $(NATIVEDIR)/gfx/d3d9_shader.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 4e71ad7000..f0efc6437b 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -21,7 +21,7 @@ #include "Log.h" #include "LogManager.h" #include "ConsoleListener.h" -#include "file/vfs.h" +#include "Common/File/VFS/VFS.h" #include "file/zip_read.h" #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" From 989e3534823d87b922c1a659ff4827eed44afb1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 09:29:36 +0200 Subject: [PATCH 822/848] Common.h shouldn't include Log.h. Buildfixes More buildfixes. Move JSON code to common. --- CMakeLists.txt | 8 +++---- Common/Arm64Emitter.cpp | 13 ++++++------ Common/Arm64Emitter.h | 9 ++++---- Common/ArmEmitter.h | 7 ++++--- Common/CodeBlock.h | 6 ++++-- Common/Common.h | 1 - Common/Common.vcxproj | 4 ++++ Common/Common.vcxproj.filters | 12 +++++++++++ .../Data/Format/JSONReader.cpp | 2 +- .../Data/Format/JSONReader.h | 0 .../Data/Format/JSONWriter.cpp | 4 ++-- .../Data/Format/JSONWriter.h | 0 Common/File/PathBrowser.cpp | 1 + Common/FileUtil.cpp | 21 ++++++++++--------- Common/FileUtil.h | 17 ++++++++------- Common/x64Emitter.h | 11 +++++----- Core/Config.cpp | 10 +++++---- Core/Debugger/SymbolMap.cpp | 4 +++- Core/Debugger/WebSocket/WebSocketUtils.cpp | 7 +++++++ Core/Debugger/WebSocket/WebSocketUtils.h | 14 ++++--------- Core/ELF/PrxDecrypter.cpp | 1 + Core/FileLoaders/DiskCachingFileLoader.cpp | 1 + Core/FileLoaders/HTTPFileLoader.cpp | 1 + Core/FileLoaders/LocalFileLoader.cpp | 4 +++- Core/FileSystems/BlockDevices.cpp | 1 + Core/FileSystems/tlzrc.cpp | 3 ++- Core/HLE/sceKernel.h | 1 + Core/MIPS/JitCommon/JitState.h | 1 + Core/MIPS/MIPSAnalyst.cpp | 4 +++- Core/MemFault.cpp | 1 + Core/Replay.cpp | 2 ++ Core/Screenshot.cpp | 1 + Core/WaveFile.cpp | 10 ++++----- Core/WaveFile.h | 3 ++- GPU/Common/FramebufferManagerCommon.h | 1 + GPU/Common/PresentationCommon.cpp | 1 + GPU/Debugger/Debugger.cpp | 1 + GPU/Debugger/Stepping.cpp | 3 ++- GPU/Vulkan/VulkanUtil.h | 1 - UI/RemoteISOScreen.cpp | 2 +- UI/Store.cpp | 5 ++--- UI/TouchControlLayoutScreen.cpp | 1 + UWP/CommonUWP/CommonUWP.vcxproj | 4 ++++ UWP/CommonUWP/CommonUWP.vcxproj.filters | 12 +++++++++++ UWP/NativeUWP/NativeUWP.vcxproj | 4 ---- UWP/NativeUWP/NativeUWP.vcxproj.filters | 4 ---- android/ab.cmd | 5 +++-- android/jni/Android.mk | 18 +++------------- ext/native/native.vcxproj | 4 ---- ext/native/native.vcxproj.filters | 15 ------------- ext/native/thin3d/thin3d_d3d11.cpp | 3 ++- headless/Headless.cpp | 3 ++- headless/StubHost.cpp | 1 + ios/ViewController.mm | 10 ++++----- libretro/Makefile.common | 21 ++++++++----------- libretro/libretro.cpp | 2 +- 56 files changed, 164 insertions(+), 142 deletions(-) rename ext/native/json/json_reader.cpp => Common/Data/Format/JSONReader.cpp (98%) rename ext/native/json/json_reader.h => Common/Data/Format/JSONReader.h (100%) rename ext/native/json/json_writer.cpp => Common/Data/Format/JSONWriter.cpp (99%) rename ext/native/json/json_writer.h => Common/Data/Format/JSONWriter.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bafe8c74b..c1244a96d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -451,6 +451,10 @@ add_library(Common STATIC Common/Data/Format/RIFF.h Common/Data/Format/IniFile.cpp Common/Data/Format/IniFile.h + Common/Data/Format/JSONReader.h + Common/Data/Format/JSONReader.cpp + Common/Data/Format/JSONWriter.h + Common/Data/Format/JSONWriter.cpp Common/Data/Hash/Hash.cpp Common/Data/Hash/Hash.h Common/Data/Text/I18n.cpp @@ -1041,10 +1045,6 @@ add_library(native STATIC ext/native/image/zim_load.h ext/native/image/zim_save.cpp ext/native/image/zim_save.h - ext/native/json/json_reader.h - ext/native/json/json_reader.cpp - ext/native/json/json_writer.h - ext/native/json/json_writer.cpp ext/native/net/http_client.cpp ext/native/net/http_client.h ext/native/net/http_headers.cpp diff --git a/Common/Arm64Emitter.cpp b/Common/Arm64Emitter.cpp index 928ef5803f..7578dff4f7 100644 --- a/Common/Arm64Emitter.cpp +++ b/Common/Arm64Emitter.cpp @@ -12,13 +12,12 @@ #include #include -#include "Arm64Emitter.h" -#include "MathUtil.h" -#include "CommonTypes.h" -#include "CommonWindows.h" -#include "CPUDetect.h" - -#include "CommonWindows.h" +#include "Common/Arm64Emitter.h" +#include "Common/MathUtil.h" +#include "Common/CommonTypes.h" +#include "Common/CommonWindows.h" +#include "Common/CPUDetect.h" +#include "Common/Log.h" #ifdef IOS #include diff --git a/Common/Arm64Emitter.h b/Common/Arm64Emitter.h index 3e5dd0050b..e63052dcd8 100644 --- a/Common/Arm64Emitter.h +++ b/Common/Arm64Emitter.h @@ -6,10 +6,11 @@ #include -#include "ArmCommon.h" -#include "BitSet.h" -#include "CodeBlock.h" -#include "Common.h" +#include "Common/ArmCommon.h" +#include "Common/BitSet.h" +#include "Common/CodeBlock.h" +#include "Common/Common.h" +#include "Common/Log.h" #define DYNA_REC JIT diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index e100eff197..e3857de088 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -20,9 +20,10 @@ #include #include -#include "Common.h" -#include "ArmCommon.h" -#include "CodeBlock.h" +#include "Common/Common.h" +#include "Common/Log.h" +#include "Common/ArmCommon.h" +#include "Common/CodeBlock.h" // VCVT flags #define TO_FLOAT 0 diff --git a/Common/CodeBlock.h b/Common/CodeBlock.h index c4023d4a8e..9aad2440d7 100644 --- a/Common/CodeBlock.h +++ b/Common/CodeBlock.h @@ -5,8 +5,10 @@ #pragma once #include -#include "Common.h" -#include "MemoryUtil.h" + +#include "Common/CommonTypes.h" +#include "Common/Log.h" +#include "Common/MemoryUtil.h" // Everything that needs to generate code should inherit from this. // You get memory management for free, plus, you can use all emitter functions without diff --git a/Common/Common.h b/Common/Common.h index 42a7846746..184db926d7 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -28,7 +28,6 @@ #pragma warning(disable:4996) #endif -#include "Log.h" #include "CommonTypes.h" #include "CommonFuncs.h" diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index d914911c40..99dc270595 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -369,6 +369,8 @@ + + @@ -647,6 +649,8 @@ + + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index ae66327176..2a3ba0cc61 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -220,6 +220,12 @@ Data\Format + + Data\Format + + + Data\Format + @@ -421,6 +427,12 @@ Data\Format + + Data\Format + + + Data\Format + diff --git a/ext/native/json/json_reader.cpp b/Common/Data/Format/JSONReader.cpp similarity index 98% rename from ext/native/json/json_reader.cpp rename to Common/Data/Format/JSONReader.cpp index 2f95f082d8..125a136258 100644 --- a/ext/native/json/json_reader.cpp +++ b/Common/Data/Format/JSONReader.cpp @@ -1,5 +1,5 @@ #include "Common/File/VFS/VFS.h" -#include "json/json_reader.h" +#include "Common/Data/Format/JSONReader.h" namespace json { diff --git a/ext/native/json/json_reader.h b/Common/Data/Format/JSONReader.h similarity index 100% rename from ext/native/json/json_reader.h rename to Common/Data/Format/JSONReader.h diff --git a/ext/native/json/json_writer.cpp b/Common/Data/Format/JSONWriter.cpp similarity index 99% rename from ext/native/json/json_writer.cpp rename to Common/Data/Format/JSONWriter.cpp index 7440cf731d..3d0801be94 100644 --- a/ext/native/json/json_writer.cpp +++ b/Common/Data/Format/JSONWriter.cpp @@ -2,8 +2,8 @@ #include #include -#include "json/json_reader.h" -#include "json/json_writer.h" +#include "Common/Data/Format/JSONReader.h" +#include "Common/Data/Format/JSONWriter.h" namespace json { diff --git a/ext/native/json/json_writer.h b/Common/Data/Format/JSONWriter.h similarity index 100% rename from ext/native/json/json_writer.h rename to Common/Data/Format/JSONWriter.h diff --git a/Common/File/PathBrowser.cpp b/Common/File/PathBrowser.cpp index 0e02907b46..a57390d447 100644 --- a/Common/File/PathBrowser.cpp +++ b/Common/File/PathBrowser.cpp @@ -8,6 +8,7 @@ #include "Common/File/PathBrowser.h" #include "Common/StringUtils.h" #include "Common/TimeUtil.h" +#include "Common/Log.h" #include "Common/Thread/ThreadUtil.h" bool LoadRemoteFileList(const std::string &url, bool *cancel, std::vector &files) { diff --git a/Common/FileUtil.cpp b/Common/FileUtil.cpp index f7d78334b6..54c6f8da85 100644 --- a/Common/FileUtil.cpp +++ b/Common/FileUtil.cpp @@ -27,6 +27,7 @@ #include #include +#include "Common/Log.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Common/SysError.h" @@ -511,7 +512,7 @@ bool GetFileDetails(const std::string &filename, FileDetails *details) { if (!GetFileAttributesEx(ConvertUTF8ToWString(filename).c_str(), GetFileExInfoStandard, &attr)) return false; details->isDirectory = (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - details->size = ((u64)attr.nFileSizeHigh << 32) | (u64)attr.nFileSizeLow; + details->size = ((uint64_t)attr.nFileSizeHigh << 32) | (uint64_t)attr.nFileSizeLow; details->atime = FiletimeToStatTime(attr.ftLastAccessTime); details->mtime = FiletimeToStatTime(attr.ftLastWriteTime); details->ctime = FiletimeToStatTime(attr.ftCreationTime); @@ -588,14 +589,14 @@ std::string GetFilename(std::string path) { // Returns the size of file (64bit) // TODO: Add a way to return an error. -u64 GetFileSize(const std::string &filename) { +uint64_t GetFileSize(const std::string &filename) { #if defined(_WIN32) && defined(UNICODE) WIN32_FILE_ATTRIBUTE_DATA attr; if (!GetFileAttributesEx(ConvertUTF8ToWString(filename).c_str(), GetFileExInfoStandard, &attr)) return 0; if (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) return 0; - return ((u64)attr.nFileSizeHigh << 32) | (u64)attr.nFileSizeLow; + return ((uint64_t)attr.nFileSizeHigh << 32) | (uint64_t)attr.nFileSizeLow; #else #if __ANDROID__ && __ANDROID_API__ < 21 struct stat file_info; @@ -618,14 +619,14 @@ u64 GetFileSize(const std::string &filename) { } // Overloaded GetSize, accepts FILE* -u64 GetFileSize(FILE *f) { +uint64_t GetFileSize(FILE *f) { // can't use off_t here because it can be 32-bit - u64 pos = ftello(f); + uint64_t pos = ftello(f); if (fseeko(f, 0, SEEK_END) != 0) { ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", f, GetLastErrorMsg().c_str()); return 0; } - u64 size = ftello(f); + uint64_t size = ftello(f); if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", f, GetLastErrorMsg().c_str()); return 0; @@ -904,7 +905,7 @@ void IOFile::SetHandle(std::FILE* file) m_file = file; } -u64 IOFile::GetSize() +uint64_t IOFile::GetSize() { if (IsOpen()) return File::GetFileSize(m_file); @@ -912,7 +913,7 @@ u64 IOFile::GetSize() return 0; } -bool IOFile::Seek(s64 off, int origin) +bool IOFile::Seek(int64_t off, int origin) { if (!IsOpen() || 0 != fseeko(m_file, off, origin)) m_good = false; @@ -920,7 +921,7 @@ bool IOFile::Seek(s64 off, int origin) return m_good; } -u64 IOFile::Tell() +uint64_t IOFile::Tell() { if (IsOpen()) return ftello(m_file); @@ -936,7 +937,7 @@ bool IOFile::Flush() return m_good; } -bool IOFile::Resize(u64 size) +bool IOFile::Resize(uint64_t size) { if (!IsOpen() || 0 != #ifdef _WIN32 diff --git a/Common/FileUtil.h b/Common/FileUtil.h index 59552d56a5..08f1c42615 100644 --- a/Common/FileUtil.h +++ b/Common/FileUtil.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "Common.h" @@ -37,7 +38,7 @@ namespace File { struct FileDetails { bool isDirectory; - u64 size; + uint64_t size; uint64_t atime; uint64_t mtime; uint64_t ctime; @@ -70,10 +71,10 @@ std::string GetFilename(std::string path); bool GetModifTime(const std::string &filename, tm &return_time); // Returns the size of filename (64bit) -u64 GetFileSize(const std::string &filename); +uint64_t GetFileSize(const std::string &filename); // Overloaded GetSize, accepts FILE* -u64 GetFileSize(FILE *f); +uint64_t GetFileSize(FILE *f); // Returns true if successful, or path already exists. bool CreateDir(const std::string &filename); @@ -121,7 +122,7 @@ const std::string &GetExeDirectory(); class IOFile { public: IOFile(); - IOFile(std::FILE* file); + IOFile(FILE* file); IOFile(const std::string& filename, const char openmode[]); ~IOFile(); @@ -172,10 +173,10 @@ public: void SetHandle(std::FILE* file); - bool Seek(s64 off, int origin); - u64 Tell(); - u64 GetSize(); - bool Resize(u64 size); + bool Seek(int64_t off, int origin); + uint64_t Tell(); + uint64_t GetSize(); + bool Resize(uint64_t size); bool Flush(); // clear error state diff --git a/Common/x64Emitter.h b/Common/x64Emitter.h index a89cd11afb..fe32fa0d6d 100644 --- a/Common/x64Emitter.h +++ b/Common/x64Emitter.h @@ -15,14 +15,15 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#ifndef _DOLPHIN_INTEL_CODEGEN_ -#define _DOLPHIN_INTEL_CODEGEN_ +#pragma once #include "ppsspp_config.h" #include -#include "Common.h" -#include "CodeBlock.h" + +#include "Common/Common.h" +#include "Common/Log.h" +#include "Common/CodeBlock.h" #if PPSSPP_ARCH(64BIT) #define PTRBITS 64 @@ -1083,5 +1084,3 @@ public: }; } // namespace - -#endif diff --git a/Core/Config.cpp b/Core/Config.cpp index 98a70cfab6..a1a3b31d34 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -23,16 +23,18 @@ #include #include "ppsspp_config.h" + #include "base/display.h" #include "base/NativeApp.h" -#include "Common/Data/Format/IniFile.h" -#include "Common/Data/Text/I18n.h" -#include "json/json_reader.h" #include "gfx_es2/gpu_features.h" #include "net/http_client.h" -#include "Common/Data/Text/Parsers.h" #include "net/url.h" +#include "Common/Log.h" +#include "Common/Data/Format/IniFile.h" +#include "Common/Data/Format/JSONReader.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Text/Parsers.h" #include "Common/CPUDetect.h" #include "Common/FileUtil.h" #include "Common/LogManager.h" diff --git a/Core/Debugger/SymbolMap.cpp b/Core/Debugger/SymbolMap.cpp index bc5dc32e2a..4ca7bec75e 100644 --- a/Core/Debugger/SymbolMap.cpp +++ b/Core/Debugger/SymbolMap.cpp @@ -31,9 +31,11 @@ #include #include -#include "Common/Data/Encoding/Utf8.h" #include "zlib.h" + #include "Common/CommonTypes.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Log.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Core/MemMap.h" diff --git a/Core/Debugger/WebSocket/WebSocketUtils.cpp b/Core/Debugger/WebSocket/WebSocketUtils.cpp index 1f34621ee1..a9120b5caa 100644 --- a/Core/Debugger/WebSocket/WebSocketUtils.cpp +++ b/Core/Debugger/WebSocket/WebSocketUtils.cpp @@ -17,10 +17,17 @@ #include #include + #include "Common/Data/Text/Parsers.h" #include "Common/StringUtils.h" #include "Core/Debugger/WebSocket/WebSocketUtils.h" +inline void DebuggerJsonAddTicket(JsonWriter &writer, const JsonGet &data) { + const JsonNode *value = data.get("ticket"); + if (value) + writer.writeRaw("ticket", json_stringify(value)); +} + JsonWriter &DebuggerRequest::Respond() { writer_.begin(); writer_.writeString("event", name); diff --git a/Core/Debugger/WebSocket/WebSocketUtils.h b/Core/Debugger/WebSocket/WebSocketUtils.h index 995568dc52..24752274f2 100644 --- a/Core/Debugger/WebSocket/WebSocketUtils.h +++ b/Core/Debugger/WebSocket/WebSocketUtils.h @@ -17,15 +17,15 @@ #pragma once +#include "ppsspp_config.h" + #include -#include "json/json_reader.h" -#include "json/json_writer.h" #include "net/websocket_server.h" #include "Common/Log.h" - -#include "ppsspp_config.h" +#include "Common/Data/Format/JSONReader.h" +#include "Common/Data/Format/JSONWriter.h" #if PPSSPP_PLATFORM(UWP) // Enum name overlapped with UWP macro, quick hack to disable it @@ -34,12 +34,6 @@ using namespace json; -static inline void DebuggerJsonAddTicket(JsonWriter &writer, const JsonGet &data) { - const JsonNode *value = data.get("ticket"); - if (value) - writer.writeRaw("ticket", json_stringify(value)); -} - struct DebuggerErrorEvent { DebuggerErrorEvent(const std::string m, LogTypes::LOG_LEVELS l, const JsonGet data = JsonValue(JSON_NULL)) : message(m), level(l) { diff --git a/Core/ELF/PrxDecrypter.cpp b/Core/ELF/PrxDecrypter.cpp index f87fa91fd7..bb0088cef5 100644 --- a/Core/ELF/PrxDecrypter.cpp +++ b/Core/ELF/PrxDecrypter.cpp @@ -8,6 +8,7 @@ extern "C" #include "ext/libkirk/SHA1.h" } #include "Common/Common.h" +#include "Common/Log.h" #include "Common/Swap.h" #include "Core/ELF/PrxDecrypter.h" diff --git a/Core/FileLoaders/DiskCachingFileLoader.cpp b/Core/FileLoaders/DiskCachingFileLoader.cpp index ee028f662d..e8a940b7d0 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.cpp +++ b/Core/FileLoaders/DiskCachingFileLoader.cpp @@ -26,6 +26,7 @@ #include "Common/Data/Encoding/Utf8.h" #include "Common/File/DiskFree.h" #include "Common/FileUtil.h" +#include "Common/Log.h" #include "Common/CommonWindows.h" #include "Core/FileLoaders/DiskCachingFileLoader.h" #include "Core/System.h" diff --git a/Core/FileLoaders/HTTPFileLoader.cpp b/Core/FileLoaders/HTTPFileLoader.cpp index 094e78e639..9cf2d653b6 100644 --- a/Core/FileLoaders/HTTPFileLoader.cpp +++ b/Core/FileLoaders/HTTPFileLoader.cpp @@ -18,6 +18,7 @@ #include #include "Common/Common.h" +#include "Common/Log.h" #include "Common/StringUtils.h" #include "Core/FileLoaders/HTTPFileLoader.h" diff --git a/Core/FileLoaders/LocalFileLoader.cpp b/Core/FileLoaders/LocalFileLoader.cpp index fc91550059..f01eaffdda 100644 --- a/Core/FileLoaders/LocalFileLoader.cpp +++ b/Core/FileLoaders/LocalFileLoader.cpp @@ -18,8 +18,10 @@ #include #include "ppsspp_config.h" -#include "Common/Data/Encoding/Utf8.h" + #include "file/file_util.h" +#include "Common/Data/Encoding/Utf8.h" +#include "Common/Log.h" #include "Common/FileUtil.h" #include "Core/FileLoaders/LocalFileLoader.h" diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index a890926cac..368d78a296 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -21,6 +21,7 @@ #include "Common/Data/Text/I18n.h" #include "Common/FileUtil.h" +#include "Common/Log.h" #include "Common/Swap.h" #include "Core/Loaders.h" #include "Core/Host.h" diff --git a/Core/FileSystems/tlzrc.cpp b/Core/FileSystems/tlzrc.cpp index 5692d52d92..414fec0032 100644 --- a/Core/FileSystems/tlzrc.cpp +++ b/Core/FileSystems/tlzrc.cpp @@ -23,7 +23,8 @@ #include #include -#include "Common.h" +#include "Common/Common.h" +#include "Common/Log.h" /*************************************************************/ diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index c9d4e20d4c..ca9bdfc2d1 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -21,6 +21,7 @@ #include #include "Common/Common.h" +#include "Common/Log.h" #include "Common/Swap.h" class PointerWrap; diff --git a/Core/MIPS/JitCommon/JitState.h b/Core/MIPS/JitCommon/JitState.h index a8bb4e6691..d3c998f817 100644 --- a/Core/MIPS/JitCommon/JitState.h +++ b/Core/MIPS/JitCommon/JitState.h @@ -19,6 +19,7 @@ #pragma once #include "Common/Common.h" +#include "Common/Log.h" #include "Core/MIPS/MIPS.h" struct JitBlock; diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 6bb213ef05..b38211c0a0 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -22,7 +22,10 @@ #include #include "ext/cityhash/city.h" +#include "ext/xxhash.h" + #include "Common/FileUtil.h" +#include "Common/Log.h" #include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/MemMap.h" @@ -35,7 +38,6 @@ #include "Core/Debugger/SymbolMap.h" #include "Core/Debugger/DebugInterface.h" #include "Core/HLE/ReplaceTables.h" -#include "ext/xxhash.h" using namespace MIPSCodeUtils; diff --git a/Core/MemFault.cpp b/Core/MemFault.cpp index 5e8748a333..a550375161 100644 --- a/Core/MemFault.cpp +++ b/Core/MemFault.cpp @@ -28,6 +28,7 @@ #include "ext/disarm.h" #endif +#include "Common/Log.h" #include "Core/Core.h" #include "Core/MemFault.h" #include "Core/MemMap.h" diff --git a/Core/Replay.cpp b/Core/Replay.cpp index 0e76c2c481..bc188fcb31 100644 --- a/Core/Replay.cpp +++ b/Core/Replay.cpp @@ -18,7 +18,9 @@ #include #include #include + #include "Common/Common.h" +#include "Common/Log.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Replay.h" diff --git a/Core/Screenshot.cpp b/Core/Screenshot.cpp index 74c10ca2fe..f1d714d7e7 100644 --- a/Core/Screenshot.cpp +++ b/Core/Screenshot.cpp @@ -27,6 +27,7 @@ #include "Common/ColorConv.h" #include "Common/FileUtil.h" +#include "Common/Log.h" #include "Core/Config.h" #include "Core/Screenshot.h" #include "Core/Core.h" diff --git a/Core/WaveFile.cpp b/Core/WaveFile.cpp index 20f98a766f..1f4f4bdef4 100644 --- a/Core/WaveFile.cpp +++ b/Core/WaveFile.cpp @@ -44,7 +44,7 @@ bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRa Write(16); // size of fmt block Write(0x00020001); // two channels, uncompressed - const u32 sample_rate = HLESampleRate; + const uint32_t sample_rate = HLESampleRate; Write(sample_rate); Write(sample_rate * 2 * 2); // two channels, 16bit @@ -53,7 +53,7 @@ bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRa Write(100 * 1000 * 1000 - 32); // We are now at offset 44 - u64 offset = file.Tell(); + uint64_t offset = file.Tell(); _assert_msg_(offset == 44, "Wrong offset: %lld", (long long)offset); return true; } @@ -70,7 +70,7 @@ void WaveFileWriter::Stop() file.Close(); } -void WaveFileWriter::Write(u32 value) +void WaveFileWriter::Write(uint32_t value) { file.WriteArray(&value, 1); } @@ -80,7 +80,7 @@ void WaveFileWriter::Write4(const char* ptr) file.WriteBytes(ptr, 4); } -void WaveFileWriter::AddStereoSamples(const short* sample_data, u32 count) +void WaveFileWriter::AddStereoSamples(const short* sample_data, uint32_t count) { _assert_msg_(file, "WaveFileWriter - file not open."); _assert_msg_(count <= BUFFER_SIZE * 2, "WaveFileWriter - buffer too small (count = %u).", count); @@ -89,7 +89,7 @@ void WaveFileWriter::AddStereoSamples(const short* sample_data, u32 count) { bool all_zero = true; - for (u32 i = 0; i < count * 2; i++) + for (uint32_t i = 0; i < count * 2; i++) { if (sample_data[i]) all_zero = false; diff --git a/Core/WaveFile.h b/Core/WaveFile.h index b9dcad5f1e..4366cd936c 100644 --- a/Core/WaveFile.h +++ b/Core/WaveFile.h @@ -14,6 +14,7 @@ #include #include +#include #include "Common/FileUtil.h" @@ -36,6 +37,6 @@ private: bool skip_silence = false; uint32_t audio_size = 0; std::array conv_buffer{}; - void Write(u32 value); + void Write(uint32_t value); void Write4(const char* ptr); }; diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 05a2a787b6..1dc6abcde8 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -22,6 +22,7 @@ #include #include "Common/CommonTypes.h" +#include "Common/Log.h" #include "Core/MemMap.h" #include "GPU/GPU.h" #include "GPU/ge_constants.h" diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 7c8266624b..0d74e0c661 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -24,6 +24,7 @@ #include "thin3d/thin3d.h" #include "Common/File/VFS/VFS.h" +#include "Common/Log.h" #include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/GPU/Debugger/Debugger.cpp b/GPU/Debugger/Debugger.cpp index 2d5da1af3a..5c70f1066d 100644 --- a/GPU/Debugger/Debugger.cpp +++ b/GPU/Debugger/Debugger.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/Log.h" #include "GPU/GPU.h" #include "GPU/Debugger/Breakpoints.h" #include "GPU/Debugger/Debugger.h" diff --git a/GPU/Debugger/Stepping.cpp b/GPU/Debugger/Stepping.cpp index bf5ddb4834..2cc06f52fe 100644 --- a/GPU/Debugger/Stepping.cpp +++ b/GPU/Debugger/Stepping.cpp @@ -18,10 +18,11 @@ #include #include +#include "Common/Log.h" +#include "Core/Core.h" #include "GPU/Common/GPUDebugInterface.h" #include "GPU/Debugger/Stepping.h" #include "GPU/GPUState.h" -#include "Core/Core.h" namespace GPUStepping { diff --git a/GPU/Vulkan/VulkanUtil.h b/GPU/Vulkan/VulkanUtil.h index 44d4cf6be0..cac2698591 100644 --- a/GPU/Vulkan/VulkanUtil.h +++ b/GPU/Vulkan/VulkanUtil.h @@ -154,7 +154,6 @@ private: void DestroyDeviceObjects(); VulkanContext *vulkan_ = nullptr; - VkPipelineCache cache_ = VK_NULL_HANDLE; VkDescriptorSetLayout descriptorSetLayout_ = VK_NULL_HANDLE; VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE; VkPipelineCache pipelineCache_ = VK_NULL_HANDLE; diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index d8e184da56..be00a5eae6 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -28,12 +28,12 @@ #include "base/NativeApp.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" -#include "json/json_reader.h" #include "net/http_client.h" #include "net/resolve.h" #include "net/url.h" #include "Common/File/PathBrowser.h" +#include "Common/Data/Format/JSONReader.h" #include "Common/Data/Text/I18n.h" #include "Common/Common.h" #include "Common/TimeUtil.h" diff --git a/UI/Store.cpp b/UI/Store.cpp index f07a95d868..040decc9bc 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -17,9 +17,6 @@ #include -#include "json/json_reader.h" - -#include "Common/Data/Text/I18n.h" #include "ui/screen.h" #include "ui/ui_context.h" #include "ui/viewgroup.h" @@ -27,6 +24,8 @@ #include "Common/Common.h" #include "Common/Log.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Format/JSONReader.h" #include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/System.h" diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 0cba83a89f..fd06719aad 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -25,6 +25,7 @@ #include "ui/ui_context.h" #include "Common/Common.h" +#include "Common/Log.h" #include "Core/Config.h" #include "Core/System.h" #include "UI/GamepadEmu.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index cc008945d9..de272962bf 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -396,6 +396,8 @@ + + @@ -482,6 +484,8 @@ + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 9f5f440125..674947102e 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -234,6 +234,12 @@ Data\Format + + Data\Format + + + Data\Format + @@ -416,6 +422,12 @@ Data\Format + + Data\Format + + + Data\Format + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index cebd2c1d40..721cda4f7d 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -384,8 +384,6 @@ - - @@ -416,8 +414,6 @@ - - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 8a588b0d57..a2f90645d1 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -100,8 +100,6 @@ gfx - - net @@ -187,8 +185,6 @@ gfx - - net diff --git a/android/ab.cmd b/android/ab.cmd index 6befeb03b3..e6f3b7771d 100644 --- a/android/ab.cmd +++ b/android/ab.cmd @@ -5,6 +5,7 @@ copy ..\assets\langregion.ini assets\langregion.ini copy ..\assets\compat.ini assets\compat.ini copy ..\assets\Roboto-Condensed.ttf assets\Roboto-Condensed.ttf copy ..\assets\*.png assets\ -SET NDK=C:\AndroidNDK +REM SET NDK=C:\Android\sdk\ndk\21.3.6528147 +SET NDK=C:\Android\ndk SET NDK_MODULE_PATH=..\ext;..\ext\native\ext -%NDK%/ndk-build -j9 %* +%NDK%/ndk-build -j32 %* diff --git a/android/jni/Android.mk b/android/jni/Android.mk index b97043f228..8654dee504 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -104,22 +104,7 @@ endif NATIVE_FILES :=\ $(SRC)/ext/native/base/display.cpp \ $(SRC)/ext/native/file/fd_util.cpp \ - $(SRC)/ext/native/file/chunk_file.cpp \ $(SRC)/ext/native/file/file_util.cpp \ - $(SRC)/ext/native/file/free.cpp \ - $(SRC)/ext/native/file/path.cpp \ - $(SRC)/ext/native/file/ini_file.cpp \ - $(SRC)/ext/native/file/zip_read.cpp \ - $(SRC)/ext/native/json/json_reader.cpp \ - $(SRC)/ext/native/json/json_writer.cpp \ - $(SRC)/ext/native/math/fast/fast_math.c \ - $(SRC)/ext/native/math/fast/fast_matrix.c \ - $(SRC)/ext/native/math/dataconv.cpp \ - $(SRC)/ext/native/math/math_util.cpp \ - $(SRC)/ext/native/math/curves.cpp \ - $(SRC)/ext/native/math/expression_parser.cpp \ - $(SRC)/ext/native/math/lin/vec3.cpp.arm \ - $(SRC)/ext/native/math/lin/matrix4x4.cpp.arm \ $(SRC)/ext/native/net/http_client.cpp \ $(SRC)/ext/native/net/http_server.cpp \ $(SRC)/ext/native/net/http_headers.cpp \ @@ -275,6 +260,9 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Data/Encoding/Compression.cpp \ $(SRC)/Common/Data/Encoding/Utf8.cpp \ $(SRC)/Common/Data/Format/RIFF.cpp \ + $(SRC)/Common/Data/Format/IniFile.cpp \ + $(SRC)/Common/Data/Format/JSONReader.cpp \ + $(SRC)/Common/Data/Format/JSONWriter.cpp \ $(SRC)/Common/Data/Hash/Hash.cpp \ $(SRC)/Common/Data/Text/I18n.cpp \ $(SRC)/Common/Data/Text/Parsers.cpp \ diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 55cab0400b..180060fd62 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -388,7 +388,6 @@ - @@ -408,7 +407,6 @@ - @@ -458,7 +456,6 @@ - @@ -486,7 +483,6 @@ - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 49e559580a..b3182870ac 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -34,9 +34,6 @@ gfx - - json - file @@ -148,9 +145,6 @@ thin3d - - json - net @@ -189,9 +183,6 @@ gfx - - json - file @@ -306,9 +297,6 @@ thin3d - - json - net @@ -338,9 +326,6 @@ {95e41110-57a2-497f-a938-b4c8e9dd6a27} - - {cda27e9f-5763-4bf2-b6bc-85a377f7020e} - {d738c2d1-749d-4b60-b98f-f3da0bbbf40c} diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index d111f75461..a374e484e1 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -7,10 +7,11 @@ #include "thin3d/d3d11_loader.h" #endif #include "base/display.h" + #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Data/Encoding/Utf8.h" - #include "Common/ColorConv.h" +#include "Common/Log.h" #include #include diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 537cc03c70..0b5ecb7eef 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -10,9 +10,10 @@ #endif #include "base/NativeApp.h" -#include "file/zip_read.h" #include "profiler/profiler.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" #include "Common/TimeUtil.h" diff --git a/headless/StubHost.cpp b/headless/StubHost.cpp index 6569cc3b1a..a555a07816 100644 --- a/headless/StubHost.cpp +++ b/headless/StubHost.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/FileUtil.h" +#include "Common/Log.h" #include "Core/CoreParameter.h" #include "Core/System.h" #include "GPU/Common/GPUDebugInterface.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 774e0381ee..1bd8087ae0 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -14,24 +14,24 @@ #include "base/display.h" #include "base/NativeApp.h" -#include "Common/TimeUtil.h" #include "file/zip_read.h" -#include "Common/Input/InputState.h" #include "net/resolve.h" #include "ui/screen.h" #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" #include "thin3d/GLRenderManager.h" -#include "Common/Input/KeyCodes.h" #include "gfx_es2/gpu_features.h" +#include "Common/Log.h" +#include "Common/TimeUtil.h" +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" +#include "Common/GraphicsContext.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" #include "Core/HLE/sceUsbCam.h" #include "Core/HLE/sceUsbGps.h" -#include "Common/GraphicsContext.h" -#include "Common/Log.h" #include #include diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 8f7588e532..71095ccea5 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -150,18 +150,21 @@ SOURCES_CXX += \ $(COMMONDIR)/Data/Encoding/Utf8.cpp \ $(COMMONDIR)/Data/Format/RIFF.cpp \ $(COMMONDIR)/Data/Format/IniFile.cpp \ + $(COMMONDIR)/Data/Format/JSONReader.cpp \ + $(COMMONDIR)/Data/Format/JSONWriter.cpp \ $(COMMONDIR)/Data/Hash/Hash.cpp \ $(COMMONDIR)/Data/Text/I18n.cpp \ $(COMMONDIR)/Data/Text/Parsers.cpp \ $(COMMONDIR)/Data/Text/WrapText.cpp \ - -SOURCES_CXX += \ $(COMMONDIR)/File/VFS/VFS.cpp \ $(COMMONDIR)/File/VFS/AssetReader.cpp \ $(COMMONDIR)/File/DiskFree.cpp \ - $(COMMONDIR)/File/PathBrowser.cpp - -SOURCES_CXX += \ + $(COMMONDIR)/File/PathBrowser.cpp \ + $(COMMONDIR)/Math/curves.cpp \ + $(COMMONDIR)/Math/expression_parser.cpp \ + $(COMMONDIR)/Math/math_util.cpp \ + $(COMMONDIR)/Math/lin/vec3.cpp \ + $(COMMONDIR)/Math/lin/matrix4x4.cpp \ $(COMMONDIR)/Serialize/Serializer.cpp \ $(COMMONDIR)/Thread/Executor.cpp \ $(COMMONDIR)/Thread/ThreadUtil.cpp \ @@ -240,7 +243,6 @@ SOURCES_CXX += \ $(GPUDIR)/GLES/StateMappingGLES.cpp \ $(GPUDIR)/GLES/StencilBufferGLES.cpp \ $(EXTDIR)/native/base/display.cpp \ - $(EXTDIR)/native/json/json_reader.cpp \ $(EXTDIR)/glslang/OGLCompilersDLL/InitializeDll.cpp \ $(EXTDIR)/glslang/glslang/GenericCodeGen/CodeGen.cpp \ $(EXTDIR)/glslang/glslang/GenericCodeGen/Link.cpp \ @@ -300,8 +302,7 @@ SOURCES_CXX += $(COMMONDIR)/MemArenaPosix.cpp \ $(EXTDIR)/glslang/glslang/OSDependent/Unix/ossource.cpp endif -SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ - $(NATIVEDIR)/file/fd_util.cpp \ +SOURCES_CXX += $(NATIVEDIR)/file/fd_util.cpp \ $(NATIVEDIR)/file/file_util.cpp \ $(NATIVEDIR)/gfx/gl_debug_log.cpp \ $(NATIVEDIR)/gfx/texture_atlas.cpp \ @@ -313,10 +314,6 @@ SOURCES_CXX += $(NATIVEDIR)/math/dataconv.cpp \ $(NATIVEDIR)/gfx_es2/glsl_program.cpp \ $(NATIVEDIR)/image/zim_load.cpp \ $(NATIVEDIR)/image/png_load.cpp \ - $(NATIVEDIR)/math/curves.cpp \ - $(NATIVEDIR)/math/expression_parser.cpp \ - $(NATIVEDIR)/math/lin/matrix4x4.cpp \ - $(NATIVEDIR)/math/lin/vec3.cpp \ $(NATIVEDIR)/net/http_client.cpp \ $(NATIVEDIR)/net/resolve.cpp \ $(NATIVEDIR)/net/url.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index f0efc6437b..1a6e82ae49 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -22,7 +22,7 @@ #include "LogManager.h" #include "ConsoleListener.h" #include "Common/File/VFS/VFS.h" -#include "file/zip_read.h" +#include "Common/File/VFS/AssetReader.h" #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" #include "GPU/Common/FramebufferManagerCommon.h" From 821817e6d4f74c82a7a23227f4e1c766dff5f5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 10:04:01 +0200 Subject: [PATCH 823/848] Move the profiler to Common --- CMakeLists.txt | 4 ++-- Common/Common.vcxproj | 2 ++ Common/Common.vcxproj.filters | 9 +++++++++ .../profiler.cpp => Common/Profiler/Profiler.cpp | 10 +++++----- .../profiler/profiler.h => Common/Profiler/Profiler.h | 0 Core/Core.cpp | 2 +- Core/CoreTiming.cpp | 2 +- Core/HLE/HLE.cpp | 2 +- Core/HLE/sceDisplay.cpp | 2 +- Core/HLE/sceIo.cpp | 2 +- Core/HLE/sceSas.cpp | 2 +- Core/HW/SasAudio.cpp | 2 +- Core/MIPS/ARM/ArmCompBranch.cpp | 2 +- Core/MIPS/ARM/ArmJit.cpp | 2 +- Core/MIPS/ARM64/Arm64CompBranch.cpp | 2 +- Core/MIPS/ARM64/Arm64Jit.cpp | 2 +- Core/MIPS/IR/IRCompBranch.cpp | 2 +- Core/MIPS/IR/IRJit.cpp | 2 +- Core/MIPS/MIPS/MipsJit.cpp | 2 +- Core/MIPS/x86/CompBranch.cpp | 2 +- Core/MIPS/x86/Jit.cpp | 2 +- GPU/Common/DrawEngineCommon.cpp | 2 +- GPU/Common/SplineCommon.cpp | 2 +- GPU/Common/TextureCacheCommon.cpp | 2 +- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/Debugger/Playback.cpp | 2 +- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/Directx9/StateMappingDX9.cpp | 2 +- GPU/GLES/DrawEngineGLES.cpp | 2 +- GPU/GLES/FramebufferManagerGLES.cpp | 2 +- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GLES/ShaderManagerGLES.cpp | 2 +- GPU/GLES/StateMappingGLES.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 2 +- GPU/GPUCommon.cpp | 2 +- GPU/Software/Clipper.cpp | 2 +- GPU/Software/Rasterizer.cpp | 2 +- GPU/Software/RasterizerRectangle.cpp | 2 +- GPU/Software/SoftGpu.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 2 +- GPU/Vulkan/FramebufferManagerVulkan.cpp | 2 +- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 2 +- GPU/Vulkan/ShaderManagerVulkan.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 2 +- UI/DevScreens.cpp | 2 +- UI/EmuScreen.cpp | 2 +- UI/NativeApp.cpp | 2 +- UI/ProfilerDraw.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 2 ++ UWP/CommonUWP/CommonUWP.vcxproj.filters | 9 +++++++++ Windows/main.cpp | 2 +- android/jni/Android.mk | 2 +- android/jni/app-android.cpp | 2 +- ext/native/native.vcxproj | 2 -- ext/native/native.vcxproj.filters | 9 --------- headless/Headless.cpp | 2 +- ios/main.mm | 2 +- 58 files changed, 78 insertions(+), 67 deletions(-) rename ext/native/profiler/profiler.cpp => Common/Profiler/Profiler.cpp (99%) rename ext/native/profiler/profiler.h => Common/Profiler/Profiler.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1244a96d4..414c9dd149 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -491,6 +491,8 @@ add_library(Common STATIC Common/Math/lin/vec3.h Common/Math/math_util.cpp Common/Math/math_util.h + Common/Profiler/Profiler.cpp + Common/Profiler/Profiler.h Common/Thread/Executor.cpp Common/Thread/Executor.h Common/Thread/PrioritizedWorkQueue.cpp @@ -1059,8 +1061,6 @@ add_library(native STATIC ext/native/net/url.h ext/native/net/websocket_server.cpp ext/native/net/websocket_server.h - ext/native/profiler/profiler.cpp - ext/native/profiler/profiler.h ext/native/thin3d/thin3d.cpp ext/native/thin3d/thin3d.h ext/native/thin3d/thin3d_create.h diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 99dc270595..6d8e13d2f8 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -393,6 +393,7 @@ + @@ -671,6 +672,7 @@ + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 2a3ba0cc61..1df3526c49 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -226,6 +226,9 @@ Data\Format + + Profiler + @@ -433,6 +436,9 @@ Data\Format + + Profiler + @@ -504,6 +510,9 @@ {b10822cf-4cc0-4bc3-91a9-b20cb66e5cbd} + + {8321632b-8fc5-4a67-adb7-126a328d50eb} + diff --git a/ext/native/profiler/profiler.cpp b/Common/Profiler/Profiler.cpp similarity index 99% rename from ext/native/profiler/profiler.cpp rename to Common/Profiler/Profiler.cpp index 50b36465c5..923a9aed62 100644 --- a/ext/native/profiler/profiler.cpp +++ b/Common/Profiler/Profiler.cpp @@ -5,14 +5,14 @@ #include #include #include +#include -#include +#include "ppsspp_config.h" + +#include "gfx_es2/draw_buffer.h" #include "Common/TimeUtil.h" -#include "gfx_es2/draw_buffer.h" -#include "ppsspp_config.h" -#include "profiler/profiler.h" - +#include "Common/Profiler/Profiler.h" #include "Common/Log.h" #define MAX_CATEGORIES 64 // Can be any number, represents max profiled names. diff --git a/ext/native/profiler/profiler.h b/Common/Profiler/Profiler.h similarity index 100% rename from ext/native/profiler/profiler.h rename to Common/Profiler/Profiler.h diff --git a/Core/Core.cpp b/Core/Core.cpp index 73d9ea35a2..e79e08e48d 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -26,7 +26,7 @@ #include "base/display.h" #include "Common/TimeUtil.h" #include "Common/Thread/ThreadUtil.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/GraphicsContext.h" #include "Common/Log.h" diff --git a/Core/CoreTiming.cpp b/Core/CoreTiming.cpp index 81a7b3444d..ca30771568 100644 --- a/Core/CoreTiming.cpp +++ b/Core/CoreTiming.cpp @@ -20,7 +20,7 @@ #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeList.h" diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index c77962347d..eb4575fea6 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -20,7 +20,7 @@ #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Log.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 390d8f2621..1c82dfa0a6 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -27,7 +27,7 @@ #endif #include "Common/Data/Text/I18n.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 4f1185fffd..bdd93d5179 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -20,7 +20,7 @@ #include #include "Common/Thread/ThreadUtil.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/FileUtil.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/HLE/sceSas.cpp b/Core/HLE/sceSas.cpp index 5205c9d22d..25cb02f392 100644 --- a/Core/HLE/sceSas.cpp +++ b/Core/HLE/sceSas.cpp @@ -32,7 +32,7 @@ #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Log.h" diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 90f408b619..ea66611e0f 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -17,7 +17,7 @@ #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/MemMapHelpers.h" diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index b92cca816a..af3fb645f6 100644 --- a/Core/MIPS/ARM/ArmCompBranch.cpp +++ b/Core/MIPS/ARM/ArmCompBranch.cpp @@ -18,7 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM) -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Core/Config.h" #include "Core/Core.h" diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 5a8316f06b..653e1afe4c 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -18,7 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM) -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Log.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/MIPS/ARM64/Arm64CompBranch.cpp b/Core/MIPS/ARM64/Arm64CompBranch.cpp index 3e84996487..ce7bc2d341 100644 --- a/Core/MIPS/ARM64/Arm64CompBranch.cpp +++ b/Core/MIPS/ARM64/Arm64CompBranch.cpp @@ -18,7 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM64) -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Core/Config.h" #include "Core/Core.h" diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index 582cb7191e..cfdb3d0385 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -18,7 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(ARM64) -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/MIPS/IR/IRCompBranch.cpp b/Core/MIPS/IR/IRCompBranch.cpp index df23efa1e1..2592d6227c 100644 --- a/Core/MIPS/IR/IRCompBranch.cpp +++ b/Core/MIPS/IR/IRCompBranch.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Core/Reporting.h" #include "Core/Config.h" diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 4324d3ba8f..77d988d139 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -18,7 +18,7 @@ #include #include "ext/xxhash.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Log.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/MIPS/MIPS/MipsJit.cpp b/Core/MIPS/MIPS/MipsJit.cpp index 0874282d50..5201437784 100644 --- a/Core/MIPS/MIPS/MipsJit.cpp +++ b/Core/MIPS/MIPS/MipsJit.cpp @@ -18,7 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(MIPS) -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Serialize/Serializer.h" #include "Core/Reporting.h" #include "Core/Config.h" diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index b8816d4a12..8c8ce8fd3d 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -18,7 +18,7 @@ #include "ppsspp_config.h" #if PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Core/Config.h" #include "Core/Core.h" diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 21e57bf525..97682d5f7d 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -22,7 +22,7 @@ #include #include "Common/Math/math_util.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 994475d718..bb554d1c38 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -17,7 +17,7 @@ #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/ColorConv.h" #include "Core/Config.h" #include "GPU/Common/DrawEngineCommon.h" diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index 2460af74dc..c4aa0d2c49 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -18,7 +18,7 @@ #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/CPUDetect.h" diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index b00d783338..03e6262940 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -18,7 +18,7 @@ #include #include "ppsspp_config.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/ColorConv.h" #include "Common/MemoryUtil.h" #include "Core/Config.h" diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 27db9fd389..8199b3667c 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -40,7 +40,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/GraphicsContext.h" #include "base/NativeApp.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Data/Text/I18n.h" #include "Core/Debugger/Breakpoints.h" #include "Core/MemMapHelpers.h" diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index d05b14bc37..4a7fb9ca00 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -21,7 +21,7 @@ #include #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Common.h" #include "Common/Log.h" #include "Core/Core.h" diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 07aae4fadf..1b5be8e793 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -20,7 +20,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/GraphicsContext.h" #include "base/NativeApp.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Data/Text/I18n.h" #include "Core/Debugger/Breakpoints.h" #include "Core/MemMapHelpers.h" diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index e37c60eaef..0efeaf996e 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 438bef2638..759f3541b5 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -26,7 +26,7 @@ #include "Core/CoreTiming.h" #include "gfx/gl_debug_log.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index f2709663cf..ac4faa624a 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -17,7 +17,7 @@ #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "gfx/gl_common.h" #include "gfx/gl_debug_log.h" #include "gfx_es2/glsl_program.h" diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 0623af9e33..8fb872cc98 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Data/Text/I18n.h" #include "Common/Log.h" diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 68c7c6a5d1..d1ffc3fecc 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -29,7 +29,7 @@ #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" #include "Common/Math/lin/matrix4x4.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "thin3d/thin3d.h" #include "thin3d/GLRenderManager.h" diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 73a1805a59..8856bd517f 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -21,7 +21,7 @@ #include "StateMappingGLES.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "gfx/gl_debug_log.h" #include "thin3d/GLRenderManager.h" diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index d700ff17ff..62844159a7 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -22,7 +22,7 @@ #include "gfx/gl_debug_log.h" #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "thin3d/GLRenderManager.h" #include "Common/ColorConv.h" diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index da92f820c4..a77a8269ad 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -2,7 +2,7 @@ #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/ColorConv.h" #include "Common/GraphicsContext.h" diff --git a/GPU/Software/Clipper.cpp b/GPU/Software/Clipper.cpp index b462bd5977..66db9a08e4 100644 --- a/GPU/Software/Clipper.cpp +++ b/GPU/Software/Clipper.cpp @@ -23,7 +23,7 @@ #include "GPU/Software/Rasterizer.h" #include "GPU/Software/RasterizerRectangle.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" namespace Clipper { diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 519d5b2e7c..7bfc9b190f 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -18,7 +18,7 @@ #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/ThreadPools.h" #include "Common/ColorConv.h" diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index be2d042692..668a9476e3 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -3,7 +3,7 @@ #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Core/System.h" diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index d0d49548b9..33de98f955 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -32,7 +32,7 @@ #include "Core/MIPS/MIPS.h" #include "Core/Reporting.h" #include "Core/Core.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "thin3d/thin3d.h" #include "GPU/Software/Rasterizer.h" diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 52880e958a..2688698efd 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -18,7 +18,7 @@ #include #include "Common/Data/Convert/SmallDataConvert.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "thin3d/VulkanRenderManager.h" #include "Common/Log.h" diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 092f314514..eec77859cb 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -17,7 +17,7 @@ #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "base/display.h" #include "Common/Math/lin/matrix4x4.h" diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 2b9724f127..96e4212ec8 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -18,7 +18,7 @@ #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Log.h" #include "Common/FileUtil.h" diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index df8446b6bb..23d39bb3bf 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -3,7 +3,7 @@ #include #include -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 2c277d7266..f8678a4dd8 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -22,7 +22,7 @@ #include "Common/Math/lin/matrix4x4.h" #include "Common/Math/math_util.h" #include "Common/Data/Convert/SmallDataConvert.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "thin3d/thin3d.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 0ff3400c1f..3e24a899c5 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -22,7 +22,7 @@ #include "Common/File/VFS/VFS.h" #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "thin3d/thin3d.h" #include "thin3d/VulkanRenderManager.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index a577639e2a..0423002a36 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -26,7 +26,7 @@ #include "ui/view.h" #include "ui/viewgroup.h" #include "ui/ui.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/LogManager.h" #include "Common/CPUDetect.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index aa201f9a13..b848d699bc 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -21,7 +21,7 @@ #include "base/display.h" #include "base/NativeApp.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "gfx/texture_atlas.h" #include "gfx_es2/gpu_features.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 2642576e7c..0eb2977cbc 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -55,7 +55,7 @@ #include "Common/Math/fast/fast_math.h" #include "Common/Math/math_util.h" #include "Common/Math/lin/matrix4x4.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "thin3d/thin3d.h" #include "ui/ui.h" #include "ui/screen.h" diff --git a/UI/ProfilerDraw.cpp b/UI/ProfilerDraw.cpp index 8d7cf74021..8b8ce6838e 100644 --- a/UI/ProfilerDraw.cpp +++ b/UI/ProfilerDraw.cpp @@ -21,7 +21,7 @@ #include "gfx_es2/draw_buffer.h" #include "ui/ui_context.h" #include "ui/view.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" static const uint32_t nice_colors[] = { 0xFF8040, diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index de272962bf..9156bfa093 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -419,6 +419,7 @@ + @@ -505,6 +506,7 @@ + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 674947102e..58ec4db297 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -58,6 +58,9 @@ {b23bdba1-6007-4edb-ac75-a04cf8c5e172} + + {6673c122-d7ed-4ccc-969a-12d317ee1f93} + @@ -240,6 +243,9 @@ Data\Format + + Profiler + @@ -428,6 +434,9 @@ Data\Format + + Profiler + diff --git a/Windows/main.cpp b/Windows/main.cpp index 40e4acdc34..5d5464f284 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -36,7 +36,7 @@ #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" #include "Common/Data/Text/I18n.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Encoding/Utf8.h" #include "net/resolve.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 8654dee504..9ef7d2b702 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -112,7 +112,6 @@ NATIVE_FILES :=\ $(SRC)/ext/native/net/sinks.cpp \ $(SRC)/ext/native/net/url.cpp \ $(SRC)/ext/native/net/websocket_server.cpp \ - $(SRC)/ext/native/profiler/profiler.cpp \ $(SRC)/ext/native/gfx_es2/glsl_program.cpp \ $(SRC)/ext/native/gfx_es2/gpu_features.cpp \ $(SRC)/ext/native/gfx_es2/gl3stub.c \ @@ -278,6 +277,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Math/expression_parser.cpp \ $(SRC)/Common/Math/lin/vec3.cpp.arm \ $(SRC)/Common/Math/lin/matrix4x4.cpp.arm \ + $(SRC)/Common/Profiler/Profiler.cpp \ $(SRC)/Common/Thread/Executor.cpp \ $(SRC)/Common/Thread/PrioritizedWorkQueue.cpp \ $(SRC)/Common/Thread/ThreadPool.cpp \ diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index b25ff4fdcd..57e2d4c7c6 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -56,7 +56,7 @@ struct JNIEnv {}; #include "Common/File/VFS/AssetReader.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/Math/math_util.h" #include "net/resolve.h" #include "Common/Data/Text/Parsers.h" diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 180060fd62..7a4d64981e 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -412,7 +412,6 @@ - @@ -488,7 +487,6 @@ - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index b3182870ac..e11d74cf0e 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -28,9 +28,6 @@ gfx - - profiler - gfx @@ -177,9 +174,6 @@ gfx - - profiler - gfx @@ -317,9 +311,6 @@ {828bddaf-63e5-4311-985b-bf377f86ff00} - - {c57b41dd-cc33-46ac-b479-19676455ae54} - {49afd06e-eb44-41ac-b038-e109e444a834} diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 0b5ecb7eef..5d88aede92 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -10,7 +10,7 @@ #endif #include "base/NativeApp.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" diff --git a/ios/main.mm b/ios/main.mm index 4c9f004c5f..762d4e8ade 100644 --- a/ios/main.mm +++ b/ios/main.mm @@ -15,7 +15,7 @@ #import "ViewController.h" #include "base/NativeApp.h" -#include "profiler/profiler.h" +#include "Common/Profiler/Profiler.h" #define CS_OPS_STATUS 0 /* return status */ #define CS_DEBUGGED 0x10000000 /* process is currently or has previously been debugged and allowed to run with invalid pages */ From b7edf754379f7e3a7d12412e63c75180e5195852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 10:10:55 +0200 Subject: [PATCH 824/848] Move Display.cpp/h to Common. --- CMakeLists.txt | 4 +-- Common/Common.vcxproj.filters | 3 ++ .../display.cpp => Common/System/Display.cpp | 2 +- .../base/display.h => Common/System/Display.h | 0 Common/Vulkan/VulkanContext.cpp | 2 +- Core/Config.cpp | 2 +- Core/Core.cpp | 2 +- GPU/Common/GPUStateUtils.cpp | 2 +- GPU/Common/PresentationCommon.cpp | 2 +- GPU/Common/ShaderUniforms.cpp | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 2 +- GPU/Software/SoftGpu.cpp | 2 +- GPU/Vulkan/FramebufferManagerVulkan.cpp | 2 +- Qt/QtMain.h | 2 +- Qt/mainwindow.cpp | 2 +- SDL/SDLGLGraphicsContext.cpp | 2 +- SDL/SDLMain.cpp | 2 +- SDL/SDLVulkanGraphicsContext.cpp | 2 +- UI/ComboKeyMappingScreen.cpp | 2 +- UI/ControlMappingScreen.cpp | 2 +- UI/DevScreens.cpp | 2 +- UI/DisplayLayoutScreen.cpp | 2 +- UI/EmuScreen.cpp | 2 +- UI/GPUDriverTestScreen.h | 2 +- UI/GameSettingsScreen.cpp | 2 +- UI/GamepadEmu.cpp | 2 +- UI/MainScreen.cpp | 2 +- UI/MiscScreens.cpp | 2 +- UI/NativeApp.cpp | 2 +- UI/ReportScreen.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 2 ++ UWP/CommonUWP/CommonUWP.vcxproj.filters | 9 +++++ UWP/PPSSPP_UWPMain.cpp | 2 +- Windows/Debugger/CtrlDisAsmView.cpp | 2 +- Windows/Debugger/CtrlMemView.cpp | 2 +- Windows/Debugger/CtrlRegisterList.cpp | 2 +- Windows/Debugger/Debugger_MemoryDlg.cpp | 2 +- Windows/GEDebugger/CtrlDisplayListView.cpp | 2 +- Windows/GPU/D3D11Context.cpp | 2 +- Windows/GPU/D3D9Context.cpp | 2 +- Windows/MainWindow.cpp | 2 +- Windows/RawInput.cpp | 2 +- Windows/TouchInputHandler.cpp | 2 +- Windows/WindowsHost.cpp | 2 +- Windows/main.cpp | 2 +- android/jni/Android.mk | 2 +- android/jni/AndroidJavaGLContext.cpp | 2 +- android/jni/AndroidVulkanContext.cpp | 2 +- android/jni/TestRunner.cpp | 2 +- android/jni/app-android.cpp | 2 +- ext/native/gfx_es2/draw_buffer.cpp | 2 +- ext/native/gfx_es2/draw_text.cpp | 2 +- ext/native/gfx_es2/draw_text_android.cpp | 2 +- ext/native/gfx_es2/draw_text_qt.cpp | 2 +- ext/native/gfx_es2/draw_text_uwp.cpp | 2 +- ext/native/gfx_es2/draw_text_win.cpp | 2 +- ext/native/native.vcxproj | 33 ------------------- ext/native/native.vcxproj.filters | 18 ---------- ext/native/thin3d/VulkanRenderManager.h | 2 +- ext/native/thin3d/thin3d.cpp | 2 +- ext/native/thin3d/thin3d_d3d11.cpp | 2 +- ext/native/thin3d/thin3d_vulkan.cpp | 2 +- ext/native/ui/screen.cpp | 2 +- ext/native/ui/ui_context.cpp | 2 +- ext/native/ui/ui_screen.cpp | 2 +- ios/DisplayManager.mm | 2 +- ios/PPSSPPUIApplication.mm | 2 +- ios/ViewController.mm | 2 +- libretro/Makefile.common | 2 +- libretro/libretro.cpp | 22 ++++++++----- 70 files changed, 91 insertions(+), 124 deletions(-) rename ext/native/base/display.cpp => Common/System/Display.cpp (97%) rename ext/native/base/display.h => Common/System/Display.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 414c9dd149..0bdfe17939 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -493,6 +493,8 @@ add_library(Common STATIC Common/Math/math_util.h Common/Profiler/Profiler.cpp Common/Profiler/Profiler.h + Common/System/Display.cpp + Common/System/Display.h Common/Thread/Executor.cpp Common/Thread/Executor.h Common/Thread/PrioritizedWorkQueue.cpp @@ -1010,8 +1012,6 @@ endif() add_library(native STATIC ${nativeExtra} - ext/native/base/display.cpp - ext/native/base/display.h ext/native/file/fd_util.cpp ext/native/file/fd_util.h ext/native/file/file_util.cpp diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 1df3526c49..483144fcab 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -513,6 +513,9 @@ {8321632b-8fc5-4a67-adb7-126a328d50eb} + + {89ddf0bd-3fc4-4a69-87a7-b82cfc412e0a} + diff --git a/ext/native/base/display.cpp b/Common/System/Display.cpp similarity index 97% rename from ext/native/base/display.cpp rename to Common/System/Display.cpp index f90784b819..0e9c1ffb62 100644 --- a/ext/native/base/display.cpp +++ b/Common/System/Display.cpp @@ -1,4 +1,4 @@ -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Math/math_util.h" int dp_xres; diff --git a/ext/native/base/display.h b/Common/System/Display.h similarity index 100% rename from ext/native/base/display.h rename to Common/System/Display.h diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 17fe8bb496..7e0338936d 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -5,7 +5,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanDebug.h" diff --git a/Core/Config.cpp b/Core/Config.cpp index a1a3b31d34..89aeb90706 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -24,7 +24,7 @@ #include "ppsspp_config.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "net/http_client.h" diff --git a/Core/Core.cpp b/Core/Core.cpp index e79e08e48d..9748441e1a 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -23,7 +23,7 @@ #include #include "base/NativeApp.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/TimeUtil.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Profiler/Profiler.h" diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 62cd71757a..8ccf5b2764 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -18,7 +18,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 0d74e0c661..d80394f55f 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -19,7 +19,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "thin3d/thin3d.h" diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index f266721050..46f6a93855 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -2,7 +2,7 @@ #include #include "ShaderUniforms.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Math/math_util.h" diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 83a2beab65..f4d4854049 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -19,7 +19,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Math/lin/matrix4x4.h" #include "ext/native/thin3d/thin3d.h" diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 33de98f955..6dd2fcd78f 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/display.h" +#include "Common/System/Display.h" #include "gfx_es2/gpu_features.h" #include "GPU/GPUState.h" diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index eec77859cb..41e47ae259 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -19,7 +19,7 @@ #include "Common/Profiler/Profiler.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "ext/native/thin3d/thin3d.h" diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 2fce102089..3a1cd3a750 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -22,7 +22,7 @@ QTM_USE_NAMESPACE #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/TimeUtil.h" #include "file/zip_read.h" #include "gfx/gl_common.h" diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index 544eaa93ed..fe48956f2e 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -7,7 +7,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "Core/MIPS/MIPSDebugInterface.h" #include "Core/Debugger/SymbolMap.h" diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index b5650590b7..2d41fd1c4f 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -4,7 +4,7 @@ #include "Core/ConfigValues.h" #include "Core/System.h" #include "base/NativeApp.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "gfx_es2/gpu_features.h" #include "thin3d/thin3d_create.h" diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index ffa534c3af..37b3ad12af 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -20,7 +20,7 @@ SDLJoystick *joystick = NULL; #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "ext/glslang/glslang/Public/ShaderLang.h" #include "image/png_load.h" diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 9bc9bf925b..77bb943ecc 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -1,7 +1,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "base/NativeApp.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" #include "thin3d/VulkanRenderManager.h" diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index e407df4625..672b760df8 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/display.h" +#include "Common/System/Display.h" #include "gfx_es2/draw_buffer.h" #include "gfx/texture_atlas.h" #include "ui/ui_context.h" diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 542a542f38..518d805292 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -19,7 +19,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "gfx/texture_atlas.h" #include "ui/root.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 0423002a36..7f7bf849fd 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -18,7 +18,7 @@ #include #include "ppsspp_config.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "Common/Data/Text/I18n.h" diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 4ae30dd4ad..1df7c0d072 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -18,7 +18,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index b848d699bc..1856580ce8 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -19,7 +19,7 @@ #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "Common/Profiler/Profiler.h" diff --git a/UI/GPUDriverTestScreen.h b/UI/GPUDriverTestScreen.h index a241e81bae..0f5de4a8b0 100644 --- a/UI/GPUDriverTestScreen.h +++ b/UI/GPUDriverTestScreen.h @@ -1,6 +1,6 @@ #pragma once -#include "base/display.h" +#include "Common/System/Display.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 9804387f7e..77ed61bed0 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -19,7 +19,7 @@ #include -#include "base/display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres +#include "Common/System/Display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres #include "base/NativeApp.h" #include "Common/Data/Color/RGBAUtil.h" diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 0277c34592..8b4d4b8b4a 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -18,7 +18,7 @@ #include #include "Common/Data/Color/RGBAUtil.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "gfx/texture_atlas.h" #include "Common/Math/math_util.h" diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 645a4255cd..04aa540a49 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -20,7 +20,7 @@ #include "ppsspp_config.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 5a861c3d58..86bc8360b2 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -21,7 +21,7 @@ #include #include "base/NativeApp.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "gfx_es2/draw_buffer.h" #include "Common/Math/curves.h" #include "ui/ui_context.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 0eb2977cbc..b4bd291126 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -43,7 +43,7 @@ #include "Windows/CaptureDevice.h" #endif -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "net/http_client.h" #include "net/resolve.h" diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index 59765847f0..bf63825722 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -17,7 +17,7 @@ #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 9156bfa093..af2508dc88 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -453,6 +453,7 @@ + @@ -529,6 +530,7 @@ + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 58ec4db297..189cf456c9 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -61,6 +61,9 @@ {6673c122-d7ed-4ccc-969a-12d317ee1f93} + + {661f7d9d-5922-48d6-88ea-2f24bb57419f} + @@ -246,6 +249,9 @@ Profiler + + System + @@ -437,6 +443,9 @@ Profiler + + System + diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 6188606368..6f48714b88 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -7,7 +7,7 @@ #include "file/file_util.h" #include "net/http_client.h" #include "net/resolve.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "thin3d/thin3d_create.h" #include "Common/Common.h" diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index c37127f0dc..e26f9644d8 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -22,7 +22,7 @@ #include "Common/CommonWindows.h" #include "Common/Data/Encoding/Utf8.h" #include "ext/xxhash.h" -#include "base/display.h" +#include "Common/System/Display.h" #include #include diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 4dda0822e1..7ae71ef331 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -9,7 +9,7 @@ #include "Windows/W32Util/Misc.h" #include "Windows/InputBox.h" #include "Windows/main.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Debugger_Disasm.h" #include "DebuggerShared.h" diff --git a/Windows/Debugger/CtrlRegisterList.cpp b/Windows/Debugger/CtrlRegisterList.cpp index 791838cdd3..02992e5f28 100644 --- a/Windows/Debugger/CtrlRegisterList.cpp +++ b/Windows/Debugger/CtrlRegisterList.cpp @@ -3,7 +3,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Data/Encoding/Utf8.h" #include "Windows/resource.h" #include "Core/MemMap.h" diff --git a/Windows/Debugger/Debugger_MemoryDlg.cpp b/Windows/Debugger/Debugger_MemoryDlg.cpp index 9604616f01..3302786160 100644 --- a/Windows/Debugger/Debugger_MemoryDlg.cpp +++ b/Windows/Debugger/Debugger_MemoryDlg.cpp @@ -4,7 +4,7 @@ #include #include "..\resource.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Data/Encoding/Utf8.h" #include "Core/Debugger/SymbolMap.h" diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index 741ca4b3af..78b3373a5e 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -1,4 +1,4 @@ -#include "base/display.h" +#include "Common/System/Display.h" #include "Windows/GEDebugger/CtrlDisplayListView.h" #include "Windows/GEDebugger/GEDebugger.h" #include "Windows/InputBox.h" diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 9ced64d60c..32d158c54e 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -5,7 +5,7 @@ #include #include "Common/Log.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Text/I18n.h" diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index be91557b47..daeb0fd86b 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -5,7 +5,7 @@ #include "gfx/d3d9_state.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Text/I18n.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 3178e1adfe..560073b65e 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -31,7 +31,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" diff --git a/Windows/RawInput.cpp b/Windows/RawInput.cpp index 9d7f9ba79a..6f8071058f 100644 --- a/Windows/RawInput.cpp +++ b/Windows/RawInput.cpp @@ -20,7 +20,7 @@ #include #include "base/NativeApp.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Input/InputState.h" #include "Common/Log.h" #include "Windows/RawInput.h" diff --git a/Windows/TouchInputHandler.cpp b/Windows/TouchInputHandler.cpp index b052ed3fa9..1066e04c85 100644 --- a/Windows/TouchInputHandler.cpp +++ b/Windows/TouchInputHandler.cpp @@ -4,7 +4,7 @@ #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "Common/CommonWindows.h" diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 3269917f10..02d28ff3d6 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -32,7 +32,7 @@ #pragma warning(pop) // native stuff -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "file/file_util.h" #include "Common/Input/InputState.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index 5d5464f284..c05d717714 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -31,7 +31,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 9ef7d2b702..2277a40f41 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -102,7 +102,6 @@ ARCH_FILES := \ endif NATIVE_FILES :=\ - $(SRC)/ext/native/base/display.cpp \ $(SRC)/ext/native/file/fd_util.cpp \ $(SRC)/ext/native/file/file_util.cpp \ $(SRC)/ext/native/net/http_client.cpp \ @@ -278,6 +277,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Math/lin/vec3.cpp.arm \ $(SRC)/Common/Math/lin/matrix4x4.cpp.arm \ $(SRC)/Common/Profiler/Profiler.cpp \ + $(SRC)/Common/System/Display.cpp \ $(SRC)/Common/Thread/Executor.cpp \ $(SRC)/Common/Thread/PrioritizedWorkQueue.cpp \ $(SRC)/Common/Thread/ThreadPool.cpp \ diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index ffd5564494..d11feaf5a9 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -1,5 +1,5 @@ #include "AndroidJavaGLContext.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "Common/Log.h" diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 49eb548c2d..6de6dc5cf7 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -1,6 +1,6 @@ #include "AndroidVulkanContext.h" #include "base/NativeApp.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanDebug.h" diff --git a/android/jni/TestRunner.cpp b/android/jni/TestRunner.cpp index b7ca679ed5..8bc9809d7b 100644 --- a/android/jni/TestRunner.cpp +++ b/android/jni/TestRunner.cpp @@ -26,7 +26,7 @@ #include #include "ppsspp_config.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/FileUtil.h" #include "Common/Log.h" diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 57e2d4c7c6..e60f6bc01c 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -49,7 +49,7 @@ struct JNIEnv {}; #define JNI_VERSION_1_6 16 #endif -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "Common/Thread/ThreadUtil.h" #include "Common/File/VFS/VFS.h" diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index a5c0e5a7a6..a31f938584 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -3,7 +3,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Math/math_util.h" #include "gfx/texture_atlas.h" #include "gfx/gl_debug_log.h" diff --git a/ext/native/gfx_es2/draw_text.cpp b/ext/native/gfx_es2/draw_text.cpp index c8d5d374d1..b1fae13c8e 100644 --- a/ext/native/gfx_es2/draw_text.cpp +++ b/ext/native/gfx_es2/draw_text.cpp @@ -1,4 +1,4 @@ -#include "base/display.h" +#include "Common/System/Display.h" #include "thin3d/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index c824c0cd48..c19f859cf7 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -1,4 +1,4 @@ -#include "base/display.h" +#include "Common/System/Display.h" #include "thin3d/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" diff --git a/ext/native/gfx_es2/draw_text_qt.cpp b/ext/native/gfx_es2/draw_text_qt.cpp index f522e2c993..56b8c6e56c 100644 --- a/ext/native/gfx_es2/draw_text_qt.cpp +++ b/ext/native/gfx_es2/draw_text_qt.cpp @@ -1,4 +1,4 @@ -#include "base/display.h" +#include "Common/System/Display.h" #include "thin3d/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index 3171b01608..71e88f0fd5 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -1,4 +1,4 @@ -#include "base/display.h" +#include "Common/System/Display.h" #include "thin3d/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" diff --git a/ext/native/gfx_es2/draw_text_win.cpp b/ext/native/gfx_es2/draw_text_win.cpp index 320d2968f3..1767d71cfa 100644 --- a/ext/native/gfx_es2/draw_text_win.cpp +++ b/ext/native/gfx_es2/draw_text_win.cpp @@ -1,4 +1,4 @@ -#include "base/display.h" +#include "Common/System/Display.h" #include "thin3d/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 7a4d64981e..7e8a930e49 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -360,22 +360,10 @@ - - true - true - true - true - true - true - true - true - - - @@ -424,27 +412,6 @@ - - - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index e11d74cf0e..76060179e4 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -5,9 +5,6 @@ tools - - base - @@ -37,9 +34,6 @@ base - - base - ui @@ -127,9 +121,6 @@ ui - - base - thin3d @@ -180,9 +171,6 @@ file - - base - ui @@ -240,12 +228,6 @@ net - - base - - - base - thin3d diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 60a99d4cc3..653fbae850 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -10,7 +10,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Math/math_util.h" diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index aabb1d818b..f15e96fa93 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -2,7 +2,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "thin3d/thin3d.h" #include "Common/Log.h" #include "Common/ColorConv.h" diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index a374e484e1..d39813667f 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -6,7 +6,7 @@ #else #include "thin3d/d3d11_loader.h" #endif -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 7195bc7bf4..2060f2d978 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -20,7 +20,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "image/zim_load.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Data/Convert/SmallDataConvert.h" diff --git a/ext/native/ui/screen.cpp b/ext/native/ui/screen.cpp index 86b1dc02c4..97f5f2c567 100644 --- a/ext/native/ui/screen.cpp +++ b/ext/native/ui/screen.cpp @@ -1,4 +1,4 @@ -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Input/InputState.h" #include "ui/root.h" #include "ui/screen.h" diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index 6b4aa25cd4..052332f0bd 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -2,7 +2,7 @@ #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "ui/ui.h" #include "ui/view.h" diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index 3e96d79c39..8ba6eb2bb0 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -2,7 +2,7 @@ #include #include -#include "base/display.h" +#include "Common/System/Display.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "Common/Math/curves.h" diff --git a/ios/DisplayManager.mm b/ios/DisplayManager.mm index 495353a6df..e3ae0a7b66 100644 --- a/ios/DisplayManager.mm +++ b/ios/DisplayManager.mm @@ -8,7 +8,7 @@ #import "DisplayManager.h" #import "ViewController.h" #import "AppDelegate.h" -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "Core/System.h" #import diff --git a/ios/PPSSPPUIApplication.mm b/ios/PPSSPPUIApplication.mm index 65a24d3c64..4beb622c44 100644 --- a/ios/PPSSPPUIApplication.mm +++ b/ios/PPSSPPUIApplication.mm @@ -12,7 +12,7 @@ #import #import -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "Common/TimeUtil.h" #include "file/zip_read.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 1bd8087ae0..6e702ba12c 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -12,7 +12,7 @@ #import #include -#include "base/display.h" +#include "Common/System/Display.h" #include "base/NativeApp.h" #include "file/zip_read.h" #include "net/resolve.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 71095ccea5..d0a534c6c9 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -170,6 +170,7 @@ SOURCES_CXX += \ $(COMMONDIR)/Thread/ThreadUtil.cpp \ $(COMMONDIR)/Thread/ThreadPool.cpp \ $(COMMONDIR)/Thread/PrioritizedWorkQueue.cpp \ + $(COMMONDIR)/System/Display.cpp \ $(COMMONDIR)/Input/GestureDetector.cpp \ $(COMMONDIR)/Input/InputState.cpp \ $(COMMONDIR)/Buffer.cpp \ @@ -242,7 +243,6 @@ SOURCES_CXX += \ $(GPUDIR)/GLES/ShaderManagerGLES.cpp \ $(GPUDIR)/GLES/StateMappingGLES.cpp \ $(GPUDIR)/GLES/StencilBufferGLES.cpp \ - $(EXTDIR)/native/base/display.cpp \ $(EXTDIR)/glslang/OGLCompilersDLL/InitializeDll.cpp \ $(EXTDIR)/glslang/glslang/GenericCodeGen/CodeGen.cpp \ $(EXTDIR)/glslang/glslang/GenericCodeGen/Link.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 1a6e82ae49..219432057e 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -3,11 +3,22 @@ #include #include #include -#include +#include +#include "base/NativeApp.h" + +#include "Common/Log.h" +#include "Common/LogManager.h" +#include "Common/System/Display.h" #include "Common/TimeUtil.h" #include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" +#include "Common/ConsoleListener.h" +#include "Common/Input/InputState.h" +#include "Common/Thread/ThreadUtil.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" + #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Core.h" @@ -18,18 +29,11 @@ #include "Core/Host.h" #include "Core/MemMap.h" #include "Core/System.h" -#include "Log.h" -#include "LogManager.h" -#include "ConsoleListener.h" -#include "Common/File/VFS/VFS.h" -#include "Common/File/VFS/AssetReader.h" + #include "GPU/GPUState.h" #include "GPU/GPUInterface.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureScalerCommon.h" -#include "Common/Input/InputState.h" -#include "base/NativeApp.h" -#include "Common/Thread/ThreadUtil.h" #include "libretro/libretro.h" #include "libretro/LibretroGraphicsContext.h" From f01ba6dc846ea00cf853def01c57b222d47cf29a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 10:30:18 +0200 Subject: [PATCH 825/848] Move NativeApp.h to Common/System, split into NativeApp.h and System.h Buildfix --- CMakeLists.txt | 1 - Common/Common.vcxproj | 4 + Common/Common.vcxproj.filters | 12 +++ Common/Data/Format/RIFF.cpp | 2 + Common/Data/Format/RIFF.h | 1 - Common/MemArenaAndroid.cpp | 2 +- Common/MemArenaPosix.cpp | 7 +- .../native/base => Common/System}/NativeApp.h | 98 ----------------- Common/System/System.h | 101 ++++++++++++++++++ Common/Vulkan/VulkanLoader.cpp | 2 +- Core/Config.cpp | 4 +- Core/Core.cpp | 3 +- Core/Dialog/PSPOskDialog.cpp | 7 +- Core/HLE/sceDisplay.cpp | 7 +- Core/HLE/sceUsbCam.cpp | 2 +- Core/HLE/sceUsbGps.cpp | 3 +- Core/HW/StereoResampler.cpp | 2 +- Core/KeyMap.cpp | 3 +- Core/System.cpp | 2 +- GPU/Common/PresentationCommon.cpp | 4 +- GPU/D3D11/GPU_D3D11.cpp | 2 +- GPU/Directx9/GPU_DX9.cpp | 2 +- Qt/QtMain.cpp | 3 +- Qt/QtMain.h | 3 +- Qt/mainwindow.cpp | 3 +- Qt/mainwindow.h | 3 +- SDL/SDLGLGraphicsContext.cpp | 12 ++- SDL/SDLJoystick.cpp | 3 +- SDL/SDLMain.cpp | 3 +- SDL/SDLVulkanGraphicsContext.cpp | 5 +- UI/ChatScreen.cpp | 2 +- UI/ControlMappingScreen.cpp | 6 +- UI/CwCheatScreen.cpp | 2 +- UI/DevScreens.cpp | 3 +- UI/DisplayLayoutScreen.cpp | 2 +- UI/EmuScreen.cpp | 10 +- UI/GameScreen.cpp | 3 +- UI/GameSettingsScreen.cpp | 15 +-- UI/GamepadEmu.cpp | 2 +- UI/MainScreen.cpp | 2 +- UI/MiscScreens.cpp | 8 +- UI/NativeApp.cpp | 20 ++-- UI/PauseScreen.cpp | 7 +- UI/RemoteISOScreen.cpp | 2 +- UI/ReportScreen.cpp | 4 +- UWP/App.cpp | 3 +- UWP/CommonUWP/CommonUWP.vcxproj | 2 + UWP/CommonUWP/CommonUWP.vcxproj.filters | 6 ++ UWP/NativeUWP/NativeUWP.vcxproj | 3 - UWP/NativeUWP/NativeUWP.vcxproj.filters | 12 --- UWP/PPSSPP_UWPMain.cpp | 5 +- UWP/UWPHost.cpp | 3 +- Windows/DinputDevice.cpp | 2 +- Windows/EmuThread.cpp | 7 +- Windows/MainWindow.cpp | 3 +- Windows/MainWindowMenu.cpp | 7 +- Windows/RawInput.cpp | 2 +- Windows/TouchInputHandler.cpp | 2 +- Windows/WindowsHost.cpp | 2 +- Windows/XinputDevice.cpp | 2 +- Windows/main.cpp | 3 +- android/ab.cmd | 4 +- android/jni/AndroidEGLContext.cpp | 2 +- android/jni/AndroidJavaGLContext.cpp | 1 - android/jni/AndroidVulkanContext.cpp | 3 +- android/jni/app-android.cpp | 12 ++- ext/native/native.vcxproj | 1 - ext/native/native.vcxproj.filters | 6 -- ext/native/ui/ui_context.cpp | 2 +- ext/native/ui/view.cpp | 3 +- headless/Headless.cpp | 3 +- headless/SDLHeadlessHost.cpp | 4 +- ios/AppDelegate.mm | 3 +- ios/DisplayManager.mm | 3 +- ios/PPSSPPUIApplication.mm | 6 +- ios/ViewController.mm | 8 +- ios/main.mm | 3 +- libretro/libretro.cpp | 4 +- unittest/JitHarness.cpp | 4 +- unittest/UnitTest.cpp | 5 +- 80 files changed, 289 insertions(+), 246 deletions(-) rename {ext/native/base => Common/System}/NativeApp.h (55%) create mode 100644 Common/System/System.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bdfe17939..2daab5c16f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -814,7 +814,6 @@ if(ANDROID) ) set(NativeAppSource ${NativeAppSource} - ext/native/base/NativeApp.h android/jni/app-android.cpp android/jni/AndroidEGLContext.cpp android/jni/AndroidEGLContext.h diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 6d8e13d2f8..e319b38ae2 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -451,6 +451,9 @@ + + + @@ -722,6 +725,7 @@ + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 483144fcab..397028e32a 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -229,6 +229,15 @@ Profiler + + System + + + System + + + System + @@ -439,6 +448,9 @@ Profiler + + System + diff --git a/Common/Data/Format/RIFF.cpp b/Common/Data/Format/RIFF.cpp index 2ef0576fde..2b6056a125 100644 --- a/Common/Data/Format/RIFF.cpp +++ b/Common/Data/Format/RIFF.cpp @@ -1,3 +1,5 @@ +#include + #include "Common/Log.h" #include "Common/Data/Format/RIFF.h" diff --git a/Common/Data/Format/RIFF.h b/Common/Data/Format/RIFF.h index ab1b5c020f..0e0dbee623 100644 --- a/Common/Data/Format/RIFF.h +++ b/Common/Data/Format/RIFF.h @@ -10,7 +10,6 @@ // otherwise the scheme breaks. #include -#include #include class RIFFReader { diff --git a/Common/MemArenaAndroid.cpp b/Common/MemArenaAndroid.cpp index 462d1a3a94..c304f86435 100644 --- a/Common/MemArenaAndroid.cpp +++ b/Common/MemArenaAndroid.cpp @@ -27,11 +27,11 @@ #include #include -#include "base/NativeApp.h" #include "Common/Log.h" #include "Common/MemoryUtil.h" #include "Common/MemArena.h" #include "Common/StringUtils.h" +#include "Common/System/System.h" // Hopefully this ABI will never change... diff --git a/Common/MemArenaPosix.cpp b/Common/MemArenaPosix.cpp index 566af59ce4..016be57ce5 100644 --- a/Common/MemArenaPosix.cpp +++ b/Common/MemArenaPosix.cpp @@ -21,9 +21,10 @@ #include -#include "FileUtil.h" -#include "MemoryUtil.h" -#include "MemArena.h" +#include "Common/FileUtil.h" +#include "Common/MemoryUtil.h" +#include "Common/MemArena.h" +#include "Common/Log.h" #include #include diff --git a/ext/native/base/NativeApp.h b/Common/System/NativeApp.h similarity index 55% rename from ext/native/base/NativeApp.h rename to Common/System/NativeApp.h index 3242bfa019..d501d03b43 100644 --- a/ext/native/base/NativeApp.h +++ b/Common/System/NativeApp.h @@ -2,7 +2,6 @@ #include #include -#include // The Native App API. // @@ -17,17 +16,6 @@ struct AxisInput; class GraphicsContext; -enum SystemPermission { - SYSTEM_PERMISSION_STORAGE, -}; - -enum PermissionStatus { - PERMISSION_STATUS_UNKNOWN, - PERMISSION_STATUS_DENIED, - PERMISSION_STATUS_PENDING, - PERMISSION_STATUS_GRANTED, -}; - // The first function to get called, just write strings to the two pointers. // This might get called multiple times in some implementations, you must be able to handle that. void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name, bool *landscape, std::string *version); @@ -101,89 +89,3 @@ void NativeSetMixer(void* mixer); // Main thread. void NativeShutdownGraphics(); void NativeShutdown(); - -// Calls back into Java / SDL -// These APIs must be implemented by every port (for example app-android.cpp, SDLMain.cpp). -// You are free to call these. -void SystemToast(const char *text); -void ShowKeyboard(); - -// Vibrate either takes a number of milliseconds to vibrate unconditionally, -// or you can specify these constants for "standard" feedback. On Android, -// these will only be performed if haptic feedback is enabled globally. -// Also, on Android, these will work even if you don't have the VIBRATE permission, -// while generic vibration will not if you don't have it. -enum { - HAPTIC_SOFT_KEYBOARD = -1, - HAPTIC_VIRTUAL_KEY = -2, - HAPTIC_LONG_PRESS_ACTIVATED = -3, -}; -void Vibrate(int length_ms); -void OpenDirectory(const char *path); -void LaunchBrowser(const char *url); -void LaunchMarket(const char *url); -void LaunchEmail(const char *email_address); -void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function cb); -void System_SendMessage(const char *command, const char *parameter); -PermissionStatus System_GetPermissionStatus(SystemPermission permission); -void System_AskForPermission(SystemPermission permission); - -// This will get muddy with multi-screen support :/ But this will always be the type of the main device. -enum SystemDeviceType { - DEVICE_TYPE_MOBILE = 0, // phones and pads - DEVICE_TYPE_TV = 1, // Android TV and similar - DEVICE_TYPE_DESKTOP = 2, // Desktop computer -}; - -enum SystemProperty { - SYSPROP_NAME, - SYSPROP_LANGREGION, - SYSPROP_CPUINFO, - SYSPROP_BOARDNAME, - SYSPROP_CLIPBOARD_TEXT, - SYSPROP_GPUDRIVER_VERSION, - - SYSPROP_HAS_FILE_BROWSER, - SYSPROP_HAS_IMAGE_BROWSER, - SYSPROP_HAS_BACK_BUTTON, - - // Available as Int: - SYSPROP_SYSTEMVERSION, - SYSPROP_DISPLAY_XRES, - SYSPROP_DISPLAY_YRES, - SYSPROP_DISPLAY_REFRESH_RATE, - SYSPROP_DISPLAY_LOGICAL_DPI, - SYSPROP_DISPLAY_DPI, - SYSPROP_DISPLAY_COUNT, - SYSPROP_MOGA_VERSION, - - // Float only: - SYSPROP_DISPLAY_SAFE_INSET_LEFT, - SYSPROP_DISPLAY_SAFE_INSET_RIGHT, - SYSPROP_DISPLAY_SAFE_INSET_TOP, - SYSPROP_DISPLAY_SAFE_INSET_BOTTOM, - - SYSPROP_DEVICE_TYPE, - SYSPROP_APP_GOLD, // To avoid having #ifdef GOLD other than in main.cpp and similar. - - // Exposed on Android. Choosing the optimal sample rate for audio - // will result in lower latencies. Buffer size is automatically matched - // by the OpenSL audio backend, only exposed here for debugging/info. - SYSPROP_AUDIO_SAMPLE_RATE, - SYSPROP_AUDIO_FRAMES_PER_BUFFER, - SYSPROP_AUDIO_OPTIMAL_SAMPLE_RATE, - SYSPROP_AUDIO_OPTIMAL_FRAMES_PER_BUFFER, - - // Exposed on SDL. - SYSPROP_AUDIO_DEVICE_LIST, - - SYSPROP_SUPPORTS_PERMISSIONS, - SYSPROP_SUPPORTS_SUSTAINED_PERF_MODE, -}; - -std::string System_GetProperty(SystemProperty prop); -int System_GetPropertyInt(SystemProperty prop); -float System_GetPropertyFloat(SystemProperty prop); -bool System_GetPropertyBool(SystemProperty prop); - -std::vector __cameraGetDeviceList(); diff --git a/Common/System/System.h b/Common/System/System.h new file mode 100644 index 0000000000..2d87f7399d --- /dev/null +++ b/Common/System/System.h @@ -0,0 +1,101 @@ +#pragma once + +#include +#include +#include + +enum SystemPermission { + SYSTEM_PERMISSION_STORAGE, +}; + +enum PermissionStatus { + PERMISSION_STATUS_UNKNOWN, + PERMISSION_STATUS_DENIED, + PERMISSION_STATUS_PENDING, + PERMISSION_STATUS_GRANTED, +}; + +// These APIs must be implemented by every port (for example app-android.cpp, SDLMain.cpp). +// Ideally these should be safe to call from any thread. +void SystemToast(const char *text); +void ShowKeyboard(); + +// Vibrate either takes a number of milliseconds to vibrate unconditionally, +// or you can specify these constants for "standard" feedback. On Android, +// these will only be performed if haptic feedback is enabled globally. +// Also, on Android, these will work even if you don't have the VIBRATE permission, +// while generic vibration will not if you don't have it. +enum { + HAPTIC_SOFT_KEYBOARD = -1, + HAPTIC_VIRTUAL_KEY = -2, + HAPTIC_LONG_PRESS_ACTIVATED = -3, +}; +void Vibrate(int length_ms); +void OpenDirectory(const char *path); +void LaunchBrowser(const char *url); +void LaunchMarket(const char *url); +void LaunchEmail(const char *email_address); +void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function cb); +void System_SendMessage(const char *command, const char *parameter); +PermissionStatus System_GetPermissionStatus(SystemPermission permission); +void System_AskForPermission(SystemPermission permission); + +// This will get muddy with multi-screen support :/ But this will always be the type of the main device. +enum SystemDeviceType { + DEVICE_TYPE_MOBILE = 0, // phones and pads + DEVICE_TYPE_TV = 1, // Android TV and similar + DEVICE_TYPE_DESKTOP = 2, // Desktop computer +}; + +enum SystemProperty { + SYSPROP_NAME, + SYSPROP_LANGREGION, + SYSPROP_CPUINFO, + SYSPROP_BOARDNAME, + SYSPROP_CLIPBOARD_TEXT, + SYSPROP_GPUDRIVER_VERSION, + + SYSPROP_HAS_FILE_BROWSER, + SYSPROP_HAS_IMAGE_BROWSER, + SYSPROP_HAS_BACK_BUTTON, + + // Available as Int: + SYSPROP_SYSTEMVERSION, + SYSPROP_DISPLAY_XRES, + SYSPROP_DISPLAY_YRES, + SYSPROP_DISPLAY_REFRESH_RATE, + SYSPROP_DISPLAY_LOGICAL_DPI, + SYSPROP_DISPLAY_DPI, + SYSPROP_DISPLAY_COUNT, + SYSPROP_MOGA_VERSION, + + // Float only: + SYSPROP_DISPLAY_SAFE_INSET_LEFT, + SYSPROP_DISPLAY_SAFE_INSET_RIGHT, + SYSPROP_DISPLAY_SAFE_INSET_TOP, + SYSPROP_DISPLAY_SAFE_INSET_BOTTOM, + + SYSPROP_DEVICE_TYPE, + SYSPROP_APP_GOLD, // To avoid having #ifdef GOLD other than in main.cpp and similar. + + // Exposed on Android. Choosing the optimal sample rate for audio + // will result in lower latencies. Buffer size is automatically matched + // by the OpenSL audio backend, only exposed here for debugging/info. + SYSPROP_AUDIO_SAMPLE_RATE, + SYSPROP_AUDIO_FRAMES_PER_BUFFER, + SYSPROP_AUDIO_OPTIMAL_SAMPLE_RATE, + SYSPROP_AUDIO_OPTIMAL_FRAMES_PER_BUFFER, + + // Exposed on SDL. + SYSPROP_AUDIO_DEVICE_LIST, + + SYSPROP_SUPPORTS_PERMISSIONS, + SYSPROP_SUPPORTS_SUSTAINED_PERF_MODE, +}; + +std::string System_GetProperty(SystemProperty prop); +int System_GetPropertyInt(SystemProperty prop); +float System_GetPropertyFloat(SystemProperty prop); +bool System_GetPropertyBool(SystemProperty prop); + +std::vector __cameraGetDeviceList(); diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index b70259c610..0a58291277 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -21,7 +21,7 @@ #include #include "Common/Log.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" #ifndef _WIN32 #include diff --git a/Core/Config.cpp b/Core/Config.cpp index 89aeb90706..3a98ae836f 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -24,8 +24,6 @@ #include "ppsspp_config.h" -#include "Common/System/Display.h" -#include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "net/http_client.h" #include "net/url.h" @@ -39,6 +37,8 @@ #include "Common/FileUtil.h" #include "Common/LogManager.h" #include "Common/OSVersion.h" +#include "Common/System/Display.h" +#include "Common/System/System.h" #include "Common/StringUtils.h" #include "Common/Vulkan/VulkanLoader.h" #include "Core/Config.h" diff --git a/Core/Core.cpp b/Core/Core.cpp index 9748441e1a..f3cdd9b624 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -22,7 +22,8 @@ #include #include -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/System/Display.h" #include "Common/TimeUtil.h" #include "Common/Thread/ThreadUtil.h" diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index add21d1cdd..c049225f02 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -16,12 +16,14 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "base/NativeApp.h" + #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" #include "Common/Data/Encoding/Utf8.h" - #include "Common/Serialize/SerializeFuncs.h" +#include "Common/System/System.h" +#include "Common/Serialize/Serializer.h" + #include "Core/Dialog/PSPOskDialog.h" #include "Core/Util/PPGeDraw.h" #include "Core/HLE/sceCtrl.h" @@ -29,7 +31,6 @@ #include "Core/HLE/sceUtility.h" #include "Core/Config.h" #include "Core/Reporting.h" -#include "Common/Serialize/Serializer.h" #include "GPU/GPUState.h" #ifndef _WIN32 diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 1c82dfa0a6..6df19c4cea 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -26,12 +26,11 @@ #include #endif -#include "Common/Data/Text/I18n.h" -#include "Common/Profiler/Profiler.h" - -#include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Profiler/Profiler.h" +#include "Common/System/System.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeMap.h" diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index 7de78168ee..7793e372a0 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -20,7 +20,7 @@ #include "ppsspp_config.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" diff --git a/Core/HLE/sceUsbGps.cpp b/Core/HLE/sceUsbGps.cpp index 3d014318ac..723e83d445 100644 --- a/Core/HLE/sceUsbGps.cpp +++ b/Core/HLE/sceUsbGps.cpp @@ -16,7 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "base/NativeApp.h" + +#include "Common/System/System.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/HLE/HLE.h" diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index c1e9b00049..898f21b48c 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -35,7 +35,7 @@ #include #include -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "Common/MathUtil.h" #include "Common/Serialize/Serializer.h" #include "Common/Log.h" diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index 20d04b9599..8d94087708 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -26,7 +26,8 @@ #include "ppsspp_config.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/Data/Format/IniFile.h" #include "Common/Input/InputState.h" #include "Common/Log.h" diff --git a/Core/System.cpp b/Core/System.cpp index a9f68c324b..48e22b6f5e 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -32,7 +32,7 @@ #include #include -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "Common/Math/math_util.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index d80394f55f..31e36a847c 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -19,10 +19,10 @@ #include #include -#include "Common/System/Display.h" -#include "base/NativeApp.h" #include "thin3d/thin3d.h" +#include "Common/System/Display.h" +#include "Common/System/System.h" #include "Common/File/VFS/VFS.h" #include "Common/Log.h" #include "Common/TimeUtil.h" diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 8199b3667c..a8f7b95fa6 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -39,7 +39,7 @@ #include "Common/Log.h" #include "Common/Serialize/Serializer.h" #include "Common/GraphicsContext.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "Common/Profiler/Profiler.h" #include "Common/Data/Text/I18n.h" #include "Core/Debugger/Breakpoints.h" diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 1b5be8e793..5db0cbffd8 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -19,7 +19,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/GraphicsContext.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "Common/Profiler/Profiler.h" #include "Common/Data/Text/I18n.h" #include "Core/Debugger/Breakpoints.h" diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 7f46133c19..450eefee31 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -31,7 +31,8 @@ #include "SDL_audio.h" #endif -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "gfx_es2/gpu_features.h" #include "Common/Math/math_util.h" diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 3a1cd3a750..cd33b61765 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -24,7 +24,8 @@ QTM_USE_NAMESPACE #include "Common/System/Display.h" #include "Common/TimeUtil.h" -#include "file/zip_read.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" #include "Common/Input/InputState.h" diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index fe48956f2e..c2301004d3 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -8,7 +8,8 @@ #include #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Core/MIPS/MIPSDebugInterface.h" #include "Core/Debugger/SymbolMap.h" #include "Core/HLE/sceUmd.h" diff --git a/Qt/mainwindow.h b/Qt/mainwindow.h index 6334bc4aca..cdc08ca196 100644 --- a/Qt/mainwindow.h +++ b/Qt/mainwindow.h @@ -8,7 +8,8 @@ #include #include -#include "base/NativeApp.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" #include "ConsoleListener.h" #include "Core/Core.h" #include "Core/Config.h" diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index 2d41fd1c4f..168a07afcd 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -1,12 +1,16 @@ #include + #include "SDLGLGraphicsContext.h" + +#include "gfx_es2/gpu_features.h" +#include "thin3d/thin3d_create.h" + +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" +#include "Common/System/Display.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" -#include "base/NativeApp.h" -#include "Common/System/Display.h" -#include "gfx_es2/gpu_features.h" -#include "thin3d/thin3d_create.h" #if defined(USING_EGL) #include "EGL/egl.h" diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp index 53ed2cc921..50793957e1 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -1,7 +1,8 @@ #include #include -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/File/VFS/VFS.h" #include "Common/FileUtil.h" diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 37b3ad12af..78eef5170e 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -21,7 +21,8 @@ SDLJoystick *joystick = NULL; #include #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" #include "ext/glslang/glslang/Public/ShaderLang.h" #include "image/png_load.h" #include "net/resolve.h" diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 77bb943ecc..3c07ab942c 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -1,6 +1,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" #include "Common/System/Display.h" #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" @@ -154,4 +155,4 @@ void SDLVulkanGraphicsContext::Poll() { if (vulkan_->GetSwapchain() && renderManager_->NeedsSwapchainRecreate()) { Resize(); } -} \ No newline at end of file +} diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index b7e4b33819..3283d86bf8 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -1,7 +1,6 @@ #include #include "ppsspp_config.h" -#include "base/NativeApp.h" #include "ui/root.h" #include "ui/ui_context.h" #include "ui/view.h" @@ -10,6 +9,7 @@ #include "Common/Data/Text/I18n.h" #include "Common/Data/Encoding/Utf8.h" +#include "Common/System/System.h" #include "Core/Config.h" #include "Core/System.h" #include "Core/HLE/proAdhoc.h" diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 518d805292..da64c785f2 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -19,8 +19,6 @@ #include #include -#include "Common/System/Display.h" -#include "base/NativeApp.h" #include "gfx/texture_atlas.h" #include "ui/root.h" #include "ui/ui.h" @@ -28,11 +26,13 @@ #include "ui/view.h" #include "ui/viewgroup.h" +#include "Common/Log.h" #include "Common/Data/Color/RGBAUtil.h" #include "Common/Data/Text/I18n.h" #include "Common/Input/KeyCodes.h" #include "Common/Input/InputState.h" -#include "Common/Log.h" +#include "Common/System/Display.h" +#include "Common/System/System.h" #include "Core/KeyMap.h" #include "Core/Host.h" #include "Core/HLE/sceCtrl.h" diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index eb67a666b8..c92f7b838d 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -15,7 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "base/NativeApp.h" #include "ext/xxhash.h" #include "ui/ui.h" @@ -23,6 +22,7 @@ #include "Common/Data/Encoding/Utf8.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" +#include "Common/System/System.h" #include "Core/Core.h" #include "Core/Config.h" #include "Core/CwCheat.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 7f7bf849fd..530b0d31ed 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -19,7 +19,8 @@ #include "ppsspp_config.h" #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "gfx_es2/gpu_features.h" #include "Common/Data/Text/I18n.h" #include "ui/ui_context.h" diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 1df7c0d072..8694bbd8bb 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -19,7 +19,7 @@ #include #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" #include "ui/ui_context.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 1856580ce8..f6c6cda45e 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -19,15 +19,10 @@ #include -#include "Common/System/Display.h" -#include "base/NativeApp.h" -#include "Common/Profiler/Profiler.h" - #include "gfx/texture_atlas.h" #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_text.h" -#include "Common/Math/curves.h" #include "ui/root.h" #include "ui/ui.h" #include "ui/ui_context.h" @@ -37,6 +32,11 @@ #include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" #include "Common/Log.h" +#include "Common/System/Display.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" +#include "Common/Profiler/Profiler.h" +#include "Common/Math/curves.h" #include "Common/TimeUtil.h" #ifndef MOBILE_DEVICE diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 81b5c585d1..9404173d19 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -19,7 +19,6 @@ #include "ppsspp_config.h" -#include "base/NativeApp.h" #include "gfx_es2/draw_buffer.h" #include "ui/ui_context.h" #include "ui/view.h" @@ -28,6 +27,8 @@ #include "Common/Data/Text/I18n.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/FileUtil.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" #include "Core/Host.h" #include "Core/Config.h" #include "Core/System.h" diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 77ed61bed0..8788263d2b 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -19,20 +19,21 @@ #include -#include "Common/System/Display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres -#include "base/NativeApp.h" - -#include "Common/Data/Color/RGBAUtil.h" -#include "Common/Math/curves.h" #include "net/resolve.h" #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_buffer.h" -#include "Common/Data/Text/I18n.h" -#include "Common/Data/Encoding/Utf8.h" #include "ui/root.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "ui/ui_context.h" + +#include "Common/System/Display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" +#include "Common/Data/Color/RGBAUtil.h" +#include "Common/Math/curves.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Encoding/Utf8.h" #include "UI/EmuScreen.h" #include "UI/GameSettingsScreen.h" #include "UI/GameInfoCache.h" diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 8b4d4b8b4a..8337c83d1c 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -19,7 +19,7 @@ #include "Common/Data/Color/RGBAUtil.h" #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "gfx/texture_atlas.h" #include "Common/Math/math_util.h" #include "ui/ui_context.h" diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 04aa540a49..6439628258 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -21,7 +21,7 @@ #include "ppsspp_config.h" #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" #include "ui/root.h" diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 86bc8360b2..b19f59bdaf 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -20,14 +20,16 @@ #include #include -#include "base/NativeApp.h" -#include "Common/System/Display.h" #include "gfx_es2/draw_buffer.h" -#include "Common/Math/curves.h" #include "ui/ui_context.h" #include "ui/view.h" #include "ui/viewgroup.h" #include "ui/ui.h" + +#include "Common/System/Display.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" +#include "Common/Math/curves.h" #include "Common/File/VFS/VFS.h" #include "Common/Data/Color/RGBAUtil.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index b4bd291126..f0da507d1a 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -43,27 +43,27 @@ #include "Windows/CaptureDevice.h" #endif -#include "Common/System/Display.h" -#include "base/NativeApp.h" #include "net/http_client.h" #include "net/resolve.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/gpu_features.h" +#include "thin3d/thin3d.h" +#include "ui/ui.h" +#include "ui/screen.h" +#include "ui/ui_context.h" +#include "ui/view.h" +#include "android/jni/app-android.h" + +#include "Common/System/Display.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" #include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" #include "Common/Math/fast/fast_math.h" #include "Common/Math/math_util.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Profiler/Profiler.h" -#include "thin3d/thin3d.h" -#include "ui/ui.h" -#include "ui/screen.h" -#include "ui/ui_context.h" -#include "ui/view.h" - -#include "android/jni/app-android.h" - #include "Common/Data/Encoding/Utf8.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index f2ec060b2a..620e5c1fc1 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -18,7 +18,6 @@ #include #include -#include "base/NativeApp.h" #include "gfx_es2/draw_buffer.h" #include "ui/view.h" #include "ui/viewgroup.h" @@ -28,19 +27,19 @@ #include "Common/Data/Text/I18n.h" #include "Common/StringUtils.h" +#include "Common/System/System.h" #include "Core/Reporting.h" #include "Core/SaveState.h" #include "Core/System.h" #include "Core/Config.h" #include "Core/ELF/ParamSFO.h" +#include "Core/HLE/sceDisplay.h" +#include "Core/HLE/sceUmd.h" #include "GPU/GPUCommon.h" #include "GPU/GPUState.h" -#include "Core/HLE/sceDisplay.h" -#include "Core/HLE/sceUmd.h" - #include "UI/PauseScreen.h" #include "UI/GameSettingsScreen.h" #include "UI/ReportScreen.h" diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index be00a5eae6..0e6ae604c9 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -25,7 +25,6 @@ #include #endif -#include "base/NativeApp.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" #include "net/http_client.h" @@ -38,6 +37,7 @@ #include "Common/Common.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" +#include "Common/System/System.h" #include "Core/Config.h" #include "Core/WebServer.h" #include "UI/RemoteISOScreen.h" diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index bf63825722..480ad5a9f6 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -17,8 +17,6 @@ #include -#include "Common/System/Display.h" -#include "base/NativeApp.h" // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" #include "thin3d/thin3d.h" @@ -30,6 +28,8 @@ #include "Common/FileUtil.h" #include "Common/Log.h" #include "Common/StringUtils.h" +#include "Common/System/Display.h" +#include "Common/System/System.h" #include "Core/Core.h" #include "Core/Reporting.h" #include "Core/Screenshot.h" diff --git a/UWP/App.cpp b/UWP/App.cpp index ee26dd40a0..94159e7602 100644 --- a/UWP/App.cpp +++ b/UWP/App.cpp @@ -5,8 +5,9 @@ #include -#include "base/NativeApp.h" #include "Common/Input/InputState.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Core/System.h" #include "Core/Core.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index af2508dc88..d1b6b551bc 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -454,6 +454,8 @@ + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 189cf456c9..22b87aec1e 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -446,6 +446,12 @@ System + + System + + + System + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 721cda4f7d..ced0674db9 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -379,8 +379,6 @@ - - @@ -410,7 +408,6 @@ - diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index a2f90645d1..9cade1425a 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -1,9 +1,6 @@  - - {903dae00-880d-4c12-bd10-29fca750376f} - {98343696-3517-451a-9b47-94d462263e3e} @@ -25,9 +22,6 @@ - - base - thin3d @@ -110,12 +104,6 @@ - - base - - - base - thin3d diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 6f48714b88..54c9b1a73e 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -3,11 +3,9 @@ #include -#include "base/NativeApp.h" #include "file/file_util.h" #include "net/http_client.h" #include "net/resolve.h" -#include "Common/System/Display.h" #include "thin3d/thin3d_create.h" #include "Common/Common.h" @@ -22,6 +20,9 @@ #include "Common/LogManager.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" +#include "Common/System/Display.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Core/System.h" #include "Core/Loaders.h" diff --git a/UWP/UWPHost.cpp b/UWP/UWPHost.cpp index d7526a9e2c..be3f93d826 100644 --- a/UWP/UWPHost.cpp +++ b/UWP/UWPHost.cpp @@ -20,7 +20,8 @@ #include #include "file/file_util.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/Input/InputState.h" #include "Common/StringUtils.h" diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 8d57cd19c5..d59874d680 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -24,7 +24,7 @@ #include "DinputDevice.h" #include "Core/Config.h" #include "Common/Input/InputState.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" #include "Common/Input/KeyCodes.h" #include "Core/Reporting.h" #include "Xinput.h" diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index bfb2df00c6..120130161e 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -2,15 +2,17 @@ #include #include -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" #include "Common/Data/Encoding/Utf8.h" - #include "Common/Log.h" #include "Common/StringUtils.h" #include "Common/GraphicsContext.h" #include "Common/TimeUtil.h" +#include "Common/Thread/ThreadUtil.h" + #include "Windows/EmuThread.h" #include "Windows/W32Util/Misc.h" #include "Windows/MainWindow.h" @@ -23,7 +25,6 @@ #include "Core/System.h" #include "Core/Config.h" #include "Core/ConfigValues.h" -#include "Common/Thread/ThreadUtil.h" enum class EmuThreadState { DISABLED, diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 560073b65e..439791544e 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -32,7 +32,8 @@ #include #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" #include "Common/Data/Text/I18n.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index fab9c450cc..6cbf136fc5 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -7,11 +7,12 @@ #include "resource.h" +#include "gfx_es2/gpu_features.h" + #include "Common/Data/Text/I18n.h" #include "Common/Data/Encoding/Utf8.h" -#include "base/NativeApp.h" - -#include "gfx_es2/gpu_features.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" #include "Common/FileUtil.h" #include "Common/Log.h" #include "Common/LogManager.h" diff --git a/Windows/RawInput.cpp b/Windows/RawInput.cpp index 6f8071058f..c23efbcf88 100644 --- a/Windows/RawInput.cpp +++ b/Windows/RawInput.cpp @@ -19,7 +19,7 @@ #include #include -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" #include "Common/System/Display.h" #include "Common/Input/InputState.h" #include "Common/Log.h" diff --git a/Windows/TouchInputHandler.cpp b/Windows/TouchInputHandler.cpp index 1066e04c85..f216e8ac80 100644 --- a/Windows/TouchInputHandler.cpp +++ b/Windows/TouchInputHandler.cpp @@ -5,7 +5,7 @@ #include #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" #include "Common/CommonWindows.h" #include "Common/CommonFuncs.h" diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 02d28ff3d6..d337085dbd 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -33,7 +33,7 @@ // native stuff #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" #include "file/file_util.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 3151a61935..4d12aa827c 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -3,7 +3,7 @@ #include #include -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" #include "Core/Config.h" #include "Common/CommonWindows.h" #include "Common/Log.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index c05d717714..6043e099ca 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -32,7 +32,8 @@ #include #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" #include "Common/Data/Text/I18n.h" diff --git a/android/ab.cmd b/android/ab.cmd index e6f3b7771d..33347178f4 100644 --- a/android/ab.cmd +++ b/android/ab.cmd @@ -5,7 +5,7 @@ copy ..\assets\langregion.ini assets\langregion.ini copy ..\assets\compat.ini assets\compat.ini copy ..\assets\Roboto-Condensed.ttf assets\Roboto-Condensed.ttf copy ..\assets\*.png assets\ -REM SET NDK=C:\Android\sdk\ndk\21.3.6528147 -SET NDK=C:\Android\ndk +SET NDK=C:\Android\sdk\ndk\21.3.6528147 +REM SET NDK=C:\Android\ndk SET NDK_MODULE_PATH=..\ext;..\ext\native\ext %NDK%/ndk-build -j32 %* diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index c84a79db01..c29ef49ba4 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -1,8 +1,8 @@ -#include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "thin3d/thin3d_create.h" #include "Common/Log.h" +#include "Common/System/System.h" #include "AndroidEGLContext.h" #include "GL/GLInterface/EGLAndroid.h" #include "Core/ConfigValues.h" diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index d11feaf5a9..c797bd046d 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -1,6 +1,5 @@ #include "AndroidJavaGLContext.h" #include "Common/System/Display.h" -#include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" #include "Common/Log.h" #include "Core/ConfigValues.h" diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 6de6dc5cf7..8ddff75115 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -1,6 +1,7 @@ #include "AndroidVulkanContext.h" -#include "base/NativeApp.h" #include "Common/System/Display.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/Log.h" #include "Common/Vulkan/VulkanContext.h" #include "Common/Vulkan/VulkanDebug.h" diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index e60f6bc01c..e81381aa6a 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -49,8 +49,14 @@ struct JNIEnv {}; #define JNI_VERSION_1_6 16 #endif +#include "net/resolve.h" +#include "android/jni/AndroidAudio.h" +#include "gfx/gl_common.h" +#include "gfx_es2/gpu_features.h" + #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/Thread/ThreadUtil.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" @@ -58,11 +64,7 @@ struct JNIEnv {}; #include "Common/Input/KeyCodes.h" #include "Common/Profiler/Profiler.h" #include "Common/Math/math_util.h" -#include "net/resolve.h" #include "Common/Data/Text/Parsers.h" -#include "android/jni/AndroidAudio.h" -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" #include "Common/Log.h" #include "Common/GraphicsContext.h" diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index 7e8a930e49..f708266706 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -364,7 +364,6 @@ - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 76060179e4..b670b9fdb1 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -31,9 +31,6 @@ file - - base - ui @@ -296,9 +293,6 @@ {49afd06e-eb44-41ac-b038-e109e444a834} - - {95e41110-57a2-497f-a938-b4c8e9dd6a27} - {d738c2d1-749d-4b60-b98f-f3da0bbbf40c} diff --git a/ext/native/ui/ui_context.cpp b/ext/native/ui/ui_context.cpp index 052332f0bd..68feedb298 100644 --- a/ext/native/ui/ui_context.cpp +++ b/ext/native/ui/ui_context.cpp @@ -3,7 +3,7 @@ #include #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" #include "ui/ui.h" #include "ui/view.h" #include "ui/ui_context.h" diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 1f807d6b53..d0182622ca 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -12,8 +12,7 @@ #include "ui/ui_tween.h" #include "ui/root.h" #include "thin3d/thin3d.h" -#include "base/NativeApp.h" - +#include "Common/System/System.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 5d88aede92..bd6735e4fe 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -9,8 +9,9 @@ #include #endif -#include "base/NativeApp.h" #include "Common/Profiler/Profiler.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index baf2da955d..f3652e03af 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -23,11 +23,11 @@ #include "headless/SDLHeadlessHost.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" -#include "Common/File/VFS/VFS.h" -#include "file/zip_read.h" #include "thin3d/thin3d_create.h" #include "thin3d/GLRenderManager.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" #include "Common/Log.h" #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" diff --git a/ios/AppDelegate.mm b/ios/AppDelegate.mm index ab79d0be07..ba8d4ff6d9 100644 --- a/ios/AppDelegate.mm +++ b/ios/AppDelegate.mm @@ -1,6 +1,7 @@ #import "AppDelegate.h" #import "ViewController.h" -#import "base/NativeApp.h" +#import "Common/System/System.h" +#import "Common/System/NativeApp.h" #import "Core/System.h" #import "Core/Config.h" #import "Common/Log.h" diff --git a/ios/DisplayManager.mm b/ios/DisplayManager.mm index e3ae0a7b66..19f828d380 100644 --- a/ios/DisplayManager.mm +++ b/ios/DisplayManager.mm @@ -9,7 +9,8 @@ #import "ViewController.h" #import "AppDelegate.h" #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" #include "Core/System.h" #import diff --git a/ios/PPSSPPUIApplication.mm b/ios/PPSSPPUIApplication.mm index 4beb622c44..cc8d21c7af 100644 --- a/ios/PPSSPPUIApplication.mm +++ b/ios/PPSSPPUIApplication.mm @@ -13,9 +13,11 @@ #import #include "Common/System/Display.h" -#include "base/NativeApp.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" #include "Common/TimeUtil.h" -#include "file/zip_read.h" +#include "Common/VFS/VFS.h" +#include "Common/VFS/AssetReader.h" #include "Common/Input/InputState.h" #include "net/resolve.h" #include "ui/screen.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 6e702ba12c..1b7837c65b 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -12,9 +12,6 @@ #import #include -#include "Common/System/Display.h" -#include "base/NativeApp.h" -#include "file/zip_read.h" #include "net/resolve.h" #include "ui/screen.h" #include "thin3d/thin3d.h" @@ -22,11 +19,16 @@ #include "thin3d/GLRenderManager.h" #include "gfx_es2/gpu_features.h" +#include "Common/System/Display.h" +#include "Common/System/System.h" +#include "Common/System/NativeApp.h" +#include "Common/VFS/VFS.h" #include "Common/Log.h" #include "Common/TimeUtil.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "Common/GraphicsContext.h" + #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" diff --git a/ios/main.mm b/ios/main.mm index 762d4e8ade..5daecb3e79 100644 --- a/ios/main.mm +++ b/ios/main.mm @@ -14,7 +14,8 @@ #import "PPSSPPUIApplication.h" #import "ViewController.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/Profiler/Profiler.h" #define CS_OPS_STATUS 0 /* return status */ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 219432057e..8b0cefa854 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -5,11 +5,11 @@ #include #include -#include "base/NativeApp.h" - #include "Common/Log.h" #include "Common/LogManager.h" #include "Common/System/Display.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/TimeUtil.h" #include "Common/FileUtil.h" #include "Common/Serialize/Serializer.h" diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index 31899887c7..7ff7f589ad 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -18,7 +18,9 @@ #include #include "ppsspp_config.h" -#include "base/NativeApp.h" + +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/TimeUtil.h" #include "Core/ConfigValues.h" #include "Core/MIPS/JitCommon/JitCommon.h" diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 43e947fe95..edb5939cba 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -34,10 +34,11 @@ #endif #include "ppsspp_config.h" -#include "base/NativeApp.h" +#include "Common/System/NativeApp.h" +#include "Common/System/System.h" #include "Common/Input/InputState.h" #include "ext/disarm.h" -#include "math/math_util.h" +#include "Common/Math/math_util.h" #include "Common/Data/Text/Parsers.h" #include "Common/ArmEmitter.h" From 7ba8f684a0a9f318c9c2b6ce6eaaeff3aefd56bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 12:37:19 +0200 Subject: [PATCH 826/848] Mac/ios buildfix --- Common/MemArenaDarwin.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Common/MemArenaDarwin.cpp b/Common/MemArenaDarwin.cpp index 593bb1495e..4d197c1f85 100644 --- a/Common/MemArenaDarwin.cpp +++ b/Common/MemArenaDarwin.cpp @@ -20,11 +20,12 @@ #if defined(__APPLE__) #include -#include +#include -#include "FileUtil.h" -#include "MemoryUtil.h" -#include "MemArena.h" +#include "Common/Log.h" +#include "Common/FileUtil.h" +#include "Common/MemoryUtil.h" +#include "Common/MemArena.h" #include #include From 6ea8af293944c9afca8f880c0d86f02cbc8d531d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 13:24:12 +0200 Subject: [PATCH 827/848] iOS buildfix --- ios/PPSSPPUIApplication.mm | 4 ++-- ios/ViewController.mm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/PPSSPPUIApplication.mm b/ios/PPSSPPUIApplication.mm index cc8d21c7af..eb66aa202b 100644 --- a/ios/PPSSPPUIApplication.mm +++ b/ios/PPSSPPUIApplication.mm @@ -16,8 +16,8 @@ #include "Common/System/System.h" #include "Common/System/NativeApp.h" #include "Common/TimeUtil.h" -#include "Common/VFS/VFS.h" -#include "Common/VFS/AssetReader.h" +#include "Common/File/VFS/VFS.h" +#include "Common/File/VFS/AssetReader.h" #include "Common/Input/InputState.h" #include "net/resolve.h" #include "ui/screen.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 1b7837c65b..a6be65bedd 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -22,7 +22,7 @@ #include "Common/System/Display.h" #include "Common/System/System.h" #include "Common/System/NativeApp.h" -#include "Common/VFS/VFS.h" +#include "Common/File/VFS/VFS.h" #include "Common/Log.h" #include "Common/TimeUtil.h" #include "Common/Input/InputState.h" From 81ad9a930a43f99bbab2b8d004bcb63fe2ef93d4 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Mon, 5 Oct 2020 00:00:28 +0800 Subject: [PATCH 828/848] SaveData:Displays all saves like a PSP for LISTALLDELETE mode. --- Core/Dialog/PSPSaveDialog.cpp | 5 ++-- Core/Dialog/SavedataParam.cpp | 50 ++++++++++++++++++++++++++++++----- Core/Dialog/SavedataParam.h | 10 ++++--- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index a5159e1c0c..72cf8768b0 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -180,7 +180,6 @@ int PSPSaveDialog::Init(int paramAddr) display = DS_SAVE_LIST_CHOICE; break; case SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE: - // TODO:Should displays all saves like a PSP? DEBUG_LOG(SCEUTILITY, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if(param.GetFilenameCount() == 0) display = DS_DELETE_NODATA; @@ -969,6 +968,8 @@ int PSPSaveDialog::Update(int animSpeed) if (param.GetFilenameCount() == 0) display = DS_DELETE_NODATA; else if (param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE || param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE) { + if (currentSelectedSave > param.GetFilenameCount() - 1) + currentSelectedSave = param.GetFilenameCount() - 1; display = DS_DELETE_LIST_CHOICE; } else { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS; @@ -1039,7 +1040,7 @@ void PSPSaveDialog::ExecuteIOAction() { } break; case DS_DELETE_DELETING: - if (param.Delete(param.GetPspParam(),currentSelectedSave)) { + if (param.Delete(param.GetPspParam(), currentSelectedSave)) { result = 0; display = DS_DELETE_DONE; } else { diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 783b4770a0..bc888e4e4a 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -322,12 +322,12 @@ bool SavedataParam::Delete(SceUtilitySavedataParam* param, int saveId) { } // Sanity check, preventing full delete of savedata/ in MGS PW demo (!) - if (!strlen(param->gameName)) { + if (!strlen(param->gameName) && param->mode != SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE) { ERROR_LOG(SCEUTILITY, "Bad param with gameName empty - cannot delete save directory"); return false; } - std::string dirPath = GetSaveFilePath(param,saveId); + std::string dirPath = GetSaveFilePath(param, GetSaveDir(saveId)); if (dirPath.size() == 0) { ERROR_LOG(SCEUTILITY, "GetSaveFilePath returned empty - cannot delete save directory"); return false; @@ -1411,6 +1411,34 @@ int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) return 0; } + if (param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTALLDELETE) { + Clear(); + int realCount = 0; + auto allSaves = pspFileSystem.GetDirListing(savePath); + saveDataListCount = (int)allSaves.size(); + saveDataList = new SaveFileInfo[saveDataListCount]; + for (auto save : allSaves) { + if (save.name == "." || save.name == "..") + continue; + std::string fileDataDir = savePath + save.name; + PSPFileInfo info = pspFileSystem.GetFileInfo(fileDataDir); + auto allFiles = pspFileSystem.GetDirListing(fileDataDir); + bool firstFile = true; + for (auto file : allFiles) { + if (firstFile) { + // Use a file in save directory to determine the directory info. + info = file; + firstFile = false; + } else + info.size += file.size; + } + SetFileInfo(realCount, info, "", save.name); + realCount++; + } + saveNameListDataCount = realCount; + return 0; + } + bool listEmptyFile = true; if (param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD || param->mode == SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE) @@ -1548,13 +1576,16 @@ int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) return 0; } -void SavedataParam::SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, std::string saveName) +void SavedataParam::SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, std::string saveName, std::string savrDir) { saveInfo.size = info.size; saveInfo.saveName = saveName; saveInfo.idx = 0; saveInfo.modif_time = info.mtime; + std::string saveDir = savrDir == "" ? GetGameName(pspParam) + saveName : savrDir; + saveInfo.saveDir = saveDir; + // Start with a blank slate. if (saveInfo.texture != NULL) { if (!noSaveIcon || saveInfo.texture != noSaveIcon->texture) { @@ -1568,13 +1599,13 @@ void SavedataParam::SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, std:: // Search save image icon0 // TODO : If icon0 don't exist, need to use icon1 which is a moving icon. Also play sound - std::string fileDataPath2 = savePath + GetGameName(pspParam) + saveName + "/" + ICON0_FILENAME; + std::string fileDataPath2 = savePath + saveDir + "/" + ICON0_FILENAME; PSPFileInfo info2 = pspFileSystem.GetFileInfo(fileDataPath2); if (info2.exists) saveInfo.texture = new PPGeImage(fileDataPath2); // Load info in PARAM.SFO - fileDataPath2 = savePath + GetGameName(pspParam) + saveName + "/" + SFO_FILENAME; + fileDataPath2 = savePath + saveDir + "/" + SFO_FILENAME; info2 = pspFileSystem.GetFileInfo(fileDataPath2); if (info2.exists) { std::vector sfoData; @@ -1590,9 +1621,9 @@ void SavedataParam::SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, std:: } } -void SavedataParam::SetFileInfo(int idx, PSPFileInfo &info, std::string saveName) +void SavedataParam::SetFileInfo(int idx, PSPFileInfo &info, std::string saveName, std::string saveDir) { - SetFileInfo(saveDataList[idx], info, saveName); + SetFileInfo(saveDataList[idx], info, saveName, saveDir); saveDataList[idx].idx = idx; } @@ -1641,11 +1672,16 @@ const SaveFileInfo& SavedataParam::GetFileInfo(int idx) { return saveDataList[idx]; } + std::string SavedataParam::GetFilename(int idx) const { return saveDataList[idx].saveName; } +std::string SavedataParam::GetSaveDir(int idx) const { + return saveDataList[idx].saveDir; +} + int SavedataParam::GetSelectedSave() { // The slot # of the same save on LOAD/SAVE lists can dismatch so this isn't right anyhow diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h index af00261a40..6e39fd30e1 100644 --- a/Core/Dialog/SavedataParam.h +++ b/Core/Dialog/SavedataParam.h @@ -65,11 +65,11 @@ static const char *const utilitySavedataTypeNames[] = { "SAVE", "LISTLOAD", "LISTSAVE", - "DELETE", "LISTDELETE", + "LISTALLDELETE", "SIZES", "AUTODELETE", - "SINGLEDELETE", + "DELETE", "LIST", "FILES", "MAKEDATASECURE", @@ -273,6 +273,7 @@ struct SaveFileInfo { s64 size; std::string saveName; + std::string saveDir; int idx; char title[128]; @@ -341,6 +342,7 @@ public: int GetFilenameCount(); const SaveFileInfo& GetFileInfo(int idx); std::string GetFilename(int idx) const; + std::string GetSaveDir(int idx) const; int GetSelectedSave(); void SetSelectedSave(int idx); @@ -361,8 +363,8 @@ public: private: void Clear(); - void SetFileInfo(int idx, PSPFileInfo &info, std::string saveName); - void SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, std::string saveName); + void SetFileInfo(int idx, PSPFileInfo &info, std::string saveName, std::string saveDir = ""); + void SetFileInfo(SaveFileInfo &saveInfo, PSPFileInfo &info, std::string saveName, std::string saveDir = ""); void ClearFileInfo(SaveFileInfo &saveInfo, const std::string &saveName); int LoadSaveData(SceUtilitySavedataParam *param, const std::string &saveDirName, const std::string& dirPath, bool secureMode); From 4f43cff5ca3e15852ed2843557b0aedd730d117b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 20:48:47 +0200 Subject: [PATCH 829/848] Move fileutil, net, image loaders, ui to Common. (#13506) * Move and rename file_util/fd_util to Common/File/FileUtil and DirListing Let's also move net while we're at it. Move the ZIM/PNG loaders over to Common. Move the UI framework into Common iOS buildfix * Buildfix * Buildfixes * Apple buildfix * This typo again.. * UWP buildfix * Fix build of PPSSPPQt, such as it is (it's not in good condition...) * Guess what? Another buildfix. --- CMakeLists.txt | 84 +++++------ Common/ArmCPUDetect.cpp | 9 +- Common/Buffer.cpp | 3 +- Common/CPUDetect.cpp | 4 +- Common/Common.vcxproj | 60 ++++++-- Common/Common.vcxproj.filters | 134 ++++++++++++++++- Common/Data/Format/JSONReader.cpp | 1 + Common/Data/Format/PNGLoad.cpp | 58 ++++++++ .../Data/Format/PNGLoad.h | 4 +- .../Data/Format/ZIMLoad.cpp | 12 +- .../Data/Format/ZIMLoad.h | 0 .../Data/Format/ZIMSave.cpp | 4 +- .../Data/Format/ZIMSave.h | 2 +- .../File/DirListing.cpp | 139 ++---------------- .../file_util.h => Common/File/DirListing.h | 8 - .../File/FileDescriptor.cpp | 2 +- .../fd_util.h => Common/File/FileDescriptor.h | 0 Common/{ => File}/FileUtil.cpp | 120 +++++++++++++-- Common/{ => File}/FileUtil.h | 12 +- Common/File/PathBrowser.cpp | 4 +- Common/File/PathBrowser.h | 4 +- Common/File/VFS/AssetReader.h | 1 - Common/File/VFS/VFS.h | 3 +- Common/LogManager.cpp | 2 +- Common/MemArenaDarwin.cpp | 11 +- Common/MemArenaPosix.cpp | 13 +- .../Net/HTTPClient.cpp | 8 +- .../http_client.h => Common/Net/HTTPClient.h | 2 +- .../Net/HTTPHeaders.cpp | 6 +- .../Net/HTTPHeaders.h | 0 .../Net/HTTPServer.cpp | 6 +- .../http_server.h => Common/Net/HTTPServer.h | 4 +- .../net/resolve.cpp => Common/Net/Resolve.cpp | 2 +- .../net/resolve.h => Common/Net/Resolve.h | 0 .../net/sinks.cpp => Common/Net/Sinks.cpp | 4 +- ext/native/net/sinks.h => Common/Net/Sinks.h | 0 ext/native/net/url.cpp => Common/Net/URL.cpp | 3 +- ext/native/net/url.h => Common/Net/URL.h | 0 .../Net/WebsocketServer.cpp | 6 +- .../Net/WebsocketServer.h | 5 +- Common/Serialize/Serializer.cpp | 2 +- .../ui_context.cpp => Common/UI/Context.cpp | 6 +- .../ui/ui_context.h => Common/UI/Context.h | 0 ext/native/ui/root.cpp => Common/UI/Root.cpp | 4 +- ext/native/ui/root.h => Common/UI/Root.h | 2 +- .../ui/screen.cpp => Common/UI/Screen.cpp | 8 +- ext/native/ui/screen.h => Common/UI/Screen.h | 0 .../ui/ui_tween.cpp => Common/UI/Tween.cpp | 6 +- ext/native/ui/ui_tween.h => Common/UI/Tween.h | 2 +- ext/native/ui/ui.cpp => Common/UI/UI.cpp | 4 +- ext/native/ui/ui.h => Common/UI/UI.h | 0 .../ui_screen.cpp => Common/UI/UIScreen.cpp | 8 +- .../ui/ui_screen.h => Common/UI/UIScreen.h | 4 +- ext/native/ui/view.cpp => Common/UI/View.cpp | 10 +- ext/native/ui/view.h => Common/UI/View.h | 0 .../viewgroup.cpp => Common/UI/ViewGroup.cpp | 10 +- .../ui/viewgroup.h => Common/UI/ViewGroup.h | 2 +- Core/AVIDump.cpp | 2 +- Core/Config.cpp | 6 +- Core/CwCheat.cpp | 2 +- Core/Debugger/SymbolMap.cpp | 2 +- .../WebSocket/GPURecordSubscriber.cpp | 2 +- Core/Debugger/WebSocket/WebSocketUtils.h | 3 +- Core/Dialog/PSPSaveDialog.cpp | 2 +- Core/Dialog/SavedataParam.cpp | 5 +- Core/ELF/PBPReader.cpp | 2 +- Core/FileLoaders/DiskCachingFileLoader.cpp | 7 +- Core/FileLoaders/HTTPFileLoader.h | 6 +- Core/FileLoaders/LocalFileLoader.cpp | 4 +- Core/FileSystems/BlockDevices.cpp | 2 +- Core/FileSystems/DirectoryFileSystem.cpp | 2 +- Core/FileSystems/VirtualDiscFileSystem.cpp | 2 +- Core/HLE/Plugins.cpp | 5 +- Core/HLE/proAdhoc.h | 2 +- Core/HLE/proAdhocServer.cpp | 2 +- Core/HLE/sceHttp.cpp | 2 +- Core/HLE/sceIo.cpp | 2 +- Core/HLE/sceKernelModule.cpp | 2 +- Core/HLE/sceNet.cpp | 2 +- Core/HLE/scePauth.cpp | 2 +- Core/HLE/sceUmd.cpp | 2 - Core/Loaders.cpp | 4 +- Core/MIPS/MIPSAnalyst.cpp | 2 +- Core/PSPLoaders.cpp | 3 +- Core/Replay.cpp | 2 +- Core/Reporting.cpp | 9 +- Core/SaveState.cpp | 2 +- Core/Screenshot.cpp | 2 +- Core/System.cpp | 2 +- Core/TextureReplacer.cpp | 2 +- Core/Util/GameManager.cpp | 4 +- Core/Util/GameManager.h | 2 +- Core/Util/PPGeDraw.cpp | 14 +- Core/Util/PortManager.cpp | 2 +- Core/WaveFile.h | 2 +- Core/WebServer.cpp | 10 +- GPU/Common/PostShader.cpp | 3 +- GPU/Debugger/Record.cpp | 2 +- GPU/GLES/GPU_GLES.cpp | 2 +- GPU/GLES/ShaderManagerGLES.cpp | 2 +- GPU/Vulkan/DebugVisVulkan.cpp | 4 +- GPU/Vulkan/GPU_Vulkan.cpp | 2 +- Qt/QtMain.h | 2 +- SDL/SDLJoystick.cpp | 2 +- SDL/SDLJoystick.h | 2 +- SDL/SDLMain.cpp | 6 +- UI/BackgroundAudio.cpp | 2 +- UI/BackgroundAudio.h | 2 +- UI/ChatScreen.cpp | 10 +- UI/ChatScreen.h | 3 +- UI/ComboKeyMappingScreen.cpp | 6 +- UI/ControlMappingScreen.cpp | 10 +- UI/ControlMappingScreen.h | 4 +- UI/CwCheatScreen.cpp | 4 +- UI/CwCheatScreen.h | 6 +- UI/DevScreens.cpp | 8 +- UI/DevScreens.h | 3 +- UI/DisplayLayoutEditor.cpp | 2 +- UI/DisplayLayoutEditor.h | 4 +- UI/DisplayLayoutScreen.cpp | 4 +- UI/DisplayLayoutScreen.h | 4 +- UI/EmuScreen.cpp | 10 +- UI/EmuScreen.h | 6 +- UI/GPUDriverTestScreen.cpp | 2 +- UI/GPUDriverTestScreen.h | 8 +- UI/GameInfoCache.cpp | 3 +- UI/GameInfoCache.h | 1 - UI/GameScreen.cpp | 8 +- UI/GameScreen.h | 2 +- UI/GameSettingsScreen.cpp | 12 +- UI/GameSettingsScreen.h | 2 +- UI/GamepadEmu.cpp | 2 +- UI/GamepadEmu.h | 4 +- UI/InstallZipScreen.cpp | 9 +- UI/InstallZipScreen.h | 4 +- UI/MainScreen.cpp | 10 +- UI/MainScreen.h | 4 +- UI/MiscScreens.cpp | 10 +- UI/MiscScreens.h | 4 +- UI/NativeApp.cpp | 14 +- UI/OnScreenDisplay.cpp | 2 +- UI/OnScreenDisplay.h | 2 +- UI/PauseScreen.cpp | 8 +- UI/PauseScreen.h | 4 +- UI/ProfilerDraw.cpp | 4 +- UI/RemoteISOScreen.cpp | 6 +- UI/RemoteISOScreen.h | 4 +- UI/ReportScreen.cpp | 4 +- UI/ReportScreen.h | 4 +- UI/SavedataScreen.cpp | 8 +- UI/SavedataScreen.h | 6 +- UI/Store.cpp | 6 +- UI/Store.h | 6 +- UI/TextureUtil.cpp | 18 +-- UI/TextureUtil.h | 2 +- UI/TiltAnalogSettingsScreen.h | 2 +- UI/TouchControlLayoutScreen.cpp | 2 +- UI/TouchControlLayoutScreen.h | 4 +- UWP/CommonUWP/CommonUWP.vcxproj | 68 +++++++-- UWP/CommonUWP/CommonUWP.vcxproj.filters | 134 ++++++++++++++++- UWP/NativeUWP/NativeUWP.vcxproj | 62 ++------ UWP/NativeUWP/NativeUWP.vcxproj.filters | 126 ---------------- UWP/PPSSPP_UWPMain.cpp | 8 +- UWP/StorageFileLoader.cpp | 3 +- UWP/UWPHost.cpp | 2 +- Windows/MainWindowMenu.cpp | 2 +- Windows/WindowsHost.cpp | 4 +- Windows/main.cpp | 4 +- android/jni/Android.mk | 51 ++++--- android/jni/TestRunner.cpp | 2 +- android/jni/app-android.cpp | 2 +- ext/native/gfx_es2/draw_text.h | 4 - ext/native/gfx_es2/draw_text_qt.h | 2 + ext/native/gfx_es2/glsl_program.cpp | 6 +- ext/native/image/png_load.cpp | 114 -------------- ext/native/native.vcxproj | 57 +------ ext/native/native.vcxproj.filters | 133 ----------------- ext/native/thin3d/thin3d_vulkan.cpp | 1 - ext/native/tools/atlastool.cpp | 6 +- ext/native/tools/zimtool.cpp | 10 +- headless/Compare.cpp | 3 +- headless/Headless.cpp | 2 +- headless/SDLHeadlessHost.cpp | 2 +- headless/StubHost.cpp | 2 +- headless/WindowsHeadlessHost.cpp | 2 +- ios/PPSSPPUIApplication.mm | 4 +- ios/ViewController.mm | 4 +- libretro/Makefile.common | 43 ++++-- libretro/libretro.cpp | 2 +- 189 files changed, 1013 insertions(+), 1098 deletions(-) create mode 100644 Common/Data/Format/PNGLoad.cpp rename ext/native/image/png_load.h => Common/Data/Format/PNGLoad.h (65%) rename ext/native/image/zim_load.cpp => Common/Data/Format/ZIMLoad.cpp (97%) rename ext/native/image/zim_load.h => Common/Data/Format/ZIMLoad.h (100%) rename ext/native/image/zim_save.cpp => Common/Data/Format/ZIMSave.cpp (98%) rename ext/native/image/zim_save.h => Common/Data/Format/ZIMSave.h (90%) rename ext/native/file/file_util.cpp => Common/File/DirListing.cpp (64%) rename ext/native/file/file_util.h => Common/File/DirListing.h (67%) rename ext/native/file/fd_util.cpp => Common/File/FileDescriptor.cpp (99%) rename ext/native/file/fd_util.h => Common/File/FileDescriptor.h (100%) rename Common/{ => File}/FileUtil.cpp (90%) rename Common/{ => File}/FileUtil.h (91%) rename ext/native/net/http_client.cpp => Common/Net/HTTPClient.cpp (99%) rename ext/native/net/http_client.h => Common/Net/HTTPClient.h (99%) rename ext/native/net/http_headers.cpp => Common/Net/HTTPHeaders.cpp (97%) rename ext/native/net/http_headers.h => Common/Net/HTTPHeaders.h (100%) rename ext/native/net/http_server.cpp => Common/Net/HTTPServer.cpp (98%) rename ext/native/net/http_server.h => Common/Net/HTTPServer.h (97%) rename ext/native/net/resolve.cpp => Common/Net/Resolve.cpp (99%) rename ext/native/net/resolve.h => Common/Net/Resolve.h (100%) rename ext/native/net/sinks.cpp => Common/Net/Sinks.cpp (99%) rename ext/native/net/sinks.h => Common/Net/Sinks.h (100%) rename ext/native/net/url.cpp => Common/Net/URL.cpp (99%) rename ext/native/net/url.h => Common/Net/URL.h (100%) rename ext/native/net/websocket_server.cpp => Common/Net/WebsocketServer.cpp (99%) rename ext/native/net/websocket_server.h => Common/Net/WebsocketServer.h (97%) rename ext/native/ui/ui_context.cpp => Common/UI/Context.cpp (99%) rename ext/native/ui/ui_context.h => Common/UI/Context.h (100%) rename ext/native/ui/root.cpp => Common/UI/Root.cpp (99%) rename ext/native/ui/root.h => Common/UI/Root.h (97%) rename ext/native/ui/screen.cpp => Common/UI/Screen.cpp (98%) rename ext/native/ui/screen.h => Common/UI/Screen.h (100%) rename ext/native/ui/ui_tween.cpp => Common/UI/Tween.cpp (96%) rename ext/native/ui/ui_tween.h => Common/UI/Tween.h (99%) rename ext/native/ui/ui.cpp => Common/UI/UI.cpp (89%) rename ext/native/ui/ui.h => Common/UI/UI.h (100%) rename ext/native/ui/ui_screen.cpp => Common/UI/UIScreen.cpp (99%) rename ext/native/ui/ui_screen.h => Common/UI/UIScreen.h (99%) rename ext/native/ui/view.cpp => Common/UI/View.cpp (99%) rename ext/native/ui/view.h => Common/UI/View.h (100%) rename ext/native/ui/viewgroup.cpp => Common/UI/ViewGroup.cpp (99%) rename ext/native/ui/viewgroup.h => Common/UI/ViewGroup.h (99%) delete mode 100644 ext/native/image/png_load.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2daab5c16f..0a7699f8c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,6 +455,12 @@ add_library(Common STATIC Common/Data/Format/JSONReader.cpp Common/Data/Format/JSONWriter.h Common/Data/Format/JSONWriter.cpp + Common/Data/Format/PNGLoad.cpp + Common/Data/Format/PNGLoad.h + Common/Data/Format/ZIMLoad.cpp + Common/Data/Format/ZIMLoad.h + Common/Data/Format/ZIMSave.cpp + Common/Data/Format/ZIMSave.h Common/Data/Hash/Hash.cpp Common/Data/Hash/Hash.h Common/Data/Text/I18n.cpp @@ -472,6 +478,12 @@ add_library(Common STATIC Common/File/DiskFree.cpp Common/File/PathBrowser.h Common/File/PathBrowser.cpp + Common/File/FileUtil.cpp + Common/File/FileUtil.h + Common/File/DirListing.cpp + Common/File/DirListing.h + Common/File/FileDescriptor.cpp + Common/File/FileDescriptor.h Common/Input/GestureDetector.cpp Common/Input/GestureDetector.h Common/Input/KeyCodes.h @@ -491,6 +503,20 @@ add_library(Common STATIC Common/Math/lin/vec3.h Common/Math/math_util.cpp Common/Math/math_util.h + Common/Net/HTTPClient.cpp + Common/Net/HTTPClient.h + Common/Net/HTTPHeaders.cpp + Common/Net/HTTPHeaders.h + Common/Net/HTTPServer.cpp + Common/Net/HTTPServer.h + Common/Net/Resolve.cpp + Common/Net/Resolve.h + Common/Net/Sinks.cpp + Common/Net/Sinks.h + Common/Net/URL.cpp + Common/Net/URL.h + Common/Net/WebsocketServer.cpp + Common/Net/WebsocketServer.h Common/Profiler/Profiler.cpp Common/Profiler/Profiler.h Common/System/Display.cpp @@ -503,6 +529,22 @@ add_library(Common STATIC Common/Thread/ThreadUtil.h Common/Thread/ThreadPool.cpp Common/Thread/ThreadPool.h + Common/UI/Root.cpp + Common/UI/Root.h + Common/UI/Screen.cpp + Common/UI/Screen.h + Common/UI/UI.cpp + Common/UI/UI.h + Common/UI/Context.cpp + Common/UI/Context.h + Common/UI/UIScreen.cpp + Common/UI/UIScreen.h + Common/UI/Tween.cpp + Common/UI/Tween.h + Common/UI/View.cpp + Common/UI/View.h + Common/UI/ViewGroup.cpp + Common/UI/ViewGroup.h Common/BitScan.h Common/BitSet.h Common/Buffer.h @@ -520,8 +562,6 @@ add_library(Common STATIC Common/FixedSizeQueue.h Common/ExceptionHandlerSetup.cpp Common/ExceptionHandlerSetup.h - Common/FileUtil.cpp - Common/FileUtil.h Common/Hashmaps.h Common/Log.h Common/Log.cpp @@ -1011,10 +1051,6 @@ endif() add_library(native STATIC ${nativeExtra} - ext/native/file/fd_util.cpp - ext/native/file/fd_util.h - ext/native/file/file_util.cpp - ext/native/file/file_util.h ext/native/gfx/gl_common.h ext/native/gfx/gl_debug_log.cpp ext/native/gfx/gl_debug_log.h @@ -1040,46 +1076,10 @@ add_library(native STATIC ext/native/gfx_es2/glsl_program.h ext/native/gfx_es2/gl3stub.c ext/native/gfx_es2/gl3stub.h - ext/native/image/png_load.cpp - ext/native/image/png_load.h - ext/native/image/zim_load.cpp - ext/native/image/zim_load.h - ext/native/image/zim_save.cpp - ext/native/image/zim_save.h - ext/native/net/http_client.cpp - ext/native/net/http_client.h - ext/native/net/http_headers.cpp - ext/native/net/http_headers.h - ext/native/net/http_server.cpp - ext/native/net/http_server.h - ext/native/net/resolve.cpp - ext/native/net/resolve.h - ext/native/net/sinks.cpp - ext/native/net/sinks.h - ext/native/net/url.cpp - ext/native/net/url.h - ext/native/net/websocket_server.cpp - ext/native/net/websocket_server.h ext/native/thin3d/thin3d.cpp ext/native/thin3d/thin3d.h ext/native/thin3d/thin3d_create.h ${THIN3D_PLATFORMS} - ext/native/ui/root.cpp - ext/native/ui/root.h - ext/native/ui/screen.cpp - ext/native/ui/screen.h - ext/native/ui/ui.cpp - ext/native/ui/ui.h - ext/native/ui/ui_context.cpp - ext/native/ui/ui_context.h - ext/native/ui/ui_screen.cpp - ext/native/ui/ui_screen.h - ext/native/ui/ui_tween.cpp - ext/native/ui/ui_tween.h - ext/native/ui/view.cpp - ext/native/ui/view.h - ext/native/ui/viewgroup.cpp - ext/native/ui/viewgroup.h ext/jpge/jpgd.cpp ext/jpge/jpgd.h ext/jpge/jpge.cpp diff --git a/Common/ArmCPUDetect.cpp b/Common/ArmCPUDetect.cpp index 5a1d53fc4a..540f7d7b0c 100644 --- a/Common/ArmCPUDetect.cpp +++ b/Common/ArmCPUDetect.cpp @@ -22,10 +22,11 @@ #if PPSSPP_ARCH(ARM) || PPSSPP_ARCH(ARM64) #include -#include "Common.h" -#include "CPUDetect.h" -#include "StringUtils.h" -#include "FileUtil.h" + +#include "Common/Common.h" +#include "Common/CPUDetect.h" +#include "Common/StringUtils.h" +#include "Common/File/FileUtil.h" #include "Common/Data/Encoding/Utf8.h" #if PPSSPP_PLATFORM(WINDOWS) diff --git a/Common/Buffer.cpp b/Common/Buffer.cpp index 78302f60fe..423c2cfb3c 100644 --- a/Common/Buffer.cpp +++ b/Common/Buffer.cpp @@ -17,8 +17,7 @@ #define MSG_NOSIGNAL 0x00 #endif -#include "file/fd_util.h" - +#include "Common/File/FileDescriptor.h" #include "Common/TimeUtil.h" #include "Common/Buffer.h" #include "Common/Log.h" diff --git a/Common/CPUDetect.cpp b/Common/CPUDetect.cpp index 1acbb1c680..9910f651cc 100644 --- a/Common/CPUDetect.cpp +++ b/Common/CPUDetect.cpp @@ -29,11 +29,9 @@ #include #include -#include "file/file_util.h" - #include "Common/Common.h" #include "Common/CPUDetect.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #if defined(_WIN32) && !defined(__MINGW32__) diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index e319b38ae2..385b483e56 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -136,7 +136,7 @@ _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) Common/DbgNew.h MultiThreadedDebug - ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. StreamingSIMDExtensions2 Precise true @@ -158,7 +158,7 @@ Common/DbgNew.h MultiThreadedDebug _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;../ext/glslang;../ext;../ext/zlib;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -181,7 +181,7 @@ Common/DbgNew.h MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -205,7 +205,7 @@ MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -234,7 +234,7 @@ false StreamingSIMDExtensions2 Precise - ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. Speed true false @@ -260,7 +260,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -291,7 +291,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -322,7 +322,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext;../ext/zlib;.. + ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -371,14 +371,20 @@ + + + + + + @@ -393,6 +399,13 @@ + + + + + + + @@ -413,7 +426,6 @@ - @@ -463,6 +475,14 @@ + + + + + + + + @@ -655,12 +675,18 @@ + + + + + + @@ -675,6 +701,13 @@ + + + + + + + @@ -684,7 +717,6 @@ - true true @@ -734,6 +766,14 @@ + + + + + + + + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 397028e32a..04386e630e 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -7,7 +7,6 @@ - @@ -238,12 +237,74 @@ System + + File + + + File + + + File + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Data\Format + + + Data\Format + + + Data\Format + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + - @@ -451,6 +512,69 @@ System + + File + + + File + + + File + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Data\Format + + + Data\Format + + + Data\Format + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + @@ -528,6 +652,12 @@ {89ddf0bd-3fc4-4a69-87a7-b82cfc412e0a} + + {b338dd13-cdae-4ef4-b122-b22967ae9bcb} + + + {6a61d762-e71c-4428-8cef-c7ddda405ba5} + diff --git a/Common/Data/Format/JSONReader.cpp b/Common/Data/Format/JSONReader.cpp index 125a136258..4f299eab4a 100644 --- a/Common/Data/Format/JSONReader.cpp +++ b/Common/Data/Format/JSONReader.cpp @@ -1,4 +1,5 @@ #include "Common/File/VFS/VFS.h" +#include "Common/File/FileUtil.h" #include "Common/Data/Format/JSONReader.h" namespace json { diff --git a/Common/Data/Format/PNGLoad.cpp b/Common/Data/Format/PNGLoad.cpp new file mode 100644 index 0000000000..7c5baf0e75 --- /dev/null +++ b/Common/Data/Format/PNGLoad.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include + +#include "Common/Data/Format/PNGLoad.h" +#include "Common/Log.h" + +// *image_data_ptr should be deleted with free() +// return value of 1 == success. +int pngLoad(const char *file, int *pwidth, int *pheight, unsigned char **image_data_ptr) { + png_image png; + memset(&png, 0, sizeof(png)); + png.version = PNG_IMAGE_VERSION; + + png_image_begin_read_from_file(&png, file); + + if (PNG_IMAGE_FAILED(png)) + { + ERROR_LOG(IO, "pngLoad: %s", png.message); + return 0; + } + *pwidth = png.width; + *pheight = png.height; + png.format = PNG_FORMAT_RGBA; + + int stride = PNG_IMAGE_ROW_STRIDE(png); + *image_data_ptr = (unsigned char *)malloc(PNG_IMAGE_SIZE(png)); + png_image_finish_read(&png, NULL, *image_data_ptr, stride, NULL); + return 1; +} + +int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, int *pheight, unsigned char **image_data_ptr) { + png_image png{}; + png.version = PNG_IMAGE_VERSION; + + png_image_begin_read_from_memory(&png, input_ptr, input_len); + + if (PNG_IMAGE_FAILED(png)) { + ERROR_LOG(IO, "pngLoad: %s", png.message); + return 0; + } + *pwidth = png.width; + *pheight = png.height; + png.format = PNG_FORMAT_RGBA; + + int stride = PNG_IMAGE_ROW_STRIDE(png); + + size_t size = PNG_IMAGE_SIZE(png); + if (!size) { + ERROR_LOG(IO, "pngLoad: empty image"); + return 0; + } + + *image_data_ptr = (unsigned char *)malloc(size); + png_image_finish_read(&png, NULL, *image_data_ptr, stride, NULL); + return 1; +} diff --git a/ext/native/image/png_load.h b/Common/Data/Format/PNGLoad.h similarity index 65% rename from ext/native/image/png_load.h rename to Common/Data/Format/PNGLoad.h index bae14c210e..48eaf6a1db 100644 --- a/ext/native/image/png_load.h +++ b/Common/Data/Format/PNGLoad.h @@ -4,9 +4,9 @@ // *image_data_ptr should be deleted with free() // return value of 1 == success. int pngLoad(const char *file, int *pwidth, - int *pheight, unsigned char **image_data_ptr, bool flip); + int *pheight, unsigned char **image_data_ptr); int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, - int *pheight, unsigned char **image_data_ptr, bool flip); + int *pheight, unsigned char **image_data_ptr); #endif // _PNG_LOAD_H diff --git a/ext/native/image/zim_load.cpp b/Common/Data/Format/ZIMLoad.cpp similarity index 97% rename from ext/native/image/zim_load.cpp rename to Common/Data/Format/ZIMLoad.cpp index 80ed88d3c2..45f23e2857 100644 --- a/ext/native/image/zim_load.cpp +++ b/Common/Data/Format/ZIMLoad.cpp @@ -1,13 +1,13 @@ -#include -#include -#include +#include +#include +#include #include "zlib.h" -#include "image/zim_load.h" -#include "Common/Math/math_util.h" -#include "Common/File/VFS/VFS.h" #include "Common/Log.h" +#include "Common/Data/Format/ZIMLoad.h" +#include "Common/Math/math_util.h" +#include "Common/File/VFS/VFS.h" int ezuncompress(unsigned char* pDest, long* pnDestLen, const unsigned char* pSrc, long nSrcLen) { z_stream stream; diff --git a/ext/native/image/zim_load.h b/Common/Data/Format/ZIMLoad.h similarity index 100% rename from ext/native/image/zim_load.h rename to Common/Data/Format/ZIMLoad.h diff --git a/ext/native/image/zim_save.cpp b/Common/Data/Format/ZIMSave.cpp similarity index 98% rename from ext/native/image/zim_save.cpp rename to Common/Data/Format/ZIMSave.cpp index f46ca72ef7..4f5fb230c6 100644 --- a/ext/native/image/zim_save.cpp +++ b/Common/Data/Format/ZIMSave.cpp @@ -2,11 +2,11 @@ #include #include -#include "image/zim_load.h" -#include "image/zim_save.h" #include "zlib.h" #include "Common/Log.h" +#include "Common/Data/Format/ZIMLoad.h" +#include "Common/Data/Format/ZIMSave.h" static const char magic[5] = "ZIMG"; diff --git a/ext/native/image/zim_save.h b/Common/Data/Format/ZIMSave.h similarity index 90% rename from ext/native/image/zim_save.h rename to Common/Data/Format/ZIMSave.h index c8938a91e9..90158d3d55 100644 --- a/ext/native/image/zim_save.h +++ b/Common/Data/Format/ZIMSave.h @@ -4,7 +4,7 @@ #include // For the type enums etc. -#include "zim_load.h" +#include "Common/Data/Format/ZIMLoad.h" // SaveZIM's responsibility: // * Write the ZIM format diff --git a/ext/native/file/file_util.cpp b/Common/File/DirListing.cpp similarity index 64% rename from ext/native/file/file_util.cpp rename to Common/File/DirListing.cpp index 55c31bb677..89c30e35b7 100644 --- a/ext/native/file/file_util.cpp +++ b/Common/File/DirListing.cpp @@ -18,10 +18,9 @@ #include #include -#include "file/file_util.h" #include "Common/Data/Encoding/Utf8.h" - #include "Common/StringUtils.h" +#include "Common/File/DirListing.h" #if !defined(__linux__) && !defined(_WIN32) && !defined(__QNX__) #define stat64 stat @@ -34,134 +33,14 @@ #define fileno #endif // HAVE_LIBNX -FILE *openCFile(const std::string &filename, const char *mode) -{ -#if defined(_WIN32) && defined(UNICODE) - return _wfopen(ConvertUTF8ToWString(filename).c_str(), ConvertUTF8ToWString(mode).c_str()); -#else - return fopen(filename.c_str(), mode); -#endif -} - -bool writeStringToFile(bool text_file, const std::string &str, const char *filename) -{ - FILE *f = openCFile(filename, text_file ? "w" : "wb"); - if (!f) - return false; - size_t len = str.size(); - if (len != fwrite(str.data(), 1, str.size(), f)) - { - fclose(f); - return false; - } - fclose(f); - return true; -} - -bool writeDataToFile(bool text_file, const void* data, const unsigned int size, const char *filename) -{ - FILE *f = openCFile(filename, text_file ? "w" : "wb"); - if (!f) - return false; - size_t len = size; - if (len != fwrite(data, 1, len, f)) - { - fclose(f); - return false; - } - fclose(f); - return true; -} - -uint64_t GetSize(FILE *f) -{ - // This will only support 64-bit when large file support is available. - // That won't be the case on some versions of Android, at least. -#if defined(__ANDROID__) || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64) - int fd = fileno(f); - - off64_t pos = lseek64(fd, 0, SEEK_CUR); - off64_t size = lseek64(fd, 0, SEEK_END); - if (size != pos && lseek64(fd, pos, SEEK_SET) != pos) { - // Should error here. - return 0; - } - return size; -#else -#ifdef _WIN32 - uint64_t pos = _ftelli64(f); -#else - uint64_t pos = ftello(f); -#endif - if (fseek(f, 0, SEEK_END) != 0) { - return 0; - } -#ifdef _WIN32 - uint64_t size = _ftelli64(f); - // Reset the seek position to where it was when we started. - if (size != pos && _fseeki64(f, pos, SEEK_SET) != 0) { -#else - uint64_t size = ftello(f); - // Reset the seek position to where it was when we started. - if (size != pos && fseeko(f, pos, SEEK_SET) != 0) { -#endif - // Should error here. - return 0; - } - return size; -#endif -} - -bool readFileToString(bool text_file, const char *filename, std::string &str) -{ - FILE *f = openCFile(filename, text_file ? "r" : "rb"); - if (!f) - return false; - size_t len = (size_t)GetSize(f); - char *buf = new char[len + 1]; - buf[fread(buf, 1, len, f)] = 0; - str = std::string(buf, len); - fclose(f); - delete [] buf; - return true; -} - -uint8_t *ReadLocalFile(const char *filename, size_t *size) { - FILE *file = openCFile(filename, "rb"); - if (!file) { - *size = 0; - return nullptr; - } - fseek(file, 0, SEEK_END); - size_t f_size = ftell(file); - if ((long)f_size < 0) { - *size = 0; - fclose(file); - return nullptr; - } - fseek(file, 0, SEEK_SET); - uint8_t *contents = new uint8_t[f_size + 1]; - if (fread(contents, 1, f_size, file) != f_size) { - delete[] contents; - contents = nullptr; - *size = 0; - } else { - contents[f_size] = 0; - *size = f_size; - } - fclose(file); - return contents; -} - - // Returns true if filename is a directory -bool isDirectory(const std::string &filename) { +bool isDirectory(const std::string & filename) { FileInfo info; getFileInfo(filename.c_str(), &info); return info.isDirectory; } -bool getFileInfo(const char *path, FileInfo *fileInfo) { +bool getFileInfo(const char *path, FileInfo * fileInfo) { // TODO: Expand relative paths? fileInfo->fullName = path; @@ -204,17 +83,17 @@ bool getFileInfo(const char *path, FileInfo *fileInfo) { return true; } -std::string getFileExtension(const std::string &fn) { +std::string getFileExtension(const std::string & fn) { int pos = (int)fn.rfind("."); if (pos < 0) return ""; - std::string ext = fn.substr(pos+1); + std::string ext = fn.substr(pos + 1); for (size_t i = 0; i < ext.size(); i++) { ext[i] = tolower(ext[i]); } return ext; } -bool FileInfo::operator <(const FileInfo &other) const { +bool FileInfo::operator <(const FileInfo & other) const { if (isDirectory && !other.isDirectory) return true; else if (!isDirectory && other.isDirectory) @@ -225,7 +104,7 @@ bool FileInfo::operator <(const FileInfo &other) const { return false; } -size_t getFilesInDir(const char *directory, std::vector *files, const char *filter, int flags) { +size_t getFilesInDir(const char *directory, std::vector * files, const char *filter, int flags) { size_t foundEntries = 0; std::set filters; if (filter) { @@ -320,7 +199,7 @@ size_t getFilesInDir(const char *directory, std::vector *files, const return foundEntries; } -int64_t getDirectoryRecursiveSize(const std::string &path, const char *filter, int flags) { +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; @@ -356,7 +235,7 @@ std::vector getWindowsDrives() str.pop_back(); // we don't want the final backslash str += "/"; drives.push_back(str); - + // advance to next drive while (*drive++) {} } diff --git a/ext/native/file/file_util.h b/Common/File/DirListing.h similarity index 67% rename from ext/native/file/file_util.h rename to Common/File/DirListing.h index 3b2fb8ac6a..965ca5d6bf 100644 --- a/ext/native/file/file_util.h +++ b/Common/File/DirListing.h @@ -7,14 +7,6 @@ #include -// Whole-file reading/writing -bool writeStringToFile(bool text_file, const std::string &str, const char *filename); -bool writeDataToFile(bool text_file, const void* data, const unsigned int size, const char *filename); - -bool readFileToString(bool text_file, const char *filename, std::string &str); -// Return value must be delete[]-d. -uint8_t *ReadLocalFile(const char *filename, size_t *size); - // Beginnings of a directory utility system. TODO: Improve. struct FileInfo { diff --git a/ext/native/file/fd_util.cpp b/Common/File/FileDescriptor.cpp similarity index 99% rename from ext/native/file/fd_util.cpp rename to Common/File/FileDescriptor.cpp index 9851d655b6..0c40ee1da7 100644 --- a/ext/native/file/fd_util.cpp +++ b/Common/File/FileDescriptor.cpp @@ -1,5 +1,4 @@ #include "ppsspp_config.h" -#include "file/fd_util.h" #include #include @@ -20,6 +19,7 @@ #include "Common/Common.h" #include "Common/Log.h" +#include "Common/File/FileDescriptor.h" namespace fd_util { diff --git a/ext/native/file/fd_util.h b/Common/File/FileDescriptor.h similarity index 100% rename from ext/native/file/fd_util.h rename to Common/File/FileDescriptor.h diff --git a/Common/FileUtil.cpp b/Common/File/FileUtil.cpp similarity index 90% rename from Common/FileUtil.cpp rename to Common/File/FileUtil.cpp index 54c6f8da85..05af060d95 100644 --- a/Common/FileUtil.cpp +++ b/Common/File/FileUtil.cpp @@ -28,12 +28,12 @@ #include #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Common/SysError.h" #ifdef _WIN32 -#include "CommonWindows.h" +#include "Common/CommonWindows.h" #include #include // for SHGetFolderPath #include @@ -618,20 +618,43 @@ uint64_t GetFileSize(const std::string &filename) { #endif } -// Overloaded GetSize, accepts FILE* -uint64_t GetFileSize(FILE *f) { - // can't use off_t here because it can be 32-bit - uint64_t pos = ftello(f); - if (fseeko(f, 0, SEEK_END) != 0) { - ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", f, GetLastErrorMsg().c_str()); - return 0; - } - uint64_t size = ftello(f); - if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { - ERROR_LOG(COMMON, "GetSize: seek failed %p: %s", f, GetLastErrorMsg().c_str()); +uint64_t GetFileSize(FILE *f) +{ + // This will only support 64-bit when large file support is available. + // That won't be the case on some versions of Android, at least. +#if defined(__ANDROID__) || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64) + int fd = fileno(f); + + off64_t pos = lseek64(fd, 0, SEEK_CUR); + off64_t size = lseek64(fd, 0, SEEK_END); + if (size != pos && lseek64(fd, pos, SEEK_SET) != pos) { + // Should error here. return 0; } return size; +#else +#ifdef _WIN32 + uint64_t pos = _ftelli64(f); +#else + uint64_t pos = ftello(f); +#endif + if (fseek(f, 0, SEEK_END) != 0) { + return 0; + } +#ifdef _WIN32 + uint64_t size = _ftelli64(f); + // Reset the seek position to where it was when we started. + if (size != pos && _fseeki64(f, pos, SEEK_SET) != 0) { +#else + uint64_t size = ftello(f); + // Reset the seek position to where it was when we started. + if (size != pos && fseeko(f, pos, SEEK_SET) != 0) { +#endif + // Should error here. + return 0; + } + return size; +#endif } // creates an empty file filename, returns true on success @@ -955,3 +978,74 @@ bool IOFile::Resize(uint64_t size) } } // namespace + +bool readFileToString(bool text_file, const char *filename, std::string & str) +{ + FILE *f = File::OpenCFile(filename, text_file ? "r" : "rb"); + if (!f) + return false; + size_t len = (size_t)File::GetFileSize(f); + char *buf = new char[len + 1]; + buf[fread(buf, 1, len, f)] = 0; + str = std::string(buf, len); + fclose(f); + delete[] buf; + return true; +} + +uint8_t *ReadLocalFile(const char *filename, size_t * size) { + FILE *file = File::OpenCFile(filename, "rb"); + if (!file) { + *size = 0; + return nullptr; + } + fseek(file, 0, SEEK_END); + size_t f_size = ftell(file); + if ((long)f_size < 0) { + *size = 0; + fclose(file); + return nullptr; + } + fseek(file, 0, SEEK_SET); + uint8_t *contents = new uint8_t[f_size + 1]; + if (fread(contents, 1, f_size, file) != f_size) { + delete[] contents; + contents = nullptr; + *size = 0; + } else { + contents[f_size] = 0; + *size = f_size; + } + fclose(file); + return contents; +} + +bool writeStringToFile(bool text_file, const std::string &str, const char *filename) +{ + FILE *f = File::OpenCFile(filename, text_file ? "w" : "wb"); + if (!f) + return false; + size_t len = str.size(); + if (len != fwrite(str.data(), 1, str.size(), f)) + { + fclose(f); + return false; + } + fclose(f); + return true; +} + +bool writeDataToFile(bool text_file, const void* data, const unsigned int size, const char *filename) +{ + FILE *f = File::OpenCFile(filename, text_file ? "w" : "wb"); + if (!f) + return false; + size_t len = size; + if (len != fwrite(data, 1, len, f)) + { + fclose(f); + return false; + } + fclose(f); + return true; +} diff --git a/Common/FileUtil.h b/Common/File/FileUtil.h similarity index 91% rename from Common/FileUtil.h rename to Common/File/FileUtil.h index 08f1c42615..a191f554eb 100644 --- a/Common/FileUtil.h +++ b/Common/File/FileUtil.h @@ -24,7 +24,7 @@ #include #include -#include "Common.h" +#include "Common/Common.h" #ifdef _MSC_VER inline struct tm* localtime_r(const time_t *clock, struct tm *result) { @@ -192,3 +192,13 @@ private: }; } // namespace + +// TODO: Refactor, this was moved from the old file_util.cpp. + +// Whole-file reading/writing +bool writeStringToFile(bool text_file, const std::string &str, const char *filename); +bool writeDataToFile(bool text_file, const void* data, const unsigned int size, const char *filename); + +bool readFileToString(bool text_file, const char *filename, std::string &str); +// Return value must be delete[]-d. +uint8_t *ReadLocalFile(const char *filename, size_t *size); diff --git a/Common/File/PathBrowser.cpp b/Common/File/PathBrowser.cpp index a57390d447..712e5a95e6 100644 --- a/Common/File/PathBrowser.cpp +++ b/Common/File/PathBrowser.cpp @@ -2,8 +2,8 @@ #include #include -#include "net/http_client.h" -#include "net/url.h" +#include "Common/Net/HTTPClient.h" +#include "Common/Net/URL.h" #include "Common/File/PathBrowser.h" #include "Common/StringUtils.h" diff --git a/Common/File/PathBrowser.h b/Common/File/PathBrowser.h index bdbce21250..01da52e89f 100644 --- a/Common/File/PathBrowser.h +++ b/Common/File/PathBrowser.h @@ -6,9 +6,9 @@ #include #include #include -#include +#include -#include "file/file_util.h" +#include "Common/File/DirListing.h" // Abstraction above path that lets you navigate easily. // "/" is a special path that means the root of the file system. On Windows, diff --git a/Common/File/VFS/AssetReader.h b/Common/File/VFS/AssetReader.h index 76b5a31439..5dcf98efc8 100644 --- a/Common/File/VFS/AssetReader.h +++ b/Common/File/VFS/AssetReader.h @@ -9,7 +9,6 @@ #include #include "Common/File/VFS/VFS.h" -#include "file/file_util.h" // Direct readers. deallocate using delete []. uint8_t *ReadLocalFile(const char *filename, size_t *size); diff --git a/Common/File/VFS/VFS.h b/Common/File/VFS/VFS.h index b823519865..693e8fbc1d 100644 --- a/Common/File/VFS/VFS.h +++ b/Common/File/VFS/VFS.h @@ -1,7 +1,8 @@ #pragma once #include -#include "file/file_util.h" + +#include "Common/File/DirListing.h" // Basic virtual file system. Used to manage assets on Android, where we have to // read them manually out of the APK zipfile, while being able to run on other diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 66c85c70b8..1ecea857e8 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -25,7 +25,7 @@ #include "Common/LogManager.h" #include "Common/ConsoleListener.h" #include "Common/Timer.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" // Don't need to savestate this. diff --git a/Common/MemArenaDarwin.cpp b/Common/MemArenaDarwin.cpp index 4d197c1f85..d35fb7f84d 100644 --- a/Common/MemArenaDarwin.cpp +++ b/Common/MemArenaDarwin.cpp @@ -21,12 +21,6 @@ #include #include - -#include "Common/Log.h" -#include "Common/FileUtil.h" -#include "Common/MemoryUtil.h" -#include "Common/MemArena.h" - #include #include #include @@ -36,6 +30,11 @@ #include #include +#include "Common/Log.h" +#include "Common/File/FileUtil.h" +#include "Common/MemoryUtil.h" +#include "Common/MemArena.h" + size_t MemArena::roundup(size_t x) { return x; } diff --git a/Common/MemArenaPosix.cpp b/Common/MemArenaPosix.cpp index 016be57ce5..65a812001b 100644 --- a/Common/MemArenaPosix.cpp +++ b/Common/MemArenaPosix.cpp @@ -19,18 +19,17 @@ #if !defined(_WIN32) && !defined(ANDROID) && !defined(__APPLE__) -#include - -#include "Common/FileUtil.h" -#include "Common/MemoryUtil.h" -#include "Common/MemArena.h" -#include "Common/Log.h" - #include #include #include #include #include +#include + +#include "Common/Log.h" +#include "Common/File/FileUtil.h" +#include "Common/MemoryUtil.h" +#include "Common/MemArena.h" static const std::string tmpfs_location = "/dev/shm"; static const std::string tmpfs_ram_temp_file = "/dev/shm/gc_mem.tmp"; diff --git a/ext/native/net/http_client.cpp b/Common/Net/HTTPClient.cpp similarity index 99% rename from ext/native/net/http_client.cpp rename to Common/Net/HTTPClient.cpp index 60c1ca8a90..41cf350625 100644 --- a/ext/native/net/http_client.cpp +++ b/Common/Net/HTTPClient.cpp @@ -1,4 +1,4 @@ -#include "net/http_client.h" +#include "Common/Net/HTTPClient.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" @@ -20,10 +20,10 @@ #include #include -#include "file/fd_util.h" -#include "net/resolve.h" -#include "net/url.h" +#include "Common/Net/Resolve.h" +#include "Common/Net/URL.h" +#include "Common/File/FileDescriptor.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Encoding/Compression.h" #include "Common/Buffer.h" diff --git a/ext/native/net/http_client.h b/Common/Net/HTTPClient.h similarity index 99% rename from ext/native/net/http_client.h rename to Common/Net/HTTPClient.h index 32490dc40b..731ff75dd5 100644 --- a/ext/native/net/http_client.h +++ b/Common/Net/HTTPClient.h @@ -5,7 +5,7 @@ #include #include -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #ifdef _WIN32 #ifndef NOMINMAX diff --git a/ext/native/net/http_headers.cpp b/Common/Net/HTTPHeaders.cpp similarity index 97% rename from ext/native/net/http_headers.cpp rename to Common/Net/HTTPHeaders.cpp index ca370dad9c..acb554ee70 100644 --- a/ext/native/net/http_headers.cpp +++ b/Common/Net/HTTPHeaders.cpp @@ -1,13 +1,13 @@ -#include "net/http_headers.h" +#include "Common/Net/HTTPHeaders.h" #include #include #include -#include "file/fd_util.h" -#include "net/sinks.h" +#include "Common/Net/Sinks.h" #include "Common/Log.h" +#include "Common/File/FileDescriptor.h" #include "Common/StringUtils.h" namespace http { diff --git a/ext/native/net/http_headers.h b/Common/Net/HTTPHeaders.h similarity index 100% rename from ext/native/net/http_headers.h rename to Common/Net/HTTPHeaders.h diff --git a/ext/native/net/http_server.cpp b/Common/Net/HTTPServer.cpp similarity index 98% rename from ext/native/net/http_server.cpp rename to Common/Net/HTTPServer.cpp index 5569923cd3..da114da85a 100644 --- a/ext/native/net/http_server.cpp +++ b/Common/Net/HTTPServer.cpp @@ -34,9 +34,9 @@ #include #include -#include "file/fd_util.h" -#include "net/http_server.h" -#include "net/sinks.h" +#include "Common/Net/HTTPServer.h" +#include "Common/Net/Sinks.h" +#include "Common/File/FileDescriptor.h" #include "Common/Thread/Executor.h" #include "Common/Buffer.h" diff --git a/ext/native/net/http_server.h b/Common/Net/HTTPServer.h similarity index 97% rename from ext/native/net/http_server.h rename to Common/Net/HTTPServer.h index 7102f963b2..9cfdf2fc1e 100644 --- a/ext/native/net/http_server.h +++ b/Common/Net/HTTPServer.h @@ -3,8 +3,8 @@ #include #include -#include "net/http_headers.h" -#include "net/resolve.h" +#include "Common/Net/HTTPHeaders.h" +#include "Common/Net/Resolve.h" #include "Common/Thread/Executor.h" namespace net { diff --git a/ext/native/net/resolve.cpp b/Common/Net/Resolve.cpp similarity index 99% rename from ext/native/net/resolve.cpp rename to Common/Net/Resolve.cpp index a6e07c0635..aac2cdb6fd 100644 --- a/ext/native/net/resolve.cpp +++ b/Common/Net/Resolve.cpp @@ -1,5 +1,5 @@ #include "ppsspp_config.h" -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #include #include diff --git a/ext/native/net/resolve.h b/Common/Net/Resolve.h similarity index 100% rename from ext/native/net/resolve.h rename to Common/Net/Resolve.h diff --git a/ext/native/net/sinks.cpp b/Common/Net/Sinks.cpp similarity index 99% rename from ext/native/net/sinks.cpp rename to Common/Net/Sinks.cpp index dbfa8643df..2d15de15cf 100644 --- a/ext/native/net/sinks.cpp +++ b/Common/Net/Sinks.cpp @@ -24,10 +24,10 @@ #include #include -#include "net/sinks.h" -#include "file/fd_util.h" +#include "Common/Net/Sinks.h" #include "Common/Log.h" +#include "Common/File/FileDescriptor.h" #ifndef MSG_NOSIGNAL // Default value to 0x00 (do nothing) in systems where it's not supported diff --git a/ext/native/net/sinks.h b/Common/Net/Sinks.h similarity index 100% rename from ext/native/net/sinks.h rename to Common/Net/Sinks.h diff --git a/ext/native/net/url.cpp b/Common/Net/URL.cpp similarity index 99% rename from ext/native/net/url.cpp rename to Common/Net/URL.cpp index b3aa5ff25d..681fc45ff2 100644 --- a/ext/native/net/url.cpp +++ b/Common/Net/URL.cpp @@ -1,7 +1,6 @@ -#include "net/url.h" - #include "Common/Log.h" #include "Common/StringUtils.h" +#include "Common/Net/URL.h" const char *UrlEncoder::unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"; const char *UrlEncoder::hexChars = "0123456789ABCDEF"; diff --git a/ext/native/net/url.h b/Common/Net/URL.h similarity index 100% rename from ext/native/net/url.h rename to Common/Net/URL.h diff --git a/ext/native/net/websocket_server.cpp b/Common/Net/WebsocketServer.cpp similarity index 99% rename from ext/native/net/websocket_server.cpp rename to Common/Net/WebsocketServer.cpp index 60f41c2290..5af6bf2bdb 100644 --- a/ext/native/net/websocket_server.cpp +++ b/Common/Net/WebsocketServer.cpp @@ -16,9 +16,9 @@ #endif #include "Common/Data/Encoding/Base64.h" -#include "net/http_server.h" -#include "net/sinks.h" -#include "net/websocket_server.h" +#include "Common/Net/HTTPServer.h" +#include "Common/Net/Sinks.h" +#include "Common/Net/WebsocketServer.h" #include "Common/Crypto/sha1.h" #include "Common/Log.h" diff --git a/ext/native/net/websocket_server.h b/Common/Net/WebsocketServer.h similarity index 97% rename from ext/native/net/websocket_server.h rename to Common/Net/WebsocketServer.h index 2c4c59739e..7a05b0f03a 100644 --- a/ext/native/net/websocket_server.h +++ b/Common/Net/WebsocketServer.h @@ -2,8 +2,9 @@ #include #include -#include "net/http_server.h" -#include "net/sinks.h" + +#include "Common/Net/HTTPServer.h" +#include "Common/Net/Sinks.h" namespace net { diff --git a/Common/Serialize/Serializer.cpp b/Common/Serialize/Serializer.cpp index c2eca8731e..4738b829f3 100644 --- a/Common/Serialize/Serializer.cpp +++ b/Common/Serialize/Serializer.cpp @@ -21,7 +21,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" PointerWrapSection PointerWrap::Section(const char *title, int ver) { diff --git a/ext/native/ui/ui_context.cpp b/Common/UI/Context.cpp similarity index 99% rename from ext/native/ui/ui_context.cpp rename to Common/UI/Context.cpp index 68feedb298..d8f45b5737 100644 --- a/ext/native/ui/ui_context.cpp +++ b/Common/UI/Context.cpp @@ -4,9 +4,9 @@ #include "Common/System/Display.h" #include "Common/System/System.h" -#include "ui/ui.h" -#include "ui/view.h" -#include "ui/ui_context.h" +#include "Common/UI/UI.h" +#include "Common/UI/View.h" +#include "Common/UI/Context.h" #include "gfx_es2/draw_buffer.h" #include "gfx_es2/draw_text.h" diff --git a/ext/native/ui/ui_context.h b/Common/UI/Context.h similarity index 100% rename from ext/native/ui/ui_context.h rename to Common/UI/Context.h diff --git a/ext/native/ui/root.cpp b/Common/UI/Root.cpp similarity index 99% rename from ext/native/ui/root.cpp rename to Common/UI/Root.cpp index 394ee2aa28..73cca79888 100644 --- a/ext/native/ui/root.cpp +++ b/Common/UI/Root.cpp @@ -3,8 +3,8 @@ #include "ppsspp_config.h" -#include "ui/root.h" -#include "ui/viewgroup.h" +#include "Common/UI/Root.h" +#include "Common/UI/ViewGroup.h" #include "Common/Log.h" #include "Common/TimeUtil.h" diff --git a/ext/native/ui/root.h b/Common/UI/Root.h similarity index 97% rename from ext/native/ui/root.h rename to Common/UI/Root.h index 052ced4f33..c19dc44acc 100644 --- a/ext/native/ui/root.h +++ b/Common/UI/Root.h @@ -2,7 +2,7 @@ #include -#include "ui/ui_context.h" +#include "Common/UI/Context.h" #include "Common/Input/InputState.h" namespace UI { diff --git a/ext/native/ui/screen.cpp b/Common/UI/Screen.cpp similarity index 98% rename from ext/native/ui/screen.cpp rename to Common/UI/Screen.cpp index 97f5f2c567..f8f4cd10dc 100644 --- a/ext/native/ui/screen.cpp +++ b/Common/UI/Screen.cpp @@ -1,9 +1,9 @@ #include "Common/System/Display.h" #include "Common/Input/InputState.h" -#include "ui/root.h" -#include "ui/screen.h" -#include "ui/ui.h" -#include "ui/view.h" +#include "Common/UI/Root.h" +#include "Common/UI/Screen.h" +#include "Common/UI/UI.h" +#include "Common/UI/View.h" #include "Common/Log.h" #include "Common/TimeUtil.h" diff --git a/ext/native/ui/screen.h b/Common/UI/Screen.h similarity index 100% rename from ext/native/ui/screen.h rename to Common/UI/Screen.h diff --git a/ext/native/ui/ui_tween.cpp b/Common/UI/Tween.cpp similarity index 96% rename from ext/native/ui/ui_tween.cpp rename to Common/UI/Tween.cpp index 3263c0da70..d06601cb71 100644 --- a/ext/native/ui/ui_tween.cpp +++ b/Common/UI/Tween.cpp @@ -1,7 +1,7 @@ #include "Common/Data/Color/RGBAUtil.h" -#include "ui/ui_tween.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/Tween.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" namespace UI { diff --git a/ext/native/ui/ui_tween.h b/Common/UI/Tween.h similarity index 99% rename from ext/native/ui/ui_tween.h rename to Common/UI/Tween.h index 67d353d074..2786963d55 100644 --- a/ext/native/ui/ui_tween.h +++ b/Common/UI/Tween.h @@ -4,7 +4,7 @@ #include #include #include "Common/TimeUtil.h" -#include "ui/view.h" +#include "Common/UI/View.h" namespace UI { diff --git a/ext/native/ui/ui.cpp b/Common/UI/UI.cpp similarity index 89% rename from ext/native/ui/ui.cpp rename to Common/UI/UI.cpp index 659aa5af5d..3148a0de57 100644 --- a/ext/native/ui/ui.cpp +++ b/Common/UI/UI.cpp @@ -6,8 +6,8 @@ #include #include "Common/Data/Color/RGBAUtil.h" -#include "ui/ui.h" -#include "ui/ui_context.h" +#include "Common/UI/UI.h" +#include "Common/UI/Context.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" diff --git a/ext/native/ui/ui.h b/Common/UI/UI.h similarity index 100% rename from ext/native/ui/ui.h rename to Common/UI/UI.h diff --git a/ext/native/ui/ui_screen.cpp b/Common/UI/UIScreen.cpp similarity index 99% rename from ext/native/ui/ui_screen.cpp rename to Common/UI/UIScreen.cpp index 8ba6eb2bb0..14f793d1e5 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/Common/UI/UIScreen.cpp @@ -6,10 +6,10 @@ #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "Common/Math/curves.h" -#include "ui/ui_screen.h" -#include "ui/ui_context.h" -#include "ui/screen.h" -#include "ui/root.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/Context.h" +#include "Common/UI/Screen.h" +#include "Common/UI/Root.h" #include "Common/Data/Text/I18n.h" #include "gfx_es2/draw_buffer.h" diff --git a/ext/native/ui/ui_screen.h b/Common/UI/UIScreen.h similarity index 99% rename from ext/native/ui/ui_screen.h rename to Common/UI/UIScreen.h index 3184b03d09..aa660b0084 100644 --- a/ext/native/ui/ui_screen.h +++ b/Common/UI/UIScreen.h @@ -3,8 +3,8 @@ #include #include "Common/Math/lin/vec3.h" -#include "ui/screen.h" -#include "ui/viewgroup.h" +#include "Common/UI/Screen.h" +#include "Common/UI/ViewGroup.h" using namespace Lin; diff --git a/ext/native/ui/view.cpp b/Common/UI/View.cpp similarity index 99% rename from ext/native/ui/view.cpp rename to Common/UI/View.cpp index d0182622ca..ece140377b 100644 --- a/ext/native/ui/view.cpp +++ b/Common/UI/View.cpp @@ -6,11 +6,11 @@ #include "gfx_es2/draw_buffer.h" #include "gfx/texture_atlas.h" #include "Common/Data/Encoding/Utf8.h" -#include "ui/ui.h" -#include "ui/view.h" -#include "ui/ui_context.h" -#include "ui/ui_tween.h" -#include "ui/root.h" +#include "Common/UI/UI.h" +#include "Common/UI/View.h" +#include "Common/UI/Context.h" +#include "Common/UI/Tween.h" +#include "Common/UI/Root.h" #include "thin3d/thin3d.h" #include "Common/System/System.h" #include "Common/TimeUtil.h" diff --git a/ext/native/ui/view.h b/Common/UI/View.h similarity index 100% rename from ext/native/ui/view.h rename to Common/UI/View.h diff --git a/ext/native/ui/viewgroup.cpp b/Common/UI/ViewGroup.cpp similarity index 99% rename from ext/native/ui/viewgroup.cpp rename to Common/UI/ViewGroup.cpp index c48f1d22f2..ddd6153548 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/Common/UI/ViewGroup.cpp @@ -5,11 +5,11 @@ #include "Common/Input/KeyCodes.h" #include "Common/Math/curves.h" -#include "ui/ui_context.h" -#include "ui/ui_tween.h" -#include "ui/root.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/Context.h" +#include "Common/UI/Tween.h" +#include "Common/UI/Root.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "gfx_es2/draw_buffer.h" #include "Common/Log.h" diff --git a/ext/native/ui/viewgroup.h b/Common/UI/ViewGroup.h similarity index 99% rename from ext/native/ui/viewgroup.h rename to Common/UI/ViewGroup.h index 7b2ec02fb0..0d17642617 100644 --- a/ext/native/ui/viewgroup.h +++ b/Common/UI/ViewGroup.h @@ -7,7 +7,7 @@ #include "Common/Math/geom2d.h" #include "Common/Input/GestureDetector.h" -#include "ui/view.h" +#include "Common/UI/View.h" namespace UI { diff --git a/Core/AVIDump.cpp b/Core/AVIDump.cpp index fd25806e51..19cbcf1227 100644 --- a/Core/AVIDump.cpp +++ b/Core/AVIDump.cpp @@ -23,7 +23,7 @@ extern "C" { #endif -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/ColorConv.h" #include "Core/Config.h" diff --git a/Core/Config.cpp b/Core/Config.cpp index 3a98ae836f..7264f38859 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -25,8 +25,8 @@ #include "ppsspp_config.h" #include "gfx_es2/gpu_features.h" -#include "net/http_client.h" -#include "net/url.h" +#include "Common/Net/HTTPClient.h" +#include "Common/Net/URL.h" #include "Common/Log.h" #include "Common/Data/Format/IniFile.h" @@ -34,7 +34,7 @@ #include "Common/Data/Text/I18n.h" #include "Common/Data/Text/Parsers.h" #include "Common/CPUDetect.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/LogManager.h" #include "Common/OSVersion.h" #include "Common/System/Display.h" diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 5feb26a353..be1edd7a23 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -5,7 +5,7 @@ #include "Common/StringUtils.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Core/CoreTiming.h" #include "Core/CoreParameter.h" #include "Core/CwCheat.h" diff --git a/Core/Debugger/SymbolMap.cpp b/Core/Debugger/SymbolMap.cpp index 4ca7bec75e..0efd301b0e 100644 --- a/Core/Debugger/SymbolMap.cpp +++ b/Core/Debugger/SymbolMap.cpp @@ -36,7 +36,7 @@ #include "Common/CommonTypes.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Core/MemMap.h" #include "Core/Debugger/SymbolMap.h" diff --git a/Core/Debugger/WebSocket/GPURecordSubscriber.cpp b/Core/Debugger/WebSocket/GPURecordSubscriber.cpp index 7e62ef4700..4ed21fbbcf 100644 --- a/Core/Debugger/WebSocket/GPURecordSubscriber.cpp +++ b/Core/Debugger/WebSocket/GPURecordSubscriber.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/Data/Encoding/Base64.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Core/Debugger/WebSocket/GPURecordSubscriber.h" #include "Core/Debugger/WebSocket/WebSocketUtils.h" #include "Core/System.h" diff --git a/Core/Debugger/WebSocket/WebSocketUtils.h b/Core/Debugger/WebSocket/WebSocketUtils.h index 24752274f2..5caa28adaf 100644 --- a/Core/Debugger/WebSocket/WebSocketUtils.h +++ b/Core/Debugger/WebSocket/WebSocketUtils.h @@ -21,11 +21,10 @@ #include -#include "net/websocket_server.h" - #include "Common/Log.h" #include "Common/Data/Format/JSONReader.h" #include "Common/Data/Format/JSONWriter.h" +#include "Common/Net/WebsocketServer.h" #if PPSSPP_PLATFORM(UWP) // Enum name overlapped with UWP macro, quick hack to disable it diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index a75308a35f..0266cd0d4a 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -24,7 +24,7 @@ #include "Common/Data/Text/I18n.h" #include "Common/Thread/ThreadUtil.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index a734fc7d69..269eb3a33f 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -15,8 +15,9 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/Data/Text/I18n.h" #include "Common/Log.h" +#include "Common/Data/Text/I18n.h" +#include "Common/Data/Format/ZIMLoad.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" @@ -34,8 +35,6 @@ #include "Core/HW/MemoryStick.h" #include "Core/Util/PPGeDraw.h" -#include "image/png_load.h" - #include static const std::string ICON0_FILENAME = "ICON0.PNG"; diff --git a/Core/ELF/PBPReader.cpp b/Core/ELF/PBPReader.cpp index 41653bfcba..de9c4452bd 100644 --- a/Core/ELF/PBPReader.cpp +++ b/Core/ELF/PBPReader.cpp @@ -20,7 +20,7 @@ #include #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Core/Loaders.h" #include "Core/ELF/PBPReader.h" diff --git a/Core/FileLoaders/DiskCachingFileLoader.cpp b/Core/FileLoaders/DiskCachingFileLoader.cpp index e8a940b7d0..412f409a84 100644 --- a/Core/FileLoaders/DiskCachingFileLoader.cpp +++ b/Core/FileLoaders/DiskCachingFileLoader.cpp @@ -15,17 +15,18 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "ppsspp_config.h" + #include #include #include #include #include -#include "ppsspp_config.h" -#include "file/file_util.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/File/DiskFree.h" -#include "Common/FileUtil.h" +#include "Common/File/DirListing.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Common/CommonWindows.h" #include "Core/FileLoaders/DiskCachingFileLoader.h" diff --git a/Core/FileLoaders/HTTPFileLoader.h b/Core/FileLoaders/HTTPFileLoader.h index cf3441df9c..d8cb6f3c47 100644 --- a/Core/FileLoaders/HTTPFileLoader.h +++ b/Core/FileLoaders/HTTPFileLoader.h @@ -20,9 +20,9 @@ #include #include -#include "net/http_client.h" -#include "net/resolve.h" -#include "net/url.h" +#include "Common/Net/HTTPClient.h" +#include "Common/Net/Resolve.h" +#include "Common/Net/URL.h" #include "Common/CommonTypes.h" #include "Core/Loaders.h" diff --git a/Core/FileLoaders/LocalFileLoader.cpp b/Core/FileLoaders/LocalFileLoader.cpp index f01eaffdda..1a6205bfab 100644 --- a/Core/FileLoaders/LocalFileLoader.cpp +++ b/Core/FileLoaders/LocalFileLoader.cpp @@ -19,10 +19,10 @@ #include "ppsspp_config.h" -#include "file/file_util.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" +#include "Common/File/DirListing.h" #include "Core/FileLoaders/LocalFileLoader.h" #ifdef _WIN32 diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index 368d78a296..9d4f85ee6a 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -20,7 +20,7 @@ #include #include "Common/Data/Text/I18n.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Common/Swap.h" #include "Core/Loaders.h" diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 0389244e0f..d6594ee52e 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -25,7 +25,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/File/DiskFree.h" #include "Common/File/VFS/VFS.h" #include "Core/FileSystems/DirectoryFileSystem.h" diff --git a/Core/FileSystems/VirtualDiscFileSystem.cpp b/Core/FileSystems/VirtualDiscFileSystem.cpp index 7aaef4327c..fde9808d8c 100644 --- a/Core/FileSystems/VirtualDiscFileSystem.cpp +++ b/Core/FileSystems/VirtualDiscFileSystem.cpp @@ -17,7 +17,7 @@ #include "ppsspp_config.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" diff --git a/Core/HLE/Plugins.cpp b/Core/HLE/Plugins.cpp index 9572d6e5ea..95e6c0efa5 100644 --- a/Core/HLE/Plugins.cpp +++ b/Core/HLE/Plugins.cpp @@ -16,9 +16,10 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "file/file_util.h" + #include "Common/Data/Format/IniFile.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" +#include "Common/File/DirListing.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/Config.h" #include "Core/MemMap.h" diff --git a/Core/HLE/proAdhoc.h b/Core/HLE/proAdhoc.h index 53348b115c..4aea8e9822 100644 --- a/Core/HLE/proAdhoc.h +++ b/Core/HLE/proAdhoc.h @@ -41,7 +41,7 @@ #include #include -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #include "Common/Serialize/Serializer.h" #include "Core/Config.h" diff --git a/Core/HLE/proAdhocServer.cpp b/Core/HLE/proAdhocServer.cpp index 52b84febb1..d9ea077054 100644 --- a/Core/HLE/proAdhocServer.cpp +++ b/Core/HLE/proAdhocServer.cpp @@ -52,7 +52,7 @@ #include "Common/Data/Text/I18n.h" #include "Common/Thread/ThreadUtil.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/TimeUtil.h" #include "Core/Util/PortManager.h" #include "Core/Core.h" diff --git a/Core/HLE/sceHttp.cpp b/Core/HLE/sceHttp.cpp index e592ef6178..6d13b6f1f2 100644 --- a/Core/HLE/sceHttp.cpp +++ b/Core/HLE/sceHttp.cpp @@ -19,7 +19,7 @@ #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceHttp.h" -#include "net/http_client.h" +#include "Common/Net/HTTPClient.h" // If http isn't loaded (seems unlikely), most functions should return SCE_KERNEL_ERROR_LIBRARY_NOTFOUND diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index bdd93d5179..a12ba039f9 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -22,7 +22,7 @@ #include "Common/Thread/ThreadUtil.h" #include "Common/Profiler/Profiler.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeMap.h" #include "Common/Serialize/SerializeSet.h" diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 601b01f166..4952f9be31 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -24,7 +24,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeSet.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Core.h" diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 629a9766c8..74d01aa789 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -22,7 +22,7 @@ #include #endif -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #include "Common/Data/Text/Parsers.h" #include "Common/Serialize/Serializer.h" diff --git a/Core/HLE/scePauth.cpp b/Core/HLE/scePauth.cpp index 84d92ec126..ceba0710fb 100644 --- a/Core/HLE/scePauth.cpp +++ b/Core/HLE/scePauth.cpp @@ -25,7 +25,7 @@ #include "Core/HLE/scePauth.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" static int scePauth_F7AA47F6(u32 srcPtr, int srcLength, u32 destLengthPtr, u32 workArea) { diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 9ff737f1b5..5cb209c6c4 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -17,8 +17,6 @@ #include -#include "file/file_util.h" - #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeMap.h" diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index 6054eed875..77c2fafae0 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -18,10 +18,8 @@ #include #include -#include "file/file_util.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" - #include "Core/FileLoaders/CachingFileLoader.h" #include "Core/FileLoaders/DiskCachingFileLoader.h" #include "Core/FileLoaders/HTTPFileLoader.h" diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index b38211c0a0..1a39988abc 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -24,7 +24,7 @@ #include "ext/cityhash/city.h" #include "ext/xxhash.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Common/TimeUtil.h" #include "Core/Config.h" diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 09eabf4dc3..51a8758843 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -17,11 +17,10 @@ #include -#include "file/file_util.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Thread/ThreadUtil.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #ifdef _WIN32 #include "Common/CommonWindows.h" diff --git a/Core/Replay.cpp b/Core/Replay.cpp index bc188fcb31..fb03eeea4a 100644 --- a/Core/Replay.cpp +++ b/Core/Replay.cpp @@ -21,7 +21,7 @@ #include "Common/Common.h" #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Replay.h" #include "Core/FileSystems/FileSystem.h" diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 449070cf6a..be0248dff7 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -26,7 +26,7 @@ #include "Core/Reporting.h" #include "Common/File/VFS/VFS.h" #include "Common/CPUDetect.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" #include "Core/Core.h" @@ -44,10 +44,9 @@ #include "Core/ELF/ParamSFO.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" -#include "net/http_client.h" -#include "net/resolve.h" -#include "net/url.h" -#include "file/file_util.h" +#include "Common/Net/HTTPClient.h" +#include "Common/Net/Resolve.h" +#include "Common/Net/URL.h" #include "Common/Thread/ThreadUtil.h" namespace Reporting diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index e354cdc3f7..d0388bb362 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -24,7 +24,7 @@ #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Text/Parsers.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" diff --git a/Core/Screenshot.cpp b/Core/Screenshot.cpp index f1d714d7e7..0e4066bdbf 100644 --- a/Core/Screenshot.cpp +++ b/Core/Screenshot.cpp @@ -26,7 +26,7 @@ #endif #include "Common/ColorConv.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Core/Config.h" #include "Core/Screenshot.h" diff --git a/Core/System.cpp b/Core/System.cpp index 48e22b6f5e..736499a7f4 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -37,7 +37,7 @@ #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Encoding/Utf8.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/TimeUtil.h" #include "Common/GraphicsContext.h" #include "Core/MemFault.h" diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index c2f8a15533..98c6102280 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -28,7 +28,7 @@ #include "Common/Data/Format/IniFile.h" #include "Common/Data/Text/Parsers.h" #include "Common/ColorConv.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Host.h" diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index c0e6b5eb0e..17b2e75751 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -23,7 +23,6 @@ #include #include -#include "file/file_util.h" #ifdef SHARED_LIBZIP #include #else @@ -31,9 +30,8 @@ #endif #include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Format/IniFile.h" - #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Core/Config.h" #include "Core/Loaders.h" diff --git a/Core/Util/GameManager.h b/Core/Util/GameManager.h index 81d1368273..63460f66d7 100644 --- a/Core/Util/GameManager.h +++ b/Core/Util/GameManager.h @@ -23,7 +23,7 @@ #pragma once #include -#include "net/http_client.h" +#include "Common/Net/HTTPClient.h" enum class GameManagerState { IDLE, diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 61507801cb..4f33737351 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -17,14 +17,14 @@ #include -#include "Common/Data/Color/RGBAUtil.h" -#include "Common/File/VFS/VFS.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_text.h" -#include "image/zim_load.h" -#include "image/png_load.h" -#include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Color/RGBAUtil.h" +#include "Common/File/VFS/VFS.h" +#include "Common/Data/Format/ZIMLoad.h" +#include "Common/Data/Format/PNGLoad.h" +#include "Common/Data/Encoding/Utf8.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/StringUtils.h" @@ -1202,7 +1202,7 @@ bool PPGeImage::Load() { unsigned char *textureData; int success; if (filename_.empty()) { - success = pngLoadPtr(Memory::GetPointer(png_), size_, &width_, &height_, &textureData, false); + success = pngLoadPtr(Memory::GetPointer(png_), size_, &width_, &height_, &textureData); } else { std::vector pngData; if (pspFileSystem.ReadEntireFile(filename_, pngData) < 0) { @@ -1210,7 +1210,7 @@ bool PPGeImage::Load() { return false; } - success = pngLoadPtr((const unsigned char *)&pngData[0], pngData.size(), &width_, &height_, &textureData, false); + success = pngLoadPtr((const unsigned char *)&pngData[0], pngData.size(), &width_, &height_, &textureData); } if (!success) { WARN_LOG(SCEGE, "Bad PPGeImage - not a valid png"); diff --git a/Core/Util/PortManager.cpp b/Core/Util/PortManager.cpp index 63bfd5baa7..3c4b808502 100644 --- a/Core/Util/PortManager.cpp +++ b/Core/Util/PortManager.cpp @@ -31,7 +31,7 @@ #include #include "Common/TimeUtil.h" #include "Common/Data/Text/I18n.h" -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" #include "Core/System.h" diff --git a/Core/WaveFile.h b/Core/WaveFile.h index 4366cd936c..3ef3f09b4c 100644 --- a/Core/WaveFile.h +++ b/Core/WaveFile.h @@ -16,7 +16,7 @@ #include #include -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" class WaveFileWriter { diff --git a/Core/WebServer.cpp b/Core/WebServer.cpp index ce7519a47c..9e96baf9f8 100644 --- a/Core/WebServer.cpp +++ b/Core/WebServer.cpp @@ -19,13 +19,13 @@ #include #include -#include "file/fd_util.h" -#include "net/http_client.h" -#include "net/http_server.h" -#include "net/sinks.h" +#include "Common/Net/HTTPClient.h" +#include "Common/Net/HTTPServer.h" +#include "Common/Net/Sinks.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" +#include "Common/File/FileDescriptor.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/GPU/Common/PostShader.cpp b/GPU/Common/PostShader.cpp index 1e650b9db1..a1c030dd3a 100644 --- a/GPU/Common/PostShader.cpp +++ b/GPU/Common/PostShader.cpp @@ -23,7 +23,8 @@ #include #include "Common/Data/Format/IniFile.h" -#include "file/file_util.h" +#include "Common/File/FileUtil.h" +#include "Common/File/DirListing.h" #include "Common/File/VFS/VFS.h" #include "gfx_es2/gpu_features.h" diff --git a/GPU/Debugger/Record.cpp b/GPU/Debugger/Record.cpp index 05ad3b2ff1..4fdc32b29f 100644 --- a/GPU/Debugger/Record.cpp +++ b/GPU/Debugger/Record.cpp @@ -23,7 +23,7 @@ #include #include "Common/Common.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 8fb872cc98..acbd172dfa 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -20,7 +20,7 @@ #include "Common/Log.h" #include "Common/Serialize/Serializer.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/GraphicsContext.h" #include "Core/Config.h" diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index d1ffc3fecc..d61d2adf76 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -34,7 +34,7 @@ #include "thin3d/GLRenderManager.h" #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/TimeUtil.h" #include "Core/Config.h" #include "Core/Host.h" diff --git a/GPU/Vulkan/DebugVisVulkan.cpp b/GPU/Vulkan/DebugVisVulkan.cpp index 023e840d56..7b55caa41c 100644 --- a/GPU/Vulkan/DebugVisVulkan.cpp +++ b/GPU/Vulkan/DebugVisVulkan.cpp @@ -17,8 +17,8 @@ #include "gfx_es2/draw_buffer.h" #include "thin3d/thin3d.h" -#include "ui/ui_context.h" -#include "ui/view.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" #include "DebugVisVulkan.h" #include "Common/Vulkan/VulkanMemory.h" diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 96e4212ec8..447f1b184c 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -21,7 +21,7 @@ #include "Common/Profiler/Profiler.h" #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/GraphicsContext.h" #include "Common/Serialize/Serializer.h" #include "Common/TimeUtil.h" diff --git a/Qt/QtMain.h b/Qt/QtMain.h index cd33b61765..9c7589b6c2 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -31,7 +31,7 @@ QTM_USE_NAMESPACE #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "thin3d/thin3d.h" -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #include "NKCodeFromQt.h" #include "Common/GraphicsContext.h" diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp index 50793957e1..3ffe815c31 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -5,7 +5,7 @@ #include "Common/System/System.h" #include "Common/File/VFS/VFS.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Core/Config.h" #include "SDL/SDLJoystick.h" diff --git a/SDL/SDLJoystick.h b/SDL/SDLJoystick.h index ea14076d64..057e332b25 100644 --- a/SDL/SDLJoystick.h +++ b/SDL/SDLJoystick.h @@ -9,7 +9,7 @@ #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" -#include "net/resolve.h" +#include "Common/Net/Resolve.h" class SDLJoystick{ public: diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 78eef5170e..923c569029 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -24,8 +24,8 @@ SDLJoystick *joystick = NULL; #include "Common/System/System.h" #include "Common/System/NativeApp.h" #include "ext/glslang/glslang/Public/ShaderLang.h" -#include "image/png_load.h" -#include "net/resolve.h" +#include "Common/Data/Format/PNGLoad.h" +#include "Common/Net/Resolve.h" #include "NKCodeFromSDL.h" #include "Common/Math/math_util.h" #include "thin3d/GLRenderManager.h" @@ -693,7 +693,7 @@ int main(int argc, char *argv[]) { snprintf(iconPath, PATH_MAX, "%sassets/icon_regular_72.png", SDL_GetBasePath() ? SDL_GetBasePath() : ""); int width = 0, height = 0; unsigned char *imageData; - if (pngLoad(iconPath, &width, &height, &imageData, false) == 1) { + if (pngLoad(iconPath, &width, &height, &imageData) == 1) { SDL_Surface *surface = SDL_CreateRGBSurface(0, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); memcpy(surface->pixels, imageData, width*height*4); diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 4d60afcaa3..272fb706dc 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -2,7 +2,7 @@ #include #include "Common/File/VFS/VFS.h" -#include "ui/root.h" +#include "Common/UI/Root.h" #include "Common/CommonTypes.h" #include "Common/Data/Format/RIFF.h" diff --git a/UI/BackgroundAudio.h b/UI/BackgroundAudio.h index a0c154411e..fb572f52a7 100644 --- a/UI/BackgroundAudio.h +++ b/UI/BackgroundAudio.h @@ -4,7 +4,7 @@ #include #include -#include "ui/root.h" +#include "Common/UI/Root.h" class AT3PlusReader; diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 3283d86bf8..c09d92708a 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -1,11 +1,11 @@ #include #include "ppsspp_config.h" -#include "ui/root.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" -#include "ui/ui.h" +#include "Common/UI/Root.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" +#include "Common/UI/UI.h" #include "Common/Data/Text/I18n.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/UI/ChatScreen.h b/UI/ChatScreen.h index ff67d8ce2c..48fe7165f1 100644 --- a/UI/ChatScreen.h +++ b/UI/ChatScreen.h @@ -1,8 +1,7 @@ #pragma once #include "ppsspp_config.h" -#include "file/file_util.h" -#include "ui/ui_screen.h" +#include "Common/UI/UIScreen.h" class ChatMenu : public PopupScreen { public: diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index 672b760df8..f56847bf85 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -18,9 +18,9 @@ #include "Common/System/Display.h" #include "gfx_es2/draw_buffer.h" #include "gfx/texture_atlas.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "Common/Data/Text/I18n.h" #include "Common/Data/Color/RGBAUtil.h" diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index da64c785f2..74320bf165 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -20,11 +20,11 @@ #include #include "gfx/texture_atlas.h" -#include "ui/root.h" -#include "ui/ui.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/Root.h" +#include "Common/UI/UI.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "Common/Log.h" #include "Common/Data/Color/RGBAUtil.h" diff --git a/UI/ControlMappingScreen.h b/UI/ControlMappingScreen.h index 3f548c2f66..d9f7776fd4 100644 --- a/UI/ControlMappingScreen.h +++ b/UI/ControlMappingScreen.h @@ -22,8 +22,8 @@ #include #include -#include "ui/view.h" -#include "ui/ui_screen.h" +#include "Common/UI/View.h" +#include "Common/UI/UIScreen.h" #include "Common/Data/Text/I18n.h" #include "UI/MiscScreens.h" diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index c92f7b838d..a13ef059d8 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -16,11 +16,11 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "ext/xxhash.h" -#include "ui/ui.h" +#include "Common/UI/UI.h" #include "Common/Data/Text/I18n.h" #include "Common/Data/Encoding/Utf8.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Common/System/System.h" #include "Core/Core.h" diff --git a/UI/CwCheatScreen.h b/UI/CwCheatScreen.h index c1bc827c68..c36704ef20 100644 --- a/UI/CwCheatScreen.h +++ b/UI/CwCheatScreen.h @@ -18,9 +18,9 @@ #include #include -#include "ui/view.h" -#include "ui/ui_screen.h" -#include "ui/ui_context.h" +#include "Common/UI/View.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/Context.h" #include "UI/MiscScreens.h" struct CheatFileInfo; diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 530b0d31ed..6e50950000 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -23,10 +23,10 @@ #include "Common/System/System.h" #include "gfx_es2/gpu_features.h" #include "Common/Data/Text/I18n.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" -#include "ui/ui.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" +#include "Common/UI/UI.h" #include "Common/Profiler/Profiler.h" #include "Common/LogManager.h" diff --git a/UI/DevScreens.h b/UI/DevScreens.h index 0d32460d4e..28e8c38bda 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -23,9 +23,8 @@ #include #include -#include "file/file_util.h" #include "Common/Data/Text/I18n.h" -#include "ui/ui_screen.h" +#include "Common/UI/UIScreen.h" #include "UI/MiscScreens.h" #include "GPU/Common/ShaderCommon.h" diff --git a/UI/DisplayLayoutEditor.cpp b/UI/DisplayLayoutEditor.cpp index 6c3e6e1f5a..f6556ca39a 100644 --- a/UI/DisplayLayoutEditor.cpp +++ b/UI/DisplayLayoutEditor.cpp @@ -17,7 +17,7 @@ #include -#include "ui/ui_context.h" +#include "Common/UI/Context.h" #include "UI/DisplayLayoutEditor.h" void MultiTouchDisplay::GetContentDimensions(const UIContext &dc, float &w, float &h) const { diff --git a/UI/DisplayLayoutEditor.h b/UI/DisplayLayoutEditor.h index 6cdd7a454d..394762a6a9 100644 --- a/UI/DisplayLayoutEditor.h +++ b/UI/DisplayLayoutEditor.h @@ -19,8 +19,8 @@ #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" class MultiTouchDisplay : public UI::View { public: diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 8694bbd8bb..0c8ddde7cd 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -22,8 +22,8 @@ #include "Common/System/System.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" -#include "ui/ui_context.h" -#include "ui/view.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" #include "Common/Data/Color/RGBAUtil.h" #include "Common/Data/Text/I18n.h" diff --git a/UI/DisplayLayoutScreen.h b/UI/DisplayLayoutScreen.h index 1a38ea706f..9db82c612c 100644 --- a/UI/DisplayLayoutScreen.h +++ b/UI/DisplayLayoutScreen.h @@ -17,8 +17,8 @@ #pragma once -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "MiscScreens.h" #include diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index f6c6cda45e..61042fc14b 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -23,11 +23,11 @@ #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_text.h" -#include "ui/root.h" -#include "ui/ui.h" -#include "ui/ui_context.h" -#include "ui/ui_tween.h" -#include "ui/view.h" +#include "Common/UI/Root.h" +#include "Common/UI/UI.h" +#include "Common/UI/Context.h" +#include "Common/UI/Tween.h" +#include "Common/UI/View.h" #include "Common/Data/Text/I18n.h" #include "Common/Input/InputState.h" diff --git a/UI/EmuScreen.h b/UI/EmuScreen.h index 0f2c33563d..77a072f433 100644 --- a/UI/EmuScreen.h +++ b/UI/EmuScreen.h @@ -22,10 +22,10 @@ #include #include "Common/Input/KeyCodes.h" +#include "Common/UI/Screen.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/Tween.h" #include "Core/KeyMap.h" -#include "ui/screen.h" -#include "ui/ui_screen.h" -#include "ui/ui_tween.h" struct AxisInput; diff --git a/UI/GPUDriverTestScreen.cpp b/UI/GPUDriverTestScreen.cpp index c23517066b..56547cd8b9 100644 --- a/UI/GPUDriverTestScreen.cpp +++ b/UI/GPUDriverTestScreen.cpp @@ -1,6 +1,6 @@ #include "GPUDriverTestScreen.h" #include "Common/Data/Text/I18n.h" -#include "ui/view.h" +#include "Common/UI/View.h" static const std::vector fsDiscard = { {Draw::ShaderLanguage::GLSL_ES_200, diff --git a/UI/GPUDriverTestScreen.h b/UI/GPUDriverTestScreen.h index 0f5de4a8b0..64a20d4c74 100644 --- a/UI/GPUDriverTestScreen.h +++ b/UI/GPUDriverTestScreen.h @@ -1,10 +1,10 @@ #pragma once #include "Common/System/Display.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" -#include "ui/ui.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" +#include "Common/UI/UI.h" #include "Common/LogManager.h" #include "UI/MiscScreens.h" diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index c297ca6125..afcc507e56 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -22,11 +22,10 @@ #include #include -#include "file/file_util.h" #include "thin3d/thin3d.h" #include "Common/Thread/PrioritizedWorkQueue.h" #include "Common/File/VFS/VFS.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/StringUtils.h" #include "Common/TimeUtil.h" #include "Core/FileSystems/ISOFileSystem.h" diff --git a/UI/GameInfoCache.h b/UI/GameInfoCache.h index 565331c14a..8563d111f9 100644 --- a/UI/GameInfoCache.h +++ b/UI/GameInfoCache.h @@ -23,7 +23,6 @@ #include #include -#include "file/file_util.h" #include "Core/ELF/ParamSFO.h" #include "UI/TextureUtil.h" diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index 9404173d19..a4eecc132f 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -20,13 +20,13 @@ #include "ppsspp_config.h" #include "gfx_es2/draw_buffer.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "Common/Data/Text/I18n.h" #include "Common/Data/Encoding/Utf8.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/System/System.h" #include "Common/System/NativeApp.h" #include "Core/Host.h" diff --git a/UI/GameScreen.h b/UI/GameScreen.h index b68c7f28c2..2e7fa3f596 100644 --- a/UI/GameScreen.h +++ b/UI/GameScreen.h @@ -20,7 +20,7 @@ #include #include "UI/MiscScreens.h" -#include "ui/ui_screen.h" +#include "Common/UI/UIScreen.h" // Game screen: Allows you to start a game, delete saves, delete the game, // set game specific settings, etc. diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 8788263d2b..3a90ec8b6f 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -19,13 +19,13 @@ #include -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_buffer.h" -#include "ui/root.h" -#include "ui/view.h" -#include "ui/viewgroup.h" -#include "ui/ui_context.h" +#include "Common/UI/Root.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" +#include "Common/UI/Context.h" #include "Common/System/Display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres #include "Common/System/System.h" @@ -51,7 +51,7 @@ #include "UI/ComboKeyMappingScreen.h" #include "UI/GPUDriverTestScreen.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/OSVersion.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index 00697f6f86..8eae42a72f 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -21,7 +21,7 @@ #include #include #include -#include "ui/ui_screen.h" +#include "Common/UI/UIScreen.h" #include "UI/MiscScreens.h" class SettingInfoMessage; diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 8337c83d1c..add209e3f2 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -22,7 +22,7 @@ #include "Common/System/System.h" #include "gfx/texture_atlas.h" #include "Common/Math/math_util.h" -#include "ui/ui_context.h" +#include "Common/UI/Context.h" #include "Common/Log.h" #include "Common/TimeUtil.h" diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index fd2fe9c7d3..8b3dd53809 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -20,8 +20,8 @@ #include "Common/Input/InputState.h" #include "gfx_es2/draw_buffer.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "Core/CoreParameter.h" class GamepadView : public UI::View { diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index a8fc7f5038..0f5f79551d 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -15,13 +15,12 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/Data/Text/I18n.h" -#include "ui/ui.h" -#include "ui/view.h" -#include "ui/viewgroup.h" -#include "file/file_util.h" +#include "Common/UI/UI.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "Common/StringUtils.h" +#include "Common/Data/Text/I18n.h" #include "Core/Util/GameManager.h" #include "UI/InstallZipScreen.h" #include "UI/MainScreen.h" diff --git a/UI/InstallZipScreen.h b/UI/InstallZipScreen.h index e8015fdfa5..e8e8d05701 100644 --- a/UI/InstallZipScreen.h +++ b/UI/InstallZipScreen.h @@ -19,8 +19,8 @@ #include -#include "ui/view.h" -#include "ui/ui_screen.h" +#include "Common/UI/View.h" +#include "Common/UI/UIScreen.h" #include "UI/MiscScreens.h" diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 6439628258..a46a28e153 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -24,16 +24,16 @@ #include "Common/System/System.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" -#include "ui/root.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/Root.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "Common/Data/Color/RGBAUtil.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/File/PathBrowser.h" #include "Common/Math/curves.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" #include "Core/System.h" diff --git a/UI/MainScreen.h b/UI/MainScreen.h index a4aed944d4..e1297cb8d8 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -19,8 +19,8 @@ #include -#include "ui/ui_screen.h" -#include "ui/viewgroup.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/ViewGroup.h" #include "UI/MiscScreens.h" #include "Common/File/PathBrowser.h" diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index b19f59bdaf..56007c863b 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -21,10 +21,10 @@ #include #include "gfx_es2/draw_buffer.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" -#include "ui/ui.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" +#include "Common/UI/UI.h" #include "Common/System/Display.h" #include "Common/System/NativeApp.h" @@ -36,7 +36,7 @@ #include "Common/Data/Text/I18n.h" #include "Common/Data/Random/Rng.h" #include "Common/TimeUtil.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Core/Config.h" #include "Core/Host.h" #include "Core/System.h" diff --git a/UI/MiscScreens.h b/UI/MiscScreens.h index d920fc77fe..e62363823f 100644 --- a/UI/MiscScreens.h +++ b/UI/MiscScreens.h @@ -22,8 +22,8 @@ #include #include -#include "file/file_util.h" -#include "ui/ui_screen.h" +#include "Common/UI/UIScreen.h" +#include "Common/File/DirListing.h" struct ShaderInfo; struct TextureShaderInfo; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index f0da507d1a..133ca5a7ab 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -43,16 +43,16 @@ #include "Windows/CaptureDevice.h" #endif -#include "net/http_client.h" -#include "net/resolve.h" +#include "Common/Net/HTTPClient.h" +#include "Common/Net/Resolve.h" #include "gfx/texture_atlas.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/gpu_features.h" #include "thin3d/thin3d.h" -#include "ui/ui.h" -#include "ui/screen.h" -#include "ui/ui_context.h" -#include "ui/view.h" +#include "Common/UI/UI.h" +#include "Common/UI/Screen.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" #include "android/jni/app-android.h" #include "Common/System/Display.h" @@ -68,7 +68,7 @@ #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" #include "Common/CPUDetect.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" #include "Common/LogManager.h" diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index 38f8549e7b..17dc3222b4 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -4,7 +4,7 @@ #include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" -#include "ui/ui_context.h" +#include "Common/UI/Context.h" #include "Common/TimeUtil.h" diff --git a/UI/OnScreenDisplay.h b/UI/OnScreenDisplay.h index 381fcf274e..6cb83aa877 100644 --- a/UI/OnScreenDisplay.h +++ b/UI/OnScreenDisplay.h @@ -5,7 +5,7 @@ #include #include "Common/Math/geom2d.h" -#include "ui/view.h" +#include "Common/UI/View.h" class DrawBuffer; diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 620e5c1fc1..92e5f178e4 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -19,10 +19,10 @@ #include #include "gfx_es2/draw_buffer.h" -#include "ui/view.h" -#include "ui/viewgroup.h" -#include "ui/ui_context.h" -#include "ui/ui_screen.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" +#include "Common/UI/Context.h" +#include "Common/UI/UIScreen.h" #include "thin3d/thin3d.h" #include "Common/Data/Text/I18n.h" diff --git a/UI/PauseScreen.h b/UI/PauseScreen.h index 8e951ffaf0..69c84d53af 100644 --- a/UI/PauseScreen.h +++ b/UI/PauseScreen.h @@ -20,8 +20,8 @@ #include #include -#include "ui/ui_screen.h" -#include "ui/viewgroup.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/ViewGroup.h" #include "UI/MiscScreens.h" #include "UI/TextureUtil.h" diff --git a/UI/ProfilerDraw.cpp b/UI/ProfilerDraw.cpp index 8b8ce6838e..95792f3800 100644 --- a/UI/ProfilerDraw.cpp +++ b/UI/ProfilerDraw.cpp @@ -19,8 +19,8 @@ #include #include "gfx_es2/draw_buffer.h" -#include "ui/ui_context.h" -#include "ui/view.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" #include "Common/Profiler/Profiler.h" static const uint32_t nice_colors[] = { diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 0e6ae604c9..a4663399cb 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -27,9 +27,9 @@ // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" -#include "net/http_client.h" -#include "net/resolve.h" -#include "net/url.h" +#include "Common/Net/HTTPClient.h" +#include "Common/Net/Resolve.h" +#include "Common/Net/URL.h" #include "Common/File/PathBrowser.h" #include "Common/Data/Format/JSONReader.h" diff --git a/UI/RemoteISOScreen.h b/UI/RemoteISOScreen.h index a294969259..7eab2270e0 100644 --- a/UI/RemoteISOScreen.h +++ b/UI/RemoteISOScreen.h @@ -20,8 +20,8 @@ #include #include -#include "ui/ui_screen.h" -#include "ui/viewgroup.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/ViewGroup.h" #include "UI/MiscScreens.h" #include "UI/MainScreen.h" diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index 480ad5a9f6..9842549f1c 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -20,12 +20,12 @@ // TODO: For text align flags, probably shouldn't be in gfx_es2/... #include "gfx_es2/draw_buffer.h" #include "thin3d/thin3d.h" -#include "ui/ui_context.h" +#include "Common/UI/Context.h" #include "UI/PauseScreen.h" #include "UI/ReportScreen.h" #include "Common/Data/Text/I18n.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Common/StringUtils.h" #include "Common/System/Display.h" diff --git a/UI/ReportScreen.h b/UI/ReportScreen.h index e3992170ac..b77f8a082f 100644 --- a/UI/ReportScreen.h +++ b/UI/ReportScreen.h @@ -19,8 +19,8 @@ #include -#include "ui/ui_screen.h" -#include "ui/viewgroup.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/ViewGroup.h" #include "UI/MiscScreens.h" enum class ReportingOverallScore : int { diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 0069f73ae8..41bd742893 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -24,15 +24,15 @@ #include "Common/Math/curves.h" #include "Common/Thread/PrioritizedWorkQueue.h" #include "Common/Data/Encoding/Utf8.h" -#include "ui/ui_context.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/Context.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "UI/SavedataScreen.h" #include "UI/MainScreen.h" #include "UI/GameInfoCache.h" #include "UI/PauseScreen.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" #include "Core/Host.h" diff --git a/UI/SavedataScreen.h b/UI/SavedataScreen.h index 49da370483..9e02f8c9cb 100644 --- a/UI/SavedataScreen.h +++ b/UI/SavedataScreen.h @@ -20,9 +20,9 @@ #include #include -#include "ui/ui_screen.h" -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "UI/MiscScreens.h" diff --git a/UI/Store.cpp b/UI/Store.cpp index 040decc9bc..ceff7c02ec 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -17,9 +17,9 @@ #include -#include "ui/screen.h" -#include "ui/ui_context.h" -#include "ui/viewgroup.h" +#include "Common/UI/Screen.h" +#include "Common/UI/Context.h" +#include "Common/UI/ViewGroup.h" #include "gfx_es2/draw_buffer.h" #include "Common/Common.h" diff --git a/UI/Store.h b/UI/Store.h index c935bcb042..b8cc7aefd0 100644 --- a/UI/Store.h +++ b/UI/Store.h @@ -19,9 +19,9 @@ #include -#include "ui/ui_screen.h" -#include "ui/viewgroup.h" -#include "net/http_client.h" +#include "Common/UI/UIScreen.h" +#include "Common/UI/ViewGroup.h" +#include "Common/Net/HTTPClient.h" #include "UI/MiscScreens.h" diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index c05be29263..b52ea1bcbb 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -1,17 +1,17 @@ #include -#include "Common/Data/Color/RGBAUtil.h" #include "thin3d/thin3d.h" -#include "image/zim_load.h" -#include "image/png_load.h" +#include "ext/jpge/jpgd.h" +#include "Common/UI/View.h" +#include "Common/UI/Context.h" +#include "gfx_es2/draw_buffer.h" + +#include "Common/Data/Color/RGBAUtil.h" +#include "Common/Data/Format/ZIMLoad.h" +#include "Common/Data/Format/PNGLoad.h" #include "Common/Math/math_util.h" #include "Common/Math/curves.h" #include "Common/File/VFS/VFS.h" -#include "ext/jpge/jpgd.h" -#include "ui/view.h" -#include "ui/ui_context.h" -#include "gfx_es2/draw_buffer.h" - #include "Common/Log.h" #include "Common/TimeUtil.h" #include "UI/TextureUtil.h" @@ -63,7 +63,7 @@ static bool LoadTextureLevels(const uint8_t *data, size_t size, ImageFileType ty break; case PNG: - if (1 == pngLoadPtr((const unsigned char *)data, size, &width[0], &height[0], &image[0], false)) { + if (1 == pngLoadPtr((const unsigned char *)data, size, &width[0], &height[0], &image[0])) { *num_levels = 1; *fmt = Draw::DataFormat::R8G8B8A8_UNORM; if (!image[0]) { diff --git a/UI/TextureUtil.h b/UI/TextureUtil.h index d5ebca8a5c..3ed46f71fd 100644 --- a/UI/TextureUtil.h +++ b/UI/TextureUtil.h @@ -3,7 +3,7 @@ #include #include "thin3d/thin3d.h" -#include "ui/view.h" +#include "Common/UI/View.h" enum ImageFileType { PNG, diff --git a/UI/TiltAnalogSettingsScreen.h b/UI/TiltAnalogSettingsScreen.h index 172675c2c6..41692bb46f 100644 --- a/UI/TiltAnalogSettingsScreen.h +++ b/UI/TiltAnalogSettingsScreen.h @@ -19,7 +19,7 @@ #include -#include "ui/view.h" +#include "Common/UI/View.h" #include "MiscScreens.h" class TiltAnalogSettingsScreen : public UIDialogScreenWithBackground { diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index fd06719aad..c2d5740a21 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -22,7 +22,7 @@ #include "gfx_es2/draw_buffer.h" #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" -#include "ui/ui_context.h" +#include "Common/UI/Context.h" #include "Common/Common.h" #include "Common/Log.h" diff --git a/UI/TouchControlLayoutScreen.h b/UI/TouchControlLayoutScreen.h index c21c24116d..89305ab7d6 100644 --- a/UI/TouchControlLayoutScreen.h +++ b/UI/TouchControlLayoutScreen.h @@ -20,8 +20,8 @@ #include #include -#include "ui/view.h" -#include "ui/viewgroup.h" +#include "Common/UI/View.h" +#include "Common/UI/ViewGroup.h" #include "MiscScreens.h" class ControlLayoutView; diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index d1b6b551bc..b7440d5ba5 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -203,7 +203,7 @@ false true pch.h - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotUsing @@ -217,7 +217,7 @@ false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h NotUsing @@ -232,7 +232,7 @@ false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h NotUsing @@ -248,7 +248,7 @@ false true pch.h - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) NotUsing @@ -263,7 +263,7 @@ false true pch.h - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) NotUsing @@ -277,7 +277,7 @@ false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h NotUsing @@ -292,7 +292,7 @@ false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h NotUsing @@ -307,7 +307,7 @@ false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h NotUsing @@ -322,7 +322,7 @@ false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h NotUsing @@ -338,7 +338,7 @@ false true pch.h - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotUsing @@ -352,7 +352,7 @@ false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h NotUsing @@ -367,7 +367,7 @@ false true - ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h NotUsing @@ -398,13 +398,19 @@ + + + + + + @@ -419,6 +425,13 @@ + + + + + + + @@ -440,7 +453,6 @@ - @@ -465,6 +477,14 @@ + + + + + + + + @@ -490,12 +510,18 @@ + + + + + + @@ -509,6 +535,13 @@ + + + + + + + @@ -519,7 +552,6 @@ - @@ -541,6 +573,14 @@ + + + + + + + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 22b87aec1e..725a3526f1 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -64,6 +64,12 @@ {661f7d9d-5922-48d6-88ea-2f24bb57419f} + + {c0424523-60b1-4886-a15d-68eda99ff01b} + + + {8e12d2c0-157a-4625-a970-665e1ec9a425} + @@ -76,7 +82,6 @@ - @@ -252,6 +257,69 @@ System + + File + + + File + + + File + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Data\Format + + + Data\Format + + + Data\Format + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + @@ -273,7 +341,6 @@ - @@ -452,6 +519,69 @@ System + + File + + + File + + + File + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Data\Format + + + Data\Format + + + Data\Format + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + + + UI + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index ced0674db9..3e504d2853 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -204,7 +204,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -219,7 +219,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -234,7 +234,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -249,7 +249,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -264,7 +264,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -279,7 +279,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -294,7 +294,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -309,7 +309,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -324,7 +324,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) @@ -339,7 +339,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -354,7 +354,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -369,7 +369,7 @@ false true pch.h - ../..;../../ext;../..;../../ext/native;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) + ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -379,61 +379,23 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create Create diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 9cade1425a..4257fc1baa 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -7,18 +7,6 @@ {8a254b8c-46f2-4ff1-bc53-deea7e614276} - - {244992ec-8dcf-49f4-b63c-cae6ac437c58} - - - {9d02a269-6cdd-4726-ab58-34c012e37d37} - - - {d8c0dd74-7ad2-440a-a3e0-5dbf3435a2fc} - - - {96ac6deb-ad00-4ee4-9f0d-515d78d1886b} - @@ -34,69 +22,12 @@ gfx - - file - - - file - - - ui - - - ui - - - ui - - - ui - - - ui - - - ui - - - ui - - - ui - - - net - - - net - - - net - - - net - - - net - - - net - gfx - - image - - - image - gfx - - net - gfx @@ -113,69 +44,12 @@ gfx - - file - - - file - - - ui - - - ui - - - ui - - - ui - - - ui - - - ui - - - ui - - - ui - - - net - - - net - - - net - - - net - - - net - - - net - gfx - - image - - - image - gfx - - net - gfx diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 54c9b1a73e..30eb175017 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -3,9 +3,9 @@ #include -#include "file/file_util.h" -#include "net/http_client.h" -#include "net/resolve.h" +#include "Common/File/FileUtil.h" +#include "Common/Net/HTTPClient.h" +#include "Common/Net/Resolve.h" #include "thin3d/thin3d_create.h" #include "Common/Common.h" @@ -15,7 +15,7 @@ #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/DirectXHelper.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Common/LogManager.h" #include "Common/TimeUtil.h" diff --git a/UWP/StorageFileLoader.cpp b/UWP/StorageFileLoader.cpp index 2797e9fe2c..3dfced89de 100644 --- a/UWP/StorageFileLoader.cpp +++ b/UWP/StorageFileLoader.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "ppltasks.h" -#include "file/file_util.h" +#include "Common/File/FileUtil.h" +#include "Common/File/DirListing.h" #include "Common/Thread/ThreadUtil.h" #include "StorageFileLoader.h" #include "Common/Log.h" diff --git a/UWP/UWPHost.cpp b/UWP/UWPHost.cpp index be3f93d826..d16b730192 100644 --- a/UWP/UWPHost.cpp +++ b/UWP/UWPHost.cpp @@ -19,7 +19,7 @@ #include -#include "file/file_util.h" +#include "Common/File/DirListing.h" #include "Common/System/NativeApp.h" #include "Common/System/System.h" #include "Common/Input/InputState.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 6cbf136fc5..56d3fb720b 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -13,7 +13,7 @@ #include "Common/Data/Encoding/Utf8.h" #include "Common/System/System.h" #include "Common/System/NativeApp.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Common/LogManager.h" #include "Common/ConsoleListener.h" diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index d337085dbd..210344033f 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -34,12 +34,12 @@ // native stuff #include "Common/System/Display.h" #include "Common/System/NativeApp.h" -#include "file/file_util.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "Common/Data/Encoding/Utf8.h" - +#include "Common/File/DirListing.h" #include "Common/StringUtils.h" + #include "Core/Core.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index 6043e099ca..1143938f8c 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -21,7 +21,7 @@ #include #include "Common/CommonWindows.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/OSVersion.h" #include "Common/Vulkan/VulkanLoader.h" #include "ppsspp_config.h" @@ -40,7 +40,7 @@ #include "Common/Profiler/Profiler.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Data/Encoding/Utf8.h" -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 2277a40f41..69bae6d39c 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -102,15 +102,6 @@ ARCH_FILES := \ endif NATIVE_FILES :=\ - $(SRC)/ext/native/file/fd_util.cpp \ - $(SRC)/ext/native/file/file_util.cpp \ - $(SRC)/ext/native/net/http_client.cpp \ - $(SRC)/ext/native/net/http_server.cpp \ - $(SRC)/ext/native/net/http_headers.cpp \ - $(SRC)/ext/native/net/resolve.cpp \ - $(SRC)/ext/native/net/sinks.cpp \ - $(SRC)/ext/native/net/url.cpp \ - $(SRC)/ext/native/net/websocket_server.cpp \ $(SRC)/ext/native/gfx_es2/glsl_program.cpp \ $(SRC)/ext/native/gfx_es2/gpu_features.cpp \ $(SRC)/ext/native/gfx_es2/gl3stub.c \ @@ -119,9 +110,6 @@ NATIVE_FILES :=\ $(SRC)/ext/native/gfx_es2/draw_text_android.cpp.arm \ $(SRC)/ext/native/gfx/gl_debug_log.cpp \ $(SRC)/ext/native/gfx/texture_atlas.cpp \ - $(SRC)/ext/native/image/zim_load.cpp \ - $(SRC)/ext/native/image/zim_save.cpp \ - $(SRC)/ext/native/image/png_load.cpp \ $(SRC)/ext/native/thin3d/thin3d.cpp \ $(SRC)/ext/native/thin3d/thin3d_gl.cpp \ $(SRC)/ext/native/thin3d/thin3d_vulkan.cpp \ @@ -129,15 +117,7 @@ NATIVE_FILES :=\ $(SRC)/ext/native/thin3d/GLQueueRunner.cpp \ $(SRC)/ext/native/thin3d/VulkanRenderManager.cpp \ $(SRC)/ext/native/thin3d/VulkanQueueRunner.cpp \ - $(SRC)/ext/native/thin3d/DataFormatGL.cpp \ - $(SRC)/ext/native/ui/root.cpp \ - $(SRC)/ext/native/ui/view.cpp \ - $(SRC)/ext/native/ui/viewgroup.cpp \ - $(SRC)/ext/native/ui/ui.cpp \ - $(SRC)/ext/native/ui/ui_screen.cpp \ - $(SRC)/ext/native/ui/ui_tween.cpp \ - $(SRC)/ext/native/ui/ui_context.cpp \ - $(SRC)/ext/native/ui/screen.cpp + $(SRC)/ext/native/thin3d/DataFormatGL.cpp EGL_FILES := \ $(SRC)/Common/GL/GLInterface/EGL.cpp \ @@ -261,6 +241,12 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Data/Format/IniFile.cpp \ $(SRC)/Common/Data/Format/JSONReader.cpp \ $(SRC)/Common/Data/Format/JSONWriter.cpp \ + $(SRC)/Common/Data/Format/PNGLoad.cpp \ + $(SRC)/Common/Data/Format/PNGLoad.h \ + $(SRC)/Common/Data/Format/ZIMLoad.cpp \ + $(SRC)/Common/Data/Format/ZIMLoad.h \ + $(SRC)/Common/Data/Format/ZIMSave.cpp \ + $(SRC)/Common/Data/Format/ZIMSave.h \ $(SRC)/Common/Data/Hash/Hash.cpp \ $(SRC)/Common/Data/Text/I18n.cpp \ $(SRC)/Common/Data/Text/Parsers.cpp \ @@ -269,6 +255,11 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/File/VFS/AssetReader.cpp \ $(SRC)/Common/File/DiskFree.cpp \ $(SRC)/Common/File/PathBrowser.cpp \ + $(SRC)/Common/File/FileUtil.cpp \ + $(SRC)/Common/File/DirListing.cpp \ + $(SRC)/Common/File/FileDescriptor.cpp \ + $(SRC)/Common/Input/GestureDetector.cpp \ + $(SRC)/Common/Input/InputState.cpp \ $(SRC)/Common/Math/fast/fast_math.c \ $(SRC)/Common/Math/fast/fast_matrix.c \ $(SRC)/Common/Math/math_util.cpp \ @@ -276,14 +267,27 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/Math/expression_parser.cpp \ $(SRC)/Common/Math/lin/vec3.cpp.arm \ $(SRC)/Common/Math/lin/matrix4x4.cpp.arm \ + $(SRC)/Common/Net/HTTPClient.cpp \ + $(SRC)/Common/Net/HTTPHeaders.cpp \ + $(SRC)/Common/Net/HTTPServer.cpp \ + $(SRC)/Common/Net/Resolve.cpp \ + $(SRC)/Common/Net/Sinks.cpp \ + $(SRC)/Common/Net/URL.cpp \ + $(SRC)/Common/Net/WebsocketServer.cpp \ $(SRC)/Common/Profiler/Profiler.cpp \ $(SRC)/Common/System/Display.cpp \ $(SRC)/Common/Thread/Executor.cpp \ $(SRC)/Common/Thread/PrioritizedWorkQueue.cpp \ $(SRC)/Common/Thread/ThreadPool.cpp \ $(SRC)/Common/Thread/ThreadUtil.cpp \ - $(SRC)/Common/Input/GestureDetector.cpp \ - $(SRC)/Common/Input/InputState.cpp \ + $(SRC)/Common/UI/Root.cpp \ + $(SRC)/Common/UI/Screen.cpp \ + $(SRC)/Common/UI/UI.cpp \ + $(SRC)/Common/UI/Context.cpp \ + $(SRC)/Common/UI/UIScreen.cpp \ + $(SRC)/Common/UI/Tween.cpp \ + $(SRC)/Common/UI/View.cpp \ + $(SRC)/Common/UI/ViewGroup.cpp \ $(SRC)/Common/Serialize/Serializer.cpp \ $(SRC)/Common/ColorConv.cpp \ $(SRC)/Common/ExceptionHandlerSetup.cpp \ @@ -294,7 +298,6 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/MemArenaWin32.cpp \ $(SRC)/Common/MemArenaPosix.cpp \ $(SRC)/Common/MemoryUtil.cpp \ - $(SRC)/Common/FileUtil.cpp \ $(SRC)/Common/StringUtils.cpp \ $(SRC)/Common/SysError.cpp \ $(SRC)/Common/ThreadPools.cpp \ diff --git a/android/jni/TestRunner.cpp b/android/jni/TestRunner.cpp index 8bc9809d7b..e5489fd0c1 100644 --- a/android/jni/TestRunner.cpp +++ b/android/jni/TestRunner.cpp @@ -28,7 +28,7 @@ #include "ppsspp_config.h" #include "Common/System/Display.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Core/Core.h" #include "Core/System.h" diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index e81381aa6a..3e6c859210 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -49,7 +49,7 @@ struct JNIEnv {}; #define JNI_VERSION_1_6 16 #endif -#include "net/resolve.h" +#include "Common/Net/Resolve.h" #include "android/jni/AndroidAudio.h" #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" diff --git a/ext/native/gfx_es2/draw_text.h b/ext/native/gfx_es2/draw_text.h index 7ee06aad5f..ed582845b9 100644 --- a/ext/native/gfx_es2/draw_text.h +++ b/ext/native/gfx_es2/draw_text.h @@ -21,10 +21,6 @@ namespace Draw { class Texture; } -#ifdef USING_QT_UI -#include -#endif - struct TextStringEntry { Draw::Texture *texture; int width; diff --git a/ext/native/gfx_es2/draw_text_qt.h b/ext/native/gfx_es2/draw_text_qt.h index c75cd51ca0..e8c01cd118 100644 --- a/ext/native/gfx_es2/draw_text_qt.h +++ b/ext/native/gfx_es2/draw_text_qt.h @@ -7,6 +7,8 @@ #if defined(USING_QT_UI) +#include + class TextDrawerQt : public TextDrawer { public: TextDrawerQt(Draw::DrawContext *draw); diff --git a/ext/native/gfx_es2/glsl_program.cpp b/ext/native/gfx_es2/glsl_program.cpp index 0578cd2cfe..a0bc2a376e 100644 --- a/ext/native/gfx_es2/glsl_program.cpp +++ b/ext/native/gfx_es2/glsl_program.cpp @@ -1,11 +1,11 @@ #include -#include -#include +#include +#include #include #include "Common/File/VFS/VFS.h" -//#include "file/zip_read.h" +#include "Common/File/FileUtil.h" #include "glsl_program.h" #include "Common/Log.h" diff --git a/ext/native/image/png_load.cpp b/ext/native/image/png_load.cpp deleted file mode 100644 index b8a273c17e..0000000000 --- a/ext/native/image/png_load.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include - -#ifdef USING_QT_UI -#include -#else -#include -#endif - -#include "png_load.h" - -#include "Common/Log.h" - -// *image_data_ptr should be deleted with free() -// return value of 1 == success. -int pngLoad(const char *file, int *pwidth, int *pheight, unsigned char **image_data_ptr, bool flip) { -#ifdef USING_QT_UI - QImage image(file, "PNG"); - if (image.isNull()) { - ERROR_LOG(IO, "pngLoad: Error loading image %s", file); - return 0; - } - - if (flip) - image = image.mirrored(); - *pwidth = image.width(); - *pheight = image.height(); - image = image.convertToFormat(QImage::Format_ARGB32); - *image_data_ptr = (unsigned char *)malloc(image.byteCount()); - uint32_t *src = (uint32_t*) image.bits(); - uint32_t *dest = (uint32_t*) *image_data_ptr; - // Qt4 does not support RGBA - for (size_t sz = 0; sz < (size_t)image.byteCount(); sz+=4, ++src, ++dest) { - const uint32_t v = *src; - *dest = (v & 0xFF00FF00) | ((v & 0xFF) << 16) | (( v >> 16 ) & 0xFF); // ARGB -> RGBA - } -#else - if (flip) - ERROR_LOG(IO, "pngLoad: flip flag not supported, image will be loaded upside down"); - png_image png; - memset(&png, 0, sizeof(png)); - png.version = PNG_IMAGE_VERSION; - - png_image_begin_read_from_file(&png, file); - - if (PNG_IMAGE_FAILED(png)) - { - ERROR_LOG(IO, "pngLoad: %s", png.message); - return 0; - } - *pwidth = png.width; - *pheight = png.height; - png.format = PNG_FORMAT_RGBA; - - int stride = PNG_IMAGE_ROW_STRIDE(png); - *image_data_ptr = (unsigned char *)malloc(PNG_IMAGE_SIZE(png)); - png_image_finish_read(&png, NULL, *image_data_ptr, stride, NULL); -#endif - - return 1; -} - -int pngLoadPtr(const unsigned char *input_ptr, size_t input_len, int *pwidth, int *pheight, unsigned char **image_data_ptr, - bool flip) { -#ifdef USING_QT_UI - QImage image; - if (!image.loadFromData(input_ptr, input_len, "PNG")) { - ERROR_LOG(IO, "pngLoad: Error loading image"); - return 0; - } - if (flip) - image = image.mirrored(); - *pwidth = image.width(); - *pheight = image.height(); - image = image.convertToFormat(QImage::Format_ARGB32); - *image_data_ptr = (unsigned char *)malloc(image.byteCount()); - uint32_t *src = (uint32_t*) image.bits(); - uint32_t *dest = (uint32_t*) *image_data_ptr; - // Qt4 does not support RGBA - for (size_t sz = 0; sz < (size_t)image.byteCount(); sz+=4, ++src, ++dest) { - const uint32_t v = *src; - *dest = (v & 0xFF00FF00) | ((v & 0xFF) << 16) | (( v >> 16 ) & 0xFF); // convert it! - } -#else - if (flip) - ERROR_LOG(IO, "pngLoad: flip flag not supported, image will be loaded upside down"); - png_image png{}; - png.version = PNG_IMAGE_VERSION; - - png_image_begin_read_from_memory(&png, input_ptr, input_len); - - if (PNG_IMAGE_FAILED(png)) { - ERROR_LOG(IO, "pngLoad: %s", png.message); - return 0; - } - *pwidth = png.width; - *pheight = png.height; - png.format = PNG_FORMAT_RGBA; - - int stride = PNG_IMAGE_ROW_STRIDE(png); - - size_t size = PNG_IMAGE_SIZE(png); - if (!size) { - ERROR_LOG(IO, "pngLoad: empty image"); - return 0; - } - - *image_data_ptr = (unsigned char *)malloc(size); - png_image_finish_read(&png, NULL, *image_data_ptr, stride, NULL); -#endif - - return 1; -} diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index f708266706..dd6381f71e 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -156,7 +156,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) true false false @@ -178,7 +178,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) true false false @@ -201,7 +201,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) true false false @@ -224,7 +224,7 @@ Level3 _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) true false false @@ -251,7 +251,7 @@ true true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) StreamingSIMDExtensions2 Precise true @@ -279,7 +279,7 @@ true true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) NotSet Precise true @@ -309,7 +309,7 @@ true true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) Precise true false @@ -338,7 +338,7 @@ true true _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\libpng17;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) + ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) NotSet Precise true @@ -360,12 +360,9 @@ - - - @@ -375,7 +372,6 @@ - @@ -385,34 +381,15 @@ - - - - - - - - - - - - - - - - - - - @@ -421,7 +398,6 @@ - @@ -430,7 +406,6 @@ - @@ -445,27 +420,11 @@ - - - - - - - - - - - - - - - - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index b670b9fdb1..9befbb1243 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -1,7 +1,6 @@  - tools @@ -10,15 +9,6 @@ gfx - - image - - - image - - - image - gfx @@ -28,42 +18,9 @@ gfx - - file - - - ui - - - net - - - file - - - net - - - ui - - - ui - gfx - - ui - - - ui - - - net - - - ui - gfx @@ -76,18 +33,9 @@ thin3d - - net - - - net - gfx - - net - gfx @@ -115,9 +63,6 @@ thin3d - - ui - thin3d @@ -130,15 +75,9 @@ thin3d - - net - thin3d - - ui - gfx @@ -147,15 +86,6 @@ gfx - - image - - - image - - - image - gfx @@ -165,42 +95,9 @@ gfx - - file - - - ui - - - net - - - file - - - net - - - ui - - - ui - gfx - - ui - - - ui - - - net - - - ui - gfx @@ -219,18 +116,9 @@ thin3d - - net - - - net - thin3d - - net - thin3d @@ -258,9 +146,6 @@ thin3d - - ui - thin3d @@ -270,15 +155,9 @@ thin3d - - net - thin3d - - ui - gfx @@ -287,18 +166,6 @@ {9da89505-72a1-40e6-86e5-705372db1608} - - {828bddaf-63e5-4311-985b-bf377f86ff00} - - - {49afd06e-eb44-41ac-b038-e109e444a834} - - - {d738c2d1-749d-4b60-b98f-f3da0bbbf40c} - - - {6a548b3d-3a4c-4114-aa2f-0b42bf7bf2ce} - {4515306f-4664-46bf-a89b-abfec5520a15} diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 2060f2d978..5d691c64ca 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -21,7 +21,6 @@ #include #include "Common/System/Display.h" -#include "image/zim_load.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "thin3d/thin3d.h" diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp index 7207fcc093..079c994cf3 100644 --- a/ext/native/tools/atlastool.cpp +++ b/ext/native/tools/atlastool.cpp @@ -31,8 +31,8 @@ #include "gfx/texture_atlas.h" -#include "image/png_load.h" -#include "image/zim_save.h" +#include "Common/Data/Format/PNGLoad.h" +#include "Common/Data/Format/ZIMSave.h" #include "kanjifilter.h" // extracted only JIS Kanji on the CJK Unified Ideographs of UCS2. Cannot reading BlockAllocator. (texture size over) @@ -152,7 +152,7 @@ struct Image { bool LoadPNG(const char *png_name) { unsigned char *img_data; int w, h; - if (1 != pngLoad(png_name, &w, &h, &img_data, false)) { + if (1 != pngLoad(png_name, &w, &h, &img_data)) { printf("Failed to load %s\n", png_name); exit(1); return false; diff --git a/ext/native/tools/zimtool.cpp b/ext/native/tools/zimtool.cpp index 9e3fe3b813..88f9e9da16 100644 --- a/ext/native/tools/zimtool.cpp +++ b/ext/native/tools/zimtool.cpp @@ -2,16 +2,14 @@ #include #include -#include "image/png_load.h" -#include "image/zim_load.h" -#include "image/zim_save.h" +#include "Common/Data/Format/PNGLoad.h" +#include "Common/Data/Format/ZIMLoad.h" +#include "Common/Data/Format/ZIMSave.h" #include "Common/Common.h" char magic[5] = "ZIMG"; -bool FLAGS_flip = false; - const char *format_strings[4] = { "8888", "4444", "565", "ETC1" }; int formats[3] = { ZIM_RGBA8888, ZIM_RGBA4444, ZIM_RGB565 }; @@ -82,7 +80,7 @@ int main(int argc, char **argv) { uint8_t *image_data; int width, height; - if (1 != pngLoad(FLAGS_infile, &width, &height, &image_data, FLAGS_flip)) { + if (1 != pngLoad(FLAGS_infile, &width, &height, &image_data)) { fprintf(stderr, "Input not a PNG file\n"); printusage(); return 1; diff --git a/headless/Compare.cpp b/headless/Compare.cpp index ba35b93c90..8036090001 100644 --- a/headless/Compare.cpp +++ b/headless/Compare.cpp @@ -16,10 +16,9 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "headless/Compare.h" -#include "file/file_util.h" #include "Common/ColorConv.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Core/Host.h" #include "GPU/GPUState.h" diff --git a/headless/Headless.cpp b/headless/Headless.cpp index bd6735e4fe..299cdd2cf0 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -15,7 +15,7 @@ #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/GraphicsContext.h" #include "Common/TimeUtil.h" #include "Core/Config.h" diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index f3652e03af..8e5799dd03 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -29,7 +29,7 @@ #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/GraphicsContext.h" #include "Common/TimeUtil.h" diff --git a/headless/StubHost.cpp b/headless/StubHost.cpp index a555a07816..1219d42365 100644 --- a/headless/StubHost.cpp +++ b/headless/StubHost.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Core/CoreParameter.h" #include "Core/System.h" diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index 64d22cc57b..2f9d06aa1f 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -26,7 +26,7 @@ #include "Common/CommonWindows.h" #include "Common/Log.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/TimeUtil.h" #include "Core/CoreParameter.h" diff --git a/ios/PPSSPPUIApplication.mm b/ios/PPSSPPUIApplication.mm index eb66aa202b..a9075cd6ac 100644 --- a/ios/PPSSPPUIApplication.mm +++ b/ios/PPSSPPUIApplication.mm @@ -19,8 +19,8 @@ #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" #include "Common/Input/InputState.h" -#include "net/resolve.h" -#include "ui/screen.h" +#include "Common/Net/Resolve.h" +#include "Common/UI/Screen.h" #include "thin3d/thin3d.h" #include "Common/Input/KeyCodes.h" #include "gfx_es2/gpu_features.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index a6be65bedd..82f4ddf00a 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -12,8 +12,8 @@ #import #include -#include "net/resolve.h" -#include "ui/screen.h" +#include "Common/Net/Resolve.h" +#include "Common/UI/Screen.h" #include "thin3d/thin3d.h" #include "thin3d/thin3d_create.h" #include "thin3d/GLRenderManager.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index d0a534c6c9..ff977d5000 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -152,6 +152,12 @@ SOURCES_CXX += \ $(COMMONDIR)/Data/Format/IniFile.cpp \ $(COMMONDIR)/Data/Format/JSONReader.cpp \ $(COMMONDIR)/Data/Format/JSONWriter.cpp \ + $(COMMONDIR)/Data/Format/PNGLoad.cpp \ + $(COMMONDIR)/Data/Format/PNGLoad.h \ + $(COMMONDIR)/Data/Format/ZIMLoad.cpp \ + $(COMMONDIR)/Data/Format/ZIMLoad.h \ + $(COMMONDIR)/Data/Format/ZIMSave.cpp \ + $(COMMONDIR)/Data/Format/ZIMSave.h \ $(COMMONDIR)/Data/Hash/Hash.cpp \ $(COMMONDIR)/Data/Text/I18n.cpp \ $(COMMONDIR)/Data/Text/Parsers.cpp \ @@ -160,23 +166,40 @@ SOURCES_CXX += \ $(COMMONDIR)/File/VFS/AssetReader.cpp \ $(COMMONDIR)/File/DiskFree.cpp \ $(COMMONDIR)/File/PathBrowser.cpp \ + $(COMMONDIR)/File/FileUtil.cpp \ + $(COMMONDIR)/File/FileDescriptor.cpp \ + $(COMMONDIR)/File/DirListing.cpp \ + $(COMMONDIR)/Input/GestureDetector.cpp \ + $(COMMONDIR)/Input/InputState.cpp \ $(COMMONDIR)/Math/curves.cpp \ $(COMMONDIR)/Math/expression_parser.cpp \ $(COMMONDIR)/Math/math_util.cpp \ $(COMMONDIR)/Math/lin/vec3.cpp \ $(COMMONDIR)/Math/lin/matrix4x4.cpp \ + $(COMMONDIR)/Net/HTTPClient.cpp \ + $(COMMONDIR)/Net/HTTPHeaders.cpp \ + $(COMMONDIR)/Net/HTTPServer.cpp \ + $(COMMONDIR)/Net/Resolve.cpp \ + $(COMMONDIR)/Net/Sinks.cpp \ + $(COMMONDIR)/Net/URL.cpp \ + $(COMMONDIR)/Net/WebsocketServer.cpp \ $(COMMONDIR)/Serialize/Serializer.cpp \ $(COMMONDIR)/Thread/Executor.cpp \ $(COMMONDIR)/Thread/ThreadUtil.cpp \ $(COMMONDIR)/Thread/ThreadPool.cpp \ $(COMMONDIR)/Thread/PrioritizedWorkQueue.cpp \ + $(COMMONDIR)/UI/Root.cpp \ + $(COMMONDIR)/UI/Screen.cpp \ + $(COMMONDIR)/UI/UI.cpp \ + $(COMMONDIR)/UI/Context.cpp \ + $(COMMONDIR)/UI/UIScreen.cpp \ + $(COMMONDIR)/UI/Tween.cpp \ + $(COMMONDIR)/UI/View.cpp \ + $(COMMONDIR)/UI/ViewGroup.cpp \ $(COMMONDIR)/System/Display.cpp \ - $(COMMONDIR)/Input/GestureDetector.cpp \ - $(COMMONDIR)/Input/InputState.cpp \ $(COMMONDIR)/Buffer.cpp \ $(COMMONDIR)/ConsoleListener.cpp \ $(COMMONDIR)/ExceptionHandlerSetup.cpp \ - $(COMMONDIR)/FileUtil.cpp \ $(COMMONDIR)/KeyMap.cpp \ $(COMMONDIR)/Log.cpp \ $(COMMONDIR)/LogManager.cpp \ @@ -302,9 +325,7 @@ SOURCES_CXX += $(COMMONDIR)/MemArenaPosix.cpp \ $(EXTDIR)/glslang/glslang/OSDependent/Unix/ossource.cpp endif -SOURCES_CXX += $(NATIVEDIR)/file/fd_util.cpp \ - $(NATIVEDIR)/file/file_util.cpp \ - $(NATIVEDIR)/gfx/gl_debug_log.cpp \ +SOURCES_CXX += $(NATIVEDIR)/gfx/gl_debug_log.cpp \ $(NATIVEDIR)/gfx/texture_atlas.cpp \ $(NATIVEDIR)/gfx/d3d9_shader.cpp \ $(NATIVEDIR)/gfx/d3d9_state.cpp \ @@ -312,8 +333,6 @@ SOURCES_CXX += $(NATIVEDIR)/file/fd_util.cpp \ $(NATIVEDIR)/gfx_es2/draw_text.cpp \ $(NATIVEDIR)/gfx_es2/gpu_features.cpp \ $(NATIVEDIR)/gfx_es2/glsl_program.cpp \ - $(NATIVEDIR)/image/zim_load.cpp \ - $(NATIVEDIR)/image/png_load.cpp \ $(NATIVEDIR)/net/http_client.cpp \ $(NATIVEDIR)/net/resolve.cpp \ $(NATIVEDIR)/net/url.cpp \ @@ -322,14 +341,6 @@ SOURCES_CXX += $(NATIVEDIR)/file/fd_util.cpp \ $(NATIVEDIR)/thin3d/GLRenderManager.cpp \ $(NATIVEDIR)/thin3d/GLQueueRunner.cpp \ $(NATIVEDIR)/thin3d/DataFormatGL.cpp \ - $(NATIVEDIR)/ui/root.cpp \ - $(NATIVEDIR)/ui/screen.cpp \ - $(NATIVEDIR)/ui/ui.cpp \ - $(NATIVEDIR)/ui/ui_context.cpp \ - $(NATIVEDIR)/ui/ui_screen.cpp \ - $(NATIVEDIR)/ui/ui_tween.cpp \ - $(NATIVEDIR)/ui/view.cpp \ - $(NATIVEDIR)/ui/viewgroup.cpp \ $(EXTDIR)/jpge/jpgd.cpp \ $(EXTDIR)/jpge/jpge.cpp \ $(COREDIR)/AVIDump.cpp \ diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 8b0cefa854..bdb5f8d1b1 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -11,7 +11,7 @@ #include "Common/System/NativeApp.h" #include "Common/System/System.h" #include "Common/TimeUtil.h" -#include "Common/FileUtil.h" +#include "Common/File/FileUtil.h" #include "Common/Serialize/Serializer.h" #include "Common/ConsoleListener.h" #include "Common/Input/InputState.h" From 3d69132ef1c18ca79a5bf9e1a3851a69298df9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 23:30:56 +0200 Subject: [PATCH 830/848] Libretro buildfixes --- libretro/LibretroD3D11Context.cpp | 2 +- libretro/Makefile.common | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/libretro/LibretroD3D11Context.cpp b/libretro/LibretroD3D11Context.cpp index cd46e66858..8fbcd50a76 100644 --- a/libretro/LibretroD3D11Context.cpp +++ b/libretro/LibretroD3D11Context.cpp @@ -1,4 +1,4 @@ - +#include "Common/Log.h" #include "Core/ConfigValues.h" #include "libretro/LibretroD3D11Context.h" #include "thin3d/d3d11_loader.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index ff977d5000..25cb8ae65c 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -153,11 +153,8 @@ SOURCES_CXX += \ $(COMMONDIR)/Data/Format/JSONReader.cpp \ $(COMMONDIR)/Data/Format/JSONWriter.cpp \ $(COMMONDIR)/Data/Format/PNGLoad.cpp \ - $(COMMONDIR)/Data/Format/PNGLoad.h \ $(COMMONDIR)/Data/Format/ZIMLoad.cpp \ - $(COMMONDIR)/Data/Format/ZIMLoad.h \ $(COMMONDIR)/Data/Format/ZIMSave.cpp \ - $(COMMONDIR)/Data/Format/ZIMSave.h \ $(COMMONDIR)/Data/Hash/Hash.cpp \ $(COMMONDIR)/Data/Text/I18n.cpp \ $(COMMONDIR)/Data/Text/Parsers.cpp \ @@ -200,7 +197,6 @@ SOURCES_CXX += \ $(COMMONDIR)/Buffer.cpp \ $(COMMONDIR)/ConsoleListener.cpp \ $(COMMONDIR)/ExceptionHandlerSetup.cpp \ - $(COMMONDIR)/KeyMap.cpp \ $(COMMONDIR)/Log.cpp \ $(COMMONDIR)/LogManager.cpp \ $(COMMONDIR)/OSVersion.cpp \ @@ -333,9 +329,6 @@ SOURCES_CXX += $(NATIVEDIR)/gfx/gl_debug_log.cpp \ $(NATIVEDIR)/gfx_es2/draw_text.cpp \ $(NATIVEDIR)/gfx_es2/gpu_features.cpp \ $(NATIVEDIR)/gfx_es2/glsl_program.cpp \ - $(NATIVEDIR)/net/http_client.cpp \ - $(NATIVEDIR)/net/resolve.cpp \ - $(NATIVEDIR)/net/url.cpp \ $(NATIVEDIR)/thin3d/thin3d.cpp \ $(NATIVEDIR)/thin3d/thin3d_gl.cpp \ $(NATIVEDIR)/thin3d/GLRenderManager.cpp \ @@ -348,6 +341,7 @@ SOURCES_CXX += $(NATIVEDIR)/gfx/gl_debug_log.cpp \ $(COREDIR)/TextureReplacer.cpp \ $(COREDIR)/Core.cpp \ $(COREDIR)/WaveFile.cpp \ + $(COREDIR)/KeyMap.cpp \ $(COREDIR)/FileLoaders/HTTPFileLoader.cpp \ $(COREDIR)/FileLoaders/CachingFileLoader.cpp \ $(COREDIR)/FileLoaders/DiskCachingFileLoader.cpp \ @@ -538,7 +532,7 @@ ifeq ($(WITH_DYNAREC),1) SOURCES_C += $(EXTDIR)/libpng17/arm/arm_init.c \ $(EXTDIR)/libpng17/arm/filter_neon_intrinsics.c - ASMFILES += $(NATIVEDIR)/math/fast/fast_matrix_neon.S \ + ASMFILES += $(COMMONDIR)/Math/fast/fast_matrix_neon.S \ $(EXTDIR)/libpng17/arm/filter_neon.S endif else ifeq ($(TARGET_ARCH),arm64) @@ -606,7 +600,7 @@ endif $(COREDIR)/MIPS/x86/RegCache.cpp \ $(COREDIR)/MIPS/x86/RegCacheFPU.cpp \ $(GPUDIR)/Common/VertexDecoderX86.cpp - SOURCES_C += $(NATIVEDIR)/math/fast/fast_matrix_sse.c + SOURCES_C += $(COMMONDIR)/Math/fast/fast_matrix_sse.c endif endif #UDIS86 From 71ecd62ab40d38d9683d9291bc67daf1b0daf341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 23:06:26 +0200 Subject: [PATCH 831/848] KeyMap fix (libretro) --- libretro/Makefile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 25cb8ae65c..0df991d730 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -340,6 +340,7 @@ SOURCES_CXX += $(NATIVEDIR)/gfx/gl_debug_log.cpp \ $(COREDIR)/Config.cpp \ $(COREDIR)/TextureReplacer.cpp \ $(COREDIR)/Core.cpp \ + $(COREDIR)/KeyMap.cpp \ $(COREDIR)/WaveFile.cpp \ $(COREDIR)/KeyMap.cpp \ $(COREDIR)/FileLoaders/HTTPFileLoader.cpp \ From 0e3a84b4a82346a850054906825ad382d5ca3172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Oct 2020 23:24:14 +0200 Subject: [PATCH 832/848] Move most GPU things to Common. It works after the move, on Windows and Android at least. Deletes the D3DX9 shader compiler loader, which was not used. --- CMakeLists.txt | 116 +++++----- Common/Common.vcxproj | 75 +++++-- Common/Common.vcxproj.filters | 198 +++++++++++++++--- Common/Data/Text/WrapText.cpp | 2 +- .../GPU/D3D11/D3D11Loader.cpp | 2 +- .../GPU/D3D11/D3D11Loader.h | 0 .../GPU/D3D11}/thin3d_d3d11.cpp | 4 +- .../GPU/D3D9/D3D9ShaderCompiler.cpp | 42 +--- .../GPU/D3D9/D3D9ShaderCompiler.h | 3 +- .../GPU/D3D9/D3D9StateCache.cpp | 3 +- .../GPU/D3D9/D3D9StateCache.h | 5 +- .../GPU/D3D9/D3DCompilerLoader.cpp | 15 +- .../GPU/D3D9/D3DCompilerLoader.h | 0 .../GPU/D3D9}/thin3d_d3d9.cpp | 23 +- .../native/thin3d => Common/GPU}/DataFormat.h | 0 .../GPU/OpenGL}/DataFormatGL.cpp | 2 +- .../GPU/OpenGL}/DataFormatGL.h | 4 +- .../GPU/OpenGL/GLCommon.h | 2 +- .../GPU/OpenGL/GLDebugLog.cpp | 4 +- .../GPU/OpenGL/GLDebugLog.h | 0 .../GPU/OpenGL/GLFeatures.cpp | 4 +- .../GPU/OpenGL/GLFeatures.h | 6 +- .../GPU/OpenGL}/GLQueueRunner.cpp | 8 +- .../GPU/OpenGL}/GLQueueRunner.h | 4 +- .../GPU/OpenGL}/GLRenderManager.cpp | 4 +- .../GPU/OpenGL}/GLRenderManager.h | 2 +- .../GPU/OpenGL/GLSLProgram.cpp | 2 +- .../GPU/OpenGL/GLSLProgram.h | 2 +- .../gfx_es2 => Common/GPU/OpenGL}/gl3stub.c | 3 +- .../gfx_es2 => Common/GPU/OpenGL}/gl3stub.h | 0 .../GPU/OpenGL}/thin3d_gl.cpp | 14 +- Common/{ => GPU}/Vulkan/VulkanContext.cpp | 4 +- Common/{ => GPU}/Vulkan/VulkanContext.h | 4 +- Common/{ => GPU}/Vulkan/VulkanDebug.cpp | 4 +- Common/{ => GPU}/Vulkan/VulkanDebug.h | 2 +- Common/{ => GPU}/Vulkan/VulkanImage.cpp | 4 +- Common/{ => GPU}/Vulkan/VulkanImage.h | 2 +- Common/{ => GPU}/Vulkan/VulkanLoader.cpp | 2 +- Common/{ => GPU}/Vulkan/VulkanLoader.h | 0 Common/{ => GPU}/Vulkan/VulkanMemory.cpp | 2 +- Common/{ => GPU}/Vulkan/VulkanMemory.h | 2 +- .../GPU/Vulkan}/VulkanQueueRunner.cpp | 2 +- .../GPU/Vulkan}/VulkanQueueRunner.h | 4 +- .../GPU/Vulkan}/VulkanRenderManager.cpp | 4 +- .../GPU/Vulkan}/VulkanRenderManager.h | 6 +- .../GPU/Vulkan}/thin3d_vulkan.cpp | 12 +- {ext/native/thin3d => Common/GPU}/thin3d.cpp | 2 +- {ext/native/thin3d => Common/GPU}/thin3d.h | 0 .../thin3d => Common/GPU}/thin3d_create.h | 2 +- Common/GraphicsContext.h | 2 +- Common/Profiler/Profiler.cpp | 2 +- .../Render/DrawBuffer.cpp | 5 +- .../Render/DrawBuffer.h | 4 +- .../Render/TextureAtlas.cpp | 2 +- .../Render/TextureAtlas.h | 0 Common/UI/Context.cpp | 2 +- Common/UI/Context.h | 2 +- Common/UI/UI.cpp | 4 +- Common/UI/UI.h | 2 +- Common/UI/UIScreen.cpp | 2 +- Common/UI/View.cpp | 6 +- Common/UI/View.h | 2 +- Common/UI/ViewGroup.cpp | 2 +- Core/Config.cpp | 4 +- Core/Dialog/PSPDialog.h | 2 +- Core/HLE/sceDisplay.cpp | 5 +- Core/Util/PPGeDraw.cpp | 2 +- Core/Util/PPGeDraw.h | 2 +- GPU/Common/DepalettizeShaderCommon.cpp | 2 +- GPU/Common/FramebufferManagerCommon.cpp | 5 +- GPU/Common/FramebufferManagerCommon.h | 2 +- GPU/Common/PostShader.cpp | 2 +- GPU/Common/PresentationCommon.cpp | 2 +- GPU/Common/ShaderId.cpp | 2 +- GPU/Common/ShaderTranslation.cpp | 4 +- GPU/Common/ShaderTranslation.h | 2 +- GPU/Common/SoftwareTransformCommon.cpp | 2 +- GPU/D3D11/D3D11Util.cpp | 2 +- GPU/D3D11/DepalettizeShaderD3D11.h | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 2 +- GPU/D3D11/FramebufferManagerD3D11.h | 2 +- GPU/D3D11/ShaderManagerD3D11.cpp | 2 +- GPU/D3D11/StateMappingD3D11.h | 2 +- GPU/D3D11/StencilBufferD3D11.cpp | 2 +- GPU/Directx9/DepalettizeShaderDX9.cpp | 4 +- GPU/Directx9/DrawEngineDX9.cpp | 2 +- GPU/Directx9/FramebufferManagerDX9.cpp | 6 +- GPU/Directx9/GPU_DX9.cpp | 2 +- GPU/Directx9/ShaderManagerDX9.cpp | 4 +- GPU/Directx9/ShaderManagerDX9.h | 1 - GPU/Directx9/StateMappingDX9.cpp | 11 +- GPU/Directx9/StencilBufferDX9.cpp | 4 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GLES/DepalettizeShaderGLES.h | 6 +- GPU/GLES/DepthBufferGLES.cpp | 2 +- GPU/GLES/DrawEngineGLES.cpp | 2 +- GPU/GLES/DrawEngineGLES.h | 4 +- GPU/GLES/FragmentShaderGeneratorGLES.cpp | 2 +- GPU/GLES/FragmentTestCacheGLES.cpp | 4 +- GPU/GLES/FramebufferManagerGLES.cpp | 8 +- GPU/GLES/FramebufferManagerGLES.h | 4 +- GPU/GLES/ShaderManagerGLES.cpp | 8 +- GPU/GLES/ShaderManagerGLES.h | 2 +- GPU/GLES/StateMappingGLES.cpp | 4 +- GPU/GLES/StateMappingGLES.h | 2 +- GPU/GLES/StencilBufferGLES.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 3 +- GPU/GLES/TextureCacheGLES.h | 6 +- GPU/GLES/TextureScalerGLES.cpp | 4 +- GPU/GLES/VertexShaderGeneratorGLES.cpp | 2 +- GPU/Software/SoftGpu.cpp | 4 +- GPU/Software/SoftGpu.h | 2 +- GPU/Vulkan/DebugVisVulkan.cpp | 8 +- GPU/Vulkan/DebugVisVulkan.h | 2 +- GPU/Vulkan/DepalettizeShaderVulkan.cpp | 8 +- GPU/Vulkan/DepalettizeShaderVulkan.h | 4 +- GPU/Vulkan/DrawEngineVulkan.cpp | 6 +- GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp | 2 +- GPU/Vulkan/FramebufferManagerVulkan.cpp | 10 +- GPU/Vulkan/FramebufferManagerVulkan.h | 2 +- GPU/Vulkan/GPU_Vulkan.cpp | 4 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 8 +- GPU/Vulkan/ShaderManagerVulkan.cpp | 6 +- GPU/Vulkan/ShaderManagerVulkan.h | 2 +- GPU/Vulkan/StateMappingVulkan.cpp | 4 +- GPU/Vulkan/StateMappingVulkan.h | 2 +- GPU/Vulkan/StencilBufferVulkan.cpp | 4 +- GPU/Vulkan/TextureCacheVulkan.cpp | 10 +- GPU/Vulkan/TextureCacheVulkan.h | 2 +- GPU/Vulkan/TextureScalerVulkan.cpp | 2 +- GPU/Vulkan/VertexShaderGeneratorVulkan.cpp | 4 +- GPU/Vulkan/VulkanUtil.cpp | 2 +- GPU/Vulkan/VulkanUtil.h | 6 +- Qt/QtMain.cpp | 2 +- Qt/QtMain.h | 12 +- SDL/SDLGLGraphicsContext.cpp | 4 +- SDL/SDLGLGraphicsContext.h | 4 +- SDL/SDLMain.cpp | 2 +- SDL/SDLVulkanGraphicsContext.cpp | 6 +- SDL/SDLVulkanGraphicsContext.h | 6 +- UI/ComboKeyMappingScreen.cpp | 4 +- UI/ControlMappingScreen.cpp | 2 +- UI/DevScreens.cpp | 2 +- UI/DisplayLayoutEditor.h | 4 +- UI/DisplayLayoutScreen.cpp | 4 +- UI/EmuScreen.cpp | 4 +- UI/GPUDriverTestScreen.h | 2 +- UI/GameInfoCache.cpp | 2 +- UI/GameScreen.cpp | 2 +- UI/GameSettingsScreen.cpp | 4 +- UI/GamepadEmu.cpp | 2 +- UI/GamepadEmu.h | 2 +- UI/MainScreen.cpp | 4 +- UI/MiscScreens.cpp | 2 +- UI/NativeApp.cpp | 6 +- UI/OnScreenDisplay.cpp | 4 +- UI/PauseScreen.cpp | 4 +- UI/ProfilerDraw.cpp | 2 +- UI/RemoteISOScreen.cpp | 2 +- UI/ReportScreen.cpp | 4 +- UI/SavedataScreen.cpp | 2 +- UI/Store.cpp | 2 +- UI/TextureUtil.cpp | 4 +- UI/TextureUtil.h | 2 +- UI/TouchControlLayoutScreen.cpp | 2 +- UI/TouchControlVisibilityScreen.cpp | 2 +- UI/TouchControlVisibilityScreen.h | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 11 + UWP/CommonUWP/CommonUWP.vcxproj.filters | 45 ++++ UWP/NativeUWP/NativeUWP.vcxproj | 13 +- UWP/NativeUWP/NativeUWP.vcxproj.filters | 40 +--- UWP/PPSSPP_UWPMain.cpp | 2 +- UWP/PPSSPP_UWPMain.h | 2 +- Windows/GEDebugger/SimpleGLWindow.cpp | 4 +- Windows/GEDebugger/SimpleGLWindow.h | 2 +- Windows/GEDebugger/VertexPreview.cpp | 4 +- Windows/GPU/D3D11Context.cpp | 6 +- Windows/GPU/D3D9Context.cpp | 6 +- Windows/GPU/WindowsGLContext.cpp | 10 +- Windows/GPU/WindowsVulkanContext.cpp | 10 +- Windows/GPU/WindowsVulkanContext.h | 2 +- Windows/MainWindowMenu.cpp | 4 +- Windows/main.cpp | 2 +- android/jni/Android.mk | 39 ++-- android/jni/AndroidEGLContext.cpp | 4 +- android/jni/AndroidEGLContext.h | 2 +- android/jni/AndroidGraphicsContext.h | 3 +- android/jni/AndroidJavaGLContext.cpp | 2 +- android/jni/AndroidJavaGLContext.h | 4 +- android/jni/AndroidVulkanContext.cpp | 10 +- android/jni/app-android.cpp | 4 +- ext/native/gfx_es2/draw_text.cpp | 2 +- ext/native/gfx_es2/draw_text.h | 2 +- ext/native/gfx_es2/draw_text_android.cpp | 2 +- ext/native/gfx_es2/draw_text_qt.cpp | 2 +- ext/native/gfx_es2/draw_text_uwp.cpp | 2 +- ext/native/gfx_es2/draw_text_win.cpp | 2 +- ext/native/native.vcxproj | 50 ----- ext/native/native.vcxproj.filters | 126 ----------- ext/native/thin3d/d3dx9_loader.cpp | 192 ----------------- ext/native/thin3d/d3dx9_loader.h | 26 --- ext/native/thin3d/vulkan_utils.cpp | 142 ------------- ext/native/tools/atlastool.cpp | 2 +- headless/SDLHeadlessHost.cpp | 8 +- headless/WindowsHeadlessHost.cpp | 4 +- ios/PPSSPPUIApplication.mm | 4 +- ios/ViewController.mm | 8 +- libretro/LibretroD3D11Context.cpp | 3 +- libretro/LibretroGLContext.cpp | 2 +- libretro/LibretroGLContext.h | 4 +- libretro/LibretroGLCoreContext.cpp | 2 +- libretro/LibretroGLCoreContext.h | 4 +- libretro/LibretroGraphicsContext.h | 2 +- libretro/LibretroVulkanContext.cpp | 6 +- libretro/Makefile.common | 56 +++-- ppsspp_config.h | 5 +- 216 files changed, 742 insertions(+), 1162 deletions(-) rename ext/native/thin3d/d3d11_loader.cpp => Common/GPU/D3D11/D3D11Loader.cpp (98%) rename ext/native/thin3d/d3d11_loader.h => Common/GPU/D3D11/D3D11Loader.h (100%) rename {ext/native/thin3d => Common/GPU/D3D11}/thin3d_d3d11.cpp (99%) rename ext/native/gfx/d3d9_shader.cpp => Common/GPU/D3D9/D3D9ShaderCompiler.cpp (71%) rename ext/native/gfx/d3d9_shader.h => Common/GPU/D3D9/D3D9ShaderCompiler.h (95%) rename ext/native/gfx/d3d9_state.cpp => Common/GPU/D3D9/D3D9StateCache.cpp (97%) rename ext/native/gfx/d3d9_state.h => Common/GPU/D3D9/D3D9StateCache.h (99%) rename ext/native/thin3d/d3d9_d3dcompiler_loader.cpp => Common/GPU/D3D9/D3DCompilerLoader.cpp (87%) rename ext/native/thin3d/d3d9_d3dcompiler_loader.h => Common/GPU/D3D9/D3DCompilerLoader.h (100%) rename {ext/native/thin3d => Common/GPU/D3D9}/thin3d_d3d9.cpp (98%) rename {ext/native/thin3d => Common/GPU}/DataFormat.h (100%) rename {ext/native/thin3d => Common/GPU/OpenGL}/DataFormatGL.cpp (97%) rename {ext/native/thin3d => Common/GPU/OpenGL}/DataFormatGL.h (67%) rename ext/native/gfx/gl_common.h => Common/GPU/OpenGL/GLCommon.h (98%) rename ext/native/gfx/gl_debug_log.cpp => Common/GPU/OpenGL/GLDebugLog.cpp (94%) rename ext/native/gfx/gl_debug_log.h => Common/GPU/OpenGL/GLDebugLog.h (100%) rename ext/native/gfx_es2/gpu_features.cpp => Common/GPU/OpenGL/GLFeatures.cpp (99%) rename ext/native/gfx_es2/gpu_features.h => Common/GPU/OpenGL/GLFeatures.h (96%) rename {ext/native/thin3d => Common/GPU/OpenGL}/GLQueueRunner.cpp (99%) rename {ext/native/thin3d => Common/GPU/OpenGL}/GLQueueRunner.h (99%) rename {ext/native/thin3d => Common/GPU/OpenGL}/GLRenderManager.cpp (99%) rename {ext/native/thin3d => Common/GPU/OpenGL}/GLRenderManager.h (99%) rename ext/native/gfx_es2/glsl_program.cpp => Common/GPU/OpenGL/GLSLProgram.cpp (99%) rename ext/native/gfx_es2/glsl_program.h => Common/GPU/OpenGL/GLSLProgram.h (97%) rename {ext/native/gfx_es2 => Common/GPU/OpenGL}/gl3stub.c (99%) rename {ext/native/gfx_es2 => Common/GPU/OpenGL}/gl3stub.h (100%) rename {ext/native/thin3d => Common/GPU/OpenGL}/thin3d_gl.cpp (99%) rename Common/{ => GPU}/Vulkan/VulkanContext.cpp (99%) rename Common/{ => GPU}/Vulkan/VulkanContext.h (99%) rename Common/{ => GPU}/Vulkan/VulkanDebug.cpp (97%) rename Common/{ => GPU}/Vulkan/VulkanDebug.h (96%) rename Common/{ => GPU}/Vulkan/VulkanImage.cpp (99%) rename Common/{ => GPU}/Vulkan/VulkanImage.h (98%) rename Common/{ => GPU}/Vulkan/VulkanLoader.cpp (99%) rename Common/{ => GPU}/Vulkan/VulkanLoader.h (100%) rename Common/{ => GPU}/Vulkan/VulkanMemory.cpp (99%) rename Common/{ => GPU}/Vulkan/VulkanMemory.h (99%) rename {ext/native/thin3d => Common/GPU/Vulkan}/VulkanQueueRunner.cpp (99%) rename {ext/native/thin3d => Common/GPU/Vulkan}/VulkanQueueRunner.h (98%) rename {ext/native/thin3d => Common/GPU/Vulkan}/VulkanRenderManager.cpp (99%) rename {ext/native/thin3d => Common/GPU/Vulkan}/VulkanRenderManager.h (99%) rename {ext/native/thin3d => Common/GPU/Vulkan}/thin3d_vulkan.cpp (99%) rename {ext/native/thin3d => Common/GPU}/thin3d.cpp (99%) rename {ext/native/thin3d => Common/GPU}/thin3d.h (100%) rename {ext/native/thin3d => Common/GPU}/thin3d_create.h (97%) rename ext/native/gfx_es2/draw_buffer.cpp => Common/Render/DrawBuffer.cpp (99%) rename ext/native/gfx_es2/draw_buffer.h => Common/Render/DrawBuffer.h (98%) rename ext/native/gfx/texture_atlas.cpp => Common/Render/TextureAtlas.cpp (98%) rename ext/native/gfx/texture_atlas.h => Common/Render/TextureAtlas.h (100%) delete mode 100644 ext/native/thin3d/d3dx9_loader.cpp delete mode 100644 ext/native/thin3d/d3dx9_loader.h delete mode 100644 ext/native/thin3d/vulkan_utils.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a7699f8c4..a70330c5ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -400,18 +400,19 @@ if(NOT (X86 OR ARM OR MIPS)) source_group(Fake FILES ${CommonFake}) endif() -set(CommonVulkan ${CommonExtra} - Common/Vulkan/VulkanDebug.cpp - Common/Vulkan/VulkanDebug.h - Common/Vulkan/VulkanContext.cpp - Common/Vulkan/VulkanContext.h - Common/Vulkan/VulkanImage.cpp - Common/Vulkan/VulkanImage.h - Common/Vulkan/VulkanLoader.cpp - Common/Vulkan/VulkanLoader.h - Common/Vulkan/VulkanMemory.cpp - Common/Vulkan/VulkanMemory.h -) +if(WIN32) + set(CommonD3D + Common/GPU/D3D9/D3D9ShaderCompiler.cpp + Common/GPU/D3D9/D3D9ShaderCompiler.h + Common/GPU/D3D9/D3D9StateCache.cpp + Common/GPU/D3D9/D3D9StateCache.h + Common/GPU/D3D9/thin3d_d3d9.cpp + Common/GPU/D3D9/D3DCompilerLoader.cpp + Common/GPU/D3D11/thin3d_d3d11.cpp + Common/GPU/D3D11/D3D11Loader.cpp + Common/GPU/D3D11/D3D11Loader.h + ) +endif() add_library(Common STATIC ${CommonX86} @@ -420,6 +421,7 @@ add_library(Common STATIC ${CommonMIPS} ${CommonFake} ${CommonVulkan} + ${CommonD3D} Common/Serialize/Serializer.cpp Common/Serialize/Serializer.h Common/Serialize/SerializeDeque.h @@ -484,6 +486,41 @@ add_library(Common STATIC Common/File/DirListing.h Common/File/FileDescriptor.cpp Common/File/FileDescriptor.h + Common/GPU/DataFormat.h + Common/GPU/thin3d.cpp + Common/GPU/thin3d.h + Common/GPU/thin3d_create.h + Common/GPU/OpenGL/GLCommon.h + Common/GPU/OpenGL/GLDebugLog.cpp + Common/GPU/OpenGL/GLDebugLog.h + Common/GPU/OpenGL/GLSLProgram.cpp + Common/GPU/OpenGL/GLSLProgram.h + Common/GPU/OpenGL/gl3stub.c + Common/GPU/OpenGL/gl3stub.h + Common/GPU/OpenGL/GLFeatures.cpp + Common/GPU/OpenGL/GLFeatures.h + Common/GPU/OpenGL/thin3d_gl.cpp + Common/GPU/OpenGL/GLRenderManager.cpp + Common/GPU/OpenGL/GLRenderManager.h + Common/GPU/OpenGL/GLQueueRunner.cpp + Common/GPU/OpenGL/GLQueueRunner.h + Common/GPU/OpenGL/DataFormatGL.cpp + Common/GPU/OpenGL/DataFormatGL.h + Common/GPU/Vulkan/VulkanDebug.cpp + Common/GPU/Vulkan/VulkanDebug.h + Common/GPU/Vulkan/VulkanContext.cpp + Common/GPU/Vulkan/VulkanContext.h + Common/GPU/Vulkan/VulkanImage.cpp + Common/GPU/Vulkan/VulkanImage.h + Common/GPU/Vulkan/VulkanLoader.cpp + Common/GPU/Vulkan/VulkanLoader.h + Common/GPU/Vulkan/VulkanMemory.cpp + Common/GPU/Vulkan/VulkanMemory.h + Common/GPU/Vulkan/thin3d_vulkan.cpp + Common/GPU/Vulkan/VulkanRenderManager.cpp + Common/GPU/Vulkan/VulkanRenderManager.h + Common/GPU/Vulkan/VulkanQueueRunner.cpp + Common/GPU/Vulkan/VulkanQueueRunner.h Common/Input/GestureDetector.cpp Common/Input/GestureDetector.h Common/Input/KeyCodes.h @@ -519,6 +556,10 @@ add_library(Common STATIC Common/Net/WebsocketServer.h Common/Profiler/Profiler.cpp Common/Profiler/Profiler.h + Common/Render/TextureAtlas.cpp + Common/Render/TextureAtlas.h + Common/Render/DrawBuffer.cpp + Common/Render/DrawBuffer.h Common/System/Display.cpp Common/System/Display.h Common/Thread/Executor.cpp @@ -1019,49 +1060,8 @@ if(ANDROID) endif() endif() -set(THIN3D_PLATFORMS ext/native/thin3d/thin3d_gl.cpp - ext/native/thin3d/GLRenderManager.cpp - ext/native/thin3d/GLRenderManager.h - ext/native/thin3d/GLQueueRunner.cpp - ext/native/thin3d/GLQueueRunner.h - ext/native/thin3d/DataFormatGL.cpp - ext/native/thin3d/DataFormatGL.h -) - -set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS} - ext/native/thin3d/thin3d_vulkan.cpp - ext/native/thin3d/VulkanRenderManager.cpp - ext/native/thin3d/VulkanRenderManager.h - ext/native/thin3d/VulkanQueueRunner.cpp - ext/native/thin3d/VulkanQueueRunner.h - ext/native/thin3d/DataFormat.h -) - -if(WIN32) - set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS} - ext/native/thin3d/thin3d_d3d9.cpp - ext/native/thin3d/thin3d_d3d11.cpp - ext/native/thin3d/d3d9_d3dcompiler_loader.cpp - ext/native/thin3d/d3dx9_loader.cpp - ext/native/thin3d/d3dx9_loader.h - ext/native/thin3d/d3d11_loader.cpp - ext/native/thin3d/d3d11_loader.h - ) -endif() - add_library(native STATIC ${nativeExtra} - ext/native/gfx/gl_common.h - ext/native/gfx/gl_debug_log.cpp - ext/native/gfx/gl_debug_log.h - ext/native/gfx/texture_atlas.cpp - ext/native/gfx/texture_atlas.h - ext/native/gfx/d3d9_shader.cpp - ext/native/gfx/d3d9_shader.h - ext/native/gfx/d3d9_state.cpp - ext/native/gfx/d3d9_state.h - ext/native/gfx_es2/draw_buffer.cpp - ext/native/gfx_es2/draw_buffer.h ext/native/gfx_es2/draw_text.cpp ext/native/gfx_es2/draw_text.h ext/native/gfx_es2/draw_text_win.cpp @@ -1070,16 +1070,6 @@ add_library(native STATIC ext/native/gfx_es2/draw_text_qt.h ext/native/gfx_es2/draw_text_android.cpp ext/native/gfx_es2/draw_text_android.h - ext/native/gfx_es2/gpu_features.cpp - ext/native/gfx_es2/gpu_features.h - ext/native/gfx_es2/glsl_program.cpp - ext/native/gfx_es2/glsl_program.h - ext/native/gfx_es2/gl3stub.c - ext/native/gfx_es2/gl3stub.h - ext/native/thin3d/thin3d.cpp - ext/native/thin3d/thin3d.h - ext/native/thin3d/thin3d_create.h - ${THIN3D_PLATFORMS} ext/jpge/jpgd.cpp ext/jpge/jpgd.h ext/jpge/jpge.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 385b483e56..cc8f5594d0 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -136,7 +136,7 @@ _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) Common/DbgNew.h MultiThreadedDebug - ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. StreamingSIMDExtensions2 Precise true @@ -158,7 +158,7 @@ Common/DbgNew.h MultiThreadedDebug _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;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -181,7 +181,7 @@ Common/DbgNew.h MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -205,7 +205,7 @@ MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -234,7 +234,7 @@ false StreamingSIMDExtensions2 Precise - ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. Speed true false @@ -260,7 +260,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -291,7 +291,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -322,7 +322,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -388,6 +388,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -407,6 +429,8 @@ + + @@ -483,11 +507,6 @@ - - - - - @@ -690,6 +709,29 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -709,6 +751,8 @@ + + @@ -774,11 +818,6 @@ - - - - - diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 04386e630e..d38ea71068 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -50,25 +50,10 @@ - - Vulkan - - - Vulkan - - - Vulkan - - - Vulkan - - - Vulkan - @@ -300,6 +285,78 @@ UI + + GPU\D3D9 + + + GPU\D3D9 + + + GPU\D3D9 + + + GPU\D3D11 + + + GPU\OpenGL + + + GPU\OpenGL + + + GPU\OpenGL + + + GPU\OpenGL + + + GPU + + + GPU + + + GPU + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\OpenGL + + + GPU\OpenGL + + + GPU\OpenGL + + + Render + + + Render + + + GPU\OpenGL + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\Vulkan + @@ -337,26 +394,11 @@ GL\GLInterface - - Vulkan - - - Vulkan - - - Vulkan - - - Vulkan - - - Vulkan - Serialize @@ -575,6 +617,81 @@ UI + + GPU\D3D9 + + + GPU\D3D11 + + + GPU\D3D9 + + + GPU\D3D9 + + + GPU\D3D9 + + + GPU\D3D11 + + + GPU\OpenGL + + + GPU\OpenGL + + + GPU\OpenGL + + + GPU\OpenGL + + + GPU\OpenGL + + + GPU + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\OpenGL + + + GPU\OpenGL + + + Render + + + Render + + + GPU\OpenGL + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\Vulkan + + + GPU\Vulkan + @@ -586,9 +703,6 @@ {2c723cf4-75b6-406a-90c0-ebb7a13ba476} - - {c14d66ef-5f7c-4565-975a-72774e7ccfb9} - {7be79ad5-3520-46a1-a370-dce2a943978c} @@ -658,6 +772,24 @@ {6a61d762-e71c-4428-8cef-c7ddda405ba5} + + {3b448d70-d5c6-4732-96f0-29f3e101bfe8} + + + {a1745de8-f61a-4f11-b715-705a8812862e} + + + {8241d0c2-78c8-4fc6-9543-69042ec5eb54} + + + {e9d7bdf2-c412-4030-a423-671066c4ea51} + + + {19ad2070-4f85-48d3-abab-add446ea3a77} + + + {c9aba118-5c31-4607-9a69-18eca9f92b44} + diff --git a/Common/Data/Text/WrapText.cpp b/Common/Data/Text/WrapText.cpp index c46688c50e..c88628acf5 100644 --- a/Common/Data/Text/WrapText.cpp +++ b/Common/Data/Text/WrapText.cpp @@ -1,5 +1,5 @@ #include -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Text/WrapText.h" diff --git a/ext/native/thin3d/d3d11_loader.cpp b/Common/GPU/D3D11/D3D11Loader.cpp similarity index 98% rename from ext/native/thin3d/d3d11_loader.cpp rename to Common/GPU/D3D11/D3D11Loader.cpp index fe0d0a02a9..2d81727ddb 100644 --- a/ext/native/thin3d/d3d11_loader.cpp +++ b/Common/GPU/D3D11/D3D11Loader.cpp @@ -1,4 +1,4 @@ -#include "thin3d/d3d11_loader.h" +#include "Common/GPU/D3D11/D3D11Loader.h" #if PPSSPP_PLATFORM(UWP) #error This file should not be compiled for UWP. diff --git a/ext/native/thin3d/d3d11_loader.h b/Common/GPU/D3D11/D3D11Loader.h similarity index 100% rename from ext/native/thin3d/d3d11_loader.h rename to Common/GPU/D3D11/D3D11Loader.h diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp similarity index 99% rename from ext/native/thin3d/thin3d_d3d11.cpp rename to Common/GPU/D3D11/thin3d_d3d11.cpp index d39813667f..263fa088e8 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -1,10 +1,10 @@ #include "ppsspp_config.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #if PPSSPP_PLATFORM(UWP) #define ptr_D3DCompile D3DCompile #else -#include "thin3d/d3d11_loader.h" +#include "Common/GPU/D3D11/D3D11Loader.h" #endif #include "Common/System/Display.h" diff --git a/ext/native/gfx/d3d9_shader.cpp b/Common/GPU/D3D9/D3D9ShaderCompiler.cpp similarity index 71% rename from ext/native/gfx/d3d9_shader.cpp rename to Common/GPU/D3D9/D3D9ShaderCompiler.cpp index bdc0b252e7..b54bb215c1 100644 --- a/ext/native/gfx/d3d9_shader.cpp +++ b/Common/GPU/D3D9/D3D9ShaderCompiler.cpp @@ -1,21 +1,13 @@ #ifdef _WIN32 #include "ppsspp_config.h" -#include "d3d9_shader.h" + +#include "Common/CommonWindows.h" +#include "Common/GPU/D3D9/D3DCompilerLoader.h" +#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" #include "Common/CommonFuncs.h" #include "Common/SysError.h" -#if PPSSPP_API(D3DX9) -#include "thin3d/d3dx9_loader.h" - -// They are the same types, just different names. -#define LPD3D_SHADER_MACRO LPD3DXMACRO -#define LPD3DINCLUDE LPD3DXINCLUDE -#define LPD3DBLOB LPD3DXBUFFER -#elif PPSSPP_API(D3D9_D3DCOMPILER) -#include "thin3d/d3d9_d3dcompiler_loader.h" -#endif - struct ID3DXConstantTable; namespace DX9 { @@ -25,18 +17,6 @@ bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPI LPD3DBLOB pErrorMsg = nullptr; // Compile pixel shader. -#if PPSSPP_API(D3DX9) - HRESULT hr = dyn_D3DXCompileShader(code, - (UINT)strlen(code), - nullptr, - nullptr, - "main", - "ps_2_0", - 0, - &pShaderCode, - &pErrorMsg, - pShaderTable); -#elif PPSSPP_API(D3D9_D3DCOMPILER) HRESULT hr = dyn_D3DCompile(code, (UINT)strlen(code), nullptr, @@ -48,7 +28,6 @@ bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPI 0, &pShaderCode, &pErrorMsg); -#endif if (pErrorMsg) { errorMessage = (CHAR *)pErrorMsg->GetBufferPointer(); @@ -79,18 +58,6 @@ bool CompileVertexShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DV LPD3DBLOB pErrorMsg = nullptr; // Compile pixel shader. -#if PPSSPP_API(D3DX9) - HRESULT hr = dyn_D3DXCompileShader(code, - (UINT)strlen(code), - nullptr, - nullptr, - "main", - "vs_2_0", - 0, - &pShaderCode, - &pErrorMsg, - pShaderTable); -#elif PPSSPP_API(D3D9_D3DCOMPILER) HRESULT hr = dyn_D3DCompile(code, (UINT)strlen(code), nullptr, @@ -102,7 +69,6 @@ bool CompileVertexShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DV 0, &pShaderCode, &pErrorMsg); -#endif if (pErrorMsg) { errorMessage = (CHAR *)pErrorMsg->GetBufferPointer(); diff --git a/ext/native/gfx/d3d9_shader.h b/Common/GPU/D3D9/D3D9ShaderCompiler.h similarity index 95% rename from ext/native/gfx/d3d9_shader.h rename to Common/GPU/D3D9/D3D9ShaderCompiler.h index 289ed24954..6c4aaf75a2 100644 --- a/ext/native/gfx/d3d9_shader.h +++ b/Common/GPU/D3D9/D3D9ShaderCompiler.h @@ -1,6 +1,7 @@ #pragma once #include "Common/CommonWindows.h" + #include #include #include @@ -12,4 +13,4 @@ namespace DX9 { bool CompilePixelShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DPIXELSHADER9 *pShader, ID3DXConstantTable **pShaderTable, std::string &errorMessage); bool CompileVertexShader(LPDIRECT3DDEVICE9 device, const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, ID3DXConstantTable **pShaderTable, std::string &errorMessage); -} // namespace +} // namespace DX9 diff --git a/ext/native/gfx/d3d9_state.cpp b/Common/GPU/D3D9/D3D9StateCache.cpp similarity index 97% rename from ext/native/gfx/d3d9_state.cpp rename to Common/GPU/D3D9/D3D9StateCache.cpp index 14887f7f17..ed0bbdeff4 100644 --- a/ext/native/gfx/d3d9_state.cpp +++ b/Common/GPU/D3D9/D3D9StateCache.cpp @@ -1,7 +1,6 @@ #ifdef _WIN32 -#include "d3d9_state.h" -#include +#include "Common/GPU/D3D9/D3D9StateCache.h" namespace DX9 { diff --git a/ext/native/gfx/d3d9_state.h b/Common/GPU/D3D9/D3D9StateCache.h similarity index 99% rename from ext/native/gfx/d3d9_state.h rename to Common/GPU/D3D9/D3D9StateCache.h index a156834517..2a7a9cad89 100644 --- a/ext/native/gfx/d3d9_state.h +++ b/Common/GPU/D3D9/D3D9StateCache.h @@ -1,9 +1,8 @@ #pragma once -#include -#include +#include -#include "gfx/d3d9_shader.h" +#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" namespace DX9 { diff --git a/ext/native/thin3d/d3d9_d3dcompiler_loader.cpp b/Common/GPU/D3D9/D3DCompilerLoader.cpp similarity index 87% rename from ext/native/thin3d/d3d9_d3dcompiler_loader.cpp rename to Common/GPU/D3D9/D3DCompilerLoader.cpp index 8cc76529fc..d47aa354f3 100644 --- a/ext/native/thin3d/d3d9_d3dcompiler_loader.cpp +++ b/Common/GPU/D3D9/D3DCompilerLoader.cpp @@ -1,13 +1,15 @@ -#include -#include +#include "ppsspp_config.h" + +#include "Common/CommonWindows.h" #include -#include "thin3d/d3d9_d3dcompiler_loader.h" +#include "Common/Log.h" +#include "Common/GPU/D3D9/D3DCompilerLoader.h" static HMODULE g_D3DCompileModule; extern pD3DCompile ptr_D3DCompile; -int d3dcompiler_version = 47; +static int d3dcompiler_version = 47; #define GB_MAKE_STR(s) # s #define GB_MAKE_STR2(x) GB_MAKE_STR(x) @@ -50,13 +52,10 @@ bool UnloadD3DCompiler() { return true; } - HRESULT dyn_D3DCompile(LPCSTR pSrcData, UINT SrcDataSize, LPCSTR pFileName, CONST D3D_SHADER_MACRO* pDefines, LPD3DINCLUDE pInclude, LPCSTR pEntrypoint, LPCSTR pTarget, UINT Flags1, UINT Flags2, LPD3DBLOB* ppShader, LPD3DBLOB* ppErrorMsgs) { - if (!g_D3DCompileModule) { - GB_D3D9_D3DCOMPILER_LOADER_CHECK_ENTRY_NULL_PTR(D3DCompile) - } + _assert_(g_D3DCompileModule != nullptr); return ptr_D3DCompile(pSrcData, SrcDataSize, pFileName, pDefines, pInclude, pEntrypoint, pTarget, Flags1, Flags2, ppShader, ppErrorMsgs); } diff --git a/ext/native/thin3d/d3d9_d3dcompiler_loader.h b/Common/GPU/D3D9/D3DCompilerLoader.h similarity index 100% rename from ext/native/thin3d/d3d9_d3dcompiler_loader.h rename to Common/GPU/D3D9/D3DCompilerLoader.h diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp similarity index 98% rename from ext/native/thin3d/thin3d_d3d9.cpp rename to Common/GPU/D3D9/thin3d_d3d9.cpp index 464da5c08d..1ec74c6ed9 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -13,29 +13,16 @@ #undef new #endif -#if PPSSPP_API(D3DX9) -#include -#ifdef USE_CRT_DBG -#define new DBG_NEW -#endif -#include "thin3d/d3dx9_loader.h" - -// They are the same types, just different names. -#define LPD3D_SHADER_MACRO LPD3DXMACRO -#define LPD3DINCLUDE LPD3DXINCLUDE -#define LPD3DBLOB LPD3DXBUFFER -#elif PPSSPP_API(D3D9_D3DCOMPILER) #include -#include "thin3d/d3d9_d3dcompiler_loader.h" -#endif +#include "Common/GPU/D3D9/D3DCompilerLoader.h" #ifndef D3DXERR_INVALIDDATA #define D3DXERR_INVALIDDATA 0x88760b59 #endif #include "Common/Math/lin/matrix4x4.h" -#include "thin3d/thin3d.h" -#include "gfx/d3d9_state.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/D3D9/D3D9StateCache.h" #include "Common/Log.h" @@ -1045,11 +1032,7 @@ bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, si LPD3DBLOB errorBuffer = nullptr; const char *source = (const char *)data; auto compile = [&](const char *profile) -> HRESULT { -#if PPSSPP_API(D3DX9) - return dyn_D3DXCompileShader(source, (UINT)strlen(source), defines, includes, "main", profile, flags, &codeBuffer, &errorBuffer, nullptr); -#elif PPSSPP_API(D3D9_D3DCOMPILER) return dyn_D3DCompile(source, (UINT)strlen(source), nullptr, defines, includes, "main", profile, 0, 0, &codeBuffer, &errorBuffer); -#endif }; HRESULT hr = compile(stage_ == ShaderStage::FRAGMENT ? "ps_2_0" : "vs_2_0"); if (FAILED(hr) && hr == D3DXERR_INVALIDDATA) { diff --git a/ext/native/thin3d/DataFormat.h b/Common/GPU/DataFormat.h similarity index 100% rename from ext/native/thin3d/DataFormat.h rename to Common/GPU/DataFormat.h diff --git a/ext/native/thin3d/DataFormatGL.cpp b/Common/GPU/OpenGL/DataFormatGL.cpp similarity index 97% rename from ext/native/thin3d/DataFormatGL.cpp rename to Common/GPU/OpenGL/DataFormatGL.cpp index 5037586691..1b8ba63acc 100644 --- a/ext/native/thin3d/DataFormatGL.cpp +++ b/Common/GPU/OpenGL/DataFormatGL.cpp @@ -1,4 +1,4 @@ -#include "thin3d/DataFormatGL.h" +#include "Common/GPU/OpenGL/DataFormatGL.h" #include "Common/Log.h" namespace Draw { diff --git a/ext/native/thin3d/DataFormatGL.h b/Common/GPU/OpenGL/DataFormatGL.h similarity index 67% rename from ext/native/thin3d/DataFormatGL.h rename to Common/GPU/OpenGL/DataFormatGL.h index 28b48f60ff..63fc0a22ec 100644 --- a/ext/native/thin3d/DataFormatGL.h +++ b/Common/GPU/OpenGL/DataFormatGL.h @@ -1,7 +1,7 @@ #pragma once -#include "gfx/gl_common.h" -#include "thin3d/DataFormat.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/DataFormat.h" namespace Draw { diff --git a/ext/native/gfx/gl_common.h b/Common/GPU/OpenGL/GLCommon.h similarity index 98% rename from ext/native/gfx/gl_common.h rename to Common/GPU/OpenGL/GLCommon.h index 011caa19e7..b9fbb3e413 100644 --- a/ext/native/gfx/gl_common.h +++ b/Common/GPU/OpenGL/GLCommon.h @@ -24,7 +24,7 @@ typedef char GLchar; #ifdef USING_GLES2 // Support OpenGL ES 3.0 // This uses the "DYNAMIC" approach from the gles3jni NDK sample. -#include "../gfx_es2/gl3stub.h" +#include "Common/GPU/OpenGL/gl3stub.h" #endif diff --git a/ext/native/gfx/gl_debug_log.cpp b/Common/GPU/OpenGL/GLDebugLog.cpp similarity index 94% rename from ext/native/gfx/gl_debug_log.cpp rename to Common/GPU/OpenGL/GLDebugLog.cpp index fc66ccf1dd..94b79dabc0 100644 --- a/ext/native/gfx/gl_debug_log.cpp +++ b/Common/GPU/OpenGL/GLDebugLog.cpp @@ -1,7 +1,7 @@ #include -#include "gfx/gl_common.h" -#include "gfx/gl_debug_log.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" #include "Common/Log.h" diff --git a/ext/native/gfx/gl_debug_log.h b/Common/GPU/OpenGL/GLDebugLog.h similarity index 100% rename from ext/native/gfx/gl_debug_log.h rename to Common/GPU/OpenGL/GLDebugLog.h diff --git a/ext/native/gfx_es2/gpu_features.cpp b/Common/GPU/OpenGL/GLFeatures.cpp similarity index 99% rename from ext/native/gfx_es2/gpu_features.cpp rename to Common/GPU/OpenGL/GLFeatures.cpp index f8b29909f3..7048b6198a 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/Common/GPU/OpenGL/GLFeatures.cpp @@ -6,14 +6,14 @@ #include "Common/StringUtils.h" #if PPSSPP_API(ANY_GL) -#include "gfx/gl_common.h" +#include "Common/GPU/OpenGL/GLCommon.h" #if defined(_WIN32) #include "GL/wglew.h" #endif #endif -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Log.h" diff --git a/ext/native/gfx_es2/gpu_features.h b/Common/GPU/OpenGL/GLFeatures.h similarity index 96% rename from ext/native/gfx_es2/gpu_features.h rename to Common/GPU/OpenGL/GLFeatures.h index 6f7dd50f54..0c4a619b45 100644 --- a/ext/native/gfx_es2/gpu_features.h +++ b/Common/GPU/OpenGL/GLFeatures.h @@ -11,9 +11,9 @@ enum { GPU_VENDOR_AMD = 2, GPU_VENDOR_INTEL = 3, GPU_VENDOR_ARM = 4, // Mali - GPU_VENDOR_IMGTEC = 5, - GPU_VENDOR_QUALCOMM = 6, - GPU_VENDOR_BROADCOM = 7, + GPU_VENDOR_IMGTEC = 5, // PowerVR + GPU_VENDOR_QUALCOMM = 6, // Adreno + GPU_VENDOR_BROADCOM = 7, // Raspberry PI etc GPU_VENDOR_VIVANTE = 8, GPU_VENDOR_UNKNOWN = 0, }; diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp similarity index 99% rename from ext/native/thin3d/GLQueueRunner.cpp rename to Common/GPU/OpenGL/GLQueueRunner.cpp index 6ce2682804..7776d7da4d 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -1,9 +1,9 @@ #include -#include "gfx/gl_common.h" -#include "gfx/gl_debug_log.h" -#include "gfx_es2/gpu_features.h" -#include "thin3d/DataFormatGL.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/GPU/OpenGL/DataFormatGL.h" #include "Common/Math/math_util.h" #include "Common/Log.h" diff --git a/ext/native/thin3d/GLQueueRunner.h b/Common/GPU/OpenGL/GLQueueRunner.h similarity index 99% rename from ext/native/thin3d/GLQueueRunner.h rename to Common/GPU/OpenGL/GLQueueRunner.h index 3737d13412..742f885768 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/Common/GPU/OpenGL/GLQueueRunner.h @@ -4,8 +4,8 @@ #include #include -#include "gfx/gl_common.h" -#include "thin3d/DataFormat.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/DataFormat.h" #include "Common/Data/Collections/TinySet.h" struct GLRViewport { diff --git a/ext/native/thin3d/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp similarity index 99% rename from ext/native/thin3d/GLRenderManager.cpp rename to Common/GPU/OpenGL/GLRenderManager.cpp index 1aa1d25949..7764adfde8 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -1,6 +1,6 @@ #include "GLRenderManager.h" -#include "gfx_es2/gpu_features.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/GPU/thin3d.h" #include "Common/Thread/ThreadUtil.h" #include "Common/Log.h" diff --git a/ext/native/thin3d/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h similarity index 99% rename from ext/native/thin3d/GLRenderManager.h rename to Common/GPU/OpenGL/GLRenderManager.h index 9fb0bc1847..a2f3a7effe 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -9,7 +9,7 @@ #include #include -#include "gfx/gl_common.h" +#include "Common/GPU/OpenGL/GLCommon.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Log.h" #include "GLQueueRunner.h" diff --git a/ext/native/gfx_es2/glsl_program.cpp b/Common/GPU/OpenGL/GLSLProgram.cpp similarity index 99% rename from ext/native/gfx_es2/glsl_program.cpp rename to Common/GPU/OpenGL/GLSLProgram.cpp index a0bc2a376e..bdc41644a4 100644 --- a/ext/native/gfx_es2/glsl_program.cpp +++ b/Common/GPU/OpenGL/GLSLProgram.cpp @@ -6,7 +6,7 @@ #include "Common/File/VFS/VFS.h" #include "Common/File/FileUtil.h" -#include "glsl_program.h" +#include "Common/GPU/OpenGL/GLSLProgram.h" #include "Common/Log.h" diff --git a/ext/native/gfx_es2/glsl_program.h b/Common/GPU/OpenGL/GLSLProgram.h similarity index 97% rename from ext/native/gfx_es2/glsl_program.h rename to Common/GPU/OpenGL/GLSLProgram.h index e2efd2a3d7..ae6020c43a 100644 --- a/ext/native/gfx_es2/glsl_program.h +++ b/Common/GPU/OpenGL/GLSLProgram.h @@ -7,7 +7,7 @@ #include #include -#include "gfx/gl_common.h" +#include "Common/GPU/OpenGL/GLCommon.h" // Represent a compiled and linked vshader/fshader pair. // A just-constructed object is valid but cannot be used as a shader program, meaning that diff --git a/ext/native/gfx_es2/gl3stub.c b/Common/GPU/OpenGL/gl3stub.c similarity index 99% rename from ext/native/gfx_es2/gl3stub.c rename to Common/GPU/OpenGL/gl3stub.c index 265004a9c3..28bbcd774a 100644 --- a/ext/native/gfx_es2/gl3stub.c +++ b/Common/GPU/OpenGL/gl3stub.c @@ -15,7 +15,8 @@ */ #include "ppsspp_config.h" -#include "../gfx/gl_common.h" + +#include "Common/GPU/OpenGL/GLCommon.h" #if defined(USING_GLES2) #if !PPSSPP_PLATFORM(IOS) diff --git a/ext/native/gfx_es2/gl3stub.h b/Common/GPU/OpenGL/gl3stub.h similarity index 100% rename from ext/native/gfx_es2/gl3stub.h rename to Common/GPU/OpenGL/gl3stub.h diff --git a/ext/native/thin3d/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp similarity index 99% rename from ext/native/thin3d/thin3d_gl.cpp rename to Common/GPU/OpenGL/thin3d_gl.cpp index 222b918a16..a58432e14b 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -7,13 +7,13 @@ #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Math/math_util.h" #include "Common/Math/lin/matrix4x4.h" -#include "thin3d/thin3d.h" -#include "thin3d/DataFormatGL.h" -#include "gfx/gl_common.h" -#include "gfx/gl_debug_log.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/OpenGL/DataFormatGL.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" +#include "Common/GPU/OpenGL/GLFeatures.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" // #define DEBUG_READ_PIXELS 1 diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/GPU/Vulkan/VulkanContext.cpp similarity index 99% rename from Common/Vulkan/VulkanContext.cpp rename to Common/GPU/Vulkan/VulkanContext.cpp index 7e0338936d..ef139e4ca7 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/GPU/Vulkan/VulkanContext.cpp @@ -7,8 +7,8 @@ #include "Common/System/Display.h" #include "Common/Log.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanDebug.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanDebug.h" #include "GPU/Common/ShaderCommon.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/Common/Vulkan/VulkanContext.h b/Common/GPU/Vulkan/VulkanContext.h similarity index 99% rename from Common/Vulkan/VulkanContext.h rename to Common/GPU/Vulkan/VulkanContext.h index fa12d26d79..a14f96bdd7 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/GPU/Vulkan/VulkanContext.h @@ -6,8 +6,8 @@ #include #include "Common/Log.h" -#include "Common/Vulkan/VulkanLoader.h" -#include "Common/Vulkan/VulkanDebug.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanDebug.h" enum { VULKAN_FLAG_VALIDATE = 1, diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/GPU/Vulkan/VulkanDebug.cpp similarity index 97% rename from Common/Vulkan/VulkanDebug.cpp rename to Common/GPU/Vulkan/VulkanDebug.cpp index 5567586822..f165d73609 100644 --- a/Common/Vulkan/VulkanDebug.cpp +++ b/Common/GPU/Vulkan/VulkanDebug.cpp @@ -19,8 +19,8 @@ #include #include "Common/Log.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanDebug.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanDebug.h" VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, diff --git a/Common/Vulkan/VulkanDebug.h b/Common/GPU/Vulkan/VulkanDebug.h similarity index 96% rename from Common/Vulkan/VulkanDebug.h rename to Common/GPU/Vulkan/VulkanDebug.h index e622f542c7..9287c1e8c5 100644 --- a/Common/Vulkan/VulkanDebug.h +++ b/Common/GPU/Vulkan/VulkanDebug.h @@ -17,7 +17,7 @@ #pragma once -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" struct VulkanLogOptions { bool breakOnWarning; diff --git a/Common/Vulkan/VulkanImage.cpp b/Common/GPU/Vulkan/VulkanImage.cpp similarity index 99% rename from Common/Vulkan/VulkanImage.cpp rename to Common/GPU/Vulkan/VulkanImage.cpp index 37a7bead4d..5301a47803 100644 --- a/Common/Vulkan/VulkanImage.cpp +++ b/Common/GPU/Vulkan/VulkanImage.cpp @@ -1,5 +1,5 @@ -#include "Common/Vulkan/VulkanImage.h" -#include "Common/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanImage.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" #include "Common/Log.h" void VulkanTexture::Wipe() { diff --git a/Common/Vulkan/VulkanImage.h b/Common/GPU/Vulkan/VulkanImage.h similarity index 98% rename from Common/Vulkan/VulkanImage.h rename to Common/GPU/Vulkan/VulkanImage.h index e16ceccc8d..0745e0e352 100644 --- a/Common/Vulkan/VulkanImage.h +++ b/Common/GPU/Vulkan/VulkanImage.h @@ -1,6 +1,6 @@ #pragma once -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" class VulkanDeviceAllocator; diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/GPU/Vulkan/VulkanLoader.cpp similarity index 99% rename from Common/Vulkan/VulkanLoader.cpp rename to Common/GPU/Vulkan/VulkanLoader.cpp index 0a58291277..f319979c8a 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/GPU/Vulkan/VulkanLoader.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "Common/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" #include #include #include diff --git a/Common/Vulkan/VulkanLoader.h b/Common/GPU/Vulkan/VulkanLoader.h similarity index 100% rename from Common/Vulkan/VulkanLoader.h rename to Common/GPU/Vulkan/VulkanLoader.h diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/GPU/Vulkan/VulkanMemory.cpp similarity index 99% rename from Common/Vulkan/VulkanMemory.cpp rename to Common/GPU/Vulkan/VulkanMemory.cpp index 9674fb702a..ce002733b7 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/GPU/Vulkan/VulkanMemory.cpp @@ -22,7 +22,7 @@ #include "Common/Log.h" #include "Common/TimeUtil.h" -#include "Common/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryPropertyMask) : vulkan_(vulkan), memoryPropertyMask_(memoryPropertyMask), size_(size), usage_(usage) { diff --git a/Common/Vulkan/VulkanMemory.h b/Common/GPU/Vulkan/VulkanMemory.h similarity index 99% rename from Common/Vulkan/VulkanMemory.h rename to Common/GPU/Vulkan/VulkanMemory.h index 54b41aed71..fc415681a0 100644 --- a/Common/Vulkan/VulkanMemory.h +++ b/Common/GPU/Vulkan/VulkanMemory.h @@ -4,7 +4,7 @@ #include #include "Common/Log.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" // VulkanMemory // diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/Common/GPU/Vulkan/VulkanQueueRunner.cpp similarity index 99% rename from ext/native/thin3d/VulkanQueueRunner.cpp rename to Common/GPU/Vulkan/VulkanQueueRunner.cpp index c563fc9851..ff5fb56d2f 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/Common/GPU/Vulkan/VulkanQueueRunner.cpp @@ -1,6 +1,6 @@ #include -#include "DataFormat.h" +#include "Common/GPU/DataFormat.h" #include "Common/Log.h" #include "Common/TimeUtil.h" #include "VulkanQueueRunner.h" diff --git a/ext/native/thin3d/VulkanQueueRunner.h b/Common/GPU/Vulkan/VulkanQueueRunner.h similarity index 98% rename from ext/native/thin3d/VulkanQueueRunner.h rename to Common/GPU/Vulkan/VulkanQueueRunner.h index 1bad9619ce..6c8f12cdc3 100644 --- a/ext/native/thin3d/VulkanQueueRunner.h +++ b/Common/GPU/Vulkan/VulkanQueueRunner.h @@ -3,10 +3,10 @@ #include #include "Common/Hashmaps.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" #include "Common/Data/Convert/SmallDataConvert.h" -#include "thin3d/DataFormat.h" #include "Common/Data/Collections/TinySet.h" +#include "Common/GPU/DataFormat.h" class VKRFramebuffer; struct VKRImage; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp similarity index 99% rename from ext/native/thin3d/VulkanRenderManager.cpp rename to Common/GPU/Vulkan/VulkanRenderManager.cpp index ecd776b2a7..df224391a3 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -6,8 +6,8 @@ #include "Common/Log.h" #include "Common/StringUtils.h" -#include "Common/Vulkan/VulkanContext.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/Thread/ThreadUtil.h" #if 0 // def _DEBUG diff --git a/ext/native/thin3d/VulkanRenderManager.h b/Common/GPU/Vulkan/VulkanRenderManager.h similarity index 99% rename from ext/native/thin3d/VulkanRenderManager.h rename to Common/GPU/Vulkan/VulkanRenderManager.h index 653fbae850..d1a781c7b3 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/Common/GPU/Vulkan/VulkanRenderManager.h @@ -11,11 +11,11 @@ #include #include "Common/System/Display.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Math/math_util.h" -#include "thin3d/DataFormat.h" -#include "thin3d/VulkanQueueRunner.h" +#include "Common/GPU/DataFormat.h" +#include "Common/GPU/Vulkan/VulkanQueueRunner.h" // Simple independent framebuffer image. Gets its own allocation, we don't have that many framebuffers so it's fine // to let them have individual non-pooled allocations. Until it's not fine. We'll see. diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp similarity index 99% rename from ext/native/thin3d/thin3d_vulkan.cpp rename to Common/GPU/Vulkan/thin3d_vulkan.cpp index 5d691c64ca..502a5194f5 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -23,14 +23,14 @@ #include "Common/System/Display.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Data/Convert/SmallDataConvert.h" -#include "thin3d/thin3d.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/Log.h" #include "Common/StringUtils.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanImage.h" -#include "Common/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanImage.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" #include "Core/Config.h" @@ -41,7 +41,7 @@ // // Vertex data lives in a separate namespace (location = 0, 1, etc) -#include "Common/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" namespace Draw { diff --git a/ext/native/thin3d/thin3d.cpp b/Common/GPU/thin3d.cpp similarity index 99% rename from ext/native/thin3d/thin3d.cpp rename to Common/GPU/thin3d.cpp index f15e96fa93..dfac21e038 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/Common/GPU/thin3d.cpp @@ -3,7 +3,7 @@ #include #include "Common/System/Display.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Log.h" #include "Common/ColorConv.h" #include "Core/Reporting.h" diff --git a/ext/native/thin3d/thin3d.h b/Common/GPU/thin3d.h similarity index 100% rename from ext/native/thin3d/thin3d.h rename to Common/GPU/thin3d.h diff --git a/ext/native/thin3d/thin3d_create.h b/Common/GPU/thin3d_create.h similarity index 97% rename from ext/native/thin3d/thin3d_create.h rename to Common/GPU/thin3d_create.h index a89c74ab96..a2030792af 100644 --- a/ext/native/thin3d/thin3d_create.h +++ b/Common/GPU/thin3d_create.h @@ -2,7 +2,7 @@ #include #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" // Separated this stuff into its own file so we don't get Windows.h included if all we want is the thin3d declarations. diff --git a/Common/GraphicsContext.h b/Common/GraphicsContext.h index bf4f493871..873722764c 100644 --- a/Common/GraphicsContext.h +++ b/Common/GraphicsContext.h @@ -2,7 +2,7 @@ #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" // Init is done differently on each platform, and done close to the creation, so it's // expected to be implemented by subclasses. diff --git a/Common/Profiler/Profiler.cpp b/Common/Profiler/Profiler.cpp index 923a9aed62..7d3521012e 100644 --- a/Common/Profiler/Profiler.cpp +++ b/Common/Profiler/Profiler.cpp @@ -9,7 +9,7 @@ #include "ppsspp_config.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/TimeUtil.h" #include "Common/Profiler/Profiler.h" diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/Common/Render/DrawBuffer.cpp similarity index 99% rename from ext/native/gfx_es2/draw_buffer.cpp rename to Common/Render/DrawBuffer.cpp index a31f938584..d0d2e42a87 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/Common/Render/DrawBuffer.cpp @@ -5,9 +5,8 @@ #include "Common/System/Display.h" #include "Common/Math/math_util.h" -#include "gfx/texture_atlas.h" -#include "gfx/gl_debug_log.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/TextureAtlas.h" +#include "Common/Render/DrawBuffer.h" #include "gfx_es2/draw_text.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Text/WrapText.h" diff --git a/ext/native/gfx_es2/draw_buffer.h b/Common/Render/DrawBuffer.h similarity index 98% rename from ext/native/gfx_es2/draw_buffer.h rename to Common/Render/DrawBuffer.h index bfcd756010..40d482ef83 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/Common/Render/DrawBuffer.h @@ -6,10 +6,10 @@ #include #include "Common/Data/Color/RGBAUtil.h" -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "Common/Math/geom2d.h" #include "Common/Math/lin/matrix4x4.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" struct Atlas; diff --git a/ext/native/gfx/texture_atlas.cpp b/Common/Render/TextureAtlas.cpp similarity index 98% rename from ext/native/gfx/texture_atlas.cpp rename to Common/Render/TextureAtlas.cpp index a38a791fa3..285f766892 100644 --- a/ext/native/gfx/texture_atlas.cpp +++ b/Common/Render/TextureAtlas.cpp @@ -1,7 +1,7 @@ #include #include -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" class ByteReader { public: diff --git a/ext/native/gfx/texture_atlas.h b/Common/Render/TextureAtlas.h similarity index 100% rename from ext/native/gfx/texture_atlas.h rename to Common/Render/TextureAtlas.h diff --git a/Common/UI/Context.cpp b/Common/UI/Context.cpp index d8f45b5737..467aa35166 100644 --- a/Common/UI/Context.cpp +++ b/Common/UI/Context.cpp @@ -7,7 +7,7 @@ #include "Common/UI/UI.h" #include "Common/UI/View.h" #include "Common/UI/Context.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "gfx_es2/draw_text.h" #include "Common/Log.h" diff --git a/Common/UI/Context.h b/Common/UI/Context.h index 696e8b6bb8..18f18bd515 100644 --- a/Common/UI/Context.h +++ b/Common/UI/Context.h @@ -6,7 +6,7 @@ #include "Common/Math/geom2d.h" #include "Common/Math/lin/vec3.h" -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" // Everything you need to draw a UI collected into a single unit that can be passed around. // Everything forward declared so this header is safe everywhere. diff --git a/Common/UI/UI.cpp b/Common/UI/UI.cpp index 3148a0de57..8a4ad5deaf 100644 --- a/Common/UI/UI.cpp +++ b/Common/UI/UI.cpp @@ -8,8 +8,8 @@ #include "Common/Data/Color/RGBAUtil.h" #include "Common/UI/UI.h" #include "Common/UI/Context.h" -#include "gfx/texture_atlas.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/TextureAtlas.h" +#include "Common/Render/DrawBuffer.h" // TODO: UI should probably not own these. DrawBuffer ui_draw2d; diff --git a/Common/UI/UI.h b/Common/UI/UI.h index 3e891a9a28..ccd6b50dbe 100644 --- a/Common/UI/UI.h +++ b/Common/UI/UI.h @@ -26,7 +26,7 @@ #include #include -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Input/InputState.h" class UIContext; diff --git a/Common/UI/UIScreen.cpp b/Common/UI/UIScreen.cpp index 14f793d1e5..8e8d447dc9 100644 --- a/Common/UI/UIScreen.cpp +++ b/Common/UI/UIScreen.cpp @@ -11,7 +11,7 @@ #include "Common/UI/Screen.h" #include "Common/UI/Root.h" #include "Common/Data/Text/I18n.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index ece140377b..ebd0e993e7 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -3,15 +3,15 @@ #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" -#include "gfx_es2/draw_buffer.h" -#include "gfx/texture_atlas.h" +#include "Common/Render/DrawBuffer.h" +#include "Common/Render/TextureAtlas.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/UI/UI.h" #include "Common/UI/View.h" #include "Common/UI/Context.h" #include "Common/UI/Tween.h" #include "Common/UI/Root.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/System/System.h" #include "Common/TimeUtil.h" #include "Common/StringUtils.h" diff --git a/Common/UI/View.h b/Common/UI/View.h index 8c46ff9060..97c5c10513 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -15,7 +15,7 @@ #include #include -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Math/math_util.h" #include "Common/Math/geom2d.h" diff --git a/Common/UI/ViewGroup.cpp b/Common/UI/ViewGroup.cpp index ddd6153548..4c21baeb5e 100644 --- a/Common/UI/ViewGroup.cpp +++ b/Common/UI/ViewGroup.cpp @@ -10,7 +10,7 @@ #include "Common/UI/Root.h" #include "Common/UI/View.h" #include "Common/UI/ViewGroup.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Log.h" #include "Common/TimeUtil.h" diff --git a/Core/Config.cpp b/Core/Config.cpp index 7264f38859..0efc72f014 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -24,7 +24,7 @@ #include "ppsspp_config.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Net/HTTPClient.h" #include "Common/Net/URL.h" @@ -40,7 +40,7 @@ #include "Common/System/Display.h" #include "Common/System/System.h" #include "Common/StringUtils.h" -#include "Common/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Loaders.h" diff --git a/Core/Dialog/PSPDialog.h b/Core/Dialog/PSPDialog.h index 8d88c5c1a7..abf652f18c 100644 --- a/Core/Dialog/PSPDialog.h +++ b/Core/Dialog/PSPDialog.h @@ -17,7 +17,7 @@ #pragma once -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "Common/Common.h" #include "Common/CommonTypes.h" diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 6df19c4cea..1b97a35336 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -26,8 +26,6 @@ #include #endif -#include "gfx_es2/gpu_features.h" - #include "Common/Data/Text/I18n.h" #include "Common/Profiler/Profiler.h" #include "Common/System/System.h" @@ -315,7 +313,8 @@ void __DisplayDoState(PointerWrap &p) { if (s < 2) { // This shouldn't have been savestated anyway, but it was. // It's unlikely to overlap with the first value in gpuStats. - p.ExpectVoid(&gl_extensions.gpuVendor, sizeof(gl_extensions.gpuVendor)); + int gpuVendorTemp = 0; + p.ExpectVoid(&gpuVendorTemp, sizeof(gpuVendorTemp)); } if (s < 6) { GPUStatistics_v0 oldStats; diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 4f33737351..b24802944d 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -17,7 +17,7 @@ #include -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "gfx_es2/draw_text.h" #include "Common/Data/Color/RGBAUtil.h" diff --git a/Core/Util/PPGeDraw.h b/Core/Util/PPGeDraw.h index c9b625f40f..dbff6bb831 100644 --- a/Core/Util/PPGeDraw.h +++ b/Core/Util/PPGeDraw.h @@ -20,7 +20,7 @@ #include #include -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "Common/CommonTypes.h" diff --git a/GPU/Common/DepalettizeShaderCommon.cpp b/GPU/Common/DepalettizeShaderCommon.cpp index d435d6ca28..23b662c672 100644 --- a/GPU/Common/DepalettizeShaderCommon.cpp +++ b/GPU/Common/DepalettizeShaderCommon.cpp @@ -17,7 +17,7 @@ #include -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "GPU/Common/ShaderId.h" #include "GPU/Common/ShaderCommon.h" diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 4accc058c5..3df2eaddfd 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -19,9 +19,8 @@ #include #include -#include "ext/native/thin3d/thin3d.h" -#include "gfx_es2/gpu_features.h" - +#include "Common/GPU/thin3d.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Data/Text/I18n.h" #include "Common/ColorConv.h" #include "Common/Common.h" diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 1dc6abcde8..44cd2f6b5f 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -27,7 +27,7 @@ #include "GPU/GPU.h" #include "GPU/ge_constants.h" #include "GPU/GPUInterface.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" enum { FB_USAGE_DISPLAYED_FRAMEBUFFER = 1, diff --git a/GPU/Common/PostShader.cpp b/GPU/Common/PostShader.cpp index a1c030dd3a..9971650ba5 100644 --- a/GPU/Common/PostShader.cpp +++ b/GPU/Common/PostShader.cpp @@ -26,7 +26,7 @@ #include "Common/File/FileUtil.h" #include "Common/File/DirListing.h" #include "Common/File/VFS/VFS.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 31e36a847c..5d62f1a7fe 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -19,7 +19,7 @@ #include #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/System/Display.h" #include "Common/System/System.h" diff --git a/GPU/Common/ShaderId.cpp b/GPU/Common/ShaderId.cpp index b33738f508..3f5864161a 100644 --- a/GPU/Common/ShaderId.cpp +++ b/GPU/Common/ShaderId.cpp @@ -1,7 +1,7 @@ #include #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/StringUtils.h" #include "Core/Config.h" diff --git a/GPU/Common/ShaderTranslation.cpp b/GPU/Common/ShaderTranslation.cpp index b93df766e5..25edef6297 100644 --- a/GPU/Common/ShaderTranslation.cpp +++ b/GPU/Common/ShaderTranslation.cpp @@ -39,8 +39,8 @@ #include "GPU/Common/ShaderTranslation.h" #include "ext/glslang/SPIRV/GlslangToSpv.h" -#include "thin3d/thin3d.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "ext/SPIRV-Cross/spirv.hpp" #include "ext/SPIRV-Cross/spirv_common.hpp" diff --git a/GPU/Common/ShaderTranslation.h b/GPU/Common/ShaderTranslation.h index 5985623661..9d4e41e3f1 100644 --- a/GPU/Common/ShaderTranslation.h +++ b/GPU/Common/ShaderTranslation.h @@ -19,7 +19,7 @@ #include #include "GPU/Common/ShaderCommon.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" struct TranslatedShaderMetadata { diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 2f68d891e0..0a369204b9 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -18,7 +18,7 @@ #include #include #include "Common/Math/math_util.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Core/Config.h" #include "GPU/GPUState.h" diff --git a/GPU/D3D11/D3D11Util.cpp b/GPU/D3D11/D3D11Util.cpp index 27fcc093dd..ee6ad435d3 100644 --- a/GPU/D3D11/D3D11Util.cpp +++ b/GPU/D3D11/D3D11Util.cpp @@ -10,7 +10,7 @@ #if PPSSPP_PLATFORM(UWP) #define ptr_D3DCompile D3DCompile #else -#include "thin3d/d3d11_loader.h" +#include "Common/GPU/D3D11/D3D11Loader.h" #endif #include "Common/CommonFuncs.h" diff --git a/GPU/D3D11/DepalettizeShaderD3D11.h b/GPU/D3D11/DepalettizeShaderD3D11.h index df9c4f5133..0941330fa6 100644 --- a/GPU/D3D11/DepalettizeShaderD3D11.h +++ b/GPU/D3D11/DepalettizeShaderD3D11.h @@ -22,7 +22,7 @@ #include "Common/CommonTypes.h" #include "GPU/ge_constants.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "GPU/Common/DepalettizeShaderCommon.h" class DepalShaderD3D11 { diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index f4d4854049..792f11f79e 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -21,7 +21,7 @@ #include "Common/System/Display.h" #include "Common/Math/lin/matrix4x4.h" -#include "ext/native/thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Common.h" #include "Common/ColorConv.h" diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index e951e277a1..a8a4089198 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -25,7 +25,7 @@ #include "GPU/GPUCommon.h" #include "GPU/Common/FramebufferManagerCommon.h" -#include "ext/native/thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" class TextureCacheD3D11; class DrawEngineD3D11; diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index a6c23e1c9d..4678f4ae65 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -25,7 +25,7 @@ #include "Common/Math/lin/matrix4x4.h" #include "Common/Math/math_util.h" #include "Common/Data/Convert/SmallDataConvert.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Log.h" #include "Common/Common.h" diff --git a/GPU/D3D11/StateMappingD3D11.h b/GPU/D3D11/StateMappingD3D11.h index df6f4a2adf..b6e356d4de 100644 --- a/GPU/D3D11/StateMappingD3D11.h +++ b/GPU/D3D11/StateMappingD3D11.h @@ -3,7 +3,7 @@ #include #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" // TODO: Do this more progressively. No need to compute the entire state if the entire state hasn't changed. diff --git a/GPU/D3D11/StencilBufferD3D11.cpp b/GPU/D3D11/StencilBufferD3D11.cpp index 5c988d7e61..4da469ae61 100644 --- a/GPU/D3D11/StencilBufferD3D11.cpp +++ b/GPU/D3D11/StencilBufferD3D11.cpp @@ -17,7 +17,7 @@ #include -#include "ext/native/thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Log.h" #include "Core/Reporting.h" diff --git a/GPU/Directx9/DepalettizeShaderDX9.cpp b/GPU/Directx9/DepalettizeShaderDX9.cpp index ec91de50ba..bff0c04933 100644 --- a/GPU/Directx9/DepalettizeShaderDX9.cpp +++ b/GPU/Directx9/DepalettizeShaderDX9.cpp @@ -18,14 +18,14 @@ #include #include -#include "thin3d/thin3d.h" +#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" +#include "Common/GPU/thin3d.h" #include "Common/Log.h" #include "Common/StringUtils.h" #include "Core/Reporting.h" #include "GPU/Directx9/TextureCacheDX9.h" #include "GPU/Directx9/DepalettizeShaderDX9.h" #include "GPU/Common/DepalettizeShaderCommon.h" -#include "gfx/d3d9_shader.h" namespace DX9 { diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index a0f4a8c743..c464652318 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -26,7 +26,7 @@ #include "Core/Config.h" #include "Core/CoreTiming.h" -#include "gfx/d3d9_state.h" +#include "Common/GPU/D3D9/D3D9StateCache.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 21cfa45c99..0c9c2d5720 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/Math/lin/matrix4x4.h" -#include "ext/native/thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/ColorConv.h" #include "Core/MemMap.h" @@ -28,7 +28,7 @@ #include "GPU/GPUState.h" #include "GPU/Debugger/Stepping.h" -#include "gfx/d3d9_state.h" +#include "Common/GPU/D3D9/D3D9StateCache.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/ShaderTranslation.h" @@ -38,7 +38,7 @@ #include "GPU/Directx9/TextureCacheDX9.h" #include "GPU/Directx9/DrawEngineDX9.h" -#include "ext/native/thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 5db0cbffd8..439b443cd7 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -31,7 +31,7 @@ #include "Core/Reporting.h" #include "Core/System.h" -#include "gfx/d3d9_state.h" +#include "Common/GPU/D3D9/D3D9StateCache.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index e292f185c4..f7c331907e 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -22,12 +22,12 @@ #include #include -#include "gfx/d3d9_shader.h" #include "Common/Data/Text/I18n.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Math/math_util.h" #include "Common/Data/Convert/SmallDataConvert.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Common.h" diff --git a/GPU/Directx9/ShaderManagerDX9.h b/GPU/Directx9/ShaderManagerDX9.h index 31458e1fee..a71b95d2e5 100644 --- a/GPU/Directx9/ShaderManagerDX9.h +++ b/GPU/Directx9/ShaderManagerDX9.h @@ -25,7 +25,6 @@ #include "GPU/Directx9/PixelShaderGeneratorDX9.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/ShaderId.h" -#include "thin3d/d3dx9_loader.h" #include "Common/Math/lin/matrix4x4.h" namespace DX9 { diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 0efeaf996e..a3ae081396 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -16,15 +16,16 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/Profiler/Profiler.h" -#include "GPU/Math3D.h" -#include "GPU/GPUState.h" -#include "GPU/ge_constants.h" +#include "Common/GPU/D3D9/D3D9ShaderCompiler.h" +#include "Common/GPU/D3D9/D3D9StateCache.h" + #include "Core/System.h" #include "Core/Config.h" #include "Core/Reporting.h" -#include "gfx/d3d9_shader.h" -#include "gfx/d3d9_state.h" +#include "GPU/Math3D.h" +#include "GPU/GPUState.h" +#include "GPU/ge_constants.h" #include "GPU/Directx9/GPU_DX9.h" #include "GPU/Directx9/ShaderManagerDX9.h" diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index baa173adeb..d938e4339a 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -17,8 +17,8 @@ #include -#include "gfx/d3d9_state.h" -#include "ext/native/thin3d/thin3d.h" +#include "Common/GPU/D3D9/D3D9StateCache.h" +#include "Common/GPU/thin3d.h" #include "Core/Reporting.h" #include "GPU/Common/StencilCommon.h" #include "GPU/Directx9/FramebufferManagerDX9.h" diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 06e2a34b5a..c867418a3f 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -27,7 +27,7 @@ #include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/ShaderManagerDX9.h" #include "GPU/Directx9/DepalettizeShaderDX9.h" -#include "gfx/d3d9_state.h" +#include "Common/GPU/D3D9/D3D9StateCache.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/TextureDecoder.h" #include "Core/Config.h" diff --git a/GPU/GLES/DepalettizeShaderGLES.h b/GPU/GLES/DepalettizeShaderGLES.h index 4368780ebd..fd9c5da7af 100644 --- a/GPU/GLES/DepalettizeShaderGLES.h +++ b/GPU/GLES/DepalettizeShaderGLES.h @@ -18,9 +18,9 @@ #include #include "Common/CommonTypes.h" -#include "gfx/gl_common.h" -#include "thin3d/thin3d.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "GPU/ge_constants.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/DepalettizeShaderCommon.h" diff --git a/GPU/GLES/DepthBufferGLES.cpp b/GPU/GLES/DepthBufferGLES.cpp index 66a83b972f..fa3ca00c5c 100644 --- a/GPU/GLES/DepthBufferGLES.cpp +++ b/GPU/GLES/DepthBufferGLES.cpp @@ -17,7 +17,7 @@ #include -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Core/ConfigValues.h" #include "Core/Reporting.h" #include "GPU/Common/GPUStateUtils.h" diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 759f3541b5..deb288bd85 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -25,7 +25,7 @@ #include "Core/Config.h" #include "Core/CoreTiming.h" -#include "gfx/gl_debug_log.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" #include "Common/Profiler/Profiler.h" #include "GPU/Math3D.h" diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index f484034e11..6c96072185 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -27,8 +27,8 @@ #include "GPU/Common/DrawEngineCommon.h" #include "GPU/Common/GPUStateUtils.h" #include "GPU/GLES/FragmentShaderGeneratorGLES.h" -#include "gfx/gl_common.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" class LinkedShader; class ShaderManagerGLES; diff --git a/GPU/GLES/FragmentShaderGeneratorGLES.cpp b/GPU/GLES/FragmentShaderGeneratorGLES.cpp index 945f3fb17b..82586c3ea6 100644 --- a/GPU/GLES/FragmentShaderGeneratorGLES.cpp +++ b/GPU/GLES/FragmentShaderGeneratorGLES.cpp @@ -20,7 +20,7 @@ #include "Common/Log.h" #include "Common/StringUtils.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Core/Reporting.h" #include "Core/Config.h" #include "GPU/Common/GPUStateUtils.h" diff --git a/GPU/GLES/FragmentTestCacheGLES.cpp b/GPU/GLES/FragmentTestCacheGLES.cpp index a9459cd49a..47a23efc4d 100644 --- a/GPU/GLES/FragmentTestCacheGLES.cpp +++ b/GPU/GLES/FragmentTestCacheGLES.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "thin3d/thin3d.h" -#include "gfx/gl_debug_log.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" #include "Core/Config.h" #include "GPU/GLES/FragmentTestCacheGLES.h" #include "GPU/GPUState.h" diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index ac4faa624a..c551b7756f 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -18,10 +18,10 @@ #include #include "Common/Profiler/Profiler.h" -#include "gfx/gl_common.h" -#include "gfx/gl_debug_log.h" -#include "gfx_es2/glsl_program.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" +#include "Common/GPU/OpenGL/GLSLProgram.h" +#include "Common/GPU/thin3d.h" #include "Common/ColorConv.h" #include "Core/MemMap.h" #include "Core/Config.h" diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 9177b62767..51d44af73c 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -17,14 +17,14 @@ #pragma once -#include "ext/native/thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" // Keeps track of allocated FBOs. // Also provides facilities for drawing and later converting raw // pixel data. #include "GPU/GPUCommon.h" #include "GPU/Common/FramebufferManagerCommon.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" struct GLSLProgram; class TextureCacheGLES; diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index d61d2adf76..e4e3d4fda4 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -24,14 +24,14 @@ #include #include "Common/Data/Convert/SmallDataConvert.h" -#include "gfx/gl_debug_log.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Profiler/Profiler.h" -#include "thin3d/thin3d.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "Common/Log.h" #include "Common/File/FileUtil.h" diff --git a/GPU/GLES/ShaderManagerGLES.h b/GPU/GLES/ShaderManagerGLES.h index 0c10d3ad73..a084edff1c 100644 --- a/GPU/GLES/ShaderManagerGLES.h +++ b/GPU/GLES/ShaderManagerGLES.h @@ -20,7 +20,7 @@ #include #include "Common/Hashmaps.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/ShaderId.h" #include "GPU/GLES/VertexShaderGeneratorGLES.h" diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 8856bd517f..46883171c7 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -22,8 +22,8 @@ #include "StateMappingGLES.h" #include "Common/Profiler/Profiler.h" -#include "gfx/gl_debug_log.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "GPU/Math3D.h" #include "GPU/GPUState.h" diff --git a/GPU/GLES/StateMappingGLES.h b/GPU/GLES/StateMappingGLES.h index da4a271551..7fe7f082fa 100644 --- a/GPU/GLES/StateMappingGLES.h +++ b/GPU/GLES/StateMappingGLES.h @@ -17,4 +17,4 @@ #pragma once -#include "gfx/gl_common.h" +#include "Common/GPU/OpenGL/GLCommon.h" diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index dce997ae81..1c19fa09e8 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "gfx_es2/glsl_program.h" +#include "Common/GPU/OpenGL/GLSLProgram.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Reporting.h" diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 62844159a7..822143f3df 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -19,11 +19,10 @@ #include #include "ext/xxhash.h" -#include "gfx/gl_debug_log.h" #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" #include "Common/Profiler/Profiler.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "Common/ColorConv.h" #include "Core/Config.h" diff --git a/GPU/GLES/TextureCacheGLES.h b/GPU/GLES/TextureCacheGLES.h index f148fd3f68..1b3ba422e3 100644 --- a/GPU/GLES/TextureCacheGLES.h +++ b/GPU/GLES/TextureCacheGLES.h @@ -19,9 +19,9 @@ #include -#include "gfx_es2/gpu_features.h" -#include "gfx/gl_common.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" #include "GPU/GLES/TextureScalerGLES.h" diff --git a/GPU/GLES/TextureScalerGLES.cpp b/GPU/GLES/TextureScalerGLES.cpp index d05e12c95b..d268fe92e1 100644 --- a/GPU/GLES/TextureScalerGLES.cpp +++ b/GPU/GLES/TextureScalerGLES.cpp @@ -16,14 +16,14 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "gfx/gl_common.h" +#include "Common/GPU/OpenGL/GLCommon.h" #include "GPU/Common/TextureScalerCommon.h" #include "GPU/GLES/TextureScalerGLES.h" #include "Common/ColorConv.h" #include "Common/Log.h" #include "Common/ThreadPools.h" -#include "thin3d/DataFormat.h" +#include "Common/GPU/DataFormat.h" int TextureScalerGLES::BytesPerPixel(u32 format) { return ((Draw::DataFormat)format == Draw::DataFormat::R8G8B8A8_UNORM) ? 4 : 2; diff --git a/GPU/GLES/VertexShaderGeneratorGLES.cpp b/GPU/GLES/VertexShaderGeneratorGLES.cpp index c3f3a0b716..8f775d2647 100644 --- a/GPU/GLES/VertexShaderGeneratorGLES.cpp +++ b/GPU/GLES/VertexShaderGeneratorGLES.cpp @@ -19,7 +19,7 @@ #include #include -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #if defined(_WIN32) && defined(_DEBUG) #include "Common/CommonWindows.h" diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 6dd2fcd78f..f5c53b7bbb 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/System/Display.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "GPU/GPUState.h" #include "GPU/ge_constants.h" @@ -33,7 +33,7 @@ #include "Core/Reporting.h" #include "Core/Core.h" #include "Common/Profiler/Profiler.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "GPU/Software/Rasterizer.h" #include "GPU/Software/Sampler.h" diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index fc9bf68b7e..bd8e6a12fe 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -19,7 +19,7 @@ #include "GPU/GPUCommon.h" #include "GPU/Common/GPUDebugInterface.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" struct FormatBuffer { FormatBuffer() { data = nullptr; } diff --git a/GPU/Vulkan/DebugVisVulkan.cpp b/GPU/Vulkan/DebugVisVulkan.cpp index 7b55caa41c..78616e86c5 100644 --- a/GPU/Vulkan/DebugVisVulkan.cpp +++ b/GPU/Vulkan/DebugVisVulkan.cpp @@ -15,14 +15,14 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "gfx_es2/draw_buffer.h" -#include "thin3d/thin3d.h" +#include "Common/Render/DrawBuffer.h" +#include "Common/GPU/thin3d.h" #include "Common/UI/Context.h" #include "Common/UI/View.h" #include "DebugVisVulkan.h" -#include "Common/Vulkan/VulkanMemory.h" -#include "Common/Vulkan/VulkanImage.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanImage.h" #include "GPU/Vulkan/GPU_Vulkan.h" #include "GPU/Vulkan/VulkanUtil.h" #include "GPU/Vulkan/TextureCacheVulkan.h" diff --git a/GPU/Vulkan/DebugVisVulkan.h b/GPU/Vulkan/DebugVisVulkan.h index e220003a56..b616d856f3 100644 --- a/GPU/Vulkan/DebugVisVulkan.h +++ b/GPU/Vulkan/DebugVisVulkan.h @@ -17,7 +17,7 @@ #pragma once -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" class GPUInterface; class UIContext; diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.cpp b/GPU/Vulkan/DepalettizeShaderVulkan.cpp index 42fe013372..4d11207eb2 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.cpp +++ b/GPU/Vulkan/DepalettizeShaderVulkan.cpp @@ -16,15 +16,15 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ColorConv.h" -#include "Common/Vulkan/VulkanImage.h" -#include "Common/Vulkan/VulkanMemory.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanImage.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanContext.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" #include "GPU/Common/DepalettizeShaderCommon.h" #include "GPU/Vulkan/DepalettizeShaderVulkan.h" #include "GPU/Vulkan/VulkanUtil.h" -#include "Common/Vulkan/VulkanImage.h" +#include "Common/GPU/Vulkan/VulkanImage.h" static const char depal_vs[] = R"(#version 450 #extension GL_ARB_separate_shader_objects : enable diff --git a/GPU/Vulkan/DepalettizeShaderVulkan.h b/GPU/Vulkan/DepalettizeShaderVulkan.h index 86cd6e615f..e78d817feb 100644 --- a/GPU/Vulkan/DepalettizeShaderVulkan.h +++ b/GPU/Vulkan/DepalettizeShaderVulkan.h @@ -20,8 +20,8 @@ #include #include "Common/CommonTypes.h" -#include "Common/Vulkan/VulkanContext.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/thin3d.h" #include "GPU/Common/DepalettizeShaderCommon.h" class DepalShaderVulkan { diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 2688698efd..04d48db348 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -19,7 +19,7 @@ #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Profiler/Profiler.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/Log.h" #include "Common/MemoryUtil.h" @@ -34,8 +34,8 @@ #include "GPU/GPUState.h" #include "GPU/ge_constants.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" #include "GPU/Common/SplineCommon.h" #include "GPU/Common/TransformCommon.h" diff --git a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp index 05fdf3a4a9..3d2ad0d1d5 100644 --- a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp @@ -18,7 +18,7 @@ #include #include -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 41e47ae259..399aa3cd87 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -22,12 +22,12 @@ #include "Common/System/Display.h" #include "Common/Math/lin/matrix4x4.h" #include "Common/Data/Convert/SmallDataConvert.h" -#include "ext/native/thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanMemory.h" -#include "Common/Vulkan/VulkanImage.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanImage.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/ColorConv.h" #include "Core/MemMap.h" #include "Core/Config.h" diff --git a/GPU/Vulkan/FramebufferManagerVulkan.h b/GPU/Vulkan/FramebufferManagerVulkan.h index a09f6ef755..a653aeb15d 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.h +++ b/GPU/Vulkan/FramebufferManagerVulkan.h @@ -17,7 +17,7 @@ #pragma once -#include "Common/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" #include "GPU/GPUInterface.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/GPUDebugInterface.h" diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 447f1b184c..197774e8d5 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -43,8 +43,8 @@ #include "GPU/Vulkan/FramebufferManagerVulkan.h" #include "GPU/Vulkan/DrawEngineVulkan.h" #include "GPU/Vulkan/TextureCacheVulkan.h" -#include "thin3d/VulkanRenderManager.h" -#include "thin3d/VulkanQueueRunner.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" +#include "Common/GPU/Vulkan/VulkanQueueRunner.h" #include "Core/MIPS/MIPS.h" #include "Core/HLE/sceKernelThread.h" diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 23d39bb3bf..2aa0546a8e 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -7,14 +7,14 @@ #include "Common/Log.h" #include "Common/StringUtils.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" #include "GPU/Vulkan/VulkanUtil.h" #include "GPU/Vulkan/PipelineManagerVulkan.h" #include "GPU/Vulkan/ShaderManagerVulkan.h" #include "GPU/Common/DrawEngineCommon.h" -#include "ext/native/thin3d/thin3d.h" -#include "ext/native/thin3d/VulkanRenderManager.h" -#include "ext/native/thin3d/VulkanQueueRunner.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" +#include "Common/GPU/Vulkan/VulkanQueueRunner.h" PipelineManagerVulkan::PipelineManagerVulkan(VulkanContext *vulkan) : vulkan_(vulkan), pipelines_(256) { // The pipeline cache is created on demand (or explicitly through Load). diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index f8678a4dd8..1dff1d8ce0 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -23,12 +23,12 @@ #include "Common/Math/math_util.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Profiler/Profiler.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/StringUtils.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" #include "Common/Log.h" #include "Common/Common.h" #include "Core/Config.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index 6e6a297ee2..016de933c6 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -21,7 +21,7 @@ #include #include "Common/Hashmaps.h" -#include "Common/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/ShaderId.h" #include "GPU/Vulkan/VertexShaderGeneratorVulkan.h" diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index b35c2114ee..1dee71861d 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -17,8 +17,8 @@ #include -#include "Common/Vulkan/VulkanLoader.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "GPU/Math3D.h" diff --git a/GPU/Vulkan/StateMappingVulkan.h b/GPU/Vulkan/StateMappingVulkan.h index 9306f5051d..7719dcf857 100644 --- a/GPU/Vulkan/StateMappingVulkan.h +++ b/GPU/Vulkan/StateMappingVulkan.h @@ -1,6 +1,6 @@ #pragma once -#include "Common/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" #include diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 613401545f..faaba54836 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -15,8 +15,8 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "ext/native/thin3d/thin3d.h" -#include "ext/native/thin3d/VulkanRenderManager.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/Log.h" #include "Core/Reporting.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 3e24a899c5..43ff63089b 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -23,8 +23,8 @@ #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" #include "Common/Profiler/Profiler.h" -#include "thin3d/thin3d.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/ColorConv.h" #include "Common/StringUtils.h" @@ -34,9 +34,9 @@ #include "Core/Reporting.h" #include "Core/System.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanImage.h" -#include "Common/Vulkan/VulkanMemory.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanImage.h" +#include "Common/GPU/Vulkan/VulkanMemory.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index d0d9014508..7c6c8f8946 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -22,7 +22,7 @@ #include "Common/Hashmaps.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" #include "GPU/Vulkan/TextureScalerVulkan.h" #include "GPU/Common/TextureCacheCommon.h" #include "GPU/Vulkan/VulkanUtil.h" diff --git a/GPU/Vulkan/TextureScalerVulkan.cpp b/GPU/Vulkan/TextureScalerVulkan.cpp index 8b903df905..28e6d4bc60 100644 --- a/GPU/Vulkan/TextureScalerVulkan.cpp +++ b/GPU/Vulkan/TextureScalerVulkan.cpp @@ -18,7 +18,7 @@ #include #include "Common/Common.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" #include "Common/ColorConv.h" #include "Common/Log.h" #include "Common/ThreadPools.h" diff --git a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp index ca732d23e9..36574f24ae 100644 --- a/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/VertexShaderGeneratorVulkan.cpp @@ -19,14 +19,14 @@ #include #include -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #if defined(_WIN32) && defined(_DEBUG) #include "Common/CommonWindows.h" #endif #include "Common/StringUtils.h" -#include "Common/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" #include "Core/Config.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" diff --git a/GPU/Vulkan/VulkanUtil.cpp b/GPU/Vulkan/VulkanUtil.cpp index 0e52abc314..bcf6f655f9 100644 --- a/GPU/Vulkan/VulkanUtil.cpp +++ b/GPU/Vulkan/VulkanUtil.cpp @@ -17,7 +17,7 @@ #include "Common/Log.h" #include "Common/StringUtils.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanContext.h" #include "GPU/Vulkan/VulkanUtil.h" Vulkan2D::Vulkan2D(VulkanContext *vulkan) : vulkan_(vulkan) { diff --git a/GPU/Vulkan/VulkanUtil.h b/GPU/Vulkan/VulkanUtil.h index cac2698591..752ea8d754 100644 --- a/GPU/Vulkan/VulkanUtil.h +++ b/GPU/Vulkan/VulkanUtil.h @@ -21,9 +21,9 @@ #include #include "Common/Hashmaps.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanLoader.h" -#include "Common/Vulkan/VulkanImage.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanImage.h" // Vulkan doesn't really have the concept of an FBO that owns the images, // but it does have the concept of a framebuffer as a set of attachments. diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 450eefee31..cb2e2ab26a 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -33,7 +33,7 @@ #include "Common/System/NativeApp.h" #include "Common/System/System.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Math/math_util.h" #include "QtMain.h" diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 9c7589b6c2..afb97149f4 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -4,7 +4,7 @@ #include #include #include -#include "gfx_es2/glsl_program.h" +#include "Common/GPU/OpenGL/GLSLProgram.h" #include #ifndef SDL @@ -26,11 +26,11 @@ QTM_USE_NAMESPACE #include "Common/TimeUtil.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Net/Resolve.h" #include "NKCodeFromQt.h" @@ -39,8 +39,8 @@ QTM_USE_NAMESPACE #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" -#include "thin3d/thin3d_create.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/thin3d_create.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" // Input void SimulateGamepad(); diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index 168a07afcd..83fd2cd873 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -2,8 +2,8 @@ #include "SDLGLGraphicsContext.h" -#include "gfx_es2/gpu_features.h" -#include "thin3d/thin3d_create.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/GPU/thin3d_create.h" #include "Common/System/NativeApp.h" #include "Common/System/System.h" diff --git a/SDL/SDLGLGraphicsContext.h b/SDL/SDLGLGraphicsContext.h index 88c9d8202d..1910ce8f56 100644 --- a/SDL/SDLGLGraphicsContext.h +++ b/SDL/SDLGLGraphicsContext.h @@ -1,8 +1,8 @@ #include "SDL_syswm.h" #include "SDL.h" -#include "thin3d/GLRenderManager.h" -#include "gfx/gl_common.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLCommon.h" #include "Common/GraphicsContext.h" class SDLGLGraphicsContext : public GraphicsContext { diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 923c569029..cc1dcdce0f 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -28,7 +28,7 @@ SDLJoystick *joystick = NULL; #include "Common/Net/Resolve.h" #include "NKCodeFromSDL.h" #include "Common/Math/math_util.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "SDL_syswm.h" diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 3c07ab942c..d8cf460bfc 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -3,9 +3,9 @@ #include "Common/System/System.h" #include "Common/System/NativeApp.h" #include "Common/System/Display.h" -#include "thin3d/thin3d.h" -#include "thin3d/thin3d_create.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/thin3d_create.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/Data/Text/Parsers.h" #include "Core/System.h" diff --git a/SDL/SDLVulkanGraphicsContext.h b/SDL/SDLVulkanGraphicsContext.h index 02e5f496e4..d654212342 100644 --- a/SDL/SDLVulkanGraphicsContext.h +++ b/SDL/SDLVulkanGraphicsContext.h @@ -2,10 +2,10 @@ #include "SDL_syswm.h" #include "Common/GraphicsContext.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanDebug.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanDebug.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" class VulkanRenderManager; diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index f56847bf85..d5742c575a 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -16,8 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/System/Display.h" -#include "gfx_es2/draw_buffer.h" -#include "gfx/texture_atlas.h" +#include "Common/Render/DrawBuffer.h" +#include "Common/Render/TextureAtlas.h" #include "Common/UI/Context.h" #include "Common/UI/View.h" #include "Common/UI/ViewGroup.h" diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 74320bf165..43a406adb4 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -19,7 +19,7 @@ #include #include -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "Common/UI/Root.h" #include "Common/UI/UI.h" #include "Common/UI/Context.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 6e50950000..bfa2495486 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -21,7 +21,7 @@ #include "Common/System/Display.h" #include "Common/System/NativeApp.h" #include "Common/System/System.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Data/Text/I18n.h" #include "Common/UI/Context.h" #include "Common/UI/View.h" diff --git a/UI/DisplayLayoutEditor.h b/UI/DisplayLayoutEditor.h index 394762a6a9..6855c127ca 100644 --- a/UI/DisplayLayoutEditor.h +++ b/UI/DisplayLayoutEditor.h @@ -17,8 +17,8 @@ #pragma once -#include "gfx/texture_atlas.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/TextureAtlas.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/View.h" #include "Common/UI/ViewGroup.h" diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 0c8ddde7cd..96b224c573 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -20,8 +20,8 @@ #include "Common/System/Display.h" #include "Common/System/System.h" -#include "gfx/texture_atlas.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/TextureAtlas.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/Context.h" #include "Common/UI/View.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 61042fc14b..079aae9795 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -19,8 +19,8 @@ #include -#include "gfx/texture_atlas.h" -#include "gfx_es2/gpu_features.h" +#include "Common/Render/TextureAtlas.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "gfx_es2/draw_text.h" #include "Common/UI/Root.h" diff --git a/UI/GPUDriverTestScreen.h b/UI/GPUDriverTestScreen.h index 64a20d4c74..7f20ecab82 100644 --- a/UI/GPUDriverTestScreen.h +++ b/UI/GPUDriverTestScreen.h @@ -8,7 +8,7 @@ #include "Common/LogManager.h" #include "UI/MiscScreens.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" class GPUDriverTestScreen : public UIDialogScreenWithBackground { public: diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index afcc507e56..c0cf42d56f 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -22,7 +22,7 @@ #include #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Thread/PrioritizedWorkQueue.h" #include "Common/File/VFS/VFS.h" #include "Common/File/FileUtil.h" diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index a4eecc132f..697a2145c9 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -19,7 +19,7 @@ #include "ppsspp_config.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/Context.h" #include "Common/UI/View.h" #include "Common/UI/ViewGroup.h" diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 3a90ec8b6f..1ae64da3ce 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -20,8 +20,8 @@ #include #include "Common/Net/Resolve.h" -#include "gfx_es2/gpu_features.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/Root.h" #include "Common/UI/View.h" #include "Common/UI/ViewGroup.h" diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index add209e3f2..e84c43f3fe 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -20,7 +20,7 @@ #include "Common/Data/Color/RGBAUtil.h" #include "Common/System/Display.h" #include "Common/System/System.h" -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "Common/Math/math_util.h" #include "Common/UI/Context.h" diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 8b3dd53809..3cacb147c4 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -18,7 +18,7 @@ #pragma once #include "Common/Input/InputState.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/View.h" #include "Common/UI/ViewGroup.h" diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index a46a28e153..bf7dd25107 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -22,8 +22,8 @@ #include "Common/System/Display.h" #include "Common/System/System.h" -#include "gfx/texture_atlas.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/TextureAtlas.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/Root.h" #include "Common/UI/Context.h" #include "Common/UI/View.h" diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 56007c863b..41c5fd1f46 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -20,7 +20,7 @@ #include #include -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/Context.h" #include "Common/UI/View.h" #include "Common/UI/ViewGroup.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 133ca5a7ab..0ae20b16a0 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -45,10 +45,10 @@ #include "Common/Net/HTTPClient.h" #include "Common/Net/Resolve.h" -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "gfx_es2/draw_text.h" -#include "gfx_es2/gpu_features.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/GPU/thin3d.h" #include "Common/UI/UI.h" #include "Common/UI/Screen.h" #include "Common/UI/Context.h" diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index 17dc3222b4..5b89f78b57 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -1,8 +1,8 @@ #include "UI/OnScreenDisplay.h" #include "Common/Data/Color/RGBAUtil.h" -#include "gfx/texture_atlas.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/TextureAtlas.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/Context.h" diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 92e5f178e4..db826278e3 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -18,12 +18,12 @@ #include #include -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/View.h" #include "Common/UI/ViewGroup.h" #include "Common/UI/Context.h" #include "Common/UI/UIScreen.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Text/I18n.h" #include "Common/StringUtils.h" diff --git a/UI/ProfilerDraw.cpp b/UI/ProfilerDraw.cpp index 95792f3800..da5dba4ba7 100644 --- a/UI/ProfilerDraw.cpp +++ b/UI/ProfilerDraw.cpp @@ -18,7 +18,7 @@ #include #include -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/UI/Context.h" #include "Common/UI/View.h" #include "Common/Profiler/Profiler.h" diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index a4663399cb..8dfabde16a 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -26,7 +26,7 @@ #endif // TODO: For text align flags, probably shouldn't be in gfx_es2/... -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Net/HTTPClient.h" #include "Common/Net/Resolve.h" #include "Common/Net/URL.h" diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index 9842549f1c..1c31856a26 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -18,8 +18,8 @@ #include // TODO: For text align flags, probably shouldn't be in gfx_es2/... -#include "gfx_es2/draw_buffer.h" -#include "thin3d/thin3d.h" +#include "Common/Render/DrawBuffer.h" +#include "Common/GPU/thin3d.h" #include "Common/UI/Context.h" #include "UI/PauseScreen.h" #include "UI/ReportScreen.h" diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 41bd742893..2fa6b2d474 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -19,7 +19,7 @@ #include #include "Common/Data/Color/RGBAUtil.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Data/Text/I18n.h" #include "Common/Math/curves.h" #include "Common/Thread/PrioritizedWorkQueue.h" diff --git a/UI/Store.cpp b/UI/Store.cpp index ceff7c02ec..b893c48b2d 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -20,7 +20,7 @@ #include "Common/UI/Screen.h" #include "Common/UI/Context.h" #include "Common/UI/ViewGroup.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Common.h" #include "Common/Log.h" diff --git a/UI/TextureUtil.cpp b/UI/TextureUtil.cpp index b52ea1bcbb..cdfe9440e2 100644 --- a/UI/TextureUtil.cpp +++ b/UI/TextureUtil.cpp @@ -1,10 +1,10 @@ #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "ext/jpge/jpgd.h" #include "Common/UI/View.h" #include "Common/UI/Context.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Data/Color/RGBAUtil.h" #include "Common/Data/Format/ZIMLoad.h" diff --git a/UI/TextureUtil.h b/UI/TextureUtil.h index 3ed46f71fd..5a4710a65a 100644 --- a/UI/TextureUtil.h +++ b/UI/TextureUtil.h @@ -2,7 +2,7 @@ #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/UI/View.h" enum ImageFileType { diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index c2d5740a21..c180541833 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -19,7 +19,7 @@ #include #include "Common/Data/Color/RGBAUtil.h" -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Data/Text/I18n.h" #include "Common/Math/math_util.h" #include "Common/UI/Context.h" diff --git a/UI/TouchControlVisibilityScreen.cpp b/UI/TouchControlVisibilityScreen.cpp index d04cf4e95c..dab63b2940 100644 --- a/UI/TouchControlVisibilityScreen.cpp +++ b/UI/TouchControlVisibilityScreen.cpp @@ -15,7 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "TouchControlVisibilityScreen.h" #include "Core/Config.h" diff --git a/UI/TouchControlVisibilityScreen.h b/UI/TouchControlVisibilityScreen.h index 895078626b..04be4a1872 100644 --- a/UI/TouchControlVisibilityScreen.h +++ b/UI/TouchControlVisibilityScreen.h @@ -17,7 +17,7 @@ #pragma once -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "MiscScreens.h" namespace UI { diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index b7440d5ba5..2a980dc4a6 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -414,6 +414,10 @@ + + + + @@ -433,6 +437,8 @@ + + @@ -525,6 +531,9 @@ + + + @@ -543,6 +552,8 @@ + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 725a3526f1..7d3f1f9ba4 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -70,6 +70,18 @@ {8e12d2c0-157a-4625-a970-665e1ec9a425} + + {03e7b6a3-ac95-4145-b045-9c644186a0a9} + + + {4a53cf3f-fb5d-471f-8570-7dcdf479cce6} + + + {84fe421c-de5d-4732-9518-dd5ef6c46a72} + + + {2eb259f7-2735-493a-88be-96eb38f1b34e} + @@ -320,6 +332,21 @@ UI + + GPU + + + GPU\D3D11 + + + Render + + + Render + + + GPU\GL + @@ -582,6 +609,24 @@ UI + + GPU + + + GPU + + + GPU + + + Render + + + Render + + + GPU\GL + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index 3e504d2853..ed65f21e62 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -379,23 +379,14 @@ - - - - - + - - - - - - + Create Create diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index 4257fc1baa..b1fe9b4b87 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -1,33 +1,10 @@  - - - {98343696-3517-451a-9b47-94d462263e3e} - - - {8a254b8c-46f2-4ff1-bc53-deea7e614276} - - - - thin3d - - - thin3d - - - gfx - - - gfx - gfx - - gfx - gfx @@ -35,23 +12,16 @@ - - thin3d - - - gfx - - - gfx - gfx - - gfx - gfx + + + {85815953-a0f8-409b-bbe9-c28f126ae7bf} + + \ No newline at end of file diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 30eb175017..4de2859f70 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -6,7 +6,7 @@ #include "Common/File/FileUtil.h" #include "Common/Net/HTTPClient.h" #include "Common/Net/Resolve.h" -#include "thin3d/thin3d_create.h" +#include "Common/GPU/thin3d_create.h" #include "Common/Common.h" #include "Common/Input/InputState.h" diff --git a/UWP/PPSSPP_UWPMain.h b/UWP/PPSSPP_UWPMain.h index ed720e8a98..3be7b25ce4 100644 --- a/UWP/PPSSPP_UWPMain.h +++ b/UWP/PPSSPP_UWPMain.h @@ -2,7 +2,7 @@ #include -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Input/InputState.h" #include "Common/GraphicsContext.h" diff --git a/Windows/GEDebugger/SimpleGLWindow.cpp b/Windows/GEDebugger/SimpleGLWindow.cpp index 3416bc17df..37e6b7bd28 100644 --- a/Windows/GEDebugger/SimpleGLWindow.cpp +++ b/Windows/GEDebugger/SimpleGLWindow.cpp @@ -17,8 +17,8 @@ #include #include "Common/Math/lin/matrix4x4.h" -#include "gfx_es2/glsl_program.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLSLProgram.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Common.h" #include "Windows/GEDebugger/SimpleGLWindow.h" diff --git a/Windows/GEDebugger/SimpleGLWindow.h b/Windows/GEDebugger/SimpleGLWindow.h index 8628ab5eef..c6ebb1c104 100644 --- a/Windows/GEDebugger/SimpleGLWindow.h +++ b/Windows/GEDebugger/SimpleGLWindow.h @@ -20,7 +20,7 @@ #include #include "CommonWindows.h" -#include "gfx_es2/glsl_program.h" +#include "Common/GPU/OpenGL/GLSLProgram.h" #include "Common/CommonWindows.h" struct SimpleGLWindow { diff --git a/Windows/GEDebugger/VertexPreview.cpp b/Windows/GEDebugger/VertexPreview.cpp index aefddc7088..cc3589eebc 100644 --- a/Windows/GEDebugger/VertexPreview.cpp +++ b/Windows/GEDebugger/VertexPreview.cpp @@ -16,8 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/Math/lin/matrix4x4.h" -#include "gfx_es2/glsl_program.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLSLProgram.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Windows/GEDebugger/GEDebugger.h" #include "Windows/GEDebugger/SimpleGLWindow.h" #include "Core/System.h" diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 32d158c54e..8f93ebc88d 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -15,9 +15,9 @@ #include "Core/System.h" #include "Windows/GPU/D3D11Context.h" #include "Windows/W32Util/Misc.h" -#include "thin3d/thin3d.h" -#include "thin3d/thin3d_create.h" -#include "thin3d/d3d11_loader.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/thin3d_create.h" +#include "Common/GPU/D3D11/D3D11Loader.h" #ifdef __MINGW32__ #undef __uuidof diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index daeb0fd86b..27a9e4cc36 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -3,7 +3,7 @@ #include "Common/CommonWindows.h" #include -#include "gfx/d3d9_state.h" +#include "Common/GPU/D3D9/D3D9StateCache.h" #include "Common/System/Display.h" #include "Common/Data/Encoding/Utf8.h" @@ -17,8 +17,8 @@ #include "Common/OSVersion.h" #include "Windows/GPU/D3D9Context.h" #include "Windows/W32Util/Misc.h" -#include "thin3d/thin3d.h" -#include "thin3d/thin3d_create.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/thin3d_create.h" #if PPSSPP_API(D3DX9) #include "thin3d/d3dx9_loader.h" diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index 57b4a51cd7..765321c903 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -17,11 +17,11 @@ #include "Common/Log.h" #include "Common/CommonWindows.h" -#include "gfx/gl_common.h" -#include "gfx/gl_debug_log.h" -#include "gfx_es2/gpu_features.h" -#include "thin3d/thin3d_create.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLDebugLog.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/GPU/thin3d_create.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "GL/gl.h" #include "GL/wglew.h" #include "Core/Config.h" diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 1c6557b2e3..5618e2f1f5 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -52,12 +52,12 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" -#include "Common/Vulkan/VulkanLoader.h" -#include "Common/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanContext.h" -#include "thin3d/thin3d.h" -#include "thin3d/thin3d_create.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/thin3d_create.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" #include "Common/Data/Text/Parsers.h" #include "Windows/GPU/WindowsVulkanContext.h" diff --git a/Windows/GPU/WindowsVulkanContext.h b/Windows/GPU/WindowsVulkanContext.h index 46abc4e841..098d737e98 100644 --- a/Windows/GPU/WindowsVulkanContext.h +++ b/Windows/GPU/WindowsVulkanContext.h @@ -19,7 +19,7 @@ #include "Common/GraphicsContext.h" #include "Windows/GPU/WindowsGraphicsContext.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" class VulkanContext; class VulkanRenderManager; diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 56d3fb720b..ee9500291d 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -7,7 +7,7 @@ #include "resource.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Data/Text/I18n.h" #include "Common/Data/Encoding/Utf8.h" @@ -18,7 +18,7 @@ #include "Common/LogManager.h" #include "Common/ConsoleListener.h" #include "Common/OSVersion.h" -#include "Common/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" #include "Common/StringUtils.h" #if PPSSPP_API(ANY_GL) #include "GPU/GLES/TextureScalerGLES.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index 1143938f8c..3abdd7dfb0 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -23,7 +23,7 @@ #include "Common/CommonWindows.h" #include "Common/File/FileUtil.h" #include "Common/OSVersion.h" -#include "Common/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" #include "ppsspp_config.h" #include diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 69bae6d39c..08c1f87950 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -102,22 +102,18 @@ ARCH_FILES := \ endif NATIVE_FILES :=\ - $(SRC)/ext/native/gfx_es2/glsl_program.cpp \ - $(SRC)/ext/native/gfx_es2/gpu_features.cpp \ - $(SRC)/ext/native/gfx_es2/gl3stub.c \ - $(SRC)/ext/native/gfx_es2/draw_buffer.cpp.arm \ + $(SRC)/Common/Render/DrawBuffer.cpp \ + $(SRC)/Common/Render/TextureAtlas.cpp \ + $(SRC)/Common/GPU/OpenGL/thin3d_gl.cpp \ + $(SRC)/Common/GPU/OpenGL/GLDebugLog.cpp \ + $(SRC)/Common/GPU/OpenGL/GLSLProgram.cpp \ + $(SRC)/Common/GPU/OpenGL/gl3stub.c \ + $(SRC)/Common/GPU/OpenGL/GLFeatures.cpp \ + $(SRC)/Common/GPU/OpenGL/GLRenderManager.cpp \ + $(SRC)/Common/GPU/OpenGL/GLQueueRunner.cpp \ + $(SRC)/Common/GPU/OpenGL/DataFormatGL.cpp \ $(SRC)/ext/native/gfx_es2/draw_text.cpp.arm \ - $(SRC)/ext/native/gfx_es2/draw_text_android.cpp.arm \ - $(SRC)/ext/native/gfx/gl_debug_log.cpp \ - $(SRC)/ext/native/gfx/texture_atlas.cpp \ - $(SRC)/ext/native/thin3d/thin3d.cpp \ - $(SRC)/ext/native/thin3d/thin3d_gl.cpp \ - $(SRC)/ext/native/thin3d/thin3d_vulkan.cpp \ - $(SRC)/ext/native/thin3d/GLRenderManager.cpp \ - $(SRC)/ext/native/thin3d/GLQueueRunner.cpp \ - $(SRC)/ext/native/thin3d/VulkanRenderManager.cpp \ - $(SRC)/ext/native/thin3d/VulkanQueueRunner.cpp \ - $(SRC)/ext/native/thin3d/DataFormatGL.cpp + $(SRC)/ext/native/gfx_es2/draw_text_android.cpp.arm EGL_FILES := \ $(SRC)/Common/GL/GLInterface/EGL.cpp \ @@ -125,11 +121,14 @@ EGL_FILES := \ $(SRC)/Common/GL/GLInterface/GLInterface.cpp VULKAN_FILES := \ - $(SRC)/Common/Vulkan/VulkanLoader.cpp \ - $(SRC)/Common/Vulkan/VulkanContext.cpp \ - $(SRC)/Common/Vulkan/VulkanDebug.cpp \ - $(SRC)/Common/Vulkan/VulkanImage.cpp \ - $(SRC)/Common/Vulkan/VulkanMemory.cpp \ + $(SRC)/Common/GPU/Vulkan/thin3d_vulkan.cpp \ + $(SRC)/Common/GPU/Vulkan/VulkanQueueRunner.cpp \ + $(SRC)/Common/GPU/Vulkan/VulkanRenderManager.cpp \ + $(SRC)/Common/GPU/Vulkan/VulkanLoader.cpp \ + $(SRC)/Common/GPU/Vulkan/VulkanContext.cpp \ + $(SRC)/Common/GPU/Vulkan/VulkanDebug.cpp \ + $(SRC)/Common/GPU/Vulkan/VulkanImage.cpp \ + $(SRC)/Common/GPU/Vulkan/VulkanMemory.cpp \ $(SRC)/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp \ $(SRC)/GPU/Vulkan/DrawEngineVulkan.cpp \ $(SRC)/GPU/Vulkan/FramebufferManagerVulkan.cpp \ diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index c29ef49ba4..55d54dff77 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -1,5 +1,5 @@ -#include "gfx_es2/gpu_features.h" -#include "thin3d/thin3d_create.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/GPU/thin3d_create.h" #include "Common/Log.h" #include "Common/System/System.h" diff --git a/android/jni/AndroidEGLContext.h b/android/jni/AndroidEGLContext.h index 45b33f8241..49a89739b2 100644 --- a/android/jni/AndroidEGLContext.h +++ b/android/jni/AndroidEGLContext.h @@ -1,6 +1,6 @@ #pragma once -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "AndroidGraphicsContext.h" #include "Common/GL/GLInterfaceBase.h" diff --git a/android/jni/AndroidGraphicsContext.h b/android/jni/AndroidGraphicsContext.h index 096a5653f3..434017e077 100644 --- a/android/jni/AndroidGraphicsContext.h +++ b/android/jni/AndroidGraphicsContext.h @@ -2,8 +2,7 @@ #include -#include "thin3d/thin3d.h" - +#include "Common/GPU/thin3d.h" #include "Common/GraphicsContext.h" enum { diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index c797bd046d..9fefc59c90 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -1,6 +1,6 @@ #include "AndroidJavaGLContext.h" #include "Common/System/Display.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/Log.h" #include "Core/ConfigValues.h" #include "Core/System.h" diff --git a/android/jni/AndroidJavaGLContext.h b/android/jni/AndroidJavaGLContext.h index 9e4b07dd1b..69f8d2bb40 100644 --- a/android/jni/AndroidJavaGLContext.h +++ b/android/jni/AndroidJavaGLContext.h @@ -5,8 +5,8 @@ #include #include "AndroidGraphicsContext.h" -#include "thin3d/GLRenderManager.h" -#include "thin3d/thin3d_create.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" +#include "Common/GPU/thin3d_create.h" // Doesn't do much. Just to fit in. class AndroidJavaEGLGraphicsContext : public AndroidGraphicsContext { diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 8ddff75115..dc68a8d75a 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -3,11 +3,11 @@ #include "Common/System/NativeApp.h" #include "Common/System/System.h" #include "Common/Log.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanDebug.h" -#include "Common/Vulkan/VulkanLoader.h" -#include "thin3d/VulkanRenderManager.h" -#include "thin3d/thin3d_create.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanDebug.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanRenderManager.h" +#include "Common/GPU/thin3d_create.h" #include "Common/Data/Text/Parsers.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 3e6c859210..54687fc1e8 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -51,8 +51,8 @@ struct JNIEnv {}; #include "Common/Net/Resolve.h" #include "android/jni/AndroidAudio.h" -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/System/Display.h" #include "Common/System/NativeApp.h" diff --git a/ext/native/gfx_es2/draw_text.cpp b/ext/native/gfx_es2/draw_text.cpp index b1fae13c8e..b85e6eeb71 100644 --- a/ext/native/gfx_es2/draw_text.cpp +++ b/ext/native/gfx_es2/draw_text.cpp @@ -1,5 +1,5 @@ #include "Common/System/Display.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/ext/native/gfx_es2/draw_text.h b/ext/native/gfx_es2/draw_text.h index ed582845b9..4d1862834d 100644 --- a/ext/native/gfx_es2/draw_text.h +++ b/ext/native/gfx_es2/draw_text.h @@ -13,7 +13,7 @@ #include #include -#include "gfx_es2/draw_buffer.h" +#include "Common/Render/DrawBuffer.h" #include "Common/Data/Text/WrapText.h" namespace Draw { diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/ext/native/gfx_es2/draw_text_android.cpp index c19f859cf7..263494f78c 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/ext/native/gfx_es2/draw_text_android.cpp @@ -1,5 +1,5 @@ #include "Common/System/Display.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/ext/native/gfx_es2/draw_text_qt.cpp b/ext/native/gfx_es2/draw_text_qt.cpp index 56b8c6e56c..91f45fe7ec 100644 --- a/ext/native/gfx_es2/draw_text_qt.cpp +++ b/ext/native/gfx_es2/draw_text_qt.cpp @@ -1,5 +1,5 @@ #include "Common/System/Display.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/ext/native/gfx_es2/draw_text_uwp.cpp index 71e88f0fd5..4ea0bbfcc9 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/ext/native/gfx_es2/draw_text_uwp.cpp @@ -1,5 +1,5 @@ #include "Common/System/Display.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/ext/native/gfx_es2/draw_text_win.cpp b/ext/native/gfx_es2/draw_text_win.cpp index 1767d71cfa..883eda1444 100644 --- a/ext/native/gfx_es2/draw_text_win.cpp +++ b/ext/native/gfx_es2/draw_text_win.cpp @@ -1,5 +1,5 @@ #include "Common/System/Display.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index dd6381f71e..a66ede425e 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -363,68 +363,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - true - true - true - true - - - - - - - - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index 9befbb1243..b1773f1582 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -6,45 +6,9 @@ - - gfx - - - gfx - - - gfx - - - gfx - - - gfx - gfx - - gfx - - - thin3d - - - thin3d - - - gfx - - - gfx - - - gfx - - - thin3d - gfx @@ -54,83 +18,14 @@ gfx - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - thin3d - gfx - - gfx - - - gfx - - - gfx - - - gfx - - - gfx - gfx - - gfx - - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - gfx - - - gfx - - - thin3d - gfx @@ -140,24 +35,6 @@ gfx - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - thin3d - - - thin3d - gfx @@ -169,8 +46,5 @@ {4515306f-4664-46bf-a89b-abfec5520a15} - - {06c6305a-a646-485b-85b9-645a24dd6553} - \ No newline at end of file diff --git a/ext/native/thin3d/d3dx9_loader.cpp b/ext/native/thin3d/d3dx9_loader.cpp deleted file mode 100644 index e67f4b6ae8..0000000000 --- a/ext/native/thin3d/d3dx9_loader.cpp +++ /dev/null @@ -1,192 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "thin3d/d3dx9_loader.h" - -#include "Common/Log.h" - -// TODO: See if we can use the bundled D3Dcompiler_47.dll to compiler for DX9 as well. - -typedef BOOL(__stdcall *TFunc_D3DXCheckVersion)(UINT D3DSDKVersion, UINT D3DXSDKVersion); -typedef HRESULT(__stdcall *TFunc_D3DXCompileShader)( - LPCSTR pSrcData, - UINT srcDataLen, - CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, - LPCSTR pFunctionName, - LPCSTR pProfile, - DWORD Flags, - LPD3DXBUFFER* ppShader, - LPD3DXBUFFER* ppErrorMsgs, - LPD3DXCONSTANTTABLE * ppConstantTable); - -typedef HRESULT(__stdcall *TFunc_D3DXAssembleShader)( - LPCSTR pSrcData, - UINT SrcDataLen, - CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, - DWORD Flags, - LPD3DXBUFFER* ppShader, - LPD3DXBUFFER * ppErrorMsgs - ); - -static HMODULE hm_d3dx; -static unsigned int d3dx_version; -static int failedFunctions; - -static TFunc_D3DXCheckVersion m_TFunc_D3DXCheckVersion; -static TFunc_D3DXAssembleShader m_TFunc_D3DXAssembleShader; -static TFunc_D3DXCompileShader m_TFunc_D3DXCompileShader; - -void makeD3DX9dllFilename_by_versionW(std::wstring& strOut, unsigned int versionNumber, bool debugVersion = false) { - wchar_t buf[256]; - wsprintf(buf, L"d3dx9%s_%02i.dll", debugVersion ? L"d" : L"", versionNumber); - strOut = buf; -} - -bool checkDllExistsW(const WCHAR* fname, bool bIncludeExeDir) { - return ::GetFileAttributesW(fname) != DWORD(-1); -} - -bool checkExistsDllW(const WCHAR *sDllFilename) { - std::wstring sfullpath(MAX_PATH, '\0'); - size_t sz = ::GetSystemDirectoryW(&sfullpath[0], (UINT)sfullpath.size()); - if (sz >= sfullpath.size()) { - sfullpath.resize(sz); - sz = ::GetSystemDirectoryW(&sfullpath[0], (UINT)sfullpath.size()); - } - sfullpath.resize(sz); - if (sz == 0) { - throw (std::runtime_error("system error")); - } - - sfullpath += L'\\'; - sfullpath += sDllFilename; - - if (checkDllExistsW(sfullpath.c_str(), true)) { - return true; - } - - return false; -} - -bool getLatestInstalledD3DXVersion(unsigned int* piOutVers, bool debugVersion) { - *piOutVers = 0; - std::wstring fname; - for (unsigned int cvers = 45; cvers > 0; cvers--) { - makeD3DX9dllFilename_by_versionW(fname, cvers, debugVersion); - if (checkExistsDllW(fname.c_str())) { - *piOutVers = cvers; - return true; - } - } - return false; -} - -HMODULE loadDllLastVersion(unsigned int* version, bool debugVersion) { - failedFunctions = 0; - - if (version) - *version = 0; - - if (!getLatestInstalledD3DXVersion(version, debugVersion)) { - return 0; - } - - std::wstring dllfname; - makeD3DX9dllFilename_by_versionW(dllfname, version ? *version : 0, debugVersion); - HMODULE hm = ::LoadLibraryW(dllfname.c_str()); - return hm; -} - -#define GB_MAKE_STR(s) # s -#define GB_MAKE_STR2(x) GB_MAKE_STR(x) - -#define __HANDLE_DLL_ENTRY(funcname) m_TFunc_##funcname = \ - ( TFunc_##funcname ) ::GetProcAddress(hm_d3dx, GB_MAKE_STR(funcname) ); \ - \ - if(!m_TFunc_##funcname) {\ - handleNotFoundAddr( GB_MAKE_STR(funcname) ); \ - } - -void handleNotFoundAddr(const char* sFuncName) { - ERROR_LOG(G3D, "Failed to find D3DX function %s", sFuncName); - failedFunctions++; -} - -int LoadD3DX9Dynamic(bool debugVersion) { - if (hm_d3dx) { - // Already loaded - return d3dx_version; - } - - hm_d3dx = loadDllLastVersion(&d3dx_version, debugVersion); - if (!hm_d3dx) { - ERROR_LOG(G3D, "Failed to find D3DX dll."); - return 0; - } - const int NERROR = -1; - int _begin = 0; - - __HANDLE_DLL_ENTRY(D3DXCheckVersion); - __HANDLE_DLL_ENTRY(D3DXAssembleShader); - __HANDLE_DLL_ENTRY(D3DXCompileShader); - - if (failedFunctions > 0) { - ERROR_LOG(G3D, "Failed to load %i D3DX functions. This will not go well.", failedFunctions); - } - - return failedFunctions > 0 ? 0 : d3dx_version; -} - -int GetD3DXVersion() { - return d3dx_version; -} - -void UnloadD3DXDynamic() { - if (hm_d3dx) { - FreeLibrary(hm_d3dx); - hm_d3dx = NULL; - d3dx_version = 0; - } -} - -// version function - -#define GB_D3D9_D3DXDLL_LOADER_CHECK_ENTRY_NULL_PTR(funcname) assert(false && GB_MAKE_STR2(funcname) ); - - -BOOL dyn_D3DXCheckVersion(UINT D3DSDKVersion, UINT D3DXSDKVersion) { - if (!m_TFunc_D3DXCheckVersion) { - GB_D3D9_D3DXDLL_LOADER_CHECK_ENTRY_NULL_PTR(D3DXCheckVersion) - } - return m_TFunc_D3DXCheckVersion(D3DSDKVersion, D3DXSDKVersion); -} - -HRESULT dyn_D3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER * ppErrorMsgs) -{ - if (!m_TFunc_D3DXAssembleShader) { - GB_D3D9_D3DXDLL_LOADER_CHECK_ENTRY_NULL_PTR(D3DXAssembleShader); - } - return m_TFunc_D3DXAssembleShader(pSrcData, SrcDataLen, pDefines, - pInclude, Flags, ppShader, ppErrorMsgs); -} - -HRESULT dyn_D3DXCompileShader(LPCSTR pSrcData, UINT srcDataLen, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, - DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, - LPD3DXCONSTANTTABLE * ppConstantTable) -{ - if (!m_TFunc_D3DXCompileShader) { - GB_D3D9_D3DXDLL_LOADER_CHECK_ENTRY_NULL_PTR(D3DXCompileShader); - } - return m_TFunc_D3DXCompileShader(pSrcData, srcDataLen, pDefines, - pInclude, pFunctionName, pProfile, - Flags, ppShader, ppErrorMsgs, ppConstantTable); -} diff --git a/ext/native/thin3d/d3dx9_loader.h b/ext/native/thin3d/d3dx9_loader.h deleted file mode 100644 index 36dad3f96b..0000000000 --- a/ext/native/thin3d/d3dx9_loader.h +++ /dev/null @@ -1,26 +0,0 @@ -// Cut-down version of https://code.google.com/p/d3dx9-dynamic-load/ -// by ksacvet777, licensed under the MIT - -#pragma once - -#include -#ifdef USE_CRT_DBG -#undef new -#endif -#include -#ifdef USE_CRT_DBG -#define new DBG_NEW -#endif -// Returns the D3DX9 version we got. 0 if none. -int LoadD3DX9Dynamic(bool debugVersion = false); // If debugVersion is set, load d3dx9d.dll -int GetD3DXVersion(); -void UnloadD3DXDynamic(); - -// Call these instead of the real D3DX9 functions. -BOOL dyn_D3DXCheckVersion(UINT D3DSDKVersion, UINT D3DXSDKVersion); -HRESULT dyn_D3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER * ppErrorMsgs); -HRESULT dyn_D3DXCompileShader(LPCSTR pSrcData, UINT srcDataLen, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, - DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, - LPD3DXCONSTANTTABLE * ppConstantTable); diff --git a/ext/native/thin3d/vulkan_utils.cpp b/ext/native/thin3d/vulkan_utils.cpp deleted file mode 100644 index 80f7086c7f..0000000000 --- a/ext/native/thin3d/vulkan_utils.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) 2015- PPSSPP Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official git repository and contact information can be found at -// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#undef min -#undef max - -#endif - -#include -#include -#include - -#ifdef USE_CRT_DBG -#undef new -#endif - -#include "ext/glslang/SPIRV/GlslangToSpv.h" -#include "ext/glslang/SPIRV/disassemble.h" - -#ifdef USE_CRT_DBG -#define new DBG_NEW -#endif - -#include "thin3d/vulkan_utils.h" - -void VulkanImage::Create2D(VulkanContext *vulkan, VkFormat format, VkFlags required_props, VkImageTiling tiling, VkImageUsageFlags usage, int width, int height) { - VkDevice device = vulkan->GetDevice(); - width_ = width; - height_ = height; - - VkImageCreateInfo i = {}; - i.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - i.pNext = NULL; - i.imageType = VK_IMAGE_TYPE_2D; - i.format = format; - i.extent = { (uint32_t)width, (uint32_t)height, 1 }; - i.mipLevels = 1; - i.arrayLayers = 1; - i.samples = VK_SAMPLE_COUNT_1_BIT; - i.tiling = tiling; - i.usage = usage; - i.flags = 0; - i.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - i.queueFamilyIndexCount = 0; - i.pQueueFamilyIndices = nullptr; - i.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - - VkMemoryRequirements mem_reqs; - - VkResult err = vkCreateImage(device, &i, nullptr, &image_); - _assert_(!err); - - vkGetImageMemoryRequirements(device, image_, &mem_reqs); - - mem_alloc_.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - mem_alloc_.pNext = NULL; - mem_alloc_.allocationSize = mem_reqs.size; - mem_alloc_.memoryTypeIndex = 0; - - bool res = vulkan->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, required_props, &mem_alloc_.memoryTypeIndex); - _assert_(res); - - err = vkAllocateMemory(device, &mem_alloc_, nullptr, &memory_); - _assert_(!err); - - err = vkBindImageMemory(device, image_, memory_, 0); // at offset 0. - _assert_(!err); -} - -void VulkanImage::SetImageData2D(VkDevice device, const uint8_t *data, int width, int height, int pitch) { - VkImageSubresource subres; - subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subres.mipLevel = 0; - subres.arrayLayer = 0; - - VkSubresourceLayout layout; - void *destData; - vkGetImageSubresourceLayout(device, image_, &subres, &layout); - - VkResult err = vkMapMemory(device, memory_, 0, mem_alloc_.allocationSize, 0, &destData); - _assert_(!err); - - uint8_t *writePtr = (uint8_t *)destData + layout.offset; - int bpp = 4; // TODO - for (int y = 0; y < height; y++) { - memcpy(writePtr + y * layout.rowPitch, data + y * pitch, bpp * width); - } - - vkUnmapMemory(device, memory_); -} - - -void VulkanImage::ChangeLayout(VkCommandBuffer cmd, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout, VkImageLayout new_image_layout) { - VkImageMemoryBarrier image_memory_barrier; - image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - image_memory_barrier.pNext = NULL; - image_memory_barrier.dstAccessMask = 0; - image_memory_barrier.srcAccessMask = 0; - image_memory_barrier.oldLayout = old_image_layout; - image_memory_barrier.newLayout = new_image_layout; - image_memory_barrier.image = image_; - image_memory_barrier.subresourceRange.aspectMask = aspectMask; - image_memory_barrier.subresourceRange.layerCount = 1; - image_memory_barrier.subresourceRange.baseArrayLayer = 0; - image_memory_barrier.subresourceRange.baseMipLevel = 0; - image_memory_barrier.subresourceRange.levelCount = 1; - - if (old_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { - image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - } - - if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { - // Make sure anything that was copying from this image has completed - image_memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; - } - - if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - // Make sure any Copy or CPU writes to image are flushed - image_memory_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT; - } - - VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - vkCmdPipelineBarrier(cmd, src_stages, dest_stages, false, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); -} diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp index 079c994cf3..7403657ece 100644 --- a/ext/native/tools/atlastool.cpp +++ b/ext/native/tools/atlastool.cpp @@ -29,7 +29,7 @@ #include #include -#include "gfx/texture_atlas.h" +#include "Common/Render/TextureAtlas.h" #include "Common/Data/Format/PNGLoad.h" #include "Common/Data/Format/ZIMSave.h" diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index 8e5799dd03..b57d02a5cd 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -21,10 +21,10 @@ #include #include "headless/SDLHeadlessHost.h" -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" -#include "thin3d/thin3d_create.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLFeatures.h" +#include "Common/GPU/thin3d_create.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp index 2f9d06aa1f..af5548bf84 100644 --- a/headless/WindowsHeadlessHost.cpp +++ b/headless/WindowsHeadlessHost.cpp @@ -19,8 +19,8 @@ #include "headless/WindowsHeadlessHost.h" -#include "gfx/gl_common.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/File/VFS/VFS.h" #include "Common/File/VFS/AssetReader.h" diff --git a/ios/PPSSPPUIApplication.mm b/ios/PPSSPPUIApplication.mm index a9075cd6ac..2166da2406 100644 --- a/ios/PPSSPPUIApplication.mm +++ b/ios/PPSSPPUIApplication.mm @@ -21,9 +21,9 @@ #include "Common/Input/InputState.h" #include "Common/Net/Resolve.h" #include "Common/UI/Screen.h" -#include "thin3d/thin3d.h" +#include "Common/GPU/thin3d.h" #include "Common/Input/KeyCodes.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #import "ios/AppDelegate.h" #include "ios/SmartKeyboardMap.hpp" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 82f4ddf00a..02b18a5ec5 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -14,10 +14,10 @@ #include "Common/Net/Resolve.h" #include "Common/UI/Screen.h" -#include "thin3d/thin3d.h" -#include "thin3d/thin3d_create.h" -#include "thin3d/GLRenderManager.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/thin3d.h" +#include "Common/GPU/thin3d_create.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/System/Display.h" #include "Common/System/System.h" diff --git a/libretro/LibretroD3D11Context.cpp b/libretro/LibretroD3D11Context.cpp index 8fbcd50a76..216876a409 100644 --- a/libretro/LibretroD3D11Context.cpp +++ b/libretro/LibretroD3D11Context.cpp @@ -1,7 +1,8 @@ #include "Common/Log.h" #include "Core/ConfigValues.h" #include "libretro/LibretroD3D11Context.h" -#include "thin3d/d3d11_loader.h" +#include "Common/GPU/D3D11/D3D11Loader.h" + #include #ifdef __MINGW32__ diff --git a/libretro/LibretroGLContext.cpp b/libretro/LibretroGLContext.cpp index c8260650cb..c8f3bcd0a7 100644 --- a/libretro/LibretroGLContext.cpp +++ b/libretro/LibretroGLContext.cpp @@ -3,7 +3,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "libretro/LibretroGLContext.h" diff --git a/libretro/LibretroGLContext.h b/libretro/LibretroGLContext.h index 73c29701b7..5c6ded1d6e 100644 --- a/libretro/LibretroGLContext.h +++ b/libretro/LibretroGLContext.h @@ -1,8 +1,8 @@ #pragma once -#include "gfx/gl_common.h" +#include "Common/GPU/OpenGL/GLCommon.h" #include "libretro/LibretroGraphicsContext.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" class LibretroGLContext : public LibretroHWRenderContext { public: diff --git a/libretro/LibretroGLCoreContext.cpp b/libretro/LibretroGLCoreContext.cpp index 14c816f1cf..7b571bdaf0 100644 --- a/libretro/LibretroGLCoreContext.cpp +++ b/libretro/LibretroGLCoreContext.cpp @@ -3,7 +3,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/System.h" -#include "gfx_es2/gpu_features.h" +#include "Common/GPU/OpenGL/GLFeatures.h" #include "libretro/LibretroGLCoreContext.h" diff --git a/libretro/LibretroGLCoreContext.h b/libretro/LibretroGLCoreContext.h index 7719a867c2..bb8d5e460f 100644 --- a/libretro/LibretroGLCoreContext.h +++ b/libretro/LibretroGLCoreContext.h @@ -1,8 +1,8 @@ #pragma once -#include "gfx/gl_common.h" +#include "Common/GPU/OpenGL/GLCommon.h" #include "libretro/LibretroGraphicsContext.h" -#include "thin3d/GLRenderManager.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" class LibretroGLCoreContext : public LibretroHWRenderContext { public: diff --git a/libretro/LibretroGraphicsContext.h b/libretro/LibretroGraphicsContext.h index 65b92d2a6a..97890c3013 100644 --- a/libretro/LibretroGraphicsContext.h +++ b/libretro/LibretroGraphicsContext.h @@ -3,7 +3,7 @@ #include "libretro/libretro.h" #include "Common/GraphicsContext.h" -#include "thin3d/thin3d_create.h" +#include "Common/GPU/thin3d_create.h" #include "Core/System.h" #include "GPU/GPUState.h" diff --git a/libretro/LibretroVulkanContext.cpp b/libretro/LibretroVulkanContext.cpp index 0f978e99b3..5d62a54b45 100644 --- a/libretro/LibretroVulkanContext.cpp +++ b/libretro/LibretroVulkanContext.cpp @@ -1,7 +1,7 @@ -#include "Common/Vulkan/VulkanLoader.h" -#include "Common/Vulkan/VulkanContext.h" -#include "Common/Vulkan/VulkanDebug.h" +#include "Common/GPU/Vulkan/VulkanLoader.h" +#include "Common/GPU/Vulkan/VulkanContext.h" +#include "Common/GPU/Vulkan/VulkanDebug.h" #include "Common/Log.h" #include "Core/Config.h" #include "Core/ConfigValues.h" diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 0df991d730..ddd0b58db1 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -90,9 +90,8 @@ ifeq ($(PLATFORM_EXT), android) $(EXTDIR)/libzip/zip_unchange_data.c SOURCES_C +=\ - $(NATIVEDIR)/gfx_es2/gl3stub.c \ - $(NATIVEDIR)/math/fast/fast_math.c \ - $(NATIVEDIR)/math/fast/fast_matrix.c + $(COMMONDIR)/Math/fast/fast_math.c \ + $(COMMONDIR)/Math/fast/fast_matrix.c endif SOURCES_C += $(LIBRETRODIR)/ext/glew/glew.c @@ -166,6 +165,23 @@ SOURCES_CXX += \ $(COMMONDIR)/File/FileUtil.cpp \ $(COMMONDIR)/File/FileDescriptor.cpp \ $(COMMONDIR)/File/DirListing.cpp \ + $(COMMONDIR)/GPU/thin3d.cpp \ + $(COMMONDIR)/GPU/OpenGL/thin3d_gl.cpp \ + $(COMMONDIR)/GPU/OpenGL/GLDebugLog.cpp \ + $(COMMONDIR)/GPU/OpenGL/GLSLProgram.cpp \ + $(COMMONDIR)/GPU/OpenGL/gl3stub.c \ + $(COMMONDIR)/GPU/OpenGL/GLFeatures.cpp \ + $(COMMONDIR)/GPU/OpenGL/GLRenderManager.cpp \ + $(COMMONDIR)/GPU/OpenGL/GLQueueRunner.cpp \ + $(COMMONDIR)/GPU/OpenGL/DataFormatGL.cpp \ + $(COMMONDIR)/GPU/Vulkan/thin3d_vulkan.cpp \ + $(COMMONDIR)/GPU/Vulkan/VulkanQueueRunner.cpp \ + $(COMMONDIR)/GPU/Vulkan/VulkanRenderManager.cpp \ + $(COMMONDIR)/GPU/Vulkan/VulkanLoader.cpp \ + $(COMMONDIR)/GPU/Vulkan/VulkanContext.cpp \ + $(COMMONDIR)/GPU/Vulkan/VulkanDebug.cpp \ + $(COMMONDIR)/GPU/Vulkan/VulkanImage.cpp \ + $(COMMONDIR)/GPU/Vulkan/VulkanMemory.cpp \ $(COMMONDIR)/Input/GestureDetector.cpp \ $(COMMONDIR)/Input/InputState.cpp \ $(COMMONDIR)/Math/curves.cpp \ @@ -180,6 +196,8 @@ SOURCES_CXX += \ $(COMMONDIR)/Net/Sinks.cpp \ $(COMMONDIR)/Net/URL.cpp \ $(COMMONDIR)/Net/WebsocketServer.cpp \ + $(COMMONDIR)/Render/DrawBuffer.cpp \ + $(COMMONDIR)/Render/TextureAtlas.cpp \ $(COMMONDIR)/Serialize/Serializer.cpp \ $(COMMONDIR)/Thread/Executor.cpp \ $(COMMONDIR)/Thread/ThreadUtil.cpp \ @@ -321,19 +339,8 @@ SOURCES_CXX += $(COMMONDIR)/MemArenaPosix.cpp \ $(EXTDIR)/glslang/glslang/OSDependent/Unix/ossource.cpp endif -SOURCES_CXX += $(NATIVEDIR)/gfx/gl_debug_log.cpp \ - $(NATIVEDIR)/gfx/texture_atlas.cpp \ - $(NATIVEDIR)/gfx/d3d9_shader.cpp \ - $(NATIVEDIR)/gfx/d3d9_state.cpp \ - $(NATIVEDIR)/gfx_es2/draw_buffer.cpp \ - $(NATIVEDIR)/gfx_es2/draw_text.cpp \ - $(NATIVEDIR)/gfx_es2/gpu_features.cpp \ - $(NATIVEDIR)/gfx_es2/glsl_program.cpp \ - $(NATIVEDIR)/thin3d/thin3d.cpp \ - $(NATIVEDIR)/thin3d/thin3d_gl.cpp \ - $(NATIVEDIR)/thin3d/GLRenderManager.cpp \ - $(NATIVEDIR)/thin3d/GLQueueRunner.cpp \ - $(NATIVEDIR)/thin3d/DataFormatGL.cpp \ +SOURCES_CXX += \ + $(NATIVEDIR)/gfx_es2/draw_text.cpp \ $(EXTDIR)/jpge/jpgd.cpp \ $(EXTDIR)/jpge/jpge.cpp \ $(COREDIR)/AVIDump.cpp \ @@ -631,14 +638,6 @@ SOURCES_C += \ $(EXTDIR)/miniupnp/miniupnpc/upnpreplyparse.c SOURCES_CXX += \ - $(COMMONDIR)/Vulkan/VulkanContext.cpp \ - $(COMMONDIR)/Vulkan/VulkanDebug.cpp \ - $(COMMONDIR)/Vulkan/VulkanImage.cpp \ - $(COMMONDIR)/Vulkan/VulkanLoader.cpp \ - $(COMMONDIR)/Vulkan/VulkanMemory.cpp \ - $(NATIVEDIR)/thin3d/thin3d_vulkan.cpp \ - $(NATIVEDIR)/thin3d/VulkanRenderManager.cpp \ - $(NATIVEDIR)/thin3d/VulkanQueueRunner.cpp \ $(GPUDIR)/Vulkan/DepalettizeShaderVulkan.cpp \ $(GPUDIR)/Vulkan/DrawEngineVulkan.cpp \ $(GPUDIR)/Vulkan/FragmentShaderGeneratorVulkan.cpp \ @@ -691,11 +690,10 @@ SOURCES_CXX += \ $(LIBRETRODIR)/LibretroD3D11Context.cpp SOURCES_CXX += \ - $(NATIVEDIR)/thin3d/thin3d_d3d9.cpp \ - $(NATIVEDIR)/thin3d/thin3d_d3d11.cpp \ - $(NATIVEDIR)/thin3d/d3dx9_loader.cpp \ - $(NATIVEDIR)/thin3d/d3d11_loader.cpp \ - $(NATIVEDIR)/thin3d/d3d9_d3dcompiler_loader.cpp + $(COMMONDIR)/GPU/D3D9/thin3d_d3d9.cpp \ + $(COMMONDIR)/GPU/D3D11/thin3d_d3d11.cpp \ + $(COMMONDIR)/GPU/D3D11/D3D11Loader.cpp \ + $(COMMONDIR)/GPU/D3D9/D3DCompilerLoader.cpp INCFLAGS += -I$(CORE_DIR)/dx9sdk/Include -I$(CORE_DIR)/dx9sdk/Include/DX11 diff --git a/ppsspp_config.h b/ppsspp_config.h index 655e744f14..e429e629cb 100644 --- a/ppsspp_config.h +++ b/ppsspp_config.h @@ -123,10 +123,7 @@ #if PPSSPP_PLATFORM(WINDOWS) #if !PPSSPP_PLATFORM(UWP) #define PPSSPP_API_D3D9 1 - -// Comment this and uncomment PPSSPP_API_D3DX9 if D3DX9 is prefered. -#define PPSSPP_API_D3D9_D3DCOMPILER 1 -// #define PPSSPP_API_D3DX9 1 #endif #define PPSSPP_API_D3D11 1 #endif + From 8761bf2bc9df1d811f9d226d472d748d4bf6053a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 00:05:28 +0200 Subject: [PATCH 833/848] Move text rendering to Common. --- CMakeLists.txt | 18 +++++---- Common/Common.vcxproj | 10 +++++ Common/Common.vcxproj.filters | 33 +++++++++++++++++ Common/Render/DrawBuffer.cpp | 2 +- .../Render/Text}/draw_text.cpp | 13 ++++--- .../Render/Text}/draw_text.h | 2 +- .../Render/Text}/draw_text_android.cpp | 9 ++--- .../Render/Text}/draw_text_android.h | 2 +- .../Render/Text}/draw_text_qt.cpp | 4 +- .../Render/Text}/draw_text_qt.h | 2 +- .../Render/Text}/draw_text_uwp.cpp | 4 +- .../Render/Text}/draw_text_uwp.h | 2 +- .../Render/Text}/draw_text_win.cpp | 4 +- .../Render/Text}/draw_text_win.h | 2 +- Common/UI/Context.cpp | 2 +- Core/Util/PPGeDraw.cpp | 2 +- UI/EmuScreen.cpp | 2 +- UI/NativeApp.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 10 +++++ UWP/CommonUWP/CommonUWP.vcxproj.filters | 33 +++++++++++++++++ UWP/NativeUWP/NativeUWP.vcxproj | 4 -- UWP/NativeUWP/NativeUWP.vcxproj.filters | 17 --------- android/jni/Android.mk | 6 +-- ext/native/native.vcxproj | 14 ------- ext/native/native.vcxproj.filters | 37 ------------------- libretro/Makefile.common | 6 +-- 26 files changed, 130 insertions(+), 112 deletions(-) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text.cpp (91%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text.h (100%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text_android.cpp (99%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text_android.h (97%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text_qt.cpp (98%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text_qt.h (96%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text_uwp.cpp (99%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text_uwp.h (97%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text_win.cpp (99%) rename {ext/native/gfx_es2 => Common/Render/Text}/draw_text_win.h (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a70330c5ae..5cceb40913 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -560,6 +560,16 @@ add_library(Common STATIC Common/Render/TextureAtlas.h Common/Render/DrawBuffer.cpp Common/Render/DrawBuffer.h + Common/Render/Text/draw_text.cpp + Common/Render/Text/draw_text.h + Common/Render/Text/draw_text_android.cpp + Common/Render/Text/draw_text_android.h + Common/Render/Text/draw_text_qt.cpp + Common/Render/Text/draw_text_qt.h + Common/Render/Text/draw_text_win.cpp + Common/Render/Text/draw_text_win.h + Common/Render/Text/draw_text_uwp.cpp + Common/Render/Text/draw_text_uwp.h Common/System/Display.cpp Common/System/Display.h Common/Thread/Executor.cpp @@ -1062,14 +1072,6 @@ endif() add_library(native STATIC ${nativeExtra} - ext/native/gfx_es2/draw_text.cpp - ext/native/gfx_es2/draw_text.h - ext/native/gfx_es2/draw_text_win.cpp - ext/native/gfx_es2/draw_text_win.h - ext/native/gfx_es2/draw_text_qt.cpp - ext/native/gfx_es2/draw_text_qt.h - ext/native/gfx_es2/draw_text_android.cpp - ext/native/gfx_es2/draw_text_android.h ext/jpge/jpgd.cpp ext/jpge/jpgd.h ext/jpge/jpge.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index cc8f5594d0..16ba97f6c2 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -431,6 +431,11 @@ + + + + + @@ -753,6 +758,11 @@ + + + + + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index d38ea71068..10c28d065c 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -357,6 +357,21 @@ GPU\Vulkan + + Render\Text + + + Render\Text + + + Render\Text + + + Render\Text + + + Render\Text + @@ -692,6 +707,21 @@ GPU\Vulkan + + Render\Text + + + Render\Text + + + Render\Text + + + Render\Text + + + Render\Text + @@ -790,6 +820,9 @@ {c9aba118-5c31-4607-9a69-18eca9f92b44} + + {9da96cce-c74a-4669-b755-c95defbe1e93} + diff --git a/Common/Render/DrawBuffer.cpp b/Common/Render/DrawBuffer.cpp index d0d2e42a87..f23c753726 100644 --- a/Common/Render/DrawBuffer.cpp +++ b/Common/Render/DrawBuffer.cpp @@ -7,7 +7,7 @@ #include "Common/Math/math_util.h" #include "Common/Render/TextureAtlas.h" #include "Common/Render/DrawBuffer.h" -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Text/WrapText.h" diff --git a/ext/native/gfx_es2/draw_text.cpp b/Common/Render/Text/draw_text.cpp similarity index 91% rename from ext/native/gfx_es2/draw_text.cpp rename to Common/Render/Text/draw_text.cpp index b85e6eeb71..e236065483 100644 --- a/ext/native/gfx_es2/draw_text.cpp +++ b/Common/Render/Text/draw_text.cpp @@ -1,13 +1,16 @@ +#include "ppsspp_config.h" + #include "Common/System/Display.h" #include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" -#include "gfx_es2/draw_text.h" -#include "gfx_es2/draw_text_win.h" -#include "gfx_es2/draw_text_uwp.h" -#include "gfx_es2/draw_text_qt.h" -#include "gfx_es2/draw_text_android.h" + +#include "Common/Render/Text/draw_text.h" +#include "Common/Render/Text/draw_text_win.h" +#include "Common/Render/Text/draw_text_uwp.h" +#include "Common/Render/Text/draw_text_qt.h" +#include "Common/Render/Text/draw_text_android.h" TextDrawer::TextDrawer(Draw::DrawContext *draw) : draw_(draw) { // These probably shouldn't be state. diff --git a/ext/native/gfx_es2/draw_text.h b/Common/Render/Text/draw_text.h similarity index 100% rename from ext/native/gfx_es2/draw_text.h rename to Common/Render/Text/draw_text.h index 4d1862834d..252029b8a3 100644 --- a/ext/native/gfx_es2/draw_text.h +++ b/Common/Render/Text/draw_text.h @@ -13,8 +13,8 @@ #include #include -#include "Common/Render/DrawBuffer.h" #include "Common/Data/Text/WrapText.h" +#include "Common/Render/DrawBuffer.h" namespace Draw { class DrawContext; diff --git a/ext/native/gfx_es2/draw_text_android.cpp b/Common/Render/Text/draw_text_android.cpp similarity index 99% rename from ext/native/gfx_es2/draw_text_android.cpp rename to Common/Render/Text/draw_text_android.cpp index 263494f78c..7e6a66d85f 100644 --- a/ext/native/gfx_es2/draw_text_android.cpp +++ b/Common/Render/Text/draw_text_android.cpp @@ -1,16 +1,15 @@ +#include "Common/Log.h" +#include "Common/StringUtils.h" #include "Common/System/Display.h" #include "Common/GPU/thin3d.h" #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" -#include "gfx_es2/draw_text.h" -#include "gfx_es2/draw_text_android.h" +#include "Common/Render/Text/draw_text.h" +#include "Common/Render/Text/draw_text_android.h" #include "android/jni/app-android.h" -#include "Common/Log.h" -#include "Common/StringUtils.h" - #if PPSSPP_PLATFORM(ANDROID) && !defined(__LIBRETRO__) #include diff --git a/ext/native/gfx_es2/draw_text_android.h b/Common/Render/Text/draw_text_android.h similarity index 97% rename from ext/native/gfx_es2/draw_text_android.h rename to Common/Render/Text/draw_text_android.h index 51e5a3ab82..4b95bdeb75 100644 --- a/ext/native/gfx_es2/draw_text_android.h +++ b/Common/Render/Text/draw_text_android.h @@ -3,7 +3,7 @@ #include "ppsspp_config.h" #include -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #if PPSSPP_PLATFORM(ANDROID) diff --git a/ext/native/gfx_es2/draw_text_qt.cpp b/Common/Render/Text/draw_text_qt.cpp similarity index 98% rename from ext/native/gfx_es2/draw_text_qt.cpp rename to Common/Render/Text/draw_text_qt.cpp index 91f45fe7ec..166aac3a47 100644 --- a/ext/native/gfx_es2/draw_text_qt.cpp +++ b/Common/Render/Text/draw_text_qt.cpp @@ -3,8 +3,8 @@ #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" -#include "gfx_es2/draw_text.h" -#include "gfx_es2/draw_text_qt.h" +#include "Common/Render/Text/draw_text.h" +#include "Common/Render/Text/draw_text_qt.h" #include "Common/Log.h" diff --git a/ext/native/gfx_es2/draw_text_qt.h b/Common/Render/Text/draw_text_qt.h similarity index 96% rename from ext/native/gfx_es2/draw_text_qt.h rename to Common/Render/Text/draw_text_qt.h index e8c01cd118..2ac661b4ad 100644 --- a/ext/native/gfx_es2/draw_text_qt.h +++ b/Common/Render/Text/draw_text_qt.h @@ -3,7 +3,7 @@ #include "ppsspp_config.h" #include -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #if defined(USING_QT_UI) diff --git a/ext/native/gfx_es2/draw_text_uwp.cpp b/Common/Render/Text/draw_text_uwp.cpp similarity index 99% rename from ext/native/gfx_es2/draw_text_uwp.cpp rename to Common/Render/Text/draw_text_uwp.cpp index 4ea0bbfcc9..7ec375ae54 100644 --- a/ext/native/gfx_es2/draw_text_uwp.cpp +++ b/Common/Render/Text/draw_text_uwp.cpp @@ -3,8 +3,8 @@ #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" -#include "gfx_es2/draw_text.h" -#include "gfx_es2/draw_text_uwp.h" +#include "Common/Render/Text/draw_text.h" +#include "Common/Render/Text/draw_text_uwp.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/ext/native/gfx_es2/draw_text_uwp.h b/Common/Render/Text/draw_text_uwp.h similarity index 97% rename from ext/native/gfx_es2/draw_text_uwp.h rename to Common/Render/Text/draw_text_uwp.h index 59995f491b..816ae7ec06 100644 --- a/ext/native/gfx_es2/draw_text_uwp.h +++ b/Common/Render/Text/draw_text_uwp.h @@ -3,7 +3,7 @@ #include "ppsspp_config.h" #include -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #if PPSSPP_PLATFORM(UWP) diff --git a/ext/native/gfx_es2/draw_text_win.cpp b/Common/Render/Text/draw_text_win.cpp similarity index 99% rename from ext/native/gfx_es2/draw_text_win.cpp rename to Common/Render/Text/draw_text_win.cpp index 883eda1444..e7518857ef 100644 --- a/ext/native/gfx_es2/draw_text_win.cpp +++ b/Common/Render/Text/draw_text_win.cpp @@ -3,8 +3,8 @@ #include "Common/Data/Hash/Hash.h" #include "Common/Data/Text/WrapText.h" #include "Common/Data/Encoding/Utf8.h" -#include "gfx_es2/draw_text.h" -#include "gfx_es2/draw_text_win.h" +#include "Common/Render/Text/draw_text.h" +#include "Common/Render/Text/draw_text_win.h" #include "Common/Log.h" #include "Common/StringUtils.h" diff --git a/ext/native/gfx_es2/draw_text_win.h b/Common/Render/Text/draw_text_win.h similarity index 97% rename from ext/native/gfx_es2/draw_text_win.h rename to Common/Render/Text/draw_text_win.h index 41489eefbb..c59fa91db4 100644 --- a/ext/native/gfx_es2/draw_text_win.h +++ b/Common/Render/Text/draw_text_win.h @@ -3,7 +3,7 @@ #include "ppsspp_config.h" #include -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #if defined(_WIN32) && !defined(USING_QT_UI) && !PPSSPP_PLATFORM(UWP) diff --git a/Common/UI/Context.cpp b/Common/UI/Context.cpp index 467aa35166..adfa7d89d0 100644 --- a/Common/UI/Context.cpp +++ b/Common/UI/Context.cpp @@ -8,7 +8,7 @@ #include "Common/UI/View.h" #include "Common/UI/Context.h" #include "Common/Render/DrawBuffer.h" -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #include "Common/Log.h" #include "UI/TextureUtil.h" diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index b24802944d..f103b8bf15 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -18,7 +18,7 @@ #include #include "Common/Render/TextureAtlas.h" -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #include "Common/Data/Color/RGBAUtil.h" #include "Common/File/VFS/VFS.h" diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 079aae9795..b3d11af155 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -21,7 +21,7 @@ #include "Common/Render/TextureAtlas.h" #include "Common/GPU/OpenGL/GLFeatures.h" -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #include "Common/UI/Root.h" #include "Common/UI/UI.h" diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 0ae20b16a0..ef7547d411 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -46,7 +46,7 @@ #include "Common/Net/HTTPClient.h" #include "Common/Net/Resolve.h" #include "Common/Render/TextureAtlas.h" -#include "gfx_es2/draw_text.h" +#include "Common/Render/Text/draw_text.h" #include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/GPU/thin3d.h" #include "Common/UI/UI.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index 2a980dc4a6..f1ad520e49 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -439,6 +439,11 @@ + + + + + @@ -554,6 +559,11 @@ + + + + + diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 7d3f1f9ba4..071580a871 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -82,6 +82,9 @@ {2eb259f7-2735-493a-88be-96eb38f1b34e} + + {28139b08-f8d5-41a2-a5ee-bf86cf1469c3} + @@ -347,6 +350,21 @@ GPU\GL + + Render\Text + + + Render\Text + + + Render\Text + + + Render\Text + + + Render\Text + @@ -627,6 +645,21 @@ GPU\GL + + Render\Text + + + Render\Text + + + Render\Text + + + Render\Text + + + Render\Text + diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj index ed65f21e62..fe5acb8cd9 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ b/UWP/NativeUWP/NativeUWP.vcxproj @@ -379,14 +379,10 @@ - - - - Create Create diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters index b1fe9b4b87..abd4278e78 100644 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ b/UWP/NativeUWP/NativeUWP.vcxproj.filters @@ -2,26 +2,9 @@ - - gfx - - - gfx - - - gfx - - - gfx - - - - - {85815953-a0f8-409b-bbe9-c28f126ae7bf} - \ No newline at end of file diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 08c1f87950..25632e73cd 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -104,16 +104,16 @@ endif NATIVE_FILES :=\ $(SRC)/Common/Render/DrawBuffer.cpp \ $(SRC)/Common/Render/TextureAtlas.cpp \ + $(SRC)/Common/GPU/OpenGL/gl3stub.c \ $(SRC)/Common/GPU/OpenGL/thin3d_gl.cpp \ $(SRC)/Common/GPU/OpenGL/GLDebugLog.cpp \ $(SRC)/Common/GPU/OpenGL/GLSLProgram.cpp \ - $(SRC)/Common/GPU/OpenGL/gl3stub.c \ $(SRC)/Common/GPU/OpenGL/GLFeatures.cpp \ $(SRC)/Common/GPU/OpenGL/GLRenderManager.cpp \ $(SRC)/Common/GPU/OpenGL/GLQueueRunner.cpp \ $(SRC)/Common/GPU/OpenGL/DataFormatGL.cpp \ - $(SRC)/ext/native/gfx_es2/draw_text.cpp.arm \ - $(SRC)/ext/native/gfx_es2/draw_text_android.cpp.arm + $(SRC)/Common/Render/Text/draw_text.cpp.arm \ + $(SRC)/Common/Render/Text/draw_text_android.cpp.arm EGL_FILES := \ $(SRC)/Common/GL/GLInterface/EGL.cpp \ diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj index a66ede425e..14fd640a74 100644 --- a/ext/native/native.vcxproj +++ b/ext/native/native.vcxproj @@ -362,20 +362,6 @@ - - - - - - - - - - - - - - diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters index b1773f1582..949fbbb1ef 100644 --- a/ext/native/native.vcxproj.filters +++ b/ext/native/native.vcxproj.filters @@ -6,43 +6,6 @@ - - gfx - - - gfx - - - gfx - - - gfx - - - gfx - - - - - gfx - - - gfx - - - gfx - - - gfx - - - gfx - - - - - {9da89505-72a1-40e6-86e5-705372db1608} - {4515306f-4664-46bf-a89b-abfec5520a15} diff --git a/libretro/Makefile.common b/libretro/Makefile.common index ddd0b58db1..6f8ffebe6c 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -326,21 +326,21 @@ SOURCES_CXX += \ ifeq ($(PLATFORM_EXT), win32) SOURCES_CXX += $(COMMONDIR)/MemArenaWin32.cpp \ $(EXTDIR)/glslang/glslang/OSDependent/Windows/ossource.cpp \ - $(NATIVEDIR)/gfx_es2/draw_text_win.cpp + $(COMMONDIR)/Render/Text/draw_text_win.cpp else ifeq ($(PLATFORM_EXT), darwin) SOURCES_CXX += $(COMMONDIR)/MemArenaDarwin.cpp \ $(EXTDIR)/glslang/glslang/OSDependent/Unix/ossource.cpp else ifeq ($(PLATFORM_EXT), android) SOURCES_CXX += $(COMMONDIR)/MemArenaAndroid.cpp \ $(EXTDIR)/glslang/glslang/OSDependent/Unix/ossource.cpp \ - $(NATIVEDIR)/gfx_es2/draw_text_android.cpp + $(COMMONDIR)/Render/Text/draw_text_android.cpp else SOURCES_CXX += $(COMMONDIR)/MemArenaPosix.cpp \ $(EXTDIR)/glslang/glslang/OSDependent/Unix/ossource.cpp endif SOURCES_CXX += \ - $(NATIVEDIR)/gfx_es2/draw_text.cpp \ + $(COMMONDIR)/Render/Text/draw_text.cpp \ $(EXTDIR)/jpge/jpgd.cpp \ $(EXTDIR)/jpge/jpge.cpp \ $(COREDIR)/AVIDump.cpp \ From b236691548ca8c1d57202d5ab78e60ef1de41333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 00:13:29 +0200 Subject: [PATCH 834/848] Complete the eradication of D3DX9 compiler loader --- Common/GPU/D3D9/D3DCompilerLoader.cpp | 7 ++----- Common/GPU/D3D9/thin3d_d3d9.cpp | 10 +--------- UI/DevScreens.cpp | 8 -------- Windows/GPU/D3D9Context.cpp | 19 +------------------ 4 files changed, 4 insertions(+), 40 deletions(-) diff --git a/Common/GPU/D3D9/D3DCompilerLoader.cpp b/Common/GPU/D3D9/D3DCompilerLoader.cpp index d47aa354f3..0a231190f9 100644 --- a/Common/GPU/D3D9/D3DCompilerLoader.cpp +++ b/Common/GPU/D3D9/D3DCompilerLoader.cpp @@ -11,16 +11,13 @@ extern pD3DCompile ptr_D3DCompile; static int d3dcompiler_version = 47; -#define GB_MAKE_STR(s) # s -#define GB_MAKE_STR2(x) GB_MAKE_STR(x) -#define GB_D3D9_D3DCOMPILER_LOADER_CHECK_ENTRY_NULL_PTR(funcname) assert(false && GB_MAKE_STR2(funcname) ); - bool LoadD3DCompilerDynamic() { g_D3DCompileModule = LoadLibrary(D3DCOMPILER_DLL); #if PPSSPP_ARCH(X86) // Workaround for distributing both 32-bit and 64-bit versions of the DLL. - if (!g_D3DCompileModule) + if (!g_D3DCompileModule) { g_D3DCompileModule = LoadLibrary(L"D3dcompiler_47.x86.dll"); + } #endif if (!g_D3DCompileModule) { g_D3DCompileModule = LoadLibrary(L"D3dcompiler_42.dll"); diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index 1ec74c6ed9..6c7b5c233f 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -1252,19 +1252,11 @@ void D3D9Context::HandleEvent(Event ev, int width, int height, void *param1, voi } DrawContext *T3DCreateDX9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, IDirect3DDevice9 *device, IDirect3DDevice9Ex *deviceEx) { -#if PPSSPP_API(D3DX9) - int d3dx_ver = LoadD3DX9Dynamic(); - if (!d3dx_ver) { - ERROR_LOG(G3D, "Failed to load D3DX9!"); - return NULL; - } -#elif PPSSPP_API(D3D9_D3DCOMPILER) bool result = LoadD3DCompilerDynamic(); if (!result) { ERROR_LOG(G3D, "Failed to load D3DCompiler!"); - return NULL; + return nullptr; } -#endif return new D3D9Context(d3d, d3dEx, adapterId, device, deviceEx); } diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index bfa2495486..e133c89bac 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -52,12 +52,8 @@ #ifdef _WIN32 #include "Common/CommonWindows.h" // Want to avoid including the full header here as it includes d3dx.h -#if PPSSPP_API(D3DX9) -int GetD3DXVersion(); -#elif PPSSPP_API(D3D9_D3DCOMPILER) int GetD3DCompilerVersion(); #endif -#endif static const char *logLevelList[] = { "Notice", @@ -485,11 +481,7 @@ void SystemInfoScreen::CreateViews() { deviceSpecs->Add(new InfoItem(si->T("Driver Version"), System_GetProperty(SYSPROP_GPUDRIVER_VERSION))); #if !PPSSPP_PLATFORM(UWP) if (GetGPUBackend() == GPUBackend::DIRECT3D9) { -#if PPSSPP_API(D3DX9) - deviceSpecs->Add(new InfoItem(si->T("D3DX Version"), StringFromFormat("%d", GetD3DXVersion()))); -#elif PPSSPP_API(D3D9_D3DCOMPILER) deviceSpecs->Add(new InfoItem(si->T("D3DCompiler Version"), StringFromFormat("%d", GetD3DCompilerVersion()))); -#endif } #endif #endif diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index 27a9e4cc36..0ccfa8364c 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -19,12 +19,7 @@ #include "Windows/W32Util/Misc.h" #include "Common/GPU/thin3d.h" #include "Common/GPU/thin3d_create.h" - -#if PPSSPP_API(D3DX9) -#include "thin3d/d3dx9_loader.h" -#elif PPSSPP_API(D3D9_D3DCOMPILER) -#include "thin3d/d3d9_d3dcompiler_loader.h" -#endif +#include "Common/GPU/D3D9/D3DCompilerLoader.h" void D3D9Context::SwapBuffers() { if (has9Ex_) { @@ -76,19 +71,11 @@ bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { return false; } -#if PPSSPP_API(D3DX9) - int d3dx_version = LoadD3DX9Dynamic(); - if (!d3dx_version) { - *error_message = "D3DX DLL not found! Try reinstalling DirectX."; - return false; - } -#elif PPSSPP_API(D3D9_D3DCOMPILER) bool result = LoadD3DCompilerDynamic(); if (!result) { *error_message = "D3DCompiler not found! Try reinstalling DirectX."; return false; } -#endif g_pfnCreate9ex = (DIRECT3DCREATE9EX)GetProcAddress(hD3D9_, "Direct3DCreate9Ex"); has9Ex_ = (g_pfnCreate9ex != NULL) && IsVistaOrHigher(); @@ -231,11 +218,7 @@ void D3D9Context::Shutdown() { device_->EndScene(); device_->Release(); d3d_->Release(); -#if PPSSPP_API(D3DX9) - UnloadD3DXDynamic(); -#elif PPSSPP_API(D3D9_D3DCOMPILER) UnloadD3DCompiler(); -#endif DX9::pD3Ddevice = nullptr; DX9::pD3DdeviceEx = nullptr; device_ = nullptr; From 4310e35714cc71407a671977bb91a23d50156be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 06:55:02 +0200 Subject: [PATCH 835/848] Windows: Remove the native project. --- Common/Common.vcxproj | 56 ++- Core/Core.vcxproj | 21 +- GPU/GPU.vcxproj | 16 +- UWP/NativeUWP/NativeUWP.vcxproj | 409 ------------------- UWP/NativeUWP/NativeUWP.vcxproj.filters | 10 - UWP/NativeUWP/pch.cpp | 1 - UWP/NativeUWP/pch.h | 9 - UWP/NativeUWP/targetver.h | 8 - UWP/PPSSPP_UWP.sln | 2 - UWP/UWP.vcxproj | 5 +- Windows/PPSSPP.sln | 27 -- Windows/PPSSPP.vcxproj | 19 +- android/jni/Android.mk | 11 +- ext/native/LICENSE.TXT | 9 - ext/native/native.vcxproj | 368 ----------------- ext/native/native.vcxproj.filters | 13 - ext/native/tools/atlastool/atlastool.vcxproj | 5 +- ext/native/tools/zimtool/zimtool.vcxproj | 5 +- headless/Headless.vcxproj | 21 +- unittest/UnitTests.vcxproj | 21 +- 20 files changed, 92 insertions(+), 944 deletions(-) delete mode 100644 UWP/NativeUWP/NativeUWP.vcxproj delete mode 100644 UWP/NativeUWP/NativeUWP.vcxproj.filters delete mode 100644 UWP/NativeUWP/pch.cpp delete mode 100644 UWP/NativeUWP/pch.h delete mode 100644 UWP/NativeUWP/targetver.h delete mode 100644 ext/native/LICENSE.TXT delete mode 100644 ext/native/native.vcxproj delete mode 100644 ext/native/native.vcxproj.filters diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 16ba97f6c2..7e5dc35f0a 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -136,7 +136,7 @@ _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) Common/DbgNew.h MultiThreadedDebug - ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. StreamingSIMDExtensions2 Precise true @@ -148,8 +148,11 @@ Windows true + - Winmm.lib + ws2_32.lib + + @@ -158,7 +161,7 @@ Common/DbgNew.h MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -171,8 +174,11 @@ Windows true + - Winmm.lib + ws2_32.lib + + @@ -181,7 +187,7 @@ Common/DbgNew.h MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -194,8 +200,11 @@ Windows true + - Winmm.lib + ws2_32.lib + + @@ -205,7 +214,7 @@ MultiThreadedDebug _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. NotSet Precise false @@ -218,8 +227,11 @@ Windows true + - Winmm.lib + ws2_32.lib + + @@ -234,7 +246,7 @@ false StreamingSIMDExtensions2 Precise - ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. Speed true false @@ -247,8 +259,11 @@ true true + - Winmm.lib + ws2_32.lib + + @@ -260,7 +275,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;_M_X64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -278,8 +293,11 @@ true true + - Winmm.lib + ws2_32.lib + + @@ -291,7 +309,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_64=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -309,8 +327,11 @@ true true + - Winmm.lib + ws2_32.lib + + @@ -322,7 +343,7 @@ USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;NDEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ext/glew;../ext/native;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. + ../ext/glew;../ext/snappy;../ext/glslang;../ext/libpng17;../ext;../ext/zlib;.. false NotSet Precise @@ -340,8 +361,11 @@ true true + - Winmm.lib + ws2_32.lib + + diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 2fc9e33ae1..e23beab505 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -138,7 +138,7 @@ Level3 - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) StreamingSIMDExtensions2 Precise @@ -161,7 +161,7 @@ Level3 - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) NotSet Precise @@ -185,7 +185,7 @@ Level3 - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotSet Precise @@ -209,7 +209,7 @@ Level3 - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotSet Precise @@ -237,7 +237,7 @@ MaxSpeed true true - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext false StreamingSIMDExtensions2 Precise @@ -268,7 +268,7 @@ MaxSpeed true true - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext NotSet Precise false @@ -299,7 +299,7 @@ MaxSpeed true true - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext NotSet Precise false @@ -330,7 +330,7 @@ MaxSpeed true true - ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/native;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext + ..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext NotSet Precise false @@ -1287,9 +1287,6 @@ {457f45d2-556f-47bc-a31d-aff0d15beaed} - - {C4DF647E-80EA-4111-A0A8-218B1B711E18} - {f761046e-6c38-4428-a5f1-38391a37bb34} @@ -1301,4 +1298,4 @@ - \ No newline at end of file + diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index d77221d6a4..5d3468b07d 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -164,7 +164,7 @@ Level3 - ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;../ext/glslang + ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/glew;../ext/snappy;../ext/glslang _CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_SECURE_NO_WARNINGS;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;%(PreprocessorDefinitions) StreamingSIMDExtensions2 Precise @@ -182,7 +182,7 @@ Level3 - ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;../ext/glslang + ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/glew;../ext/snappy;../ext/glslang NotSet Precise false @@ -202,7 +202,7 @@ Level3 - ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;../ext/glslang + ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/glew;../ext/snappy;../ext/glslang NotSet Precise false @@ -221,7 +221,7 @@ Level3 - ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;../ext/glslang + ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/glew;../ext/snappy;../ext/glslang NotSet Precise false @@ -244,7 +244,7 @@ MaxSpeed true true - ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;../ext/glslang + ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/glew;../ext/snappy;../ext/glslang false StreamingSIMDExtensions2 Precise @@ -267,7 +267,7 @@ MaxSpeed true true - ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;../ext/glslang + ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/glew;../ext/snappy;../ext/glslang false NotSet Precise @@ -292,7 +292,7 @@ MaxSpeed true true - ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;../ext/glslang + ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/glew;../ext/snappy;../ext/glslang false NotSet Precise @@ -317,7 +317,7 @@ MaxSpeed true true - ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/native;../ext/glew;../ext/snappy;../ext/glslang + ..\dx9sdk\Include\DX11;../common;..;../ext;../ext/glew;../ext/snappy;../ext/glslang false NotSet Precise diff --git a/UWP/NativeUWP/NativeUWP.vcxproj b/UWP/NativeUWP/NativeUWP.vcxproj deleted file mode 100644 index fe5acb8cd9..0000000000 --- a/UWP/NativeUWP/NativeUWP.vcxproj +++ /dev/null @@ -1,409 +0,0 @@ - - - - - Debug - ARM - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - UWP Gold - ARM - - - UWP Gold - ARM64 - - - UWP Gold - Win32 - - - UWP Gold - x64 - - - - {935028af-b850-4ad7-a00e-7ba84fb97d05} - StaticLibrary - NativeUWP - en-US - 14.0 - true - Windows Store - 10.0.15063.0 - 10.0 - 10.0.17763.0 - - - - StaticLibrary - true - - - StaticLibrary - true - - - StaticLibrary - true - - - StaticLibrary - true - - - StaticLibrary - false - true - - - StaticLibrary - false - true - - - StaticLibrary - false - false - - - StaticLibrary - false - false - - - StaticLibrary - false - false - - - StaticLibrary - false - false - - - StaticLibrary - false - true - - - StaticLibrary - false - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - Console - false - false - - - - - Use - false - true - pch.h - ../..;../../ext;../..;../../ext/native;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - - - Console - false - false - - - - - - - - - Create - Create - Create - Create - Create - Create - Create - Create - Create - Create - Create - Create - - - - - {ddf90203-0aae-4f38-b589-2e9637658ce6} - - - - - - \ No newline at end of file diff --git a/UWP/NativeUWP/NativeUWP.vcxproj.filters b/UWP/NativeUWP/NativeUWP.vcxproj.filters deleted file mode 100644 index abd4278e78..0000000000 --- a/UWP/NativeUWP/NativeUWP.vcxproj.filters +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/UWP/NativeUWP/pch.cpp b/UWP/NativeUWP/pch.cpp deleted file mode 100644 index bcb5590be1..0000000000 --- a/UWP/NativeUWP/pch.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pch.h" diff --git a/UWP/NativeUWP/pch.h b/UWP/NativeUWP/pch.h deleted file mode 100644 index 529bbb17fe..0000000000 --- a/UWP/NativeUWP/pch.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "targetver.h" - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include diff --git a/UWP/NativeUWP/targetver.h b/UWP/NativeUWP/targetver.h deleted file mode 100644 index a66ecb00f1..0000000000 --- a/UWP/NativeUWP/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/UWP/PPSSPP_UWP.sln b/UWP/PPSSPP_UWP.sln index 63a8e5f693..fc6a017b01 100644 --- a/UWP/PPSSPP_UWP.sln +++ b/UWP/PPSSPP_UWP.sln @@ -11,8 +11,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CoreUWP", "CoreUWP\CoreUWP. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPU_UWP", "GPU_UWP\GPU_UWP.vcxproj", "{5D271429-C288-4534-98AF-94475D940058}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NativeUWP", "NativeUWP\NativeUWP.vcxproj", "{935028AF-B850-4AD7-A00E-7BA84FB97D05}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UI_UWP", "UI_UWP\UI_UWP.vcxproj", "{5FAC15BD-7397-4512-99D5-66CDC03AF5B7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libkirk_UWP", "libkirk_UWP\libkirk_UWP.vcxproj", "{2F911C05-B341-4291-8BF5-09EDECBDD5F5}" diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 67e2def6bd..c3bbfac336 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -1728,9 +1728,6 @@ {2f911c05-b341-4291-8bf5-09edecbdd5f5} - - {935028af-b850-4ad7-a00e-7ba84fb97d05} - {2b2d16bd-1d37-46af-a3f8-552900951b26} @@ -1758,4 +1755,4 @@ - \ No newline at end of file + diff --git a/Windows/PPSSPP.sln b/Windows/PPSSPP.sln index 942e26be29..ee3d5e3512 100644 --- a/Windows/PPSSPP.sln +++ b/Windows/PPSSPP.sln @@ -8,7 +8,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPPWindows", "PPSSPP.vcx {129E5E2B-39C1-4D84-96FE-DFD22DBB4A25} = {129E5E2B-39C1-4D84-96FE-DFD22DBB4A25} {533F1D30-D04D-47CC-AD71-20F658907E36} = {533F1D30-D04D-47CC-AD71-20F658907E36} {F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34} - {C4DF647E-80EA-4111-A0A8-218B1B711E18} = {C4DF647E-80EA-4111-A0A8-218B1B711E18} {3BAAE095-E0AB-4B0E-B5DF-CE39C8AE31DE} = {3BAAE095-E0AB-4B0E-B5DF-CE39C8AE31DE} {457F45D2-556F-47BC-A31D-AFF0D15BEAED} = {457F45D2-556F-47BC-A31D-AFF0D15BEAED} {3FCDBAE2-5103-4350-9A8E-848CE9C73195} = {3FCDBAE2-5103-4350-9A8E-848CE9C73195} @@ -17,7 +16,6 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\Common\Common.vcxproj", "{3FCDBAE2-5103-4350-9A8E-848CE9C73195}" ProjectSection(ProjectDependencies) = postProject {F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34} - {C4DF647E-80EA-4111-A0A8-218B1B711E18} = {C4DF647E-80EA-4111-A0A8-218B1B711E18} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\ext\zlib\zlib.vcxproj", "{F761046E-6C38-4428-A5F1-38391A37BB34}" @@ -32,17 +30,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "..\Core\Core.vcxpro ProjectSection(ProjectDependencies) = postProject {129E5E2B-39C1-4D84-96FE-DFD22DBB4A25} = {129E5E2B-39C1-4D84-96FE-DFD22DBB4A25} {F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34} - {C4DF647E-80EA-4111-A0A8-218B1B711E18} = {C4DF647E-80EA-4111-A0A8-218B1B711E18} {457F45D2-556F-47BC-A31D-AFF0D15BEAED} = {457F45D2-556F-47BC-A31D-AFF0D15BEAED} {3FCDBAE2-5103-4350-9A8E-848CE9C73195} = {3FCDBAE2-5103-4350-9A8E-848CE9C73195} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "native", "..\ext\native\native.vcxproj", "{C4DF647E-80EA-4111-A0A8-218B1B711E18}" - ProjectSection(ProjectDependencies) = postProject - {F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34} - {EDFA2E87-8AC1-4853-95D4-D7594FF81947} = {EDFA2E87-8AC1-4853-95D4-D7594FF81947} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPPHeadless", "..\headless\Headless.vcxproj", "{EE9BD869-CAA3-447D-8328-294D90DE2C1F}" ProjectSection(ProjectDependencies) = postProject {129E5E2B-39C1-4D84-96FE-DFD22DBB4A25} = {129E5E2B-39C1-4D84-96FE-DFD22DBB4A25} @@ -61,13 +52,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "..\unittest\Uni {129E5E2B-39C1-4D84-96FE-DFD22DBB4A25} = {129E5E2B-39C1-4D84-96FE-DFD22DBB4A25} {533F1D30-D04D-47CC-AD71-20F658907E36} = {533F1D30-D04D-47CC-AD71-20F658907E36} {F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34} - {C4DF647E-80EA-4111-A0A8-218B1B711E18} = {C4DF647E-80EA-4111-A0A8-218B1B711E18} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UI", "..\UI\UI.vcxproj", "{004B8D11-2BE3-4BD9-AB40-2BE04CF2096F}" ProjectSection(ProjectDependencies) = postProject {533F1D30-D04D-47CC-AD71-20F658907E36} = {533F1D30-D04D-47CC-AD71-20F658907E36} - {C4DF647E-80EA-4111-A0A8-218B1B711E18} = {C4DF647E-80EA-4111-A0A8-218B1B711E18} {457F45D2-556F-47BC-A31D-AFF0D15BEAED} = {457F45D2-556F-47BC-A31D-AFF0D15BEAED} {3FCDBAE2-5103-4350-9A8E-848CE9C73195} = {3FCDBAE2-5103-4350-9A8E-848CE9C73195} EndProjectSection @@ -178,22 +167,6 @@ Global {533F1D30-D04D-47CC-AD71-20F658907E36}.Release|Win32.Build.0 = Release|Win32 {533F1D30-D04D-47CC-AD71-20F658907E36}.Release|x64.ActiveCfg = Release|x64 {533F1D30-D04D-47CC-AD71-20F658907E36}.Release|x64.Build.0 = Release|x64 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Debug|ARM.ActiveCfg = Debug|ARM - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Debug|ARM.Build.0 = Debug|ARM - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Debug|ARM64.Build.0 = Debug|ARM64 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Debug|Win32.ActiveCfg = Debug|Win32 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Debug|Win32.Build.0 = Debug|Win32 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Debug|x64.ActiveCfg = Debug|x64 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Debug|x64.Build.0 = Debug|x64 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Release|ARM.ActiveCfg = Release|ARM - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Release|ARM.Build.0 = Release|ARM - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Release|ARM64.ActiveCfg = Release|ARM64 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Release|ARM64.Build.0 = Release|ARM64 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Release|Win32.ActiveCfg = Release|Win32 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Release|Win32.Build.0 = Release|Win32 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Release|x64.ActiveCfg = Release|x64 - {C4DF647E-80EA-4111-A0A8-218B1B711E18}.Release|x64.Build.0 = Release|x64 {EE9BD869-CAA3-447D-8328-294D90DE2C1F}.Debug|ARM.ActiveCfg = Debug|ARM {EE9BD869-CAA3-447D-8328-294D90DE2C1F}.Debug|ARM.Build.0 = Debug|ARM {EE9BD869-CAA3-447D-8328-294D90DE2C1F}.Debug|ARM64.ActiveCfg = Debug|ARM64 diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index def7547093..55a21f5a1d 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -237,7 +237,7 @@ Use Level3 ProgramDatabase - ../ffmpeg/Windows/x86/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/x86/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/glew;../ext/zlib stdafx.h;Common/DbgNew.h MultiThreadedDebug StreamingSIMDExtensions2 @@ -275,7 +275,7 @@ Use Level3 ProgramDatabase - ../ffmpeg/Windows/x86_64/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/x86_64/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/glew;../ext/zlib stdafx.h;Common/DbgNew.h MultiThreadedDebug false @@ -310,7 +310,7 @@ Use Level3 ProgramDatabase - ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/glew;../ext/zlib stdafx.h;Common/DbgNew.h MultiThreadedDebug false @@ -344,7 +344,7 @@ Use Level3 ProgramDatabase - ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/glew;../ext/zlib stdafx.h MultiThreadedDebug false @@ -384,7 +384,7 @@ Use Level3 ProgramDatabase - ../ffmpeg/Windows/x86/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/x86/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/glew;../ext/zlib stdafx.h stdafx.h true @@ -433,7 +433,7 @@ Use Level3 ProgramDatabase - ../ffmpeg/Windows/x86_64/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/x86_64/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/glew;../ext/zlib stdafx.h true false @@ -475,7 +475,7 @@ Use Level3 ProgramDatabase - ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/glew;../ext/zlib stdafx.h true false @@ -515,7 +515,7 @@ Use Level3 ProgramDatabase - ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../ext;../common;..;../ext/glew;../ext/zlib stdafx.h true false @@ -1689,9 +1689,6 @@ {457f45d2-556f-47bc-a31d-aff0d15beaed} - - {C4DF647E-80EA-4111-A0A8-218B1B711E18} - {f761046e-6c38-4428-a5f1-38391a37bb34} diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 25632e73cd..8538ce1f5a 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -102,8 +102,6 @@ ARCH_FILES := \ endif NATIVE_FILES :=\ - $(SRC)/Common/Render/DrawBuffer.cpp \ - $(SRC)/Common/Render/TextureAtlas.cpp \ $(SRC)/Common/GPU/OpenGL/gl3stub.c \ $(SRC)/Common/GPU/OpenGL/thin3d_gl.cpp \ $(SRC)/Common/GPU/OpenGL/GLDebugLog.cpp \ @@ -111,9 +109,7 @@ NATIVE_FILES :=\ $(SRC)/Common/GPU/OpenGL/GLFeatures.cpp \ $(SRC)/Common/GPU/OpenGL/GLRenderManager.cpp \ $(SRC)/Common/GPU/OpenGL/GLQueueRunner.cpp \ - $(SRC)/Common/GPU/OpenGL/DataFormatGL.cpp \ - $(SRC)/Common/Render/Text/draw_text.cpp.arm \ - $(SRC)/Common/Render/Text/draw_text_android.cpp.arm + $(SRC)/Common/GPU/OpenGL/DataFormatGL.cpp EGL_FILES := \ $(SRC)/Common/GL/GLInterface/EGL.cpp \ @@ -257,6 +253,11 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/File/FileUtil.cpp \ $(SRC)/Common/File/DirListing.cpp \ $(SRC)/Common/File/FileDescriptor.cpp \ + $(SRC)/Common/GPU/thin3d.cpp \ + $(SRC)/Common/Render/DrawBuffer.cpp \ + $(SRC)/Common/Render/TextureAtlas.cpp \ + $(SRC)/Common/Render/Text/draw_text.cpp \ + $(SRC)/Common/Render/Text/draw_text_android.cpp \ $(SRC)/Common/Input/GestureDetector.cpp \ $(SRC)/Common/Input/InputState.cpp \ $(SRC)/Common/Math/fast/fast_math.c \ diff --git a/ext/native/LICENSE.TXT b/ext/native/LICENSE.TXT deleted file mode 100644 index e92ab68fef..0000000000 --- a/ext/native/LICENSE.TXT +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (C) 2012 Henrik Rydgard - -This applies to all the code here not covered under other licenses, see README.md. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ext/native/native.vcxproj b/ext/native/native.vcxproj deleted file mode 100644 index 14fd640a74..0000000000 --- a/ext/native/native.vcxproj +++ /dev/null @@ -1,368 +0,0 @@ - - - - - Debug - ARM - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - - {C4DF647E-80EA-4111-A0A8-218B1B711E18} - Win32Proj - native - 10.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StaticLibrary - true - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - true - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - true - Unicode - $(DefaultPlatformToolset) - true - - - StaticLibrary - true - Unicode - $(DefaultPlatformToolset) - true - - - StaticLibrary - false - false - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - false - Unicode - $(DefaultPlatformToolset) - - - StaticLibrary - false - Unicode - $(DefaultPlatformToolset) - true - - - StaticLibrary - false - Unicode - $(DefaultPlatformToolset) - true - - - - - - - - - $(VC_IncludePath);$(WindowsSDK_IncludePath) - - - $(VC_IncludePath);$(WindowsSDK_IncludePath) - - - - - - - - - $(VC_IncludePath);$(WindowsSDK_IncludePath) - - - $(VC_IncludePath);$(WindowsSDK_IncludePath) - - - - - - Level3 - _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) - true - false - false - MultiThreadedDebug - ../../Common/DbgNew.h - ProgramDatabase - - - Windows - true - - - Ws2_32.lib - - - - - - - Level3 - _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) - true - false - false - MultiThreadedDebug - false - ../../Common/DbgNew.h - ProgramDatabase - - - Windows - true - - - Ws2_32.lib - - - - - - - Level3 - _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) - true - false - false - MultiThreadedDebug - false - ../../Common/DbgNew.h - ProgramDatabase - - - Windows - true - - - Ws2_32.lib - - - - - - - Level3 - _CRTDBG_MAP_ALLOC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) - true - false - false - MultiThreadedDebug - false - - - ProgramDatabase - - - Windows - true - - - Ws2_32.lib - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) - StreamingSIMDExtensions2 - Precise - true - false - MultiThreaded - ProgramDatabase - false - - - Windows - true - true - true - - - Ws2_32.lib - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) - NotSet - Precise - true - false - MultiThreaded - ProgramDatabase - false - true - false - - - Windows - true - true - true - - - Ws2_32.lib - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) - Precise - true - false - MultiThreaded - ProgramDatabase - false - true - false - - - Windows - true - true - true - - - Ws2_32.lib - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ..\..\ext;..\..;..\..\dx9sdk\Include;..\..\dx9sdk\Include\DX11;..\zlib;..\ext\zlib;..\native;..\RollerballGL;..\glew;..\SDL\include;%(AdditionalIncludeDirectories) - NotSet - Precise - true - false - MultiThreaded - ProgramDatabase - false - true - false - - - Windows - true - true - true - - - Ws2_32.lib - - - - - - - - - \ No newline at end of file diff --git a/ext/native/native.vcxproj.filters b/ext/native/native.vcxproj.filters deleted file mode 100644 index 949fbbb1ef..0000000000 --- a/ext/native/native.vcxproj.filters +++ /dev/null @@ -1,13 +0,0 @@ - - - - - tools - - - - - {4515306f-4664-46bf-a89b-abfec5520a15} - - - \ No newline at end of file diff --git a/ext/native/tools/atlastool/atlastool.vcxproj b/ext/native/tools/atlastool/atlastool.vcxproj index 805700c863..afd5ad8b43 100644 --- a/ext/native/tools/atlastool/atlastool.vcxproj +++ b/ext/native/tools/atlastool/atlastool.vcxproj @@ -17,9 +17,6 @@ {f761046e-6c38-4428-a5f1-38391a37bb34} - - {c4df647e-80ea-4111-a0a8-218b1b711e18} - @@ -111,4 +108,4 @@ - \ No newline at end of file + diff --git a/ext/native/tools/zimtool/zimtool.vcxproj b/ext/native/tools/zimtool/zimtool.vcxproj index 1eecf94c3f..5c91fc8a23 100644 --- a/ext/native/tools/zimtool/zimtool.vcxproj +++ b/ext/native/tools/zimtool/zimtool.vcxproj @@ -17,9 +17,6 @@ {f761046e-6c38-4428-a5f1-38391a37bb34} - - {c4df647e-80ea-4111-a0a8-218b1b711e18} - @@ -108,4 +105,4 @@ - \ No newline at end of file + diff --git a/headless/Headless.vcxproj b/headless/Headless.vcxproj index 8702c8a511..29d26051d5 100644 --- a/headless/Headless.vcxproj +++ b/headless/Headless.vcxproj @@ -176,7 +176,7 @@ NotUsing 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 - ../ffmpeg/Windows/x86/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native + ../ffmpeg/Windows/x86/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew EnableFastChecks StreamingSIMDExtensions2 Precise @@ -209,7 +209,7 @@ NotUsing Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/x86_64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native + ../ffmpeg/Windows/x86_64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew NotSet Precise false @@ -242,7 +242,7 @@ NotUsing Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native + ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew Precise false true @@ -271,7 +271,7 @@ NotUsing Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native + ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew Precise false true @@ -303,7 +303,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS - ../ffmpeg/Windows/x86/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native + ../ffmpeg/Windows/x86/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew false StreamingSIMDExtensions2 Precise @@ -339,7 +339,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/x86_64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native + ../ffmpeg/Windows/x86_64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew false NotSet Precise @@ -377,7 +377,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native + ../ffmpeg/Windows/aarch64/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew false Precise Speed @@ -411,7 +411,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_CONSOLE;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew;../ext/native + ../ffmpeg/Windows/arm/include;../dx9sdk/Include/DX11;../Common;..;../Core;../ext/glew false Precise Speed @@ -500,9 +500,6 @@ {457f45d2-556f-47bc-a31d-aff0d15beaed} - - {C4DF647E-80EA-4111-A0A8-218B1B711E18} - {f761046e-6c38-4428-a5f1-38391a37bb34} @@ -516,4 +513,4 @@ - \ No newline at end of file + diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index 86caf65925..a401a081b7 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -169,7 +169,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/x86/include;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/x86/include;../ext;../common;..;../ext/glew;../ext/zlib true false false @@ -191,7 +191,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/x86_64/include;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/x86_64/include;../ext;../common;..;../ext/glew;../ext/zlib true false false @@ -214,7 +214,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/aarch64/include;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/aarch64/include;../ext;../common;..;../ext/glew;../ext/zlib true false false @@ -237,7 +237,7 @@ Level3 _CRTDBG_MAP_ALLOC;USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/arm/include;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/arm/include;../ext;../common;..;../ext/glew;../ext/zlib true false false @@ -264,7 +264,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/x86/include;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/x86/include;../ext;../common;..;../ext/glew;../ext/zlib false Size true @@ -291,7 +291,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/x86_64/include;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/x86_64/include;../ext;../common;..;../ext/glew;../ext/zlib false true false @@ -320,7 +320,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_64=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/aarch64/include;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/aarch64/include;../ext;../common;..;../ext/glew;../ext/zlib false true false @@ -349,7 +349,7 @@ true true USING_WIN_UI;GLEW_STATIC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_ARCH_32=1;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions) - ../ffmpeg/Windows/arm/include;../ext;../common;..;../ext/native;../ext/glew;../ext/zlib + ../ffmpeg/Windows/arm/include;../ext;../common;..;../ext/glew;../ext/zlib false true false @@ -414,9 +414,6 @@ {457f45d2-556f-47bc-a31d-aff0d15beaed} - - {c4df647e-80ea-4111-a0a8-218b1b711e18} - {004b8d11-2be3-4bd9-ab40-2be04cf2096f} @@ -429,4 +426,4 @@ - \ No newline at end of file + From c42e9278b350860776133c96a90675e03ce81f8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 09:13:35 +0200 Subject: [PATCH 836/848] Buildfix linux --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cceb40913..ff39a5b5ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,6 +169,9 @@ include_directories(ext/native) # Work around for some misfeature of the current glslang build system include_directories(ext/glslang) +# Not sure if this is the best way - what about system glew? +# Anyway, glew will be going away anyway. +include_directories(ext/glew) if(NOT OPENGL_LIBRARIES AND USING_GLES2) set(OPENGL_LIBRARIES GLESv2 EGL) From 7d43ca512533b424c224c641f2f8385aa056275c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 10:19:04 +0200 Subject: [PATCH 837/848] Fix Qt build by simply moving the offending file to the native project. No idea why Qt include paths only work there. --- CMakeLists.txt | 71 ++++++++++++++--------------- Common/GPU/thin3d.cpp | 5 +- Common/Render/Text/draw_text_qt.cpp | 1 + Common/Render/Text/draw_text_qt.h | 2 +- macshaders.sh | 11 ----- 5 files changed, 38 insertions(+), 52 deletions(-) delete mode 100644 macshaders.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index ff39a5b5ed..a62d384318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,8 +164,6 @@ else() set(CoreLinkType STATIC) endif() -include_directories(ext/native) - # Work around for some misfeature of the current glslang build system include_directories(ext/glslang) @@ -302,12 +300,7 @@ if(NOT MSVC) if(IOS) elseif(APPLE AND NOT CMAKE_CROSSCOMPILING) - # We want C++11, so target 10.7+ - if(USING_QT_UI) - set(MACOSX_VERSION_MIN "10.8") - else() - set(MACOSX_VERSION_MIN "10.7") - endif() + set(MACOSX_VERSION_MIN "10.8") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=${MACOSX_VERSION_MIN}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=${MACOSX_VERSION_MIN} -stdlib=libc++ -U__STRICT_ANSI__") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") @@ -357,6 +350,14 @@ macro(setup_target_project TargetName ProjectDir) endforeach() endmacro() +add_subdirectory(ext) + +if(WIN32) + include_directories(dx9sdk/Include) + include_directories(dx9sdk/Include/DX11) +endif() + + set(CommonX86 Common/ABI.cpp Common/ABI.h @@ -423,7 +424,6 @@ add_library(Common STATIC ${CommonARM64} ${CommonMIPS} ${CommonFake} - ${CommonVulkan} ${CommonD3D} Common/Serialize/Serializer.cpp Common/Serialize/Serializer.h @@ -567,8 +567,6 @@ add_library(Common STATIC Common/Render/Text/draw_text.h Common/Render/Text/draw_text_android.cpp Common/Render/Text/draw_text_android.h - Common/Render/Text/draw_text_qt.cpp - Common/Render/Text/draw_text_qt.h Common/Render/Text/draw_text_win.cpp Common/Render/Text/draw_text_win.h Common/Render/Text/draw_text_uwp.cpp @@ -644,39 +642,21 @@ add_library(Common STATIC Common/TimeUtil.h ) -add_subdirectory(ext) - include_directories(Common) setup_target_project(Common Common) target_link_libraries(Common Ext::Snappy) -if(WIN32) - include_directories(dx9sdk/Include) - include_directories(dx9sdk/Include/DX11) - if(MINGW) - set(CMAKE_RC_COMPILE_OBJECT " -O coff ") - # required when using the dx9sdk include paths - add_definitions(-include ${CMAKE_CURRENT_SOURCE_DIR}/Windows/mingw_defines.h) - else() - target_link_libraries(Common dxguid) - endif() - target_link_libraries(Common winmm d3d9 dsound) -endif() - -if(TARGET SDL2::SDL2) - target_link_libraries(Common SDL2::SDL2) -endif() - if(USING_GLES2 OR (USING_EGL AND NOT USING_FBDEV)) find_package(X11) endif() add_library(gason STATIC - ext/gason/gason.cpp - ext/gason/gason.h + ext/gason/gason.cpp + ext/gason/gason.h ) + if(USE_FFMPEG) if(NOT FFMPEG_DIR) if(NOT USE_SYSTEM_FFMPEG) @@ -981,11 +961,13 @@ elseif(USING_QT_UI) if(USING_GLES2) add_definitions(-DQT_OPENGL_ES -DQT_OPENGL_ES_2) endif() - include_directories(${CMAKE_CURRENT_BINARY_DIR} Qt) + + include_directories(Qt) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) set(nativeExtraLibs ${nativeExtraLibs} Qt5::OpenGL Qt5::Gui Qt5::Core Qt5::Multimedia) set(TargetBin PPSSPPQt) - # Enable SDL if found + # Enable SDL joystick if SDL is found if(SDL2_FOUND) add_definitions(-DSDL) set(nativeExtra ${nativeExtra} @@ -1026,6 +1008,22 @@ elseif(NOT LIBRETRO) message(FATAL_ERROR "Could not find SDL2. Failing.") endif() +if(WIN32) + if(MINGW) + set(CMAKE_RC_COMPILE_OBJECT " -O coff ") + # required when using the dx9sdk include paths + add_definitions(-include ${CMAKE_CURRENT_SOURCE_DIR}/Windows/mingw_defines.h) + else() + target_link_libraries(Common dxguid) + endif() + target_link_libraries(Common winmm d3d9 dsound) +endif() + +if(TARGET SDL2::SDL2) + target_link_libraries(Common SDL2::SDL2) +endif() + + list(APPEND NativeAppSource android/jni/TestRunner.cpp UI/DiscordIntegration.cpp @@ -1075,12 +1073,13 @@ endif() add_library(native STATIC ${nativeExtra} + Common/Render/Text/draw_text_qt.cpp + Common/Render/Text/draw_text_qt.h ext/jpge/jpgd.cpp ext/jpge/jpgd.h ext/jpge/jpge.cpp ext/jpge/jpge.h ) -include_directories(ext/native) if(LINUX AND NOT ANDROID) set(RT_LIB rt) @@ -1103,7 +1102,6 @@ elseif(WIN32) elseif(${CMAKE_SYSTEM_NAME} MATCHES "^(DragonFly|FreeBSD|NetBSD)$") target_link_libraries(native execinfo) endif() -setup_target_project(native native) add_library(kirk STATIC ext/libkirk/AES.c @@ -1809,7 +1807,6 @@ set(CoreExtraLibs ${CoreExtraLibs} armips) # target_link_libraries(native X11-xcb X11) #endif() - set(GlslangLibs glslang OGLCompiler OSDependent SPIRV SPVRemapper spirv-cross-glsl) if(WIN32) diff --git a/Common/GPU/thin3d.cpp b/Common/GPU/thin3d.cpp index dfac21e038..95dce26147 100644 --- a/Common/GPU/thin3d.cpp +++ b/Common/GPU/thin3d.cpp @@ -6,7 +6,6 @@ #include "Common/GPU/thin3d.h" #include "Common/Log.h" #include "Common/ColorConv.h" -#include "Core/Reporting.h" namespace Draw { @@ -450,7 +449,7 @@ void ConvertFromRGBA8888(uint8_t *dst, const uint8_t *src, uint32_t dstStride, u case Draw::DataFormat::R8G8B8A8_UNORM: case Draw::DataFormat::UNDEFINED: default: - WARN_LOG_REPORT_ONCE(convFromRGBA, G3D, "Unable to convert from format: %d", (int)format); + WARN_LOG(G3D, "Unable to convert from format: %d", (int)format); break; } } @@ -492,7 +491,7 @@ void ConvertFromBGRA8888(uint8_t *dst, const uint8_t *src, uint32_t dstStride, u dst += dstStride * 3; } } else { - WARN_LOG_REPORT_ONCE(convFromBGRA, G3D, "Unable to convert from format to BGRA: %d", (int)format); + WARN_LOG(G3D, "Unable to convert from format to BGRA: %d", (int)format); } } diff --git a/Common/Render/Text/draw_text_qt.cpp b/Common/Render/Text/draw_text_qt.cpp index 166aac3a47..ce0600cb81 100644 --- a/Common/Render/Text/draw_text_qt.cpp +++ b/Common/Render/Text/draw_text_qt.cpp @@ -10,6 +10,7 @@ #if defined(USING_QT_UI) +#include #include #include #include diff --git a/Common/Render/Text/draw_text_qt.h b/Common/Render/Text/draw_text_qt.h index 2ac661b4ad..47fb8ab48f 100644 --- a/Common/Render/Text/draw_text_qt.h +++ b/Common/Render/Text/draw_text_qt.h @@ -7,7 +7,7 @@ #if defined(USING_QT_UI) -#include +class QFont; class TextDrawerQt : public TextDrawer { public: diff --git a/macshaders.sh b/macshaders.sh deleted file mode 100644 index 19e8a352be..0000000000 --- a/macshaders.sh +++ /dev/null @@ -1,11 +0,0 @@ -# AWFUL way to make the shaders macosx compatible! - -cd assets/shaders -for i in *.vs *.fs -do - sed -i '' s/lowp\ //g $i - sed -i '' s/highp\ //g $i - sed -i '' s/mediump\ //g $i - sed -i '' s/#version\ 140//g $i -done -cd ../.. From 886a8b1ac6d24c69980eecf14f0ef628466e3edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 20:58:33 +0200 Subject: [PATCH 838/848] Remove Timer.cpp/h. Move various collections into Common/Data/Collections. --- CMakeLists.txt | 12 +- Common/Arm64Emitter.cpp | 2 +- Common/Common.vcxproj | 11 +- Common/Common.vcxproj.filters | 17 +- .../{ => Data/Collections}/FixedSizeQueue.h | 0 Common/{ => Data/Collections}/Hashmaps.h | 0 .../{ => Data/Collections}/ThreadSafeList.h | 0 Common/GPU/Vulkan/VulkanQueueRunner.h | 2 +- Common/LogManager.cpp | 4 +- Common/Math/math_util.h | 20 ++ Common/MathUtil.h | 30 --- Common/TimeUtil.cpp | 43 ++- Common/TimeUtil.h | 2 + Common/Timer.cpp | 252 ------------------ Common/Timer.h | 60 ----- Core/Core.vcxproj | 4 +- Core/Core.vcxproj.filters | 6 + Core/HLE/__sceAudio.cpp | 2 +- Core/HLE/sceAudio.cpp | 2 +- Core/HLE/sceGe.cpp | 2 +- Core/HW/StereoResampler.cpp | 2 +- {Common => Core}/ThreadPools.cpp | 0 {Common => Core}/ThreadPools.h | 0 GPU/Common/DrawEngineCommon.h | 2 +- GPU/Common/TextureScalerCommon.cpp | 2 +- GPU/Common/VertexDecoderCommon.h | 2 +- GPU/D3D11/DrawEngineD3D11.h | 2 +- GPU/D3D11/FramebufferManagerD3D11.cpp | 7 +- GPU/D3D11/TextureScalerD3D11.cpp | 2 +- GPU/Directx9/DrawEngineDX9.h | 2 +- GPU/Directx9/TextureScalerDX9.cpp | 2 +- GPU/GLES/DrawEngineGLES.h | 7 +- GPU/GLES/ShaderManagerGLES.h | 2 +- GPU/GLES/TextureScalerGLES.cpp | 2 +- GPU/Software/Rasterizer.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.h | 2 +- GPU/Vulkan/PipelineManagerVulkan.h | 2 +- GPU/Vulkan/ShaderManagerVulkan.h | 2 +- GPU/Vulkan/TextureCacheVulkan.h | 2 +- GPU/Vulkan/TextureScalerVulkan.cpp | 2 +- GPU/Vulkan/VulkanUtil.h | 2 +- UI/BackgroundAudio.cpp | 2 +- UWP/CommonUWP/CommonUWP.vcxproj | 34 ++- UWP/CommonUWP/CommonUWP.vcxproj.filters | 16 +- UWP/CoreUWP/CoreUWP.vcxproj | 2 + UWP/CoreUWP/CoreUWP.vcxproj.filters | 2 + Windows/XinputDevice.cpp | 14 +- android/jni/Android.mk | 3 +- libretro/Makefile.common | 5 +- 49 files changed, 152 insertions(+), 445 deletions(-) rename Common/{ => Data/Collections}/FixedSizeQueue.h (100%) rename Common/{ => Data/Collections}/Hashmaps.h (100%) rename Common/{ => Data/Collections}/ThreadSafeList.h (100%) delete mode 100644 Common/MathUtil.h delete mode 100644 Common/Timer.cpp delete mode 100644 Common/Timer.h rename {Common => Core}/ThreadPools.cpp (100%) rename {Common => Core}/ThreadPools.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a62d384318..ce647f7040 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -439,7 +439,10 @@ add_library(Common STATIC Common/Crypto/sha256.cpp Common/Crypto/sha256.h Common/Data/Collections/ConstMap.h + Common/Data/Collections/FixedSizeQueue.h + Common/Data/Collections/Hashmaps.h Common/Data/Collections/TinySet.h + Common/Data/Collections/ThreadSafeList.h Common/Data/Color/RGBAUtil.cpp Common/Data/Color/RGBAUtil.h Common/Data/Convert/SmallDataConvert.cpp @@ -611,10 +614,8 @@ add_library(Common STATIC Common/ConsoleListener.h Common/DbgNew.h Common/FakeEmitter.h - Common/FixedSizeQueue.h Common/ExceptionHandlerSetup.cpp Common/ExceptionHandlerSetup.h - Common/Hashmaps.h Common/Log.h Common/Log.cpp Common/LogManager.cpp @@ -633,11 +634,6 @@ add_library(Common STATIC Common/StringUtils.h Common/SysError.h Common/SysError.cpp - Common/ThreadPools.cpp - Common/ThreadPools.h - Common/ThreadSafeList.h - Common/Timer.cpp - Common/Timer.h Common/TimeUtil.cpp Common/TimeUtil.h ) @@ -1775,6 +1771,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/System.h Core/TextureReplacer.cpp Core/TextureReplacer.h + Core/ThreadPools.cpp + Core/ThreadPools.h Core/Util/AudioFormat.cpp Core/Util/AudioFormat.h Core/Util/AudioFormatNEON.cpp diff --git a/Common/Arm64Emitter.cpp b/Common/Arm64Emitter.cpp index 7578dff4f7..467dd6d8ee 100644 --- a/Common/Arm64Emitter.cpp +++ b/Common/Arm64Emitter.cpp @@ -13,7 +13,7 @@ #include #include "Common/Arm64Emitter.h" -#include "Common/MathUtil.h" +#include "Common/Math/math_util.h" #include "Common/CommonTypes.h" #include "Common/CommonWindows.h" #include "Common/CPUDetect.h" diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 7e5dc35f0a..0bb5e7ef50 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -384,6 +384,9 @@ + + + @@ -479,7 +482,6 @@ - true @@ -502,12 +504,10 @@ true - - @@ -519,14 +519,11 @@ - - - @@ -836,13 +833,11 @@ - - diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 10c28d065c..5cc1151375 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -7,18 +7,15 @@ - - - Crypto @@ -33,12 +30,10 @@ - - GL\GLInterface @@ -51,7 +46,6 @@ - @@ -372,6 +366,15 @@ Render\Text + + Data\Collections + + + Data\Collections + + + Data\Collections + @@ -381,12 +384,10 @@ - - Crypto diff --git a/Common/FixedSizeQueue.h b/Common/Data/Collections/FixedSizeQueue.h similarity index 100% rename from Common/FixedSizeQueue.h rename to Common/Data/Collections/FixedSizeQueue.h diff --git a/Common/Hashmaps.h b/Common/Data/Collections/Hashmaps.h similarity index 100% rename from Common/Hashmaps.h rename to Common/Data/Collections/Hashmaps.h diff --git a/Common/ThreadSafeList.h b/Common/Data/Collections/ThreadSafeList.h similarity index 100% rename from Common/ThreadSafeList.h rename to Common/Data/Collections/ThreadSafeList.h diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.h b/Common/GPU/Vulkan/VulkanQueueRunner.h index 6c8f12cdc3..ada7cc49e2 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.h +++ b/Common/GPU/Vulkan/VulkanQueueRunner.h @@ -2,7 +2,7 @@ #include -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "Common/GPU/Vulkan/VulkanContext.h" #include "Common/Data/Convert/SmallDataConvert.h" #include "Common/Data/Collections/TinySet.h" diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 1ecea857e8..d518df7a99 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -24,7 +24,7 @@ #include "Common/LogManager.h" #include "Common/ConsoleListener.h" -#include "Common/Timer.h" +#include "Common/TimeUtil.h" #include "Common/File/FileUtil.h" #include "Common/StringUtils.h" @@ -220,7 +220,7 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, const } std::lock_guard lk(log_lock_); - Common::Timer::GetTimeFormatted(message.timestamp); + GetTimeFormatted(message.timestamp); if (hleCurrentThreadName) { snprintf(message.header, sizeof(message.header), "%-12.12s %c[%s]: %s:%d", diff --git a/Common/Math/math_util.h b/Common/Math/math_util.h index 0cf1101321..0807d47003 100644 --- a/Common/Math/math_util.h +++ b/Common/Math/math_util.h @@ -62,6 +62,26 @@ inline T clamp_value(T val, T floor, T cap) { return val; } +#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) +#define ROUND_DOWN(x, a) ((x) & ~((a) - 1)) + +template +inline void Clamp(T* val, const T& min, const T& max) +{ + if (*val < min) + *val = min; + else if (*val > max) + *val = max; +} + +template +inline T Clamp(const T val, const T& min, const T& max) +{ + T ret = val; + Clamp(&ret, min, max); + return ret; +} + union FP32 { uint32_t u; float f; diff --git a/Common/MathUtil.h b/Common/MathUtil.h deleted file mode 100644 index d56d5c19e5..0000000000 --- a/Common/MathUtil.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -namespace MathUtil -{ - -#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) -#define ROUND_DOWN(x, a) ((x) & ~((a) - 1)) - -template -inline void Clamp(T* val, const T& min, const T& max) -{ - if (*val < min) - *val = min; - else if (*val > max) - *val = max; -} - -template -inline T Clamp(const T val, const T& min, const T& max) -{ - T ret = val; - Clamp(&ret, min, max); - return ret; -} - -} \ No newline at end of file diff --git a/Common/TimeUtil.cpp b/Common/TimeUtil.cpp index 106f761b74..2cb375c9a0 100644 --- a/Common/TimeUtil.cpp +++ b/Common/TimeUtil.cpp @@ -1,20 +1,23 @@ #include #include +#include + +#include "ppsspp_config.h" #include "Common/TimeUtil.h" -#ifdef _WIN32 -#include -#else -#include -#include -#endif - #ifdef HAVE_LIBNX #include #endif // HAVE_LIBNX -#include "Common/Log.h" +#ifdef _WIN32 +#include "CommonWindows.h" +#include +#include +#else +#include +#include +#endif static double curtime = 0; @@ -64,3 +67,27 @@ void sleep_ms(int ms) { usleep(ms * 1000); #endif } + +// Return the current time formatted as Minutes:Seconds:Milliseconds +// in the form 00:00:000. +void GetTimeFormatted(char formattedTime[13]) { + time_t sysTime; + struct tm * gmTime; + char tmp[13]; + + time(&sysTime); + gmTime = localtime(&sysTime); + + strftime(tmp, 6, "%M:%S", gmTime); + + // Now tack on the milliseconds +#ifdef _WIN32 + struct timeb tp; + (void)::ftime(&tp); + snprintf(formattedTime, 13, "%s:%03i", tmp, tp.millitm); +#else + struct timeval t; + (void)gettimeofday(&t, NULL); + snprintf(formattedTime, 13, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); +#endif +} diff --git a/Common/TimeUtil.h b/Common/TimeUtil.h index c19e98f5ad..8d7273c466 100644 --- a/Common/TimeUtil.h +++ b/Common/TimeUtil.h @@ -5,3 +5,5 @@ double time_now_d(); // Sleep. Does not necessarily have millisecond granularity, especially on Windows. void sleep_ms(int ms); + +void GetTimeFormatted(char formattedTime[13]); diff --git a/Common/Timer.cpp b/Common/Timer.cpp deleted file mode 100644 index 9c34ee151a..0000000000 --- a/Common/Timer.cpp +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include - -#include "ppsspp_config.h" - -#ifdef _WIN32 -#include "CommonWindows.h" -#include -#include -#else -#include -#endif - -#include "Timer.h" -#include "StringUtils.h" - -namespace Common -{ - -u32 Timer::GetTimeMs() -{ -#if defined(_WIN32) -#if PPSSPP_PLATFORM(UWP) - return (u32)GetTickCount64(); -#else - return timeGetTime(); -#endif -#else - // REALTIME is probably not a good idea for measuring updates. - struct timeval t; - (void)gettimeofday(&t, NULL); - return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); -#endif -} - -// -------------------------------------------- -// Initiate, Start, Stop, and Update the time -// -------------------------------------------- - -// Set initial values for the class -Timer::Timer() - : m_LastTime(0), m_StartTime(0), m_Running(false) -{ - Update(); - -#ifdef _WIN32 - QueryPerformanceFrequency((LARGE_INTEGER*)&m_frequency); -#endif -} - -// Write the starting time -void Timer::Start() -{ - m_StartTime = GetTimeMs(); - m_Running = true; -} - -// Stop the timer -void Timer::Stop() -{ - // Write the final time - m_LastTime = GetTimeMs(); - m_Running = false; -} - -// Update the last time variable -void Timer::Update() -{ - m_LastTime = GetTimeMs(); - //TODO(ector) - QPF -} - -// ------------------------------------- -// Get time difference and elapsed time -// ------------------------------------- - -// Get the number of milliseconds since the last Update() -u64 Timer::GetTimeDifference() const -{ - return GetTimeMs() - m_LastTime; -} - -// Add the time difference since the last Update() to the starting time. -// This is used to compensate for a paused game. -void Timer::AddTimeDifference() -{ - m_StartTime += GetTimeDifference(); -} - -// Wind back the starting time to a custom time -void Timer::WindBackStartingTime(u64 WindBack) -{ - m_StartTime += WindBack; -} - -// Get the time elapsed since the Start() -u64 Timer::GetTimeElapsed() const -{ - // If we have not started yet, return 1 (because then I don't - // have to change the FPS calculation in CoreRerecording.cpp . - if (m_StartTime == 0) return 1; - - // Return the final timer time if the timer is stopped - if (!m_Running) return (m_LastTime - m_StartTime); - - return (GetTimeMs() - m_StartTime); -} - -// Get the formatted time elapsed since the Start() -std::string Timer::GetTimeElapsedFormatted() const -{ - // If we have not started yet, return zero - if (m_StartTime == 0) - return "00:00:00:000"; - - // The number of milliseconds since the start. - // Use a different value if the timer is stopped. - u64 Milliseconds; - if (m_Running) - Milliseconds = GetTimeMs() - m_StartTime; - else - Milliseconds = m_LastTime - m_StartTime; - // Seconds - u32 Seconds = (u32)(Milliseconds / 1000); - // Minutes - u32 Minutes = Seconds / 60; - // Hours - u32 Hours = Minutes / 60; - - std::string TmpStr = StringFromFormat("%02d:%02d:%02d:%03d", - Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); - return TmpStr; -} - -// Get current time -void Timer::IncreaseResolution() -{ -#if defined(USING_WIN_UI) - timeBeginPeriod(1); -#endif -} - -void Timer::RestoreResolution() -{ -#if defined(USING_WIN_UI) - timeEndPeriod(1); -#endif -} - -// Get the number of seconds since January 1 1970 -u64 Timer::GetTimeSinceJan1970() -{ - time_t ltime; - time(<ime); - return((u64)ltime); -} - -u64 Timer::GetLocalTimeSinceJan1970() -{ - time_t sysTime, tzDiff, tzDST; - struct tm * gmTime; - - time(&sysTime); - - // Account for DST where needed - gmTime = localtime(&sysTime); - if(gmTime->tm_isdst == 1) - tzDST = 3600; - else - tzDST = 0; - - // Lazy way to get local time in sec - gmTime = gmtime(&sysTime); - tzDiff = sysTime - mktime(gmTime); - - return (u64)(sysTime + tzDiff + tzDST); -} - -// Return the current time formatted as Minutes:Seconds:Milliseconds -// in the form 00:00:000. -void Timer::GetTimeFormatted(char formattedTime[13]) -{ - time_t sysTime; - struct tm * gmTime; - char tmp[13]; - - time(&sysTime); - gmTime = localtime(&sysTime); - - strftime(tmp, 6, "%M:%S", gmTime); - - // Now tack on the milliseconds -#ifdef _WIN32 - struct timeb tp; - (void)::ftime(&tp); - snprintf(formattedTime, 13, "%s:%03i", tmp, tp.millitm); -#else - struct timeval t; - (void)gettimeofday(&t, NULL); - snprintf(formattedTime, 13, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); -#endif -} - -// Returns a timestamp with decimals for precise time comparisons -// ---------------- -double Timer::GetDoubleTime() -{ -#ifdef _WIN32 - struct timeb tp; - (void)::ftime(&tp); -#else - struct timeval t; - (void)gettimeofday(&t, NULL); -#endif - // Get continuous timestamp - u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); - - // Remove a few years. We only really want enough seconds to make - // sure that we are detecting actual actions, perhaps 60 seconds is - // enough really, but I leave a year of seconds anyway, in case the - // user's clock is incorrect or something like that. - TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); - - // Make a smaller integer that fits in the double - u32 Seconds = (u32)TmpSeconds; -#ifdef _WIN32 - double ms = tp.millitm / 1000.0 / 1000.0; -#else - double ms = t.tv_usec / 1000000.0; -#endif - double TmpTime = Seconds + ms; - - return TmpTime; -} - -} // Namespace Common diff --git a/Common/Timer.h b/Common/Timer.h deleted file mode 100644 index 8d775b8423..0000000000 --- a/Common/Timer.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0 or later versions. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#pragma once - -#include "Common.h" -#include - -namespace Common -{ -class Timer -{ -public: - Timer(); - - void Start(); - void Stop(); - void Update(); - - // The time difference is always returned in milliseconds, regardless of alternative internal representation - u64 GetTimeDifference() const; - void AddTimeDifference(); - void WindBackStartingTime(u64 WindBack); - - static void IncreaseResolution(); - static void RestoreResolution(); - static u64 GetTimeSinceJan1970(); - static u64 GetLocalTimeSinceJan1970(); - static double GetDoubleTime(); - - static void GetTimeFormatted(char formattedTime[13]); - std::string GetTimeElapsedFormatted() const; - u64 GetTimeElapsed() const; - - static u32 GetTimeMs(); - -private: - u64 m_LastTime; - u64 m_StartTime; -#ifdef _WIN32 - u64 m_frequency; -#endif - bool m_Running; -}; - -} // Namespace Common diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index e23beab505..e91c514383 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -898,6 +898,7 @@ + true @@ -1245,6 +1246,7 @@ + true @@ -1298,4 +1300,4 @@ - + \ No newline at end of file diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index f59875b48c..76fac1fe88 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -962,6 +962,9 @@ Core + + Core + @@ -1643,6 +1646,9 @@ Core + + Core + diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index 57ef29281d..1f722d11d1 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -21,7 +21,7 @@ #include "Common/CommonTypes.h" #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" -#include "Common/FixedSizeQueue.h" +#include "Common/Data/Collections/FixedSizeQueue.h" #ifdef _M_SSE #include diff --git a/Core/HLE/sceAudio.cpp b/Core/HLE/sceAudio.cpp index 76f97e9a20..aa247385d4 100644 --- a/Core/HLE/sceAudio.cpp +++ b/Core/HLE/sceAudio.cpp @@ -17,7 +17,7 @@ #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" -#include "Common/FixedSizeQueue.h" +#include "Common/Data/Collections/FixedSizeQueue.h" #include "Core/MIPS/MIPS.h" #include "Core/Host.h" #include "Core/CoreTiming.h" diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 0cdae03b8a..8c27ed16c6 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -23,7 +23,7 @@ #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeList.h" #include "Common/Serialize/SerializeMap.h" -#include "Common/ThreadSafeList.h" +#include "Common/Data/Collections/ThreadSafeList.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/MIPS/MIPS.h" diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index 898f21b48c..8e7f22833d 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -36,7 +36,7 @@ #include #include "Common/System/System.h" -#include "Common/MathUtil.h" +#include "Common/Math/math_util.h" #include "Common/Serialize/Serializer.h" #include "Common/Log.h" #include "Common/TimeUtil.h" diff --git a/Common/ThreadPools.cpp b/Core/ThreadPools.cpp similarity index 100% rename from Common/ThreadPools.cpp rename to Core/ThreadPools.cpp diff --git a/Common/ThreadPools.h b/Core/ThreadPools.h similarity index 100% rename from Common/ThreadPools.h rename to Core/ThreadPools.h diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index bf2f3968e4..f53b96f487 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -20,7 +20,7 @@ #include #include "Common/CommonTypes.h" -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "GPU/GPUState.h" #include "GPU/Common/GPUDebugInterface.h" diff --git a/GPU/Common/TextureScalerCommon.cpp b/GPU/Common/TextureScalerCommon.cpp index 3214b42306..64a3d7dd96 100644 --- a/GPU/Common/TextureScalerCommon.cpp +++ b/GPU/Common/TextureScalerCommon.cpp @@ -26,7 +26,7 @@ #include "Common/Common.h" #include "Common/Log.h" #include "Common/CommonFuncs.h" -#include "Common/ThreadPools.h" +#include "Core/ThreadPools.h" #include "Common/CPUDetect.h" #include "ext/xbrz/xbrz.h" diff --git a/GPU/Common/VertexDecoderCommon.h b/GPU/Common/VertexDecoderCommon.h index 0d451465b8..6013b1a356 100644 --- a/GPU/Common/VertexDecoderCommon.h +++ b/GPU/Common/VertexDecoderCommon.h @@ -22,7 +22,7 @@ #include "ppsspp_config.h" #include "Common/Common.h" -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "Common/Log.h" #include "Core/Reporting.h" #include "GPU/ge_constants.h" diff --git a/GPU/D3D11/DrawEngineD3D11.h b/GPU/D3D11/DrawEngineD3D11.h index 88d27c6bc1..fbc94f2d7a 100644 --- a/GPU/D3D11/DrawEngineD3D11.h +++ b/GPU/D3D11/DrawEngineD3D11.h @@ -21,7 +21,7 @@ #include #include -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "GPU/GPUState.h" #include "GPU/Common/GPUDebugInterface.h" #include "GPU/Common/IndexGenerator.h" diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 792f11f79e..437fe4922c 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -19,13 +19,13 @@ #include #include +#include "Common/Common.h" #include "Common/System/Display.h" #include "Common/Math/lin/matrix4x4.h" +#include "Common/Math/math_util.h" #include "Common/GPU/thin3d.h" - -#include "Common/Common.h" #include "Common/ColorConv.h" -#include "Common/MathUtil.h" + #include "Core/MemMap.h" #include "Core/Config.h" #include "Core/ConfigValues.h" @@ -34,7 +34,6 @@ #include "GPU/ge_constants.h" #include "GPU/GPUState.h" #include "GPU/Debugger/Stepping.h" - #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/ShaderTranslation.h" diff --git a/GPU/D3D11/TextureScalerD3D11.cpp b/GPU/D3D11/TextureScalerD3D11.cpp index 32c06c45ee..17dcfa3c25 100644 --- a/GPU/D3D11/TextureScalerD3D11.cpp +++ b/GPU/D3D11/TextureScalerD3D11.cpp @@ -19,7 +19,7 @@ #include #include "Common/ColorConv.h" -#include "Common/ThreadPools.h" +#include "Core/ThreadPools.h" #include "GPU/Common/TextureScalerCommon.h" #include "GPU/D3D11/TextureScalerD3D11.h" #include "GPU/D3D11/GPU_D3D11.h" diff --git a/GPU/Directx9/DrawEngineDX9.h b/GPU/Directx9/DrawEngineDX9.h index 22cb6a7a4e..3ddf99b79b 100644 --- a/GPU/Directx9/DrawEngineDX9.h +++ b/GPU/Directx9/DrawEngineDX9.h @@ -19,7 +19,7 @@ #include -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "GPU/GPUState.h" #include "GPU/Common/GPUDebugInterface.h" #include "GPU/Common/IndexGenerator.h" diff --git a/GPU/Directx9/TextureScalerDX9.cpp b/GPU/Directx9/TextureScalerDX9.cpp index bbf732a08d..4508358d7e 100644 --- a/GPU/Directx9/TextureScalerDX9.cpp +++ b/GPU/Directx9/TextureScalerDX9.cpp @@ -19,7 +19,7 @@ #include "Common/Common.h" #include "Common/ColorConv.h" -#include "Common/ThreadPools.h" +#include "Core/ThreadPools.h" #include "GPU/Common/TextureScalerCommon.h" #include "GPU/Directx9/TextureScalerDX9.h" #include "GPU/Directx9/GPU_DX9.h" diff --git a/GPU/GLES/DrawEngineGLES.h b/GPU/GLES/DrawEngineGLES.h index 6c96072185..9291543478 100644 --- a/GPU/GLES/DrawEngineGLES.h +++ b/GPU/GLES/DrawEngineGLES.h @@ -17,8 +17,9 @@ #pragma once -#include -#include +#include "Common/Data/Collections/Hashmaps.h" +#include "Common/GPU/OpenGL/GLCommon.h" +#include "Common/GPU/OpenGL/GLRenderManager.h" #include "GPU/GPUState.h" #include "GPU/Common/GPUDebugInterface.h" @@ -27,8 +28,6 @@ #include "GPU/Common/DrawEngineCommon.h" #include "GPU/Common/GPUStateUtils.h" #include "GPU/GLES/FragmentShaderGeneratorGLES.h" -#include "Common/GPU/OpenGL/GLCommon.h" -#include "Common/GPU/OpenGL/GLRenderManager.h" class LinkedShader; class ShaderManagerGLES; diff --git a/GPU/GLES/ShaderManagerGLES.h b/GPU/GLES/ShaderManagerGLES.h index a084edff1c..613fab8eaf 100644 --- a/GPU/GLES/ShaderManagerGLES.h +++ b/GPU/GLES/ShaderManagerGLES.h @@ -19,7 +19,7 @@ #include -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "Common/GPU/OpenGL/GLRenderManager.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/ShaderId.h" diff --git a/GPU/GLES/TextureScalerGLES.cpp b/GPU/GLES/TextureScalerGLES.cpp index d268fe92e1..2a22d8b178 100644 --- a/GPU/GLES/TextureScalerGLES.cpp +++ b/GPU/GLES/TextureScalerGLES.cpp @@ -22,7 +22,7 @@ #include "GPU/GLES/TextureScalerGLES.h" #include "Common/ColorConv.h" #include "Common/Log.h" -#include "Common/ThreadPools.h" +#include "Core/ThreadPools.h" #include "Common/GPU/DataFormat.h" int TextureScalerGLES::BytesPerPixel(u32 format) { diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 7bfc9b190f..feaeca1e89 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -20,7 +20,7 @@ #include "Common/Profiler/Profiler.h" -#include "Common/ThreadPools.h" +#include "Core/ThreadPools.h" #include "Common/ColorConv.h" #include "Core/Config.h" #include "Core/MemMap.h" diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 4b807315d0..3f46a62186 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -31,7 +31,7 @@ // The format of the various uniform buffers may vary though - vertex shaders that don't skin // won't get any bone data, etc. -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "GPU/Vulkan/VulkanUtil.h" diff --git a/GPU/Vulkan/PipelineManagerVulkan.h b/GPU/Vulkan/PipelineManagerVulkan.h index 0cdb4a855a..d7d47fd0ef 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.h +++ b/GPU/Vulkan/PipelineManagerVulkan.h @@ -18,7 +18,7 @@ #pragma once #include -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "GPU/Common/VertexDecoderCommon.h" #include "GPU/Common/ShaderId.h" diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index 016de933c6..92a52594ff 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -20,7 +20,7 @@ #include #include -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "Common/GPU/Vulkan/VulkanMemory.h" #include "GPU/Common/ShaderCommon.h" #include "GPU/Common/ShaderId.h" diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index 7c6c8f8946..a61ba47d20 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -19,7 +19,7 @@ #include -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" #include "Common/GPU/Vulkan/VulkanContext.h" diff --git a/GPU/Vulkan/TextureScalerVulkan.cpp b/GPU/Vulkan/TextureScalerVulkan.cpp index 28e6d4bc60..66720c0f36 100644 --- a/GPU/Vulkan/TextureScalerVulkan.cpp +++ b/GPU/Vulkan/TextureScalerVulkan.cpp @@ -21,7 +21,7 @@ #include "Common/GPU/Vulkan/VulkanContext.h" #include "Common/ColorConv.h" #include "Common/Log.h" -#include "Common/ThreadPools.h" +#include "Core/ThreadPools.h" #include "GPU/Common/TextureScalerCommon.h" #include "GPU/Vulkan/TextureScalerVulkan.h" diff --git a/GPU/Vulkan/VulkanUtil.h b/GPU/Vulkan/VulkanUtil.h index 752ea8d754..8e837df544 100644 --- a/GPU/Vulkan/VulkanUtil.h +++ b/GPU/Vulkan/VulkanUtil.h @@ -20,7 +20,7 @@ #include #include -#include "Common/Hashmaps.h" +#include "Common/Data/Collections/Hashmaps.h" #include "Common/GPU/Vulkan/VulkanContext.h" #include "Common/GPU/Vulkan/VulkanLoader.h" #include "Common/GPU/Vulkan/VulkanImage.h" diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 272fb706dc..ba03df8ca2 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -9,7 +9,7 @@ #include "Common/Log.h" #include "Common/Serialize/SerializeFuncs.h" #include "Common/TimeUtil.h" -#include "Common/FixedSizeQueue.h" +#include "Common/Data/Collections/FixedSizeQueue.h" #include "Core/HW/SimpleAudioDec.h" #include "Core/HLE/__sceAudio.h" #include "GameInfoCache.h" diff --git a/UWP/CommonUWP/CommonUWP.vcxproj b/UWP/CommonUWP/CommonUWP.vcxproj index f1ad520e49..e8d56b3ab6 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj +++ b/UWP/CommonUWP/CommonUWP.vcxproj @@ -204,7 +204,7 @@ true pch.h ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotUsing @@ -218,7 +218,7 @@ false true ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h NotUsing @@ -233,7 +233,7 @@ false true ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h NotUsing @@ -249,7 +249,7 @@ true pch.h ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) NotUsing @@ -264,7 +264,7 @@ true pch.h ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) NotUsing @@ -278,7 +278,7 @@ false true ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h NotUsing @@ -293,7 +293,7 @@ false true ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h NotUsing @@ -308,7 +308,7 @@ false true ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h NotUsing @@ -323,7 +323,7 @@ false true ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) pch.h NotUsing @@ -339,7 +339,7 @@ true pch.h ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) NotUsing @@ -353,7 +353,7 @@ false true ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h NotUsing @@ -368,7 +368,7 @@ false true ../..;../../ext/native;../../ext/snappy;../../ext/glslang;../../ext/zlib;../../ext/libpng17;$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories) - NOMINMAX;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NOMINMAX;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions) pch.h NotUsing @@ -387,6 +387,9 @@ + + + @@ -464,11 +467,9 @@ - - @@ -479,14 +480,11 @@ - - - @@ -586,13 +584,11 @@ - - diff --git a/UWP/CommonUWP/CommonUWP.vcxproj.filters b/UWP/CommonUWP/CommonUWP.vcxproj.filters index 071580a871..7576f5735f 100644 --- a/UWP/CommonUWP/CommonUWP.vcxproj.filters +++ b/UWP/CommonUWP/CommonUWP.vcxproj.filters @@ -109,9 +109,7 @@ - - @@ -386,11 +384,9 @@ - - @@ -398,10 +394,7 @@ - - - @@ -660,6 +653,15 @@ Render\Text + + Data\Collections + + + Data\Collections + + + Data\Collections + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index 1ee0d6c4b8..2e46086a0b 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -568,6 +568,7 @@ + @@ -820,6 +821,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index 11ff8c7a08..ea66a38598 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -911,6 +911,7 @@ Ext\libzip + @@ -1542,6 +1543,7 @@ Ext\libzip + diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 4d12aa827c..f3f0ef32ce 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -7,15 +7,15 @@ #include "Core/Config.h" #include "Common/CommonWindows.h" #include "Common/Log.h" +#include "Common/TimeUtil.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "XinputDevice.h" #include "Core/Core.h" #include "Core/KeyMap.h" #include "Core/HLE/sceCtrl.h" -#include "Common/Timer.h" -static int newVibrationTime = 0; +static double newVibrationTime = 0.0; // Utilities to dynamically load XInput. Adapted from SDL. @@ -24,8 +24,8 @@ static int newVibrationTime = 0; typedef DWORD (WINAPI *XInputGetState_t) (DWORD dwUserIndex, XINPUT_STATE* pState); typedef DWORD (WINAPI *XInputSetState_t) (DWORD dwUserIndex, XINPUT_VIBRATION* pVibration); -static XInputGetState_t PPSSPP_XInputGetState = NULL; -static XInputSetState_t PPSSPP_XInputSetState = NULL; +static XInputGetState_t PPSSPP_XInputGetState = nullptr; +static XInputSetState_t PPSSPP_XInputSetState = nullptr; static DWORD PPSSPP_XInputVersion = 0; static HMODULE s_pXInputDLL = 0; static int s_XInputDLLRefCount = 0; @@ -364,11 +364,11 @@ void XinputDevice::ApplyButtons(int pad, const XINPUT_STATE &state) { void XinputDevice::ApplyVibration(int pad, XINPUT_VIBRATION &vibration) { if (PSP_IsInited()) { - newVibrationTime = Common::Timer::GetTimeMs() >> 6; + newVibrationTime = time_now_d(); // We have to run PPSSPP_XInputSetState at time intervals // since it bugs otherwise with very high unthrottle speeds // and freezes at constant vibration or no vibration at all. - if (abs(newVibrationTime - prevVibrationTime) >= 1) { + if (newVibrationTime - prevVibrationTime >= 1.0 / 64.0) { if (GetUIState() == UISTATE_INGAME) { vibration.wLeftMotorSpeed = sceCtrlGetLeftVibration(); // use any value between 0-65535 here vibration.wRightMotorSpeed = sceCtrlGetRightVibration(); // use any value between 0-65535 here @@ -377,7 +377,7 @@ void XinputDevice::ApplyVibration(int pad, XINPUT_VIBRATION &vibration) { vibration.wRightMotorSpeed = 0; } - if ((prevVibration[pad].wLeftMotorSpeed != vibration.wLeftMotorSpeed || prevVibration[pad].wRightMotorSpeed != vibration.wRightMotorSpeed)) { + if (prevVibration[pad].wLeftMotorSpeed != vibration.wLeftMotorSpeed || prevVibration[pad].wRightMotorSpeed != vibration.wRightMotorSpeed) { PPSSPP_XInputSetState(pad, &vibration); prevVibration[pad] = vibration; } diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 8538ce1f5a..5772dbc805 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -300,8 +300,6 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Common/MemoryUtil.cpp \ $(SRC)/Common/StringUtils.cpp \ $(SRC)/Common/SysError.cpp \ - $(SRC)/Common/ThreadPools.cpp \ - $(SRC)/Common/Timer.cpp \ $(SRC)/Common/TimeUtil.cpp \ $(SRC)/GPU/Math3D.cpp \ $(SRC)/GPU/GPU.cpp \ @@ -395,6 +393,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/Screenshot.cpp \ $(SRC)/Core/System.cpp \ $(SRC)/Core/TextureReplacer.cpp \ + $(SRC)/Core/ThreadPools.cpp \ $(SRC)/Core/WebServer.cpp \ $(SRC)/Core/Debugger/Breakpoints.cpp \ $(SRC)/Core/Debugger/DisassemblyManager.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 6f8ffebe6c..010b7ee46a 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -221,9 +221,7 @@ SOURCES_CXX += \ $(COMMONDIR)/MemoryUtil.cpp \ $(COMMONDIR)/SysError.cpp \ $(COMMONDIR)/StringUtils.cpp \ - $(COMMONDIR)/Timer.cpp \ - $(COMMONDIR)/TimeUtil.cpp \ - $(COMMONDIR)/ThreadPools.cpp + $(COMMONDIR)/TimeUtil.cpp SOURCES_CXX += \ @@ -501,6 +499,7 @@ SOURCES_CXX += \ $(COREDIR)/SaveState.cpp \ $(COREDIR)/Screenshot.cpp \ $(COREDIR)/System.cpp \ + $(COREDIR)/ThreadPools.cpp \ $(COREDIR)/Util/BlockAllocator.cpp \ $(COREDIR)/Util/PPGeDraw.cpp \ $(COREDIR)/Util/AudioFormat.cpp \ From f3a9d040da66f9bf583e3183998cb3a8525596bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 21:04:50 +0200 Subject: [PATCH 839/848] Cap the global thread pool at 16 threads. --- Core/Config.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 0efc72f014..95daf8a869 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -396,7 +396,9 @@ std::string CreateRandMAC() { } static int DefaultNumWorkers() { - return cpu_info.num_cores; + // Let's cap the global thread pool at 16 threads. Nothing we do really should have much + // use for more... + return std::min(16, cpu_info.num_cores); } static int DefaultCpuCore() { From 93e327ab781d60a6a02f6af7336888de3e1baf53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 21:34:22 +0200 Subject: [PATCH 840/848] Vulkan: Automatically generate mipmaps for replacement textures. --- GPU/Vulkan/TextureCacheVulkan.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 43ff63089b..db328b4349 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -710,7 +710,10 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { // Adjust maxLevel to actually present levels.. bool badMipSizes = false; + + // maxLevel here is the max level to upload. Not the count. int maxLevel = entry->maxLevel; + for (int i = 0; i <= maxLevel; i++) { // If encountering levels pointing to nothing, adjust max level. u32 levelTexaddr = gstate.getTextureAddress(i); @@ -740,6 +743,10 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { maxLevel = 0; } + // We generate missing mipmaps from maxLevel+1 up to this level. maxLevel can get overwritten below + // such as when using replacement textures - but let's keep the same amount of levels. + int maxLevelToGenerate = maxLevel; + // If GLES3 is available, we can preallocate the storage, which makes texture loading more efficient. VkFormat dstFmt = GetDestFormat(GETextureFormat(entry->format), gstate.getClutPaletteFormat()); @@ -824,8 +831,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { } VkImageLayout imageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - // If we want to use the GE debugger, we should add VK_IMAGE_USAGE_TRANSFER_SRC_BIT too... + VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; // Compute experiment if (actualFmt == VULKAN_8888_FORMAT && scaleFactor > 1 && hardwareScaling) { @@ -845,7 +851,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { snprintf(texName, sizeof(texName), "texture_%08x_%s", entry->addr, GeTextureFormatToString((GETextureFormat)entry->format)); image->SetTag(texName); - bool allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevel + 1, actualFmt, imageLayout, usage, mapping); + bool allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevelToGenerate + 1, actualFmt, imageLayout, usage, mapping); if (!allocSuccess && !lowMemoryMode_) { WARN_LOG_REPORT(G3D, "Texture cache ran out of GPU memory; switching to low memory mode"); lowMemoryMode_ = true; @@ -864,7 +870,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { scaleFactor = 1; actualFmt = dstFmt; - 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); + allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevelToGenerate + 1, actualFmt, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, mapping); } if (!allocSuccess) { @@ -987,6 +993,11 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { } } + // Generate any additional mipmap levels. + for (int level = maxLevel + 1; level <= maxLevelToGenerate; level++) { + entry->vkTex->GenerateMip(cmdInit, level); + } + if (maxLevel == 0) { entry->status |= TexCacheEntry::STATUS_BAD_MIPS; } else { From 868901252f2fea29e2318694e8a8bc3fc3c131e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 22:36:19 +0200 Subject: [PATCH 841/848] Delete useless Qt-specific path in TextureReplacer --- Core/TextureReplacer.cpp | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 98c6102280..664e5bd19a 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -600,34 +600,6 @@ void ReplacedTexture::Load(int level, void *out, int rowPitch) { const ReplacedTextureLevel &info = levels_[level]; -#ifdef USING_QT_UI - QImage image(info.file.c_str(), "PNG"); - if (image.isNull()) { - ERROR_LOG(G3D, "Could not load texture replacement info: %s", info.file.c_str()); - return; - } - - image = image.convertToFormat(QImage::Format_ARGB32); - bool alphaFull = true; - for (int y = 0; y < image.height(); ++y) { - const QRgb *src = (const QRgb *)image.constScanLine(y); - uint8_t *outLine = (uint8_t *)out + y * rowPitch; - for (int x = 0; x < image.width(); ++x) { - outLine[x * 4 + 0] = qRed(src[x]); - outLine[x * 4 + 1] = qGreen(src[x]); - outLine[x * 4 + 2] = qBlue(src[x]); - outLine[x * 4 + 3] = qAlpha(src[x]); - // We're already scanning each pixel... - if (qAlpha(src[x]) != 255) { - alphaFull = false; - } - } - } - - if (level == 0 || !alphaFull) { - alphaStatus_ = alphaFull ? ReplacedTextureAlpha::FULL : ReplacedTextureAlpha::UNKNOWN; - } -#else png_image png = {}; png.version = PNG_IMAGE_VERSION; @@ -662,7 +634,6 @@ void ReplacedTexture::Load(int level, void *out, int rowPitch) { fclose(fp); png_image_free(&png); -#endif } bool TextureReplacer::GenerateIni(const std::string &gameID, std::string *generatedFilename) { From f5d674e3c7a8c178478472de52374548cd553f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 22:54:50 +0200 Subject: [PATCH 842/848] Add some recent contributors to the credits list. @ANR2ME @adenovan @iota97 --- UI/MiscScreens.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 41c5fd1f46..16ad329f64 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -715,6 +715,9 @@ void CreditsScreen::render() { "xebra", "LunaMoo", "zminhquanz", + "ANR2ME", + "adenovan", + "iota97", "", cr->T("specialthanks", "Special thanks to:"), specialthanksMaxim.c_str(), From ed3b99d921e10f6a500360865a5e2469d9412525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 23:05:25 +0200 Subject: [PATCH 843/848] Fix libretro makefile build --- libretro/Makefile.common | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 010b7ee46a..950b6a864a 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -169,7 +169,6 @@ SOURCES_CXX += \ $(COMMONDIR)/GPU/OpenGL/thin3d_gl.cpp \ $(COMMONDIR)/GPU/OpenGL/GLDebugLog.cpp \ $(COMMONDIR)/GPU/OpenGL/GLSLProgram.cpp \ - $(COMMONDIR)/GPU/OpenGL/gl3stub.c \ $(COMMONDIR)/GPU/OpenGL/GLFeatures.cpp \ $(COMMONDIR)/GPU/OpenGL/GLRenderManager.cpp \ $(COMMONDIR)/GPU/OpenGL/GLQueueRunner.cpp \ @@ -223,6 +222,8 @@ SOURCES_CXX += \ $(COMMONDIR)/StringUtils.cpp \ $(COMMONDIR)/TimeUtil.cpp +SOURCES_C +=\ + $(COMMONDIR)/GPU/OpenGL/gl3stub.c SOURCES_CXX += \ $(GPUCOMMONDIR)/VertexDecoderCommon.cpp \ @@ -345,7 +346,6 @@ SOURCES_CXX += \ $(COREDIR)/Config.cpp \ $(COREDIR)/TextureReplacer.cpp \ $(COREDIR)/Core.cpp \ - $(COREDIR)/KeyMap.cpp \ $(COREDIR)/WaveFile.cpp \ $(COREDIR)/KeyMap.cpp \ $(COREDIR)/FileLoaders/HTTPFileLoader.cpp \ @@ -689,11 +689,13 @@ SOURCES_CXX += \ $(LIBRETRODIR)/LibretroD3D11Context.cpp SOURCES_CXX += \ - $(COMMONDIR)/GPU/D3D9/thin3d_d3d9.cpp \ - $(COMMONDIR)/GPU/D3D11/thin3d_d3d11.cpp \ - $(COMMONDIR)/GPU/D3D11/D3D11Loader.cpp \ - $(COMMONDIR)/GPU/D3D9/D3DCompilerLoader.cpp - + $(COMMONDIR)/GPU/D3D9/D3D9ShaderCompiler.cpp \ + $(COMMONDIR)/GPU/D3D9/D3D9StateCache.cpp \ + $(COMMONDIR)/GPU/D3D9/D3DCompilerLoader.cpp \ + $(COMMONDIR)/GPU/D3D9/thin3d_d3d9.cpp \ + $(COMMONDIR)/GPU/D3D11/D3D11Loader.cpp \ + $(COMMONDIR)/GPU/D3D11/thin3d_d3d11.cpp + INCFLAGS += -I$(CORE_DIR)/dx9sdk/Include -I$(CORE_DIR)/dx9sdk/Include/DX11 endif From 92e6a91ae7316ff6992b084793a0682a378e2a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2020 20:26:04 +0200 Subject: [PATCH 844/848] Add compat.ini setting to work around memstick size math problem in Harry Potter - Goblet of Fire See issue #13266 --- Core/Compatibility.cpp | 1 + Core/Compatibility.h | 1 + Core/HW/MemoryStick.cpp | 44 +++++++++++++++++++++++++++++++---------- Core/HW/MemoryStick.h | 17 ++++++++++++++++ assets/compat.ini | 5 +++++ 5 files changed, 58 insertions(+), 10 deletions(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index bd7c044c8b..f2738b48ad 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -70,6 +70,7 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "MoreAccurateVMMUL", &flags_.MoreAccurateVMMUL); CheckSetting(iniFile, gameID, "ForceSoftwareRenderer", &flags_.ForceSoftwareRenderer); CheckSetting(iniFile, gameID, "DarkStalkersPresentHack", &flags_.DarkStalkersPresentHack); + CheckSetting(iniFile, gameID, "ReportSmallMemstick", &flags_.ReportSmallMemstick); } 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 460776a90a..c44c64d673 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -68,6 +68,7 @@ struct CompatFlags { bool MoreAccurateVMMUL; bool ForceSoftwareRenderer; bool DarkStalkersPresentHack; + bool ReportSmallMemstick; }; class IniFile; diff --git a/Core/HW/MemoryStick.cpp b/Core/HW/MemoryStick.cpp index f2acf2991b..f0d9a38708 100644 --- a/Core/HW/MemoryStick.cpp +++ b/Core/HW/MemoryStick.cpp @@ -1,6 +1,24 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + #include "Common/Serialize/Serializer.h" #include "Common/Serialize/SerializeFuncs.h" #include "Core/CoreTiming.h" +#include "Core/Compatibility.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/HW/MemoryStick.h" #include "Core/System.h" @@ -8,26 +26,31 @@ // MS and FatMS states. static MemStickState memStickState; static MemStickFatState memStickFatState; -static u64 memStickSize; static bool memStickNeedsAssign = false; static u64 memStickInsertedAt = 0; +const u64 normalMemstickSize = 9ULL * 1024 * 1024 * 1024; +const u64 smallMemstickSize = 1ULL * 1024 * 1024 * 1024; + void MemoryStick_DoState(PointerWrap &p) { - auto s = p.Section("MemoryStick", 1, 3); + auto s = p.Section("MemoryStick", 1, 4); if (!s) return; Do(p, memStickState); Do(p, memStickFatState); - if (s >= 2) + if (s >= 4) { + // Do nothing. + } else if (s >= 2) { + // Really no point in storing the memstick size. + u64 memStickSize = normalMemstickSize; Do(p, memStickSize); - else - memStickSize = 1ULL * 1024 * 1024 * 1024; + } + if (s >= 3) { Do(p, memStickNeedsAssign); Do(p, memStickInsertedAt); } - } MemStickState MemoryStick_State() { @@ -49,6 +72,11 @@ u64 MemoryStick_SectorSize() { u64 MemoryStick_FreeSpace() { u64 freeSpace = pspFileSystem.FreeSpace("ms0:/"); + + // Cap the memory stick size to avoid math errors when old games get sizes that were + // hard to imagine back then. + // We have a compat setting to make it even smaller for Harry Potter : Goblet of Fire, see #13266. + const u64 memStickSize = PSP_CoreParameter().compat.flags().ReportSmallMemstick ? smallMemstickSize : normalMemstickSize; if (freeSpace < memStickSize) return freeSpace; return memStickSize; @@ -84,9 +112,5 @@ void MemoryStick_Init() { memStickFatState = PSP_FAT_MEMORYSTICK_STATE_UNASSIGNED; } - // Harry Potter and the Goblet of Fire has a bug where it can't handle certain amounts - // of free space due to incorrect 32-bit math. - // We use 9GB here, which does not trigger the bug, as a cap for the max free space. - memStickSize = 9ULL * 1024 * 1024 * 1024; // 9GB memStickNeedsAssign = false; } diff --git a/Core/HW/MemoryStick.h b/Core/HW/MemoryStick.h index 01b526fa98..f8bd295aba 100644 --- a/Core/HW/MemoryStick.h +++ b/Core/HW/MemoryStick.h @@ -1,3 +1,20 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + #pragma once #include "Common/CommonTypes.h" diff --git a/assets/compat.ini b/assets/compat.ini index 92fdd66323..7185f02589 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -767,3 +767,8 @@ ULJM05005 = true ULES00016 = true ULUS10005 = true ULJM05005 = true + +[ReportSmallMemStick] +# Harry Potter and the Goblet of Fire - issue #13266 +ULUS10032 = true +ULES00210 = true From 092e3e40eef277809fdf6dc229713fa7d5aeb841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 6 Oct 2020 00:13:05 +0200 Subject: [PATCH 845/848] Also report a smaller memstick for Street Fighter Alpha 3 MAX (see #10462) --- assets/compat.ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 7185f02589..6fd290455b 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -772,3 +772,10 @@ ULJM05005 = true # Harry Potter and the Goblet of Fire - issue #13266 ULUS10032 = true ULES00210 = true +# Street Fighter Alpha 3 MAX - issue #10462 +ULJM05082 = true +ULUS10062 = true +ULES00235 = true +ULJM05225 = true +CPCS01043 = true +ULUS10062 = true From d798e23871997c7262e6d4b85d8cf1f73e1c630c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 6 Oct 2020 00:16:23 +0200 Subject: [PATCH 846/848] Buildfix - remove more Qt-specific code in TextureReplacer --- Core/TextureReplacer.cpp | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/Core/TextureReplacer.cpp b/Core/TextureReplacer.cpp index 664e5bd19a..3b9aeb99e4 100644 --- a/Core/TextureReplacer.cpp +++ b/Core/TextureReplacer.cpp @@ -15,16 +15,13 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#ifdef USING_QT_UI -#include -#else #include -#endif #include -#include "Common/Data/Text/I18n.h" #include "ext/xxhash.h" + +#include "Common/Data/Text/I18n.h" #include "Common/Data/Format/IniFile.h" #include "Common/Data/Text/Parsers.h" #include "Common/ColorConv.h" @@ -333,16 +330,6 @@ void TextureReplacer::PopulateReplacement(ReplacedTexture *result, u64 cachekey, level.fmt = ReplacedTextureFormat::F_8888; level.file = filename; -#ifdef USING_QT_UI - QImage image(filename.c_str(), "PNG"); - if (image.isNull()) { - ERROR_LOG(G3D, "Could not load texture replacement info: %s", filename.c_str()); - } else { - level.w = (image.width() * w) / newW; - level.h = (image.height() * h) / newH; - good = true; - } -#else png_image png = {}; png.version = PNG_IMAGE_VERSION; FILE *fp = File::OpenCFile(filename, "rb"); @@ -357,7 +344,6 @@ void TextureReplacer::PopulateReplacement(ReplacedTexture *result, u64 cachekey, fclose(fp); png_image_free(&png); -#endif if (good && i != 0) { // Check that the mipmap size is correct. Can't load mips of the wrong size. @@ -377,7 +363,6 @@ void TextureReplacer::PopulateReplacement(ReplacedTexture *result, u64 cachekey, result->alphaStatus_ = ReplacedTextureAlpha::UNKNOWN; } -#ifndef USING_QT_UI static bool WriteTextureToPNG(png_imagep image, const std::string &filename, int convert_to_8bit, const void *buffer, png_int_32 row_stride, const void *colormap) { FILE *fp = File::OpenCFile(filename, "wb"); if (!fp) { @@ -395,7 +380,6 @@ static bool WriteTextureToPNG(png_imagep image, const std::string &filename, int return false; } } -#endif void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &replacedInfo, const void *data, int pitch, int level, int w, int h) { _assert_msg_(enabled_, "Replacement not enabled"); @@ -459,9 +443,6 @@ void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &repl h = lookupH * replacedInfo.scaleFactor; } -#ifdef USING_QT_UI - ERROR_LOG(G3D, "Replacement texture saving not implemented for Qt"); -#else if (replacedInfo.fmt != ReplacedTextureFormat::F_8888) { saveBuf.resize((pitch * h) / sizeof(u16)); switch (replacedInfo.fmt) { @@ -512,7 +493,6 @@ void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &repl } else if (success) { NOTICE_LOG(G3D, "Saving texture for replacement: %08x / %dx%d", replacedInfo.hash, w, h); } -#endif // Remember that we've saved this for next time. ReplacedTextureLevel saved; From 99d0df07844decb8b739bf5ccc9cf5759f84190a Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Tue, 6 Oct 2020 04:50:25 +0200 Subject: [PATCH 847/848] SDL: Implement multitouch support Pass proper touch events instead of merely emulating a mouse. Also, disable SDL's built-in mouse emulation (added in SDL 2.0.10). Signed-off-by: Sebastian Krzyszkowiak --- SDL/SDLMain.cpp | 80 ++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index cc1dcdce0f..8d43dfdb66 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -479,6 +479,10 @@ int main(int argc, char *argv[]) { putenv((char*)"SDL_VIDEO_CENTERED=1"); SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); +#ifdef SDL_HINT_TOUCH_MOUSE_EVENTS + SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); +#endif + if (VulkanMayBeAvailable()) { printf("DEBUG: Vulkan might be available.\n"); } else { @@ -863,68 +867,56 @@ int main(int argc, char *argv[]) { NativeKey(key); break; } -#if !SDL_VERSION_ATLEAST(2, 0, 10) // This behavior doesn't feel right on a macbook with a touchpad. #if !PPSSPP_PLATFORM(MAC) case SDL_FINGERMOTION: { SDL_GetWindowSize(window, &w, &h); - touchEvent.type = SDL_MOUSEMOTION; - touchEvent.motion.type = SDL_MOUSEMOTION; - touchEvent.motion.timestamp = event.tfinger.timestamp; - touchEvent.motion.windowID = SDL_GetWindowID(window); - touchEvent.motion.state = SDL_GetMouseState(NULL, NULL); - touchEvent.motion.x = event.tfinger.x * w; - touchEvent.motion.y = event.tfinger.y * h; - - SDL_WarpMouseInWindow(window, event.tfinger.x * w, event.tfinger.y * h); - - SDL_PushEvent(&touchEvent); + TouchInput input; + input.id = event.tfinger.fingerId; + input.x = event.tfinger.x * w; + input.y = event.tfinger.y * h; + input.flags = TOUCH_MOVE; + input.timestamp = event.tfinger.timestamp; + NativeTouch(input); break; } case SDL_FINGERDOWN: { SDL_GetWindowSize(window, &w, &h); - touchEvent.type = SDL_MOUSEBUTTONDOWN; - touchEvent.button.type = SDL_MOUSEBUTTONDOWN; - touchEvent.button.timestamp = SDL_GetTicks(); - touchEvent.button.windowID = SDL_GetWindowID(window); - touchEvent.button.button = SDL_BUTTON_LEFT; - touchEvent.button.state = SDL_PRESSED; - touchEvent.button.clicks = 1; - touchEvent.button.x = event.tfinger.x * w; - touchEvent.button.y = event.tfinger.y * h; + TouchInput input; + input.id = event.tfinger.fingerId; + input.x = event.tfinger.x * w; + input.y = event.tfinger.y * h; + input.flags = TOUCH_DOWN; + input.timestamp = event.tfinger.timestamp; + NativeTouch(input); - touchEvent.motion.type = SDL_MOUSEMOTION; - touchEvent.motion.timestamp = SDL_GetTicks(); - touchEvent.motion.windowID = SDL_GetWindowID(window); - touchEvent.motion.x = event.tfinger.x * w; - touchEvent.motion.y = event.tfinger.y * h; - // Any real mouse cursor should also move - SDL_WarpMouseInWindow(window, event.tfinger.x * w, event.tfinger.y * h); - // First finger down event also has to be a motion to that position - SDL_PushEvent(&touchEvent); - touchEvent.motion.type = SDL_MOUSEBUTTONDOWN; - // Now we push the mouse button event - SDL_PushEvent(&touchEvent); + KeyInput key; + key.deviceId = DEVICE_ID_MOUSE; + key.keyCode = NKCODE_EXT_MOUSEBUTTON_1; + key.flags = KEY_DOWN; + NativeKey(key); break; } case SDL_FINGERUP: { SDL_GetWindowSize(window, &w, &h); - touchEvent.type = SDL_MOUSEBUTTONUP; - touchEvent.button.type = SDL_MOUSEBUTTONUP; - touchEvent.button.timestamp = SDL_GetTicks(); - touchEvent.button.windowID = SDL_GetWindowID(window); - touchEvent.button.button = SDL_BUTTON_LEFT; - touchEvent.button.state = SDL_RELEASED; - touchEvent.button.clicks = 1; - touchEvent.button.x = event.tfinger.x * w; - touchEvent.button.y = event.tfinger.y * h; - SDL_PushEvent(&touchEvent); + TouchInput input; + input.id = event.tfinger.fingerId; + input.x = event.tfinger.x * w; + input.y = event.tfinger.y * h; + input.flags = TOUCH_UP; + input.timestamp = event.tfinger.timestamp; + NativeTouch(input); + + KeyInput key; + key.deviceId = DEVICE_ID_MOUSE; + key.keyCode = NKCODE_EXT_MOUSEBUTTON_1; + key.flags = KEY_UP; + NativeKey(key); break; } -#endif #endif case SDL_MOUSEBUTTONDOWN: switch (event.button.button) { From 44a93f98edaebdb54f15544cf3d33ecc87f6a3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 6 Oct 2020 16:57:23 +0200 Subject: [PATCH 848/848] SDL: Apply patch from issue #13516, fixing issue with Wacom tablets with readonly flags set. --- SDL/SDLJoystick.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp index 3ffe815c31..1dfedeac51 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -58,15 +58,19 @@ void SDLJoystick::setUpController(int deviceIndex) { int cbGUID = 33; char pszGUID[cbGUID]; SDL_Joystick* joystick = SDL_JoystickOpen(deviceIndex); - SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), pszGUID, cbGUID); - // create default mapping - this is the PS3 dual shock mapping - std::string mapping = string(pszGUID) + "," + string(SDL_JoystickName(joystick)) + ",x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4"; - if (SDL_GameControllerAddMapping(mapping.c_str()) == 1){ - cout << "Added default mapping ok" << endl; + if (joystick) { + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), pszGUID, cbGUID); + // create default mapping - this is the PS3 dual shock mapping + std::string mapping = string(pszGUID) + "," + string(SDL_JoystickName(joystick)) + ",x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4"; + if (SDL_GameControllerAddMapping(mapping.c_str()) == 1){ + cout << "Added default mapping ok" << endl; + } else { + cout << "Failed to add default mapping" << endl; + } + SDL_JoystickClose(joystick); } else { - cout << "Failed to add default mapping" << endl; + cout << "Failed to get joystick identifier. Read-only device? Control pad device " + std::to_string(deviceIndex) << endl; } - SDL_JoystickClose(joystick); } SDL_GameController *controller = SDL_GameControllerOpen(deviceIndex); if (controller) {