implement textures

This commit is contained in:
Samuliak 2024-07-02 13:40:29 +02:00
parent bac3a8e040
commit b62a14d3ff
3 changed files with 63 additions and 3 deletions

View file

@ -54,4 +54,7 @@ class RendererMTL final : public Renderer {
commandBuffer = commandQueue->commandBuffer(); commandBuffer = commandQueue->commandBuffer();
} }
} }
MTL::Texture* getTexture(Metal::Texture& tex);
void bindTexturesToSlots();
}; };

View file

@ -1,3 +1,4 @@
#include "PICA/gpu.hpp"
#include "renderer_mtl/renderer_mtl.hpp" #include "renderer_mtl/renderer_mtl.hpp"
#include <cmrc/cmrc.hpp> #include <cmrc/cmrc.hpp>
@ -209,6 +210,9 @@ void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Ve
renderCommandEncoder->setRenderPipelineState(drawPipeline); renderCommandEncoder->setRenderPipelineState(drawPipeline);
renderCommandEncoder->setVertexBytes(vertices.data(), vertices.size_bytes(), VERTEX_BUFFER_BINDING_INDEX); renderCommandEncoder->setVertexBytes(vertices.data(), vertices.size_bytes(), VERTEX_BUFFER_BINDING_INDEX);
// Bind resources
bindTexturesToSlots();
// TODO: respect primitive type // TODO: respect primitive type
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(vertices.size())); renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(vertices.size()));
@ -226,3 +230,49 @@ void RendererMTL::deinitGraphicsContext() {
// TODO: implement // TODO: implement
Helpers::warn("RendererMTL::deinitGraphicsContext not implemented"); 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?
}
}
}

View file

@ -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; return (alpha << 24) | (intensity << 16) | (intensity << 8) | intensity;
} }
case PICA::TextureFmt::ETC1: return getTexelETC(false, u, v, size.u(), data); case PICA::TextureFmt::ETC1: {
case PICA::TextureFmt::ETC1A4: return getTexelETC(true, u, v, size.u(), data); //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: default:
Helpers::panic("[Texture::DecodeTexel] Unimplemented format = %d", static_cast<int>(fmt)); 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); texture->replaceRegion(MTL::Region(0, 0, size.u(), size.v()), 0, 0, decoded.data(), bytesPerRow, 0);
} }