Merge pull request #19779 from hrydgard/more-depth-work

Depth raster: Some prep for parallelization
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2024-12-29 13:28:26 +01:00
commit 49a18086e3
9 files changed
+132 -33

No files matched your search

+1 -1
View File
@@ -250,7 +250,7 @@ std::vector<File::FileInfo> 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);
}
}
+47
View File
@@ -46,3 +46,50 @@ void ParallelRangeLoop(ThreadManager *threadMan, const std::function<void(int, i
// NOTE: These support a max of 2GB.
void ParallelMemcpy(ThreadManager *threadMan, void *dst, const void *src, size_t bytes, TaskPriority priority = TaskPriority::NORMAL);
void ParallelMemset(ThreadManager *threadMan, void *dst, uint8_t value, size_t bytes, TaskPriority priority = TaskPriority::NORMAL);
template<class T>
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<class T>
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<T>(counter, func, i, count, priority));
}
return counter;
}
// To wait for all tasks to finish: if (counter) counter->WaitAndRelease();
+3
View File
@@ -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);
}
+30 -12
View File
@@ -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<ZCompareMode::Greater>(stats, depth, depthStride, draw.scissor, &tx[i], &ty[i], &tz[i]);
DepthRaster4Triangles<ZCompareMode::Greater>(stats, depth, depthStride, scissor, &tx[i], &ty[i], &tz[i]);
break;
}
case ZCompareMode::Less:
{
DepthRaster4Triangles<ZCompareMode::Less>(stats, depth, depthStride, draw.scissor, &tx[i], &ty[i], &tz[i]);
DepthRaster4Triangles<ZCompareMode::Less>(stats, depth, depthStride, scissor, &tx[i], &ty[i], &tz[i]);
break;
}
case ZCompareMode::Always:
{
DepthRaster4Triangles<ZCompareMode::Always>(stats, depth, depthStride, draw.scissor, &tx[i], &ty[i], &tz[i]);
DepthRaster4Triangles<ZCompareMode::Always>(stats, depth, depthStride, scissor, &tx[i], &ty[i], &tz[i]);
break;
}
}
+5 -3
View File
@@ -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);
+32 -13
View File
@@ -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
+2
View File
@@ -367,4 +367,6 @@ protected:
int depthVertexCount_ = 0;
int depthIndexCount_ = 0;
std::vector<DepthDraw> depthDraws_;
double rasterTimeStart_ = 0.0;
};
+6 -2
View File
@@ -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;
+6 -2
View File
@@ -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,