From b62a14d3ffb5c16962d3a931cf9cee298939c38d Mon Sep 17 00:00:00 2001 From: Samuliak <samuliak77@gmail.com> Date: Tue, 2 Jul 2024 13:40:29 +0200 Subject: [PATCH] implement textures --- include/renderer_mtl/renderer_mtl.hpp | 3 ++ src/core/renderer_mtl/renderer_mtl.cpp | 50 ++++++++++++++++++++++++++ src/core/renderer_mtl/texture.cpp | 13 +++++-- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/include/renderer_mtl/renderer_mtl.hpp b/include/renderer_mtl/renderer_mtl.hpp index 892eedc1..5d30c644 100644 --- a/include/renderer_mtl/renderer_mtl.hpp +++ b/include/renderer_mtl/renderer_mtl.hpp @@ -54,4 +54,7 @@ class RendererMTL final : public Renderer { commandBuffer = commandQueue->commandBuffer(); } } + + MTL::Texture* getTexture(Metal::Texture& tex); + void bindTexturesToSlots(); }; diff --git a/src/core/renderer_mtl/renderer_mtl.cpp b/src/core/renderer_mtl/renderer_mtl.cpp index dbf34881..d1b734e3 100644 --- a/src/core/renderer_mtl/renderer_mtl.cpp +++ b/src/core/renderer_mtl/renderer_mtl.cpp @@ -1,3 +1,4 @@ +#include "PICA/gpu.hpp" #include "renderer_mtl/renderer_mtl.hpp" #include <cmrc/cmrc.hpp> @@ -209,6 +210,9 @@ void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Ve renderCommandEncoder->setRenderPipelineState(drawPipeline); renderCommandEncoder->setVertexBytes(vertices.data(), vertices.size_bytes(), VERTEX_BUFFER_BINDING_INDEX); + // Bind resources + bindTexturesToSlots(); + // TODO: respect primitive type renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(vertices.size())); @@ -226,3 +230,49 @@ void RendererMTL::deinitGraphicsContext() { // TODO: implement Helpers::warn("RendererMTL::deinitGraphicsContext not implemented"); } + +MTL::Texture* RendererMTL::getTexture(Metal::Texture& tex) { + auto buffer = textureCache.find(tex); + + if (buffer.has_value()) { + return buffer.value().get().texture; + } else { + const auto textureData = std::span{gpu.getPointerPhys<u8>(tex.location), tex.sizeInBytes()}; // Get pointer to the texture data in 3DS memory + Metal::Texture& newTex = textureCache.add(tex); + newTex.decodeTexture(textureData); + + return newTex.texture; + } +} + +void RendererMTL::bindTexturesToSlots() { + static constexpr std::array<u32, 3> ioBases = { + PICA::InternalRegs::Tex0BorderColor, + PICA::InternalRegs::Tex1BorderColor, + PICA::InternalRegs::Tex2BorderColor, + }; + + for (int i = 0; i < 3; i++) { + if ((regs[PICA::InternalRegs::TexUnitCfg] & (1 << i)) == 0) { + continue; + } + + const size_t ioBase = ioBases[i]; + + const u32 dim = regs[ioBase + 1]; + const u32 config = regs[ioBase + 2]; + const u32 height = dim & 0x7ff; + const u32 width = Helpers::getBits<16, 11>(dim); + const u32 addr = (regs[ioBase + 4] & 0x0FFFFFFF) << 3; + u32 format = regs[ioBase + (i == 0 ? 13 : 5)] & 0xF; + + if (addr != 0) [[likely]] { + Metal::Texture targetTex(device, addr, static_cast<PICA::TextureFmt>(format), width, height, config); + MTL::Texture* tex = getTexture(targetTex); + // TODO: bind the texture + Helpers::warn("Wanted to bind texture %p at index %i", tex, i); + } else { + // TODO: bind a dummy texture? + } + } +} diff --git a/src/core/renderer_mtl/texture.cpp b/src/core/renderer_mtl/texture.cpp index a556263c..a4c1dd4d 100644 --- a/src/core/renderer_mtl/texture.cpp +++ b/src/core/renderer_mtl/texture.cpp @@ -228,8 +228,14 @@ u32 Texture::decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> return (alpha << 24) | (intensity << 16) | (intensity << 8) | intensity; } - case PICA::TextureFmt::ETC1: return getTexelETC(false, u, v, size.u(), data); - case PICA::TextureFmt::ETC1A4: return getTexelETC(true, u, v, size.u(), data); + case PICA::TextureFmt::ETC1: { + //return getTexelETC(false, u, v, size.u(), data); + Helpers::panic("[Texture::DecodeTexel] Unimplemented format = %d", static_cast<int>(fmt)); + } + case PICA::TextureFmt::ETC1A4: { + //return getTexelETC(true, u, v, size.u(), data); + Helpers::panic("[Texture::DecodeTexel] Unimplemented format = %d", static_cast<int>(fmt)); + } default: Helpers::panic("[Texture::DecodeTexel] Unimplemented format = %d", static_cast<int>(fmt)); @@ -248,7 +254,8 @@ void Texture::decodeTexture(std::span<const u8> data) { } } - u32 bytesPerRow = sizeInBytes() / size.v(); + // TODO: is this correct? + u32 bytesPerRow = 4 * size.u();//sizeInBytes() / size.v(); texture->replaceRegion(MTL::Region(0, 0, size.u(), size.v()), 0, 0, decoded.data(), bytesPerRow, 0); }