From f5830983be8c2ccca18eaf1073803c771aef690b Mon Sep 17 00:00:00 2001
From: Samuliak <samuliak77@gmail.com>
Date: Tue, 9 Apr 2024 18:52:25 +0200
Subject: [PATCH] metal: bind sampler to shader

---
 .../renderer_metal/mtl_graphics_pipeline.cpp  | 33 ++++++++++++-------
 .../renderer_metal/mtl_pipeline_cache.cpp     |  4 +--
 .../renderer_metal/mtl_rasterizer.cpp         |  2 ++
 3 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/src/video_core/renderer_metal/mtl_graphics_pipeline.cpp b/src/video_core/renderer_metal/mtl_graphics_pipeline.cpp
index cfe827c100..e37eda2747 100644
--- a/src/video_core/renderer_metal/mtl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_metal/mtl_graphics_pipeline.cpp
@@ -65,9 +65,8 @@ void GraphicsPipeline::Configure(bool is_indexed) {
 
     // Find resources
     size_t stage = 4;
-    // const auto& cbufs{maxwell3d->state.shader_stages[stage].const_buffers};
+    const auto& cbufs{maxwell3d->state.shader_stages[stage].const_buffers};
     const auto read_handle{[&](const auto& desc, u32 index) {
-        /*
         ASSERT(cbufs[desc.cbuf_index].enabled);
         const u32 index_offset{index << desc.size_shift};
         const u32 offset{desc.cbuf_offset + index_offset};
@@ -83,25 +82,32 @@ void GraphicsPipeline::Configure(bool is_indexed) {
                 const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)
                                   << desc.secondary_shift_left};
                 const u32 raw{lhs_raw | rhs_raw};
+
                 return TexturePair(raw, false);
             }
         }
-        */
-        // HACK: hardcode the texture address
-        return TexturePair(/*gpu_memory->Read<u32>(addr)*/ 310378932, false);
+        auto a = gpu_memory->Read<u32>(addr);
+        // HACK: hardcode the image
+        if (a != 310378932)
+            a = 310378932;
+
+        return TexturePair(a, false);
     }};
 
     const Shader::Info& info{stage_infos[stage]};
+
     std::array<VideoCommon::ImageViewInOut, 32> views;
+    std::array<VideoCommon::SamplerId, 32> samplers;
     size_t view_index{};
+    size_t sampler_index{};
+
     for (const auto& desc : info.texture_descriptors) {
         for (u32 index = 0; index < desc.count; ++index) {
             const auto handle{read_handle(desc, index)};
-            views[view_index++] = {
-                .index = handle.first,
-                .blacklist = false,
-                .id = {},
-            };
+            views[view_index++] = {handle.first};
+
+            VideoCommon::SamplerId sampler{texture_cache.GetGraphicsSamplerId(handle.second)};
+            samplers[sampler_index++] = sampler;
         }
     }
     texture_cache.FillGraphicsImageViews<true>(std::span(views.data(), view_index));
@@ -119,11 +125,14 @@ void GraphicsPipeline::Configure(bool is_indexed) {
     // Bind resources
 
     // HACK: try to find a texture that we can bind
-    VideoCommon::ImageViewInOut* texture_buffer_it{views.data()};
+    const VideoCommon::ImageViewInOut* views_it{views.data()};
+    const VideoCommon::SamplerId* samplers_it{samplers.data()};
 
-    ImageView& image_view{texture_cache.GetImageView(texture_buffer_it->id)};
+    ImageView& image_view{texture_cache.GetImageView(views_it->id)};
+    Sampler& sampler{texture_cache.GetSampler(*samplers_it)};
 
     command_recorder.GetRenderCommandEncoder()->setFragmentTexture(image_view.GetHandle(), 0);
+    command_recorder.GetRenderCommandEncoder()->setFragmentSamplerState(sampler.GetHandle(), 0);
 }
 
 void GraphicsPipeline::MakePipeline(MTL::RenderPassDescriptor* render_pass) {
diff --git a/src/video_core/renderer_metal/mtl_pipeline_cache.cpp b/src/video_core/renderer_metal/mtl_pipeline_cache.cpp
index 2681277e12..e80b3eb3e0 100644
--- a/src/video_core/renderer_metal/mtl_pipeline_cache.cpp
+++ b/src/video_core/renderer_metal/mtl_pipeline_cache.cpp
@@ -298,9 +298,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
             return out;
         }
 
-        fragment float4 fragmentMain(VertexOut in [[stage_in]], texture2d<float> tex [[texture(0)]]) {
-            constexpr sampler samplr(mip_filter::linear, mag_filter::linear, min_filter::linear);
-
+        fragment float4 fragmentMain(VertexOut in [[stage_in]], texture2d<float> tex [[texture(0)]], sampler samplr [[sampler(0)]]) {
             return tex.sample(samplr, in.texCoord);
         }
     )",
diff --git a/src/video_core/renderer_metal/mtl_rasterizer.cpp b/src/video_core/renderer_metal/mtl_rasterizer.cpp
index a244038409..e2e95f7f13 100644
--- a/src/video_core/renderer_metal/mtl_rasterizer.cpp
+++ b/src/video_core/renderer_metal/mtl_rasterizer.cpp
@@ -48,6 +48,8 @@ void RasterizerMetal::Draw(bool is_indexed, u32 instance_count) {
     if (!pipeline) {
         return;
     }
+    // Set the engine
+    pipeline->SetEngine(maxwell3d, gpu_memory);
     pipeline->Configure(is_indexed);
 
     // HACK: dummy draw call