diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index 46f9e61919a..90a86a7fce5 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -1883,6 +1883,12 @@ void MTLContext::ensure_texture_bindings( * shader. */ id tex = bound_texture->get_metal_handle(); + /* If texture resource is an image binding and has a non-default swizzle mask, we need + * to bind the source texture resource to retain image write access. */ + if (!is_resource_sampler && bound_texture->has_custom_swizzle()) { + tex = bound_texture->get_metal_handle_base(); + } + if (bool(shader_texture_info.stage_mask & ShaderStage::COMPUTE)) { cs.bind_compute_texture(tex, slot); cs.bind_compute_sampler(bound_sampler, use_argument_buffer_for_samplers, slot); diff --git a/source/blender/gpu/metal/mtl_texture.hh b/source/blender/gpu/metal/mtl_texture.hh index 196ddd7b1c4..24080f81614 100644 --- a/source/blender/gpu/metal/mtl_texture.hh +++ b/source/blender/gpu/metal/mtl_texture.hh @@ -291,6 +291,14 @@ class MTLTexture : public Texture { return name_; } + bool has_custom_swizzle() + { + return (mtl_swizzle_mask_.red != MTLTextureSwizzleRed || + mtl_swizzle_mask_.green != MTLTextureSwizzleGreen || + mtl_swizzle_mask_.blue != MTLTextureSwizzleBlue || + mtl_swizzle_mask_.alpha != MTLTextureSwizzleAlpha); + } + id get_vertex_buffer() const { if (resource_mode_ == MTL_TEXTURE_MODE_VBO) {