mirror of
https://github.com/whoahq/whoa.git
synced 2026-03-18 05:31:07 +03:00
feat: Convert GxTex_Argb4444 textures to RGBA8 during Metal upload to simplify handling
This commit is contained in:
parent
15eafe92d7
commit
7fdd22545f
@ -12,6 +12,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
@ -42,13 +43,19 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTLPixelFormat MtlPixelFormatForGx(EGxTexFormat format) {
|
MTLPixelFormat MtlPixelFormatForGx(EGxTexFormat format) {
|
||||||
|
// Note: GxTex format names describe the packed 32-bit value layout (MSB to LSB).
|
||||||
|
// On little-endian, this means the byte order in memory is reversed.
|
||||||
|
// Metal pixel formats describe byte order in memory.
|
||||||
|
// GxTex_Argb8888: packed as 0xAARRGGBB, bytes in memory: BB GG RR AA -> use BGRA
|
||||||
|
// GxTex_Abgr8888: packed as 0xAABBGGRR, bytes in memory: RR GG BB AA -> use RGBA
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case GxTex_Abgr8888:
|
case GxTex_Abgr8888:
|
||||||
return MTLPixelFormatRGBA8Unorm;
|
return MTLPixelFormatRGBA8Unorm;
|
||||||
case GxTex_Argb8888:
|
case GxTex_Argb8888:
|
||||||
return MTLPixelFormatBGRA8Unorm;
|
return MTLPixelFormatBGRA8Unorm;
|
||||||
case GxTex_Argb4444:
|
case GxTex_Argb4444:
|
||||||
return MTLPixelFormatABGR4Unorm;
|
// Convert ARGB4444 to RGBA8 during upload for simpler handling
|
||||||
|
return MTLPixelFormatRGBA8Unorm;
|
||||||
case GxTex_Argb1555:
|
case GxTex_Argb1555:
|
||||||
return MTLPixelFormatBGR5A1Unorm;
|
return MTLPixelFormatBGR5A1Unorm;
|
||||||
case GxTex_Rgb565:
|
case GxTex_Rgb565:
|
||||||
@ -1656,10 +1663,42 @@ void CGxDeviceMTL::ITexUpload(CGxTex* texId) {
|
|||||||
[texture replaceRegion:region mipmapLevel:mipLevel - baseMip withBytes:texels bytesPerRow:bytesPerRow];
|
[texture replaceRegion:region mipmapLevel:mipLevel - baseMip withBytes:texels bytesPerRow:bytesPerRow];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
const void* uploadTexels = texels;
|
||||||
|
std::vector<uint32_t> convertedData; // RGBA8 is 32-bit per pixel
|
||||||
|
|
||||||
|
// Handle Argb4444 format conversion to RGBA8
|
||||||
|
// Game packs as: A[15:12] R[11:8] G[7:4] B[3:0] (each 4 bits)
|
||||||
|
// We expand to RGBA8: R[7:0] G[7:0] B[7:0] A[7:0] (each 8 bits)
|
||||||
|
if (format == GxTex_Argb4444) {
|
||||||
|
uint32_t pixelCount = mipWidth * mipHeight;
|
||||||
|
convertedData.resize(pixelCount);
|
||||||
|
const uint16_t* srcData = static_cast<const uint16_t*>(texels);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < pixelCount; ++i) {
|
||||||
|
uint16_t pixel = srcData[i];
|
||||||
|
// Extract 4-bit nibbles from game's ARGB format
|
||||||
|
uint8_t a4 = (pixel >> 12) & 0xF;
|
||||||
|
uint8_t r4 = (pixel >> 8) & 0xF;
|
||||||
|
uint8_t g4 = (pixel >> 4) & 0xF;
|
||||||
|
uint8_t b4 = pixel & 0xF;
|
||||||
|
|
||||||
|
// Expand 4-bit to 8-bit (multiply by 17 = 0x11 to scale 0-15 to 0-255)
|
||||||
|
uint8_t r8 = r4 * 17;
|
||||||
|
uint8_t g8 = g4 * 17;
|
||||||
|
uint8_t b8 = b4 * 17;
|
||||||
|
uint8_t a8 = a4 * 17;
|
||||||
|
|
||||||
|
// Pack as RGBA8 (little-endian: ABGR in memory)
|
||||||
|
convertedData[i] = (a8 << 24) | (b8 << 16) | (g8 << 8) | r8;
|
||||||
|
}
|
||||||
|
uploadTexels = convertedData.data();
|
||||||
|
texelStrideInBytes = mipWidth * 4; // 4 bytes per pixel for RGBA8
|
||||||
|
}
|
||||||
|
|
||||||
if (texId->m_target == GxTex_CubeMap) {
|
if (texId->m_target == GxTex_CubeMap) {
|
||||||
[texture replaceRegion:region mipmapLevel:mipLevel - baseMip slice:face withBytes:texels bytesPerRow:texelStrideInBytes bytesPerImage:0];
|
[texture replaceRegion:region mipmapLevel:mipLevel - baseMip slice:face withBytes:uploadTexels bytesPerRow:texelStrideInBytes bytesPerImage:0];
|
||||||
} else {
|
} else {
|
||||||
[texture replaceRegion:region mipmapLevel:mipLevel - baseMip withBytes:texels bytesPerRow:texelStrideInBytes];
|
[texture replaceRegion:region mipmapLevel:mipLevel - baseMip withBytes:uploadTexels bytesPerRow:texelStrideInBytes];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user