Latte: Refactor clear code

This commit is contained in:
Exzap 2025-05-10 13:58:43 +02:00
parent 111637a9fd
commit 96765e4ac6

View file

@ -82,35 +82,89 @@ namespace GX2
}
}
void GX2ClearColor(GX2ColorBuffer* colorBuffer, float r, float g, float b, float a)
void SubmitHLEClear(GX2ColorBuffer* colorBuffer, float colorRGBA[4], GX2DepthBuffer* depthBuffer, float depthClearValue, uint8 stencilClearValue, bool clearColor, bool clearDepth, bool clearStencil)
{
GX2ReserveCmdSpace(50);
uint32 hleClearFlags = 0;
if (clearColor)
hleClearFlags |= 1;
if (clearDepth)
hleClearFlags |= 2;
if (clearStencil)
hleClearFlags |= 4;
// color buffer
MPTR colorPhysAddr = MPTR_NULL;
uint32 colorFormat = 0;
uint32 colorTileMode = 0;
uint32 colorWidth = 0;
uint32 colorHeight = 0;
uint32 colorPitch = 0;
uint32 colorFirstSlice = 0;
uint32 colorNumSlices = 0;
if (colorBuffer != nullptr)
{
colorPhysAddr = memory_virtualToPhysical(colorBuffer->surface.imagePtr);
colorFormat = (uint32)colorBuffer->surface.format.value();
colorTileMode = (uint32)colorBuffer->surface.tileMode.value();
colorWidth = colorBuffer->surface.width;
colorHeight = colorBuffer->surface.height;
colorPitch = colorBuffer->surface.pitch;
colorFirstSlice = _swapEndianU32(colorBuffer->viewFirstSlice);
colorNumSlices = _swapEndianU32(colorBuffer->viewNumSlices);
}
// depth buffer
MPTR depthPhysAddr = MPTR_NULL;
uint32 depthFormat = 0;
uint32 depthTileMode = 0;
uint32 depthWidth = 0;
uint32 depthHeight = 0;
uint32 depthPitch = 0;
uint32 depthFirstSlice = 0;
uint32 depthNumSlices = 0;
if (depthBuffer != nullptr)
{
depthPhysAddr = memory_virtualToPhysical(depthBuffer->surface.imagePtr);
depthFormat = (uint32)depthBuffer->surface.format.value();
depthTileMode = (uint32)depthBuffer->surface.tileMode.value();
depthWidth = depthBuffer->surface.width;
depthHeight = depthBuffer->surface.height;
depthPitch = depthBuffer->surface.pitch;
depthFirstSlice = _swapEndianU32(depthBuffer->viewFirstSlice);
depthNumSlices = _swapEndianU32(depthBuffer->viewNumSlices);
}
gx2WriteGather_submit(pm4HeaderType3(IT_HLE_CLEAR_COLOR_DEPTH_STENCIL, 23),
hleClearFlags,
colorPhysAddr,
colorFormat,
colorTileMode,
colorWidth,
colorHeight,
colorPitch,
colorFirstSlice,
colorNumSlices,
depthPhysAddr,
depthFormat,
depthTileMode,
depthWidth,
depthHeight,
depthPitch,
depthFirstSlice,
depthNumSlices,
(uint32)(colorRGBA[0] * 255.0f),
(uint32)(colorRGBA[1] * 255.0f),
(uint32)(colorRGBA[2] * 255.0f),
(uint32)(colorRGBA[3] * 255.0f),
*(uint32*)&depthClearValue,
stencilClearValue&0xFF);
}
void GX2ClearColor(GX2ColorBuffer* colorBuffer, float r, float g, float b, float a)
{
if ((colorBuffer->surface.resFlag & GX2_RESFLAG_USAGE_COLOR_BUFFER) != 0)
{
gx2WriteGather_submitU32AsBE(pm4HeaderType3(IT_HLE_CLEAR_COLOR_DEPTH_STENCIL, 23));
gx2WriteGather_submitU32AsBE(1); // color (1)
gx2WriteGather_submitU32AsBE(memory_virtualToPhysical(colorBuffer->surface.imagePtr));
gx2WriteGather_submitU32AsBE((uint32)colorBuffer->surface.format.value());
gx2WriteGather_submitU32AsBE((uint32)colorBuffer->surface.tileMode.value());
gx2WriteGather_submitU32AsBE(colorBuffer->surface.width);
gx2WriteGather_submitU32AsBE(colorBuffer->surface.height);
gx2WriteGather_submitU32AsBE(colorBuffer->surface.pitch);
gx2WriteGather_submitU32AsBE(_swapEndianU32(colorBuffer->viewFirstSlice));
gx2WriteGather_submitU32AsBE(_swapEndianU32(colorBuffer->viewNumSlices));
gx2WriteGather_submitU32AsBE(MPTR_NULL);
gx2WriteGather_submitU32AsBE(0); // depth buffer format
gx2WriteGather_submitU32AsBE(0); // tilemode for depth buffer
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE((uint32)(r * 255.0f));
gx2WriteGather_submitU32AsBE((uint32)(g * 255.0f));
gx2WriteGather_submitU32AsBE((uint32)(b * 255.0f));
gx2WriteGather_submitU32AsBE((uint32)(a * 255.0f));
gx2WriteGather_submitU32AsBE(0); // clear depth
gx2WriteGather_submitU32AsBE(0); // clear stencil
float colorRGBA[4] = { r, g, b, a };
SubmitHLEClear(colorBuffer, colorRGBA, nullptr, 0.0f, 0, true, false, false);
}
else
{
@ -120,7 +174,6 @@ namespace GX2
void GX2ClearBuffersEx(GX2ColorBuffer* colorBuffer, GX2DepthBuffer* depthBuffer, float r, float g, float b, float a, float depthClearValue, uint8 stencilClearValue, GX2ClearFlags clearFlags)
{
GX2ReserveCmdSpace(50);
_updateDepthStencilClearRegs(depthClearValue, stencilClearValue, clearFlags);
uint32 hleClearFlags = 0;
@ -130,42 +183,13 @@ namespace GX2
hleClearFlags |= 4;
hleClearFlags |= 1;
// send command to clear color, depth and stencil
if (_swapEndianU32(colorBuffer->viewFirstSlice) != 0)
debugBreakpoint();
gx2WriteGather_submitU32AsBE(pm4HeaderType3(IT_HLE_CLEAR_COLOR_DEPTH_STENCIL, 23));
gx2WriteGather_submitU32AsBE(hleClearFlags); // color (1), depth (2), stencil (4)
gx2WriteGather_submitU32AsBE(memory_virtualToPhysical(colorBuffer->surface.imagePtr));
gx2WriteGather_submitU32AsBE((uint32)colorBuffer->surface.format.value());
gx2WriteGather_submitU32AsBE((uint32)colorBuffer->surface.tileMode.value());
gx2WriteGather_submitU32AsBE((uint32)colorBuffer->surface.width);
gx2WriteGather_submitU32AsBE((uint32)colorBuffer->surface.height);
gx2WriteGather_submitU32AsBE((uint32)colorBuffer->surface.pitch);
gx2WriteGather_submitU32AsBE(_swapEndianU32(colorBuffer->viewFirstSlice));
gx2WriteGather_submitU32AsBE(_swapEndianU32(colorBuffer->viewNumSlices));
gx2WriteGather_submitU32AsBE(memory_virtualToPhysical(depthBuffer->surface.imagePtr));
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.format.value());
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.tileMode.value());
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.width);
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.height);
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.pitch);
gx2WriteGather_submitU32AsBE(_swapEndianU32(depthBuffer->viewFirstSlice));
gx2WriteGather_submitU32AsBE(_swapEndianU32(depthBuffer->viewNumSlices));
gx2WriteGather_submitU32AsBE((uint32)(r * 255.0f));
gx2WriteGather_submitU32AsBE((uint32)(g * 255.0f));
gx2WriteGather_submitU32AsBE((uint32)(b * 255.0f));
gx2WriteGather_submitU32AsBE((uint32)(a * 255.0f));
gx2WriteGather_submitU32AsBE(*(uint32*)&depthClearValue); // clear depth
gx2WriteGather_submitU32AsBE(stencilClearValue&0xFF); // clear stencil
float colorRGBA[4] = { r, g, b, a };
SubmitHLEClear(colorBuffer, colorRGBA, depthBuffer, depthClearValue, stencilClearValue, true, (clearFlags & GX2ClearFlags::CLEAR_DEPTH) != 0, (clearFlags & GX2ClearFlags::CLEAR_STENCIL) != 0);
}
// always uses passed depthClearValue/stencilClearValue for clearing, even if clear flags dont specify value updates
void GX2ClearDepthStencilEx(GX2DepthBuffer* depthBuffer, float depthClearValue, uint8 stencilClearValue, GX2ClearFlags clearFlags)
{
GX2ReserveCmdSpace(50);
if (!depthBuffer && (depthBuffer->surface.width == 0 || depthBuffer->surface.height == 0))
{
// Super Smash Bros tries to clear an uninitialized depth surface?
@ -175,41 +199,8 @@ namespace GX2
_updateDepthStencilClearRegs(depthClearValue, stencilClearValue, clearFlags);
uint32 hleClearFlags = 0;
if ((clearFlags & GX2ClearFlags::CLEAR_DEPTH) != 0)
hleClearFlags |= 2;
if ((clearFlags & GX2ClearFlags::CLEAR_STENCIL) != 0)
hleClearFlags |= 4;
// send command to clear color, depth and stencil
if (hleClearFlags != 0)
{
gx2WriteGather_submitU32AsBE(pm4HeaderType3(IT_HLE_CLEAR_COLOR_DEPTH_STENCIL, 23));
gx2WriteGather_submitU32AsBE(hleClearFlags); // color (1), depth (2), stencil (4)
gx2WriteGather_submitU32AsBE(MPTR_NULL);
gx2WriteGather_submitU32AsBE(0); // format for color buffer
gx2WriteGather_submitU32AsBE(0); // tilemode for color buffer
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(memory_virtualToPhysical(depthBuffer->surface.imagePtr));
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.format.value());
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.tileMode.value());
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.width);
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.height);
gx2WriteGather_submitU32AsBE((uint32)depthBuffer->surface.pitch);
gx2WriteGather_submitU32AsBE(_swapEndianU32(depthBuffer->viewFirstSlice));
gx2WriteGather_submitU32AsBE(_swapEndianU32(depthBuffer->viewNumSlices));
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(0);
gx2WriteGather_submitU32AsBE(*(uint32*)&depthClearValue); // clear depth
gx2WriteGather_submitU32AsBE(stencilClearValue & 0xFF); // clear stencil
}
float colorRGBA[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
SubmitHLEClear(nullptr, colorRGBA, depthBuffer, depthClearValue, stencilClearValue, false, (clearFlags & GX2ClearFlags::CLEAR_DEPTH) != 0, (clearFlags & GX2ClearFlags::CLEAR_STENCIL) != 0);
}
void GX2BlitInit()