Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions GPU/Software/BinManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ void BinManager::AddPoint(const VertexData &v0) {
Expand(range);
}

void BinManager::Drain() {
void BinManager::Drain(bool flushing) {
PROFILE_THIS_SCOPE("bin_drain");

// If the waitable has fully drained, we can update our binning decisions.
Expand Down Expand Up @@ -446,24 +446,32 @@ void BinManager::Drain() {
queue_.SkipNext();
}
} else {
int max = flushing ? QUEUED_PRIMS : QUEUED_PRIMS / 2;
while (!queue_.Empty()) {
const BinItem &item = queue_.PeekNext();
for (int i = 0; i < (int)taskRanges_.size(); ++i) {
const BinCoords range = taskRanges_[i].Intersect(item.range);
if (range.Invalid())
continue;

// This shouldn't often happen, but if it does, wait for space.
if (taskQueues_[i].Full())
waitable_->Wait();
if (taskQueues_[i].NearFull()) {
// This shouldn't often happen, but if it does, wait for space.
if (taskQueues_[i].Full())
waitable_->Wait();
// If we're not flushing and not near full, let's just continue later.
// Near full means we'd drain on next prim, so better to finish it now.
else if (!flushing && !queue_.NearFull())
max = 0;
}

BinItem &taskItem = taskQueues_[i].PeekPush();
taskItem = item;
taskItem.range = range;
taskQueues_[i].PushPeeked();

}
queue_.SkipNext();
if (--max <= 0)
break;
}

int threads = 0;
Expand Down Expand Up @@ -491,7 +499,7 @@ void BinManager::Flush(const char *reason) {
double st;
if (coreCollectDebugStats)
st = time_now_d();
Drain();
Drain(true);
waitable_->Wait();
taskRanges_.clear();
tasksSplit_ = false;
Expand Down
10 changes: 7 additions & 3 deletions GPU/Software/BinManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ struct BinQueue {
return size_ == N - 1;
}

bool NearFull() const {
return size_ >= N - 2;
}

bool Empty() const {
return size_ == 0;
}
Expand Down Expand Up @@ -195,7 +199,7 @@ class BinManager {
void AddLine(const VertexData &v0, const VertexData &v1);
void AddPoint(const VertexData &v0);

void Drain();
void Drain(bool flushing = false);
void Flush(const char *reason);
bool HasPendingWrite(uint32_t start, uint32_t stride, uint32_t w, uint32_t h);
// Assumes you've also checked for a write (writes are partial so are automatically reads.)
Expand Down Expand Up @@ -228,8 +232,8 @@ class BinManager {
static constexpr int QUEUED_STATES = 4096;
// These are 1KB each, so half an MB.
static constexpr int QUEUED_CLUTS = 512;
// About 320 KB, but we have usually 16 or less of them, so 5 MB - 20 MB.
static constexpr int QUEUED_PRIMS = 1024;
// About 360 KB, but we have usually 16 or less of them, so 5 MB - 22 MB.
static constexpr int QUEUED_PRIMS = 2048;

typedef BinQueue<Rasterizer::RasterizerState, QUEUED_STATES> BinStateQueue;
typedef BinQueue<BinClut, QUEUED_CLUTS> BinClutQueue;
Expand Down