Skip to content

Commit

Permalink
Merge pull request #128 from GPUCode/span-across
Browse files Browse the repository at this point in the history
texture: Use spans
  • Loading branch information
wheremyfoodat authored Jul 20, 2023
2 parents 5b4f6ef + a019d98 commit fbcb7ce
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 61 deletions.
8 changes: 4 additions & 4 deletions include/PICA/gpu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,17 @@ class GPU {

// Get a pointer of type T* to the data starting from physical address paddr
template <typename T>
T* getPointerPhys(u32 paddr) {
if (paddr >= PhysicalAddrs::FCRAM && paddr <= PhysicalAddrs::FCRAMEnd) {
T* getPointerPhys(u32 paddr, u32 size = 0) {
if (paddr >= PhysicalAddrs::FCRAM && paddr + size <= PhysicalAddrs::FCRAMEnd) {
u8* fcram = mem.getFCRAM();
u32 index = paddr - PhysicalAddrs::FCRAM;

return (T*)&fcram[index];
} else if (paddr >= PhysicalAddrs::VRAM && paddr <= PhysicalAddrs::VRAMEnd) {
} else if (paddr >= PhysicalAddrs::VRAM && paddr + size <= PhysicalAddrs::VRAMEnd) {
u32 index = paddr - PhysicalAddrs::VRAM;
return (T*)&vram[index];
} else [[unlikely]] {
Helpers::panic("[GPU] Tried to access unknown physical address: %08X", paddr);
}
}
};
};
8 changes: 4 additions & 4 deletions include/renderer_gl/textures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ struct Texture {

void allocate();
void setNewConfig(u32 newConfig);
void decodeTexture(const void* data);
void decodeTexture(std::span<const u8> data);
void free();
u64 sizeInBytes();

u32 decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data);
u32 decodeTexel(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);
Expand All @@ -59,6 +59,6 @@ struct Texture {

// Returns the texel at coordinates (u, v) of an ETC1(A4) texture
// TODO: Make hasAlpha a template parameter
u32 getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, const void* data);
u32 getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, std::span<const u8> data);
u32 decodeETC(u32 alpha, u32 u, u32 v, u64 colourData);
};
};
7 changes: 3 additions & 4 deletions src/core/renderer_gl/etc1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ static constexpr u32 signExtend3To32(u32 val) {
return (u32)(s32(val) << 29 >> 29);
}

u32 Texture::getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, const void* data) {
u32 Texture::getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, std::span<const u8> data) {
// Pixel offset of the 8x8 tile based on u, v and the width of the texture
u32 offs = ((u & ~7) * 8) + ((v & ~7) * width);
if (!hasAlpha)
Expand All @@ -30,8 +30,7 @@ u32 Texture::getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, const void* dat
offs += subTileSize * subTileIndex;

u32 alpha;
const u8* tmp = static_cast<const u8*>(data) + offs; // Pointer to colour and alpha data as u8*
const u64* ptr = reinterpret_cast<const u64*>(tmp); // Cast to u64*
const u64* ptr = reinterpret_cast<const u64*>(data.data() + offs); // Cast to u64*

if (hasAlpha) {
// First 64 bits of the 4x4 subtile are alpha data
Expand Down Expand Up @@ -118,4 +117,4 @@ u32 Texture::decodeETC(u32 alpha, u32 u, u32 v, u64 colourData) {
b = std::clamp(b + modifier, 0, 255);

return (alpha << 24) | (u32(b) << 16) | (u32(g) << 8) | u32(r);
}
}
4 changes: 2 additions & 2 deletions src/core/renderer_gl/renderer_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ OpenGL::Texture RendererGL::getTexture(Texture& tex) {
if (buffer.has_value()) {
return buffer.value().get().texture;
} else {
const void* textureData = gpu.getPointerPhys<void*>(tex.location); // Get pointer to the texture data in 3DS memory
const auto textureData = std::span{gpu.getPointerPhys<u8>(tex.location), tex.sizeInBytes()}; // Get pointer to the texture data in 3DS memory
Texture& newTex = textureCache.add(tex);
newTex.decodeTexture(textureData);

Expand Down Expand Up @@ -517,4 +517,4 @@ void RendererGL::screenshot(const std::string& name) {
}

stbi_write_png(name.c_str(), width, height, 4, flippedPixels.data(), 0);
}
}
78 changes: 31 additions & 47 deletions src/core/renderer_gl/textures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,11 @@ u32 Texture::getSwizzledOffset_4bpp(u32 u, u32 v, u32 width) {
// Get the texel at position (u, v)
// fmt: format of the texture
// data: texture data of the texture
u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) {
u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data) {
switch (fmt) {
case PICA::TextureFmt::RGBA4: {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
auto ptr = static_cast<const u8*>(data);
u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8);
u16 texel = u16(data[offset]) | (u16(data[offset + 1]) << 8);

u8 alpha = Colour::convert4To8Bit(getBits<0, 4, u8>(texel));
u8 b = Colour::convert4To8Bit(getBits<4, 4, u8>(texel));
Expand All @@ -128,9 +127,8 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) {
}

case PICA::TextureFmt::RGBA5551: {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
auto ptr = static_cast<const u8*>(data);
u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8);
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(data[offset]) | (u16(data[offset + 1]) << 8);

u8 alpha = getBit<0>(texel) ? 0xff : 0;
u8 b = Colour::convert5To8Bit(getBits<1, 5, u8>(texel));
Expand All @@ -141,56 +139,47 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) {
}

case PICA::TextureFmt::RGB565: {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
auto ptr = static_cast<const u8*>(data);
u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8);
const u32 offset = getSwizzledOffset(u, v, size.u(), 2);
const u16 texel = u16(data[offset]) | (u16(data[offset + 1]) << 8);

u8 b = Colour::convert5To8Bit(getBits<0, 5, u8>(texel));
u8 g = Colour::convert6To8Bit(getBits<5, 6, u8>(texel));
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));

