Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor software renderer jit cache to be shared #15180

Merged
merged 12 commits into from
Nov 28, 2021
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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,8 @@ set(GPU_SOURCES
GPU/Software/Rasterizer.h
GPU/Software/RasterizerRectangle.cpp
GPU/Software/RasterizerRectangle.h
GPU/Software/RasterizerRegCache.cpp
GPU/Software/RasterizerRegCache.h
GPU/Software/Sampler.cpp
GPU/Software/Sampler.h
GPU/Software/SoftGpu.cpp
Expand Down
2 changes: 2 additions & 0 deletions GPU/GPU.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@
<ClInclude Include="Software\FuncId.h" />
<ClInclude Include="Software\Rasterizer.h" />
<ClInclude Include="Software\RasterizerRectangle.h" />
<ClInclude Include="Software\RasterizerRegCache.h" />
<ClInclude Include="Software\Sampler.h" />
<ClInclude Include="Software\SoftGpu.h" />
<ClInclude Include="Software\TransformUnit.h" />
Expand Down Expand Up @@ -636,6 +637,7 @@
<ClCompile Include="Software\FuncId.cpp" />
<ClCompile Include="Software\Rasterizer.cpp" />
<ClCompile Include="Software\RasterizerRectangle.cpp" />
<ClCompile Include="Software\RasterizerRegCache.cpp" />
<ClCompile Include="Software\Sampler.cpp" />
<ClCompile Include="Software\SamplerX86.cpp" />
<ClCompile Include="Software\SoftGpu.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions GPU/GPU.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@
<ClInclude Include="Software\DrawPixel.h">
<Filter>Software</Filter>
</ClInclude>
<ClInclude Include="Software\RasterizerRegCache.h">
<Filter>Software</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math3D.cpp">
Expand Down Expand Up @@ -545,5 +548,8 @@
<ClCompile Include="Software\DrawPixelX86.cpp">
<Filter>Software</Filter>
</ClCompile>
<ClCompile Include="Software\RasterizerRegCache.cpp">
<Filter>Software</Filter>
</ClCompile>
</ItemGroup>
</Project>
27 changes: 27 additions & 0 deletions GPU/Math3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class Vec2
#if defined(_M_SSE)
__m128i ivec;
__m128 vec;
#elif PPSSPP_ARCH(ARM64)
int32x4_t ivec;
float32x4_t vec;
#endif
};

Expand All @@ -76,6 +79,11 @@ class Vec2
#if defined(_M_SSE)
Vec2(const __m128 &_vec) : vec(_vec) {}
Vec2(const __m128i &_ivec) : ivec(_ivec) {}
#elif PPSSPP_ARCH(ARM64)
Vec2(const float32x4_t &_vec) : vec(_vec) {}
#if !defined(_MSC_VER)
Vec2(const int32x4_t &_ivec) : ivec(_ivec) {}
#endif
#endif

template<typename T2>
Expand Down Expand Up @@ -204,6 +212,9 @@ class Vec3
#if defined(_M_SSE)
__m128i ivec;
__m128 vec;
#elif PPSSPP_ARCH(ARM64)
int32x4_t ivec;
float32x4_t vec;
#endif
};

Expand All @@ -220,6 +231,14 @@ class Vec3
Vec3(const Vec3Packed<T> &_xyz) {
vec = _mm_loadu_ps(_xyz.AsArray());
}
#elif PPSSPP_ARCH(ARM64)
Vec3(const float32x4_t &_vec) : vec(_vec) {}
#if !defined(_MSC_VER)
Vec3(const int32x4_t &_ivec) : ivec(_ivec) {}
#endif
Vec3(const Vec3Packed<T> &_xyz) {
vec = vld1q_f32(_xyz.AsArray());
}
#else
Vec3(const Vec3Packed<T> &_xyz) : x(_xyz.x), y(_xyz.y), z(_xyz.z) {}
#endif
Expand Down Expand Up @@ -552,6 +571,9 @@ class Vec4
#if defined(_M_SSE)
__m128i ivec;
__m128 vec;
#elif PPSSPP_ARCH(ARM64)
int32x4_t ivec;
float32x4_t vec;
#endif
};

Expand All @@ -566,6 +588,11 @@ class Vec4
#if defined(_M_SSE)
Vec4(const __m128 &_vec) : vec(_vec) {}
Vec4(const __m128i &_ivec) : ivec(_ivec) {}
#elif PPSSPP_ARCH(ARM64)
Vec4(const float32x4_t &_vec) : vec(_vec) {}
#if !defined(_MSC_VER)
Vec4(const int32x4_t &_ivec) : ivec(_ivec) {}
#endif
#endif

