From 3bb1ccd4d8d0a144eeba737270b2aaac8d44c17d Mon Sep 17 00:00:00 2001 From: Samuliak <samuliak77@gmail.com> Date: Tue, 2 Jul 2024 14:02:00 +0200 Subject: [PATCH] sample textures --- include/renderer_mtl/renderer_mtl.hpp | 2 +- src/core/renderer_mtl/renderer_mtl.cpp | 7 ++- src/host_shaders/metal_shaders.metal | 69 +++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/include/renderer_mtl/renderer_mtl.hpp b/include/renderer_mtl/renderer_mtl.hpp index 5d30c644..751f3dee 100644 --- a/include/renderer_mtl/renderer_mtl.hpp +++ b/include/renderer_mtl/renderer_mtl.hpp @@ -56,5 +56,5 @@ class RendererMTL final : public Renderer { } MTL::Texture* getTexture(Metal::Texture& tex); - void bindTexturesToSlots(); + void bindTexturesToSlots(MTL::RenderCommandEncoder* encoder); }; diff --git a/src/core/renderer_mtl/renderer_mtl.cpp b/src/core/renderer_mtl/renderer_mtl.cpp index d1b734e3..e6694647 100644 --- a/src/core/renderer_mtl/renderer_mtl.cpp +++ b/src/core/renderer_mtl/renderer_mtl.cpp @@ -211,7 +211,7 @@ void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Ve renderCommandEncoder->setVertexBytes(vertices.data(), vertices.size_bytes(), VERTEX_BUFFER_BINDING_INDEX); // Bind resources - bindTexturesToSlots(); + bindTexturesToSlots(renderCommandEncoder); // TODO: respect primitive type renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(vertices.size())); @@ -245,7 +245,7 @@ MTL::Texture* RendererMTL::getTexture(Metal::Texture& tex) { } } -void RendererMTL::bindTexturesToSlots() { +void RendererMTL::bindTexturesToSlots(MTL::RenderCommandEncoder* encoder) { static constexpr std::array<u32, 3> ioBases = { PICA::InternalRegs::Tex0BorderColor, PICA::InternalRegs::Tex1BorderColor, @@ -269,8 +269,7 @@ void RendererMTL::bindTexturesToSlots() { 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); + encoder->setFragmentTexture(tex, i); } else { // TODO: bind a dummy texture? } diff --git a/src/host_shaders/metal_shaders.metal b/src/host_shaders/metal_shaders.metal index 7c13f524..3ad30d0a 100644 --- a/src/host_shaders/metal_shaders.metal +++ b/src/host_shaders/metal_shaders.metal @@ -32,16 +32,83 @@ struct DrawVertexIn { struct DrawVertexOut { float4 position [[position]]; float4 color; + float3 texCoord0; + float2 texCoord1; + float2 texCoord2; }; vertex DrawVertexOut vertexDraw(DrawVertexIn in [[stage_in]]) { DrawVertexOut out; + + // Position out.position = in.position; + // HACK: rotate the position + out.position.xy = -out.position.yx; // in.position.z is in range of [-1 ... 1], convert it to [0 ... 1] out.position.z = (in.position.z + 1.0) * 0.5; + + // Color out.color = in.color; + // Texture coordinates + out.texCoord0 = float3(in.texCoord0, in.texCoord0W); + out.texCoord0.y = 1.0 - out.texCoord0.y; + out.texCoord1 = in.texCoord1; + out.texCoord1.y = 1.0 - out.texCoord1.y; + out.texCoord2 = in.texCoord2; + out.texCoord2.y = 1.0 - out.texCoord2.y; + return out; } -fragment float4 fragmentDraw(DrawVertexOut in [[stage_in]]) { return in.color; } +fragment float4 fragmentDraw(DrawVertexOut in [[stage_in]], texture2d<float> tex0 [[texture(0)]], texture2d<float> tex1 [[texture(1)]], texture2d<float> tex2 [[texture(2)]]) { + // TODO: upload this as argument + sampler samplr; + + float4 tevSources[16]; + tevSources[0] = in.color; + // TODO: uncomment + //calcLighting(tevSources[1], tevSources[2]); + + // TODO: uncomment + //uint textureConfig = readPicaReg(0x80u); + // HACK + uint textureConfig = 0b111u; + float2 texCoord2 = (textureConfig & (1u << 13)) != 0u ? in.texCoord1 : in.texCoord2; + + if ((textureConfig & 1u) != 0u) tevSources[3] = tex0.sample(samplr, in.texCoord0.xy); + if ((textureConfig & 2u) != 0u) tevSources[4] = tex1.sample(samplr, in.texCoord1); + if ((textureConfig & 4u) != 0u) tevSources[5] = tex2.sample(samplr, texCoord2); + tevSources[13] = float4(0.0); // Previous buffer + tevSources[15] = in.color; // Previous combiner + + // TODO: uncomment + //float4 tevNextPreviousBuffer = v_textureEnvBufferColor; + // HACK + float4 tevNextPreviousBuffer = float4(0.0); + // TODO: uncomment + //uint textureEnvUpdateBuffer = readPicaReg(0xE0u); + // HACK + uint textureEnvUpdateBuffer = 0b111111u; + + for (int i = 0; i < 6; i++) { + // TODO: uncomment + tevSources[14] = float4(0.0);//v_textureEnvColor[i]; // Constant color + // TODO: uncomment + tevSources[15] = float4(1.0);//tevCalculateCombiner(i); + tevSources[13] = tevNextPreviousBuffer; + + if (i < 4) { + if ((textureEnvUpdateBuffer & (0x100u << i)) != 0u) { + tevNextPreviousBuffer.rgb = tevSources[15].rgb; + } + + if ((textureEnvUpdateBuffer & (0x1000u << i)) != 0u) { + tevNextPreviousBuffer.a = tevSources[15].a; + } + } + } + + // HACK: should be tevSources[15] + return tevSources[3]; +}