From 2052ae5c2b0a6ebce6aa0f49406523a259c2643f Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Tue, 21 May 2024 12:33:38 +0200 Subject: [PATCH] gpu/utils: only sort by relevant texture capabilities Capabilities like vertex, texel buffer support or readback shouldn't influence the sorting, because this requirement will typically be explicitly filtered for when searching for such formats. This capability sorting only exists to allow prioritizing formats that have the optional ability to leverage more performant code paths, e.g. by allowing blits, linear sampling or texture storage. And in either case, we wouldn't want to pick a worse rendering format just for some minor side benefit from having it be compute-dispatchable when blending or some other obscure edge case like that. (And lastly, there is also the user friendliness consideration of wanting "primitive" texture formats near the top of the list) --- src/gpu/utils.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/gpu/utils.c b/src/gpu/utils.c index c9c15e7a..5b216b01 100644 --- a/src/gpu/utils.c +++ b/src/gpu/utils.c @@ -36,15 +36,27 @@ static int cmp_fmt(const void *pa, const void *pb) if (a->emulated != b->emulated) return PL_CMP(a->emulated, b->emulated); - int ca = __builtin_popcount(a->caps), - cb = __builtin_popcount(b->caps); + // Prefer formats with many optional rendering capabilities + const enum pl_fmt_caps caps_whitelist = + PL_FMT_CAP_SAMPLEABLE | + PL_FMT_CAP_STORABLE | + PL_FMT_CAP_LINEAR | + PL_FMT_CAP_RENDERABLE | + PL_FMT_CAP_BLENDABLE | + PL_FMT_CAP_BLITTABLE; + + enum pl_fmt_caps a_caps = a->caps & caps_whitelist, + b_caps = b->caps & caps_whitelist; + + int ca = __builtin_popcount(a_caps), + cb = __builtin_popcount(b_caps); if (ca != cb) return -PL_CMP(ca, cb); // invert to sort higher values first // If the population count is the same but the caps are different, prefer // the caps with a "lower" value (which tend to be more fundamental caps) - if (a->caps != b->caps) - return PL_CMP(a->caps, b->caps); + if (a_caps != b_caps) + return PL_CMP(a_caps, b_caps); // If the capabilities are equal, sort based on the component attributes for (int i = 0; i < PL_ARRAY_SIZE(a->component_depth); i++) {