Metal: Resolve artifact in EEVEE Next Film Cryptomatte
Cryptomatte passes would generate a feathered outline in Metal due to missing texture fence in chained read->modify->write->read->... patterns. Added imageFence function to explicitly state that imageStore's should be visible to future imageLoad's. Authored by Apple: Michael Parkin-White Pull Request: https://projects.blender.org/blender/blender/pulls/119163
This commit is contained in:
committed by
Clément Foucault
parent
8b01578826
commit
6b56ed3cd3
@@ -34,6 +34,8 @@ void cryptomatte_clear_samples(FilmSample dst)
|
||||
int layer_len = imageSize(cryptomatte_img).z;
|
||||
for (int i = 0; i < layer_len; i++) {
|
||||
imageStore(cryptomatte_img, ivec3(dst.texel, i), vec4(0.0));
|
||||
/* Ensure stores are visible to later reads. */
|
||||
imageFence(cryptomatte_img);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,4 +73,6 @@ void cryptomatte_store_film_sample(FilmSample dst,
|
||||
imageStore(cryptomatte_img, img_co, sample_pair);
|
||||
break;
|
||||
}
|
||||
/* Ensure stores are visible to later reads. */
|
||||
imageFence(cryptomatte_img);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@ void cryptomatte_store_samples(ivec2 texel, int layer, vec2 samples[CRYPTOMATTE_
|
||||
pass_sample.zw = samples[p * 2 + 1];
|
||||
imageStore(cryptomatte_img, ivec3(texel, p + layer_id), pass_sample);
|
||||
}
|
||||
/* Ensure stores are visible to later reads. */
|
||||
imageFence(cryptomatte_img);
|
||||
}
|
||||
|
||||
void main()
|
||||
|
||||
@@ -142,17 +142,10 @@ void film_sample_accum_combined(FilmSample samp, inout vec4 accum, inout float w
|
||||
weight_accum += weight;
|
||||
}
|
||||
|
||||
#ifdef GPU_METAL
|
||||
void film_sample_cryptomatte_accum(FilmSample samp,
|
||||
int layer,
|
||||
sampler2D tex,
|
||||
thread vec2 *crypto_samples)
|
||||
#else
|
||||
void film_sample_cryptomatte_accum(FilmSample samp,
|
||||
int layer,
|
||||
sampler2D tex,
|
||||
inout vec2 crypto_samples[4])
|
||||
#endif
|
||||
{
|
||||
float hash = texelFetch(tex, samp.texel, 0)[layer];
|
||||
/* Find existing entry. */
|
||||
@@ -247,11 +240,7 @@ vec2 film_pixel_history_motion_vector(ivec2 texel_sample)
|
||||
/* \a t is inter-pixel position. 0 means perfectly on a pixel center.
|
||||
* Returns weights in both dimensions.
|
||||
* Multiply each dimension weights to get final pixel weights. */
|
||||
#ifdef GPU_METAL
|
||||
void film_get_catmull_rom_weights(vec2 t, thread vec2 *weights)
|
||||
#else
|
||||
void film_get_catmull_rom_weights(vec2 t, out vec2 weights[4])
|
||||
#endif
|
||||
{
|
||||
vec2 t2 = t * t;
|
||||
vec2 t3 = t2 * t;
|
||||
|
||||
@@ -366,6 +366,9 @@ struct SStruct {
|
||||
#define imageStore(_tex, _coord, _value) _texture_write_internal(_tex, _coord, _value)
|
||||
#define imageStoreFast(_tex, _coord, _value) _texture_write_internal_fast(_tex, _coord, _value)
|
||||
|
||||
/* Texture synchronization functions. */
|
||||
#define imageFence(image) image.texture->fence()
|
||||
|
||||
/* Singular return values from texture functions of type DEPTH are often indexed with either .r or
|
||||
* .x. This is a lightweight wrapper type for handling this syntax. */
|
||||
union _msl_return_float {
|
||||
|
||||
@@ -83,6 +83,9 @@
|
||||
#define isampler2DAtomic isampler2D
|
||||
#define isampler3DAtomic isampler3D
|
||||
|
||||
/* Pass through functions. */
|
||||
#define imageFence(image)
|
||||
|
||||
/* Backend Functions. */
|
||||
#define select(A, B, mask) mix(A, B, mask)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user