This commit is contained in:
wheremyfoodat 2025-03-14 12:38:09 +02:00
parent 67f0388eae
commit c061bb7b47
7 changed files with 182 additions and 180 deletions

View file

@ -28,7 +28,7 @@ namespace Metal {
// Range of VRAM taken up by buffer
Interval<u32> range;
PICA::PixelFormatInfo formatInfo;
PICA::MTLPixelFormatInfo formatInfo;
MTL::Texture* base = nullptr;
MTL::Texture* texture = nullptr;
MTL::SamplerState* sampler = nullptr;

View file

@ -7,19 +7,24 @@
#include "opengl.hpp"
namespace PICA {
struct PixelFormatInfo {
struct MTLPixelFormatInfo {
MTL::PixelFormat pixelFormat;
size_t bytesPerTexel;
void (*decoder)(OpenGL::uvec2, u32, u32, std::span<const u8>, std::vector<u8>&);
bool needsSwizzle{false};
MTL::TextureSwizzleChannels swizzle{.red = MTL::TextureSwizzleRed, .green = MTL::TextureSwizzleGreen, .blue = MTL::TextureSwizzleBlue, .alpha = MTL::TextureSwizzleAlpha};
bool needsSwizzle = false;
MTL::TextureSwizzleChannels swizzle{
.red = MTL::TextureSwizzleRed,
.green = MTL::TextureSwizzleGreen,
.blue = MTL::TextureSwizzleBlue,
.alpha = MTL::TextureSwizzleAlpha,
};
};
extern PixelFormatInfo pixelFormatInfos[14];
extern MTLPixelFormatInfo mtlPixelFormatInfos[14];
void checkForPixelFormatSupport(MTL::Device* device);
inline PixelFormatInfo getPixelFormatInfo(TextureFmt format) { return pixelFormatInfos[static_cast<int>(format)]; }
void checkForMTLPixelFormatSupport(MTL::Device* device);
inline MTLPixelFormatInfo getMTLPixelFormatInfo(TextureFmt format) { return mtlPixelFormatInfos[static_cast<int>(format)]; }
inline MTL::PixelFormat toMTLPixelFormatColor(ColorFmt format) {
switch (format) {

View file

@ -1,16 +1,17 @@
#include "renderer_mtl/mtl_texture.hpp"
#include <fmt/format.h>
#include <array>
#include "colour.hpp"
#include "renderer_mtl/objc_helper.hpp"
using namespace Helpers;
namespace Metal {
void Texture::allocate() {
formatInfo = PICA::getPixelFormatInfo(format);
formatInfo = PICA::getMTLPixelFormatInfo(format);
MTL::TextureDescriptor* descriptor = MTL::TextureDescriptor::alloc()->init();
descriptor->setTextureType(MTL::TextureType2D);
@ -20,9 +21,7 @@ namespace Metal {
descriptor->setUsage(MTL::TextureUsageShaderRead);
descriptor->setStorageMode(MTL::StorageModeShared); // TODO: use private + staging buffers?
texture = device->newTexture(descriptor);
texture->setLabel(toNSString(
"Base texture " + std::string(PICA::textureFormatToString(format)) + " " + std::to_string(size.u()) + "x" + std::to_string(size.v())
));
texture->setLabel(toNSString(fmt::format("Base texture {} {}x{}", std::string(PICA::textureFormatToString(format)), size.u(), size.v())));
descriptor->release();
if (formatInfo.needsSwizzle) {
@ -63,9 +62,11 @@ namespace Metal {
if (texture) {
texture->release();
}
if (base) {
base->release();
base->release();
}
if (sampler) {
sampler->release();
}

View file

@ -5,51 +5,52 @@
using namespace Helpers;
namespace PICA {
PixelFormatInfo pixelFormatInfos[14] = {
{MTL::PixelFormatRGBA8Unorm, 4, decodeTexelABGR8ToRGBA8}, // RGBA8
{MTL::PixelFormatRGBA8Unorm, 4, decodeTexelBGR8ToRGBA8}, // RGB8
{MTL::PixelFormatBGR5A1Unorm, 2, decodeTexelA1BGR5ToBGR5A1}, // RGBA5551
{MTL::PixelFormatB5G6R5Unorm, 2, decodeTexelB5G6R5ToB5G6R5}, // RGB565
{MTL::PixelFormatABGR4Unorm, 2, decodeTexelABGR4ToABGR4}, // RGBA4
{MTL::PixelFormatRG8Unorm, 2, decodeTexelAI8ToRG8, true,
{
.red = MTL::TextureSwizzleRed,
.green = MTL::TextureSwizzleRed,
.blue = MTL::TextureSwizzleRed,
.alpha = MTL::TextureSwizzleGreen,
}
}, // IA8
{MTL::PixelFormatRG8Unorm, 2, decodeTexelGR8ToRG8}, // RG8
{MTL::PixelFormatR8Unorm, 1, decodeTexelI8ToR8, true,
{
.red = MTL::TextureSwizzleRed,
.green = MTL::TextureSwizzleRed,
.blue = MTL::TextureSwizzleRed,
.alpha = MTL::TextureSwizzleOne
}
}, // I8
{MTL::PixelFormatA8Unorm, 1, decodeTexelA8ToA8}, // A8
{MTL::PixelFormatABGR4Unorm, 2, decodeTexelAI4ToABGR4}, // IA4
{MTL::PixelFormatR8Unorm, 1, decodeTexelI4ToR8, true,
{
.red = MTL::TextureSwizzleRed,
.green = MTL::TextureSwizzleRed,
.blue = MTL::TextureSwizzleRed,
.alpha = MTL::TextureSwizzleOne
}
}, // I4
{MTL::PixelFormatA8Unorm, 1, decodeTexelA4ToA8}, // A4
{MTL::PixelFormatRGBA8Unorm, 4, decodeTexelETC1ToRGBA8}, // ETC1
{MTL::PixelFormatRGBA8Unorm, 4, decodeTexelETC1A4ToRGBA8}, // ETC1A4
MTLPixelFormatInfo mtlPixelFormatInfos[14] = {
{MTL::PixelFormatRGBA8Unorm, 4, decodeTexelABGR8ToRGBA8}, // RGBA8
{MTL::PixelFormatRGBA8Unorm, 4, decodeTexelBGR8ToRGBA8}, // RGB8
{MTL::PixelFormatBGR5A1Unorm, 2, decodeTexelA1BGR5ToBGR5A1}, // RGBA5551
{MTL::PixelFormatB5G6R5Unorm, 2, decodeTexelB5G6R5ToB5G6R5}, // RGB565
{MTL::PixelFormatABGR4Unorm, 2, decodeTexelABGR4ToABGR4}, // RGBA4
{MTL::PixelFormatRG8Unorm,
2,
decodeTexelAI8ToRG8,
true,
{
.red = MTL::TextureSwizzleRed,
.green = MTL::TextureSwizzleRed,
.blue = MTL::TextureSwizzleRed,
.alpha = MTL::TextureSwizzleGreen,
}}, // IA8
{MTL::PixelFormatRG8Unorm, 2, decodeTexelGR8ToRG8}, // RG8
{MTL::PixelFormatR8Unorm,
1,
decodeTexelI8ToR8,
true,
{.red = MTL::TextureSwizzleRed, .green = MTL::TextureSwizzleRed, .blue = MTL::TextureSwizzleRed, .alpha = MTL::TextureSwizzleOne}}, // I8
{MTL::PixelFormatA8Unorm, 1, decodeTexelA8ToA8}, // A8
{MTL::PixelFormatABGR4Unorm, 2, decodeTexelAI4ToABGR4}, // IA4
{MTL::PixelFormatR8Unorm,
1,
decodeTexelI4ToR8,
true,
{.red = MTL::TextureSwizzleRed, .green = MTL::TextureSwizzleRed, .blue = MTL::TextureSwizzleRed, .alpha = MTL::TextureSwizzleOne}}, // I4
{MTL::PixelFormatA8Unorm, 1, decodeTexelA4ToA8}, // A4
{MTL::PixelFormatRGBA8Unorm, 4, decodeTexelETC1ToRGBA8}, // ETC1
{MTL::PixelFormatRGBA8Unorm, 4, decodeTexelETC1A4ToRGBA8}, // ETC1A4
};
void checkForPixelFormatSupport(MTL::Device* device) {
if (!device->supportsFamily(MTL::GPUFamilyApple1)) {
pixelFormatInfos[2] = {MTL::PixelFormatRGBA8Unorm, 4, decodeTexelA1BGR5ToRGBA8};
pixelFormatInfos[3] = {MTL::PixelFormatRGBA8Unorm, 4, decodeTexelB5G6R5ToRGBA8};
pixelFormatInfos[4] = {MTL::PixelFormatRGBA8Unorm, 4, decodeTexelABGR4ToRGBA8};
pixelFormatInfos[9] = {MTL::PixelFormatRG8Unorm, 2, decodeTexelAI4ToRG8, true,
{
void checkForMTLPixelFormatSupport(MTL::Device* device) {
if (!device->supportsFamily(MTL::GPUFamilyApple1)) {
mtlPixelFormatInfos[2] = {MTL::PixelFormatRGBA8Unorm, 4, decodeTexelA1BGR5ToRGBA8};
mtlPixelFormatInfos[3] = {MTL::PixelFormatRGBA8Unorm, 4, decodeTexelB5G6R5ToRGBA8};
mtlPixelFormatInfos[4] = {MTL::PixelFormatRGBA8Unorm, 4, decodeTexelABGR4ToRGBA8};
mtlPixelFormatInfos[9] = {
MTL::PixelFormatRG8Unorm,
2,
decodeTexelAI4ToRG8,
true,
{
.red = MTL::TextureSwizzleRed,
.green = MTL::TextureSwizzleRed,
.blue = MTL::TextureSwizzleRed,
@ -58,4 +59,4 @@ namespace PICA {
};
}
}
}
} // namespace PICA

View file

@ -102,19 +102,16 @@ void RendererMTL::display() {
renderCommandEncoder->setRenderPipelineState(displayPipeline);
renderCommandEncoder->setFragmentSamplerState(nearestSampler, 0);
const int xMultiplier = 2;
const int yMultiplier = 2;
// Top screen
if (topScreen) {
renderCommandEncoder->setViewport(MTL::Viewport{0, 0, 400 * xMultiplier, 240 * yMultiplier, 0.0f, 1.0f});
renderCommandEncoder->setViewport(MTL::Viewport{0, 0, 400, 240, 0.0f, 1.0f});
renderCommandEncoder->setFragmentTexture(topScreen->get().texture, 0);
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
}
// Bottom screen
if (bottomScreen) {
renderCommandEncoder->setViewport(MTL::Viewport{40 * xMultiplier, 240 * yMultiplier, 320 * xMultiplier, 240 * yMultiplier, 0.0f, 1.0f});
renderCommandEncoder->setViewport(MTL::Viewport{40, 240, 320, 240, 0.0f, 1.0f});
renderCommandEncoder->setFragmentTexture(bottomScreen->get().texture, 0);
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
}
@ -141,7 +138,7 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) {
device = MTL::CreateSystemDefaultDevice();
metalLayer->setDevice(device);
#endif
checkForPixelFormatSupport(device);
checkForMTLPixelFormatSupport(device);
commandQueue = device->newCommandQueue();

View file

@ -3,8 +3,8 @@
#include <array>
#include <string>
#include "math_util.hpp"
#include "colour.hpp"
#include "math_util.hpp"
using namespace Helpers;
@ -38,187 +38,185 @@ u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width) {
}
void decodeTexelABGR8ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset(u, v, size.u(), 4);
const u8 alpha = inData[offset];
const u8 b = inData[offset + 1];
const u8 g = inData[offset + 2];
const u8 r = inData[offset + 3];
const u32 offset = getSwizzledOffset(u, v, size.u(), 4);
const u8 alpha = inData[offset];
const u8 b = inData[offset + 1];
const u8 g = inData[offset + 2];
const u8 r = inData[offset + 3];
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(alpha);
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(alpha);
}
void decodeTexelBGR8ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset(u, v, size.u(), 3);
const u8 b = inData[offset];
const u8 g = inData[offset + 1];
const u8 r = inData[offset + 2];
const u32 offset = getSwizzledOffset(u, v, size.u(), 3);
const u8 b = inData[offset];
const u8 g = inData[offset + 1];
const u8 r = inData[offset + 2];
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(0xff);
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(0xff);
}
void decodeTexelA1BGR5ToBGR5A1(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
u8 alpha = getBit<0>(texel);
u8 b = getBits<1, 5, u8>(texel);
u8 g = getBits<6, 5, u8>(texel);
u8 r = getBits<11, 5, u8>(texel);
u8 alpha = getBit<0>(texel);
u8 b = getBits<1, 5, u8>(texel);
u8 g = getBits<6, 5, u8>(texel);
u8 r = getBits<11, 5, u8>(texel);
u16 outTexel = (alpha << 15) | (r << 10) | (g << 5) | b;
outData.push_back(outTexel & 0xff);
outData.push_back((outTexel >> 8) & 0xff);
u16 outTexel = (alpha << 15) | (r << 10) | (g << 5) | b;
outData.push_back(outTexel & 0xff);
outData.push_back((outTexel >> 8) & 0xff);
}
void decodeTexelA1BGR5ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
u8 alpha = getBit<0>(texel) ? 0xff : 0;
u8 b = Colour::convert5To8Bit(getBits<1, 5, u8>(texel));
u8 g = Colour::convert5To8Bit(getBits<6, 5, u8>(texel));
u8 r = Colour::convert5To8Bit(getBits<11, 5, u8>(texel));
u8 alpha = getBit<0>(texel) ? 0xff : 0;
u8 b = Colour::convert5To8Bit(getBits<1, 5, u8>(texel));
u8 g = Colour::convert5To8Bit(getBits<6, 5, u8>(texel));
u8 r = Colour::convert5To8Bit(getBits<11, 5, u8>(texel));
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(alpha);
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(alpha);
}
void decodeTexelB5G6R5ToB5G6R5(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
outData.push_back(texel & 0xff);
outData.push_back((texel >> 8) & 0xff);
outData.push_back(texel & 0xff);
outData.push_back((texel >> 8) & 0xff);
}
void decodeTexelB5G6R5ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
const u8 b = Colour::convert5To8Bit(getBits<0, 5, u8>(texel));
const u8 g = Colour::convert6To8Bit(getBits<5, 6, u8>(texel));
const u8 r = Colour::convert5To8Bit(getBits<11, 5, u8>(texel));
const u8 b = Colour::convert5To8Bit(getBits<0, 5, u8>(texel));
const u8 g = Colour::convert6To8Bit(getBits<5, 6, u8>(texel));
const u8 r = Colour::convert5To8Bit(getBits<11, 5, u8>(texel));
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(0xff);
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(0xff);
}
void decodeTexelABGR4ToABGR4(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
u8 alpha = getBits<0, 4, u8>(texel);
u8 b = getBits<4, 4, u8>(texel);
u8 g = getBits<8, 4, u8>(texel);
u8 r = getBits<12, 4, u8>(texel);
u8 alpha = getBits<0, 4, u8>(texel);
u8 b = getBits<4, 4, u8>(texel);
u8 g = getBits<8, 4, u8>(texel);
u8 r = getBits<12, 4, u8>(texel);
outData.push_back((b << 4) | alpha);
outData.push_back((r << 4) | g);
outData.push_back((b << 4) | alpha);
outData.push_back((r << 4) | g);
}
void decodeTexelABGR4ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
u16 texel = u16(inData[offset]) | (u16(inData[offset + 1]) << 8);
u8 alpha = Colour::convert4To8Bit(getBits<0, 4, u8>(texel));
u8 b = Colour::convert4To8Bit(getBits<4, 4, u8>(texel));
u8 g = Colour::convert4To8Bit(getBits<8, 4, u8>(texel));
u8 r = Colour::convert4To8Bit(getBits<12, 4, u8>(texel));
u8 alpha = Colour::convert4To8Bit(getBits<0, 4, u8>(texel));
u8 b = Colour::convert4To8Bit(getBits<4, 4, u8>(texel));
u8 g = Colour::convert4To8Bit(getBits<8, 4, u8>(texel));
u8 r = Colour::convert4To8Bit(getBits<12, 4, u8>(texel));
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(alpha);
outData.push_back(r);
outData.push_back(g);
outData.push_back(b);
outData.push_back(alpha);
}
void decodeTexelAI8ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
// Same as I8 except each pixel gets its own alpha value too
const u8 alpha = inData[offset];
const u8 intensity = inData[offset + 1];
// Same as I8 except each pixel gets its own alpha value too
const u8 alpha = inData[offset];
const u8 intensity = inData[offset + 1];
outData.push_back(intensity);
outData.push_back(alpha);
outData.push_back(intensity);
outData.push_back(alpha);
}
void decodeTexelGR8ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
constexpr u8 b = 0;
const u8 g = inData[offset];
const u8 r = inData[offset + 1];
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
constexpr u8 b = 0;
const u8 g = inData[offset];
const u8 r = inData[offset + 1];
outData.push_back(r);
outData.push_back(g);
outData.push_back(r);
outData.push_back(g);
}
void decodeTexelI8ToR8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 intensity = inData[offset];
u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 intensity = inData[offset];
outData.push_back(intensity);
outData.push_back(intensity);
}
void decodeTexelA8ToA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 alpha = inData[offset];
u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 alpha = inData[offset];
outData.push_back(alpha);
outData.push_back(alpha);
}
void decodeTexelAI4ToABGR4(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 texel = inData[offset];
const u8 alpha = texel & 0xf;
const u8 intensity = texel >> 4;
const u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 texel = inData[offset];
const u8 alpha = texel & 0xf;
const u8 intensity = texel >> 4;
outData.push_back((intensity << 4) | intensity);
outData.push_back((alpha << 4) | intensity);
outData.push_back((intensity << 4) | intensity);
outData.push_back((alpha << 4) | intensity);
}
void decodeTexelAI4ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 texel = inData[offset];
const u8 alpha = Colour::convert4To8Bit(texel & 0xf);
const u8 intensity = Colour::convert4To8Bit(texel >> 4);
const u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 texel = inData[offset];
const u8 alpha = Colour::convert4To8Bit(texel & 0xf);
const u8 intensity = Colour::convert4To8Bit(texel >> 4);
outData.push_back(intensity);
outData.push_back(alpha);
outData.push_back(intensity);
outData.push_back(alpha);
}
void decodeTexelI4ToR8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
u32 offset = getSwizzledOffset_4bpp(u, v, size.u());
u32 offset = getSwizzledOffset_4bpp(u, v, size.u());
// For odd U coordinates, grab the top 4 bits, and the low 4 bits for even coordinates
u8 intensity = inData[offset] >> ((u % 2) ? 4 : 0);
intensity = Colour::convert4To8Bit(getBits<0, 4>(intensity));
// For odd U coordinates, grab the top 4 bits, and the low 4 bits for even coordinates
u8 intensity = inData[offset] >> ((u % 2) ? 4 : 0);
intensity = Colour::convert4To8Bit(getBits<0, 4>(intensity));
outData.push_back(intensity);
outData.push_back(intensity);
}
void decodeTexelA4ToA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
const u32 offset = getSwizzledOffset_4bpp(u, v, size.u());
const u32 offset = getSwizzledOffset_4bpp(u, v, size.u());
// For odd U coordinates, grab the top 4 bits, and the low 4 bits for even coordinates
u8 alpha = inData[offset] >> ((u % 2) ? 4 : 0);
alpha = Colour::convert4To8Bit(getBits<0, 4>(alpha));
// For odd U coordinates, grab the top 4 bits, and the low 4 bits for even coordinates
u8 alpha = inData[offset] >> ((u % 2) ? 4 : 0);
alpha = Colour::convert4To8Bit(getBits<0, 4>(alpha));
outData.push_back(alpha);
outData.push_back(alpha);
}
static constexpr u32 signExtend3To32(u32 val) {
return (u32)(s32(val) << 29 >> 29);
}
static constexpr u32 signExtend3To32(u32 val) { return (u32)(s32(val) << 29 >> 29); }
void decodeETC(u32 u, u32 v, u64 colourData, u32 alpha, std::vector<u8>& outData) {
static constexpr u32 modifiers[8][2] = {
@ -328,9 +326,9 @@ void getTexelETC(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, s
}
void decodeTexelETC1ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
getTexelETC<false>(size, u, v, inData, outData);
getTexelETC<false>(size, u, v, inData, outData);
}
void decodeTexelETC1A4ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, std::vector<u8>& outData) {
getTexelETC<true>(size, u, v, inData, outData);
getTexelETC<true>(size, u, v, inData, outData);
}

View file

@ -655,7 +655,7 @@ float4 performLogicOp(LogicOp logicOp, float4 s, float4 d) {
return as_type<float4>(performLogicOpU(logicOp, as_type<uint4>(s), as_type<uint4>(d)));
}
fragment float4 fragmentDraw(DrawVertexOut in [[stage_in]], constant PicaRegs& picaRegs [[buffer(0)]], constant FragTEV& tev [[buffer(1)]], constant LogicOp& logicOp [[buffer(2)]], constant uint2& lutSlices [[buffer(3)]], texture2d<float> tex0 [[texture(0)]], texture2d<float> tex1 [[texture(1)]], texture2d<float> tex2 [[texture(2)]], texture2d_array<float> texLightingLut [[texture(3)]], texture1d_array<float> texFogLut [[texture(4)]], sampler samplr0 [[sampler(0)]], sampler samplr1 [[sampler(1)]], sampler samplr2 [[sampler(2)]], sampler linearSampler [[sampler(3)]]) {
fragment float4 fragmentDraw(DrawVertexOut in [[stage_in]], float4 prevColor [[color(0)]], constant PicaRegs& picaRegs [[buffer(0)]], constant FragTEV& tev [[buffer(1)]], constant LogicOp& logicOp [[buffer(2)]], constant uint2& lutSlices [[buffer(3)]], texture2d<float> tex0 [[texture(0)]], texture2d<float> tex1 [[texture(1)]], texture2d<float> tex2 [[texture(2)]], texture2d_array<float> texLightingLut [[texture(3)]], texture1d_array<float> texFogLut [[texture(4)]], sampler samplr0 [[sampler(0)]], sampler samplr1 [[sampler(1)]], sampler samplr2 [[sampler(2)]], sampler linearSampler [[sampler(3)]]) {
Globals globals;
// HACK
@ -755,5 +755,5 @@ fragment float4 fragmentDraw(DrawVertexOut in [[stage_in]], constant PicaRegs& p
}
}
return performLogicOp(logicOp, color, float4(1.0, 0.0, 0.0, 1.0));
}
return performLogicOp(logicOp, color, prevColor);
}