template<typename T2>
Expand Down
140 changes: 1 addition & 139 deletions GPU/Software/DrawPixel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ static inline u32 ApplyLogicOp(GELogicOp op, u32 old_color, u32 new_color) {
}

template <bool clearMode, GEBufferFormat fbFormat>
void SOFTPIXEL_CALL DrawSinglePixel(int x, int y, int z, int fog, SOFTPIXEL_VEC4I color_in, const PixelFuncID &pixelID) {
void SOFTRAST_CALL DrawSinglePixel(int x, int y, int z, int fog, Vec4IntArg color_in, const PixelFuncID &pixelID) {
Vec4<int> prim_color = Vec4<int>(color_in).Clamp(0, 255);
// Depth range test - applied in clear mode, if not through mode.
if (pixelID.applyDepthRange)
Expand Down Expand Up @@ -635,142 +635,4 @@ void ComputePixelBlendState(PixelBlendState &state, const PixelFuncID &id) {
}
}

void PixelRegCache::Reset() {
regs.clear();
}

void PixelRegCache::Release(PixelRegCache::Reg r, PixelRegCache::Type t, PixelRegCache::Purpose p) {
RegStatus *status = FindReg(r, t);
if (status) {
_assert_msg_(status->locked > 0, "softjit Release() reg that isn't locked");
_assert_msg_(!status->forceLocked, "softjit Release() reg that is force locked");
status->purpose = p;
status->locked--;
return;
}

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

void PixelRegCache::Unlock(PixelRegCache::Reg r, PixelRegCache::Type t) {
RegStatus *status = FindReg(r, t);
if (status) {
_assert_msg_(status->locked > 0, "softjit Unlock() reg that isn't locked");
status->locked--;
return;
}

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

bool PixelRegCache::Has(PixelRegCache::Purpose p, PixelRegCache::Type t) {
for (auto &reg : regs) {
if (reg.purpose == p && reg.type == t) {
return true;
}
}
return false;
}

PixelRegCache::Reg PixelRegCache::Find(PixelRegCache::Purpose p, PixelRegCache::Type t) {
for (auto &reg : regs) {
if (reg.purpose == p && reg.type == t) {
_assert_msg_(reg.locked <= 255, "softjit Find() reg has lots of locks");
reg.locked++;
return reg.reg;
}
}
_assert_msg_(false, "softjit Find() reg that isn't there (%d)", p);
return Reg(-1);
}

PixelRegCache::Reg PixelRegCache::Alloc(PixelRegCache::Purpose p, PixelRegCache::Type t) {
_assert_msg_(!Has(p, t), "softjit Alloc() reg duplicate");
RegStatus *best = nullptr;
for (auto &reg : regs) {
if (reg.locked != 0 || reg.forceLocked || reg.type != t)
continue;

if (best == nullptr)
best = &reg;
// Prefer a free/purposeless reg.
if (reg.purpose == INVALID || reg.purpose >= TEMP0) {
best = &reg;
break;
}
// But also prefer a lower priority reg.
if (reg.purpose < best->purpose)
best = &reg;
}

if (best) {
best->locked = 1;
best->purpose = p;
return best->reg;
}

_assert_msg_(false, "softjit Alloc() reg with none free (%d)", p);
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");
}

void PixelRegCache::GrabReg(PixelRegCache::Reg r, PixelRegCache::Purpose p, PixelRegCache::Type t, bool &needsSwap, PixelRegCache::Reg swapReg) {
for (auto &reg : regs) {
if (reg.reg != r || reg.type != t)
continue;

// Easy version, it's free.
if (reg.locked == 0 && !reg.forceLocked) {
needsSwap = false;
reg.purpose = p;
reg.locked = 1;
return;
}

// Okay, we need to swap. Find that reg.
needsSwap = true;
RegStatus *swap = FindReg(swapReg, t);
if (swap) {
swap->purpose = reg.purpose;
swap->forceLocked = reg.forceLocked;
swap->locked = reg.locked;
} else {
RegStatus newStatus = reg;
newStatus.reg = swapReg;
regs.push_back(newStatus);
}

reg.purpose = p;
reg.locked = 1;
reg.forceLocked = false;
return;
}

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

PixelRegCache::RegStatus *PixelRegCache::FindReg(PixelRegCache::Reg r, PixelRegCache::Type t) {
for (auto &reg : regs) {
if (reg.reg == r && reg.type == t) {
return &reg;
}
}

return nullptr;
}

};
Loading