Skip to content

Commit 8b8f37d

Browse files
committed
vulkan/swapchain: add pl_vulkan_swapchain_params.{alpha,color}_bits
1 parent 1a7f88f commit 8b8f37d

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ project('libplacebo', ['c', 'cpp'],
1212
7,
1313
# API version
1414
{
15+
'359': 'add pl_vulkan_swapchain_params.{alpha,color}_bits',
1516
'358': 'add PL_COLOR_SYSTEM_YCGCO_{RE,RO}',
1617
'357': 'add pl_daylight_from_temp, pl_blackbody_from_temp, and generalize pl_white_from_temp',
1718
'356': 'pl_avframe_set_repr now sets frame.alpha_mode',

src/include/libplacebo/vulkan.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,18 @@ struct pl_vulkan_swapchain_params {
356356
// drivers which don't dither properly when outputting high bit depth
357357
// SDR backbuffers to 8-bit screens.
358358
bool disable_10bit_sdr;
359+
360+
// Minimum number of alpha bits requested in the swapchain format. In
361+
// practice, this can be used to prefer formats with higher alpha bit depth
362+
// (e.g. rgba8/rgba16 over rgb10a2), potentially trading 2 bits per color
363+
// channel for increased alpha precision. This is a hint, if no matching
364+
// format is found, lower bit depths will be accepted.
365+
uint8_t alpha_bits;
366+
367+
// Minimum number of color bits requested in the swapchain format. This can
368+
// be used to prefer formats with higher color bit depth. This is a hint,
369+
// if no matching format is found, lower bit depths will be accepted.
370+
uint8_t color_bits;
359371
};
360372

361373
#define pl_vulkan_swapchain_params(...) (&(struct pl_vulkan_swapchain_params) { __VA_ARGS__ })

src/vulkan/swapchain.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,20 @@ static bool map_color_space(VkColorSpaceKHR space, struct pl_color_space *out)
159159
}
160160
}
161161

162+
static inline int quant_score(int depth, int requested)
163+
{
164+
pl_assert(depth >= 0 && depth <= 16);
165+
pl_assert(requested >= 0 && requested <= 16);
166+
return requested <= depth ? 0 : 17 * (16 - depth) + requested - depth;
167+
}
168+
162169
static bool pick_surf_format(pl_swapchain sw, const struct pl_color_space *hint)
163170
{
164171
struct priv *p = PL_PRIV(sw);
165172
struct vk_ctx *vk = p->vk;
166173
pl_gpu gpu = sw->gpu;
167174

168-
int best_score = 0, best_id;
175+
int best_score = -1000, best_id;
169176
bool wide_gamut = pl_color_primaries_is_wide_gamut(hint->primaries);
170177
bool prefer_hdr = pl_color_transfer_is_hdr(hint->transfer);
171178

@@ -227,6 +234,12 @@ static bool pick_surf_format(pl_swapchain sw, const struct pl_color_space *hint)
227234
default: // skip any other format
228235
continue;
229236
}
237+
int alpha_depth = plfmt->num_components < 4 ? 0 : PL_MIN(plfmt->component_depth[3], 16);
238+
int err = quant_score(plfmt->component_depth[0], PL_MIN(p->params.color_bits, 16)) +
239+
quant_score(alpha_depth, PL_MIN(p->params.alpha_bits, 16));
240+
// Reset score if we don't meet the requested bit depth
241+
if (err)
242+
score = -err;
230243
#ifdef __APPLE__
231244
// On Apple hardware, only these formats allow direct-to-display
232245
// rendering, so give them a slight score boost to tie-break against
@@ -274,7 +287,7 @@ static bool pick_surf_format(pl_swapchain sw, const struct pl_color_space *hint)
274287
}
275288
}
276289

277-
if (!best_score) {
290+
if (best_score == -1000) {
278291
PL_ERR(vk, "Failed picking any valid, renderable surface format!");
279292
return false;
280293
}

0 commit comments

Comments
 (0)