AnyPS5/core/libs/prx/libSceAgcDriver/tests/TextureTiling.cpp

92 lines
5.1 KiB
C++

#include "GraphicsTests.hpp"
#include "prx/libSceAgcDriver/Graphics/include/TextureTiling.hpp"
#include <string>
#include <string_view>
namespace {
using namespace AgcDriver::Graphics;
template<typename TAction>
void reject(TAction action, std::string_view reason) {
try {
action();
} catch (const std::runtime_error& error) {
Require(std::string_view(error.what()).find(reason) != std::string_view::npos, std::string("unexpected texture tiling test error: ") + error.what());
return;
}
throw std::runtime_error(std::string("expected texture tiling rejection: ") + std::string(reason));
}
}
void RunTextureTilingTests() {
{
const auto mips = ComputeMipLayout(TextureTileMode::kLinear, 1, 4, 4, 2);
Require(mips.size() == 2, "linear mip chain must contain the requested mip count");
Require(mips[0].tiledOffset == 512 && mips[0].tiledSize == 1024, "linear mip 0 offset or size changed");
Require(mips[0].width == 4 && mips[0].height == 4, "linear mip 0 dimensions changed");
Require(mips[0].blocksPerRow == 256 && mips[0].pitchBytes == 256, "linear mip 0 row layout changed");
Require(!mips[0].tail, "linear mips must never fall into a mip tail");
Require(mips[1].tiledOffset == 0 && mips[1].tiledSize == 512, "linear mip 1 offset or size changed");
Require(mips[1].width == 2 && mips[1].height == 2, "linear mip 1 dimensions changed");
Require(mips[1].linearOffset == mips[1].tiledOffset && mips[1].linearSize == mips[1].tiledSize, "linear tiling must keep linear and tiled layout identical");
}
{
const auto mips = ComputeMipLayout(TextureTileMode::kLinear, 169, 8, 8, 1);
Require(mips.size() == 1, "compressed linear layout must contain one mip");
Require(mips[0].width == 2 && mips[0].height == 2, "compressed linear mip block dimensions changed");
Require(mips[0].blocksPerRow == 32 && mips[0].pitchBytes == 256, "compressed linear mip row layout changed");
Require(mips[0].tiledSize == 512 && mips[0].linearSize == 512, "compressed linear mip size changed");
}
{
const auto mips = ComputeMipLayout(TextureTileMode::kStandard256B, 1, 64, 64, 1);
Require(mips.size() == 1, "standard 256B layout must contain one mip");
Require(mips[0].tiledOffset == 0 && mips[0].tiledSize == 4096, "standard 256B mip 0 offset or size changed");
Require(mips[0].width == 64 && mips[0].height == 64, "standard 256B mip 0 dimensions changed");
Require(mips[0].blocksPerRow == 4 && mips[0].pitchBytes == 64, "standard 256B mip 0 row layout changed");
Require(!mips[0].tail, "standard 256B textures must never use a mip tail");
const auto surfaceSize = ComputeSurfaceSize(mips, 3);
Require(surfaceSize == 4096ull * 3ull, "surface size must multiply the slice size by the array layer count");
}
{
const auto mips = ComputeMipLayout(TextureTileMode::kStandard256B, 1, 32, 32, 6);
Require(mips.size() == 6, "standard 256B mip chain must contain the requested mip count");
for (const auto& mip : mips) Require(!mip.tail, "standard 256B tile mode must never produce a mip tail");
}
{
const auto mips = ComputeMipLayout(TextureTileMode::kStandard64KB, 1, 1024, 1024, 11);
Require(mips.size() == 11, "standard 64KB mip chain must contain the requested mip count");
auto tailSeen = false;
for (const auto& mip : mips) {
Require(mip.width != 0 && mip.height != 0, "every standard 64KB mip must have nonzero dimensions");
Require(mip.tiledSize != 0 && mip.linearSize != 0, "every standard 64KB mip must have a nonzero size");
if (mip.tail) {
tailSeen = true;
Require(mip.blocksPerRow == 1, "mip tail levels must report a single block per row");
Require(mip.tiledOffset == 0 && mip.linearOffset == 0, "mip tail levels must share the tail block offset");
}
}
Require(tailSeen, "a deep standard 64KB mip chain must fall into the mip tail");
Require(!mips.front().tail, "the base level of a deep mip chain must not be in the mip tail");
}
{
const auto mips = ComputeMipLayout(TextureTileMode::kStandard4KB, 1, 512, 512, 10);
Require(mips.size() == 10, "standard 4KB mip chain must contain the requested mip count");
auto tailSeen = false;
for (const auto& mip : mips) {
if (mip.tail) tailSeen = true;
}
Require(tailSeen, "a deep standard 4KB mip chain must fall into the mip tail");
}
reject([] { ComputeMipLayout(TextureTileMode::kLinear, 1, 0, 4, 1); }, "zero-sized texture");
reject([] { ComputeMipLayout(TextureTileMode::kLinear, 1, 4, 0, 1); }, "zero-sized texture");
reject([] { ComputeMipLayout(TextureTileMode::kLinear, 1, 4, 4, 0); }, "mip count is out of range");
reject([] { ComputeMipLayout(TextureTileMode::kLinear, 1, 4, 4, 17); }, "mip count is out of range");
reject([] { ComputeSurfaceSize({}, 1); }, "empty mip chain");
reject([] { ComputeSurfaceSize(ComputeMipLayout(TextureTileMode::kLinear, 1, 4, 4, 1), 0); }, "zero array layers");
}