diff --git a/Backends/Graphics5/Vulkan/Sources/kinc/backend/graphics5/Vulkan.c.h b/Backends/Graphics5/Vulkan/Sources/kinc/backend/graphics5/Vulkan.c.h index 9e48682db..309c02164 100644 --- a/Backends/Graphics5/Vulkan/Sources/kinc/backend/graphics5/Vulkan.c.h +++ b/Backends/Graphics5/Vulkan/Sources/kinc/backend/graphics5/Vulkan.c.h @@ -389,7 +389,10 @@ void create_swapchain(int window_index) { VkAttachmentDescription attachments[2]; attachments[0].format = window->format.format; attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + // On tiled GPU DONT_CARE discards the tile, so that frame stores + // garbage over already-rendered content, which generates black flashes + // LOAD preserves the content across the re-begin + attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; @@ -494,7 +497,7 @@ void create_render_target_render_pass(struct vk_window *window) { VkAttachmentDescription attachments[2]; attachments[0].format = VK_FORMAT_B8G8R8A8_UNORM; // target->impl.format; // TODO attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; @@ -1130,6 +1133,7 @@ void kinc_g5_begin(kinc_g5_render_target_t *renderTarget, int window_index) { if (window->resized) { vkDeviceWaitIdle(vk_ctx.device); create_swapchain(window_index); + window->resized = false; } // Get the index of the next available swapchain image: diff --git a/Backends/Graphics5/Vulkan/Sources/kinc/backend/graphics5/commandlist.c.h b/Backends/Graphics5/Vulkan/Sources/kinc/backend/graphics5/commandlist.c.h index a06f9307f..2674875ef 100644 --- a/Backends/Graphics5/Vulkan/Sources/kinc/backend/graphics5/commandlist.c.h +++ b/Backends/Graphics5/Vulkan/Sources/kinc/backend/graphics5/commandlist.c.h @@ -289,6 +289,14 @@ void kinc_g5_command_list_begin(kinc_g5_command_list_t *list) { err = vkBeginCommandBuffer(list->impl._buffer, &cmd_buf_info); assert(!err); + // Between-frame leftover list: the current image was just presented and not re-acquired, + // so don't touch it - that black-screens FIFO on strict drivers (Mali) + // The backbuffer pass opens next frame after acquire. + if (!began) { + in_render_pass = false; + return; + } + VkImageMemoryBarrier prePresentBarrier = {0}; prePresentBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; prePresentBarrier.pNext = NULL; @@ -325,6 +333,14 @@ void kinc_g5_command_list_begin(kinc_g5_command_list_t *list) { } void kinc_g5_command_list_end(kinc_g5_command_list_t *list) { + // Leftover list (see kinc_g5_command_list_begin): no pass was opened + // so just close the buffer - no end-pass, no present barrier + if (!began) { + VkResult err = vkEndCommandBuffer(list->impl._buffer); + assert(!err); + return; + } + vkCmdEndRenderPass(list->impl._buffer); VkImageMemoryBarrier prePresentBarrier = {0}; @@ -593,7 +609,7 @@ void kinc_g5_command_list_set_render_targets(kinc_g5_command_list_t *list, struc for (int i = 0; i < count; ++i) { attachments[i].format = targets[i]->impl.format; attachments[i].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; diff --git a/Backends/System/Android/Sources/kinc/backend/system.c.h b/Backends/System/Android/Sources/kinc/backend/system.c.h index 5cf5552be..79d2cd26a 100644 --- a/Backends/System/Android/Sources/kinc/backend/system.c.h +++ b/Backends/System/Android/Sources/kinc/backend/system.c.h @@ -1082,14 +1082,23 @@ bool kinc_internal_handle_messages(void) { } } - if (activityJustResized && app->window != NULL) { - activityJustResized = false; + // onNativeWindowResized is not fired on every android, some only send APP_CMD_CONFIG_CHANGED + // poll actual surface size and resize when it changes + static int32_t last_window_width = -1; + static int32_t last_window_height = -1; + if (app->window != NULL) { int32_t width = kinc_android_width(); int32_t height = kinc_android_height(); + bool size_changed = last_window_width != -1 && (width != last_window_width || height != last_window_height); + last_window_width = width; + last_window_height = height; + if (activityJustResized || size_changed) { + activityJustResized = false; #ifdef KINC_VULKAN - kinc_internal_resize(0, width, height); + kinc_internal_resize(0, width, height); #endif - kinc_internal_call_resize_callback(0, width, height); + kinc_internal_call_resize_callback(0, width, height); + } } // Get screen rotation