@@ -109,6 +109,7 @@ void *Sys_LoadFunction(void *handle, const char *name) {
109109#include "vk_surface_sprites.h"
110110#include "vk_world_effects.h"
111111#include "vk_frame.h"
112+ #include "vk_resource_state.h"
112113
113114#include "vk_post_process.h"
114115#ifdef USE_VULKAN_RAY_TRACING
@@ -629,6 +630,7 @@ PFN_vkResetFences qvkResetFences;
629630PFN_vkUnmapMemory qvkUnmapMemory ;
630631PFN_vkUpdateDescriptorSets qvkUpdateDescriptorSets ;
631632PFN_vkWaitForFences qvkWaitForFences ;
633+ PFN_vkGetFenceStatus qvkGetFenceStatus ;
632634PFN_vkAcquireNextImageKHR qvkAcquireNextImageKHR ;
633635PFN_vkCreateSwapchainKHR qvkCreateSwapchainKHR ;
634636PFN_vkDestroySwapchainKHR qvkDestroySwapchainKHR ;
@@ -1055,6 +1057,7 @@ void VK_EndImmediateCommands( VkCommandBuffer command_buffer, const char *locati
10551057
10561058
10571059// Optimized layout transition helper using C23 designated initializers
1060+ // Now uses resource state tracker to avoid redundant barriers
10581061static void record_image_layout_transition (
10591062 VkCommandBuffer command_buffer ,
10601063 VkImage image ,
@@ -1064,101 +1067,26 @@ static void record_image_layout_transition(
10641067 uint32_t src_stage_override ,
10651068 uint32_t dst_stage_override )
10661069{
1067- (void )dst_stage_override ; // Suppress unused parameter warning
1068-
1069- // Determine source stage and access mask
1070- uint32_t src_stage ;
1071- VkAccessFlags src_access ;
1072-
1073- switch ( old_layout ) {
1074- case VK_IMAGE_LAYOUT_UNDEFINED :
1075- src_stage = (src_stage_override != 0 ) ? src_stage_override : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ;
1076- src_access = VK_ACCESS_NONE ;
1077- break ;
1078- case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL :
1079- src_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT ;
1080- src_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ;
1081- break ;
1082- case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
1083- src_stage = VK_PIPELINE_STAGE_TRANSFER_BIT ;
1084- src_access = VK_ACCESS_TRANSFER_WRITE_BIT ;
1085- break ;
1086- case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL :
1087- src_stage = VK_PIPELINE_STAGE_TRANSFER_BIT ;
1088- src_access = VK_ACCESS_TRANSFER_READ_BIT ;
1089- break ;
1090- case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
1091- src_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT ;
1092- src_access = VK_ACCESS_SHADER_READ_BIT ;
1093- break ;
1094- case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR :
1095- src_stage = VK_PIPELINE_STAGE_TRANSFER_BIT ;
1096- src_access = VK_ACCESS_NONE ;
1097- break ;
1098- default :
1099- ri .Error ( ERR_DROP , "unsupported old layout %i" , old_layout );
1100- src_stage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT ;
1101- src_access = VK_ACCESS_NONE ;
1102- break ;
1070+ // Use resource state tracker to avoid redundant barriers
1071+ // If old_layout is UNDEFINED, try to get actual layout from state tracker
1072+ VkImageLayout actual_old_layout = old_layout ;
1073+ if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED ) {
1074+ VkImageLayout tracked_layout = vk_resource_state_get_image_layout (image );
1075+ if (tracked_layout != VK_IMAGE_LAYOUT_UNDEFINED ) {
1076+ actual_old_layout = tracked_layout ;
1077+ }
11031078 }
1104-
1105- // Determine destination stage and access mask
1106- uint32_t dst_stage ;
1107- VkAccessFlags dst_access ;
11081079
1109- switch ( new_layout ) {
1110- case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL :
1111- dst_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT ;
1112- dst_access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ;
1113- break ;
1114- case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1115- dst_stage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT ;
1116- dst_access = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT ;
1117- break ;
1118- case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR :
1119- dst_stage = VK_PIPELINE_STAGE_TRANSFER_BIT ;
1120- dst_access = VK_ACCESS_NONE ;
1121- break ;
1122- case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL :
1123- dst_stage = VK_PIPELINE_STAGE_TRANSFER_BIT ;
1124- dst_access = VK_ACCESS_TRANSFER_READ_BIT ;
1125- break ;
1126- case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL :
1127- dst_stage = VK_PIPELINE_STAGE_TRANSFER_BIT ;
1128- dst_access = VK_ACCESS_TRANSFER_WRITE_BIT ;
1129- break ;
1130- case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
1131- dst_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT ;
1132- dst_access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT ;
1133- break ;
1134- default :
1135- ri .Error ( ERR_DROP , "unsupported new layout %i" , new_layout );
1136- dst_stage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT ;
1137- dst_access = VK_ACCESS_NONE ;
1138- break ;
1080+ // Use state tracker transition (will skip if layout hasn't changed)
1081+ if (actual_old_layout == VK_IMAGE_LAYOUT_UNDEFINED ) {
1082+ // First use - use automatic transition
1083+ vk_resource_state_transition_image (command_buffer , image , image_aspect_flags ,
1084+ new_layout , src_stage_override , dst_stage_override );
1085+ } else {
1086+ // Known old layout - use explicit transition
1087+ vk_resource_state_transition_image_explicit (command_buffer , image , image_aspect_flags ,
1088+ actual_old_layout , new_layout , src_stage_override , dst_stage_override );
11391089 }
1140-
1141- // Use C23 designated initializer for better performance and type safety
1142- const VkImageMemoryBarrier barrier = {
1143- .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ,
1144- .pNext = NULL ,
1145- .srcAccessMask = src_access ,
1146- .dstAccessMask = dst_access ,
1147- .oldLayout = old_layout ,
1148- .newLayout = new_layout ,
1149- .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
1150- .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ,
1151- .image = image ,
1152- .subresourceRange = {
1153- .aspectMask = image_aspect_flags ,
1154- .baseMipLevel = 0 ,
1155- .levelCount = VK_REMAINING_MIP_LEVELS ,
1156- .baseArrayLayer = 0 ,
1157- .layerCount = VK_REMAINING_ARRAY_LAYERS
1158- }
1159- };
1160-
1161- qvkCmdPipelineBarrier ( command_buffer , src_stage , dst_stage , 0 , 0 , NULL , 0 , NULL , 1 , & barrier );
11621090}
11631091
11641092
@@ -3891,6 +3819,7 @@ static void init_vulkan_library( void )
38913819 INIT_DEVICE_FUNCTION (vkResetCommandBuffer )
38923820 INIT_DEVICE_FUNCTION (vkResetDescriptorPool )
38933821 INIT_DEVICE_FUNCTION (vkResetFences )
3822+ INIT_DEVICE_FUNCTION (vkGetFenceStatus )
38943823 INIT_DEVICE_FUNCTION (vkUnmapMemory )
38953824 INIT_DEVICE_FUNCTION (vkUpdateDescriptorSets )
38963825 INIT_DEVICE_FUNCTION (vkWaitForFences )
@@ -4462,6 +4391,7 @@ qvkGetPipelineCacheData = NULL;
44624391 qvkResetFences = NULL ;
44634392 qvkResetQueryPool = NULL ;
44644393 qvkCmdResetQueryPool = NULL ;
4394+ qvkGetFenceStatus = NULL ;
44654395 qvkUnmapMemory = NULL ;
44664396 qvkUpdateDescriptorSets = NULL ;
44674397 qvkWaitForFences = NULL ;
@@ -4809,6 +4739,9 @@ void vk_initialize( void )
48094739 if (vk .device != (VkDevice )0x20000000 ) {
48104740 vk_create_sync_primitives ();
48114741 ri .Printf (PRINT_ALL , "Vulkan: Sync primitives created\n" );
4742+
4743+ // Initialize resource state tracker
4744+ vk_resource_state_init ();
48124745 // Optional: initialize timeline semaphore if available
48134746 #ifdef VK_KHR_TIMELINE_SEMAPHORE
48144747 if (qvkCreateSemaphore ) {
@@ -9858,6 +9791,9 @@ void vk_shutdown( refShutdownCode_t code ) {
98589791 // Shutdown world effects system
98599792 vk_world_effects_shutdown ();
98609793
9794+ // Shutdown resource state tracker
9795+ vk_resource_state_shutdown ();
9796+
98619797 // Ray tracing and raymarching moved to RTX renderer only
98629798
98639799 // Shutdown async compute
0 commit comments