diff --git a/src/Cafe/OS/libs/gx2/GX2_Blit.cpp b/src/Cafe/OS/libs/gx2/GX2_Blit.cpp index c8080f38..db21c9af 100644 --- a/src/Cafe/OS/libs/gx2/GX2_Blit.cpp +++ b/src/Cafe/OS/libs/gx2/GX2_Blit.cpp @@ -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()