JBR-8363 Vulkan: Organize usage of FlushRenderPass and FlushSurface

This commit is contained in:
Nikita Gubarkov
2025-03-03 23:46:42 +01:00
committed by jbrbot
parent abedae8cbe
commit 03ae80c49f
4 changed files with 27 additions and 29 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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,