diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index af512f222..4466eb51d 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -210,13 +210,14 @@ static inline void setTexture(id encoder, Graphics::Re } } -static inline void setSampler(id encoder, Graphics::RenderEncoderBindings &bindings, ShaderStageType stage, int index, id sampler) +static inline void setSampler(id encoder, Graphics::RenderEncoderBindings &bindings, ShaderStageType stage, int index, love::graphics::Texture *samplertex) { - void *s = (__bridge void *)sampler; + void *s = samplertex != nullptr ? (void *)samplertex->getSamplerHandle() : nullptr; auto &binding = bindings.samplers[index][stage]; if (binding != s) { binding = s; + id sampler = (__bridge id) s; if (stage == SHADERSTAGE_VERTEX) [encoder setVertexSamplerState:sampler atIndex:index]; else if (stage == SHADERSTAGE_PIXEL) @@ -224,13 +225,14 @@ static inline void setSampler(id encoder, Graphics::Ren } } -static inline void setSampler(id encoder, Graphics::RenderEncoderBindings &bindings, int index, id sampler) +static inline void setSampler(id encoder, Graphics::RenderEncoderBindings &bindings, int index, love::graphics::Texture *samplertex) { - void *s = (__bridge void *)sampler; + void *s = samplertex != nullptr ? (void *)samplertex->getSamplerHandle() : nullptr; auto &binding = bindings.samplers[index][SHADERSTAGE_COMPUTE]; if (binding != s) { binding = s; + id sampler = (__bridge id) s; [encoder setSamplerState:sampler atIndex:index]; } } @@ -777,6 +779,7 @@ id Graphics::getCachedSampler(const SamplerState &s) desc.lodMinClamp = s.minLod; desc.lodMaxClamp = s.maxLod; + // TODO: This isn't supported on some older iOS devices... if (s.depthSampleMode.hasValue) desc.compareFunction = getMTLCompareFunction(s.depthSampleMode.value); @@ -984,7 +987,7 @@ void Graphics::applyShaderUniforms(id encoder, love::g for (const Shader::TextureBinding &b : s->getTextureBindings()) { id texture = b.texture; - id sampler = b.sampler; + auto samplertex = b.samplerTexture; uint8 texindex = b.textureStages[SHADERSTAGE_COMPUTE]; uint8 sampindex = b.samplerStages[SHADERSTAGE_COMPUTE]; @@ -992,7 +995,7 @@ void Graphics::applyShaderUniforms(id encoder, love::g if (texindex != LOVE_UINT8_MAX) setTexture(encoder, bindings, texindex, texture); if (sampindex != LOVE_UINT8_MAX) - setSampler(encoder, bindings, sampindex, sampler); + setSampler(encoder, bindings, sampindex, samplertex); } for (const Shader::BufferBinding &b : s->getBufferBindings()) @@ -1078,7 +1081,7 @@ void Graphics::applyShaderUniforms(id renderEncoder, lo for (const Shader::TextureBinding &b : s->getTextureBindings()) { id texture = b.texture; - id sampler = b.sampler; + auto samplertex = b.samplerTexture; if (b.isMainTexture) { @@ -1090,7 +1093,7 @@ void Graphics::applyShaderUniforms(id renderEncoder, lo } texture = getMTLTexture(maintex); - sampler = getMTLSampler(maintex); + samplertex = maintex; } uint8 texindex = b.textureStages[SHADERSTAGE_VERTEX]; @@ -1099,7 +1102,7 @@ void Graphics::applyShaderUniforms(id renderEncoder, lo if (texindex != LOVE_UINT8_MAX) setTexture(renderEncoder, bindings, SHADERSTAGE_VERTEX, texindex, texture); if (sampindex != LOVE_UINT8_MAX) - setSampler(renderEncoder, bindings, SHADERSTAGE_VERTEX, sampindex, sampler); + setSampler(renderEncoder, bindings, SHADERSTAGE_VERTEX, sampindex, samplertex); texindex = b.textureStages[SHADERSTAGE_PIXEL]; sampindex = b.samplerStages[SHADERSTAGE_PIXEL]; @@ -1107,7 +1110,7 @@ void Graphics::applyShaderUniforms(id renderEncoder, lo if (texindex != LOVE_UINT8_MAX) setTexture(renderEncoder, bindings, SHADERSTAGE_PIXEL, texindex, texture); if (sampindex != LOVE_UINT8_MAX) - setSampler(renderEncoder, bindings, SHADERSTAGE_PIXEL, sampindex, sampler); + setSampler(renderEncoder, bindings, SHADERSTAGE_PIXEL, sampindex, samplertex); } for (const Shader::BufferBinding &b : s->getBufferBindings()) diff --git a/src/modules/graphics/metal/Shader.h b/src/modules/graphics/metal/Shader.h index f0e2d178a..b2aec762a 100644 --- a/src/modules/graphics/metal/Shader.h +++ b/src/modules/graphics/metal/Shader.h @@ -81,7 +81,9 @@ public: struct TextureBinding { id texture; - id sampler; + + // Indirect sampler ref in case Texture's sampler state changes. + Texture *samplerTexture; bool isMainTexture; diff --git a/src/modules/graphics/metal/Shader.mm b/src/modules/graphics/metal/Shader.mm index b36c5be0c..7e8687e9f 100644 --- a/src/modules/graphics/metal/Shader.mm +++ b/src/modules/graphics/metal/Shader.mm @@ -768,7 +768,7 @@ void Shader::compileFromGLSLang(id device, const glslang::TProgram &p else { b.texture = getMTLTexture(u.textures[i]); - b.sampler = getMTLSampler(u.textures[i]); + b.samplerTexture = u.textures[i]; BuiltinUniform builtin = BUILTIN_MAX_ENUM; if (getConstant(u.name.c_str(), builtin) && builtin == BUILTIN_TEXTURE_MAIN) @@ -969,9 +969,8 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex info->textures[i] = tex; - // TODO: handle changing a sampler after Shader:send(texture)... textureBindings[info->ints[i]].texture = getMTLTexture(tex); - textureBindings[info->ints[i]].sampler = getMTLSampler(tex); + textureBindings[info->ints[i]].samplerTexture = tex; } }}