diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index d4998631903..c12698e8e4c 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -161,20 +161,28 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info, bool *n util_format_get_mask(info->src.format) != info->mask || info->scissor_enable || info->swizzle_enable || - info->alpha_blend) + info->alpha_blend) { + fprintf(stderr, "DEBUG: blit_native rejected: mask/scissor/swizzle/alpha_blend\n"); return false; + } if (info->render_condition_enable && - ctx->render_condition_active) + ctx->render_condition_active) { + fprintf(stderr, "DEBUG: blit_native rejected: render_condition\n"); return false; + } if (util_format_is_depth_or_stencil(info->dst.format) && - (dst_format != info->src.format || info->filter == PIPE_TEX_FILTER_LINEAR)) + (dst_format != info->src.format || info->filter == PIPE_TEX_FILTER_LINEAR)) { + fprintf(stderr, "DEBUG: blit_native rejected: depth/stencil format mismatch\n"); return false; + } /* vkCmdBlitImage must not be used for multisampled source or destination images. */ - if (info->src.resource->nr_samples > 1 || info->dst.resource->nr_samples > 1) + if (info->src.resource->nr_samples > 1 || info->dst.resource->nr_samples > 1) { + fprintf(stderr, "DEBUG: blit_native rejected: multisampled\n"); return false; + } struct zink_resource *src = zink_resource(info->src.resource); struct zink_resource *use_src = src; @@ -188,28 +196,55 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info, bool *n VkFormat dst_aspect_fmt = dst_aspects == VK_IMAGE_ASPECT_COLOR_BIT ? dst->format : dst_aspects == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) ? dst_vkformat : vk_format_get_aspect_format(dst_vkformat, dst_aspects); - if (src->format != zink_get_format(screen, info->src.format) || dst_aspect_fmt != dst_vkformat) + if (src->format != zink_get_format(screen, info->src.format) || dst_aspect_fmt != dst_vkformat) { + fprintf(stderr, "DEBUG: blit_native rejected: format aspect mismatch src_format=%u vs expected=%u, dst_aspect_fmt=%u vs dst_vkformat=%u\n", + src->format, zink_get_format(screen, info->src.format), dst_aspect_fmt, dst_vkformat); return false; + } /* TODO: remove this in the future when spec permits to allow single-aspected blits */ if (src->format != zink_get_format(screen, info->src.format) || - dst->format != zink_get_format(screen, info->dst.format)) + dst->format != zink_get_format(screen, info->dst.format)) { + fprintf(stderr, "DEBUG: blit_native rejected: format mismatch src->format=%u vs info->src.format=%s, dst->format=%u vs info->dst.format=%s\n", + src->format, util_format_short_name(info->src.format), + dst->format, util_format_short_name(info->dst.format)); return false; - if (src->format != VK_FORMAT_A8_UNORM_KHR && zink_format_is_emulated_alpha(info->src.format)) + } + if (src->format != VK_FORMAT_A8_UNORM_KHR && zink_format_is_emulated_alpha(info->src.format)) { + fprintf(stderr, "DEBUG: blit_native rejected: emulated alpha\n"); return false; + } if (!(src->obj->vkfeats & VK_FORMAT_FEATURE_BLIT_SRC_BIT) || - !(dst->obj->vkfeats & VK_FORMAT_FEATURE_BLIT_DST_BIT)) + !(dst->obj->vkfeats & VK_FORMAT_FEATURE_BLIT_DST_BIT)) { + fprintf(stderr, "DEBUG: blit_native rejected: missing blit feature bits src=0x%x dst=0x%x\n", + src->obj->vkfeats, dst->obj->vkfeats); return false; + } if ((util_format_is_pure_sint(info->src.format) != util_format_is_pure_sint(info->dst.format)) || (util_format_is_pure_uint(info->src.format) != - util_format_is_pure_uint(info->dst.format))) + util_format_is_pure_uint(info->dst.format))) { + fprintf(stderr, "DEBUG: blit_native rejected: sint/uint mismatch\n"); return false; + } if (info->filter == PIPE_TEX_FILTER_LINEAR && - !(src->obj->vkfeats & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) + !(src->obj->vkfeats & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) { + fprintf(stderr, "DEBUG: blit_native rejected: linear filter not supported\n"); return false; + } + + /* TESTING: Allow format conversion to test alpha=1 fix + * Reject blits that require format conversion - kosmickrisp's meta blit + * texture sampling via argument buffers has issues + if (info->src.format != info->dst.format) { + fprintf(stderr, "DEBUG: blit_native rejected: format conversion needed %s -> %s\n", + util_format_short_name(info->src.format), + util_format_short_name(info->dst.format)); + return false; + } + */ VkImageBlit region = {0}; @@ -321,6 +356,12 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info, bool *n info->src.box.width, info->src.box.height, info->dst.box.width, info->dst.box.height); + fprintf(stderr, "DEBUG: blit_native VkImages: src=%p dst=%p dst_dt_idx=%u dst_is_swapchain=%d\n", + (void*)use_src->obj->image, + (void*)dst->obj->image, + dst->obj->dt_idx, + dst->swapchain ? 1 : 0); + VKCTX(CmdBlitImage)(cmdbuf, use_src->obj->image, src->layout, dst->obj->image, dst->layout, 1, ®ion, @@ -363,6 +404,13 @@ zink_blit(struct pipe_context *pctx, struct zink_resource *dst = zink_resource(info->dst.resource); bool needs_present_readback = false; + fprintf(stderr, "DEBUG: zink_blit: src=%s %dx%d -> dst=%s %dx%d mask=0x%x\n", + util_format_short_name(info->src.format), + info->src.box.width, info->src.box.height, + util_format_short_name(info->dst.format), + info->dst.box.width, info->dst.box.height, + info->mask); + if (ctx->awaiting_resolve && ctx->in_rp && ctx->dynamic_fb.tc_info.has_resolve) { bool is_depth = util_format_is_depth_or_stencil(info->src.format); struct pipe_resource *resolve = ctx->fb_state.resolve; @@ -388,14 +436,21 @@ zink_blit(struct pipe_context *pctx, */ if (info->src.resource->nr_samples > 1 && info->dst.resource->nr_samples <= 1) { - if (blit_resolve(ctx, info, &needs_present_readback)) + if (blit_resolve(ctx, info, &needs_present_readback)) { + fprintf(stderr, "DEBUG: blit_resolve succeeded\n"); goto end; + } } else { - if (try_copy_region(pctx, info)) + if (try_copy_region(pctx, info)) { + fprintf(stderr, "DEBUG: try_copy_region succeeded\n"); goto end; - if (blit_native(ctx, info, &needs_present_readback)) + } + if (blit_native(ctx, info, &needs_present_readback)) { + fprintf(stderr, "DEBUG: blit_native succeeded\n"); goto end; + } } + fprintf(stderr, "DEBUG: using util_blitter fallback\n"); } @@ -550,6 +605,20 @@ zink_blit(struct pipe_context *pctx, } else { struct pipe_blit_info new_info = *info; new_info.src.resource = &use_src->base.b; + + fprintf(stderr, "DEBUG: zink_blit util_blitter path - srcbox y=%d height=%d\n", + new_info.src.box.y, new_info.src.box.height); + + /* Fix Y-flip coordinates: when srcbox has y=0 and negative height (Y-flip), + * the source region would span from y=0 to y=-height which is invalid. + * Instead, adjust to y=abs(height) with negative height to read from the + * valid texture region in reverse order (0 to height, flipped). */ + if (new_info.src.box.height < 0 && new_info.src.box.y == 0) { + new_info.src.box.y = -new_info.src.box.height; + fprintf(stderr, "DEBUG: zink_blit fixed Y-flip: src.box.y now %d, height %d\n", + new_info.src.box.y, new_info.src.box.height); + } + util_blitter_blit(ctx->blitter, &new_info, NULL); } ctx->blitting = false; diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c index 84b0eba7ef1..6c7359c3b49 100644 --- a/src/gallium/drivers/zink/zink_kopper.c +++ b/src/gallium/drivers/zink/zink_kopper.c @@ -521,6 +521,7 @@ zink_kopper_displaytarget_create(struct zink_screen *screen, unsigned tex_usage, if (srgb == format) srgb = PIPE_FORMAT_NONE; } + /* Force RGBA format to avoid BGRA format conversion issues in kosmickrisp blit */ cdt->formats[0] = zink_get_format(screen, format); if (srgb) { cdt->format_list.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO; diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 9dfe28de61f..e108d6ecae7 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -1699,6 +1699,8 @@ resource_create(struct pipe_screen *pscreen, if (cdt->swapchain->scci.flags == VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) res->obj->vkflags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT; res->obj->vkusage = cdt->swapchain->scci.imageUsage; + /* Set format features for swapchain images - they use optimal tiling */ + res->obj->vkfeats = zink_get_format_props(screen, templ->format)->optimalTilingFeatures; res->base.b.bind |= PIPE_BIND_DISPLAY_TARGET; res->linear = false; res->swapchain = true; diff --git a/src/kosmickrisp/vulkan/kk_cmd_buffer.c b/src/kosmickrisp/vulkan/kk_cmd_buffer.c index f3ec6f1fdad..8f792051456 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_buffer.c +++ b/src/kosmickrisp/vulkan/kk_cmd_buffer.c @@ -413,6 +413,12 @@ kk_cmd_buffer_flush_push_descriptors(struct kk_cmd_buffer *cmd, { u_foreach_bit(set_idx, desc->push_dirty) { struct kk_push_descriptor_set *push_set = desc->push[set_idx]; + /* If push_set is NULL, the push_dirty bit shouldn't have been set, but + * handle it gracefully to avoid crashes. */ + if (unlikely(push_set == NULL)) { + desc->push_dirty &= ~BITFIELD_BIT(set_idx); + continue; + } struct kk_bo *bo = kk_cmd_allocate_buffer(cmd, sizeof(push_set->data), KK_MIN_UBO_ALIGNMENT); if (bo == NULL) diff --git a/src/kosmickrisp/vulkan/kk_cmd_draw.c b/src/kosmickrisp/vulkan/kk_cmd_draw.c index fdb37887539..593fb41e1ad 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_draw.c +++ b/src/kosmickrisp/vulkan/kk_cmd_draw.c @@ -826,6 +826,9 @@ kk_flush_draw_state(struct kk_cmd_buffer *cmd) mtl_set_depth_stencil_state(enc, gfx->depth_stencil_state); } + fprintf(stderr, "DEBUG: kk_flush_draw_state push_dirty=0x%x root_dirty=%d\n", + desc->push_dirty, desc->root_dirty); + if (desc->push_dirty) kk_cmd_buffer_flush_push_descriptors(cmd, desc); if (desc->root_dirty) diff --git a/src/kosmickrisp/vulkan/kk_cmd_meta.c b/src/kosmickrisp/vulkan/kk_cmd_meta.c index c889fe19a0d..5de04e34023 100644 --- a/src/kosmickrisp/vulkan/kk_cmd_meta.c +++ b/src/kosmickrisp/vulkan/kk_cmd_meta.c @@ -92,6 +92,9 @@ struct kk_meta_save { struct kk_buffer_address desc0_set_addr; bool has_push_desc0; uint8_t push[KK_MAX_PUSH_SIZE]; + /* Save render pass state that meta operations modify */ + mtl_render_pass_descriptor *render_pass_descriptor; + struct kk_rendering_state render; }; static void @@ -111,6 +114,12 @@ kk_meta_begin(struct kk_cmd_buffer *cmd, struct kk_meta_save *save, save->pipeline.gfx.occlusion = cmd->state.gfx.occlusion.mode; save->pipeline.gfx.is_ds_dynamic = cmd->state.gfx.is_depth_stencil_dynamic; + /* Save render pass state */ + save->render_pass_descriptor = cmd->state.gfx.render_pass_descriptor; + save->render = cmd->state.gfx.render; + + /* Reset all graphics state to ensure clean state for meta operations */ + kk_cmd_buffer_dirty_all_gfx(cmd); cmd->state.gfx.is_depth_stencil_dynamic = false; cmd->state.gfx.depth_stencil_state = NULL; @@ -171,14 +180,19 @@ kk_meta_end(struct kk_cmd_buffer *cmd, struct kk_meta_save *save, cmd->state.gfx.vb.attribs_read = save->pipeline.gfx.attribs_read; cmd->state.gfx.is_depth_stencil_dynamic = save->pipeline.gfx.is_ds_dynamic; - cmd->state.gfx.dirty |= KK_DIRTY_PIPELINE; cmd->state.gfx.vb.addr_range[0] = save->vb0; cmd->state.gfx.vb.handles[0] = save->vb0_handle; - cmd->state.gfx.dirty |= KK_DIRTY_VB; cmd->state.gfx.occlusion.mode = save->pipeline.gfx.occlusion; - cmd->state.gfx.dirty |= KK_DIRTY_OCCLUSION; + + /* Restore render pass state */ + cmd->state.gfx.render_pass_descriptor = save->render_pass_descriptor; + cmd->state.gfx.render = save->render; + + /* Mark ALL graphics state as dirty to ensure proper refresh after + * meta operations that may have changed render pass/framebuffer state */ + kk_cmd_buffer_dirty_all_gfx(cmd); desc->root_dirty = true; } else { @@ -225,10 +239,20 @@ kk_CmdBlitImage2(VkCommandBuffer commandBuffer, VK_FROM_HANDLE(kk_cmd_buffer, cmd, commandBuffer); struct kk_device *dev = kk_cmd_buffer_device(cmd); + VK_FROM_HANDLE(kk_image, src_image, pBlitImageInfo->srcImage); + VK_FROM_HANDLE(kk_image, dst_image, pBlitImageInfo->dstImage); + fprintf( + stderr, + "DEBUG: kk_CmdBlitImage2 src=%p (fmt=%u) -> dst=%p (fmt=%u) regions=%u\n", + (void *)src_image, src_image->vk.format, (void *)dst_image, + dst_image->vk.format, pBlitImageInfo->regionCount); + struct kk_meta_save save; kk_meta_begin(cmd, &save, VK_PIPELINE_BIND_POINT_GRAPHICS); vk_meta_blit_image2(&cmd->vk, &dev->meta, pBlitImageInfo); kk_meta_end(cmd, &save, VK_PIPELINE_BIND_POINT_GRAPHICS); + + fprintf(stderr, "DEBUG: kk_CmdBlitImage2 completed\n"); } VKAPI_ATTR void VKAPI_CALL diff --git a/src/kosmickrisp/vulkan/kk_image_view.c b/src/kosmickrisp/vulkan/kk_image_view.c index 49fab5d6926..e37ceff1658 100644 --- a/src/kosmickrisp/vulkan/kk_image_view.c +++ b/src/kosmickrisp/vulkan/kk_image_view.c @@ -152,6 +152,12 @@ kk_image_view_init(struct kk_device *dev, struct kk_image_view *view, view->planes[view_plane].sampled_gpu_resource_id = mtl_texture_get_gpu_resource_id( view->planes[view_plane].mtl_handle_sampled); + fprintf( + stderr, + "DEBUG: kk_image_view_init plane=%u sampled_gpu_resource_id=%llu mtl_handle=%p\n", + view_plane, + (unsigned long long)view->planes[view_plane].sampled_gpu_resource_id, + (void *)view->planes[view_plane].mtl_handle_sampled); } if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) { diff --git a/src/vulkan/runtime/vk_meta_blit_resolve.c b/src/vulkan/runtime/vk_meta_blit_resolve.c index ca49fcb22ef..296235ee788 100644 --- a/src/vulkan/runtime/vk_meta_blit_resolve.c +++ b/src/vulkan/runtime/vk_meta_blit_resolve.c @@ -324,6 +324,12 @@ build_blit_shader(const struct vk_meta_blit_key *key) out_type, out_name); out->data.location = out_location; + /* Force alpha to 1.0 for color blits - some apps render with alpha=0 + * which causes gray/transparent areas on Metal */ + if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && out_comps == 4) { + val = nir_vector_insert_imm(b, val, nir_imm_float(b, 1.0f), 3); + } + nir_store_var(b, out, val, BITFIELD_MASK(out_comps)); } }