Skip to content

Commit

Permalink
softjit: Add levels of register locking.
Browse files Browse the repository at this point in the history
Locking also in helpers, so need to nest locks.
  • Loading branch information
unknownbrackets committed Nov 26, 2021
1 parent 1e00a3b commit f881930
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
35 changes: 24 additions & 11 deletions GPU/Software/DrawPixel.cpp
Expand Up @@ -408,19 +408,19 @@ void SOFTPIXEL_CALL DrawSinglePixel(int x, int y, int z, int fog, SOFTPIXEL_VEC4
SetPixelDepth(x, y, z);
} else if (pixelID.stencilTest) {
if (!StencilTestPassed(pixelID, stencil)) {
stencil = ApplyStencilOp(fbFormat, GEStencilOp(pixelID.sFail), stencil);
stencil = ApplyStencilOp(fbFormat, pixelID.SFail(), stencil);
SetPixelStencil(fbFormat, x, y, stencil);
return;
}

// Also apply depth at the same time. If disabled, same as passing.
if (pixelID.DepthTestFunc() != GE_COMP_ALWAYS && !DepthTestPassed(pixelID.DepthTestFunc(), x, y, z)) {
stencil = ApplyStencilOp(fbFormat, GEStencilOp(pixelID.zFail), stencil);
stencil = ApplyStencilOp(fbFormat, pixelID.ZFail(), stencil);
SetPixelStencil(fbFormat, x, y, stencil);
return;
}

stencil = ApplyStencilOp(fbFormat, GEStencilOp(pixelID.zPass), stencil);
stencil = ApplyStencilOp(fbFormat, pixelID.ZPass(), stencil);
} else {
if (pixelID.DepthTestFunc() != GE_COMP_ALWAYS && !DepthTestPassed(pixelID.DepthTestFunc(), x, y, z)) {
return;
Expand Down Expand Up @@ -576,26 +576,28 @@ void PixelRegCache::Reset() {
regs.clear();
}

void PixelRegCache::Release(PixelRegCache::Reg r, PixelRegCache::Type t) {
void PixelRegCache::Release(PixelRegCache::Reg r, PixelRegCache::Type t, PixelRegCache::Purpose p) {
for (auto &reg : regs) {
if (reg.reg == r && reg.type == t) {
reg.purpose = INVALID;
reg.locked = false;
_assert_msg_(reg.locked > 0, "softjit Release() reg that isn't locked");
reg.purpose = p;
reg.locked--;
return;
}
}

RegStatus newStatus;
newStatus.reg = r;
newStatus.purpose = INVALID;
newStatus.purpose = p;
newStatus.type = t;
regs.push_back(newStatus);
}

void PixelRegCache::Unlock(PixelRegCache::Reg r, PixelRegCache::Type t) {
for (auto &reg : regs) {
if (reg.reg == r && reg.type == t) {
reg.locked = false;
_assert_msg_(reg.locked > 0, "softjit Unlock() reg that isn't locked");
reg.locked--;
return;
}
}
Expand All @@ -615,7 +617,8 @@ bool PixelRegCache::Has(PixelRegCache::Purpose p, PixelRegCache::Type t) {
PixelRegCache::Reg PixelRegCache::Find(PixelRegCache::Purpose p, PixelRegCache::Type t) {
for (auto &reg : regs) {
if (reg.purpose == p && reg.type == t) {
reg.locked = true;
_assert_msg_(reg.locked <= 255, "softjit Find() reg has lots of locks");
reg.locked++;
return reg.reg;
}
}
Expand All @@ -627,7 +630,7 @@ PixelRegCache::Reg PixelRegCache::Alloc(PixelRegCache::Purpose p, PixelRegCache:
_assert_msg_(!Has(p, t), "softjit Alloc() reg duplicate");
RegStatus *best = nullptr;
for (auto &reg : regs) {
if (reg.locked || reg.type != t)
if (reg.locked != 0 || reg.forceLocked || reg.type != t)
continue;

if (best == nullptr)
Expand All @@ -640,7 +643,7 @@ PixelRegCache::Reg PixelRegCache::Alloc(PixelRegCache::Purpose p, PixelRegCache:
}

if (best) {
best->locked = true;
best->locked = 1;
best->purpose = p;
return best->reg;
}
Expand All @@ -649,5 +652,15 @@ PixelRegCache::Reg PixelRegCache::Alloc(PixelRegCache::Purpose p, PixelRegCache:
return Reg();
}

void PixelRegCache::ForceLock(PixelRegCache::Purpose p, PixelRegCache::Type t, bool state) {
for (auto &reg : regs) {
if (reg.purpose == p && reg.type == t) {
reg.forceLocked = state;
return;
}
}

_assert_msg_(false, "softjit ForceLock() reg that isn't there");
}

};
8 changes: 6 additions & 2 deletions GPU/Software/DrawPixel.h
Expand Up @@ -66,6 +66,8 @@ struct PixelRegCache {
GSTATE,
CONST_BASE,
ALPHA,
COLOR_OFF,
DEPTH_OFF,

// Above this can only be temps.
TEMP0,
Expand All @@ -90,15 +92,17 @@ struct PixelRegCache {
Reg reg;
Purpose purpose;
Type type;
bool locked = false;
uint8_t locked = 0;
bool forceLocked = false;
};

void Reset();
void Release(Reg r, Type t);
void Release(Reg r, Type t, Purpose p = INVALID);
void Unlock(Reg r, Type t);
bool Has(Purpose p, Type t);
Reg Find(Purpose p, Type t);
Reg Alloc(Purpose p, Type t);
void ForceLock(Purpose p, Type t, bool state = true);

private:
std::vector<RegStatus> regs;
Expand Down

0 comments on commit f881930

Please sign in to comment.