Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion src/xrt/auxiliary/vk/vk_hud_blend.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,16 @@ vk_hud_blend_init_ex(struct vk_hud_blend *blend,
return false;
}

// #1786: premultiplied variant, same state but colour src ONE. Picked per
// draw by vk_hud_blend_draw_no_layout_ex(); everything else uses the
// straight pipeline above.
blend_att.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
ret = vk->vkCreateGraphicsPipelines(vk->device, VK_NULL_HANDLE, 1, &pipe_ci, NULL, &blend->pipeline_premul);
if (ret != VK_SUCCESS) {
U_LOG_E("[HUD blend] Failed to create premultiplied pipeline: %d", ret);
return false;
}

blend->initialized = true;
return true;
}
Expand Down Expand Up @@ -527,6 +537,23 @@ vk_hud_blend_draw_no_layout(struct vk_hud_blend *blend,
int32_t dst_y,
uint32_t dst_w,
uint32_t dst_h)
{
vk_hud_blend_draw_no_layout_ex(blend, vk, cmd, fb, fb_w, fb_h, hud_image, dst_x, dst_y, dst_w, dst_h, false);
}

void
vk_hud_blend_draw_no_layout_ex(struct vk_hud_blend *blend,
struct vk_bundle *vk,
VkCommandBuffer cmd,
VkFramebuffer fb,
uint32_t fb_w,
uint32_t fb_h,
VkImage hud_image,
int32_t dst_x,
int32_t dst_y,
uint32_t dst_w,
uint32_t dst_h,
bool premultiplied)
{
if (!blend->initialized || hud_image == VK_NULL_HANDLE || fb == VK_NULL_HANDLE ||
dst_w == 0 || dst_h == 0) {
Expand All @@ -551,7 +578,8 @@ vk_hud_blend_draw_no_layout(struct vk_hud_blend *blend,
VkRect2D scissor = {{dst_x, dst_y}, {dst_w, dst_h}};
vk->vkCmdSetScissor(cmd, 0, 1, &scissor);

vk->vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, blend->pipeline);
vk->vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
premultiplied ? blend->pipeline_premul : blend->pipeline);
vk->vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, blend->pipe_layout, 0, 1,
&desc_set, 0, NULL);
vk->vkCmdDraw(cmd, 3, 1, 0, 0);
Expand Down Expand Up @@ -598,6 +626,9 @@ vk_hud_blend_fini(struct vk_hud_blend *blend, struct vk_bundle *vk)
if (blend->pipeline != VK_NULL_HANDLE) {
vk->vkDestroyPipeline(vk->device, blend->pipeline, NULL);
}
if (blend->pipeline_premul != VK_NULL_HANDLE) {
vk->vkDestroyPipeline(vk->device, blend->pipeline_premul, NULL);
}
if (blend->render_pass != VK_NULL_HANDLE) {
vk->vkDestroyRenderPass(vk->device, blend->render_pass, NULL);
}
Expand Down
27 changes: 26 additions & 1 deletion src/xrt/auxiliary/vk/vk_hud_blend.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ extern "C" {
struct vk_hud_blend
{
VkRenderPass render_pass;
VkPipeline pipeline;
VkPipeline pipeline; //!< Straight-alpha colour blend (src SRC_ALPHA).
VkPipeline pipeline_premul; //!< Premultiplied colour blend (src ONE), #1786.
VkPipelineLayout pipe_layout;
VkDescriptorSetLayout desc_layout;
VkDescriptorPool desc_pool;
Expand Down Expand Up @@ -138,6 +139,30 @@ vk_hud_blend_draw(struct vk_hud_blend *blend,
uint32_t dst_w,
uint32_t dst_h);

/*!
* vk_hud_blend_draw_no_layout(), choosing the colour blend per draw (#1786).
*
* @p premultiplied false is the straight-alpha blend every other draw uses
* (colour src SRC_ALPHA, dst ONE_MINUS_SRC_ALPHA). True treats the source as
* premultiplied (colour src ONE, dst ONE_MINUS_SRC_ALPHA). The alpha blend is
* whatever the blend was initialized with, in both cases.
*
* @ingroup aux_vk
*/
void
vk_hud_blend_draw_no_layout_ex(struct vk_hud_blend *blend,
struct vk_bundle *vk,
VkCommandBuffer cmd,
VkFramebuffer fb,
uint32_t fb_w,
uint32_t fb_h,
VkImage hud_image,
int32_t dst_x,
int32_t dst_y,
uint32_t dst_w,
uint32_t dst_h,
bool premultiplied);

/*!
* Draw without managing target image layout transitions or framebuffer
* caching. Use this when blending into a non-swapchain target (e.g. an
Expand Down
6 changes: 5 additions & 1 deletion src/xrt/compositor/gl/comp_gl_compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6244,7 +6244,11 @@ gl_compositor_layer_commit_locked(struct xrt_compositor *xc, xrt_graphics_sync_h

glUseProgram(c->program_window_space);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// #1786: same rule as D3D11/D3D12/vk_native's window-space pass —
// SOURCE_ALPHA_BIT clear means premultiplied bytes, set means
// straight. Deliberately not comp_layer_blend_mode() (#1599).
bool ws_premultiplied = (layer->data.flags & XRT_LAYER_COMPOSITION_BLEND_TEXTURE_SOURCE_ALPHA_BIT) == 0;
glBlendFunc(ws_premultiplied ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

GLint loc_ws_rect = glGetUniformLocation(c->program_window_space, "u_rect");
GLint loc_ws_tex = glGetUniformLocation(c->program_window_space, "u_texture");
Expand Down
12 changes: 9 additions & 3 deletions src/xrt/compositor/vk_native/comp_vk_native_compositor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2622,6 +2622,12 @@ vk_compositor_render_window_space_into_atlas(struct comp_vk_native_compositor *c
const struct xrt_layer_window_space_data *ws = &layer->data.window_space;
uint32_t sc_index = ws->sub.image_index;

// #1786: same rule as D3D11/D3D12's window-space pass —
// SOURCE_ALPHA_BIT clear means premultiplied bytes, set means
// straight. Deliberately not comp_layer_blend_mode() (#1599): see
// the comment in comp_d3d11_renderer.cpp's window-space draw.
bool ws_premultiplied = (layer->data.flags & XRT_LAYER_COMPOSITION_BLEND_TEXTURE_SOURCE_ALPHA_BIT) == 0;

VkImage src_image = (VkImage)(uintptr_t)
comp_vk_native_swapchain_get_image(xsc, sc_index);
if (src_image == VK_NULL_HANDLE) {
Expand Down Expand Up @@ -2699,9 +2705,9 @@ vk_compositor_render_window_space_into_atlas(struct comp_vk_native_compositor *c
}
}

vk_hud_blend_draw_no_layout(&c->window_space_blend, vk, cmd,
c->atlas_ws_fb, atlas_w, atlas_h,
src_image, dx, dy, (uint32_t)dw_i, (uint32_t)dh_i);
vk_hud_blend_draw_no_layout_ex(&c->window_space_blend, vk, cmd, c->atlas_ws_fb, atlas_w,
atlas_h, src_image, dx, dy, (uint32_t)dw_i, (uint32_t)dh_i,
ws_premultiplied);
}

// Source back to COLOR_ATTACHMENT_OPTIMAL so the app can rerender.
Expand Down
5 changes: 4 additions & 1 deletion tests/tests_comp_layer_view_camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,10 @@ TEST_CASE("comp_layer_blend_mode: no backend reimplements the blend rule (#1621)
const char *rel;
uint32_t allowed_flag_reads;
} backends[] = {
{"gl/comp_gl_compositor.cpp", 0},
// #1786: GL's one allowance is the SAME Local2D / window-space
// channel D3D11's is (its own premul/straight decision, deliberately
// not comp_layer_blend_mode() -- see comp_d3d11_renderer.cpp).
{"gl/comp_gl_compositor.cpp", 1},
{"metal/comp_metal_compositor.m", 0},
// The Local2D / window-space channel, above.
{"d3d11/comp_d3d11_renderer.cpp", 1},
Expand Down
Loading