mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #19779 from hrydgard/more-depth-work
Depth raster: Some prep for parallelization
This commit is contained in:
9 files changed
+132
-33
No files matched your search
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
|
||||
@@ -367,4 +367,6 @@ protected:
|
||||
int depthVertexCount_ = 0;
|
||||
int depthIndexCount_ = 0;
|
||||
std::vector<DepthDraw> depthDraws_;
|
||||
|
||||
double rasterTimeStart_ = 0.0;
|
||||
};
|
||||
@@ -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
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user