diff options
57 files changed, 665 insertions, 532 deletions
diff --git a/externals/cpp-httplib b/externals/cpp-httplib | |||
| Subproject 9648f950f5a8a41d18833cf4a85f5821b1bcac5 | Subproject 305a7abcb9b4e9e349843c6d563212e6c1bbbf2 | ||
diff --git a/externals/microprofile/microprofile.h b/externals/microprofile/microprofile.h index a06f6457d..639f3618c 100644 --- a/externals/microprofile/microprofile.h +++ b/externals/microprofile/microprofile.h | |||
| @@ -1246,7 +1246,7 @@ struct MicroProfileScopeLock | |||
| 1246 | { | 1246 | { |
| 1247 | bool bUseLock; | 1247 | bool bUseLock; |
| 1248 | std::recursive_mutex& m; | 1248 | std::recursive_mutex& m; |
| 1249 | MicroProfileScopeLock(std::recursive_mutex& m) : bUseLock(g_bUseLock), m(m) | 1249 | MicroProfileScopeLock(std::recursive_mutex& m_) : bUseLock(g_bUseLock), m(m_) |
| 1250 | { | 1250 | { |
| 1251 | if(bUseLock) | 1251 | if(bUseLock) |
| 1252 | m.lock(); | 1252 | m.lock(); |
diff --git a/externals/microprofile/microprofileui.h b/externals/microprofile/microprofileui.h index 85fbf2cb9..1357a08fd 100644 --- a/externals/microprofile/microprofileui.h +++ b/externals/microprofile/microprofileui.h | |||
| @@ -213,8 +213,8 @@ struct MicroProfileCustom | |||
| 213 | 213 | ||
| 214 | struct SOptionDesc | 214 | struct SOptionDesc |
| 215 | { | 215 | { |
| 216 | SOptionDesc(){} | 216 | SOptionDesc()=default; |
| 217 | SOptionDesc(uint8_t nSubType, uint8_t nIndex, const char* fmt, ...):nSubType(nSubType), nIndex(nIndex) | 217 | SOptionDesc(uint8_t nSubType_, uint8_t nIndex_, const char* fmt, ...):nSubType(nSubType_), nIndex(nIndex_) |
| 218 | { | 218 | { |
| 219 | va_list args; | 219 | va_list args; |
| 220 | va_start (args, fmt); | 220 | va_start (args, fmt); |
| @@ -573,10 +573,10 @@ inline void MicroProfileToolTipMeta(MicroProfileStringArray* pToolTip) | |||
| 573 | } | 573 | } |
| 574 | else | 574 | else |
| 575 | { | 575 | { |
| 576 | for(int i = 0; i < MICROPROFILE_META_MAX; ++i) | 576 | for(int k = 0; k < MICROPROFILE_META_MAX; ++k) |
| 577 | { | 577 | { |
| 578 | nMetaSumInclusive[i] += nMetaSum[i]; | 578 | nMetaSumInclusive[k] += nMetaSum[k]; |
| 579 | nMetaSum[i] = 0; | 579 | nMetaSum[k] = 0; |
| 580 | } | 580 | } |
| 581 | } | 581 | } |
| 582 | break; | 582 | break; |
| @@ -708,10 +708,10 @@ inline void MicroProfileDrawFloatTooltip(uint32_t nX, uint32_t nY, uint32_t nTok | |||
| 708 | 708 | ||
| 709 | if(UI.nMouseLeftMod) | 709 | if(UI.nMouseLeftMod) |
| 710 | { | 710 | { |
| 711 | int nIndex = (g_MicroProfileUI.LockedToolTipFront + MICROPROFILE_TOOLTIP_MAX_LOCKED - 1) % MICROPROFILE_TOOLTIP_MAX_LOCKED; | 711 | int nToolTipIndex = (g_MicroProfileUI.LockedToolTipFront + MICROPROFILE_TOOLTIP_MAX_LOCKED - 1) % MICROPROFILE_TOOLTIP_MAX_LOCKED; |
| 712 | g_MicroProfileUI.nLockedToolTipColor[nIndex] = S.TimerInfo[nTimerId].nColor; | 712 | g_MicroProfileUI.nLockedToolTipColor[nToolTipIndex] = S.TimerInfo[nTimerId].nColor; |
| 713 | MicroProfileStringArrayCopy(&g_MicroProfileUI.LockedToolTips[nIndex], &ToolTip); | 713 | MicroProfileStringArrayCopy(&g_MicroProfileUI.LockedToolTips[nToolTipIndex], &ToolTip); |
| 714 | g_MicroProfileUI.LockedToolTipFront = nIndex; | 714 | g_MicroProfileUI.LockedToolTipFront = nToolTipIndex; |
| 715 | 715 | ||
| 716 | } | 716 | } |
| 717 | } | 717 | } |
| @@ -917,9 +917,8 @@ inline void MicroProfileDrawDetailedBars(uint32_t nWidth, uint32_t nHeight, int | |||
| 917 | float fStart = floor(fMsBase*fRcpStep) * fStep; | 917 | float fStart = floor(fMsBase*fRcpStep) * fStep; |
| 918 | for(float f = fStart; f < fMsEnd; ) | 918 | for(float f = fStart; f < fMsEnd; ) |
| 919 | { | 919 | { |
| 920 | float fStart = f; | ||
| 921 | float fNext = f + fStep; | 920 | float fNext = f + fStep; |
| 922 | MicroProfileDrawBox(((fStart-fMsBase) * fMsToScreen), nBaseY, (fNext-fMsBase) * fMsToScreen+1, nBaseY + nHeight, UI.nOpacityBackground | g_nMicroProfileBackColors[nColorIndex++ & 1]); | 921 | MicroProfileDrawBox(((f-fMsBase) * fMsToScreen), nBaseY, (fNext-fMsBase) * fMsToScreen+1, nBaseY + nHeight, UI.nOpacityBackground | g_nMicroProfileBackColors[nColorIndex++ & 1]); |
| 923 | f = fNext; | 922 | f = fNext; |
| 924 | } | 923 | } |
| 925 | } | 924 | } |
| @@ -1116,9 +1115,9 @@ inline void MicroProfileDrawDetailedBars(uint32_t nWidth, uint32_t nHeight, int | |||
| 1116 | 1115 | ||
| 1117 | nMaxStackDepth = MicroProfileMax(nMaxStackDepth, nStackPos); | 1116 | nMaxStackDepth = MicroProfileMax(nMaxStackDepth, nStackPos); |
| 1118 | float fMsStart = fToMs * MicroProfileLogTickDifference(nBaseTicks, nTickStart); | 1117 | float fMsStart = fToMs * MicroProfileLogTickDifference(nBaseTicks, nTickStart); |
| 1119 | float fMsEnd = fToMs * MicroProfileLogTickDifference(nBaseTicks, nTickEnd); | 1118 | float fMsEnd2 = fToMs * MicroProfileLogTickDifference(nBaseTicks, nTickEnd); |
| 1120 | float fXStart = fMsStart * fMsToScreen; | 1119 | float fXStart = fMsStart * fMsToScreen; |
| 1121 | float fXEnd = fMsEnd * fMsToScreen; | 1120 | float fXEnd = fMsEnd2 * fMsToScreen; |
| 1122 | float fYStart = (float)(nY + nStackPos * nYDelta); | 1121 | float fYStart = (float)(nY + nStackPos * nYDelta); |
| 1123 | float fYEnd = fYStart + (MICROPROFILE_DETAILED_BAR_HEIGHT); | 1122 | float fYEnd = fYStart + (MICROPROFILE_DETAILED_BAR_HEIGHT); |
| 1124 | float fXDist = MicroProfileMax(fXStart - fMouseX, fMouseX - fXEnd); | 1123 | float fXDist = MicroProfileMax(fXStart - fMouseX, fMouseX - fXEnd); |
| @@ -1269,22 +1268,22 @@ inline void MicroProfileDrawDetailedBars(uint32_t nWidth, uint32_t nHeight, int | |||
| 1269 | if(UI.nRangeBegin != UI.nRangeEnd) | 1268 | if(UI.nRangeBegin != UI.nRangeEnd) |
| 1270 | { | 1269 | { |
| 1271 | float fMsStart = fToMsCpu * MicroProfileLogTickDifference(nBaseTicksCpu, UI.nRangeBegin); | 1270 | float fMsStart = fToMsCpu * MicroProfileLogTickDifference(nBaseTicksCpu, UI.nRangeBegin); |
| 1272 | float fMsEnd = fToMsCpu * MicroProfileLogTickDifference(nBaseTicksCpu, UI.nRangeEnd); | 1271 | float fMsEnd3 = fToMsCpu * MicroProfileLogTickDifference(nBaseTicksCpu, UI.nRangeEnd); |
| 1273 | float fXStart = fMsStart * fMsToScreen; | 1272 | float fXStart = fMsStart * fMsToScreen; |
| 1274 | float fXEnd = fMsEnd * fMsToScreen; | 1273 | float fXEnd = fMsEnd3 * fMsToScreen; |
| 1275 | MicroProfileDrawBox(fXStart, nBaseY, fXEnd, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT, MicroProfileBoxTypeFlat); | 1274 | MicroProfileDrawBox(fXStart, nBaseY, fXEnd, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT, MicroProfileBoxTypeFlat); |
| 1276 | MicroProfileDrawLineVertical(fXStart, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT | 0x44000000); | 1275 | MicroProfileDrawLineVertical(fXStart, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT | 0x44000000); |
| 1277 | MicroProfileDrawLineVertical(fXEnd, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT | 0x44000000); | 1276 | MicroProfileDrawLineVertical(fXEnd, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT | 0x44000000); |
| 1278 | 1277 | ||
| 1279 | fMsStart += fDetailedOffset; | 1278 | fMsStart += fDetailedOffset; |
| 1280 | fMsEnd += fDetailedOffset; | 1279 | fMsEnd3 += fDetailedOffset; |
| 1281 | char sBuffer[32]; | 1280 | char sBuffer[32]; |
| 1282 | uint32_t nLenStart = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsStart); | 1281 | uint32_t nLenStart = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsStart); |
| 1283 | float fStartTextWidth = (float)((1+MICROPROFILE_TEXT_WIDTH) * nLenStart); | 1282 | float fStartTextWidth = (float)((1+MICROPROFILE_TEXT_WIDTH) * nLenStart); |
| 1284 | float fStartTextX = fXStart - fStartTextWidth - 2; | 1283 | float fStartTextX = fXStart - fStartTextWidth - 2; |
| 1285 | MicroProfileDrawBox(fStartTextX, nBaseY, fStartTextX + fStartTextWidth + 2, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); | 1284 | MicroProfileDrawBox(fStartTextX, nBaseY, fStartTextX + fStartTextWidth + 2, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); |
| 1286 | MicroProfileDrawText(fStartTextX+1, nBaseY, UINT32_MAX, sBuffer, nLenStart); | 1285 | MicroProfileDrawText(fStartTextX+1, nBaseY, UINT32_MAX, sBuffer, nLenStart); |
| 1287 | uint32_t nLenEnd = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsEnd); | 1286 | uint32_t nLenEnd = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsEnd3); |
| 1288 | MicroProfileDrawBox(fXEnd+1, nBaseY, fXEnd+1+(1+MICROPROFILE_TEXT_WIDTH) * nLenEnd + 3, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); | 1287 | MicroProfileDrawBox(fXEnd+1, nBaseY, fXEnd+1+(1+MICROPROFILE_TEXT_WIDTH) * nLenEnd + 3, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); |
| 1289 | MicroProfileDrawText(fXEnd+2, nBaseY+1, UINT32_MAX, sBuffer, nLenEnd); | 1288 | MicroProfileDrawText(fXEnd+2, nBaseY+1, UINT32_MAX, sBuffer, nLenEnd); |
| 1290 | 1289 | ||
| @@ -1297,9 +1296,9 @@ inline void MicroProfileDrawDetailedBars(uint32_t nWidth, uint32_t nHeight, int | |||
| 1297 | if(UI.nRangeBeginGpu != UI.nRangeEndGpu) | 1296 | if(UI.nRangeBeginGpu != UI.nRangeEndGpu) |
| 1298 | { | 1297 | { |
| 1299 | float fMsStart = fToMsGpu * MicroProfileLogTickDifference(nBaseTicksGpu, UI.nRangeBeginGpu); | 1298 | float fMsStart = fToMsGpu * MicroProfileLogTickDifference(nBaseTicksGpu, UI.nRangeBeginGpu); |
| 1300 | float fMsEnd = fToMsGpu * MicroProfileLogTickDifference(nBaseTicksGpu, UI.nRangeEndGpu); | 1299 | float fMsEnd4 = fToMsGpu * MicroProfileLogTickDifference(nBaseTicksGpu, UI.nRangeEndGpu); |
| 1301 | float fXStart = fMsStart * fMsToScreen; | 1300 | float fXStart = fMsStart * fMsToScreen; |
| 1302 | float fXEnd = fMsEnd * fMsToScreen; | 1301 | float fXEnd = fMsEnd4 * fMsToScreen; |
| 1303 | MicroProfileDrawBox(fXStart, nBaseY, fXEnd, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU, MicroProfileBoxTypeFlat); | 1302 | MicroProfileDrawBox(fXStart, nBaseY, fXEnd, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU, MicroProfileBoxTypeFlat); |
| 1304 | MicroProfileDrawLineVertical(fXStart, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU | 0x44000000); | 1303 | MicroProfileDrawLineVertical(fXStart, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU | 0x44000000); |
| 1305 | MicroProfileDrawLineVertical(fXEnd, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU | 0x44000000); | 1304 | MicroProfileDrawLineVertical(fXEnd, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU | 0x44000000); |
| @@ -1307,14 +1306,14 @@ inline void MicroProfileDrawDetailedBars(uint32_t nWidth, uint32_t nHeight, int | |||
| 1307 | nBaseY += MICROPROFILE_TEXT_HEIGHT+1; | 1306 | nBaseY += MICROPROFILE_TEXT_HEIGHT+1; |
| 1308 | 1307 | ||
| 1309 | fMsStart += fDetailedOffset; | 1308 | fMsStart += fDetailedOffset; |
| 1310 | fMsEnd += fDetailedOffset; | 1309 | fMsEnd4 += fDetailedOffset; |
| 1311 | char sBuffer[32]; | 1310 | char sBuffer[32]; |
| 1312 | uint32_t nLenStart = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsStart); | 1311 | uint32_t nLenStart = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsStart); |
| 1313 | float fStartTextWidth = (float)((1+MICROPROFILE_TEXT_WIDTH) * nLenStart); | 1312 | float fStartTextWidth = (float)((1+MICROPROFILE_TEXT_WIDTH) * nLenStart); |
| 1314 | float fStartTextX = fXStart - fStartTextWidth - 2; | 1313 | float fStartTextX = fXStart - fStartTextWidth - 2; |
| 1315 | MicroProfileDrawBox(fStartTextX, nBaseY, fStartTextX + fStartTextWidth + 2, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); | 1314 | MicroProfileDrawBox(fStartTextX, nBaseY, fStartTextX + fStartTextWidth + 2, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); |
| 1316 | MicroProfileDrawText(fStartTextX+1, nBaseY, UINT32_MAX, sBuffer, nLenStart); | 1315 | MicroProfileDrawText(fStartTextX+1, nBaseY, UINT32_MAX, sBuffer, nLenStart); |
| 1317 | uint32_t nLenEnd = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsEnd); | 1316 | uint32_t nLenEnd = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsEnd4); |
| 1318 | MicroProfileDrawBox(fXEnd+1, nBaseY, fXEnd+1+(1+MICROPROFILE_TEXT_WIDTH) * nLenEnd + 3, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); | 1317 | MicroProfileDrawBox(fXEnd+1, nBaseY, fXEnd+1+(1+MICROPROFILE_TEXT_WIDTH) * nLenEnd + 3, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); |
| 1319 | MicroProfileDrawText(fXEnd+2, nBaseY+1, UINT32_MAX, sBuffer, nLenEnd); | 1318 | MicroProfileDrawText(fXEnd+2, nBaseY+1, UINT32_MAX, sBuffer, nLenEnd); |
| 1320 | } | 1319 | } |
| @@ -1716,8 +1715,8 @@ bool MicroProfileDrawGraph(uint32_t nScreenWidth, uint32_t nScreenHeight) | |||
| 1716 | uint32_t nTextCount = 0; | 1715 | uint32_t nTextCount = 0; |
| 1717 | uint32_t nGraphIndex = (S.nGraphPut + MICROPROFILE_GRAPH_HISTORY - int(MICROPROFILE_GRAPH_HISTORY*(1.f - fMouseXPrc))) % MICROPROFILE_GRAPH_HISTORY; | 1716 | uint32_t nGraphIndex = (S.nGraphPut + MICROPROFILE_GRAPH_HISTORY - int(MICROPROFILE_GRAPH_HISTORY*(1.f - fMouseXPrc))) % MICROPROFILE_GRAPH_HISTORY; |
| 1718 | 1717 | ||
| 1719 | uint32_t nX = UI.nMouseX; | 1718 | uint32_t nMouseX = UI.nMouseX; |
| 1720 | uint32_t nY = UI.nMouseY + 20; | 1719 | uint32_t nMouseY = UI.nMouseY + 20; |
| 1721 | 1720 | ||
| 1722 | for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) | 1721 | for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) |
| 1723 | { | 1722 | { |
| @@ -1736,7 +1735,7 @@ bool MicroProfileDrawGraph(uint32_t nScreenWidth, uint32_t nScreenHeight) | |||
| 1736 | } | 1735 | } |
| 1737 | if(nTextCount) | 1736 | if(nTextCount) |
| 1738 | { | 1737 | { |
| 1739 | MicroProfileDrawFloatWindow(nX, nY, Strings.ppStrings, Strings.nNumStrings, 0, pColors); | 1738 | MicroProfileDrawFloatWindow(nMouseX, nMouseY, Strings.ppStrings, Strings.nNumStrings, 0, pColors); |
| 1740 | } | 1739 | } |
| 1741 | 1740 | ||
| 1742 | if(UI.nMouseRight) | 1741 | if(UI.nMouseRight) |
| @@ -2321,8 +2320,8 @@ inline void MicroProfileDrawMenu(uint32_t nWidth, uint32_t nHeight) | |||
| 2321 | uint32_t nMenuX[MICROPROFILE_MENU_MAX] = {0}; | 2320 | uint32_t nMenuX[MICROPROFILE_MENU_MAX] = {0}; |
| 2322 | uint32_t nNumMenuItems = 0; | 2321 | uint32_t nNumMenuItems = 0; |
| 2323 | 2322 | ||
| 2324 | int nLen = snprintf(buffer, 127, "MicroProfile"); | 2323 | int nMPTextLen = snprintf(buffer, 127, "MicroProfile"); |
| 2325 | MicroProfileDrawText(nX, nY, UINT32_MAX, buffer, nLen); | 2324 | MicroProfileDrawText(nX, nY, UINT32_MAX, buffer, nMPTextLen); |
| 2326 | nX += (sizeof("MicroProfile")+2) * (MICROPROFILE_TEXT_WIDTH+1); | 2325 | nX += (sizeof("MicroProfile")+2) * (MICROPROFILE_TEXT_WIDTH+1); |
| 2327 | pMenuText[nNumMenuItems++] = "Mode"; | 2326 | pMenuText[nNumMenuItems++] = "Mode"; |
| 2328 | pMenuText[nNumMenuItems++] = "Groups"; | 2327 | pMenuText[nNumMenuItems++] = "Groups"; |
| @@ -2438,16 +2437,16 @@ inline void MicroProfileDrawMenu(uint32_t nWidth, uint32_t nHeight) | |||
| 2438 | int nNumLines = 0; | 2437 | int nNumLines = 0; |
| 2439 | bool bSelected = false; | 2438 | bool bSelected = false; |
| 2440 | const char* pString = CB(nNumLines, &bSelected); | 2439 | const char* pString = CB(nNumLines, &bSelected); |
| 2441 | uint32_t nWidth = 0, nHeight = 0; | 2440 | uint32_t nTextWidth = 0, nTextHeight = 0; |
| 2442 | while(pString) | 2441 | while(pString) |
| 2443 | { | 2442 | { |
| 2444 | nWidth = MicroProfileMax<int>(nWidth, (int)strlen(pString)); | 2443 | nTextWidth = MicroProfileMax<int>(nTextWidth, (int)strlen(pString)); |
| 2445 | nNumLines++; | 2444 | nNumLines++; |
| 2446 | pString = CB(nNumLines, &bSelected); | 2445 | pString = CB(nNumLines, &bSelected); |
| 2447 | } | 2446 | } |
| 2448 | nWidth = (2+nWidth) * (MICROPROFILE_TEXT_WIDTH+1); | 2447 | nTextWidth = (2+nTextWidth) * (MICROPROFILE_TEXT_WIDTH+1); |
| 2449 | nHeight = nNumLines * (MICROPROFILE_TEXT_HEIGHT+1); | 2448 | nTextHeight = nNumLines * (MICROPROFILE_TEXT_HEIGHT+1); |
| 2450 | if(UI.nMouseY <= nY + nHeight+0 && UI.nMouseY >= nY-0 && UI.nMouseX <= nX + nWidth + 0 && UI.nMouseX >= nX - 0) | 2449 | if(UI.nMouseY <= nY + nTextHeight+0 && UI.nMouseY >= nY-0 && UI.nMouseX <= nX + nTextWidth + 0 && UI.nMouseX >= nX - 0) |
| 2451 | { | 2450 | { |
| 2452 | UI.nActiveMenu = nMenu; | 2451 | UI.nActiveMenu = nMenu; |
| 2453 | } | 2452 | } |
| @@ -2455,21 +2454,21 @@ inline void MicroProfileDrawMenu(uint32_t nWidth, uint32_t nHeight) | |||
| 2455 | { | 2454 | { |
| 2456 | UI.nActiveMenu = UINT32_MAX; | 2455 | UI.nActiveMenu = UINT32_MAX; |
| 2457 | } | 2456 | } |
| 2458 | MicroProfileDrawBox(nX, nY, nX + nWidth, nY + nHeight, 0xff000000|g_nMicroProfileBackColors[1]); | 2457 | MicroProfileDrawBox(nX, nY, nX + nTextWidth, nY + nTextHeight, 0xff000000|g_nMicroProfileBackColors[1]); |
| 2459 | for(int i = 0; i < nNumLines; ++i) | 2458 | for(int i = 0; i < nNumLines; ++i) |
| 2460 | { | 2459 | { |
| 2461 | bool bSelected = false; | 2460 | bool bSelected2 = false; |
| 2462 | const char* pString = CB(i, &bSelected); | 2461 | const char* pString2 = CB(i, &bSelected2); |
| 2463 | if(UI.nMouseY >= nY && UI.nMouseY < nY + MICROPROFILE_TEXT_HEIGHT + 1) | 2462 | if(UI.nMouseY >= nY && UI.nMouseY < nY + MICROPROFILE_TEXT_HEIGHT + 1) |
| 2464 | { | 2463 | { |
| 2465 | if(UI.nMouseLeft || UI.nMouseRight) | 2464 | if(UI.nMouseLeft || UI.nMouseRight) |
| 2466 | { | 2465 | { |
| 2467 | CBClick[nMenu](i); | 2466 | CBClick[nMenu](i); |
| 2468 | } | 2467 | } |
| 2469 | MicroProfileDrawBox(nX, nY, nX + nWidth, nY + MICROPROFILE_TEXT_HEIGHT + 1, 0xff888888); | 2468 | MicroProfileDrawBox(nX, nY, nX + nTextWidth, nY + MICROPROFILE_TEXT_HEIGHT + 1, 0xff888888); |
| 2470 | } | 2469 | } |
| 2471 | int nLen = snprintf(buffer, SBUF_SIZE-1, "%c %s", bSelected ? '*' : ' ' ,pString); | 2470 | int nTextLen = snprintf(buffer, SBUF_SIZE-1, "%c %s", bSelected2 ? '*' : ' ' ,pString2); |
| 2472 | MicroProfileDrawText(nX, nY, UINT32_MAX, buffer, nLen); | 2471 | MicroProfileDrawText(nX, nY, UINT32_MAX, buffer, nTextLen); |
| 2473 | nY += MICROPROFILE_TEXT_HEIGHT+1; | 2472 | nY += MICROPROFILE_TEXT_HEIGHT+1; |
| 2474 | } | 2473 | } |
| 2475 | } | 2474 | } |
| @@ -2605,7 +2604,7 @@ inline void MicroProfileDrawCustom(uint32_t nWidth, uint32_t nHeight) | |||
| 2605 | for(uint32_t i = 0; i < nCount; ++i) | 2604 | for(uint32_t i = 0; i < nCount; ++i) |
| 2606 | { | 2605 | { |
| 2607 | nOffsetY += (1+MICROPROFILE_TEXT_HEIGHT); | 2606 | nOffsetY += (1+MICROPROFILE_TEXT_HEIGHT); |
| 2608 | uint32_t nWidth = MicroProfileMin(nMaxWidth, (uint32_t)(nMaxWidth * pMs[i] * fRcpReference)); | 2607 | nWidth = MicroProfileMin(nMaxWidth, (uint32_t)(nMaxWidth * pMs[i] * fRcpReference)); |
| 2609 | MicroProfileDrawBox(nMaxOffsetX, nOffsetY, nMaxOffsetX+nWidth, nOffsetY+MICROPROFILE_TEXT_HEIGHT, pColors[i]|0xff000000); | 2608 | MicroProfileDrawBox(nMaxOffsetX, nOffsetY, nMaxOffsetX+nWidth, nOffsetY+MICROPROFILE_TEXT_HEIGHT, pColors[i]|0xff000000); |
| 2610 | } | 2609 | } |
| 2611 | } | 2610 | } |
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9182dbfd4..39d038493 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt | |||
| @@ -65,6 +65,10 @@ if (MSVC) | |||
| 65 | /we4305 # 'context': truncation from 'type1' to 'type2' | 65 | /we4305 # 'context': truncation from 'type1' to 'type2' |
| 66 | /we4388 # 'expression': signed/unsigned mismatch | 66 | /we4388 # 'expression': signed/unsigned mismatch |
| 67 | /we4389 # 'operator': signed/unsigned mismatch | 67 | /we4389 # 'operator': signed/unsigned mismatch |
| 68 | /we4456 # Declaration of 'identifier' hides previous local declaration | ||
| 69 | /we4457 # Declaration of 'identifier' hides function parameter | ||
| 70 | /we4458 # Declaration of 'identifier' hides class member | ||
| 71 | /we4459 # Declaration of 'identifier' hides global declaration | ||
| 68 | /we4505 # 'function': unreferenced local function has been removed | 72 | /we4505 # 'function': unreferenced local function has been removed |
| 69 | /we4547 # 'operator': operator before comma has no effect; expected operator with side-effect | 73 | /we4547 # 'operator': operator before comma has no effect; expected operator with side-effect |
| 70 | /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? | 74 | /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? |
| @@ -92,6 +96,7 @@ else() | |||
| 92 | -Werror=missing-declarations | 96 | -Werror=missing-declarations |
| 93 | -Werror=missing-field-initializers | 97 | -Werror=missing-field-initializers |
| 94 | -Werror=reorder | 98 | -Werror=reorder |
| 99 | -Werror=shadow | ||
| 95 | -Werror=sign-compare | 100 | -Werror=sign-compare |
| 96 | -Werror=switch | 101 | -Werror=switch |
| 97 | -Werror=uninitialized | 102 | -Werror=uninitialized |
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index e553b8203..89575a53e 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt | |||
| @@ -49,9 +49,6 @@ if (NOT MSVC) | |||
| 49 | target_compile_options(audio_core PRIVATE | 49 | target_compile_options(audio_core PRIVATE |
| 50 | -Werror=conversion | 50 | -Werror=conversion |
| 51 | -Werror=ignored-qualifiers | 51 | -Werror=ignored-qualifiers |
| 52 | -Werror=shadow | ||
| 53 | -Werror=unused-parameter | ||
| 54 | -Werror=unused-variable | ||
| 55 | 52 | ||
| 56 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 53 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
| 57 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> | 54 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> |
diff --git a/src/common/bounded_threadsafe_queue.h b/src/common/bounded_threadsafe_queue.h index e83064c7f..7e465549b 100644 --- a/src/common/bounded_threadsafe_queue.h +++ b/src/common/bounded_threadsafe_queue.h | |||
| @@ -1,10 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se> | 1 | // SPDX-FileCopyrightText: Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se> |
| 2 | // SPDX-License-Identifier: MIT | 2 | // SPDX-License-Identifier: MIT |
| 3 | |||
| 3 | #pragma once | 4 | #pragma once |
| 4 | #ifdef _MSC_VER | ||
| 5 | #pragma warning(push) | ||
| 6 | #pragma warning(disable : 4324) | ||
| 7 | #endif | ||
| 8 | 5 | ||
| 9 | #include <atomic> | 6 | #include <atomic> |
| 10 | #include <bit> | 7 | #include <bit> |
| @@ -12,105 +9,63 @@ | |||
| 12 | #include <memory> | 9 | #include <memory> |
| 13 | #include <mutex> | 10 | #include <mutex> |
| 14 | #include <new> | 11 | #include <new> |
| 15 | #include <stdexcept> | ||
| 16 | #include <stop_token> | 12 | #include <stop_token> |
| 17 | #include <type_traits> | 13 | #include <type_traits> |
| 18 | #include <utility> | 14 | #include <utility> |
| 19 | 15 | ||
| 20 | namespace Common { | 16 | namespace Common { |
| 21 | namespace mpsc { | 17 | |
| 22 | #if defined(__cpp_lib_hardware_interference_size) | 18 | #if defined(__cpp_lib_hardware_interference_size) |
| 23 | constexpr size_t hardware_interference_size = std::hardware_destructive_interference_size; | 19 | constexpr size_t hardware_interference_size = std::hardware_destructive_interference_size; |
| 24 | #else | 20 | #else |
| 25 | constexpr size_t hardware_interference_size = 64; | 21 | constexpr size_t hardware_interference_size = 64; |
| 26 | #endif | 22 | #endif |
| 27 | 23 | ||
| 28 | template <typename T> | 24 | #ifdef _MSC_VER |
| 29 | using AlignedAllocator = std::allocator<T>; | 25 | #pragma warning(push) |
| 30 | 26 | #pragma warning(disable : 4324) | |
| 31 | template <typename T> | 27 | #endif |
| 32 | struct Slot { | ||
| 33 | ~Slot() noexcept { | ||
| 34 | if (turn.test()) { | ||
| 35 | destroy(); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | template <typename... Args> | ||
| 40 | void construct(Args&&... args) noexcept { | ||
| 41 | static_assert(std::is_nothrow_constructible_v<T, Args&&...>, | ||
| 42 | "T must be nothrow constructible with Args&&..."); | ||
| 43 | std::construct_at(reinterpret_cast<T*>(&storage), std::forward<Args>(args)...); | ||
| 44 | } | ||
| 45 | |||
| 46 | void destroy() noexcept { | ||
| 47 | static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); | ||
| 48 | std::destroy_at(reinterpret_cast<T*>(&storage)); | ||
| 49 | } | ||
| 50 | |||
| 51 | T&& move() noexcept { | ||
| 52 | return reinterpret_cast<T&&>(storage); | ||
| 53 | } | ||
| 54 | |||
| 55 | // Align to avoid false sharing between adjacent slots | ||
| 56 | alignas(hardware_interference_size) std::atomic_flag turn{}; | ||
| 57 | struct aligned_store { | ||
| 58 | struct type { | ||
| 59 | alignas(T) unsigned char data[sizeof(T)]; | ||
| 60 | }; | ||
| 61 | }; | ||
| 62 | typename aligned_store::type storage; | ||
| 63 | }; | ||
| 64 | 28 | ||
| 65 | template <typename T, typename Allocator = AlignedAllocator<Slot<T>>> | 29 | template <typename T, size_t capacity = 0x400> |
| 66 | class Queue { | 30 | class MPSCQueue { |
| 67 | public: | 31 | public: |
| 68 | explicit Queue(const size_t capacity, const Allocator& allocator = Allocator()) | 32 | explicit MPSCQueue() : allocator{std::allocator<Slot<T>>()} { |
| 69 | : allocator_(allocator) { | ||
| 70 | if (capacity < 1) { | ||
| 71 | throw std::invalid_argument("capacity < 1"); | ||
| 72 | } | ||
| 73 | // Ensure that the queue length is an integer power of 2 | ||
| 74 | // This is so that idx(i) can be a simple i & mask_ insted of i % capacity | ||
| 75 | // https://github.com/rigtorp/MPMCQueue/pull/36 | ||
| 76 | if (!std::has_single_bit(capacity)) { | ||
| 77 | throw std::invalid_argument("capacity must be an integer power of 2"); | ||
| 78 | } | ||
| 79 | |||
| 80 | mask_ = capacity - 1; | ||
| 81 | |||
| 82 | // Allocate one extra slot to prevent false sharing on the last slot | 33 | // Allocate one extra slot to prevent false sharing on the last slot |
| 83 | slots_ = allocator_.allocate(mask_ + 2); | 34 | slots = allocator.allocate(capacity + 1); |
| 84 | // Allocators are not required to honor alignment for over-aligned types | 35 | // Allocators are not required to honor alignment for over-aligned types |
| 85 | // (see http://eel.is/c++draft/allocator.requirements#10) so we verify | 36 | // (see http://eel.is/c++draft/allocator.requirements#10) so we verify |
| 86 | // alignment here | 37 | // alignment here |
| 87 | if (reinterpret_cast<uintptr_t>(slots_) % alignof(Slot<T>) != 0) { | 38 | if (reinterpret_cast<uintptr_t>(slots) % alignof(Slot<T>) != 0) { |
| 88 | allocator_.deallocate(slots_, mask_ + 2); | 39 | allocator.deallocate(slots, capacity + 1); |
| 89 | throw std::bad_alloc(); | 40 | throw std::bad_alloc(); |
| 90 | } | 41 | } |
| 91 | for (size_t i = 0; i < mask_ + 1; ++i) { | 42 | for (size_t i = 0; i < capacity; ++i) { |
| 92 | std::construct_at(&slots_[i]); | 43 | std::construct_at(&slots[i]); |
| 93 | } | 44 | } |
| 45 | static_assert(std::has_single_bit(capacity), "capacity must be an integer power of 2"); | ||
| 94 | static_assert(alignof(Slot<T>) == hardware_interference_size, | 46 | static_assert(alignof(Slot<T>) == hardware_interference_size, |
| 95 | "Slot must be aligned to cache line boundary to prevent false sharing"); | 47 | "Slot must be aligned to cache line boundary to prevent false sharing"); |
| 96 | static_assert(sizeof(Slot<T>) % hardware_interference_size == 0, | 48 | static_assert(sizeof(Slot<T>) % hardware_interference_size == 0, |
| 97 | "Slot size must be a multiple of cache line size to prevent " | 49 | "Slot size must be a multiple of cache line size to prevent " |
| 98 | "false sharing between adjacent slots"); | 50 | "false sharing between adjacent slots"); |
| 99 | static_assert(sizeof(Queue) % hardware_interference_size == 0, | 51 | static_assert(sizeof(MPSCQueue) % hardware_interference_size == 0, |
| 100 | "Queue size must be a multiple of cache line size to " | 52 | "Queue size must be a multiple of cache line size to " |
| 101 | "prevent false sharing between adjacent queues"); | 53 | "prevent false sharing between adjacent queues"); |
| 102 | } | 54 | } |
| 103 | 55 | ||
| 104 | ~Queue() noexcept { | 56 | ~MPSCQueue() noexcept { |
| 105 | for (size_t i = 0; i < mask_ + 1; ++i) { | 57 | for (size_t i = 0; i < capacity; ++i) { |
| 106 | slots_[i].~Slot(); | 58 | std::destroy_at(&slots[i]); |
| 107 | } | 59 | } |
| 108 | allocator_.deallocate(slots_, mask_ + 2); | 60 | allocator.deallocate(slots, capacity + 1); |
| 109 | } | 61 | } |
| 110 | 62 | ||
| 111 | // non-copyable and non-movable | 63 | // The queue must be both non-copyable and non-movable |
| 112 | Queue(const Queue&) = delete; | 64 | MPSCQueue(const MPSCQueue&) = delete; |
| 113 | Queue& operator=(const Queue&) = delete; | 65 | MPSCQueue& operator=(const MPSCQueue&) = delete; |
| 66 | |||
| 67 | MPSCQueue(MPSCQueue&&) = delete; | ||
| 68 | MPSCQueue& operator=(MPSCQueue&&) = delete; | ||
| 114 | 69 | ||
| 115 | void Push(const T& v) noexcept { | 70 | void Push(const T& v) noexcept { |
| 116 | static_assert(std::is_nothrow_copy_constructible_v<T>, | 71 | static_assert(std::is_nothrow_copy_constructible_v<T>, |
| @@ -125,8 +80,8 @@ public: | |||
| 125 | 80 | ||
| 126 | void Pop(T& v, std::stop_token stop) noexcept { | 81 | void Pop(T& v, std::stop_token stop) noexcept { |
| 127 | auto const tail = tail_.fetch_add(1); | 82 | auto const tail = tail_.fetch_add(1); |
| 128 | auto& slot = slots_[idx(tail)]; | 83 | auto& slot = slots[idx(tail)]; |
| 129 | if (false == slot.turn.test()) { | 84 | if (!slot.turn.test()) { |
| 130 | std::unique_lock lock{cv_mutex}; | 85 | std::unique_lock lock{cv_mutex}; |
| 131 | cv.wait(lock, stop, [&slot] { return slot.turn.test(); }); | 86 | cv.wait(lock, stop, [&slot] { return slot.turn.test(); }); |
| 132 | } | 87 | } |
| @@ -137,12 +92,46 @@ public: | |||
| 137 | } | 92 | } |
| 138 | 93 | ||
| 139 | private: | 94 | private: |
| 95 | template <typename U = T> | ||
| 96 | struct Slot { | ||
| 97 | ~Slot() noexcept { | ||
| 98 | if (turn.test()) { | ||
| 99 | destroy(); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | template <typename... Args> | ||
| 104 | void construct(Args&&... args) noexcept { | ||
| 105 | static_assert(std::is_nothrow_constructible_v<U, Args&&...>, | ||
| 106 | "T must be nothrow constructible with Args&&..."); | ||
| 107 | std::construct_at(reinterpret_cast<U*>(&storage), std::forward<Args>(args)...); | ||
| 108 | } | ||
| 109 | |||
| 110 | void destroy() noexcept { | ||
| 111 | static_assert(std::is_nothrow_destructible_v<U>, "T must be nothrow destructible"); | ||
| 112 | std::destroy_at(reinterpret_cast<U*>(&storage)); | ||
| 113 | } | ||
| 114 | |||
| 115 | U&& move() noexcept { | ||
| 116 | return reinterpret_cast<U&&>(storage); | ||
| 117 | } | ||
| 118 | |||
| 119 | // Align to avoid false sharing between adjacent slots | ||
| 120 | alignas(hardware_interference_size) std::atomic_flag turn{}; | ||
| 121 | struct aligned_store { | ||
| 122 | struct type { | ||
| 123 | alignas(U) unsigned char data[sizeof(U)]; | ||
| 124 | }; | ||
| 125 | }; | ||
| 126 | typename aligned_store::type storage; | ||
| 127 | }; | ||
| 128 | |||
| 140 | template <typename... Args> | 129 | template <typename... Args> |
| 141 | void emplace(Args&&... args) noexcept { | 130 | void emplace(Args&&... args) noexcept { |
| 142 | static_assert(std::is_nothrow_constructible_v<T, Args&&...>, | 131 | static_assert(std::is_nothrow_constructible_v<T, Args&&...>, |
| 143 | "T must be nothrow constructible with Args&&..."); | 132 | "T must be nothrow constructible with Args&&..."); |
| 144 | auto const head = head_.fetch_add(1); | 133 | auto const head = head_.fetch_add(1); |
| 145 | auto& slot = slots_[idx(head)]; | 134 | auto& slot = slots[idx(head)]; |
| 146 | slot.turn.wait(true); | 135 | slot.turn.wait(true); |
| 147 | slot.construct(std::forward<Args>(args)...); | 136 | slot.construct(std::forward<Args>(args)...); |
| 148 | slot.turn.test_and_set(); | 137 | slot.turn.test_and_set(); |
| @@ -150,31 +139,29 @@ private: | |||
| 150 | } | 139 | } |
| 151 | 140 | ||
| 152 | constexpr size_t idx(size_t i) const noexcept { | 141 | constexpr size_t idx(size_t i) const noexcept { |
| 153 | return i & mask_; | 142 | return i & mask; |
| 154 | } | 143 | } |
| 155 | 144 | ||
| 156 | std::conditional_t<true, std::condition_variable_any, std::condition_variable> cv; | 145 | static constexpr size_t mask = capacity - 1; |
| 157 | std::mutex cv_mutex; | ||
| 158 | size_t mask_; | ||
| 159 | Slot<T>* slots_; | ||
| 160 | [[no_unique_address]] Allocator allocator_; | ||
| 161 | 146 | ||
| 162 | // Align to avoid false sharing between head_ and tail_ | 147 | // Align to avoid false sharing between head_ and tail_ |
| 163 | alignas(hardware_interference_size) std::atomic<size_t> head_{0}; | 148 | alignas(hardware_interference_size) std::atomic<size_t> head_{0}; |
| 164 | alignas(hardware_interference_size) std::atomic<size_t> tail_{0}; | 149 | alignas(hardware_interference_size) std::atomic<size_t> tail_{0}; |
| 165 | 150 | ||
| 151 | std::mutex cv_mutex; | ||
| 152 | std::condition_variable_any cv; | ||
| 153 | |||
| 154 | Slot<T>* slots; | ||
| 155 | [[no_unique_address]] std::allocator<Slot<T>> allocator; | ||
| 156 | |||
| 166 | static_assert(std::is_nothrow_copy_assignable_v<T> || std::is_nothrow_move_assignable_v<T>, | 157 | static_assert(std::is_nothrow_copy_assignable_v<T> || std::is_nothrow_move_assignable_v<T>, |
| 167 | "T must be nothrow copy or move assignable"); | 158 | "T must be nothrow copy or move assignable"); |
| 168 | 159 | ||
| 169 | static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); | 160 | static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); |
| 170 | }; | 161 | }; |
| 171 | } // namespace mpsc | ||
| 172 | |||
| 173 | template <typename T, typename Allocator = mpsc::AlignedAllocator<mpsc::Slot<T>>> | ||
| 174 | using MPSCQueue = mpsc::Queue<T, Allocator>; | ||
| 175 | |||
| 176 | } // namespace Common | ||
| 177 | 162 | ||
| 178 | #ifdef _MSC_VER | 163 | #ifdef _MSC_VER |
| 179 | #pragma warning(pop) | 164 | #pragma warning(pop) |
| 180 | #endif | 165 | #endif |
| 166 | |||
| 167 | } // namespace Common | ||
diff --git a/src/common/detached_tasks.cpp b/src/common/detached_tasks.cpp index c1362631e..ec31d0b88 100644 --- a/src/common/detached_tasks.cpp +++ b/src/common/detached_tasks.cpp | |||
| @@ -33,9 +33,9 @@ void DetachedTasks::AddTask(std::function<void()> task) { | |||
| 33 | ++instance->count; | 33 | ++instance->count; |
| 34 | std::thread([task{std::move(task)}]() { | 34 | std::thread([task{std::move(task)}]() { |
| 35 | task(); | 35 | task(); |
| 36 | std::unique_lock lock{instance->mutex}; | 36 | std::unique_lock thread_lock{instance->mutex}; |
| 37 | --instance->count; | 37 | --instance->count; |
| 38 | std::notify_all_at_thread_exit(instance->cv, std::move(lock)); | 38 | std::notify_all_at_thread_exit(instance->cv, std::move(thread_lock)); |
| 39 | }).detach(); | 39 | }).detach(); |
| 40 | } | 40 | } |
| 41 | 41 | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2bd720f08..670410e75 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -743,16 +743,11 @@ if (MSVC) | |||
| 743 | /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data | 743 | /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data |
| 744 | /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch | 744 | /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch |
| 745 | /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data | 745 | /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data |
| 746 | /we4456 # Declaration of 'identifier' hides previous local declaration | ||
| 747 | /we4457 # Declaration of 'identifier' hides function parameter | ||
| 748 | /we4458 # Declaration of 'identifier' hides class member | ||
| 749 | /we4459 # Declaration of 'identifier' hides global declaration | ||
| 750 | ) | 746 | ) |
| 751 | else() | 747 | else() |
| 752 | target_compile_options(core PRIVATE | 748 | target_compile_options(core PRIVATE |
| 753 | -Werror=conversion | 749 | -Werror=conversion |
| 754 | -Werror=ignored-qualifiers | 750 | -Werror=ignored-qualifiers |
| 755 | -Werror=shadow | ||
| 756 | 751 | ||
| 757 | $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> | 752 | $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> |
| 758 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 753 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 9b5a5ca57..9a285dfc6 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp | |||
| @@ -107,6 +107,7 @@ void ARM_Interface::Run() { | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | // Otherwise, run the thread. | 109 | // Otherwise, run the thread. |
| 110 | system.EnterDynarmicProfile(); | ||
| 110 | if (current_thread->GetStepState() == StepState::StepPending) { | 111 | if (current_thread->GetStepState() == StepState::StepPending) { |
| 111 | hr = StepJit(); | 112 | hr = StepJit(); |
| 112 | 113 | ||
| @@ -116,6 +117,7 @@ void ARM_Interface::Run() { | |||
| 116 | } else { | 117 | } else { |
| 117 | hr = RunJit(); | 118 | hr = RunJit(); |
| 118 | } | 119 | } |
| 120 | system.ExitDynarmicProfile(); | ||
| 119 | 121 | ||
| 120 | // Notify the debugger and go to sleep if a breakpoint was hit. | 122 | // Notify the debugger and go to sleep if a breakpoint was hit. |
| 121 | if (Has(hr, breakpoint)) { | 123 | if (Has(hr, breakpoint)) { |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 954136adb..7723d9782 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -138,7 +138,6 @@ struct System::Impl { | |||
| 138 | 138 | ||
| 139 | kernel.Suspend(false); | 139 | kernel.Suspend(false); |
| 140 | core_timing.SyncPause(false); | 140 | core_timing.SyncPause(false); |
| 141 | cpu_manager.Pause(false); | ||
| 142 | is_paused = false; | 141 | is_paused = false; |
| 143 | 142 | ||
| 144 | return status; | 143 | return status; |
| @@ -150,25 +149,22 @@ struct System::Impl { | |||
| 150 | 149 | ||
| 151 | core_timing.SyncPause(true); | 150 | core_timing.SyncPause(true); |
| 152 | kernel.Suspend(true); | 151 | kernel.Suspend(true); |
| 153 | cpu_manager.Pause(true); | ||
| 154 | is_paused = true; | 152 | is_paused = true; |
| 155 | 153 | ||
| 156 | return status; | 154 | return status; |
| 157 | } | 155 | } |
| 158 | 156 | ||
| 159 | std::unique_lock<std::mutex> StallCPU() { | 157 | std::unique_lock<std::mutex> StallProcesses() { |
| 160 | std::unique_lock<std::mutex> lk(suspend_guard); | 158 | std::unique_lock<std::mutex> lk(suspend_guard); |
| 161 | kernel.Suspend(true); | 159 | kernel.Suspend(true); |
| 162 | core_timing.SyncPause(true); | 160 | core_timing.SyncPause(true); |
| 163 | cpu_manager.Pause(true); | ||
| 164 | return lk; | 161 | return lk; |
| 165 | } | 162 | } |
| 166 | 163 | ||
| 167 | void UnstallCPU() { | 164 | void UnstallProcesses() { |
| 168 | if (!is_paused) { | 165 | if (!is_paused) { |
| 169 | core_timing.SyncPause(false); | 166 | core_timing.SyncPause(false); |
| 170 | kernel.Suspend(false); | 167 | kernel.Suspend(false); |
| 171 | cpu_manager.Pause(false); | ||
| 172 | } | 168 | } |
| 173 | } | 169 | } |
| 174 | 170 | ||
| @@ -334,6 +330,8 @@ struct System::Impl { | |||
| 334 | gpu_core->NotifyShutdown(); | 330 | gpu_core->NotifyShutdown(); |
| 335 | } | 331 | } |
| 336 | 332 | ||
| 333 | kernel.ShutdownCores(); | ||
| 334 | cpu_manager.Shutdown(); | ||
| 337 | debugger.reset(); | 335 | debugger.reset(); |
| 338 | services.reset(); | 336 | services.reset(); |
| 339 | service_manager.reset(); | 337 | service_manager.reset(); |
| @@ -499,12 +497,12 @@ void System::DetachDebugger() { | |||
| 499 | } | 497 | } |
| 500 | } | 498 | } |
| 501 | 499 | ||
| 502 | std::unique_lock<std::mutex> System::StallCPU() { | 500 | std::unique_lock<std::mutex> System::StallProcesses() { |
| 503 | return impl->StallCPU(); | 501 | return impl->StallProcesses(); |
| 504 | } | 502 | } |
| 505 | 503 | ||
| 506 | void System::UnstallCPU() { | 504 | void System::UnstallProcesses() { |
| 507 | impl->UnstallCPU(); | 505 | impl->UnstallProcesses(); |
| 508 | } | 506 | } |
| 509 | 507 | ||
| 510 | void System::InitializeDebugger() { | 508 | void System::InitializeDebugger() { |
diff --git a/src/core/core.h b/src/core/core.h index 5c367349e..60efe4410 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -163,8 +163,8 @@ public: | |||
| 163 | /// Forcibly detach the debugger if it is running. | 163 | /// Forcibly detach the debugger if it is running. |
| 164 | void DetachDebugger(); | 164 | void DetachDebugger(); |
| 165 | 165 | ||
| 166 | std::unique_lock<std::mutex> StallCPU(); | 166 | std::unique_lock<std::mutex> StallProcesses(); |
| 167 | void UnstallCPU(); | 167 | void UnstallProcesses(); |
| 168 | 168 | ||
| 169 | /** | 169 | /** |
| 170 | * Initialize the debugger. | 170 | * Initialize the debugger. |
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index b4718fbbe..1c07dc90e 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -16,31 +16,28 @@ | |||
| 16 | 16 | ||
| 17 | namespace Core { | 17 | namespace Core { |
| 18 | 18 | ||
| 19 | CpuManager::CpuManager(System& system_) | 19 | CpuManager::CpuManager(System& system_) : system{system_} {} |
| 20 | : pause_barrier{std::make_unique<Common::Barrier>(1)}, system{system_} {} | ||
| 21 | CpuManager::~CpuManager() = default; | 20 | CpuManager::~CpuManager() = default; |
| 22 | 21 | ||
| 23 | void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, | 22 | void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, |
| 24 | std::size_t core) { | 23 | std::size_t core) { |
| 25 | cpu_manager.RunThread(stop_token, core); | 24 | cpu_manager.RunThread(core); |
| 26 | } | 25 | } |
| 27 | 26 | ||
| 28 | void CpuManager::Initialize() { | 27 | void CpuManager::Initialize() { |
| 29 | running_mode = true; | 28 | num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1; |
| 30 | if (is_multicore) { | 29 | |
| 31 | for (std::size_t core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { | 30 | for (std::size_t core = 0; core < num_cores; core++) { |
| 32 | core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); | 31 | core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); |
| 33 | } | ||
| 34 | pause_barrier = std::make_unique<Common::Barrier>(Core::Hardware::NUM_CPU_CORES + 1); | ||
| 35 | } else { | ||
| 36 | core_data[0].host_thread = std::jthread(ThreadStart, std::ref(*this), 0); | ||
| 37 | pause_barrier = std::make_unique<Common::Barrier>(2); | ||
| 38 | } | 32 | } |
| 39 | } | 33 | } |
| 40 | 34 | ||
| 41 | void CpuManager::Shutdown() { | 35 | void CpuManager::Shutdown() { |
| 42 | running_mode = false; | 36 | for (std::size_t core = 0; core < num_cores; core++) { |
| 43 | Pause(false); | 37 | if (core_data[core].host_thread.joinable()) { |
| 38 | core_data[core].host_thread.join(); | ||
| 39 | } | ||
| 40 | } | ||
| 44 | } | 41 | } |
| 45 | 42 | ||
| 46 | std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() { | 43 | std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() { |
| @@ -51,8 +48,8 @@ std::function<void(void*)> CpuManager::GetIdleThreadStartFunc() { | |||
| 51 | return IdleThreadFunction; | 48 | return IdleThreadFunction; |
| 52 | } | 49 | } |
| 53 | 50 | ||
| 54 | std::function<void(void*)> CpuManager::GetSuspendThreadStartFunc() { | 51 | std::function<void(void*)> CpuManager::GetShutdownThreadStartFunc() { |
| 55 | return SuspendThreadFunction; | 52 | return ShutdownThreadFunction; |
| 56 | } | 53 | } |
| 57 | 54 | ||
| 58 | void CpuManager::GuestThreadFunction(void* cpu_manager_) { | 55 | void CpuManager::GuestThreadFunction(void* cpu_manager_) { |
| @@ -82,17 +79,12 @@ void CpuManager::IdleThreadFunction(void* cpu_manager_) { | |||
| 82 | } | 79 | } |
| 83 | } | 80 | } |
| 84 | 81 | ||
| 85 | void CpuManager::SuspendThreadFunction(void* cpu_manager_) { | 82 | void CpuManager::ShutdownThreadFunction(void* cpu_manager) { |
| 86 | CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_); | 83 | static_cast<CpuManager*>(cpu_manager)->ShutdownThread(); |
| 87 | if (cpu_manager->is_multicore) { | ||
| 88 | cpu_manager->MultiCoreRunSuspendThread(); | ||
| 89 | } else { | ||
| 90 | cpu_manager->SingleCoreRunSuspendThread(); | ||
| 91 | } | ||
| 92 | } | 84 | } |
| 93 | 85 | ||
| 94 | void* CpuManager::GetStartFuncParamater() { | 86 | void* CpuManager::GetStartFuncParameter() { |
| 95 | return static_cast<void*>(this); | 87 | return this; |
| 96 | } | 88 | } |
| 97 | 89 | ||
| 98 | /////////////////////////////////////////////////////////////////////////////// | 90 | /////////////////////////////////////////////////////////////////////////////// |
| @@ -113,12 +105,10 @@ void CpuManager::MultiCoreRunGuestLoop() { | |||
| 113 | 105 | ||
| 114 | while (true) { | 106 | while (true) { |
| 115 | auto* physical_core = &kernel.CurrentPhysicalCore(); | 107 | auto* physical_core = &kernel.CurrentPhysicalCore(); |
| 116 | system.EnterDynarmicProfile(); | ||
| 117 | while (!physical_core->IsInterrupted()) { | 108 | while (!physical_core->IsInterrupted()) { |
| 118 | physical_core->Run(); | 109 | physical_core->Run(); |
| 119 | physical_core = &kernel.CurrentPhysicalCore(); | 110 | physical_core = &kernel.CurrentPhysicalCore(); |
| 120 | } | 111 | } |
| 121 | system.ExitDynarmicProfile(); | ||
| 122 | { | 112 | { |
| 123 | Kernel::KScopedDisableDispatch dd(kernel); | 113 | Kernel::KScopedDisableDispatch dd(kernel); |
| 124 | physical_core->ArmInterface().ClearExclusiveState(); | 114 | physical_core->ArmInterface().ClearExclusiveState(); |
| @@ -134,21 +124,6 @@ void CpuManager::MultiCoreRunIdleThread() { | |||
| 134 | } | 124 | } |
| 135 | } | 125 | } |
| 136 | 126 | ||
| 137 | void CpuManager::MultiCoreRunSuspendThread() { | ||
| 138 | auto& kernel = system.Kernel(); | ||
| 139 | kernel.CurrentScheduler()->OnThreadStart(); | ||
| 140 | while (true) { | ||
| 141 | auto core = kernel.CurrentPhysicalCoreIndex(); | ||
| 142 | auto& scheduler = *kernel.CurrentScheduler(); | ||
| 143 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | ||
| 144 | current_thread->DisableDispatch(); | ||
| 145 | |||
| 146 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context); | ||
| 147 | ASSERT(core == kernel.CurrentPhysicalCoreIndex()); | ||
| 148 | scheduler.RescheduleCurrentCore(); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | /////////////////////////////////////////////////////////////////////////////// | 127 | /////////////////////////////////////////////////////////////////////////////// |
| 153 | /// SingleCore /// | 128 | /// SingleCore /// |
| 154 | /////////////////////////////////////////////////////////////////////////////// | 129 | /////////////////////////////////////////////////////////////////////////////// |
| @@ -166,12 +141,10 @@ void CpuManager::SingleCoreRunGuestLoop() { | |||
| 166 | auto& kernel = system.Kernel(); | 141 | auto& kernel = system.Kernel(); |
| 167 | while (true) { | 142 | while (true) { |
| 168 | auto* physical_core = &kernel.CurrentPhysicalCore(); | 143 | auto* physical_core = &kernel.CurrentPhysicalCore(); |
| 169 | system.EnterDynarmicProfile(); | ||
| 170 | if (!physical_core->IsInterrupted()) { | 144 | if (!physical_core->IsInterrupted()) { |
| 171 | physical_core->Run(); | 145 | physical_core->Run(); |
| 172 | physical_core = &kernel.CurrentPhysicalCore(); | 146 | physical_core = &kernel.CurrentPhysicalCore(); |
| 173 | } | 147 | } |
| 174 | system.ExitDynarmicProfile(); | ||
| 175 | kernel.SetIsPhantomModeForSingleCore(true); | 148 | kernel.SetIsPhantomModeForSingleCore(true); |
| 176 | system.CoreTiming().Advance(); | 149 | system.CoreTiming().Advance(); |
| 177 | kernel.SetIsPhantomModeForSingleCore(false); | 150 | kernel.SetIsPhantomModeForSingleCore(false); |
| @@ -194,21 +167,6 @@ void CpuManager::SingleCoreRunIdleThread() { | |||
| 194 | } | 167 | } |
| 195 | } | 168 | } |
| 196 | 169 | ||
| 197 | void CpuManager::SingleCoreRunSuspendThread() { | ||
| 198 | auto& kernel = system.Kernel(); | ||
| 199 | kernel.CurrentScheduler()->OnThreadStart(); | ||
| 200 | while (true) { | ||
| 201 | auto core = kernel.GetCurrentHostThreadID(); | ||
| 202 | auto& scheduler = *kernel.CurrentScheduler(); | ||
| 203 | Kernel::KThread* current_thread = scheduler.GetCurrentThread(); | ||
| 204 | current_thread->DisableDispatch(); | ||
| 205 | |||
| 206 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[0].host_context); | ||
| 207 | ASSERT(core == kernel.GetCurrentHostThreadID()); | ||
| 208 | scheduler.RescheduleCurrentCore(); | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | void CpuManager::PreemptSingleCore(bool from_running_enviroment) { | 170 | void CpuManager::PreemptSingleCore(bool from_running_enviroment) { |
| 213 | { | 171 | { |
| 214 | auto& kernel = system.Kernel(); | 172 | auto& kernel = system.Kernel(); |
| @@ -241,24 +199,16 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) { | |||
| 241 | } | 199 | } |
| 242 | } | 200 | } |
| 243 | 201 | ||
| 244 | void CpuManager::Pause(bool paused) { | 202 | void CpuManager::ShutdownThread() { |
| 245 | std::scoped_lock lk{pause_lock}; | 203 | auto& kernel = system.Kernel(); |
| 246 | 204 | auto core = is_multicore ? kernel.CurrentPhysicalCoreIndex() : 0; | |
| 247 | if (pause_state == paused) { | 205 | auto* current_thread = kernel.GetCurrentEmuThread(); |
| 248 | return; | ||
| 249 | } | ||
| 250 | |||
| 251 | // Set the new state | ||
| 252 | pause_state.store(paused); | ||
| 253 | |||
| 254 | // Wake up any waiting threads | ||
| 255 | pause_state.notify_all(); | ||
| 256 | 206 | ||
| 257 | // Wait for all threads to successfully change state before returning | 207 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context); |
| 258 | pause_barrier->Sync(); | 208 | UNREACHABLE(); |
| 259 | } | 209 | } |
| 260 | 210 | ||
| 261 | void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { | 211 | void CpuManager::RunThread(std::size_t core) { |
| 262 | /// Initialization | 212 | /// Initialization |
| 263 | system.RegisterCoreThread(core); | 213 | system.RegisterCoreThread(core); |
| 264 | std::string name; | 214 | std::string name; |
| @@ -272,8 +222,6 @@ void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { | |||
| 272 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); | 222 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); |
| 273 | auto& data = core_data[core]; | 223 | auto& data = core_data[core]; |
| 274 | data.host_context = Common::Fiber::ThreadToFiber(); | 224 | data.host_context = Common::Fiber::ThreadToFiber(); |
| 275 | const bool sc_sync = !is_async_gpu && !is_multicore; | ||
| 276 | bool sc_sync_first_use = sc_sync; | ||
| 277 | 225 | ||
| 278 | // Cleanup | 226 | // Cleanup |
| 279 | SCOPE_EXIT({ | 227 | SCOPE_EXIT({ |
| @@ -281,32 +229,13 @@ void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { | |||
| 281 | MicroProfileOnThreadExit(); | 229 | MicroProfileOnThreadExit(); |
| 282 | }); | 230 | }); |
| 283 | 231 | ||
| 284 | /// Running | 232 | // Running |
| 285 | while (running_mode) { | 233 | if (!is_async_gpu && !is_multicore) { |
| 286 | if (pause_state.load(std::memory_order_relaxed)) { | 234 | system.GPU().ObtainContext(); |
| 287 | // Wait for caller to acknowledge pausing | ||
| 288 | pause_barrier->Sync(); | ||
| 289 | |||
| 290 | // Wait until unpaused | ||
| 291 | pause_state.wait(true, std::memory_order_relaxed); | ||
| 292 | |||
| 293 | // Wait for caller to acknowledge unpausing | ||
| 294 | pause_barrier->Sync(); | ||
| 295 | } | ||
| 296 | |||
| 297 | if (sc_sync_first_use) { | ||
| 298 | system.GPU().ObtainContext(); | ||
| 299 | sc_sync_first_use = false; | ||
| 300 | } | ||
| 301 | |||
| 302 | // Emulation was stopped | ||
| 303 | if (stop_token.stop_requested()) { | ||
| 304 | return; | ||
| 305 | } | ||
| 306 | |||
| 307 | auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); | ||
| 308 | Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext()); | ||
| 309 | } | 235 | } |
| 236 | |||
| 237 | auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); | ||
| 238 | Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext()); | ||
| 310 | } | 239 | } |
| 311 | 240 | ||
| 312 | } // namespace Core | 241 | } // namespace Core |
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h index ddd9691ca..681bdaf19 100644 --- a/src/core/cpu_manager.h +++ b/src/core/cpu_manager.h | |||
| @@ -46,12 +46,10 @@ public: | |||
| 46 | void Initialize(); | 46 | void Initialize(); |
| 47 | void Shutdown(); | 47 | void Shutdown(); |
| 48 | 48 | ||
| 49 | void Pause(bool paused); | ||
| 50 | |||
| 51 | static std::function<void(void*)> GetGuestThreadStartFunc(); | 49 | static std::function<void(void*)> GetGuestThreadStartFunc(); |
| 52 | static std::function<void(void*)> GetIdleThreadStartFunc(); | 50 | static std::function<void(void*)> GetIdleThreadStartFunc(); |
| 53 | static std::function<void(void*)> GetSuspendThreadStartFunc(); | 51 | static std::function<void(void*)> GetShutdownThreadStartFunc(); |
| 54 | void* GetStartFuncParamater(); | 52 | void* GetStartFuncParameter(); |
| 55 | 53 | ||
| 56 | void PreemptSingleCore(bool from_running_enviroment = true); | 54 | void PreemptSingleCore(bool from_running_enviroment = true); |
| 57 | 55 | ||
| @@ -63,38 +61,33 @@ private: | |||
| 63 | static void GuestThreadFunction(void* cpu_manager); | 61 | static void GuestThreadFunction(void* cpu_manager); |
| 64 | static void GuestRewindFunction(void* cpu_manager); | 62 | static void GuestRewindFunction(void* cpu_manager); |
| 65 | static void IdleThreadFunction(void* cpu_manager); | 63 | static void IdleThreadFunction(void* cpu_manager); |
| 66 | static void SuspendThreadFunction(void* cpu_manager); | 64 | static void ShutdownThreadFunction(void* cpu_manager); |
| 67 | 65 | ||
| 68 | void MultiCoreRunGuestThread(); | 66 | void MultiCoreRunGuestThread(); |
| 69 | void MultiCoreRunGuestLoop(); | 67 | void MultiCoreRunGuestLoop(); |
| 70 | void MultiCoreRunIdleThread(); | 68 | void MultiCoreRunIdleThread(); |
| 71 | void MultiCoreRunSuspendThread(); | ||
| 72 | 69 | ||
| 73 | void SingleCoreRunGuestThread(); | 70 | void SingleCoreRunGuestThread(); |
| 74 | void SingleCoreRunGuestLoop(); | 71 | void SingleCoreRunGuestLoop(); |
| 75 | void SingleCoreRunIdleThread(); | 72 | void SingleCoreRunIdleThread(); |
| 76 | void SingleCoreRunSuspendThread(); | ||
| 77 | 73 | ||
| 78 | static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core); | 74 | static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core); |
| 79 | 75 | ||
| 80 | void RunThread(std::stop_token stop_token, std::size_t core); | 76 | void ShutdownThread(); |
| 77 | void RunThread(std::size_t core); | ||
| 81 | 78 | ||
| 82 | struct CoreData { | 79 | struct CoreData { |
| 83 | std::shared_ptr<Common::Fiber> host_context; | 80 | std::shared_ptr<Common::Fiber> host_context; |
| 84 | std::jthread host_thread; | 81 | std::jthread host_thread; |
| 85 | }; | 82 | }; |
| 86 | 83 | ||
| 87 | std::atomic<bool> running_mode{}; | ||
| 88 | std::atomic<bool> pause_state{}; | ||
| 89 | std::unique_ptr<Common::Barrier> pause_barrier{}; | ||
| 90 | std::mutex pause_lock{}; | ||
| 91 | |||
| 92 | std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{}; | 84 | std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{}; |
| 93 | 85 | ||
| 94 | bool is_async_gpu{}; | 86 | bool is_async_gpu{}; |
| 95 | bool is_multicore{}; | 87 | bool is_multicore{}; |
| 96 | std::atomic<std::size_t> current_core{}; | 88 | std::atomic<std::size_t> current_core{}; |
| 97 | std::size_t idle_count{}; | 89 | std::size_t idle_count{}; |
| 90 | std::size_t num_cores{}; | ||
| 98 | static constexpr std::size_t max_cycle_runs = 5; | 91 | static constexpr std::size_t max_cycle_runs = 5; |
| 99 | 92 | ||
| 100 | System& system; | 93 | System& system; |
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index edf991d71..ab3940922 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp | |||
| @@ -67,17 +67,19 @@ public: | |||
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | bool SignalDebugger(SignalInfo signal_info) { | 69 | bool SignalDebugger(SignalInfo signal_info) { |
| 70 | std::scoped_lock lk{connection_lock}; | 70 | { |
| 71 | std::scoped_lock lk{connection_lock}; | ||
| 71 | 72 | ||
| 72 | if (stopped) { | 73 | if (stopped) { |
| 73 | // Do not notify the debugger about another event. | 74 | // Do not notify the debugger about another event. |
| 74 | // It should be ignored. | 75 | // It should be ignored. |
| 75 | return false; | 76 | return false; |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | // Set up the state. | 79 | // Set up the state. |
| 79 | stopped = true; | 80 | stopped = true; |
| 80 | info = signal_info; | 81 | info = signal_info; |
| 82 | } | ||
| 81 | 83 | ||
| 82 | // Write a single byte into the pipe to wake up the debug interface. | 84 | // Write a single byte into the pipe to wake up the debug interface. |
| 83 | boost::asio::write(signal_pipe, boost::asio::buffer(&stopped, sizeof(stopped))); | 85 | boost::asio::write(signal_pipe, boost::asio::buffer(&stopped, sizeof(stopped))); |
| @@ -141,9 +143,6 @@ private: | |||
| 141 | AsyncReceiveInto(signal_pipe, pipe_data, [&](auto d) { PipeData(d); }); | 143 | AsyncReceiveInto(signal_pipe, pipe_data, [&](auto d) { PipeData(d); }); |
| 142 | AsyncReceiveInto(client_socket, client_data, [&](auto d) { ClientData(d); }); | 144 | AsyncReceiveInto(client_socket, client_data, [&](auto d) { ClientData(d); }); |
| 143 | 145 | ||
| 144 | // Stop the emulated CPU. | ||
| 145 | AllCoreStop(); | ||
| 146 | |||
| 147 | // Set the active thread. | 146 | // Set the active thread. |
| 148 | UpdateActiveThread(); | 147 | UpdateActiveThread(); |
| 149 | 148 | ||
| @@ -159,7 +158,7 @@ private: | |||
| 159 | switch (info.type) { | 158 | switch (info.type) { |
| 160 | case SignalType::Stopped: | 159 | case SignalType::Stopped: |
| 161 | // Stop emulation. | 160 | // Stop emulation. |
| 162 | AllCoreStop(); | 161 | PauseEmulation(); |
| 163 | 162 | ||
| 164 | // Notify the client. | 163 | // Notify the client. |
| 165 | active_thread = info.thread; | 164 | active_thread = info.thread; |
| @@ -171,7 +170,6 @@ private: | |||
| 171 | frontend->ShuttingDown(); | 170 | frontend->ShuttingDown(); |
| 172 | 171 | ||
| 173 | // Wait for emulation to shut down gracefully now. | 172 | // Wait for emulation to shut down gracefully now. |
| 174 | suspend.reset(); | ||
| 175 | signal_pipe.close(); | 173 | signal_pipe.close(); |
| 176 | client_socket.shutdown(boost::asio::socket_base::shutdown_both); | 174 | client_socket.shutdown(boost::asio::socket_base::shutdown_both); |
| 177 | LOG_INFO(Debug_GDBStub, "Shut down server"); | 175 | LOG_INFO(Debug_GDBStub, "Shut down server"); |
| @@ -189,32 +187,29 @@ private: | |||
| 189 | std::scoped_lock lk{connection_lock}; | 187 | std::scoped_lock lk{connection_lock}; |
| 190 | stopped = true; | 188 | stopped = true; |
| 191 | } | 189 | } |
| 192 | AllCoreStop(); | 190 | PauseEmulation(); |
| 193 | UpdateActiveThread(); | 191 | UpdateActiveThread(); |
| 194 | frontend->Stopped(active_thread); | 192 | frontend->Stopped(active_thread); |
| 195 | break; | 193 | break; |
| 196 | } | 194 | } |
| 197 | case DebuggerAction::Continue: | 195 | case DebuggerAction::Continue: |
| 198 | active_thread->SetStepState(Kernel::StepState::NotStepping); | 196 | MarkResumed([&] { ResumeEmulation(); }); |
| 199 | ResumeInactiveThreads(); | ||
| 200 | AllCoreResume(); | ||
| 201 | break; | 197 | break; |
| 202 | case DebuggerAction::StepThreadUnlocked: | 198 | case DebuggerAction::StepThreadUnlocked: |
| 203 | active_thread->SetStepState(Kernel::StepState::StepPending); | 199 | MarkResumed([&] { |
| 204 | ResumeInactiveThreads(); | 200 | active_thread->SetStepState(Kernel::StepState::StepPending); |
| 205 | AllCoreResume(); | 201 | active_thread->Resume(Kernel::SuspendType::Debug); |
| 202 | ResumeEmulation(active_thread); | ||
| 203 | }); | ||
| 206 | break; | 204 | break; |
| 207 | case DebuggerAction::StepThreadLocked: | 205 | case DebuggerAction::StepThreadLocked: { |
| 208 | active_thread->SetStepState(Kernel::StepState::StepPending); | 206 | MarkResumed([&] { |
| 209 | SuspendInactiveThreads(); | 207 | active_thread->SetStepState(Kernel::StepState::StepPending); |
| 210 | AllCoreResume(); | 208 | active_thread->Resume(Kernel::SuspendType::Debug); |
| 209 | }); | ||
| 211 | break; | 210 | break; |
| 211 | } | ||
| 212 | case DebuggerAction::ShutdownEmulation: { | 212 | case DebuggerAction::ShutdownEmulation: { |
| 213 | // Suspend all threads and release any locks held | ||
| 214 | active_thread->RequestSuspend(Kernel::SuspendType::Debug); | ||
| 215 | SuspendInactiveThreads(); | ||
| 216 | AllCoreResume(); | ||
| 217 | |||
| 218 | // Spawn another thread that will exit after shutdown, | 213 | // Spawn another thread that will exit after shutdown, |
| 219 | // to avoid a deadlock | 214 | // to avoid a deadlock |
| 220 | Core::System* system_ref{&system}; | 215 | Core::System* system_ref{&system}; |
| @@ -226,33 +221,33 @@ private: | |||
| 226 | } | 221 | } |
| 227 | } | 222 | } |
| 228 | 223 | ||
| 229 | void AllCoreStop() { | 224 | void PauseEmulation() { |
| 230 | if (!suspend) { | 225 | // Put all threads to sleep on next scheduler round. |
| 231 | suspend = system.StallCPU(); | 226 | for (auto* thread : ThreadList()) { |
| 227 | thread->RequestSuspend(Kernel::SuspendType::Debug); | ||
| 232 | } | 228 | } |
| 233 | } | ||
| 234 | 229 | ||
| 235 | void AllCoreResume() { | 230 | // Signal an interrupt so that scheduler will fire. |
| 236 | stopped = false; | 231 | system.Kernel().InterruptAllPhysicalCores(); |
| 237 | system.UnstallCPU(); | ||
| 238 | suspend.reset(); | ||
| 239 | } | 232 | } |
| 240 | 233 | ||
| 241 | void SuspendInactiveThreads() { | 234 | void ResumeEmulation(Kernel::KThread* except = nullptr) { |
| 235 | // Wake up all threads. | ||
| 242 | for (auto* thread : ThreadList()) { | 236 | for (auto* thread : ThreadList()) { |
| 243 | if (thread != active_thread) { | 237 | if (thread == except) { |
| 244 | thread->RequestSuspend(Kernel::SuspendType::Debug); | 238 | continue; |
| 245 | } | 239 | } |
| 240 | |||
| 241 | thread->SetStepState(Kernel::StepState::NotStepping); | ||
| 242 | thread->Resume(Kernel::SuspendType::Debug); | ||
| 246 | } | 243 | } |
| 247 | } | 244 | } |
| 248 | 245 | ||
| 249 | void ResumeInactiveThreads() { | 246 | template <typename Callback> |
| 250 | for (auto* thread : ThreadList()) { | 247 | void MarkResumed(Callback&& cb) { |
| 251 | if (thread != active_thread) { | 248 | std::scoped_lock lk{connection_lock}; |
| 252 | thread->Resume(Kernel::SuspendType::Debug); | 249 | stopped = false; |
| 253 | thread->SetStepState(Kernel::StepState::NotStepping); | 250 | cb(); |
| 254 | } | ||
| 255 | } | ||
| 256 | } | 251 | } |
| 257 | 252 | ||
| 258 | void UpdateActiveThread() { | 253 | void UpdateActiveThread() { |
| @@ -260,8 +255,6 @@ private: | |||
| 260 | if (std::find(threads.begin(), threads.end(), active_thread) == threads.end()) { | 255 | if (std::find(threads.begin(), threads.end(), active_thread) == threads.end()) { |
| 261 | active_thread = threads[0]; | 256 | active_thread = threads[0]; |
| 262 | } | 257 | } |
| 263 | active_thread->Resume(Kernel::SuspendType::Debug); | ||
| 264 | active_thread->SetStepState(Kernel::StepState::NotStepping); | ||
| 265 | } | 258 | } |
| 266 | 259 | ||
| 267 | const std::vector<Kernel::KThread*>& ThreadList() { | 260 | const std::vector<Kernel::KThread*>& ThreadList() { |
| @@ -277,7 +270,6 @@ private: | |||
| 277 | boost::asio::io_context io_context; | 270 | boost::asio::io_context io_context; |
| 278 | boost::process::async_pipe signal_pipe; | 271 | boost::process::async_pipe signal_pipe; |
| 279 | boost::asio::ip::tcp::socket client_socket; | 272 | boost::asio::ip::tcp::socket client_socket; |
| 280 | std::optional<std::unique_lock<std::mutex>> suspend; | ||
| 281 | 273 | ||
| 282 | SignalInfo info; | 274 | SignalInfo info; |
| 283 | Kernel::KThread* active_thread; | 275 | Kernel::KThread* active_thread; |
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 8c79b4f0f..cd863e715 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp | |||
| @@ -275,11 +275,15 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a | |||
| 275 | shmem->Close(); | 275 | shmem->Close(); |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | void KProcess::RegisterThread(const KThread* thread) { | 278 | void KProcess::RegisterThread(KThread* thread) { |
| 279 | KScopedLightLock lk{list_lock}; | ||
| 280 | |||
| 279 | thread_list.push_back(thread); | 281 | thread_list.push_back(thread); |
| 280 | } | 282 | } |
| 281 | 283 | ||
| 282 | void KProcess::UnregisterThread(const KThread* thread) { | 284 | void KProcess::UnregisterThread(KThread* thread) { |
| 285 | KScopedLightLock lk{list_lock}; | ||
| 286 | |||
| 283 | thread_list.remove(thread); | 287 | thread_list.remove(thread); |
| 284 | } | 288 | } |
| 285 | 289 | ||
| @@ -297,6 +301,50 @@ ResultCode KProcess::Reset() { | |||
| 297 | return ResultSuccess; | 301 | return ResultSuccess; |
| 298 | } | 302 | } |
| 299 | 303 | ||
| 304 | ResultCode KProcess::SetActivity(ProcessActivity activity) { | ||
| 305 | // Lock ourselves and the scheduler. | ||
| 306 | KScopedLightLock lk{state_lock}; | ||
| 307 | KScopedLightLock list_lk{list_lock}; | ||
| 308 | KScopedSchedulerLock sl{kernel}; | ||
| 309 | |||
| 310 | // Validate our state. | ||
| 311 | R_UNLESS(status != ProcessStatus::Exiting, ResultInvalidState); | ||
| 312 | R_UNLESS(status != ProcessStatus::Exited, ResultInvalidState); | ||
| 313 | |||
| 314 | // Either pause or resume. | ||
| 315 | if (activity == ProcessActivity::Paused) { | ||
| 316 | // Verify that we're not suspended. | ||
| 317 | if (is_suspended) { | ||
| 318 | return ResultInvalidState; | ||
| 319 | } | ||
| 320 | |||
| 321 | // Suspend all threads. | ||
| 322 | for (auto* thread : GetThreadList()) { | ||
| 323 | thread->RequestSuspend(SuspendType::Process); | ||
| 324 | } | ||
| 325 | |||
| 326 | // Set ourselves as suspended. | ||
| 327 | SetSuspended(true); | ||
| 328 | } else { | ||
| 329 | ASSERT(activity == ProcessActivity::Runnable); | ||
| 330 | |||
| 331 | // Verify that we're suspended. | ||
| 332 | if (!is_suspended) { | ||
| 333 | return ResultInvalidState; | ||
| 334 | } | ||
| 335 | |||
| 336 | // Resume all threads. | ||
| 337 | for (auto* thread : GetThreadList()) { | ||
| 338 | thread->Resume(SuspendType::Process); | ||
| 339 | } | ||
| 340 | |||
| 341 | // Set ourselves as resumed. | ||
| 342 | SetSuspended(false); | ||
| 343 | } | ||
| 344 | |||
| 345 | return ResultSuccess; | ||
| 346 | } | ||
| 347 | |||
| 300 | ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | 348 | ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, |
| 301 | std::size_t code_size) { | 349 | std::size_t code_size) { |
| 302 | program_id = metadata.GetTitleID(); | 350 | program_id = metadata.GetTitleID(); |
| @@ -556,9 +604,10 @@ bool KProcess::IsSignaled() const { | |||
| 556 | } | 604 | } |
| 557 | 605 | ||
| 558 | KProcess::KProcess(KernelCore& kernel_) | 606 | KProcess::KProcess(KernelCore& kernel_) |
| 559 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, | 607 | : KAutoObjectWithSlabHeapAndContainer{kernel_}, page_table{std::make_unique<KPageTable>( |
| 560 | page_table{std::make_unique<KPageTable>(kernel_.System())}, handle_table{kernel_}, | 608 | kernel_.System())}, |
| 561 | address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, state_lock{kernel_} {} | 609 | handle_table{kernel_}, address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, |
| 610 | state_lock{kernel_}, list_lock{kernel_} {} | ||
| 562 | 611 | ||
| 563 | KProcess::~KProcess() = default; | 612 | KProcess::~KProcess() = default; |
| 564 | 613 | ||
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 9f171e3da..e562a79b8 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h | |||
| @@ -63,6 +63,11 @@ enum class ProcessStatus { | |||
| 63 | DebugBreak, | 63 | DebugBreak, |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | enum class ProcessActivity : u32 { | ||
| 67 | Runnable, | ||
| 68 | Paused, | ||
| 69 | }; | ||
| 70 | |||
| 66 | class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> { | 71 | class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> { |
| 67 | KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); | 72 | KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); |
| 68 | 73 | ||
| @@ -282,17 +287,17 @@ public: | |||
| 282 | u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; | 287 | u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; |
| 283 | 288 | ||
| 284 | /// Gets the list of all threads created with this process as their owner. | 289 | /// Gets the list of all threads created with this process as their owner. |
| 285 | const std::list<const KThread*>& GetThreadList() const { | 290 | std::list<KThread*>& GetThreadList() { |
| 286 | return thread_list; | 291 | return thread_list; |
| 287 | } | 292 | } |
| 288 | 293 | ||
| 289 | /// Registers a thread as being created under this process, | 294 | /// Registers a thread as being created under this process, |
| 290 | /// adding it to this process' thread list. | 295 | /// adding it to this process' thread list. |
| 291 | void RegisterThread(const KThread* thread); | 296 | void RegisterThread(KThread* thread); |
| 292 | 297 | ||
| 293 | /// Unregisters a thread from this process, removing it | 298 | /// Unregisters a thread from this process, removing it |
| 294 | /// from this process' thread list. | 299 | /// from this process' thread list. |
| 295 | void UnregisterThread(const KThread* thread); | 300 | void UnregisterThread(KThread* thread); |
| 296 | 301 | ||
| 297 | /// Clears the signaled state of the process if and only if it's signaled. | 302 | /// Clears the signaled state of the process if and only if it's signaled. |
| 298 | /// | 303 | /// |
| @@ -347,6 +352,8 @@ public: | |||
| 347 | 352 | ||
| 348 | void DoWorkerTaskImpl(); | 353 | void DoWorkerTaskImpl(); |
| 349 | 354 | ||
| 355 | ResultCode SetActivity(ProcessActivity activity); | ||
| 356 | |||
| 350 | void PinCurrentThread(s32 core_id); | 357 | void PinCurrentThread(s32 core_id); |
| 351 | void UnpinCurrentThread(s32 core_id); | 358 | void UnpinCurrentThread(s32 core_id); |
| 352 | void UnpinThread(KThread* thread); | 359 | void UnpinThread(KThread* thread); |
| @@ -442,7 +449,7 @@ private: | |||
| 442 | std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{}; | 449 | std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{}; |
| 443 | 450 | ||
| 444 | /// List of threads that are running with this process as their owner. | 451 | /// List of threads that are running with this process as their owner. |
| 445 | std::list<const KThread*> thread_list; | 452 | std::list<KThread*> thread_list; |
| 446 | 453 | ||
| 447 | /// List of shared memory that are running with this process as their owner. | 454 | /// List of shared memory that are running with this process as their owner. |
| 448 | std::list<KSharedMemoryInfo*> shared_memory_list; | 455 | std::list<KSharedMemoryInfo*> shared_memory_list; |
| @@ -475,6 +482,7 @@ private: | |||
| 475 | KThread* exception_thread{}; | 482 | KThread* exception_thread{}; |
| 476 | 483 | ||
| 477 | KLightLock state_lock; | 484 | KLightLock state_lock; |
| 485 | KLightLock list_lock; | ||
| 478 | 486 | ||
| 479 | using TLPTree = | 487 | using TLPTree = |
| 480 | Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>; | 488 | Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>; |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index ea2160099..8d48a7901 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -267,15 +267,15 @@ ResultCode KThread::InitializeDummyThread(KThread* thread) { | |||
| 267 | ResultCode KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) { | 267 | ResultCode KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) { |
| 268 | return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, | 268 | return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, |
| 269 | Core::CpuManager::GetIdleThreadStartFunc(), | 269 | Core::CpuManager::GetIdleThreadStartFunc(), |
| 270 | system.GetCpuManager().GetStartFuncParamater()); | 270 | system.GetCpuManager().GetStartFuncParameter()); |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | ResultCode KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, | 273 | ResultCode KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, |
| 274 | KThreadFunction func, uintptr_t arg, | 274 | KThreadFunction func, uintptr_t arg, |
| 275 | s32 virt_core) { | 275 | s32 virt_core) { |
| 276 | return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority, | 276 | return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority, |
| 277 | Core::CpuManager::GetSuspendThreadStartFunc(), | 277 | Core::CpuManager::GetShutdownThreadStartFunc(), |
| 278 | system.GetCpuManager().GetStartFuncParamater()); | 278 | system.GetCpuManager().GetStartFuncParameter()); |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, | 281 | ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, |
| @@ -284,7 +284,7 @@ ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, | |||
| 284 | system.Kernel().GlobalSchedulerContext().AddThread(thread); | 284 | system.Kernel().GlobalSchedulerContext().AddThread(thread); |
| 285 | return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, | 285 | return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, |
| 286 | ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(), | 286 | ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(), |
| 287 | system.GetCpuManager().GetStartFuncParamater()); | 287 | system.GetCpuManager().GetStartFuncParameter()); |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | void KThread::PostDestroy(uintptr_t arg) { | 290 | void KThread::PostDestroy(uintptr_t arg) { |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b2c4f12b4..73593c7a0 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -76,7 +76,7 @@ struct KernelCore::Impl { | |||
| 76 | InitializeMemoryLayout(); | 76 | InitializeMemoryLayout(); |
| 77 | Init::InitializeKPageBufferSlabHeap(system); | 77 | Init::InitializeKPageBufferSlabHeap(system); |
| 78 | InitializeSchedulers(); | 78 | InitializeSchedulers(); |
| 79 | InitializeSuspendThreads(); | 79 | InitializeShutdownThreads(); |
| 80 | InitializePreemption(kernel); | 80 | InitializePreemption(kernel); |
| 81 | 81 | ||
| 82 | RegisterHostThread(); | 82 | RegisterHostThread(); |
| @@ -143,9 +143,9 @@ struct KernelCore::Impl { | |||
| 143 | CleanupObject(system_resource_limit); | 143 | CleanupObject(system_resource_limit); |
| 144 | 144 | ||
| 145 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 145 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 146 | if (suspend_threads[core_id]) { | 146 | if (shutdown_threads[core_id]) { |
| 147 | suspend_threads[core_id]->Close(); | 147 | shutdown_threads[core_id]->Close(); |
| 148 | suspend_threads[core_id] = nullptr; | 148 | shutdown_threads[core_id] = nullptr; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | schedulers[core_id]->Finalize(); | 151 | schedulers[core_id]->Finalize(); |
| @@ -247,14 +247,14 @@ struct KernelCore::Impl { | |||
| 247 | system.CoreTiming().ScheduleEvent(time_interval, preemption_event); | 247 | system.CoreTiming().ScheduleEvent(time_interval, preemption_event); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | void InitializeSuspendThreads() { | 250 | void InitializeShutdownThreads() { |
| 251 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 251 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { |
| 252 | suspend_threads[core_id] = KThread::Create(system.Kernel()); | 252 | shutdown_threads[core_id] = KThread::Create(system.Kernel()); |
| 253 | ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, | 253 | ASSERT(KThread::InitializeHighPriorityThread(system, shutdown_threads[core_id], {}, {}, |
| 254 | core_id) | 254 | core_id) |
| 255 | .IsSuccess()); | 255 | .IsSuccess()); |
| 256 | suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); | 256 | shutdown_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); |
| 257 | suspend_threads[core_id]->DisableDispatch(); | 257 | shutdown_threads[core_id]->DisableDispatch(); |
| 258 | } | 258 | } |
| 259 | } | 259 | } |
| 260 | 260 | ||
| @@ -769,7 +769,7 @@ struct KernelCore::Impl { | |||
| 769 | std::weak_ptr<ServiceThread> default_service_thread; | 769 | std::weak_ptr<ServiceThread> default_service_thread; |
| 770 | Common::ThreadWorker service_threads_manager; | 770 | Common::ThreadWorker service_threads_manager; |
| 771 | 771 | ||
| 772 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; | 772 | std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads; |
| 773 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; | 773 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; |
| 774 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; | 774 | std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; |
| 775 | 775 | ||
| @@ -920,6 +920,12 @@ const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { | |||
| 920 | return *impl->global_object_list_container; | 920 | return *impl->global_object_list_container; |
| 921 | } | 921 | } |
| 922 | 922 | ||
| 923 | void KernelCore::InterruptAllPhysicalCores() { | ||
| 924 | for (auto& physical_core : impl->cores) { | ||
| 925 | physical_core.Interrupt(); | ||
| 926 | } | ||
| 927 | } | ||
| 928 | |||
| 923 | void KernelCore::InvalidateAllInstructionCaches() { | 929 | void KernelCore::InvalidateAllInstructionCaches() { |
| 924 | for (auto& physical_core : impl->cores) { | 930 | for (auto& physical_core : impl->cores) { |
| 925 | physical_core.ArmInterface().ClearInstructionCache(); | 931 | physical_core.ArmInterface().ClearInstructionCache(); |
| @@ -1067,17 +1073,20 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const { | |||
| 1067 | return *impl->hidbus_shared_mem; | 1073 | return *impl->hidbus_shared_mem; |
| 1068 | } | 1074 | } |
| 1069 | 1075 | ||
| 1070 | void KernelCore::Suspend(bool in_suspention) { | 1076 | void KernelCore::Suspend(bool suspended) { |
| 1071 | const bool should_suspend = exception_exited || in_suspention; | 1077 | const bool should_suspend{exception_exited || suspended}; |
| 1072 | { | 1078 | const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; |
| 1073 | KScopedSchedulerLock lock(*this); | 1079 | |
| 1074 | const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; | 1080 | for (auto* process : GetProcessList()) { |
| 1075 | for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { | 1081 | process->SetActivity(activity); |
| 1076 | impl->suspend_threads[core_id]->SetState(state); | 1082 | } |
| 1077 | impl->suspend_threads[core_id]->SetWaitReasonForDebugging( | 1083 | } |
| 1078 | ThreadWaitReasonForDebugging::Suspended); | 1084 | |
| 1079 | } | 1085 | void KernelCore::ShutdownCores() { |
| 1086 | for (auto* thread : impl->shutdown_threads) { | ||
| 1087 | void(thread->Run()); | ||
| 1080 | } | 1088 | } |
| 1089 | InterruptAllPhysicalCores(); | ||
| 1081 | } | 1090 | } |
| 1082 | 1091 | ||
| 1083 | bool KernelCore::IsMulticore() const { | 1092 | bool KernelCore::IsMulticore() const { |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 926e14c6f..4e7beab0e 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -184,6 +184,8 @@ public: | |||
| 184 | 184 | ||
| 185 | const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const; | 185 | const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const; |
| 186 | 186 | ||
| 187 | void InterruptAllPhysicalCores(); | ||
| 188 | |||
| 187 | void InvalidateAllInstructionCaches(); | 189 | void InvalidateAllInstructionCaches(); |
| 188 | 190 | ||
| 189 | void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); | 191 | void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); |
| @@ -269,12 +271,15 @@ public: | |||
| 269 | /// Gets the shared memory object for HIDBus services. | 271 | /// Gets the shared memory object for HIDBus services. |
| 270 | const Kernel::KSharedMemory& GetHidBusSharedMem() const; | 272 | const Kernel::KSharedMemory& GetHidBusSharedMem() const; |
| 271 | 273 | ||
| 272 | /// Suspend/unsuspend the OS. | 274 | /// Suspend/unsuspend all processes. |
| 273 | void Suspend(bool in_suspention); | 275 | void Suspend(bool suspend); |
| 274 | 276 | ||
| 275 | /// Exceptional exit the OS. | 277 | /// Exceptional exit all processes. |
| 276 | void ExceptionalExit(); | 278 | void ExceptionalExit(); |
| 277 | 279 | ||
| 280 | /// Notify emulated CPU cores to shut down. | ||
| 281 | void ShutdownCores(); | ||
| 282 | |||
| 278 | bool IsMulticore() const; | 283 | bool IsMulticore() const; |
| 279 | 284 | ||
| 280 | bool IsShuttingDown() const; | 285 | bool IsShuttingDown() const; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 584fa5b1c..2ff6d5fa6 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "common/scope_exit.h" | 15 | #include "common/scope_exit.h" |
| 16 | #include "core/core.h" | 16 | #include "core/core.h" |
| 17 | #include "core/core_timing.h" | 17 | #include "core/core_timing.h" |
| 18 | #include "core/debugger/debugger.h" | ||
| 18 | #include "core/hle/kernel/k_client_port.h" | 19 | #include "core/hle/kernel/k_client_port.h" |
| 19 | #include "core/hle/kernel/k_client_session.h" | 20 | #include "core/hle/kernel/k_client_session.h" |
| 20 | #include "core/hle/kernel/k_code_memory.h" | 21 | #include "core/hle/kernel/k_code_memory.h" |
| @@ -627,6 +628,12 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 627 | const auto thread_processor_id = current_thread->GetActiveCore(); | 628 | const auto thread_processor_id = current_thread->GetActiveCore(); |
| 628 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); | 629 | system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); |
| 629 | } | 630 | } |
| 631 | |||
| 632 | if (system.DebuggerEnabled()) { | ||
| 633 | auto* thread = system.Kernel().GetCurrentEmuThread(); | ||
| 634 | system.GetDebugger().NotifyThreadStopped(thread); | ||
| 635 | thread->RequestSuspend(Kernel::SuspendType::Debug); | ||
| 636 | } | ||
| 630 | } | 637 | } |
| 631 | 638 | ||
| 632 | static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { | 639 | static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { |
| @@ -1719,11 +1726,12 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha | |||
| 1719 | /// Exits the current process | 1726 | /// Exits the current process |
| 1720 | static void ExitProcess(Core::System& system) { | 1727 | static void ExitProcess(Core::System& system) { |
| 1721 | auto* current_process = system.Kernel().CurrentProcess(); | 1728 | auto* current_process = system.Kernel().CurrentProcess(); |
| 1722 | UNIMPLEMENTED(); | ||
| 1723 | 1729 | ||
| 1724 | LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); | 1730 | LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); |
| 1725 | ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, | 1731 | ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, |
| 1726 | "Process has already exited"); | 1732 | "Process has already exited"); |
| 1733 | |||
| 1734 | system.Exit(); | ||
| 1727 | } | 1735 | } |
| 1728 | 1736 | ||
| 1729 | static void ExitProcess32(Core::System& system) { | 1737 | static void ExitProcess32(Core::System& system) { |
| @@ -2530,7 +2538,7 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd | |||
| 2530 | return ResultOutOfRange; | 2538 | return ResultOutOfRange; |
| 2531 | } | 2539 | } |
| 2532 | 2540 | ||
| 2533 | const auto* const current_process = system.Kernel().CurrentProcess(); | 2541 | auto* const current_process = system.Kernel().CurrentProcess(); |
| 2534 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); | 2542 | const auto total_copy_size = out_thread_ids_size * sizeof(u64); |
| 2535 | 2543 | ||
| 2536 | if (out_thread_ids_size > 0 && | 2544 | if (out_thread_ids_size > 0 && |
| @@ -2982,7 +2990,6 @@ static const FunctionDef* GetSVCInfo64(u32 func_num) { | |||
| 2982 | } | 2990 | } |
| 2983 | 2991 | ||
| 2984 | void Call(Core::System& system, u32 immediate) { | 2992 | void Call(Core::System& system, u32 immediate) { |
| 2985 | system.ExitDynarmicProfile(); | ||
| 2986 | auto& kernel = system.Kernel(); | 2993 | auto& kernel = system.Kernel(); |
| 2987 | kernel.EnterSVCProfile(); | 2994 | kernel.EnterSVCProfile(); |
| 2988 | 2995 | ||
| @@ -3007,8 +3014,6 @@ void Call(Core::System& system, u32 immediate) { | |||
| 3007 | auto* host_context = thread->GetHostContext().get(); | 3014 | auto* host_context = thread->GetHostContext().get(); |
| 3008 | host_context->Rewind(); | 3015 | host_context->Rewind(); |
| 3009 | } | 3016 | } |
| 3010 | |||
| 3011 | system.EnterDynarmicProfile(); | ||
| 3012 | } | 3017 | } |
| 3013 | 3018 | ||
| 3014 | } // namespace Kernel::Svc | 3019 | } // namespace Kernel::Svc |
diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp index b971846e7..3ace2dabd 100644 --- a/src/core/hle/service/glue/notif.cpp +++ b/src/core/hle/service/glue/notif.cpp | |||
| @@ -1,6 +1,11 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include <algorithm> | ||
| 5 | #include <cstring> | ||
| 6 | |||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 4 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 5 | #include "core/hle/service/glue/notif.h" | 10 | #include "core/hle/service/glue/notif.h" |
| 6 | 11 | ||
| @@ -9,11 +14,11 @@ namespace Service::Glue { | |||
| 9 | NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { | 14 | NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { |
| 10 | // clang-format off | 15 | // clang-format off |
| 11 | static const FunctionInfo functions[] = { | 16 | static const FunctionInfo functions[] = { |
| 12 | {500, nullptr, "RegisterAlarmSetting"}, | 17 | {500, &NOTIF_A::RegisterAlarmSetting, "RegisterAlarmSetting"}, |
| 13 | {510, nullptr, "UpdateAlarmSetting"}, | 18 | {510, &NOTIF_A::UpdateAlarmSetting, "UpdateAlarmSetting"}, |
| 14 | {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"}, | 19 | {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"}, |
| 15 | {530, nullptr, "LoadApplicationParameter"}, | 20 | {530, &NOTIF_A::LoadApplicationParameter, "LoadApplicationParameter"}, |
| 16 | {540, nullptr, "DeleteAlarmSetting"}, | 21 | {540, &NOTIF_A::DeleteAlarmSetting, "DeleteAlarmSetting"}, |
| 17 | {1000, &NOTIF_A::Initialize, "Initialize"}, | 22 | {1000, &NOTIF_A::Initialize, "Initialize"}, |
| 18 | }; | 23 | }; |
| 19 | // clang-format on | 24 | // clang-format on |
| @@ -23,21 +28,132 @@ NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { | |||
| 23 | 28 | ||
| 24 | NOTIF_A::~NOTIF_A() = default; | 29 | NOTIF_A::~NOTIF_A() = default; |
| 25 | 30 | ||
| 31 | void NOTIF_A::RegisterAlarmSetting(Kernel::HLERequestContext& ctx) { | ||
| 32 | const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); | ||
| 33 | const auto application_parameter_size = ctx.GetReadBufferSize(1); | ||
| 34 | |||
| 35 | ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting), | ||
| 36 | "alarm_setting_buffer_size is not 0x40 bytes"); | ||
| 37 | ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter), | ||
| 38 | "application_parameter_size is bigger than 0x400 bytes"); | ||
| 39 | |||
| 40 | AlarmSetting new_alarm{}; | ||
| 41 | memcpy(&new_alarm, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting)); | ||
| 42 | |||
| 43 | // TODO: Count alarms per game id | ||
| 44 | if (alarms.size() >= max_alarms) { | ||
| 45 | LOG_ERROR(Service_NOTIF, "Alarm limit reached"); | ||
| 46 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 47 | rb.Push(ResultUnknown); | ||
| 48 | return; | ||
| 49 | } | ||
| 50 | |||
| 51 | new_alarm.alarm_setting_id = last_alarm_setting_id++; | ||
| 52 | alarms.push_back(new_alarm); | ||
| 53 | |||
| 54 | // TODO: Save application parameter data | ||
| 55 | |||
| 56 | LOG_WARNING(Service_NOTIF, | ||
| 57 | "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", | ||
| 58 | application_parameter_size, new_alarm.alarm_setting_id, new_alarm.kind, | ||
| 59 | new_alarm.muted); | ||
| 60 | |||
| 61 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 62 | rb.Push(ResultSuccess); | ||
| 63 | rb.Push(new_alarm.alarm_setting_id); | ||
| 64 | } | ||
| 65 | |||
| 66 | void NOTIF_A::UpdateAlarmSetting(Kernel::HLERequestContext& ctx) { | ||
| 67 | const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); | ||
| 68 | const auto application_parameter_size = ctx.GetReadBufferSize(1); | ||
| 69 | |||
| 70 | ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting), | ||
| 71 | "alarm_setting_buffer_size is not 0x40 bytes"); | ||
| 72 | ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter), | ||
| 73 | "application_parameter_size is bigger than 0x400 bytes"); | ||
| 74 | |||
| 75 | AlarmSetting alarm_setting{}; | ||
| 76 | memcpy(&alarm_setting, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting)); | ||
| 77 | |||
| 78 | const auto alarm_it = GetAlarmFromId(alarm_setting.alarm_setting_id); | ||
| 79 | if (alarm_it != alarms.end()) { | ||
| 80 | LOG_DEBUG(Service_NOTIF, "Alarm updated"); | ||
| 81 | *alarm_it = alarm_setting; | ||
| 82 | // TODO: Save application parameter data | ||
| 83 | } | ||
| 84 | |||
| 85 | LOG_WARNING(Service_NOTIF, | ||
| 86 | "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", | ||
| 87 | application_parameter_size, alarm_setting.alarm_setting_id, alarm_setting.kind, | ||
| 88 | alarm_setting.muted); | ||
| 89 | |||
| 90 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 91 | rb.Push(ResultSuccess); | ||
| 92 | } | ||
| 93 | |||
| 26 | void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) { | 94 | void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) { |
| 27 | // Returns an array of AlarmSetting | 95 | LOG_INFO(Service_NOTIF, "called, alarm_count={}", alarms.size()); |
| 28 | constexpr s32 alarm_count = 0; | ||
| 29 | 96 | ||
| 30 | LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | 97 | // TODO: Only return alarms of this game id |
| 98 | ctx.WriteBuffer(alarms); | ||
| 31 | 99 | ||
| 32 | IPC::ResponseBuilder rb{ctx, 3}; | 100 | IPC::ResponseBuilder rb{ctx, 3}; |
| 33 | rb.Push(ResultSuccess); | 101 | rb.Push(ResultSuccess); |
| 34 | rb.Push(alarm_count); | 102 | rb.Push(static_cast<u32>(alarms.size())); |
| 103 | } | ||
| 104 | |||
| 105 | void NOTIF_A::LoadApplicationParameter(Kernel::HLERequestContext& ctx) { | ||
| 106 | IPC::RequestParser rp{ctx}; | ||
| 107 | const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; | ||
| 108 | |||
| 109 | const auto alarm_it = GetAlarmFromId(alarm_setting_id); | ||
| 110 | if (alarm_it == alarms.end()) { | ||
| 111 | LOG_ERROR(Service_NOTIF, "Invalid alarm setting id={}", alarm_setting_id); | ||
| 112 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 113 | rb.Push(ResultUnknown); | ||
| 114 | return; | ||
| 115 | } | ||
| 116 | |||
| 117 | // TODO: Read application parameter related to this setting id | ||
| 118 | ApplicationParameter application_parameter{}; | ||
| 119 | |||
| 120 | LOG_WARNING(Service_NOTIF, "(STUBBED) called, alarm_setting_id={}", alarm_setting_id); | ||
| 121 | |||
| 122 | ctx.WriteBuffer(application_parameter); | ||
| 123 | |||
| 124 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 125 | rb.Push(ResultSuccess); | ||
| 126 | rb.Push(static_cast<u32>(application_parameter.size())); | ||
| 127 | } | ||
| 128 | |||
| 129 | void NOTIF_A::DeleteAlarmSetting(Kernel::HLERequestContext& ctx) { | ||
| 130 | IPC::RequestParser rp{ctx}; | ||
| 131 | const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; | ||
| 132 | |||
| 133 | std::erase_if(alarms, [alarm_setting_id](const AlarmSetting& alarm) { | ||
| 134 | return alarm.alarm_setting_id == alarm_setting_id; | ||
| 135 | }); | ||
| 136 | |||
| 137 | LOG_INFO(Service_NOTIF, "called, alarm_setting_id={}", alarm_setting_id); | ||
| 138 | |||
| 139 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 140 | rb.Push(ResultSuccess); | ||
| 35 | } | 141 | } |
| 36 | 142 | ||
| 37 | void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) { | 143 | void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) { |
| 144 | // TODO: Load previous alarms from config | ||
| 145 | |||
| 38 | LOG_WARNING(Service_NOTIF, "(STUBBED) called"); | 146 | LOG_WARNING(Service_NOTIF, "(STUBBED) called"); |
| 39 | IPC::ResponseBuilder rb{ctx, 2}; | 147 | IPC::ResponseBuilder rb{ctx, 2}; |
| 40 | rb.Push(ResultSuccess); | 148 | rb.Push(ResultSuccess); |
| 41 | } | 149 | } |
| 42 | 150 | ||
| 151 | std::vector<NOTIF_A::AlarmSetting>::iterator NOTIF_A::GetAlarmFromId( | ||
| 152 | AlarmSettingId alarm_setting_id) { | ||
| 153 | return std::find_if(alarms.begin(), alarms.end(), | ||
| 154 | [alarm_setting_id](const AlarmSetting& alarm) { | ||
| 155 | return alarm.alarm_setting_id == alarm_setting_id; | ||
| 156 | }); | ||
| 157 | } | ||
| 158 | |||
| 43 | } // namespace Service::Glue | 159 | } // namespace Service::Glue |
diff --git a/src/core/hle/service/glue/notif.h b/src/core/hle/service/glue/notif.h index 7310d7f72..4467e1f35 100644 --- a/src/core/hle/service/glue/notif.h +++ b/src/core/hle/service/glue/notif.h | |||
| @@ -3,6 +3,10 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <array> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "common/uuid.h" | ||
| 6 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 7 | 11 | ||
| 8 | namespace Core { | 12 | namespace Core { |
| @@ -17,8 +21,52 @@ public: | |||
| 17 | ~NOTIF_A() override; | 21 | ~NOTIF_A() override; |
| 18 | 22 | ||
| 19 | private: | 23 | private: |
| 24 | static constexpr std::size_t max_alarms = 8; | ||
| 25 | |||
| 26 | // This is nn::notification::AlarmSettingId | ||
| 27 | using AlarmSettingId = u16; | ||
| 28 | static_assert(sizeof(AlarmSettingId) == 0x2, "AlarmSettingId is an invalid size"); | ||
| 29 | |||
| 30 | using ApplicationParameter = std::array<u8, 0x400>; | ||
| 31 | static_assert(sizeof(ApplicationParameter) == 0x400, "ApplicationParameter is an invalid size"); | ||
| 32 | |||
| 33 | struct DailyAlarmSetting { | ||
| 34 | s8 hour; | ||
| 35 | s8 minute; | ||
| 36 | }; | ||
| 37 | static_assert(sizeof(DailyAlarmSetting) == 0x2, "DailyAlarmSetting is an invalid size"); | ||
| 38 | |||
| 39 | struct WeeklyScheduleAlarmSetting { | ||
| 40 | INSERT_PADDING_BYTES(0xA); | ||
| 41 | std::array<DailyAlarmSetting, 0x7> day_of_week; | ||
| 42 | }; | ||
| 43 | static_assert(sizeof(WeeklyScheduleAlarmSetting) == 0x18, | ||
| 44 | "WeeklyScheduleAlarmSetting is an invalid size"); | ||
| 45 | |||
| 46 | // This is nn::notification::AlarmSetting | ||
| 47 | struct AlarmSetting { | ||
| 48 | AlarmSettingId alarm_setting_id; | ||
| 49 | u8 kind; | ||
| 50 | u8 muted; | ||
| 51 | INSERT_PADDING_BYTES(0x4); | ||
| 52 | Common::UUID account_id; | ||
| 53 | u64 application_id; | ||
| 54 | INSERT_PADDING_BYTES(0x8); | ||
| 55 | WeeklyScheduleAlarmSetting schedule; | ||
| 56 | }; | ||
| 57 | static_assert(sizeof(AlarmSetting) == 0x40, "AlarmSetting is an invalid size"); | ||
| 58 | |||
| 59 | void RegisterAlarmSetting(Kernel::HLERequestContext& ctx); | ||
| 60 | void UpdateAlarmSetting(Kernel::HLERequestContext& ctx); | ||
| 20 | void ListAlarmSettings(Kernel::HLERequestContext& ctx); | 61 | void ListAlarmSettings(Kernel::HLERequestContext& ctx); |
| 62 | void LoadApplicationParameter(Kernel::HLERequestContext& ctx); | ||
| 63 | void DeleteAlarmSetting(Kernel::HLERequestContext& ctx); | ||
| 21 | void Initialize(Kernel::HLERequestContext& ctx); | 64 | void Initialize(Kernel::HLERequestContext& ctx); |
| 65 | |||
| 66 | std::vector<AlarmSetting>::iterator GetAlarmFromId(AlarmSettingId alarm_setting_id); | ||
| 67 | |||
| 68 | std::vector<AlarmSetting> alarms{}; | ||
| 69 | AlarmSettingId last_alarm_setting_id{}; | ||
| 22 | }; | 70 | }; |
| 23 | 71 | ||
| 24 | } // namespace Service::Glue | 72 | } // namespace Service::Glue |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 705fefc83..527531f29 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -150,9 +150,9 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector | |||
| 150 | event.event->GetWritableEvent().Clear(); | 150 | event.event->GetWritableEvent().Clear(); |
| 151 | if (events_interface.failed[event_id]) { | 151 | if (events_interface.failed[event_id]) { |
| 152 | { | 152 | { |
| 153 | auto lk = system.StallCPU(); | 153 | auto lk = system.StallProcesses(); |
| 154 | gpu.WaitFence(params.syncpt_id, target_value); | 154 | gpu.WaitFence(params.syncpt_id, target_value); |
| 155 | system.UnstallCPU(); | 155 | system.UnstallProcesses(); |
| 156 | } | 156 | } |
| 157 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 157 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 158 | events_interface.failed[event_id] = false; | 158 | events_interface.failed[event_id] = false; |
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index d4fa69a77..48e799cf5 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt | |||
| @@ -44,7 +44,6 @@ else() | |||
| 44 | -Werror | 44 | -Werror |
| 45 | -Werror=conversion | 45 | -Werror=conversion |
| 46 | -Werror=ignored-qualifiers | 46 | -Werror=ignored-qualifiers |
| 47 | -Werror=shadow | ||
| 48 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 47 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
| 49 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> | 48 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> |
| 50 | -Werror=unused-variable | 49 | -Werror=unused-variable |
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 4c76ce1ea..ae1dbe619 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -253,9 +253,6 @@ else() | |||
| 253 | -Werror | 253 | -Werror |
| 254 | -Werror=conversion | 254 | -Werror=conversion |
| 255 | -Werror=ignored-qualifiers | 255 | -Werror=ignored-qualifiers |
| 256 | -Werror=implicit-fallthrough | ||
| 257 | -Werror=shadow | ||
| 258 | -Werror=sign-compare | ||
| 259 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> | 256 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> |
| 260 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> | 257 | $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> |
| 261 | -Werror=unused-variable | 258 | -Werror=unused-variable |
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 256695804..14de7bc89 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -258,10 +258,6 @@ if (MSVC) | |||
| 258 | target_compile_options(video_core PRIVATE | 258 | target_compile_options(video_core PRIVATE |
| 259 | /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data | 259 | /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data |
| 260 | /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data | 260 | /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data |
| 261 | /we4456 # Declaration of 'identifier' hides previous local declaration | ||
| 262 | /we4457 # Declaration of 'identifier' hides function parameter | ||
| 263 | /we4458 # Declaration of 'identifier' hides class member | ||
| 264 | /we4459 # Declaration of 'identifier' hides global declaration | ||
| 265 | ) | 261 | ) |
| 266 | else() | 262 | else() |
| 267 | target_compile_options(video_core PRIVATE | 263 | target_compile_options(video_core PRIVATE |
| @@ -269,7 +265,6 @@ else() | |||
| 269 | -Wno-error=sign-conversion | 265 | -Wno-error=sign-conversion |
| 270 | -Werror=pessimizing-move | 266 | -Werror=pessimizing-move |
| 271 | -Werror=redundant-move | 267 | -Werror=redundant-move |
| 272 | -Werror=shadow | ||
| 273 | -Werror=type-limits | 268 | -Werror=type-limits |
| 274 | 269 | ||
| 275 | $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> | 270 | $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> |
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index ad9fd5eff..be0ac2214 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h | |||
| @@ -98,7 +98,7 @@ struct CommandDataContainer { | |||
| 98 | struct SynchState final { | 98 | struct SynchState final { |
| 99 | using CommandQueue = Common::MPSCQueue<CommandDataContainer>; | 99 | using CommandQueue = Common::MPSCQueue<CommandDataContainer>; |
| 100 | std::mutex write_lock; | 100 | std::mutex write_lock; |
| 101 | CommandQueue queue{512}; // size must be 2^n | 101 | CommandQueue queue; |
| 102 | u64 last_fence{}; | 102 | u64 last_fence{}; |
| 103 | std::atomic<u64> signaled_fence{}; | 103 | std::atomic<u64> signaled_fence{}; |
| 104 | std::condition_variable_any cv; | 104 | std::condition_variable_any cv; |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index a3d478837..4cba777e6 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp | |||
| @@ -328,31 +328,32 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, | |||
| 328 | const VkImageAspectFlags aspect_mask = image.AspectMask(); | 328 | const VkImageAspectFlags aspect_mask = image.AspectMask(); |
| 329 | const VkImage vk_image = image.Handle(); | 329 | const VkImage vk_image = image.Handle(); |
| 330 | const bool is_initialized = image.ExchangeInitialization(); | 330 | const bool is_initialized = image.ExchangeInitialization(); |
| 331 | scheduler.Record( | 331 | scheduler.Record([vk_pipeline, vk_image, aspect_mask, |
| 332 | [vk_pipeline, vk_image, aspect_mask, is_initialized](vk::CommandBuffer cmdbuf) { | 332 | is_initialized](vk::CommandBuffer cmdbuf) { |
| 333 | const VkImageMemoryBarrier image_barrier{ | 333 | const VkImageMemoryBarrier image_barrier{ |
| 334 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, | 334 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
| 335 | .pNext = nullptr, | 335 | .pNext = nullptr, |
| 336 | .srcAccessMask = is_initialized ? VK_ACCESS_SHADER_WRITE_BIT : VK_ACCESS_NONE, | 336 | .srcAccessMask = static_cast<VkAccessFlags>(is_initialized ? VK_ACCESS_SHADER_WRITE_BIT |
| 337 | .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, | 337 | : VK_ACCESS_NONE), |
| 338 | .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, | 338 | .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, |
| 339 | .newLayout = VK_IMAGE_LAYOUT_GENERAL, | 339 | .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, |
| 340 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, | 340 | .newLayout = VK_IMAGE_LAYOUT_GENERAL, |
| 341 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, | 341 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
| 342 | .image = vk_image, | 342 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
| 343 | .subresourceRange{ | 343 | .image = vk_image, |
| 344 | .aspectMask = aspect_mask, | 344 | .subresourceRange{ |
| 345 | .baseMipLevel = 0, | 345 | .aspectMask = aspect_mask, |
| 346 | .levelCount = VK_REMAINING_MIP_LEVELS, | 346 | .baseMipLevel = 0, |
| 347 | .baseArrayLayer = 0, | 347 | .levelCount = VK_REMAINING_MIP_LEVELS, |
| 348 | .layerCount = VK_REMAINING_ARRAY_LAYERS, | 348 | .baseArrayLayer = 0, |
| 349 | }, | 349 | .layerCount = VK_REMAINING_ARRAY_LAYERS, |
| 350 | }; | 350 | }, |
| 351 | cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | 351 | }; |
| 352 | : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, | 352 | cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT |
| 353 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); | 353 | : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, |
| 354 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); | 354 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); |
| 355 | }); | 355 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); |
| 356 | }); | ||
| 356 | for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { | 357 | for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { |
| 357 | const size_t input_offset = swizzle.buffer_offset + map.offset; | 358 | const size_t input_offset = swizzle.buffer_offset + map.offset; |
| 358 | const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 8U); | 359 | const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 8U); |
diff --git a/src/web_service/telemetry_json.cpp b/src/web_service/telemetry_json.cpp index 6215c914f..46faddb61 100644 --- a/src/web_service/telemetry_json.cpp +++ b/src/web_service/telemetry_json.cpp | |||
| @@ -13,8 +13,8 @@ namespace WebService { | |||
| 13 | namespace Telemetry = Common::Telemetry; | 13 | namespace Telemetry = Common::Telemetry; |
| 14 | 14 | ||
| 15 | struct TelemetryJson::Impl { | 15 | struct TelemetryJson::Impl { |
| 16 | Impl(std::string host, std::string username, std::string token) | 16 | Impl(std::string host_, std::string username_, std::string token_) |
| 17 | : host{std::move(host)}, username{std::move(username)}, token{std::move(token)} {} | 17 | : host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} {} |
| 18 | 18 | ||
| 19 | nlohmann::json& TopSection() { | 19 | nlohmann::json& TopSection() { |
| 20 | return sections[static_cast<u8>(Telemetry::FieldType::None)]; | 20 | return sections[static_cast<u8>(Telemetry::FieldType::None)]; |
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp index 58b0c2f10..dce9772fe 100644 --- a/src/web_service/web_backend.cpp +++ b/src/web_service/web_backend.cpp | |||
| @@ -30,10 +30,10 @@ constexpr std::array<const char, 1> API_VERSION{'1'}; | |||
| 30 | constexpr std::size_t TIMEOUT_SECONDS = 30; | 30 | constexpr std::size_t TIMEOUT_SECONDS = 30; |
| 31 | 31 | ||
| 32 | struct Client::Impl { | 32 | struct Client::Impl { |
| 33 | Impl(std::string host, std::string username, std::string token) | 33 | Impl(std::string host_, std::string username_, std::string token_) |
| 34 | : host{std::move(host)}, username{std::move(username)}, token{std::move(token)} { | 34 | : host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} { |
| 35 | std::scoped_lock lock{jwt_cache.mutex}; | 35 | std::scoped_lock lock{jwt_cache.mutex}; |
| 36 | if (this->username == jwt_cache.username && this->token == jwt_cache.token) { | 36 | if (username == jwt_cache.username && token == jwt_cache.token) { |
| 37 | jwt = jwt_cache.jwt; | 37 | jwt = jwt_cache.jwt; |
| 38 | } | 38 | } |
| 39 | } | 39 | } |
| @@ -69,8 +69,8 @@ struct Client::Impl { | |||
| 69 | */ | 69 | */ |
| 70 | WebResult GenericRequest(const std::string& method, const std::string& path, | 70 | WebResult GenericRequest(const std::string& method, const std::string& path, |
| 71 | const std::string& data, const std::string& accept, | 71 | const std::string& data, const std::string& accept, |
| 72 | const std::string& jwt = "", const std::string& username = "", | 72 | const std::string& jwt_ = "", const std::string& username_ = "", |
| 73 | const std::string& token = "") { | 73 | const std::string& token_ = "") { |
| 74 | if (cli == nullptr) { | 74 | if (cli == nullptr) { |
| 75 | cli = std::make_unique<httplib::Client>(host.c_str()); | 75 | cli = std::make_unique<httplib::Client>(host.c_str()); |
| 76 | } | 76 | } |
| @@ -85,14 +85,14 @@ struct Client::Impl { | |||
| 85 | cli->set_write_timeout(TIMEOUT_SECONDS); | 85 | cli->set_write_timeout(TIMEOUT_SECONDS); |
| 86 | 86 | ||
| 87 | httplib::Headers params; | 87 | httplib::Headers params; |
| 88 | if (!jwt.empty()) { | 88 | if (!jwt_.empty()) { |
| 89 | params = { | 89 | params = { |
| 90 | {std::string("Authorization"), fmt::format("Bearer {}", jwt)}, | 90 | {std::string("Authorization"), fmt::format("Bearer {}", jwt_)}, |
| 91 | }; | 91 | }; |
| 92 | } else if (!username.empty()) { | 92 | } else if (!username_.empty()) { |
| 93 | params = { | 93 | params = { |
| 94 | {std::string("x-username"), username}, | 94 | {std::string("x-username"), username_}, |
| 95 | {std::string("x-token"), token}, | 95 | {std::string("x-token"), token_}, |
| 96 | }; | 96 | }; |
| 97 | } | 97 | } |
| 98 | 98 | ||
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index bde465485..cbe4e2daa 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -127,7 +127,7 @@ void EmuThread::run() { | |||
| 127 | class OpenGLSharedContext : public Core::Frontend::GraphicsContext { | 127 | class OpenGLSharedContext : public Core::Frontend::GraphicsContext { |
| 128 | public: | 128 | public: |
| 129 | /// Create the original context that should be shared from | 129 | /// Create the original context that should be shared from |
| 130 | explicit OpenGLSharedContext(QSurface* surface) : surface(surface) { | 130 | explicit OpenGLSharedContext(QSurface* surface_) : surface{surface_} { |
| 131 | QSurfaceFormat format; | 131 | QSurfaceFormat format; |
| 132 | format.setVersion(4, 6); | 132 | format.setVersion(4, 6); |
| 133 | format.setProfile(QSurfaceFormat::CompatibilityProfile); | 133 | format.setProfile(QSurfaceFormat::CompatibilityProfile); |
| @@ -364,9 +364,9 @@ void GRenderWindow::RestoreGeometry() { | |||
| 364 | QWidget::restoreGeometry(geometry); | 364 | QWidget::restoreGeometry(geometry); |
| 365 | } | 365 | } |
| 366 | 366 | ||
| 367 | void GRenderWindow::restoreGeometry(const QByteArray& geometry) { | 367 | void GRenderWindow::restoreGeometry(const QByteArray& geometry_) { |
| 368 | // Make sure users of this class don't need to deal with backing up the geometry themselves | 368 | // Make sure users of this class don't need to deal with backing up the geometry themselves |
| 369 | QWidget::restoreGeometry(geometry); | 369 | QWidget::restoreGeometry(geometry_); |
| 370 | BackupGeometry(); | 370 | BackupGeometry(); |
| 371 | } | 371 | } |
| 372 | 372 | ||
| @@ -1014,8 +1014,8 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const { | |||
| 1014 | return unsupported_ext; | 1014 | return unsupported_ext; |
| 1015 | } | 1015 | } |
| 1016 | 1016 | ||
| 1017 | void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) { | 1017 | void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread_) { |
| 1018 | this->emu_thread = emu_thread; | 1018 | emu_thread = emu_thread_; |
| 1019 | } | 1019 | } |
| 1020 | 1020 | ||
| 1021 | void GRenderWindow::OnEmulationStopping() { | 1021 | void GRenderWindow::OnEmulationStopping() { |
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index d01538039..81fe52c0e 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h | |||
| @@ -56,12 +56,12 @@ public: | |||
| 56 | 56 | ||
| 57 | /** | 57 | /** |
| 58 | * Sets whether the emulation thread is running or not | 58 | * Sets whether the emulation thread is running or not |
| 59 | * @param running Boolean value, set the emulation thread to running if true | 59 | * @param running_ Boolean value, set the emulation thread to running if true |
| 60 | * @note This function is thread-safe | 60 | * @note This function is thread-safe |
| 61 | */ | 61 | */ |
| 62 | void SetRunning(bool running) { | 62 | void SetRunning(bool running_) { |
| 63 | std::unique_lock lock{running_mutex}; | 63 | std::unique_lock lock{running_mutex}; |
| 64 | this->running = running; | 64 | running = running_; |
| 65 | lock.unlock(); | 65 | lock.unlock(); |
| 66 | running_cv.notify_all(); | 66 | running_cv.notify_all(); |
| 67 | if (!running) { | 67 | if (!running) { |
| @@ -138,8 +138,8 @@ public: | |||
| 138 | 138 | ||
| 139 | void BackupGeometry(); | 139 | void BackupGeometry(); |
| 140 | void RestoreGeometry(); | 140 | void RestoreGeometry(); |
| 141 | void restoreGeometry(const QByteArray& geometry); // overridden | 141 | void restoreGeometry(const QByteArray& geometry_); // overridden |
| 142 | QByteArray saveGeometry(); // overridden | 142 | QByteArray saveGeometry(); // overridden |
| 143 | 143 | ||
| 144 | qreal windowPixelRatio() const; | 144 | qreal windowPixelRatio() const; |
| 145 | 145 | ||
| @@ -189,7 +189,7 @@ public: | |||
| 189 | void Exit(); | 189 | void Exit(); |
| 190 | 190 | ||
| 191 | public slots: | 191 | public slots: |
| 192 | void OnEmulationStarting(EmuThread* emu_thread); | 192 | void OnEmulationStarting(EmuThread* emu_thread_); |
| 193 | void OnEmulationStopping(); | 193 | void OnEmulationStopping(); |
| 194 | void OnFramebufferSizeChanged(); | 194 | void OnFramebufferSizeChanged(); |
| 195 | 195 | ||
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index b415a1cc4..e99657bd6 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp | |||
| @@ -27,12 +27,11 @@ | |||
| 27 | #include "yuzu/hotkeys.h" | 27 | #include "yuzu/hotkeys.h" |
| 28 | #include "yuzu/uisettings.h" | 28 | #include "yuzu/uisettings.h" |
| 29 | 29 | ||
| 30 | ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, | 30 | ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, |
| 31 | InputCommon::InputSubsystem* input_subsystem, | 31 | InputCommon::InputSubsystem* input_subsystem, |
| 32 | Core::System& system_) | 32 | Core::System& system_) |
| 33 | : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, | 33 | : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry{registry_}, |
| 34 | registry(registry), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, | 34 | system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, this)}, |
| 35 | this)}, | ||
| 36 | cpu_tab{std::make_unique<ConfigureCpu>(system_, this)}, | 35 | cpu_tab{std::make_unique<ConfigureCpu>(system_, this)}, |
| 37 | debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, | 36 | debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, |
| 38 | filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, | 37 | filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, |
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 32ddfd4e0..12cf25daf 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h | |||
| @@ -40,7 +40,7 @@ class ConfigureDialog : public QDialog { | |||
| 40 | Q_OBJECT | 40 | Q_OBJECT |
| 41 | 41 | ||
| 42 | public: | 42 | public: |
| 43 | explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, | 43 | explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, |
| 44 | InputCommon::InputSubsystem* input_subsystem, Core::System& system_); | 44 | InputCommon::InputSubsystem* input_subsystem, Core::System& system_); |
| 45 | ~ConfigureDialog() override; | 45 | ~ConfigureDialog() override; |
| 46 | 46 | ||
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 1c05dd0f3..f3be9a374 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -264,15 +264,16 @@ QString ConfigureInputPlayer::AnalogToText(const Common::ParamPackage& param, | |||
| 264 | return QObject::tr("[unknown]"); | 264 | return QObject::tr("[unknown]"); |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index, | 267 | ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index_, |
| 268 | QWidget* bottom_row, | 268 | QWidget* bottom_row_, |
| 269 | InputCommon::InputSubsystem* input_subsystem_, | 269 | InputCommon::InputSubsystem* input_subsystem_, |
| 270 | InputProfiles* profiles_, Core::HID::HIDCore& hid_core_, | 270 | InputProfiles* profiles_, Core::HID::HIDCore& hid_core_, |
| 271 | bool is_powered_on_, bool debug) | 271 | bool is_powered_on_, bool debug_) |
| 272 | : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index(player_index), | 272 | : QWidget(parent), |
| 273 | debug(debug), is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, | 273 | ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index{player_index_}, debug{debug_}, |
| 274 | profiles(profiles_), timeout_timer(std::make_unique<QTimer>()), | 274 | is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, profiles(profiles_), |
| 275 | poll_timer(std::make_unique<QTimer>()), bottom_row(bottom_row), hid_core{hid_core_} { | 275 | timeout_timer(std::make_unique<QTimer>()), |
| 276 | poll_timer(std::make_unique<QTimer>()), bottom_row{bottom_row_}, hid_core{hid_core_} { | ||
| 276 | if (player_index == 0) { | 277 | if (player_index == 0) { |
| 277 | auto* emulated_controller_p1 = | 278 | auto* emulated_controller_p1 = |
| 278 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); | 279 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); |
| @@ -696,39 +697,38 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 696 | UpdateControllerEnabledButtons(); | 697 | UpdateControllerEnabledButtons(); |
| 697 | UpdateControllerButtonNames(); | 698 | UpdateControllerButtonNames(); |
| 698 | UpdateMotionButtons(); | 699 | UpdateMotionButtons(); |
| 699 | connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), | 700 | connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { |
| 700 | [this, player_index](int) { | 701 | UpdateControllerAvailableButtons(); |
| 701 | UpdateControllerAvailableButtons(); | 702 | UpdateControllerEnabledButtons(); |
| 702 | UpdateControllerEnabledButtons(); | 703 | UpdateControllerButtonNames(); |
| 703 | UpdateControllerButtonNames(); | 704 | UpdateMotionButtons(); |
| 704 | UpdateMotionButtons(); | 705 | const Core::HID::NpadStyleIndex type = |
| 705 | const Core::HID::NpadStyleIndex type = | 706 | GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); |
| 706 | GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); | 707 | |
| 707 | 708 | if (player_index == 0) { | |
| 708 | if (player_index == 0) { | 709 | auto* emulated_controller_p1 = |
| 709 | auto* emulated_controller_p1 = | 710 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); |
| 710 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); | 711 | auto* emulated_controller_handheld = |
| 711 | auto* emulated_controller_handheld = | 712 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); |
| 712 | hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); | 713 | bool is_connected = emulated_controller->IsConnected(true); |
| 713 | bool is_connected = emulated_controller->IsConnected(true); | 714 | |
| 714 | 715 | emulated_controller_p1->SetNpadStyleIndex(type); | |
| 715 | emulated_controller_p1->SetNpadStyleIndex(type); | 716 | emulated_controller_handheld->SetNpadStyleIndex(type); |
| 716 | emulated_controller_handheld->SetNpadStyleIndex(type); | 717 | if (is_connected) { |
| 717 | if (is_connected) { | 718 | if (type == Core::HID::NpadStyleIndex::Handheld) { |
| 718 | if (type == Core::HID::NpadStyleIndex::Handheld) { | 719 | emulated_controller_p1->Disconnect(); |
| 719 | emulated_controller_p1->Disconnect(); | 720 | emulated_controller_handheld->Connect(true); |
| 720 | emulated_controller_handheld->Connect(true); | 721 | emulated_controller = emulated_controller_handheld; |
| 721 | emulated_controller = emulated_controller_handheld; | 722 | } else { |
| 722 | } else { | 723 | emulated_controller_handheld->Disconnect(); |
| 723 | emulated_controller_handheld->Disconnect(); | 724 | emulated_controller_p1->Connect(true); |
| 724 | emulated_controller_p1->Connect(true); | 725 | emulated_controller = emulated_controller_p1; |
| 725 | emulated_controller = emulated_controller_p1; | ||
| 726 | } | ||
| 727 | } | ||
| 728 | ui->controllerFrame->SetController(emulated_controller); | ||
| 729 | } | 726 | } |
| 730 | emulated_controller->SetNpadStyleIndex(type); | 727 | } |
| 731 | }); | 728 | ui->controllerFrame->SetController(emulated_controller); |
| 729 | } | ||
| 730 | emulated_controller->SetNpadStyleIndex(type); | ||
| 731 | }); | ||
| 732 | 732 | ||
| 733 | connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, | 733 | connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, |
| 734 | &ConfigureInputPlayer::UpdateMappingWithDefaults); | 734 | &ConfigureInputPlayer::UpdateMappingWithDefaults); |
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 54b3fe150..af8343b2e 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp | |||
| @@ -35,10 +35,10 @@ | |||
| 35 | #include "yuzu/uisettings.h" | 35 | #include "yuzu/uisettings.h" |
| 36 | #include "yuzu/util/util.h" | 36 | #include "yuzu/util/util.h" |
| 37 | 37 | ||
| 38 | ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id, const std::string& file_name, | 38 | ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, |
| 39 | Core::System& system_) | 39 | Core::System& system_) |
| 40 | : QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()), | 40 | : QDialog(parent), |
| 41 | title_id(title_id), system{system_} { | 41 | ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_} { |
| 42 | const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name)); | 42 | const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name)); |
| 43 | const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()) | 43 | const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()) |
| 44 | : fmt::format("{:016X}", title_id); | 44 | : fmt::format("{:016X}", title_id); |
| @@ -116,8 +116,8 @@ void ConfigurePerGame::HandleApplyButtonClicked() { | |||
| 116 | ApplyConfiguration(); | 116 | ApplyConfiguration(); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file) { | 119 | void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file_) { |
| 120 | this->file = std::move(file); | 120 | file = std::move(file_); |
| 121 | LoadConfiguration(); | 121 | LoadConfiguration(); |
| 122 | } | 122 | } |
| 123 | 123 | ||
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index e6dc05546..17a98a0f3 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h | |||
| @@ -39,14 +39,14 @@ class ConfigurePerGame : public QDialog { | |||
| 39 | 39 | ||
| 40 | public: | 40 | public: |
| 41 | // Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263 | 41 | // Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263 |
| 42 | explicit ConfigurePerGame(QWidget* parent, u64 title_id, const std::string& file_name, | 42 | explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, |
| 43 | Core::System& system_); | 43 | Core::System& system_); |
| 44 | ~ConfigurePerGame() override; | 44 | ~ConfigurePerGame() override; |
| 45 | 45 | ||
| 46 | /// Save all button configurations to settings file | 46 | /// Save all button configurations to settings file |
| 47 | void ApplyConfiguration(); | 47 | void ApplyConfiguration(); |
| 48 | 48 | ||
| 49 | void LoadFromFile(FileSys::VirtualFile file); | 49 | void LoadFromFile(FileSys::VirtualFile file_); |
| 50 | 50 | ||
| 51 | private: | 51 | private: |
| 52 | void changeEvent(QEvent* event) override; | 52 | void changeEvent(QEvent* event) override; |
diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp index 7893a85bb..4906997ab 100644 --- a/src/yuzu/configuration/configure_per_game_addons.cpp +++ b/src/yuzu/configuration/configure_per_game_addons.cpp | |||
| @@ -89,8 +89,8 @@ void ConfigurePerGameAddons::ApplyConfiguration() { | |||
| 89 | Settings::values.disabled_addons[title_id] = disabled_addons; | 89 | Settings::values.disabled_addons[title_id] = disabled_addons; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | void ConfigurePerGameAddons::LoadFromFile(FileSys::VirtualFile file) { | 92 | void ConfigurePerGameAddons::LoadFromFile(FileSys::VirtualFile file_) { |
| 93 | this->file = std::move(file); | 93 | file = std::move(file_); |
| 94 | LoadConfiguration(); | 94 | LoadConfiguration(); |
| 95 | } | 95 | } |
| 96 | 96 | ||
diff --git a/src/yuzu/configuration/configure_per_game_addons.h b/src/yuzu/configuration/configure_per_game_addons.h index 24b017494..14690fba8 100644 --- a/src/yuzu/configuration/configure_per_game_addons.h +++ b/src/yuzu/configuration/configure_per_game_addons.h | |||
| @@ -35,7 +35,7 @@ public: | |||
| 35 | /// Save all button configurations to settings file | 35 | /// Save all button configurations to settings file |
| 36 | void ApplyConfiguration(); | 36 | void ApplyConfiguration(); |
| 37 | 37 | ||
| 38 | void LoadFromFile(FileSys::VirtualFile file); | 38 | void LoadFromFile(FileSys::VirtualFile file_); |
| 39 | 39 | ||
| 40 | void SetTitleId(u64 id); | 40 | void SetTitleId(u64 id); |
| 41 | 41 | ||
diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp index 4fcc22b7a..688c2dd38 100644 --- a/src/yuzu/configuration/configure_ringcon.cpp +++ b/src/yuzu/configuration/configure_ringcon.cpp | |||
| @@ -165,10 +165,10 @@ ConfigureRingController::ConfigureRingController(QWidget* parent, | |||
| 165 | const std::string invert_str = invert_value ? "+" : "-"; | 165 | const std::string invert_str = invert_value ? "+" : "-"; |
| 166 | param.Set("invert_x", invert_str); | 166 | param.Set("invert_x", invert_str); |
| 167 | emulated_device->SetRingParam(param); | 167 | emulated_device->SetRingParam(param); |
| 168 | for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; | 168 | for (int sub_button_id2 = 0; sub_button_id2 < ANALOG_SUB_BUTTONS_NUM; |
| 169 | ++sub_button_id) { | 169 | ++sub_button_id2) { |
| 170 | analog_map_buttons[sub_button_id]->setText( | 170 | analog_map_buttons[sub_button_id2]->setText( |
| 171 | AnalogToText(param, analog_sub_buttons[sub_button_id])); | 171 | AnalogToText(param, analog_sub_buttons[sub_button_id2])); |
| 172 | } | 172 | } |
| 173 | }); | 173 | }); |
| 174 | context_menu.exec( | 174 | context_menu.exec( |
diff --git a/src/yuzu/configuration/configure_touch_from_button.cpp b/src/yuzu/configuration/configure_touch_from_button.cpp index c17da6fd1..06cc452c3 100644 --- a/src/yuzu/configuration/configure_touch_from_button.cpp +++ b/src/yuzu/configuration/configure_touch_from_button.cpp | |||
| @@ -68,10 +68,10 @@ static QString ButtonToText(const Common::ParamPackage& param) { | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | ConfigureTouchFromButton::ConfigureTouchFromButton( | 70 | ConfigureTouchFromButton::ConfigureTouchFromButton( |
| 71 | QWidget* parent, const std::vector<Settings::TouchFromButtonMap>& touch_maps, | 71 | QWidget* parent, const std::vector<Settings::TouchFromButtonMap>& touch_maps_, |
| 72 | InputCommon::InputSubsystem* input_subsystem_, const int default_index) | 72 | InputCommon::InputSubsystem* input_subsystem_, const int default_index) |
| 73 | : QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), | 73 | : QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), |
| 74 | touch_maps(touch_maps), input_subsystem{input_subsystem_}, selected_index(default_index), | 74 | touch_maps{touch_maps_}, input_subsystem{input_subsystem_}, selected_index{default_index}, |
| 75 | timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) { | 75 | timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) { |
| 76 | ui->setupUi(this); | 76 | ui->setupUi(this); |
| 77 | binding_list_model = new QStandardItemModel(0, 3, this); | 77 | binding_list_model = new QStandardItemModel(0, 3, this); |
diff --git a/src/yuzu/configuration/configure_touch_from_button.h b/src/yuzu/configuration/configure_touch_from_button.h index e1400481a..b8c55db66 100644 --- a/src/yuzu/configuration/configure_touch_from_button.h +++ b/src/yuzu/configuration/configure_touch_from_button.h | |||
| @@ -37,7 +37,7 @@ class ConfigureTouchFromButton : public QDialog { | |||
| 37 | 37 | ||
| 38 | public: | 38 | public: |
| 39 | explicit ConfigureTouchFromButton(QWidget* parent, | 39 | explicit ConfigureTouchFromButton(QWidget* parent, |
| 40 | const std::vector<Settings::TouchFromButtonMap>& touch_maps, | 40 | const std::vector<Settings::TouchFromButtonMap>& touch_maps_, |
| 41 | InputCommon::InputSubsystem* input_subsystem_, | 41 | InputCommon::InputSubsystem* input_subsystem_, |
| 42 | int default_index = 0); | 42 | int default_index = 0); |
| 43 | ~ConfigureTouchFromButton() override; | 43 | ~ConfigureTouchFromButton() override; |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 8f486a131..0ea31cd33 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -113,9 +113,9 @@ QString WaitTreeText::GetText() const { | |||
| 113 | return text; | 113 | return text; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table, | 116 | WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address_, const Kernel::KHandleTable& handle_table, |
| 117 | Core::System& system_) | 117 | Core::System& system_) |
| 118 | : mutex_address(mutex_address), system{system_} { | 118 | : mutex_address{mutex_address_}, system{system_} { |
| 119 | mutex_value = system.Memory().Read32(mutex_address); | 119 | mutex_value = system.Memory().Read32(mutex_address); |
| 120 | owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask); | 120 | owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask); |
| 121 | owner = handle_table.GetObject<Kernel::KThread>(owner_handle).GetPointerUnsafe(); | 121 | owner = handle_table.GetObject<Kernel::KThread>(owner_handle).GetPointerUnsafe(); |
| @@ -140,8 +140,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() cons | |||
| 140 | return list; | 140 | return list; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | WaitTreeCallstack::WaitTreeCallstack(const Kernel::KThread& thread, Core::System& system_) | 143 | WaitTreeCallstack::WaitTreeCallstack(const Kernel::KThread& thread_, Core::System& system_) |
| 144 | : thread(thread), system{system_} {} | 144 | : thread{thread_}, system{system_} {} |
| 145 | WaitTreeCallstack::~WaitTreeCallstack() = default; | 145 | WaitTreeCallstack::~WaitTreeCallstack() = default; |
| 146 | 146 | ||
| 147 | QString WaitTreeCallstack::GetText() const { | 147 | QString WaitTreeCallstack::GetText() const { |
| @@ -171,8 +171,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons | |||
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | WaitTreeSynchronizationObject::WaitTreeSynchronizationObject( | 173 | WaitTreeSynchronizationObject::WaitTreeSynchronizationObject( |
| 174 | const Kernel::KSynchronizationObject& o, Core::System& system_) | 174 | const Kernel::KSynchronizationObject& object_, Core::System& system_) |
| 175 | : object(o), system{system_} {} | 175 | : object{object_}, system{system_} {} |
| 176 | WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default; | 176 | WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default; |
| 177 | 177 | ||
| 178 | WaitTreeExpandableItem::WaitTreeExpandableItem() = default; | 178 | WaitTreeExpandableItem::WaitTreeExpandableItem() = default; |
| @@ -380,8 +380,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
| 380 | return list; | 380 | return list; |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object, Core::System& system_) | 383 | WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object_, Core::System& system_) |
| 384 | : WaitTreeSynchronizationObject(object, system_) {} | 384 | : WaitTreeSynchronizationObject(object_, system_) {} |
| 385 | WaitTreeEvent::~WaitTreeEvent() = default; | 385 | WaitTreeEvent::~WaitTreeEvent() = default; |
| 386 | 386 | ||
| 387 | WaitTreeThreadList::WaitTreeThreadList(std::vector<Kernel::KThread*>&& list, Core::System& system_) | 387 | WaitTreeThreadList::WaitTreeThreadList(std::vector<Kernel::KThread*>&& list, Core::System& system_) |
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 4a36dfc48..f21b9f467 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h | |||
| @@ -78,7 +78,7 @@ public: | |||
| 78 | class WaitTreeMutexInfo : public WaitTreeExpandableItem { | 78 | class WaitTreeMutexInfo : public WaitTreeExpandableItem { |
| 79 | Q_OBJECT | 79 | Q_OBJECT |
| 80 | public: | 80 | public: |
| 81 | explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table, | 81 | explicit WaitTreeMutexInfo(VAddr mutex_address_, const Kernel::KHandleTable& handle_table, |
| 82 | Core::System& system_); | 82 | Core::System& system_); |
| 83 | ~WaitTreeMutexInfo() override; | 83 | ~WaitTreeMutexInfo() override; |
| 84 | 84 | ||
| @@ -97,7 +97,7 @@ private: | |||
| 97 | class WaitTreeCallstack : public WaitTreeExpandableItem { | 97 | class WaitTreeCallstack : public WaitTreeExpandableItem { |
| 98 | Q_OBJECT | 98 | Q_OBJECT |
| 99 | public: | 99 | public: |
| 100 | explicit WaitTreeCallstack(const Kernel::KThread& thread, Core::System& system_); | 100 | explicit WaitTreeCallstack(const Kernel::KThread& thread_, Core::System& system_); |
| 101 | ~WaitTreeCallstack() override; | 101 | ~WaitTreeCallstack() override; |
| 102 | 102 | ||
| 103 | QString GetText() const override; | 103 | QString GetText() const override; |
| @@ -112,7 +112,7 @@ private: | |||
| 112 | class WaitTreeSynchronizationObject : public WaitTreeExpandableItem { | 112 | class WaitTreeSynchronizationObject : public WaitTreeExpandableItem { |
| 113 | Q_OBJECT | 113 | Q_OBJECT |
| 114 | public: | 114 | public: |
| 115 | explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object, | 115 | explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object_, |
| 116 | Core::System& system_); | 116 | Core::System& system_); |
| 117 | ~WaitTreeSynchronizationObject() override; | 117 | ~WaitTreeSynchronizationObject() override; |
| 118 | 118 | ||
| @@ -162,7 +162,7 @@ private: | |||
| 162 | class WaitTreeEvent : public WaitTreeSynchronizationObject { | 162 | class WaitTreeEvent : public WaitTreeSynchronizationObject { |
| 163 | Q_OBJECT | 163 | Q_OBJECT |
| 164 | public: | 164 | public: |
| 165 | explicit WaitTreeEvent(const Kernel::KReadableEvent& object, Core::System& system_); | 165 | explicit WaitTreeEvent(const Kernel::KReadableEvent& object_, Core::System& system_); |
| 166 | ~WaitTreeEvent() override; | 166 | ~WaitTreeEvent() override; |
| 167 | }; | 167 | }; |
| 168 | 168 | ||
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 6321afc83..05d309827 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -28,8 +28,8 @@ | |||
| 28 | #include "yuzu/uisettings.h" | 28 | #include "yuzu/uisettings.h" |
| 29 | #include "yuzu/util/controller_navigation.h" | 29 | #include "yuzu/util/controller_navigation.h" |
| 30 | 30 | ||
| 31 | GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent) | 31 | GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist_, QObject* parent) |
| 32 | : QObject(parent), gamelist{gamelist} {} | 32 | : QObject(parent), gamelist{gamelist_} {} |
| 33 | 33 | ||
| 34 | // EventFilter in order to process systemkeys while editing the searchfield | 34 | // EventFilter in order to process systemkeys while editing the searchfield |
| 35 | bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { | 35 | bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { |
| @@ -80,9 +80,9 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve | |||
| 80 | return QObject::eventFilter(obj, event); | 80 | return QObject::eventFilter(obj, event); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | void GameListSearchField::setFilterResult(int visible, int total) { | 83 | void GameListSearchField::setFilterResult(int visible_, int total_) { |
| 84 | this->visible = visible; | 84 | visible = visible_; |
| 85 | this->total = total; | 85 | total = total_; |
| 86 | 86 | ||
| 87 | label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); | 87 | label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); |
| 88 | } | 88 | } |
| @@ -309,9 +309,9 @@ void GameList::OnFilterCloseClicked() { | |||
| 309 | main_window->filterBarSetChecked(false); | 309 | main_window->filterBarSetChecked(false); |
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvider* provider, | 312 | GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvider* provider_, |
| 313 | Core::System& system_, GMainWindow* parent) | 313 | Core::System& system_, GMainWindow* parent) |
| 314 | : QWidget{parent}, vfs(std::move(vfs)), provider(provider), system{system_} { | 314 | : QWidget{parent}, vfs{std::move(vfs_)}, provider{provider_}, system{system_} { |
| 315 | watcher = new QFileSystemWatcher(this); | 315 | watcher = new QFileSystemWatcher(this); |
| 316 | connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); | 316 | connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); |
| 317 | 317 | ||
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 464da98ad..bc36d015a 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h | |||
| @@ -67,8 +67,8 @@ public: | |||
| 67 | COLUMN_COUNT, // Number of columns | 67 | COLUMN_COUNT, // Number of columns |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs, | 70 | explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs_, |
| 71 | FileSys::ManualContentProvider* provider, Core::System& system_, | 71 | FileSys::ManualContentProvider* provider_, Core::System& system_, |
| 72 | GMainWindow* parent = nullptr); | 72 | GMainWindow* parent = nullptr); |
| 73 | ~GameList() override; | 73 | ~GameList() override; |
| 74 | 74 | ||
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index f2a986ed8..cd7d63536 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h | |||
| @@ -225,8 +225,8 @@ public: | |||
| 225 | static constexpr int GameDirRole = Qt::UserRole + 2; | 225 | static constexpr int GameDirRole = Qt::UserRole + 2; |
| 226 | 226 | ||
| 227 | explicit GameListDir(UISettings::GameDir& directory, | 227 | explicit GameListDir(UISettings::GameDir& directory, |
| 228 | GameListItemType dir_type = GameListItemType::CustomDir) | 228 | GameListItemType dir_type_ = GameListItemType::CustomDir) |
| 229 | : dir_type{dir_type} { | 229 | : dir_type{dir_type_} { |
| 230 | setData(type(), TypeRole); | 230 | setData(type(), TypeRole); |
| 231 | 231 | ||
| 232 | UISettings::GameDir* game_dir = &directory; | 232 | UISettings::GameDir* game_dir = &directory; |
| @@ -348,7 +348,7 @@ public: | |||
| 348 | explicit GameListSearchField(GameList* parent = nullptr); | 348 | explicit GameListSearchField(GameList* parent = nullptr); |
| 349 | 349 | ||
| 350 | QString filterText() const; | 350 | QString filterText() const; |
| 351 | void setFilterResult(int visible, int total); | 351 | void setFilterResult(int visible_, int total_); |
| 352 | 352 | ||
| 353 | void clear(); | 353 | void clear(); |
| 354 | void setFocus(); | 354 | void setFocus(); |
| @@ -356,7 +356,7 @@ public: | |||
| 356 | private: | 356 | private: |
| 357 | class KeyReleaseEater : public QObject { | 357 | class KeyReleaseEater : public QObject { |
| 358 | public: | 358 | public: |
| 359 | explicit KeyReleaseEater(GameList* gamelist, QObject* parent = nullptr); | 359 | explicit KeyReleaseEater(GameList* gamelist_, QObject* parent = nullptr); |
| 360 | 360 | ||
| 361 | private: | 361 | private: |
| 362 | GameList* gamelist = nullptr; | 362 | GameList* gamelist = nullptr; |
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index ca1899b5c..63326968b 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp | |||
| @@ -223,12 +223,12 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri | |||
| 223 | } | 223 | } |
| 224 | } // Anonymous namespace | 224 | } // Anonymous namespace |
| 225 | 225 | ||
| 226 | GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs, | 226 | GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs_, |
| 227 | FileSys::ManualContentProvider* provider, | 227 | FileSys::ManualContentProvider* provider_, |
| 228 | QVector<UISettings::GameDir>& game_dirs, | 228 | QVector<UISettings::GameDir>& game_dirs_, |
| 229 | const CompatibilityList& compatibility_list, Core::System& system_) | 229 | const CompatibilityList& compatibility_list_, Core::System& system_) |
| 230 | : vfs(std::move(vfs)), provider(provider), game_dirs(game_dirs), | 230 | : vfs{std::move(vfs_)}, provider{provider_}, game_dirs{game_dirs_}, |
| 231 | compatibility_list(compatibility_list), system{system_} {} | 231 | compatibility_list{compatibility_list_}, system{system_} {} |
| 232 | 232 | ||
| 233 | GameListWorker::~GameListWorker() = default; | 233 | GameListWorker::~GameListWorker() = default; |
| 234 | 234 | ||
diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h index 622d241fb..24a4e92c3 100644 --- a/src/yuzu/game_list_worker.h +++ b/src/yuzu/game_list_worker.h | |||
| @@ -33,10 +33,10 @@ class GameListWorker : public QObject, public QRunnable { | |||
| 33 | Q_OBJECT | 33 | Q_OBJECT |
| 34 | 34 | ||
| 35 | public: | 35 | public: |
| 36 | explicit GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs, | 36 | explicit GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs_, |
| 37 | FileSys::ManualContentProvider* provider, | 37 | FileSys::ManualContentProvider* provider_, |
| 38 | QVector<UISettings::GameDir>& game_dirs, | 38 | QVector<UISettings::GameDir>& game_dirs_, |
| 39 | const CompatibilityList& compatibility_list, Core::System& system_); | 39 | const CompatibilityList& compatibility_list_, Core::System& system_); |
| 40 | ~GameListWorker() override; | 40 | ~GameListWorker() override; |
| 41 | 41 | ||
| 42 | /// Starts the processing of directory tree information. | 42 | /// Starts the processing of directory tree information. |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 33886e50e..b460020b1 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -934,8 +934,7 @@ void GMainWindow::InitializeWidgets() { | |||
| 934 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::Vulkan); | 934 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::Vulkan); |
| 935 | } else { | 935 | } else { |
| 936 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); | 936 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); |
| 937 | const auto filter = Settings::values.scaling_filter.GetValue(); | 937 | if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { |
| 938 | if (filter == Settings::ScalingFilter::Fsr) { | ||
| 939 | Settings::values.scaling_filter.SetValue(Settings::ScalingFilter::NearestNeighbor); | 938 | Settings::values.scaling_filter.SetValue(Settings::ScalingFilter::NearestNeighbor); |
| 940 | UpdateFilterText(); | 939 | UpdateFilterText(); |
| 941 | } | 940 | } |
| @@ -1442,7 +1441,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p | |||
| 1442 | } | 1441 | } |
| 1443 | return false; | 1442 | return false; |
| 1444 | } | 1443 | } |
| 1445 | game_path = filename; | 1444 | current_game_path = filename; |
| 1446 | 1445 | ||
| 1447 | system->TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt"); | 1446 | system->TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt"); |
| 1448 | return true; | 1447 | return true; |
| @@ -1508,7 +1507,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | |||
| 1508 | 1507 | ||
| 1509 | // Register an ExecuteProgram callback such that Core can execute a sub-program | 1508 | // Register an ExecuteProgram callback such that Core can execute a sub-program |
| 1510 | system->RegisterExecuteProgramCallback( | 1509 | system->RegisterExecuteProgramCallback( |
| 1511 | [this](std::size_t program_index) { render_window->ExecuteProgram(program_index); }); | 1510 | [this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); }); |
| 1512 | 1511 | ||
| 1513 | // Register an Exit callback such that Core can exit the currently running application. | 1512 | // Register an Exit callback such that Core can exit the currently running application. |
| 1514 | system->RegisterExitCallback([this]() { render_window->Exit(); }); | 1513 | system->RegisterExitCallback([this]() { render_window->Exit(); }); |
| @@ -1641,7 +1640,7 @@ void GMainWindow::ShutdownGame() { | |||
| 1641 | emu_frametime_label->setVisible(false); | 1640 | emu_frametime_label->setVisible(false); |
| 1642 | renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan); | 1641 | renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan); |
| 1643 | 1642 | ||
| 1644 | game_path.clear(); | 1643 | current_game_path.clear(); |
| 1645 | 1644 | ||
| 1646 | // When closing the game, destroy the GLWindow to clear the context after the game is closed | 1645 | // When closing the game, destroy the GLWindow to clear the context after the game is closed |
| 1647 | render_window->ReleaseRenderTarget(); | 1646 | render_window->ReleaseRenderTarget(); |
| @@ -2560,7 +2559,7 @@ void GMainWindow::OnRestartGame() { | |||
| 2560 | return; | 2559 | return; |
| 2561 | } | 2560 | } |
| 2562 | // Make a copy since BootGame edits game_path | 2561 | // Make a copy since BootGame edits game_path |
| 2563 | BootGame(QString(game_path)); | 2562 | BootGame(QString(current_game_path)); |
| 2564 | } | 2563 | } |
| 2565 | 2564 | ||
| 2566 | void GMainWindow::OnPauseGame() { | 2565 | void GMainWindow::OnPauseGame() { |
| @@ -2989,7 +2988,7 @@ void GMainWindow::OnToggleAdaptingFilter() { | |||
| 2989 | 2988 | ||
| 2990 | void GMainWindow::OnConfigurePerGame() { | 2989 | void GMainWindow::OnConfigurePerGame() { |
| 2991 | const u64 title_id = system->GetCurrentProcessProgramID(); | 2990 | const u64 title_id = system->GetCurrentProcessProgramID(); |
| 2992 | OpenPerGameConfiguration(title_id, game_path.toStdString()); | 2991 | OpenPerGameConfiguration(title_id, current_game_path.toStdString()); |
| 2993 | } | 2992 | } |
| 2994 | 2993 | ||
| 2995 | void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) { | 2994 | void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) { |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 600647015..8cf224c9c 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -369,7 +369,7 @@ private: | |||
| 369 | bool emulation_running = false; | 369 | bool emulation_running = false; |
| 370 | std::unique_ptr<EmuThread> emu_thread; | 370 | std::unique_ptr<EmuThread> emu_thread; |
| 371 | // The path to the game currently running | 371 | // The path to the game currently running |
| 372 | QString game_path; | 372 | QString current_game_path; |
| 373 | 373 | ||
| 374 | bool auto_paused = false; | 374 | bool auto_paused = false; |
| 375 | bool auto_muted = false; | 375 | bool auto_muted = false; |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 9746585f5..58b885465 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h | |||
| @@ -20,7 +20,7 @@ enum class MouseButton; | |||
| 20 | 20 | ||
| 21 | class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { | 21 | class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { |
| 22 | public: | 22 | public: |
| 23 | explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem, Core::System& system_); | 23 | explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_); |
| 24 | ~EmuWindow_SDL2(); | 24 | ~EmuWindow_SDL2(); |
| 25 | 25 | ||
| 26 | /// Whether the window is still open, and a close request hasn't yet been sent | 26 | /// Whether the window is still open, and a close request hasn't yet been sent |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 8075c9082..9b660c13c 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp | |||
| @@ -73,9 +73,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { | |||
| 73 | return unsupported_ext.empty(); | 73 | return unsupported_ext.empty(); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, | 76 | EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, |
| 77 | Core::System& system_, bool fullscreen) | 77 | Core::System& system_, bool fullscreen) |
| 78 | : EmuWindow_SDL2{input_subsystem, system_} { | 78 | : EmuWindow_SDL2{input_subsystem_, system_} { |
| 79 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); | 79 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); |
| 80 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); | 80 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); |
| 81 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); | 81 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h index d159166fd..39346e704 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h | |||
| @@ -17,7 +17,7 @@ class InputSubsystem; | |||
| 17 | 17 | ||
| 18 | class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { | 18 | class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { |
| 19 | public: | 19 | public: |
| 20 | explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, Core::System& system_, | 20 | explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, |
| 21 | bool fullscreen); | 21 | bool fullscreen); |
| 22 | ~EmuWindow_SDL2_GL(); | 22 | ~EmuWindow_SDL2_GL(); |
| 23 | 23 | ||
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index d5fe35aa0..65455c86e 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp | |||
| @@ -21,9 +21,9 @@ | |||
| 21 | #include <SDL.h> | 21 | #include <SDL.h> |
| 22 | #include <SDL_syswm.h> | 22 | #include <SDL_syswm.h> |
| 23 | 23 | ||
| 24 | EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem, | 24 | EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, |
| 25 | Core::System& system_, bool fullscreen) | 25 | Core::System& system_, bool fullscreen) |
| 26 | : EmuWindow_SDL2{input_subsystem, system_} { | 26 | : EmuWindow_SDL2{input_subsystem_, system_} { |
| 27 | const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, | 27 | const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, |
| 28 | Common::g_scm_branch, Common::g_scm_desc); | 28 | Common::g_scm_branch, Common::g_scm_desc); |
| 29 | render_window = | 29 | render_window = |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h index d92e3aaab..e39ad754d 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h | |||
| @@ -18,7 +18,7 @@ class InputSubsystem; | |||
| 18 | 18 | ||
| 19 | class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { | 19 | class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { |
| 20 | public: | 20 | public: |
| 21 | explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem, Core::System& system, | 21 | explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, |
| 22 | bool fullscreen); | 22 | bool fullscreen); |
| 23 | ~EmuWindow_SDL2_VK() override; | 23 | ~EmuWindow_SDL2_VK() override; |
| 24 | 24 | ||
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 0dce5e274..e840732e2 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -138,6 +138,12 @@ int main(int argc, char** argv) { | |||
| 138 | 138 | ||
| 139 | Config config{config_path}; | 139 | Config config{config_path}; |
| 140 | 140 | ||
| 141 | // apply the log_filter setting | ||
| 142 | // the logger was initialized before and doesn't pick up the filter on its own | ||
| 143 | Common::Log::Filter filter; | ||
| 144 | filter.ParseFilterString(Settings::values.log_filter.GetValue()); | ||
| 145 | Common::Log::SetGlobalFilter(filter); | ||
| 146 | |||
| 141 | if (!program_args.empty()) { | 147 | if (!program_args.empty()) { |
| 142 | Settings::values.program_args = program_args; | 148 | Settings::values.program_args = program_args; |
| 143 | } | 149 | } |