mojira.dev
MC-311521

GpuSampler mipmap filtering differs between the OpenGL and Vulkan backends

The two backends derive different mipmap state from the same createSampler arguments.

https://mcsrc.dev/2/26.3-snapshot-10/com/mojang/renderpearl/backend/vulkan/VulkanGpuSampler#L45-49

createInfo.mipmapMode(maxLod.orElse(1000.0) > 0.25 ? 1 : 0);
createInfo.maxLod(Math.max(0.25F, (float)maxLod.orElse(1000.0)));

https://mcsrc.dev/2/26.3-snapshot-10/com/mojang/renderpearl/backend/opengl/GlSampler#L40-58

switch (minFilter) {
   case NEAREST -> GL33C.glSamplerParameteri(this.id, 10241, 9986);   // NEAREST_MIPMAP_LINEAR
   case LINEAR  -> GL33C.glSamplerParameteri(this.id, 10241, 9987);   // LINEAR_MIPMAP_LINEAR
}
...
if (maxLod.isPresent()) {
   GL33C.glSamplerParameterf(this.id, 33083, (float)maxLod.getAsDouble());
}

Vulkan switches to VK_SAMPLER_MIPMAP_MODE_NEAREST when maxLod <= 0.25; OpenGL always selects a *_MIPMAP_LINEAR minification filter regardless of maxLod. Vulkan also clamps maxLod to a floor of 0.25, while OpenGL leaves GL_TEXTURE_MAX_LOD at its default of 1000 when maxLod is empty.

A sampler created with a low maxLod therefore interpolates between mip levels on OpenGL and does not on Vulkan. The 0.25 floor looks deliberate, so the intended behaviour is presumably the Vulkan one; in that case GlSampler should select GL_NEAREST_MIPMAP_NEAREST / GL_LINEAR_MIPMAP_NEAREST under the same condition and apply the same clamp.

Linked issues

Comments 1

Lolo

(Unassigned)

Community Consensus

26.3 Snapshot 10

Retrieved