mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-11 08:39:48 +12:00
[PICA] More textures. Upstream should also build now
This commit is contained in:
parent
51130b295a
commit
ccdab41c28
5 changed files with 66 additions and 36 deletions
|
@ -41,7 +41,7 @@ public:
|
|||
}
|
||||
|
||||
// Adds a surface object to the cache and returns it
|
||||
SurfaceType add(const SurfaceType& surface) {
|
||||
SurfaceType& add(const SurfaceType& surface) {
|
||||
if (size >= capacity) {
|
||||
Helpers::panic("Surface cache full! Add emptying!");
|
||||
}
|
||||
|
|
|
@ -55,11 +55,11 @@ struct Texture {
|
|||
}
|
||||
|
||||
void allocate();
|
||||
void decodeTexture(void* data);
|
||||
void decodeTexture(const void* data);
|
||||
void free();
|
||||
u64 sizeInBytes();
|
||||
|
||||
u32 decodeTexel(u32 u, u32 v, Formats fmt, void* data);
|
||||
u32 decodeTexel(u32 u, u32 v, Formats fmt, const void* data);
|
||||
|
||||
// Get the morton interleave offset of a texel based on its U and V values
|
||||
static u32 mortonInterleave(u32 u, u32 v);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
using namespace Floats;
|
||||
|
||||
GPU::GPU(Memory& mem) : mem(mem), renderer(regs) {
|
||||
GPU::GPU(Memory& mem) : mem(mem), renderer(*this, regs) {
|
||||
vram = new u8[vramSize];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "renderer_gl/renderer_gl.hpp"
|
||||
#include "PICA/float_types.hpp"
|
||||
#include "PICA/gpu.hpp"
|
||||
#include "PICA/regs.hpp"
|
||||
|
||||
using namespace Floats;
|
||||
|
@ -108,6 +109,7 @@ const char* displayFragmentShader = R"(
|
|||
void Renderer::reset() {
|
||||
depthBufferCache.reset();
|
||||
colourBufferCache.reset();
|
||||
textureCache.reset();
|
||||
|
||||
// Init the colour/depth buffer settings to some random defaults on reset
|
||||
colourBufferLoc = 0;
|
||||
|
@ -183,6 +185,16 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c
|
|||
|
||||
//if (depthScale.toFloat32() != -1.0 || depthOffset.toFloat32() != 0.0)
|
||||
// Helpers::panic("TODO: Implement depth scale/offset. Remove the depth *= -1.0 from vertex shader");
|
||||
if (regs[0x80] & 1) {
|
||||
u32 dim = regs[0x82];
|
||||
u32 height = dim & 0x7ff;
|
||||
u32 width = (dim >> 16) & 0x7ff;
|
||||
u32 addr = (regs[0x85] & 0x0FFFFFFF) << 3;
|
||||
u32 format = regs[0x8E] & 0xF;
|
||||
|
||||
Texture targetTex(addr, static_cast<Texture::Formats>(format), width, height);
|
||||
OpenGL::Texture tex = getTexture(targetTex);
|
||||
}
|
||||
|
||||
// TODO: Actually use this
|
||||
float viewportWidth = f24::fromRaw(regs[PICAInternalRegs::ViewportWidth] & 0xffffff).toFloat32() * 2.0;
|
||||
|
@ -259,4 +271,19 @@ OpenGL::Framebuffer Renderer::getColourFBO() {
|
|||
} else {
|
||||
return colourBufferCache.add(sampleBuffer).fbo;
|
||||
}
|
||||
}
|
||||
|
||||
OpenGL::Texture Renderer::getTexture(Texture& tex) {
|
||||
// Similar logic as the getColourFBO/getDepthBuffer functions
|
||||
auto buffer = textureCache.find(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
|
||||
Texture& newTex = textureCache.add(tex);
|
||||
newTex.decodeTexture(textureData);
|
||||
|
||||
return newTex.texture;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#include "colour.hpp"
|
||||
|
||||
void Texture::allocate() {
|
||||
Helpers::panic("Tried to allocate texture");
|
||||
printf("Tried to allocate texture\n");
|
||||
}
|
||||
|
||||
void Texture::free() {
|
||||
|
@ -16,40 +16,40 @@ u64 Texture::sizeInBytes() {
|
|||
u64 pixelCount = u64(size.x()) * u64(size.y());
|
||||
|
||||
switch (format) {
|
||||
case Formats::RGBA8: // 4 bytes per pixel
|
||||
return pixelCount * 4;
|
||||
case Formats::RGBA8: // 4 bytes per pixel
|
||||
return pixelCount * 4;
|
||||
|
||||
case Formats::RGB8: // 3 bytes per pixel
|
||||
return pixelCount * 3;
|
||||
case Formats::RGB8: // 3 bytes per pixel
|
||||
return pixelCount * 3;
|
||||
|
||||
case Formats::RGBA5551: // 2 bytes per pixel
|
||||
case Formats::RGB565:
|
||||
case Formats::RGBA4:
|
||||
case Formats::RG8:
|
||||
case Formats::IA8:
|
||||
return pixelCount * 2;
|
||||
case Formats::RGBA5551: // 2 bytes per pixel
|
||||
case Formats::RGB565:
|
||||
case Formats::RGBA4:
|
||||
case Formats::RG8:
|
||||
case Formats::IA8:
|
||||
return pixelCount * 2;
|
||||
|
||||
case Formats::A8: // 1 byte per pixel
|
||||
case Formats::I8:
|
||||
case Formats::IA4:
|
||||
return pixelCount;
|
||||
case Formats::A8: // 1 byte per pixel
|
||||
case Formats::I8:
|
||||
case Formats::IA4:
|
||||
return pixelCount;
|
||||
|
||||
case Formats::I4: // 4 bits per pixel
|
||||
case Formats::A4:
|
||||
return pixelCount / 2;
|
||||
case Formats::I4: // 4 bits per pixel
|
||||
case Formats::A4:
|
||||
return pixelCount / 2;
|
||||
|
||||
case Formats::ETC1: // Compressed formats
|
||||
case Formats::ETC1A4: {
|
||||
// Number of 8x8 tiles
|
||||
const u64 tileCount = pixelCount / 64;
|
||||
// Each 8x8 consists of 4 4x4 tiles, which are 8 bytes each on ETC1 and 16 bytes each on ETC1A4
|
||||
const u64 tileSize = 4 * (format == Formats::ETC1 ? 8 : 16);
|
||||
return tileCount * tileSize;
|
||||
}
|
||||
case Formats::ETC1: // Compressed formats
|
||||
case Formats::ETC1A4: {
|
||||
// Number of 4x4 tiles
|
||||
const u64 tileCount = pixelCount / 16;
|
||||
// Tiles are 8 bytes each on ETC1 and 16 bytes each on ETC1A4
|
||||
const u64 tileSize = format == Formats::ETC1 ? 8 : 16;
|
||||
return tileCount * tileSize;
|
||||
}
|
||||
|
||||
default:
|
||||
Helpers::panic("[PICA] Attempted to get size of invalid texture type");
|
||||
}
|
||||
default:
|
||||
Helpers::panic("[PICA] Attempted to get size of invalid texture type");
|
||||
}
|
||||
}
|
||||
|
||||
// u and v are the UVs of the relevant texel
|
||||
|
@ -73,11 +73,14 @@ u32 Texture::getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel) {
|
|||
return offset * bytesPerPixel;
|
||||
}
|
||||
|
||||
u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, void* data) {
|
||||
// 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, Texture::Formats fmt, const void* data) {
|
||||
switch (fmt) {
|
||||
case Formats::RGBA4: {
|
||||
u32 offset = getSwizzledOffset(u, v, size.u(), 2);
|
||||
u8* ptr = static_cast<u8*>(data);
|
||||
auto ptr = static_cast<const u8*>(data);
|
||||
u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8);
|
||||
|
||||
u8 alpha = Colour::convert4To8Bit(texel & 0xf);
|
||||
|
@ -93,7 +96,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, void* data) {
|
|||
}
|
||||
}
|
||||
|
||||
void Texture::decodeTexture(void* data) {
|
||||
void Texture::decodeTexture(const void* data) {
|
||||
std::vector<u32> decoded;
|
||||
decoded.reserve(size.u() * size.v());
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue