mirror of
https://git.citron-emu.org/citron/emulator
synced 2026-01-31 06:43:35 +00:00
fix(vulkan): coordinate query cache with render pass boundaries
- Close queries before ending render pass in EndRenderPass - Close queries before starting new render pass in RequestRenderpass - Simplify EndPendingOperations to delegate to EndRenderPass - Fixes validation errors about queries started in wrong render pass context
This commit is contained in:
@@ -98,6 +98,17 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) {
|
||||
render_area.height == state.render_area.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
// CRITICAL: Before transitioning to a new render pass, we must close any queries
|
||||
// that were started outside the current render pass context. Vulkan requires that
|
||||
// if vkCmdBeginQuery was called outside a render pass, vkCmdEndQuery must also
|
||||
// be called outside that render pass.
|
||||
if (query_cache && !state.renderpass) {
|
||||
// We're transitioning from outside render pass to inside
|
||||
// Close any queries that were started outside
|
||||
query_cache->NotifySegment(false);
|
||||
}
|
||||
|
||||
EndRenderPass();
|
||||
state.renderpass = renderpass;
|
||||
state.framebuffer = framebuffer_handle;
|
||||
@@ -122,6 +133,7 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) {
|
||||
num_renderpass_images = framebuffer->NumImages();
|
||||
renderpass_images = framebuffer->Images();
|
||||
renderpass_image_ranges = framebuffer->ImageRanges();
|
||||
// Note: Queries will be started by the next draw call via NotifySegment(true) in PrepareDraw
|
||||
}
|
||||
|
||||
void Scheduler::RequestOutsideRenderPassOperationContext() {
|
||||
@@ -279,18 +291,8 @@ void Scheduler::InvalidateState() {
|
||||
}
|
||||
|
||||
void Scheduler::EndPendingOperations() {
|
||||
#if ANDROID
|
||||
if (Settings::IsGPULevelHigh()) {
|
||||
// This is problematic on Android, disable on GPU Normal and Low.
|
||||
// query_cache->DisableStreams();
|
||||
}
|
||||
#else
|
||||
// query_cache->DisableStreams();
|
||||
#endif
|
||||
if (Settings::IsGPULevelNormal()) {
|
||||
// Skip query cache operations for Low accuracy
|
||||
query_cache->NotifySegment(false);
|
||||
}
|
||||
// EndRenderPass now handles closing queries before ending the render pass
|
||||
// This ensures queries started inside a render pass are properly ended
|
||||
EndRenderPass();
|
||||
}
|
||||
|
||||
@@ -298,6 +300,12 @@ void Scheduler::EndRenderPass() {
|
||||
if (!state.renderpass) {
|
||||
return;
|
||||
}
|
||||
// CRITICAL: End any active queries before ending the render pass
|
||||
// Queries started inside a render pass must be ended before vkCmdEndRenderPass
|
||||
// This prevents validation errors about queries started in subpass but not ended
|
||||
if (query_cache) {
|
||||
query_cache->NotifySegment(false);
|
||||
}
|
||||
Record([num_images = num_renderpass_images, images = renderpass_images,
|
||||
ranges = renderpass_image_ranges](vk::CommandBuffer cmdbuf) {
|
||||
std::array<VkImageMemoryBarrier, 9> barriers;
|
||||
|
||||
Reference in New Issue
Block a user