use more efficient pixel formats

This commit is contained in:
Samuliak 2024-07-07 19:03:01 +02:00
parent 7731787aa2
commit 07b3e47d7a
4 changed files with 142 additions and 79 deletions

View file

@ -7,6 +7,7 @@
#include "helpers.hpp"
#include "math_util.hpp"
#include "opengl.hpp"
#include "renderer_mtl/pica_to_mtl.hpp"
template <typename T>
using Interval = boost::icl::right_open_interval<T>;
@ -25,6 +26,7 @@ struct Texture {
// Range of VRAM taken up by buffer
Interval<u32> range;
PICA::PixelFormatInfo formatInfo;
MTL::Texture* texture = nullptr;
MTL::SamplerState* sampler = nullptr;
@ -51,7 +53,9 @@ struct Texture {
void free();
u64 sizeInBytes();
u32 decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
u8 decodeTexelU8(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
u16 decodeTexelU16(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
u32 decodeTexelU32(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
// Get the morton interleave offset of a texel based on its U and V values
static u32 mortonInterleave(u32 u, u32 v);

View file

@ -5,13 +5,39 @@
namespace PICA {
struct PixelFormatInfo {
MTL::PixelFormat pixelFormat;
size_t bytesPerTexel;
};
constexpr PixelFormatInfo pixelFormatInfos[14] = {
{MTL::PixelFormatRGBA8Unorm, 4}, // RGBA8
{MTL::PixelFormatRGBA8Unorm, 4}, // RGB8
{MTL::PixelFormatBGR5A1Unorm, 2}, // RGBA5551
{MTL::PixelFormatB5G6R5Unorm, 2}, // RGB565
{MTL::PixelFormatABGR4Unorm, 2}, // RGBA4
{MTL::PixelFormatRGBA8Unorm, 4}, // IA8
{MTL::PixelFormatRG8Unorm, 2}, // RG8
{MTL::PixelFormatRGBA8Unorm, 4}, // I8
{MTL::PixelFormatA8Unorm, 1}, // A8
{MTL::PixelFormatABGR4Unorm, 2}, // IA4
{MTL::PixelFormatABGR4Unorm, 2}, // I4
{MTL::PixelFormatA8Unorm, 1}, // A4
{MTL::PixelFormatRGBA8Unorm, 4}, // ETC1
{MTL::PixelFormatRGBA8Unorm, 4}, // ETC1A4
};
inline PixelFormatInfo getPixelFormatInfo(TextureFmt format) {
return pixelFormatInfos[static_cast<int>(format)];
}
inline MTL::PixelFormat toMTLPixelFormatColor(ColorFmt format) {
switch (format) {
case ColorFmt::RGBA8: return MTL::PixelFormatRGBA8Unorm;
case ColorFmt::RGB8: return MTL::PixelFormatRGBA8Unorm; // TODO: return the correct format
case ColorFmt::RGB8: return MTL::PixelFormatRGBA8Unorm;
case ColorFmt::RGBA5551: return MTL::PixelFormatBGR5A1Unorm;
case ColorFmt::RGB565: return MTL::PixelFormatB5G6R5Unorm; // TODO: check if this is correct
case ColorFmt::RGBA4: return MTL::PixelFormatABGR4Unorm; // TODO: check if this is correct
case ColorFmt::RGB565: return MTL::PixelFormatB5G6R5Unorm;
case ColorFmt::RGBA4: return MTL::PixelFormatABGR4Unorm;
}
}
@ -19,7 +45,7 @@ inline MTL::PixelFormat toMTLPixelFormatDepth(DepthFmt format) {
switch (format) {
case DepthFmt::Depth16: return MTL::PixelFormatDepth16Unorm;
case DepthFmt::Unknown1: return MTL::PixelFormatInvalid;
case DepthFmt::Depth24: return MTL::PixelFormatDepth32Float; // TODO: is this okay?
case DepthFmt::Depth24: return MTL::PixelFormatDepth32Float; // Metal does not support 24-bit depth formats
// Apple sillicon doesn't support 24-bit depth buffers, so we use 32-bit instead
case DepthFmt::Depth24Stencil8: return MTL::PixelFormatDepth32Float_Stencil8;
}