diff --git a/include/PICA/gpu.hpp b/include/PICA/gpu.hpp index d4e54358e..4304a2def 100644 --- a/include/PICA/gpu.hpp +++ b/include/PICA/gpu.hpp @@ -129,17 +129,17 @@ class GPU { // Get a pointer of type T* to the data starting from physical address paddr template - 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); } } -}; \ No newline at end of file +}; diff --git a/include/renderer_gl/textures.hpp b/include/renderer_gl/textures.hpp index 5469a59f6..a2b6c09d8 100644 --- a/include/renderer_gl/textures.hpp +++ b/include/renderer_gl/textures.hpp @@ -40,11 +40,11 @@ struct Texture { void allocate(); void setNewConfig(u32 newConfig); - void decodeTexture(const void* data); + void decodeTexture(std::span 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 data); // Get the morton interleave offset of a texel based on its U and V values static u32 mortonInterleave(u32 u, u32 v); @@ -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 data); u32 decodeETC(u32 alpha, u32 u, u32 v, u64 colourData); -}; \ No newline at end of file +}; diff --git a/src/core/renderer_gl/etc1.cpp b/src/core/renderer_gl/etc1.cpp index 82f067240..8aefd622c 100644 --- a/src/core/renderer_gl/etc1.cpp +++ b/src/core/renderer_gl/etc1.cpp @@ -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 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) @@ -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(data) + offs; // Pointer to colour and alpha data as u8* - const u64* ptr = reinterpret_cast(tmp); // Cast to u64* + const u64* ptr = reinterpret_cast(data.data() + offs); // Cast to u64* if (hasAlpha) { // First 64 bits of the 4x4 subtile are alpha data @@ -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); -} \ No newline at end of file +} diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index 4d9484449..bef3fe936 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -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(tex.location); // Get pointer to the texture data in 3DS memory + const auto textureData = std::span{gpu.getPointerPhys(tex.location), tex.sizeInBytes()}; // Get pointer to the texture data in 3DS memory Texture& newTex = textureCache.add(tex); newTex.decodeTexture(textureData); @@ -517,4 +517,4 @@ void RendererGL::screenshot(const std::string& name) { } stbi_write_png(name.c_str(), width, height, 4, flippedPixels.data(), 0); -} \ No newline at end of file +} diff --git a/src/core/renderer_gl/textures.cpp b/src/core/renderer_gl/textures.cpp index 819bf783c..9e303fd93 100644 --- a/src/core/renderer_gl/textures.cpp +++ b/src/core/renderer_gl/textures.cpp @@ -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 data) { switch (fmt) { case PICA::TextureFmt::RGBA4: { u32 offset = getSwizzledOffset(u, v, size.u(), 2); - auto ptr = static_cast(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)); @@ -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(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)); @@ -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(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(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(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(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(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); @@ -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(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 @@ -212,8 +200,7 @@ 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(data); - const u8 alpha = ptr[offset]; + const u8 alpha = data[offset]; // A8 sets RGB to 0 return (alpha << 24) | (0 << 16) | (0 << 8) | 0; @@ -221,10 +208,9 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) { case PICA::TextureFmt::I4: { u32 offset = getSwizzledOffset_4bpp(u, v, size.u()); - auto ptr = static_cast(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 @@ -233,8 +219,7 @@ 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(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; @@ -242,11 +227,10 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, const void* data) { case PICA::TextureFmt::IA8: { u32 offset = getSwizzledOffset(u, v, size.u(), 2); - auto ptr = static_cast(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; } @@ -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 data) { std::vector decoded; decoded.reserve(u64(size.u()) * u64(size.v())); @@ -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()); -} \ No newline at end of file +}