return (0xff << 24) | (b << 16) | (g << 8) | r;
}

case PICA::TextureFmt::RG8: {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
auto ptr = static_cast<const u8*>(data);

constexpr u8 b = 0;
u8 g = ptr[offset];
u8 r = ptr[offset + 1];
const u8 g = data[offset];
const u8 r = data[offset + 1];

return (0xff << 24) | (b << 16) | (g << 8) | r;
}

case PICA::TextureFmt::RGB8: {
u32 offset = getSwizzledOffset(u, v, size.u(), 3);
auto ptr = static_cast<const u8*>(data);

u8 b = ptr[offset];
u8 g = ptr[offset + 1];
u8 r = ptr[offset + 2];
const u32 offset = getSwizzledOffset(u, v, size.u(), 3);
const u8 b = data[offset];
const u8 g = data[offset + 1];
const u8 r = data[offset + 2];

return (0xff << 24) | (b << 16) | (g << 8) | r;
}

case PICA::TextureFmt::RGBA8: {
u32 offset = getSwizzledOffset(u, v, size.u(), 4);
auto ptr = static_cast<const u8*>(data);

u8 alpha = ptr[offset];
u8 b = ptr[offset + 1];
u8 g = ptr[offset + 2];
u8 r = ptr[offset + 3];
const u32 offset = getSwizzledOffset(u, v, size.u(), 4);
const u8 alpha = data[offset];
const u8 b = data[offset + 1];
const u8 g = data[offset + 2];
const u8 r = data[offset + 3];

return (alpha << 24) | (b << 16) | (g << 8) | r;
}

case PICA::TextureFmt::IA4: {
u32 offset = getSwizzledOffset(u, v, size.u(), 1);
auto ptr = static_cast<const u8*>(data);

const u8 texel = ptr[offset];
const u32 offset = getSwizzledOffset(u, v, size.u(), 1);
const u8 texel = data[offset];
const u8 alpha = Colour::convert4To8Bit(texel & 0xf);
const u8 intensity = Colour::convert4To8Bit(texel >> 4);

Expand All @@ -199,11 +188,10 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) {
}

case PICA::TextureFmt::A4: {
u32 offset = getSwizzledOffset_4bpp(u, v, size.u());
auto ptr = static_cast<const u8*>(data);
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 = ptr[offset] >> ((u % 2) ? 4 : 0);
u8 alpha = data[offset] >> ((u % 2) ? 4 : 0);
alpha = Colour::convert4To8Bit(getBits<0, 4>(alpha));

// A8 sets RGB to 0
Expand All @@ -212,19 +200,17 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) {

case PICA::TextureFmt::A8: {
u32 offset = getSwizzledOffset(u, v, size.u(), 1);
auto ptr = static_cast<const u8*>(data);
const u8 alpha = ptr[offset];
const u8 alpha = data[offset];

// A8 sets RGB to 0
return (alpha << 24) | (0 << 16) | (0 << 8) | 0;
}

case PICA::TextureFmt::I4: {
u32 offset = getSwizzledOffset_4bpp(u, v, size.u());
auto ptr = static_cast<const u8*>(data);

// For odd U coordinates, grab the top 4 bits, and the low 4 bits for even coordinates
u8 intensity = ptr[offset] >> ((u % 2) ? 4 : 0);
u8 intensity = data[offset] >> ((u % 2) ? 4 : 0);
intensity = Colour::convert4To8Bit(getBits<0, 4>(intensity));

// Intensity formats just copy the intensity value to every colour channel
Expand All @@ -233,20 +219,18 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) {

case PICA::TextureFmt::I8: {
u32 offset = getSwizzledOffset(u, v, size.u(), 1);
auto ptr = static_cast<const u8*>(data);
const u8 intensity = ptr[offset];
const u8 intensity = data[offset];

// Intensity formats just copy the intensity value to every colour channel
return (0xff << 24) | (intensity << 16) | (intensity << 8) | intensity;
}

case PICA::TextureFmt::IA8: {
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
auto ptr = static_cast<const u8*>(data);

// Same as I8 except each pixel gets its own alpha value too
const u8 alpha = ptr[offset];
const u8 intensity = ptr[offset + 1];
const u8 alpha = data[offset];
const u8 intensity = data[offset + 1];
return (alpha << 24) | (intensity << 16) | (intensity << 8) | intensity;
}

Expand All @@ -258,7 +242,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) {
}
}

void Texture::decodeTexture(const void* data) {
void Texture::decodeTexture(std::span<const u8> data) {
std::vector<u32> decoded;
decoded.reserve(u64(size.u()) * u64(size.v()));

Expand All @@ -272,4 +256,4 @@ void Texture::decodeTexture(const void* data) {

texture.bind();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.u(), size.v(), GL_RGBA, GL_UNSIGNED_BYTE, decoded.data());
}
}

0 comments on commit fbcb7ce

Please sign in to comment.