Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mac/vulkan: always return 10bit color depth for dithering #15125

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Akemi
Copy link
Member

@Akemi Akemi commented Oct 18, 2024

see #13767.

@Dudemanguy is that what you had in mind?

should i optimise the sw->fns->color_depth(sw) call so it isn't called twice in the worst case?

@@ -842,7 +842,7 @@ static void apply_target_options(struct priv *p, struct pl_frame *target)
int dither_depth = opts->dither_depth;
if (dither_depth == 0) {
struct ra_swapchain *sw = p->ra_ctx->swapchain;
if (sw->fns->color_depth) {
if (sw->fns->color_depth && sw->fns->color_depth(sw) != 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't need to check that. Anybody implementing this but returning 0 or some other bad value is just wrong.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 is also perfectly valid value default value for auto dither.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we only check for sw->fns->color_depth current behaviour will be changed. see also #13643 where we removed the color_depth(struct ra_swapchain *sw) stub in video/out/vulkan/context.c.

now that i added the 'stub' back for vulkan, at least it always returns 0 on all other contexts, the if (sw->fns->color_depth) would always be true and the else if (!pl_color_transfer_is_hdr(target->color.transfer)) condition could never be hit in any case. making it basically dead code.

since dither_depth == 0 is checked before, dither_depth is already 0 in that case. i decided to only change it if the actual function call would change it, and the else if can still be hit.

would you prefer me to change the if/else if to something like?

    struct ra_swapchain *sw = p->ra_ctx->swapchain;
    if (dither_depth == 0 && sw->fns->color_depth)
        dither_depth = sw->fns->color_depth(sw);
    if (dither_depth == 0 && !pl_color_transfer_is_hdr(target->color.transfer))
        dither_depth = 8;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that i added the 'stub' back for vulkan, at least it always returns 0 on all other contexts

Return -1 for unsupported. 0 is currently used as "auto" value.

@@ -50,6 +50,11 @@ static void mac_vk_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info)
[p->vo_mac fillVsyncWithInfo:info];
}

static int mac_vk_color_depth(struct ra_ctx *ctx)
{
return 10;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we at least check backbuffer type before returning this? This will be wrong if we have swapchain configured to ARGB8888

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is probably some way. though i am not sure if this would conflict with how moltenvk works, since we would need to retrieve the current drawable most likely, which moltenvk would to too for drawing.

video/out/vo_gpu_next.c Outdated Show resolved Hide resolved
Copy link

Download the artifacts for this pull request:

Windows
macOS

@kasper93
Copy link
Contributor

kasper93 commented Oct 18, 2024

Correct me if I'm wrong, but this whole change looks like a hack to disable another hack?

Specifically this part

        } else if (!pl_color_transfer_is_hdr(target->color.transfer)) {
            dither_depth = 8;

which is just wrong and if it causes problems it should be reworked to do this only on affected platforms.

EDIT: I don't think we should add a workaround to platforms that works as expected and instead contain focus on others that are affected.

EDIT2: After reading the code again, I think for now we can implement

static int mac_vk_color_depth(struct ra_ctx *ctx)
{
    return 0;
}

to use default behavior of dithering to output swap chain. And avoid duplicating format checks.

@Akemi
Copy link
Member Author

Akemi commented Oct 18, 2024

yeah i think the pl_color_transfer_is_hdr() else if case is problematic. deciding the colour depth by source isn't optimal. anyway this is also the reason why i changed the if like i did, see above.

[edit]

which is just wrong and if it causes problems it should be reworked to do this only on affected platforms.

maybe i misunderstand, but that's what this does atm. previously this was always the case for auto on vulkan. with the changes of this PR it will only hit on platforms/contexts that don't implement color_depth(), so as before but without macvk.

@kasper93
Copy link
Contributor

this is also the reason why i changed the if like i did, see above.

Yes, I understand, I was confused. See my suggested changes, should make auto work fine for mac_vk, but not the rest vulkan.

if (p->params.color_depth)
return p->params.color_depth(sw->ctx);

return 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return 0;
return -1;

@@ -842,7 +842,7 @@ static void apply_target_options(struct priv *p, struct pl_frame *target)
int dither_depth = opts->dither_depth;
if (dither_depth == 0) {
struct ra_swapchain *sw = p->ra_ctx->swapchain;
if (sw->fns->color_depth) {
if (sw->fns->color_depth && sw->fns->color_depth(sw) != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (sw->fns->color_depth && sw->fns->color_depth(sw) != 0) {
if (sw->fns->color_depth && sw->fns->color_depth(sw) != -1) {

@@ -50,6 +50,11 @@ static void mac_vk_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info)
[p->vo_mac fillVsyncWithInfo:info];
}

static int mac_vk_color_depth(struct ra_ctx *ctx)
{
return 10;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return 10;
return 0;

macOS apparently always operates at 10bit internally regardless of the
display's bit depth. this changed at some point in the more recent macOS
versions, where previously macOS operated at a frame buffer depth
corresponding to the display. either 30-Bit Color (ARGB2101010) for
10bit or 24-Bit Color (ARGB8888) for 8bit.

Fixes 13767
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants