diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKBlitLoops.c b/src/java.desktop/share/native/common/java2d/vulkan/VKBlitLoops.c index 4fac72684a78..87a355511169 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKBlitLoops.c +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKBlitLoops.c @@ -143,6 +143,8 @@ static void VKBlitTextureToTexture(VKRenderingContext* context, VKImage* src, VK { VKSDOps* surface = context->surface; + // TODO this looks wrong, needs to be investigated + // we shouldn't normally need to flush DST surface before the blit, only SRC VKRenderer_FlushRenderPass(surface); VKDevice* device = surface->device; @@ -336,6 +338,7 @@ void VKBlitLoops_IsoBlit(JNIEnv *env, } if (sx2 > sx1 && sy2 > sy1) { + VKRenderer_FlushRenderPass(srcOps); VKBlitTextureToTexture(context, srcOps->image, context->surface->image, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); } diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c index 87314cae5275..e7fda66b99bc 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderQueue.c @@ -559,13 +559,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_vulkan_VKRenderQueue_flushBuffer J2dRlsTraceLn2(J2D_TRACE_VERBOSE, "VKRenderQueue_flushBuffer: SET_SURFACES src=%p dst=%p", src, dst); - if (context.surface != NULL && context.surface != dst) { - // TODO Problematic surface flush on a context switch without explicit presentation request. - // Its presence here should not make any difference, but for some reason does. - // Related scenarios need an investigation, e.g. J2Demo. - VKRenderer_FlushSurface(context.surface); - } - context.surface = dst; } break; diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c index 0347eb753860..ae1636b5d4d1 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.c @@ -757,11 +757,24 @@ static void VKRenderer_BeginRenderPass(VKSDOps* surface) { * End render pass for the surface and record it into the primary command buffer, * which will be executed on the next VKRenderer_Flush. */ -void VKRenderer_FlushRenderPass(VKSDOps* surface) { - assert(surface != NULL && surface->renderPass != NULL); +VkBool32 VKRenderer_FlushRenderPass(VKSDOps* surface) { + assert(surface != NULL); + // If pendingFlush is TRUE, pendingCommands must be FALSE + assert(surface->renderPass == NULL || !surface->renderPass->pendingFlush || !surface->renderPass->pendingCommands); + // Note that we skip render pass initialization, if we have pending flush, + // which means that we missed the last flush, but didn't start a new render pass yet. + // So now we are going to catch up the last frame, and don't need reconfiguration. + // We also skip initialization if we have pending commands, because that means we are in the middle of frame. + if (surface->renderPass == NULL || (!surface->renderPass->pendingCommands && !surface->renderPass->pendingFlush)) { + if (!VKRenderer_InitRenderPass(surface)) return VK_FALSE; + // Check for pendingClear after VKRenderer_InitRenderPass, it may be set after reconfiguration. + if (!surface->renderPass->pendingClear) return VK_FALSE; + } + assert(surface->renderPass != NULL); + VKRenderer_FlushDraw(surface); VkBool32 hasCommands = surface->renderPass->pendingCommands, clear = surface->renderPass->pendingClear; - if(!hasCommands && !clear) return; + if(!hasCommands && !clear) return VK_FALSE; VKDevice* device = surface->device; VKRenderer* renderer = device->renderer; surface->renderPass->lastTimestamp = renderer->writeTimestamp; @@ -810,24 +823,13 @@ void VKRenderer_FlushRenderPass(VKSDOps* surface) { device->vkCmdEndRenderPass(cb); VKRenderer_ResetDrawing(surface); J2dRlsTraceLn3(J2D_TRACE_VERBOSE, "VKRenderer_FlushRenderPass(%p): hasCommands=%d, clear=%d", surface, hasCommands, clear); + return VK_TRUE; } void VKRenderer_FlushSurface(VKSDOps* surface) { assert(surface != NULL); - // If pendingFlush is TRUE, pendingCommands must be FALSE - assert(surface->renderPass == NULL || !surface->renderPass->pendingFlush || !surface->renderPass->pendingCommands); - // Note that we skip render pass initialization, if we have pending flush, - // which means that we missed the last flush, but didn't start a new render pass yet. - // So now we are going to catch up the last frame, and don't need reconfiguration. - // We also skip initialization if we have pending commands, because that means we are in the middle of frame. - if (surface->renderPass == NULL || (!surface->renderPass->pendingCommands && !surface->renderPass->pendingFlush)) { - if (!VKRenderer_InitRenderPass(surface)) return; - // Check for pendingClear after VKRenderer_InitRenderPass, it may be set after reconfiguration. - if (!surface->renderPass->pendingClear) return; - } - + if (!VKRenderer_FlushRenderPass(surface)) return; surface->renderPass->pendingFlush = VK_FALSE; - VKRenderer_FlushRenderPass(surface); // If this is a swapchain surface, we need to blit the content onto it and queue it for presentation. if (surface->drawableType == VKSD_WINDOW) { diff --git a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.h b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.h index f8efb0f160a6..d458de48d429 100644 --- a/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.h +++ b/src/java.desktop/share/native/common/java2d/vulkan/VKRenderer.h @@ -85,6 +85,12 @@ void VKRenderer_Flush(VKRenderer* renderer); */ void VKRenderer_DestroyRenderPass(VKSDOps* surface); +/** + * End render pass for the surface and record it into the primary command buffer, + * which will be executed on the next VKRenderer_Flush. + */ +VkBool32 VKRenderer_FlushRenderPass(VKSDOps* surface); + /** * Flush pending render pass and queue surface for presentation (if applicable). */ @@ -96,12 +102,6 @@ void VKRenderer_FlushSurface(VKSDOps* surface); */ void VKRenderer_ConfigureSurface(VKSDOps* surface, VkExtent2D extent); -/** - * End render pass for the surface and record it into the primary command buffer, - * which will be executed on the next VKRenderer_Flush. - */ -void VKRenderer_FlushRenderPass(VKSDOps* surface); - // Blit operations. void VKRenderer_TextureRender(const VKRenderingContext* context,