diff --git a/Common/File/AndroidStorage.cpp b/Common/File/AndroidStorage.cpp index 477ae13ac3..5d295a31ce 100644 --- a/Common/File/AndroidStorage.cpp +++ b/Common/File/AndroidStorage.cpp @@ -250,7 +250,7 @@ std::vector Android_ListContentUri(const std::string &uri, const } else if (ParseFileInfo(line, &info)) { // We can just reconstruct the URI. info.fullName = Path(uri) / info.name; - INFO_LOG(Log::FileSystem, "%s", info.name.c_str()); + // INFO_LOG(Log::FileSystem, "%s", info.name.c_str()); items.push_back(info); } } diff --git a/Common/Thread/ParallelLoop.h b/Common/Thread/ParallelLoop.h index 0e2d52b37b..3f599b6713 100644 --- a/Common/Thread/ParallelLoop.h +++ b/Common/Thread/ParallelLoop.h @@ -46,3 +46,50 @@ void ParallelRangeLoop(ThreadManager *threadMan, const std::function +class SimpleParallelTask : public Task { +public: + SimpleParallelTask(WaitableCounter *counter, T func, int index, int count, TaskPriority p) + : counter_(counter), func_(func), index_(index), count_(count), priority_(p) { + } + + TaskType Type() const override { + return TaskType::CPU_COMPUTE; + } + + TaskPriority Priority() const override { + return priority_; + } + + void Run() override { + func_(index_, count_); + counter_->Count(); + } + + T func_; + WaitableCounter *counter_; + + int index_; + int count_; + const TaskPriority priority_; +}; + +template +WaitableCounter *RunParallel(ThreadManager *threadMan, T func, int count, TaskPriority priority = TaskPriority::NORMAL) { + if (count == 1) { + func(0, 1); + return nullptr; + } + + WaitableCounter *counter = new WaitableCounter(count); + + for (int i = 0; i < count; i++) { + threadMan->EnqueueTaskOnThread(i, new SimpleParallelTask(counter, func, i, count, priority)); + } + + return counter; +} + +// To wait for all tasks to finish: if (counter) counter->WaitAndRelease(); diff --git a/Core/HW/MemoryStick.cpp b/Core/HW/MemoryStick.cpp index 643c97e865..1018284534 100644 --- a/Core/HW/MemoryStick.cpp +++ b/Core/HW/MemoryStick.cpp @@ -31,6 +31,7 @@ #include "Core/HW/MemoryStick.h" #include "Core/System.h" #include "Common/CommonTypes.h" +#include "Common/TimeUtil.h" #include "Common/Thread/Promise.h" // MS and FatMS states. @@ -108,6 +109,7 @@ static uint64_t ComputeSizeOfSavedataForGame(const Path &saveFolder, const std:: } u64 MemoryStick_FreeSpace(std::string gameID) { + double start = time_now_d(); INFO_LOG(Log::IO, "Calculating free disk space (%s)", gameID.c_str()); const CompatFlags &flags = PSP_CoreParameter().compat.flags(); @@ -143,6 +145,7 @@ u64 MemoryStick_FreeSpace(std::string gameID) { realFreeSpace = memstickInitialFree - memstickCurrentUse; } } + INFO_LOG(Log::IO, "Done calculating free disk space (%0.3f s)", time_now_d() - start); return std::min(simulatedFreeSpace, realFreeSpace); } diff --git a/GPU/Common/DepthRaster.cpp b/GPU/Common/DepthRaster.cpp index fa706807ed..b464e3012b 100644 --- a/GPU/Common/DepthRaster.cpp +++ b/GPU/Common/DepthRaster.cpp @@ -8,6 +8,24 @@ #include "Common/Math/math_util.h" #include "GPU/Common/VertexDecoderCommon.h" +DepthScissor DepthScissor::Tile(int tile, int numTiles) const { + if (numTiles == 1) { + return *this; + } + // First tiling algorithm: Split into vertical slices. + int w = x2 - x1; + int tileW = (w / numTiles) & ~3; // Round to four pixels. + + // TODO: Should round x1 to four pixels as well! except the first one + + DepthScissor scissor; + scissor.x1 = x1 + tileW * tile; + scissor.x2 = (tile == numTiles - 1) ? x2 : (x1 + tileW * (tile + 1)); + scissor.y1 = y1; + scissor.y2 = y2; + return scissor; +} + // x1/x2 etc are the scissor rect. static void DepthRasterRect(uint16_t *dest, int stride, const DepthScissor scissor, int v1x, int v1y, int v2x, int v2y, short depthValue, ZCompareMode compareMode) { // Swap coordinates if needed, we don't back-face-cull rects. @@ -279,7 +297,7 @@ void ConvertPredecodedThroughForDepthRaster(float *dest, const void *decodedVert } } -int DepthRasterClipIndexedRectangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw) { +int DepthRasterClipIndexedRectangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw, const DepthScissor scissor) { int outCount = 0; const int count = draw.vertexCount; for (int i = 0; i < count; i += 2) { @@ -316,7 +334,7 @@ int DepthRasterClipIndexedRectangles(int *tx, int *ty, float *tz, const float *t return outCount; } -int DepthRasterClipIndexedTriangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw) { +int DepthRasterClipIndexedTriangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw, const DepthScissor scissor) { int outCount = 0; int flipCull = 0; @@ -333,10 +351,10 @@ int DepthRasterClipIndexedTriangles(int *tx, int *ty, float *tz, const float *tr const float *verts[12]; // four triangles at a time! const int count = draw.vertexCount; - Vec4F32 scissorX1 = Vec4F32::Splat((float)draw.scissor.x1); - Vec4F32 scissorY1 = Vec4F32::Splat((float)draw.scissor.y1); - Vec4F32 scissorX2 = Vec4F32::Splat((float)draw.scissor.x2); - Vec4F32 scissorY2 = Vec4F32::Splat((float)draw.scissor.y2); + Vec4F32 scissorX1 = Vec4F32::Splat((float)scissor.x1); + Vec4F32 scissorY1 = Vec4F32::Splat((float)scissor.y1); + Vec4F32 scissorX2 = Vec4F32::Splat((float)scissor.x2); + Vec4F32 scissorY2 = Vec4F32::Splat((float)scissor.y2); for (int i = 0; i < count; i += 3) { // Collect valid triangles into buffer. @@ -407,7 +425,7 @@ int DepthRasterClipIndexedTriangles(int *tx, int *ty, float *tz, const float *tr Vec4S32 maxX = Vec4S32FromF32(x0.Max(x1.Max(x2)).Min(scissorX2)); Vec4S32 maxY = Vec4S32FromF32(y0.Max(y1.Max(y2)).Min(scissorY2)); - // If all are equal in any dimension, all four triangles are tiny nonsense and can be skipped early. + // If all are equal in any dimension, all four triangles are tiny nonsense (or outside the scissor) and can be skipped early. Vec4S32 eqMask = minX.CompareEq(maxX) | minY.CompareEq(maxY); // Otherwise we just proceed to triangle setup with all four for now. Later might want to // compact the remaining triangles... Or do more checking here. @@ -459,7 +477,7 @@ int DepthRasterClipIndexedTriangles(int *tx, int *ty, float *tz, const float *tr } // Rasterizes screen-space vertices. -void DepthRasterScreenVerts(uint16_t *depth, int depthStride, const int *tx, const int *ty, const float *tz, int count, const DepthDraw &draw) { +void DepthRasterScreenVerts(uint16_t *depth, int depthStride, const int *tx, const int *ty, const float *tz, int count, const DepthDraw &draw, const DepthScissor scissor) { // Prim should now be either TRIANGLES or RECTs. _dbg_assert_(draw.prim == GE_PRIM_RECTANGLES || draw.prim == GE_PRIM_TRIANGLES); @@ -469,7 +487,7 @@ void DepthRasterScreenVerts(uint16_t *depth, int depthStride, const int *tx, con uint16_t z = (uint16_t)tz[i + 1]; // depth from second vertex // TODO: Should clip coordinates to the scissor rectangle. // We remove the subpixel information here. - DepthRasterRect(depth, depthStride, draw.scissor, tx[i], ty[i], tx[i + 1], ty[i + 1], z, draw.compareMode); + DepthRasterRect(depth, depthStride, scissor, tx[i], ty[i], tx[i + 1], ty[i + 1], z, draw.compareMode); } gpuStats.numDepthRasterPrims += count / 2; break; @@ -481,17 +499,17 @@ void DepthRasterScreenVerts(uint16_t *depth, int depthStride, const int *tx, con switch (draw.compareMode) { case ZCompareMode::Greater: { - DepthRaster4Triangles(stats, depth, depthStride, draw.scissor, &tx[i], &ty[i], &tz[i]); + DepthRaster4Triangles(stats, depth, depthStride, scissor, &tx[i], &ty[i], &tz[i]); break; } case ZCompareMode::Less: { - DepthRaster4Triangles(stats, depth, depthStride, draw.scissor, &tx[i], &ty[i], &tz[i]); + DepthRaster4Triangles(stats, depth, depthStride, scissor, &tx[i], &ty[i], &tz[i]); break; } case ZCompareMode::Always: { - DepthRaster4Triangles(stats, depth, depthStride, draw.scissor, &tx[i], &ty[i], &tz[i]); + DepthRaster4Triangles(stats, depth, depthStride, scissor, &tx[i], &ty[i], &tz[i]); break; } } diff --git a/GPU/Common/DepthRaster.h b/GPU/Common/DepthRaster.h index 104ccec36f..95404f530f 100644 --- a/GPU/Common/DepthRaster.h +++ b/GPU/Common/DepthRaster.h @@ -26,6 +26,8 @@ struct DepthScissor { u16 y1; u16 x2; u16 y2; + + DepthScissor Tile(int tile, int numTiles) const; }; struct DepthDraw { @@ -49,9 +51,9 @@ struct DepthDraw { class VertexDecoder; struct TransformedVertex; -int DepthRasterClipIndexedTriangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw); -int DepthRasterClipIndexedRectangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw); +int DepthRasterClipIndexedTriangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw, const DepthScissor scissor); +int DepthRasterClipIndexedRectangles(int *tx, int *ty, float *tz, const float *transformed, const uint16_t *indexBuffer, const DepthDraw &draw, const DepthScissor scissor); void DecodeAndTransformForDepthRaster(float *dest, const float *worldviewproj, const void *vertexData, int indexLowerBound, int indexUpperBound, VertexDecoder *dec, u32 vertTypeID); void TransformPredecodedForDepthRaster(float *dest, const float *worldviewproj, const void *decodedVertexData, VertexDecoder *dec, int count); void ConvertPredecodedThroughForDepthRaster(float *dest, const void *decodedVertexData, VertexDecoder *dec, int count); -void DepthRasterScreenVerts(uint16_t *depth, int depthStride, const int *tx, const int *ty, const float *tz, int count, const DepthDraw &draw); +void DepthRasterScreenVerts(uint16_t *depth, int depthStride, const int *tx, const int *ty, const float *tz, int count, const DepthDraw &draw, const DepthScissor scissor); diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index 357736b9b2..bf7c97d8d8 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -1042,6 +1042,10 @@ void DrawEngineCommon::DepthRasterTransform(GEPrimitiveType prim, VertexDecoder depthIndexCount_ += vertexCount; depthVertexCount_ += numDecoded; + if (depthDraws_.empty()) { + rasterTimeStart_ = time_now_d(); + } + depthDraws_.push_back(draw); // FlushQueuedDepth(); @@ -1081,11 +1085,19 @@ void DrawEngineCommon::DepthRasterPredecoded(GEPrimitiveType prim, const void *i depthDraws_.push_back(draw); + if (depthDraws_.empty()) { + rasterTimeStart_ = time_now_d(); + } // FlushQueuedDepth(); } void DrawEngineCommon::FlushQueuedDepth() { - TimeCollector collectStat(&gpuStats.msRasterizeDepth, coreCollectDebugStats); + if (rasterTimeStart_ != 0.0) { + gpuStats.msRasterTimeAvailable += time_now_d() - rasterTimeStart_; + rasterTimeStart_ = 0.0; + } + + const bool collectStats = coreCollectDebugStats; for (const auto &draw : depthDraws_) { int *tx = depthScreenVerts_; @@ -1097,19 +1109,26 @@ void DrawEngineCommon::FlushQueuedDepth() { const float *vertices = depthTransformed_ + 4 * draw.vertexOffset; const uint16_t *indices = depthIndices_ + draw.indexOffset; - switch (draw.prim) { - case GE_PRIM_RECTANGLES: - outVertCount = DepthRasterClipIndexedRectangles(tx, ty, tz, vertices, indices, draw); - break; - case GE_PRIM_TRIANGLES: - outVertCount = DepthRasterClipIndexedTriangles(tx, ty, tz, vertices, indices, draw); - break; - default: - _dbg_assert_(false); - break; + DepthScissor tileScissor = draw.scissor.Tile(0, 1); + + { + TimeCollector collectStat(&gpuStats.msCullDepth, collectStats); + switch (draw.prim) { + case GE_PRIM_RECTANGLES: + outVertCount = DepthRasterClipIndexedRectangles(tx, ty, tz, vertices, indices, draw, tileScissor); + break; + case GE_PRIM_TRIANGLES: + outVertCount = DepthRasterClipIndexedTriangles(tx, ty, tz, vertices, indices, draw, tileScissor); + break; + default: + _dbg_assert_(false); + break; + } + } + { + TimeCollector collectStat(&gpuStats.msRasterizeDepth, collectStats); + DepthRasterScreenVerts((uint16_t *)Memory::GetPointerWrite(draw.depthAddr), draw.depthStride, tx, ty, tz, outVertCount, draw, tileScissor); } - // TODO: Could potentially split into tasks here! - DepthRasterScreenVerts((uint16_t *)Memory::GetPointerWrite(draw.depthAddr), draw.depthStride, tx, ty, tz, outVertCount, draw); } // Reset queue diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index 8b56f3cd65..e927a82e9a 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -367,4 +367,6 @@ protected: int depthVertexCount_ = 0; int depthIndexCount_ = 0; std::vector depthDraws_; + + double rasterTimeStart_ = 0.0; }; diff --git a/GPU/GPU.h b/GPU/GPU.h index cbf5bc93a1..506f0d9c38 100644 --- a/GPU/GPU.h +++ b/GPU/GPU.h @@ -108,8 +108,10 @@ struct GPUStatistics { numCachedReplacedTextures = 0; numClutTextures = 0; msProcessingDisplayLists = 0; - msPrepareDepth = 0.0f; - msRasterizeDepth = 0.0f; + msPrepareDepth = 0.0; + msCullDepth = 0.0; + msRasterizeDepth = 0.0; + msRasterTimeAvailable = 0.0; numDepthRasterPrims = 0; numDepthRasterEarlySize = 0; numDepthRasterNoPixels = 0; @@ -156,7 +158,9 @@ struct GPUStatistics { int numClutTextures; double msProcessingDisplayLists; double msPrepareDepth; + double msCullDepth; double msRasterizeDepth; + double msRasterTimeAvailable; int vertexGPUCycles; int otherGPUCycles; int numDepthRasterPrims; diff --git a/GPU/GPUCommonHW.cpp b/GPU/GPUCommonHW.cpp index c665f379a2..a58d5c3e28 100644 --- a/GPU/GPUCommonHW.cpp +++ b/GPU/GPUCommonHW.cpp @@ -1763,7 +1763,7 @@ void GPUCommonHW::Execute_BoneMtxData(u32 op, u32 diff) { gstate_c.Dirty(DIRTY_BONEMATRIX0 << (num / 12)); } else { gstate_c.deferredVertTypeDirty |= DIRTY_BONEMATRIX0 << (num / 12); - } + } ((u32 *)gstate.boneMatrix)[num] = newVal; } num++; @@ -1801,7 +1801,8 @@ size_t GPUCommonHW::FormatGPUStatsCommon(char *buffer, size_t size) { "replacer: tracks %d references, %d unique textures\n" "Cpy: depth %d, color %d, reint %d, blend %d, self %d\n" "GPU cycles: %d (%0.1f per vertex)\n" - "Z-rast: %0.2f/%0.2f ms, %d prim, %d nopix, %d small, %d earlysize, %d zcull, %d box\n%s", + "Z-rast: %0.2f+%0.2f+%0.2f (total %0.2f/%0.2f) ms\n" + "Z-rast: %d prim, %d nopix, %d small, %d earlysize, %d zcull, %d box\n%s", gpuStats.msProcessingDisplayLists * 1000.0f, gpuStats.numDrawSyncs, gpuStats.numListSyncs, @@ -1839,7 +1840,10 @@ size_t GPUCommonHW::FormatGPUStatsCommon(char *buffer, size_t size) { gpuStats.vertexGPUCycles + gpuStats.otherGPUCycles, vertexAverageCycles, gpuStats.msPrepareDepth * 1000.0, + gpuStats.msCullDepth * 1000.0, gpuStats.msRasterizeDepth * 1000.0, + (gpuStats.msPrepareDepth + gpuStats.msCullDepth + gpuStats.msRasterizeDepth) * 1000.0, + gpuStats.msRasterTimeAvailable * 1000.0, gpuStats.numDepthRasterPrims, gpuStats.numDepthRasterNoPixels, gpuStats.numDepthRasterTooSmall,