2023-08-03 15:40:22 -04:00
|
|
|
#pragma once
|
|
|
|
|
2024-02-22 08:43:21 -05:00
|
|
|
#include "maybe_unused.h"
|
2023-08-03 15:40:22 -04:00
|
|
|
#include "GSHandler.h"
|
|
|
|
|
|
|
|
namespace GsTransfer
|
|
|
|
{
|
|
|
|
struct TransferRangeSrc
|
|
|
|
{
|
|
|
|
static uint32 GetBufferAddress(const CGSHandler::BITBLTBUF& bltBuf)
|
|
|
|
{
|
|
|
|
return bltBuf.GetSrcPtr();
|
|
|
|
}
|
|
|
|
static uint32 GetBufferWidth(const CGSHandler::BITBLTBUF& bltBuf)
|
|
|
|
{
|
|
|
|
return bltBuf.GetSrcWidth();
|
|
|
|
}
|
|
|
|
static uint32 GetBufferPsm(const CGSHandler::BITBLTBUF& bltBuf)
|
|
|
|
{
|
|
|
|
return bltBuf.nSrcPsm;
|
|
|
|
}
|
|
|
|
static uint32 GetSAX(const CGSHandler::TRXPOS& trxPos)
|
|
|
|
{
|
|
|
|
return trxPos.nSSAX;
|
|
|
|
}
|
|
|
|
static uint32 GetSAY(const CGSHandler::TRXPOS& trxPos)
|
|
|
|
{
|
|
|
|
return trxPos.nSSAY;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TransferRangeDst
|
|
|
|
{
|
|
|
|
static uint32 GetBufferAddress(const CGSHandler::BITBLTBUF& bltBuf)
|
|
|
|
{
|
|
|
|
return bltBuf.GetDstPtr();
|
|
|
|
}
|
|
|
|
static uint32 GetBufferWidth(const CGSHandler::BITBLTBUF& bltBuf)
|
|
|
|
{
|
|
|
|
return bltBuf.GetDstWidth();
|
|
|
|
}
|
|
|
|
static uint32 GetBufferPsm(const CGSHandler::BITBLTBUF& bltBuf)
|
|
|
|
{
|
|
|
|
return bltBuf.nDstPsm;
|
|
|
|
}
|
|
|
|
static uint32 GetSAX(const CGSHandler::TRXPOS& trxPos)
|
|
|
|
{
|
|
|
|
return trxPos.nDSAX;
|
|
|
|
}
|
|
|
|
static uint32 GetSAY(const CGSHandler::TRXPOS& trxPos)
|
|
|
|
{
|
|
|
|
return trxPos.nDSAY;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename TransferRangeTraits>
|
|
|
|
static std::pair<uint32, uint32> GetRange(const CGSHandler::BITBLTBUF& bltBuf, const CGSHandler::TRXREG& trxReg, const CGSHandler::TRXPOS& trxPos)
|
|
|
|
{
|
|
|
|
uint32 transferAddress = TransferRangeTraits::GetBufferAddress(bltBuf);
|
|
|
|
uint32 psm = TransferRangeTraits::GetBufferPsm(bltBuf);
|
|
|
|
|
|
|
|
//Find the pages that are touched by this transfer
|
|
|
|
auto transferPageSize = CGsPixelFormats::GetPsmPageSize(psm);
|
|
|
|
|
|
|
|
// DBZ Budokai Tenkaichi 2 and 3 use invalid (empty) buffer sizes
|
|
|
|
// Account for that, by assuming trxReg.nRRW.
|
|
|
|
auto width = TransferRangeTraits::GetBufferWidth(bltBuf);
|
|
|
|
if(width == 0)
|
|
|
|
{
|
|
|
|
width = trxReg.nRRW;
|
|
|
|
}
|
|
|
|
|
2023-08-15 12:03:12 -04:00
|
|
|
assert(trxReg.nRRW != 0);
|
|
|
|
assert(trxReg.nRRH != 0);
|
|
|
|
|
|
|
|
//Since there's a possibility of using RRW for the buffer width, we need to round up
|
|
|
|
uint32 pagePitch = (width + transferPageSize.first - 1) / transferPageSize.first;
|
|
|
|
|
2023-08-03 15:40:22 -04:00
|
|
|
uint32 sax = TransferRangeTraits::GetSAX(trxPos);
|
|
|
|
uint32 say = TransferRangeTraits::GetSAY(trxPos);
|
|
|
|
|
2023-08-15 12:03:12 -04:00
|
|
|
uint32 pageStartX = sax / transferPageSize.first;
|
|
|
|
uint32 pageStartY = say / transferPageSize.second;
|
|
|
|
uint32 pageEndX = (sax + trxReg.nRRW - 1) / transferPageSize.first;
|
|
|
|
uint32 pageEndY = (say + trxReg.nRRH - 1) / transferPageSize.second;
|
2023-08-03 15:40:22 -04:00
|
|
|
|
2023-08-15 12:03:12 -04:00
|
|
|
//Single page transfer
|
|
|
|
if((pageStartX == pageEndX) && (pageStartY == pageEndY))
|
|
|
|
{
|
|
|
|
uint32 transferPage = (pageStartY * pagePitch) + pageStartX;
|
|
|
|
uint32 transferOffset = transferPage * CGsPixelFormats::PAGESIZE;
|
|
|
|
return std::make_pair(transferAddress + transferOffset, CGsPixelFormats::PAGESIZE);
|
|
|
|
}
|
2023-08-03 15:40:22 -04:00
|
|
|
|
2023-08-15 12:03:12 -04:00
|
|
|
uint32 pageCountY = pageEndY - pageStartY + 1;
|
2023-08-03 15:40:22 -04:00
|
|
|
|
2023-08-15 12:03:12 -04:00
|
|
|
uint32 pageCount = pagePitch * pageCountY;
|
2023-08-03 15:40:22 -04:00
|
|
|
uint32 transferSize = pageCount * CGsPixelFormats::PAGESIZE;
|
2023-08-21 10:50:54 -04:00
|
|
|
uint32 transferOffset = ((pageStartY * pagePitch) + pageStartX) * CGsPixelFormats::PAGESIZE;
|
2023-08-03 15:40:22 -04:00
|
|
|
|
|
|
|
return std::make_pair(transferAddress + transferOffset, transferSize);
|
|
|
|
}
|
|
|
|
|
2024-02-22 08:43:21 -05:00
|
|
|
FRAMEWORK_MAYBE_UNUSED
|
2023-08-03 15:40:22 -04:00
|
|
|
static auto GetSrcRange(const CGSHandler::BITBLTBUF& bltBuf, const CGSHandler::TRXREG& trxReg, const CGSHandler::TRXPOS& trxPos)
|
|
|
|
{
|
|
|
|
return GetRange<TransferRangeSrc>(bltBuf, trxReg, trxPos);
|
|
|
|
}
|
|
|
|
|
2024-02-22 08:43:21 -05:00
|
|
|
FRAMEWORK_MAYBE_UNUSED
|
2023-08-03 15:40:22 -04:00
|
|
|
static auto GetDstRange(const CGSHandler::BITBLTBUF& bltBuf, const CGSHandler::TRXREG& trxReg, const CGSHandler::TRXPOS& trxPos)
|
|
|
|
{
|
|
|
|
return GetRange<TransferRangeDst>(bltBuf, trxReg, trxPos);
|
|
|
|
}
|
|
|
|
}
|