31#include <SDL2/SDL_vulkan.h>
33#define VMA_IMPLEMENTATION
38 inline VKAPI_ATTR VkBool32 VKAPI_CALL
divide_debug_callback( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
39 VkDebugUtilsMessageTypeFlagsEXT messageType,
40 const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
51 const auto to_string_message_severity = []( VkDebugUtilsMessageSeverityFlagBitsEXT s ) ->
const char*
55 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
return "VERBOSE";
56 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
return "ERROR";
57 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
return "WARNING";
58 case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
return "INFO";
59 default:
return "UNKNOWN";
63 const auto to_string_message_type = []( VkDebugUtilsMessageTypeFlagsEXT s )
66 if ( s & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT )
68 ret.append(
"[General]");
70 if ( s & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT )
72 ret.append(
"[Validation]" );
74 if ( s & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT )
76 ret.append(
"[Performance]" );
78 if ( s & VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT )
80 ret.append(
"[Address Binding]" );
84 ret.append(
"[Unknown]");
90 constexpr const char* kSkippedMessages[] = {
91 "UNASSIGNED-BestPractices-vkCreateInstance-specialuse-extension-debugging",
92 "UNASSIGNED-BestPractices-vkCreateDevice-specialuse-extension-d3demulation",
93 "UNASSIGNED-BestPractices-vkCreateDevice-specialuse-extension-glemulation",
94 "UNASSIGNED-BestPractices-vkBindMemory-small-dedicated-allocation",
95 "UNASSIGNED-BestPractices-vkAllocateMemory-small-allocation",
96 "UNASSIGNED-BestPractices-SpirvDeprecated_WorkgroupSize"
99 if ( pCallbackData->pMessageIdName !=
nullptr )
101 if ( strstr( pCallbackData->pMessageIdName,
"UNASSIGNED-BestPractices-Error-Result") != nullptr )
104 if ( strstr( pCallbackData->pMessage,
"vkAllocateMemory()" ) != nullptr )
111 for (
const char* msg : kSkippedMessages )
113 if ( strstr( pCallbackData->pMessageIdName, msg ) != nullptr )
120 const string outputError = Util::StringFormat(
"[ {} ] {} : {}\n",
121 to_string_message_severity( messageSeverity ),
122 to_string_message_type( messageType ).c_str(),
123 pCallbackData->pMessage );
125 const bool isConsoleImmediate = Console::IsFlagSet( Console::Flags::PRINT_IMMEDIATE );
126 const bool severityDecoration = Console::IsFlagSet( Console::Flags::DECORATE_SEVERITY );
128 Console::ToggleFlag( Console::Flags::PRINT_IMMEDIATE,
true );
129 Console::ToggleFlag( Console::Flags::DECORATE_SEVERITY,
false );
131 if ( messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT ||
132 messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT )
134 Console::printfn( outputError.c_str() );
136 else if ( messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT )
138 Console::warnfn( outputError.c_str() );
142 Console::errorfn( outputError.c_str() );
143 DIVIDE_ASSERT( VK_API::GetStateTracker()._assertOnAPIError && !(*VK_API::GetStateTracker()._assertOnAPIError), outputError.c_str() );
146 Console::ToggleFlag( Console::Flags::DECORATE_SEVERITY, severityDecoration );
147 Console::ToggleFlag( Console::Flags::PRINT_IMMEDIATE, isConsoleImmediate );
173 return Paths::Shaders::g_cacheLocation / Paths::g_buildTypeLocation / Paths::Shaders::g_cacheLocationVK;
193 ret = VK_SHADER_STAGE_ALL;
197 ret = VK_SHADER_STAGE_ALL_GRAPHICS;
201 ret = VK_SHADER_STAGE_COMPUTE_BIT;
207 ret |= VK_SHADER_STAGE_VERTEX_BIT;
211 ret |= VK_SHADER_STAGE_GEOMETRY_BIT;
215 ret |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
219 ret |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
223 ret |= VK_SHADER_STAGE_FRAGMENT_BIT;
227 ret |= VK_SHADER_STAGE_COMPUTE_BIT;
237 VkDescriptorBufferInfo _info{};
295 VkPipeline newPipeline;
296 if ( vkCreateComputePipelines( device, pipelineCache, 1, &pipelineInfo,
nullptr, &newPipeline ) != VK_SUCCESS )
299 return VK_NULL_HANDLE;
311 viewportState.pScissors = &
_scissor;
315 constexpr VkDynamicState dynamicStates[] = {
316 VK_DYNAMIC_STATE_VIEWPORT,
317 VK_DYNAMIC_STATE_SCISSOR,
318 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
319 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
320 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
321 VK_DYNAMIC_STATE_DEPTH_BIAS,
322 VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE,
323 VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE,
324 VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE,
325 VK_DYNAMIC_STATE_DEPTH_COMPARE_OP,
326 VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE,
327 VK_DYNAMIC_STATE_STENCIL_OP,
328 VK_DYNAMIC_STATE_CULL_MODE,
329 VK_DYNAMIC_STATE_FRONT_FACE,
330 VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE,
331 VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE,
333 VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
334 VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
335 VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
346 constexpr U32 stateCount =
to_U32( std::size( dynamicStates ) );
353 pipelineInfo.pDynamicState = &dynamicState;
358 pipelineInfo.pViewportState = &viewportState;
361 pipelineInfo.pColorBlendState = &colorBlending;
364 pipelineInfo.subpass = 0;
368 VkPipeline newPipeline;
369 if ( vkCreateGraphicsPipelines( device, pipelineCache, 1, &pipelineInfo,
nullptr, &newPipeline ) != VK_SUCCESS )
372 return VK_NULL_HANDLE;
387 bool needsClean =
false;
390 if (it.second == 0u || force)
407 return it.second == 0u;
418 if ( it.second > 0u )
432 : _context( context )
434 , _queueIndex(context.getQueue(type)._index)
474 VK_CHECK( vkBeginCommandBuffer( cmd, &cmdBeginInfo ) );
483 VK_CHECK( vkEndCommandBuffer( cmd ) );
486 submitInfo.commandBufferCount = 1;
487 submitInfo.pCommandBuffers = &cmd;
539 if ( isResourceTransient )
557 : _context( context )
576 if ( windowState.
_window ==
nullptr )
585 VkExtent2D surfaceExtent = windowState.
_swapChain->surfaceExtent();
587 if ( windowDimensions.
width != surfaceExtent.width || windowDimensions.
height != surfaceExtent.height )
590 surfaceExtent = windowState.
_swapChain->surfaceExtent();
593 const VkResult result = windowState.
_swapChain->beginFrame();
594 if ( result != VK_SUCCESS )
596 if ( result != VK_ERROR_OUT_OF_DATE_KHR && result != VK_SUBOPTIMAL_KHR )
627 assert( windowState.
_window !=
nullptr );
639 VkCommandBuffer cmd = windowState.
_swapChain->getFrameData()._commandBuffer;
642 s_dynamicOffsets.clear();
644 const VkResult result = windowState.
_swapChain->endFrame();
646 if ( result != VK_SUCCESS )
648 if ( result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR )
668 if ( pool._frameCount > 1u )
670 pool._allocatorPool->Flip();
671 pool._handle = pool._allocatorPool->GetAllocator();
692 if ( !it.second._isValid )
696 if ( it.second._program->getGUID() == program->
getGUID() )
728 vkDeviceWaitIdle(
_device->getVKDevice() );
742 if (windowState.
_surface ==
nullptr )
766 _descriptorSets.fill( VK_NULL_HANDLE );
767 _dummyDescriptorSet = VK_NULL_HANDLE ;
773 auto systemInfoRet = vkb::SystemInfo::get_system_info();
774 if ( !systemInfoRet )
781 vkb::InstanceBuilder builder{};
782 builder.set_app_name( window->
title() )
787 .set_debug_callback( divide_debug_callback )
788 .set_debug_callback_user_data_pointer(
this );
790 vkb::SystemInfo& systemInfo = systemInfoRet.value();
792 s_hasValidationFeaturesSupport =
false;
793 s_hasDebugMarkerSupport =
false;
794 if (
Config::ENABLE_GPU_VALIDATION && (config.debug.renderer.enableRenderAPIDebugging || config.debug.renderer.enableRenderAPIBestPractices) )
796 if (systemInfo.is_extension_available( VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME ) )
798 builder.enable_extension( VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME );
800 s_hasValidationFeaturesSupport =
true;
803 if ( systemInfo.is_extension_available( VK_EXT_DEBUG_UTILS_EXTENSION_NAME ) )
805 builder.enable_extension( VK_EXT_DEBUG_UTILS_EXTENSION_NAME );
806 builder.add_validation_feature_enable( VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT );
807 if (config.debug.renderer.enableRenderAPIBestPractices )
809 builder.add_validation_feature_enable( VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT );
812 s_hasDebugMarkerSupport = config.debug.renderer.useExtensions;
815 if ( systemInfo.validation_layers_available )
817 builder.enable_validation_layers();
821 auto instanceRet = builder.build();
828 _vkbInstance = instanceRet.value();
830 auto& perWindowContext = _perWindowState[window->
getGUID()];
831 perWindowContext._window = window;
834 SDL_Vulkan_CreateSurface( perWindowContext._window->getRawWindow(), _vkbInstance.instance, &perWindowContext._surface );
836 if ( perWindowContext._surface ==
nullptr )
841 _device = std::make_unique<VKDevice>( _vkbInstance, perWindowContext._surface );
843 VkDevice vkDevice = _device->getVKDevice();
844 if ( vkDevice == VK_NULL_HANDLE )
860 VkPhysicalDevice physicalDevice = _device->getVKPhysicalDevice();
863 if ( s_hasDebugMarkerSupport )
872 s_hasDynamicBlendStateSupport = config.debug.renderer.useExtensions && _device->supportsDynamicExtension3();
873 if ( s_hasDynamicBlendStateSupport )
880 s_hasPushDescriptorSupport = config.debug.renderer.useExtensions && _device->supportsPushDescriptors();
881 if ( s_hasPushDescriptorSupport )
886 s_hasDescriptorBufferSupport = config.debug.renderer.useExtensions && _device->supportsDescriptorBuffers();
887 if ( s_hasDescriptorBufferSupport )
891 vkGetDescriptorEXT = (PFN_vkGetDescriptorEXT)vkGetDeviceProcAddr( vkDevice,
"vkGetDescriptorEXT" );
899 VkFormatProperties2 properties{};
900 properties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
902 vkGetPhysicalDeviceFormatProperties2( physicalDevice, VK_FORMAT_D24_UNORM_S8_UINT, &properties );
903 s_depthFormatInformation._d24s8Supported = properties.formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
904 vkGetPhysicalDeviceFormatProperties2( physicalDevice, VK_FORMAT_D32_SFLOAT_S8_UINT, &properties );
905 s_depthFormatInformation._d32s8Supported = properties.formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
906 DIVIDE_ASSERT( s_depthFormatInformation._d24s8Supported || s_depthFormatInformation._d32s8Supported );
909 vkGetPhysicalDeviceFormatProperties2( physicalDevice, VK_FORMAT_X8_D24_UNORM_PACK32, &properties );
910 s_depthFormatInformation._d24x8Supported = properties.formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
911 vkGetPhysicalDeviceFormatProperties2( physicalDevice, VK_FORMAT_D32_SFLOAT, &properties );
912 s_depthFormatInformation._d32FSupported = properties.formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
913 DIVIDE_ASSERT( s_depthFormatInformation._d24x8Supported || s_depthFormatInformation._d32FSupported );
915 VkPhysicalDeviceProperties deviceProperties{};
916 vkGetPhysicalDeviceProperties( physicalDevice, &deviceProperties );
920 switch ( deviceProperties.vendorID )
946 case VK_VENDOR_ID_MESA:
956 deviceProperties.deviceName,
957 deviceProperties.vendorID,
958 deviceProperties.deviceID,
959 deviceProperties.driverVersion,
960 deviceProperties.apiVersion );
964 VK_CHECK( vkGetPhysicalDeviceToolProperties( physicalDevice, &toolCount, NULL ) );
966 if ( toolCount > 0u )
968 std::vector<VkPhysicalDeviceToolPropertiesEXT> tools;
969 tools.resize( toolCount );
970 VK_CHECK( vkGetPhysicalDeviceToolProperties( physicalDevice, &toolCount, tools.data() ) );
974 for ( VkPhysicalDeviceToolPropertiesEXT& tool : tools )
981 deviceInformation._versionInfo._major = 1u;
982 deviceInformation._versionInfo._minor =
to_U8( VK_API_VERSION_MINOR( deviceProperties.apiVersion ) );
984 deviceInformation._maxTextureUnits = deviceProperties.limits.maxDescriptorSetSampledImages;
985 deviceInformation._maxVertAttributeBindings = deviceProperties.limits.maxVertexInputBindings;
986 deviceInformation._maxVertAttributes = deviceProperties.limits.maxVertexInputAttributes;
987 deviceInformation._maxRTColourAttachments = deviceProperties.limits.maxColorAttachments;
988 deviceInformation._maxDrawIndirectCount = deviceProperties.limits.maxDrawIndirectCount;
989 deviceInformation._maxTextureSize = deviceProperties.limits.maxImageDimension2D;
991 deviceInformation._shaderCompilerThreads = 0xFFFFFFFF;
992 CLAMP( config.rendering.maxAnisotropicFilteringLevel,
994 to_U8( deviceProperties.limits.maxSamplerAnisotropy ) );
995 deviceInformation._maxAnisotropy = config.rendering.maxAnisotropicFilteringLevel;
999 const VkSampleCountFlags counts = deviceProperties.limits.framebufferColorSampleCounts & deviceProperties.limits.framebufferDepthSampleCounts;
1000 U8 maxMSAASamples = 0u;
1001 if ( counts & VK_SAMPLE_COUNT_2_BIT )
1003 maxMSAASamples = 2u;
1005 if ( counts & VK_SAMPLE_COUNT_4_BIT )
1007 maxMSAASamples = 4u;
1009 if ( counts & VK_SAMPLE_COUNT_8_BIT )
1011 maxMSAASamples = 8u;
1013 if ( counts & VK_SAMPLE_COUNT_16_BIT )
1015 maxMSAASamples = 16u;
1017 if ( counts & VK_SAMPLE_COUNT_32_BIT )
1019 maxMSAASamples = 32u;
1021 if ( counts & VK_SAMPLE_COUNT_64_BIT )
1023 maxMSAASamples = 64u;
1026 config.rendering.MSAASamples = std::min( config.rendering.MSAASamples, maxMSAASamples );
1027 config.rendering.shadowMapping.csm.MSAASamples = std::min( config.rendering.shadowMapping.csm.MSAASamples, maxMSAASamples );
1028 config.rendering.shadowMapping.spot.MSAASamples = std::min( config.rendering.shadowMapping.spot.MSAASamples, maxMSAASamples );
1032 for (
U8 i = 0u; i < 3; ++i )
1034 deviceInformation._maxWorgroupCount[i] = deviceProperties.limits.maxComputeWorkGroupCount[i];
1035 deviceInformation._maxWorgroupSize[i] = deviceProperties.limits.maxComputeWorkGroupSize[i];
1037 deviceInformation._maxWorgroupInvocations = deviceProperties.limits.maxComputeWorkGroupInvocations;
1038 deviceInformation._maxComputeSharedMemoryBytes = deviceProperties.limits.maxComputeSharedMemorySize;
1040 deviceInformation._maxWorgroupCount[0], deviceInformation._maxWorgroupCount[1], deviceInformation._maxWorgroupCount[2],
1041 deviceInformation._maxWorgroupSize[0], deviceInformation._maxWorgroupSize[1], deviceInformation._maxWorgroupSize[2],
1042 deviceInformation._maxWorgroupInvocations );
1046 deviceInformation._maxVertOutputComponents = deviceProperties.limits.maxVertexOutputComponents;
1049 deviceInformation._offsetAlignmentBytesUBO = deviceProperties.limits.minUniformBufferOffsetAlignment;
1050 deviceInformation._maxSizeBytesUBO = deviceProperties.limits.maxUniformBufferRange;
1051 deviceInformation._offsetAlignmentBytesSSBO = deviceProperties.limits.minStorageBufferOffsetAlignment;
1052 deviceInformation._maxSizeBytesSSBO = deviceProperties.limits.maxStorageBufferRange;
1053 deviceInformation._maxSSBOBufferBindings = deviceProperties.limits.maxPerStageDescriptorStorageBuffers;
1055 const bool UBOSizeOver1Mb = deviceInformation._maxSizeBytesUBO / 1024 > 1024;
1057 deviceProperties.limits.maxDescriptorSetUniformBuffers,
1058 (deviceInformation._maxSizeBytesUBO / 1024) / (UBOSizeOver1Mb ? 1024 : 1),
1059 UBOSizeOver1Mb ?
"Mb" :
"Kb",
1060 deviceInformation._offsetAlignmentBytesUBO );
1062 deviceInformation._maxSSBOBufferBindings,
1063 deviceInformation._maxSizeBytesSSBO / 1024 / 1024,
1064 deviceProperties.limits.maxDescriptorSetStorageBuffers,
1065 deviceInformation._offsetAlignmentBytesSSBO );
1067 deviceInformation._maxClipAndCullDistances = deviceProperties.limits.maxCombinedClipAndCullDistances;
1068 deviceInformation._maxClipDistances = deviceProperties.limits.maxClipDistances;
1069 deviceInformation._maxCullDistances = deviceProperties.limits.maxCullDistances;
1078 VmaAllocatorCreateInfo allocatorInfo = {};
1079 allocatorInfo.physicalDevice = physicalDevice;
1080 allocatorInfo.device = vkDevice;
1081 allocatorInfo.instance = _vkbInstance.instance;
1082 allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_3;
1083 allocatorInfo.preferredLargeHeapBlockSize = 0;
1085 vmaCreateAllocator( &allocatorInfo, &_allocator );
1086 GetStateTracker()._allocatorInstance._allocator = &_allocator;
1088 VkPipelineCacheCreateInfo pipelineCacheCreateInfo{};
1089 pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
1094 if ( errCache == FileError::NONE )
1096 data.seekg(0, std::ios::end);
1097 const size_t fileSize =
to_size(data.tellg());
1099 pipeline_data.resize(fileSize);
1100 data.read(
reinterpret_cast<char*
>(pipeline_data.data()), fileSize);
1102 pipelineCacheCreateInfo.initialDataSize = fileSize;
1103 pipelineCacheCreateInfo.pInitialData = pipeline_data.data();
1115 if ( _context.context().config().runtime.usePipelineCache )
1117 VK_CHECK( vkCreatePipelineCache( vkDevice, &pipelineCacheCreateInfo,
nullptr, &_pipelineCache ) );
1120 initStatePerWindow( perWindowContext );
1122 s_stateTracker.init(_device.get(), &perWindowContext);
1123 s_stateTracker._assertOnAPIError = &config.debug.renderer.assertOnRenderAPIError;
1124 s_stateTracker._enabledAPIDebugging = &config.debug.renderer.enableRenderAPIDebugging;
1145 vkDestroyPipelineLayout( device, layout,
nullptr );
1146 vkDestroyPipeline( device, pipeline,
nullptr );
1147 if ( wireframePipeline != VK_NULL_HANDLE )
1149 vkDestroyPipeline( device, wireframePipeline,
nullptr );
1155 deletePipeline(
_device->getVKDevice());
1194 if (
_device->getVKDevice() != VK_NULL_HANDLE )
1196 vkDeviceWaitIdle(
_device->getVKDevice() );
1202 pool._allocatorPool.reset();
1221 if ( err != FileError::NONE )
1273 default:
return false;
1298 s_lastBuffer->
draw( cmd, &userData );
1308 for (
const auto& binding : bindings )
1326 auto& drawDescriptor = program->perDrawDescriptorSetLayout();
1327 const bool targetDescriptorEmpty =
IsEmpty( drawDescriptor );
1328 const auto& setUsageData = program->setUsage();
1331 thread_local eastl::fixed_vector<VkWriteDescriptorSet, MAX_BINDINGS_PER_DESCRIPTOR_SET> descriptorWrites;
1332 U8 imageInfoIndex = 0u;
1334 bool needsBind =
false;
1339 if ( !setUsageData[usageIdx] )
1351 for (
U8 i = 0u; i <
entry._set->_bindingCount; ++i )
1391 DynamicEntry& crtBufferInfo = s_dynamicBindings[usageIdx][srcBinding.
_slot];
1392 if ( isPushDescriptor || crtBufferInfo._info.buffer != buffer || crtBufferInfo._info.range > boundRange || (crtBufferInfo._stageFlags & stageFlags) != stageFlags)
1394 crtBufferInfo._info.buffer = buffer;
1395 crtBufferInfo._info.offset = isPushDescriptor ? offset : 0u;
1396 crtBufferInfo._info.range = boundRange;
1397 crtBufferInfo._stageFlags |= stageFlags;
1400 VkDescriptorSetLayoutBinding newBinding{};
1401 newBinding.descriptorCount = 1u;
1403 newBinding.stageFlags = crtBufferInfo._stageFlags;
1404 newBinding.binding = srcBinding.
_slot;
1405 newBinding.pImmutableSamplers =
nullptr;
1407 descriptorWrites.push_back(
vk::writeDescriptorSet( newBinding.descriptorType, newBinding.binding, &crtBufferInfo._info, 1u ) );
1409 if (!isPushDescriptor )
1413 if ( dynamicBinding._slot == srcBinding.
_slot )
1415 dynamicBinding._offset =
to_U32(offset);
1446 descriptor._format = vkTex->vkFormat();
1450 const VkImageLayout targetLayout =
IsDepthTexture( vkTex->descriptor()._packing ) ? VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1454 const VkImageView imageView = vkTex->
getImageView( descriptor );
1456 VkDescriptorImageInfo& imageInfo = imageInfoArray[imageInfoIndex++];
1459 VkDescriptorSetLayoutBinding newBinding{};
1461 newBinding.descriptorCount = 1;
1462 newBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1463 newBinding.stageFlags = stageFlags;
1464 newBinding.binding = srcBinding.
_slot;
1466 descriptorWrites.push_back(
vk::writeDescriptorSet( newBinding.descriptorType, newBinding.binding, &imageInfo, 1u ) );
1487 descriptor._format = vkTex->vkFormat();
1494 const VkImageLayout targetLayout = descriptor._usage ==
ImageUsage::SHADER_READ ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
1495 VkDescriptorImageInfo& imageInfo = imageInfoArray[imageInfoIndex++];
1499 VkDescriptorSetLayoutBinding newBinding{};
1501 newBinding.descriptorCount = 1;
1502 newBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1503 newBinding.stageFlags = stageFlags;
1504 newBinding.binding = srcBinding.
_slot;
1506 descriptorWrites.push_back(
vk::writeDescriptorSet( newBinding.descriptorType, newBinding.binding, &imageInfo, 1u ) );
1515 if (!descriptorWrites.empty())
1517 if ( !isPushDescriptor )
1528 for ( VkWriteDescriptorSet& w : descriptorWrites )
1532 VK_PROFILE( vkUpdateDescriptorSets,
_device->getVKDevice(),
to_U32( descriptorWrites.size() ), descriptorWrites.data(), 0,
nullptr );
1540 pipeline._bindPoint,
1541 pipeline._vkPipelineLayout,
1543 to_U32(descriptorWrites.size()),
1544 descriptorWrites.data());
1546 descriptorWrites.clear();
1547 s_dynamicBindings[usageIdx] = {};
1555 thread_local VkDescriptorSetLayout tempLayout{ VK_NULL_HANDLE };
1559 if ( tempLayout == VK_NULL_HANDLE )
1561 VkDescriptorSetLayoutCreateInfo layoutInfo{
1562 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1573 s_dynamicOffsets.clear();
1579 const bool setUsed = setUsageData[i + offset];
1585 if ( binding._slot !=
U8_MAX )
1587 s_dynamicOffsets.push_back( binding._offset );
1595 pipeline._bindPoint,
1596 pipeline._vkPipelineLayout,
1600 to_U32( s_dynamicOffsets.size() ),
1601 s_dynamicOffsets.data() );
1614 auto& activeState = GetStateTracker()._activeWindow->_activeState;
1616 if ( currentState._stencilEnabled )
1618 if ( !activeState._isSet || !activeState._block._stencilEnabled )
1620 vkCmdSetStencilTestEnable( cmdBuffer, VK_TRUE );
1623 if ( !activeState._isSet || activeState._block._stencilMask != currentState._stencilMask )
1625 vkCmdSetStencilCompareMask( cmdBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, currentState._stencilMask );
1628 if ( !activeState._isSet || activeState._block._stencilWriteMask != currentState._stencilWriteMask )
1630 vkCmdSetStencilWriteMask( cmdBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, currentState._stencilWriteMask );
1633 if ( !activeState._isSet || activeState._block._stencilRef != currentState._stencilRef )
1635 vkCmdSetStencilReference( cmdBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, currentState._stencilRef );
1638 if ( !activeState._isSet ||
1639 activeState._block._stencilFailOp != currentState._stencilFailOp ||
1640 activeState._block._stencilPassOp != currentState._stencilPassOp ||
1641 activeState._block._stencilZFailOp != currentState._stencilZFailOp ||
1642 activeState._block._stencilFunc != currentState._stencilFunc )
1644 vkCmdSetStencilOp(cmdBuffer,
1645 VK_STENCIL_FACE_FRONT_AND_BACK,
1653 else if ( !activeState._isSet || !activeState._block._stencilEnabled )
1655 vkCmdSetStencilTestEnable( cmdBuffer, VK_FALSE );
1659 if ( !activeState._isSet || activeState._block._zFunc != currentState._zFunc )
1665 if ( !activeState._isSet || activeState._block._depthWriteEnabled != currentState._depthWriteEnabled )
1667 vkCmdSetDepthWriteEnable( cmdBuffer, currentState._depthWriteEnabled );
1671 if ( !activeState._isSet || !
COMPARE( activeState._block._zBias, currentState._zBias ) || !
COMPARE( activeState._block._zUnits, currentState._zUnits ) )
1673 if ( !
IS_ZERO( currentState._zBias ) )
1675 vkCmdSetDepthBiasEnable(cmdBuffer, VK_TRUE);
1676 vkCmdSetDepthBias( cmdBuffer, currentState._zUnits, 0.f, currentState._zBias );
1680 vkCmdSetDepthBiasEnable( cmdBuffer, VK_FALSE );
1685 if ( !activeState._isSet || activeState._block._cullMode != currentState._cullMode )
1691 if ( !activeState._isSet || activeState._block._frontFaceCCW != currentState._frontFaceCCW )
1693 vkCmdSetFrontFace( cmdBuffer, currentState._frontFaceCCW ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE );
1697 if ( !activeState._isSet || activeState._block._depthTestEnabled != currentState._depthTestEnabled )
1699 vkCmdSetDepthTestEnable( cmdBuffer, currentState._depthTestEnabled );
1703 if ( !activeState._isSet || activeState._block._rasterizationEnabled != currentState._rasterizationEnabled )
1705 vkCmdSetRasterizerDiscardEnable( cmdBuffer, !currentState._rasterizationEnabled );
1709 if ( !activeState._isSet || activeState._block._primitiveRestartEnabled != currentState._primitiveRestartEnabled )
1711 vkCmdSetPrimitiveRestartEnable( cmdBuffer, currentState._primitiveRestartEnabled );
1715 if ( s_hasDynamicBlendStateSupport )
1718 if ( !activeState._isSet || activeState._block._colourWrite != currentState._colourWrite )
1721 const VkColorComponentFlags colourFlags = (currentState._colourWrite.b[0] == 1 ? VK_COLOR_COMPONENT_R_BIT : 0) |
1722 (currentState._colourWrite.b[1] == 1 ? VK_COLOR_COMPONENT_G_BIT : 0) |
1723 (currentState._colourWrite.b[2] == 1 ? VK_COLOR_COMPONENT_B_BIT : 0) |
1724 (currentState._colourWrite.b[3] == 1 ? VK_COLOR_COMPONENT_A_BIT : 0);
1725 writeMask.fill(colourFlags);
1730 if ( !activeState._isSet || activeState._blendStates != blendStates )
1739 blendEnabled[i] = blendState.enabled() ? VK_TRUE : VK_FALSE;
1741 auto& equation = blendEquations[i];
1753 equation.srcAlphaBlendFactor = equation.srcColorBlendFactor;
1754 equation.dstAlphaBlendFactor = equation.dstColorBlendFactor;
1755 equation.alphaBlendOp = equation.colorBlendOp;
1762 activeState._blendStates = blendStates;
1769 activeState._block = currentState;
1770 activeState._isSet =
true;
1778 size_t stateHash = pipeline.stateHash();
1791 thread_local VkDescriptorSetLayout dummyLayout = VK_NULL_HANDLE;
1793 if ( dummyLayout == VK_NULL_HANDLE )
1795 VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo
1797 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1805 if ( program ==
nullptr )
1816 VkPushConstantRange push_constant;
1817 push_constant.offset = 0u;
1820 compiledPipeline.
_stageFlags = push_constant.stageFlags;
1823 pipeline_layout_info.pPushConstantRanges = &push_constant;
1824 pipeline_layout_info.pushConstantRangeCount = 1;
1830 compiledPipeline.
_program->dynamicBindings(dynamicBindings);
1833 const auto& setUsageData = compiledPipeline.
_program->setUsage();
1841 pipeline_layout_info.pSetLayouts = tempLayouts;
1851 bool isGraphicsPipeline =
false;
1852 for (
const auto& stage : shaderStages )
1855 isGraphicsPipeline = isGraphicsPipeline || stage._shader->stageMask() != VK_SHADER_STAGE_COMPUTE_BIT;
1857 compiledPipeline.
_bindPoint = isGraphicsPipeline ? VK_PIPELINE_BIND_POINT_GRAPHICS : VK_PIPELINE_BIND_POINT_COMPUTE;
1875 defaultState._frontFaceCCW ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE);
1876 pipelineBuilder.
_rasterizer.rasterizerDiscardEnable = !defaultState._rasterizationEnabled;
1878 VkSampleCountFlagBits msaaSampleFlags = VK_SAMPLE_COUNT_1_BIT;
1880 if ( msaaSamples > 0u )
1883 msaaSampleFlags =
static_cast<VkSampleCountFlagBits
>(msaaSamples);
1888 if ( msaaSamples > 0u )
1892 VkStencilOpState stencilOpState{};
1897 stencilOpState.compareMask = defaultState._stencilMask;
1898 stencilOpState.writeMask = defaultState._stencilWriteMask;
1899 stencilOpState.reference = defaultState._stencilRef;
1902 pipelineBuilder.
_depthStencil.stencilTestEnable = defaultState._stencilEnabled;
1906 pipelineBuilder.
_rasterizer.depthBiasConstantFactor = defaultState._zUnits;
1907 pipelineBuilder.
_rasterizer.depthBiasClamp = defaultState._zUnits;
1908 pipelineBuilder.
_rasterizer.depthBiasSlopeFactor = defaultState._zBias;
1914 (cWrite.
b[0] == 1 ? VK_COLOR_COMPONENT_R_BIT : 0) |
1915 (cWrite.
b[1] == 1 ? VK_COLOR_COMPONENT_G_BIT : 0) |
1916 (cWrite.
b[2] == 1 ? VK_COLOR_COMPONENT_B_BIT : 0) |
1917 (cWrite.
b[3] == 1 ? VK_COLOR_COMPONENT_A_BIT : 0),
1924 blend.blendEnable = blendState.enabled() ? VK_TRUE : VK_FALSE;
1936 blend.srcAlphaBlendFactor = blend.srcColorBlendFactor;
1937 blend.dstAlphaBlendFactor = blend.dstColorBlendFactor;
1938 blend.alphaBlendOp = blend.colorBlendOp;
1952 pipelineBuilder.
_rasterizer.polygonMode = VK_POLYGON_MODE_LINE;
1973 bindDynamicState( pipeline.descriptor()._stateBlock, pipeline.descriptor()._blendStates, cmdBuffer );
1974 ResetDescriptorDynamicOffsets();
2001 VkBuffer _srcBuffer{ VK_NULL_HANDLE };
2002 VkBuffer _dstBuffer{ VK_NULL_HANDLE };
2019 memBarrierOut.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
2020 memBarrierOut.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
2024 memBarrierOut.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
2025 memBarrierOut.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
2031 memBarrierOut.offset = request.
dstOffset;
2032 memBarrierOut.size = request.
size;
2033 memBarrierOut.buffer = request.
dstBuffer;
2040 for (
const auto& request : transferQueueBatched )
2045 if ( !barriers.empty() )
2048 dependencyInfo.bufferMemoryBarrierCount =
to_U32( barriers.size() );
2049 dependencyInfo.pBufferMemoryBarriers = barriers.data();
2051 VK_PROFILE( vkCmdPipelineBarrier2, cmd, &dependencyInfo );
2062 VkCopyBufferInfo2 copyInfo = { .sType = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 };
2063 copyInfo.dstBuffer = request._dstBuffer;
2064 copyInfo.srcBuffer = request._srcBuffer;
2065 copyInfo.regionCount =
to_U32( request._copiesPerBuffer.size() );
2066 copyInfo.pRegions = request._copiesPerBuffer.data();
2068 VK_PROFILE( vkCmdCopyBuffer2, cmd, ©Info );
2076 copyRequests.clear();
2077 copyRequests.reserve( transferQueueBatched.size() );
2079 VkBufferCopy2 copy{ .sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2 };
2081 for (
const auto& request : transferQueueBatched )
2083 copy.dstOffset = request.dstOffset;
2084 copy.srcOffset = request.srcOffset;
2085 copy.size = request.size;
2090 if (
entry._srcBuffer == request.srcBuffer &&
entry._dstBuffer == request.dstBuffer )
2092 entry._copiesPerBuffer.emplace_back( copy );
2112 transferQueueBatched.clear();
2114 while ( !transferQueue.
_requests.empty() )
2117 if ( request.
srcBuffer != VK_NULL_HANDLE )
2119 transferQueueBatched.push_back( request );
2139 FlushBarriers(s_barriers, s_transferQueueBatched, cmdBuffer,
true );
2142 FlushBarriers(s_barriers, s_transferQueueBatched, cmdBuffer,
false );
2144 s_transferQueueBatched.clear();
2145 transferQueue.
_dirty.store(
false);
2153 VkBufferMemoryBarrier2 barriers[2] = {};
2155 dependencyInfo.bufferMemoryBarrierCount = 1u;
2156 if ( request.
srcBuffer != VK_NULL_HANDLE )
2158 PrepareTransferRequest( request,
true, barriers[0] );
2160 VkBufferCopy2 copy{ .sType = VK_STRUCTURE_TYPE_BUFFER_COPY_2 };
2163 copy.size = request.
size;
2165 VkCopyBufferInfo2 copyInfo = { .sType = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 };
2168 copyInfo.regionCount = 1u;
2169 copyInfo.pRegions = ©
2171 vkCmdCopyBuffer2( cmd, ©Info );
2172 dependencyInfo.bufferMemoryBarrierCount = 2u;
2175 PrepareTransferRequest( request,
false, barriers[1] );
2176 dependencyInfo.pBufferMemoryBarriers = barriers;
2177 VK_PROFILE( vkCmdPipelineBarrier2, cmd, &dependencyInfo );
2189 },
"Deferred Buffer Uploads" );
2218 auto& stateTracker = GetStateTracker();
2220 VkCommandBuffer cmdBuffer = getCurrentCommandBuffer();
2225 FlushBufferTransferRequests();
2230 flushPushConstantsLocks();
2233 switch ( cmd->type() )
2239 thread_local VkRenderingAttachmentInfo dummyAttachment
2241 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
2242 .imageView = VK_NULL_HANDLE,
2243 .imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
2244 .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
2245 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
2258 thread_local VkRenderingInfo renderingInfo{};
2263 PushDebugMessage( cmdBuffer, crtCmd->
_name.c_str() );
2265 stateTracker._activeRenderTargetID = crtCmd->
_target;
2268 FlushBufferTransferRequests(cmdBuffer);
2277 swapChainImageFormat[0] = swapChain->
getSwapChain().image_format;
2278 stateTracker._pipelineRenderInfo.colorAttachmentCount =
to_U32(swapChainImageFormat.size());
2279 stateTracker._pipelineRenderInfo.pColorAttachmentFormats = swapChainImageFormat.data();
2282 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
2285 .extent = swapChain->surfaceExtent()
2288 .colorAttachmentCount =
to_U32( attachmentInfo.size() ),
2289 .pColorAttachments = attachmentInfo.data(),
2294 imageBarrier.subresourceRange = {
2295 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2298 .baseArrayLayer = 0,
2302 imageBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
2303 imageBarrier.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
2304 imageBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2306 imageBarrier.srcAccessMask = VK_ACCESS_2_NONE;
2307 imageBarrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
2308 imageBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2311 dependencyInfo.imageMemoryBarrierCount = 1u;
2312 dependencyInfo.pImageMemoryBarriers = &imageBarrier;
2314 VK_PROFILE( vkCmdPipelineBarrier2, cmdBuffer, &dependencyInfo);
2316 stateTracker._activeMSAASamples = 1u;
2322 renderingInfo = rt->renderingInfo();
2330 stateTracker._renderTargetFormatHash = 0u;
2331 for (
U32 i = 0u; i < stateTracker._pipelineRenderInfo.colorAttachmentCount; ++i )
2333 Util::Hash_combine( stateTracker._renderTargetFormatHash, stateTracker._pipelineRenderInfo.pColorAttachmentFormats[i]);
2337 renderingInfo.renderArea.offset.
x,
2338 renderingInfo.renderArea.offset.y,
2339 to_I32(renderingInfo.renderArea.extent.width),
2340 to_I32(renderingInfo.renderArea.extent.height)
2343 stateTracker._activeRenderTargetDimensions = { renderArea.
sizeX, renderArea.
sizeY};
2345 _context.setViewport( renderArea );
2346 _context.setScissor( renderArea );
2347 VK_PROFILE( vkCmdBeginRendering, cmdBuffer, &renderingInfo);
2358 imageBarrier.image = stateTracker._activeWindow->_swapChain->getCurrentImage();
2359 imageBarrier.subresourceRange = {
2360 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
2363 .baseArrayLayer = 0,
2367 imageBarrier.dstAccessMask = VK_ACCESS_2_NONE;
2368 imageBarrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT;
2369 imageBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
2371 imageBarrier.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
2372 imageBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
2373 imageBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2376 dependencyInfo.imageMemoryBarrierCount = 1u;
2377 dependencyInfo.pImageMemoryBarriers = &imageBarrier;
2379 VK_PROFILE( vkCmdPipelineBarrier2,cmdBuffer, &dependencyInfo );
2389 PopDebugMessage( cmdBuffer );
2390 stateTracker._renderTargetFormatHash = 0u;
2391 stateTracker._activeMSAASamples = _context.context().config().rendering.MSAASamples;
2392 stateTracker._activeRenderTargetDimensions = s_stateTracker._activeWindow->_window->getDrawableSize();
2394 FlushBufferTransferRequests( cmdBuffer );
2431 if ( crtCmd->
_texture != INVALID_HANDLE<Texture> )
2441 if ( crtCmd->
_texture != INVALID_HANDLE<Texture> )
2452 assert( pipeline !=
nullptr );
2455 const auto handle = pipeline->descriptor()._shaderProgramHandle;
2463 if ( stateTracker._pipeline._vkPipeline != VK_NULL_HANDLE )
2467 if ( uniforms !=
nullptr )
2469 if ( stateTracker._pipeline._program->uploadUniformData( *uniforms, _context.descriptorSet(
DescriptorSetUsage::PER_DRAW ).impl(), _uniformsMemCommand ) )
2472 _uniformsNeedLock = _uniformsNeedLock || _uniformsMemCommand._bufferLocks.empty();
2478 stateTracker._pipeline._vkPipelineLayout,
2479 stateTracker._pipeline._program->stageMask(),
2484 stateTracker._pushConstantsValid =
true;
2499 PopDebugMessage( cmdBuffer );
2506 InsertDebugMessage( cmdBuffer, crtCmd->
_msg.c_str(), crtCmd->
_msgId );
2516 if ( crtCmd->
_texture != INVALID_HANDLE<Texture> )
2527 if ( stateTracker._pipeline._vkPipeline != VK_NULL_HANDLE )
2529 if ( !stateTracker._pushConstantsValid )
2532 stateTracker._pipeline._vkPipelineLayout,
2533 stateTracker._pipeline._program->stageMask(),
2536 &s_defaultPushConstants[0].mat );
2537 stateTracker._pushConstantsValid =
true;
2544 DIVIDE_ASSERT( currentDrawCommand._drawCount < _context.GetDeviceInformation()._maxDrawIndirectCount );
2548 Draw( currentDrawCommand, cmdBuffer );
2556 VK_PROFILE( vkCmdBindPipeline, cmdBuffer, stateTracker._pipeline._bindPoint, stateTracker._pipeline._vkPipelineWireframe );
2557 Draw( currentDrawCommand, cmdBuffer );
2559 VK_PROFILE( vkCmdBindPipeline, cmdBuffer, stateTracker._pipeline._bindPoint, stateTracker._pipeline._vkPipeline );
2560 stateTracker._pipeline._topology = oldTopology;
2564 _context.registerDrawCalls( drawCount );
2571 if ( !stateTracker._pushConstantsValid )
2574 stateTracker._pipeline._vkPipelineLayout,
2575 stateTracker._pipeline._program->stageMask(),
2578 &s_defaultPushConstants[0].mat );
2579 stateTracker._pushConstantsValid =
true;
2583 if ( stateTracker._pipeline._vkPipeline != VK_NULL_HANDLE )
2593 constexpr U8 MAX_BUFFER_BARRIERS_PER_CMD{64};
2595 std::array<VkImageMemoryBarrier2, RT_MAX_ATTACHMENT_COUNT> imageBarriers{};
2596 U8 imageBarrierCount = 0u;
2598 std::array<VkBufferMemoryBarrier2, MAX_BUFFER_BARRIERS_PER_CMD> bufferBarriers{};
2599 U8 bufferBarrierCount = 0u;
2613 VkBufferMemoryBarrier2& memoryBarrier = bufferBarriers[bufferBarrierCount++];
2617 memoryBarrier.buffer = vkBuffer->
_buffer;
2621 switch (lock.
_type )
2630 memoryBarrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
2631 memoryBarrier.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
2632 memoryBarrier.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT | ALL_SHADER_STAGES;
2633 memoryBarrier.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT;
2634 if ( isCommandBuffer )
2636 memoryBarrier.dstStageMask |= VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT;
2637 memoryBarrier.dstAccessMask |= VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT;
2647 memoryBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT;
2648 memoryBarrier.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT;
2649 memoryBarrier.dstStageMask = VK_PIPELINE_STAGE_2_HOST_BIT;
2650 memoryBarrier.dstAccessMask = VK_ACCESS_2_HOST_READ_BIT;
2654 memoryBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT;
2655 memoryBarrier.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT;
2656 memoryBarrier.dstStageMask = ALL_SHADER_STAGES;
2657 memoryBarrier.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT;
2658 if ( isCommandBuffer )
2660 memoryBarrier.dstStageMask |= VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT;
2661 memoryBarrier.dstAccessMask |= VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT;
2666 memoryBarrier.srcStageMask = ALL_SHADER_STAGES;
2667 memoryBarrier.srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT;
2668 if ( isCommandBuffer )
2670 memoryBarrier.srcStageMask |= VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT;
2671 memoryBarrier.srcAccessMask |= VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT;
2673 memoryBarrier.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT;
2674 memoryBarrier.dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT;
2678 memoryBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT;
2679 memoryBarrier.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT;
2680 memoryBarrier.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT;
2681 memoryBarrier.dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT | VK_ACCESS_2_SHADER_READ_BIT;
2682 if ( isCommandBuffer )
2684 memoryBarrier.dstStageMask |= VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT;
2685 memoryBarrier.dstAccessMask |= VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT;
2690 memoryBarrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
2691 memoryBarrier.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
2692 memoryBarrier.dstStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
2693 memoryBarrier.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT;
2697 memoryBarrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
2698 memoryBarrier.srcAccessMask = VK_ACCESS_2_MEMORY_READ_BIT;
2699 memoryBarrier.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
2700 memoryBarrier.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
2704 memoryBarrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT;
2705 memoryBarrier.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
2706 memoryBarrier.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT;
2707 memoryBarrier.dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT;
2712 if ( bufferBarrierCount == MAX_BUFFER_BARRIERS_PER_CMD )
2716 dependencyInfo.bufferMemoryBarrierCount = bufferBarrierCount;
2717 dependencyInfo.pBufferMemoryBarriers = bufferBarriers.data();
2719 VK_PROFILE( vkCmdPipelineBarrier2, cmdBuffer, &dependencyInfo );
2720 bufferBarrierCount = 0u;
2726 if ( it._sourceLayout == it._targetLayout )
2734 const bool isDepthTexture =
IsDepthTexture( vkTex->descriptor()._packing );
2738 switch ( it._targetLayout )
2746 switch ( it._sourceLayout )
2784 switch ( it._sourceLayout )
2822 switch ( it._sourceLayout )
2875 auto subRange = it._targetView._subRange;
2876 const VkImageSubresourceRange subResourceRange = {
2878 .baseMipLevel = subRange._mipLevels._offset,
2879 .levelCount = subRange._mipLevels._count ==
U16_MAX ? VK_REMAINING_MIP_LEVELS : subRange._mipLevels._count,
2880 .baseArrayLayer = subRange._layerRange._offset,
2881 .layerCount = subRange._layerRange._count ==
U16_MAX ? VK_REMAINING_ARRAY_LAYERS : subRange._layerRange._count,
2888 if ( imageBarrierCount > 0u || bufferBarrierCount > 0u)
2891 dependencyInfo.imageMemoryBarrierCount = imageBarrierCount;
2892 dependencyInfo.pImageMemoryBarriers = imageBarriers.data();
2893 dependencyInfo.bufferMemoryBarrierCount = bufferBarrierCount;
2894 dependencyInfo.pBufferMemoryBarriers = bufferBarriers.data();
2896 VK_PROFILE( vkCmdPipelineBarrier2, cmdBuffer, &dependencyInfo );
2933 flushPushConstantsLocks();
2934 s_transientDeleteQueue.flush( _device->getDevice() );
2936 GetStateTracker()._activeRenderTargetDimensions = s_stateTracker._activeWindow->_window->getDrawableSize();
2941 return setViewportInternal( newViewport, getCurrentCommandBuffer() );
2948 VkViewport targetViewport{};
2949 targetViewport.width =
to_F32( newViewport.sizeX );
2950 targetViewport.height = -
to_F32( newViewport.sizeY );
2951 targetViewport.x =
to_F32(newViewport.offsetX);
2952 if ( newViewport.offsetY == 0 )
2954 targetViewport.y =
to_F32(newViewport.sizeY);
2958 targetViewport.y =
to_F32(newViewport.offsetY);
2959 targetViewport.y = GetStateTracker()._activeRenderTargetDimensions.height + targetViewport.y;
2961 targetViewport.minDepth = 0.f;
2962 targetViewport.maxDepth = 1.f;
2964 vkCmdSetViewport( cmdBuffer, 0, 1, &targetViewport );
2970 return setScissorInternal( newScissor, getCurrentCommandBuffer() );
2977 const VkOffset2D offset{ std::max( 0, newScissor.offsetX ), std::max( 0, newScissor.offsetY ) };
2978 const VkExtent2D extent{
to_U32( newScissor.sizeX ),
to_U32( newScissor.sizeY ) };
2979 const VkRect2D targetScissor{ offset, extent };
2980 vkCmdSetScissor( cmdBuffer, 0, 1, &targetScissor );
2988 thread_local eastl::fixed_vector<VkDescriptorSetLayoutBinding, MAX_BINDINGS_PER_DESCRIPTOR_SET, false> layoutBinding{};
2990 layoutBinding.clear();
2991 dynamicBindings.clear();
3002 VkDescriptorSetLayoutBinding& newBinding = layoutBinding.emplace_back();
3003 newBinding.descriptorCount = 1u;
3005 newBinding.stageFlags = GetFlagsForStageVisibility( bindings[slot]._visibility );
3006 newBinding.binding = slot;
3007 newBinding.pImmutableSamplers =
nullptr;
3021 if ( isPushDescriptor )
3023 layoutCreateInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
3048 pool._allocatorPool->SetPoolSizeMultiplier( VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0.f );
3049 pool._allocatorPool->SetPoolSizeMultiplier( VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 0.f );
3050 pool._allocatorPool->SetPoolSizeMultiplier( VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 0.f );
3051 pool._allocatorPool->SetPoolSizeMultiplier( VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 0.f );
3059 pool._allocatorPool->SetPoolSizeMultiplier( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 0.f);
3060 pool._allocatorPool->SetPoolSizeMultiplier( VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 0.f);
3066 pool._allocatorPool->SetPoolSizeMultiplier( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0.f );
3067 pool._allocatorPool->SetPoolSizeMultiplier( VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0.f );
3070 pool._handle = pool._allocatorPool->GetAllocator();
3074 void VK_API::onThreadCreated( [[maybe_unused]]
const std::thread::id& threadID, [[maybe_unused]]
const bool isMainRenderThread )
noexcept
3080 if ( program ==
nullptr )
3099 constexpr F32 color[4] = { 0.0f, 1.0f, 0.0f, 1.f };
3101 VkDebugUtilsLabelEXT labelInfo{};
3102 labelInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
3103 labelInfo.pLabelName = message;
3104 memcpy( labelInfo.color, &color[0],
sizeof(
F32 ) * 4 );
3118 constexpr F32 color[4] = { 0.5f, 0.5f, 0.5f, 1.f };
3120 VkDebugUtilsLabelEXT labelInfo{};
3121 labelInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
3122 labelInfo.pLabelName = message;
3123 memcpy( labelInfo.color, &color[0],
sizeof(
F32 ) * 4 );
3147 thread_local size_t cached_hash = 0u;
3148 thread_local VkSampler cached_handle = VK_NULL_HANDLE;
3154 samplerHashInOut =
GetHash( sampler );
3158 if ( cached_hash == samplerHashInOut )
3160 return cached_handle;
3162 cached_hash = samplerHashInOut;
3167 const SamplerObjectMap::const_iterator it =
s_samplerMap.find( cached_hash );
3171 cached_handle = it->second;
3172 return cached_handle;
3176 cached_handle = VK_NULL_HANDLE;
3180 const SamplerObjectMap::const_iterator it =
s_samplerMap.find( cached_hash );
3187 cached_handle = samplerHandler;
3191 cached_handle = it->second;
3195 return cached_handle;
3200 return std::make_unique<vkRenderTarget>(
_context, descriptor );
3205 return std::make_shared<vkGenericVertexData>(
_context, ringBufferLength, name );
3210 return std::make_unique<vkShaderBuffer>(
_context, descriptor );
VkFlags VkShaderStageFlags
#define PROFILE_SCOPE_AUTO(CATEGORY)
#define PROFILE_VK_INIT(DEVICES, PHYSICAL_DEVICES, CMD_QUEUES, CMD_QUEUES_FAMILY, NUM_CMD_QUEUS, FUNCTIONS)
#define PROFILE_TAG(NAME,...)
#define PROFILE_SCOPE(NAME, CATEGORY)
#define PROFILE_VK_EVENT_AUTO_AND_CONTEX(BUFFER)
WindowManager & windowManager() noexcept
static void MaxMSAASamples(const U8 maxSampleCount) noexcept
static void blitFrom(vkRenderTarget &rt, VkCommandBuffer cmdBuffer, vkRenderTarget *source, const RTBlitParams ¶ms) noexcept
static void end(vkRenderTarget &rt, VkCommandBuffer cmdBuffer, const RTTransitionMask &mask)
static void begin(vkRenderTarget &rt, VkCommandBuffer cmdBuffer, const RTDrawDescriptor &descriptor, const RTClearDescriptor &clearPolicy, VkPipelineRenderingCreateInfo &pipelineRenderingCreateInfoOut)
static DescriptorBuilder Begin(DescriptorLayoutCache *layoutCache, vke::DescriptorAllocatorHandle *allocator)
bool buildSetFromLayout(VkDescriptorSet &set, const VkDescriptorSetLayout &layoutIn, VkDevice device)
vec2< U16 > getDrawableSize() const noexcept
bool minimized() const noexcept
const char * title() const noexcept
SDL_Window * getRawWindow() const noexcept
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
static bool IsSubmitCommand(GFX::CommandType type) noexcept
static const DeviceInformation & GetDeviceInformation() noexcept
static U64 FrameCount() noexcept
static void OverrideDeviceInformation(const DeviceInformation &info) noexcept
FORCE_INLINE I64 getGUID() const noexcept
static void CleanExpiredSyncObjects(RenderAPI api, U64 frameNumber)
static SyncObjectHandle CreateSyncObject(RenderAPI api, U8 flag=DEFAULT_SYNC_FLAG_INTERNAL)
T * find(PoolHandle handle) const
PlatformContext & context() noexcept
DisplayWindow & mainWindow() noexcept
Application & app() noexcept
Configuration & config() noexcept
U8 getSampleCount() const noexcept
FORCE_INLINE BufferUsageType getUsage() const noexcept
virtual LockableBuffer * getBufferImpl()=0
FORCE_INLINE size_t getPrimitiveSize() const noexcept
std::array< BindingsPerSetArray, to_base(DescriptorSetUsage::COUNT)> BindingSetData
static void DestroyStaticData()
std::array< BindingsPerSet, MAX_BINDINGS_PER_DESCRIPTOR_SET > BindingsPerSetArray
static BindingSetData & GetBindingSetData() noexcept
static U32 GetBindingCount(DescriptorSetUsage usage, DescriptorSetBindingType type)
static DepthFormatInformation s_depthFormatInformation
static bool s_hasDescriptorBufferSupport
static void PushDebugMessage(VkCommandBuffer cmdBuffer, const char *message, U32 id=U32_MAX)
static void RegisterTransferRequest(const VKTransferQueue::TransferRequest &request)
static void PopDebugMessage(VkCommandBuffer cmdBuffer)
bool drawToWindow(DisplayWindow &window) override
void closeRenderingAPI() override
static void RegisterCustomAPIDelete(DELEGATE< void, VkDevice > &&cbk, bool isResourceTransient)
static bool s_hasValidationFeaturesSupport
VK_API(GFXDevice &context) noexcept
static bool s_hasDynamicBlendStateSupport
bool frameStarted() override
static eastl::stack< vkShaderProgram * > s_reloadedShaders
void flushCommand(GFX::CommandBase *cmd) noexcept override
void idle(bool fast) noexcept override
static SamplerObjectMap s_samplerMap
hashMap< size_t, CompiledPipeline > _compiledPipelines
static VKStateTracker & GetStateTracker() noexcept
static void OnShaderReloaded(vkShaderProgram *program)
static VKDeletionQueue s_transientDeleteQueue
void destroyStatePerWindow(VKPerWindowState &windowState)
std::array< VkDescriptorSetLayout, to_base(DescriptorSetUsage::COUNT)> _descriptorSetLayouts
bool setScissorInternal(const Rect< I32 > &newScissor) noexcept override
void onThreadCreated(const std::thread::id &threadID, bool isMainRenderThread) noexcept override
GenericVertexData_ptr newGVD(U32 ringBufferLength, const std::string_view name) const override
ErrorCode initRenderingAPI(I32 argc, char **argv, Configuration &config) noexcept override
bool bindShaderResources(const DescriptorSetEntries &descriptorSetEntries) override
void destroyPipeline(CompiledPipeline &pipeline, bool defer)
static void SubmitTransferRequest(const VKTransferQueue::TransferRequest &request, VkCommandBuffer cmd)
VkCommandBuffer getCurrentCommandBuffer() const noexcept
void postFlushCommandBuffer(Handle< GFX::CommandBuffer > commandBuffer) noexcept override
void preFlushCommandBuffer(Handle< GFX::CommandBuffer > commandBuffer) override
static VKStateTracker s_stateTracker
std::array< VkDescriptorSet, to_base(DescriptorSetUsage::COUNT)> _descriptorSets
static void FlushBufferTransferRequests()
void prepareFlushWindow(DisplayWindow &window) override
vkb::Instance _vkbInstance
std::array< DynamicBindings, to_base(DescriptorSetUsage::COUNT)> _descriptorDynamicBindings
bool setViewportInternal(const Rect< I32 > &newViewport) noexcept override
void flushPushConstantsLocks()
hashMap< I64, VKPerWindowState > _perWindowState
bool frameEnded() override
static bool s_hasDebugMarkerSupport
void initStatePerWindow(VKPerWindowState &windowState)
VkDescriptorSetLayout createLayoutFromBindings(const DescriptorSetUsage usage, const ShaderProgram::BindingsPerSetArray &bindings, DynamicBindings &dynamicBindings)
VkPipelineCache _pipelineCache
static VkSampler GetSamplerHandle(SamplerDescriptor sampler, size_t &samplerHashInOut)
Return the Vulkan sampler object's handle for the given hash value.
ShaderResult bindPipeline(const Pipeline &pipeline, VkCommandBuffer cmdBuffer)
static bool Draw(const GenericDrawCommand &cmd, VkCommandBuffer cmdBuffer)
RenderTarget_uptr newRT(const RenderTargetDescriptor &descriptor) const override
GFX::MemoryBarrierCommand _uniformsMemCommand
void onRenderThreadLoopStart() override
void bindDynamicState(const RenderStateBlock ¤tState, const RTBlendStates &blendStates, VkCommandBuffer cmdBuffer) noexcept
static bool s_hasPushDescriptorSupport
void flushWindow(DisplayWindow &window) override
static VKTransferQueue s_transferQueue
DescriptorLayoutCache_uptr _descriptorLayoutCache
void initDescriptorSets() override
ShaderBuffer_uptr newSB(const ShaderBufferDescriptor &descriptor) const override
hashMap< size_t, VkSampler, NoHash< size_t > > SamplerObjectMap
VkDescriptorSet _dummyDescriptorSet
static SharedMutex s_samplerMapLock
void recreateSwapChain(VKPerWindowState &windowState)
static VKDeletionQueue s_deviceDeleteQueue
void onRenderThreadLoopEnd() override
static void InsertDebugMessage(VkCommandBuffer cmdBuffer, const char *message, U32 id=U32_MAX)
void destroyPipelineCache()
VkCommandPool createCommandPool(uint32_t queueFamilyIndex, VkCommandPoolCreateFlags createFlags=VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT) const
void submitToQueue(QueueType queue, const VkSubmitInfo &submitInfo, VkFence &fence) const
VKQueue getQueue(QueueType type) const noexcept
VkDevice getVKDevice() const noexcept
vkb::Swapchain _swapChain
VkImageView getCurrentImageView() const noexcept
VkImage getCurrentImage() const noexcept
vkb::Swapchain & getSwapChain() noexcept
virtual void draw(const GenericDrawCommand &command, VDIUserData *data)=0
static void Destruct(VkSampler &handle)
static VkSampler Construct(const SamplerDescriptor &descriptor)
ShaderResult validatePreBind(const bool rebind) override
const vkShaders & shaderStages() const noexcept
VkShaderStageFlags stageMask() const noexcept
static void TransitionTexture(TransitionType type, const VkImageSubresourceRange &subresourceRange, VkImage image, VkImageMemoryBarrier2 &memBarrier)
static void Copy(VkCommandBuffer cmdBuffer, const vkTexture *source, const U8 sourceSamples, const vkTexture *destination, const U8 destinationSamples, CopyTexParams params)
VkImageView getImageView(const CachedImageView::Descriptor &descriptor) const
@ UNDEFINED_TO_SHADER_READ_COLOUR
@ UNDEFINED_TO_SHADER_READ_DEPTH
@ SHADER_READ_COLOUR_TO_GENERAL
@ DEPTH_ATTACHMENT_TO_SHADER_WRITE
@ COLOUR_ATTACHMENT_TO_SHADER_READ_WRITE
@ COLOUR_ATTACHMENT_TO_SHADER_WRITE
@ DEPTH_ATTACHMENT_TO_SHADER_READ_WRITE
@ UNDEFINED_TO_COLOUR_ATTACHMENT
@ SHADER_READ_COLOUR_TO_SHADER_READ_WRITE
@ DEPTH_STENCIL_ATTACHMENT_TO_SHADER_READ_WRITE
@ GENERAL_TO_SHADER_READ_DEPTH
@ SHADER_READ_WRITE_TO_SHADER_READ_COLOUR
@ SHADER_READ_WRITE_TO_SHADER_READ_DEPTH
@ UNDEFINED_TO_DEPTH_ATTACHMENT
@ COLOUR_ATTACHMENT_TO_SHADER_READ
@ DEPTH_ATTACHMENT_TO_SHADER_READ
@ DEPTH_STENCIL_ATTACHMENT_TO_SHADER_READ
@ SHADER_READ_DEPTH_TO_SHADER_READ_WRITE
@ UNDEFINED_TO_DEPTH_STENCIL_ATTACHMENT
@ GENERAL_TO_SHADER_READ_COLOUR
@ DEPTH_STENCIL_ATTACHMENT_TO_SHADER_WRITE
@ SHADER_READ_DEPTH_TO_GENERAL
@ UNDEFINED_TO_SHADER_READ_WRITE
static VkImageAspectFlags GetAspectFlags(const TextureDescriptor &descriptor) noexcept
static DescriptorAllocatorPool * Create(const VkDevice &device, Divide::I32 nFrames=3)
constexpr U8 MAX_DEBUG_SCOPE_DEPTH
Maximum number of nested debug scopes we support in the renderer.
constexpr auto ENGINE_VERSION_MINOR
constexpr unsigned char MINIMUM_VULKAN_MINOR_VERSION
constexpr bool ENABLE_GPU_VALIDATION
Error callbacks, validations, buffer checks, etc. are controlled by this flag. Heavy performance impa...
constexpr unsigned char DESIRED_VULKAN_MINOR_VERSION
constexpr auto ENGINE_VERSION_PATCH
constexpr U8 MAX_FRAMES_IN_FLIGHT
Maximum number of active frames until we start waiting on a fence/sync.
constexpr auto ENGINE_VERSION_MAJOR
constexpr char ENGINE_NAME[]
void SetObjectName(VkDevice device, uint64_t object, VkObjectType objectType, const char *name)
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT
PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT
PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT
PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT
PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT
constexpr Optick::Category::Type Graphics
Str StringFormat(const char *fmt, Args &&...args)
void Hash_combine(size_t &seed, const T &v, const Rest &... rest) noexcept
a la Boost
VkDescriptorType vkDescriptorType(DescriptorSetBindingType type, bool isPushDescriptor) noexcept
void SubmitRenderCommand(const GenericDrawCommand &drawCommand, const VkCommandBuffer commandBuffer, bool indexed)
Note: If internal format is not GL_NONE, an indexed draw is issued!
void OnStartup(VkDevice device)
void PrepareTransferRequest(const VKTransferQueue::TransferRequest &request, bool toWrite, VkBufferMemoryBarrier2 &memBarrierOut)
FORCE_INLINE ResourcePath PipelineCacheLocation()
FORCE_INLINE bool IsTriangles(const PrimitiveTopology topology)
void ResetDescriptorDynamicOffsets()
void BatchTransferQueue(BarrierContainer &barriers, BatchedTransferQueue &transferQueueBatched, VKTransferQueue &transferQueue)
std::array< DynamicEntry, MAX_BINDINGS_PER_DESCRIPTOR_SET > DynamicBufferEntry
VkShaderStageFlags GetFlagsForStageVisibility(const BaseType< ShaderStageVisibility > mask) noexcept
const ResourcePath PipelineCacheFileName
eastl::fixed_vector< VkBufferMemoryBarrier2, 32, true > BarrierContainer
thread_local std::array< DynamicBufferEntry, to_base(DescriptorSetUsage::COUNT)> s_dynamicBindings
void FlushCopyRequests(CopyContainer ©Requests, VkCommandBuffer cmd)
vector< PerBufferCopies > CopyContainer
void PrepareBufferCopyBarriers(CopyContainer ©Requests, BatchedTransferQueue &transferQueueBatched)
void FlushTransferQueue(VkCommandBuffer cmdBuffer, VKTransferQueue &transferQueue)
thread_local eastl::fixed_vector< U32, MAX_BINDINGS_PER_DESCRIPTOR_SET *to_base(DescriptorSetUsage::COUNT), false > s_dynamicOffsets
thread_local bool s_pipelineReset
void FlushBarriers(BarrierContainer &barriers, BatchedTransferQueue &transferQueueBatched, VkCommandBuffer cmd, bool toWrite)
eastl::fixed_vector< VKTransferQueue::TransferRequest, 64, false > BatchedTransferQueue
VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo(VkPolygonMode polygonMode, VkCullModeFlags cullMode, VkFrontFace frontFace, VkPipelineRasterizationStateCreateFlags flags=0)
VkCommandBufferAllocateInfo commandBufferAllocateInfo(VkCommandPool commandPool, VkCommandBufferLevel level, uint32_t bufferCount)
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo(const VkDescriptorSetLayoutBinding *pBindings, uint32_t bindingCount)
VkSubmitInfo submitInfo()
VkFenceCreateInfo fenceCreateInfo(VkFenceCreateFlags flags=0)
VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule shaderModule, const char *entryPoint="main")
VkWriteDescriptorSet writeDescriptorSet(VkDescriptorType type, uint32_t binding, VkDescriptorBufferInfo *bufferInfo, uint32_t descriptorCount=1)
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo(const VkDynamicState *pDynamicStates, uint32_t dynamicStateCount, VkPipelineDynamicStateCreateFlags flags=0)
VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo(VkSampleCountFlagBits rasterizationSamples, VkPipelineMultisampleStateCreateFlags flags=0)
VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo(VkBool32 depthTestEnable, VkBool32 depthWriteEnable, VkCompareOp depthCompareOp)
VkComputePipelineCreateInfo computePipelineCreateInfo(VkPipelineLayout layout, VkPipelineCreateFlags flags=0)
VkDependencyInfo dependencyInfo()
VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo(uint32_t patchControlPoints)
VkDescriptorImageInfo descriptorImageInfo(VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout)
VkCommandBufferBeginInfo commandBufferBeginInfo(VkCommandBufferUsageFlags flags=0)
VkImageMemoryBarrier2 imageMemoryBarrier2()
Initialize an image memory barrier with no image transfer ownership.
VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState(VkColorComponentFlags colorWriteMask, VkBool32 blendEnable)
VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo(uint32_t viewportCount, uint32_t scissorCount, VkPipelineViewportStateCreateFlags flags=0)
VkGraphicsPipelineCreateInfo pipelineCreateInfo()
VkBufferMemoryBarrier2 bufferMemoryBarrier2()
VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo()
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo(const VkDescriptorSetLayout *pSetLayouts, uint32_t setLayoutCount=1)
VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo(VkPrimitiveTopology topology, VkPipelineInputAssemblyStateCreateFlags flags, VkBool32 primitiveRestartEnable)
VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo(uint32_t attachmentCount, const VkPipelineColorBlendAttachmentState *pAttachments)
Handle console commands that start with a forward slash.
@ RT_DEPTH_STENCIL_ATTACHMENT
std::array< VkBlendFactor, to_base(BlendProperty::COUNT)> vkBlendTable
std::array< DescriptorSetEntry, to_base(DescriptorSetUsage::COUNT)> DescriptorSetEntries
DELEGATE_STD< Ret, Args... > DELEGATE
std::lock_guard< mutex > LockGuard
std::array< VkPolygonMode, to_base(FillMode::COUNT)> vkFillModeTable
bool IS_ZERO(const T X) noexcept
constexpr U32 to_U32(const T value)
TextureType TargetType(const ImageView &imageView) noexcept
static PFN_vkCmdSetColorBlendEnableEXT vkCmdSetColorBlendEnableEXT
bool isEnabledOption(const GenericDrawCommand &cmd, CmdRenderOptions option) noexcept
std::array< VkBlendOp, to_base(BlendOperation::COUNT)> vkBlendOpTable
FileError writeFile(const ResourcePath &filePath, const std::string_view fileName, const char *content, const size_t length, const FileType fileType)
FileError readFile(const ResourcePath &filePath, std::string_view fileName, FileType fileType, std::ifstream &sreamOut)
eastl::fixed_vector< DynamicBinding, MAX_BINDINGS_PER_DESCRIPTOR_SET, false > DynamicBindings
constexpr RenderTargetID SCREEN_TARGET_ID
static PFN_vkCmdBindDescriptorBuffersEXT vkCmdBindDescriptorBuffersEXT
constexpr U32 VK_VENDOR_ID_QUALCOMM
static PFN_vkCmdSetDescriptorBufferOffsetsEXT vkCmdSetDescriptorBufferOffsetsEXT
constexpr U8 MAX_BINDINGS_PER_DESCRIPTOR_SET
static PFN_vkGetDescriptorEXT vkGetDescriptorEXT
static PFN_vkGetDescriptorSetLayoutBindingOffsetEXT vkGetDescriptorSetLayoutBindingOffsetEXT
constexpr U32 VK_VENDOR_ID_INTEL
@ TRIANGLE_STRIP_ADJACENCY
constexpr F32 to_F32(const T value)
std::shared_mutex SharedMutex
size_t GetHash(const PropertyDescriptor< T > &descriptor) noexcept
std::array< VkCompareOp, to_base(ComparisonFunction::COUNT)> vkCompareFuncTable
static PFN_vkCmdBindDescriptorBufferEmbeddedSamplersEXT vkCmdBindDescriptorBufferEmbeddedSamplersEXT
@ COUNT
Place all properties above this.
eastl::vector< Type > vector
bool IsDepthTexture(GFXImagePacking packing) noexcept
std::shared_lock< mutex > SharedLock
static PFN_vkGetDescriptorSetLayoutSizeEXT vkGetDescriptorSetLayoutSizeEXT
static PFN_vkCmdSetColorBlendEquationEXT vkCmdSetColorBlendEquationEXT
constexpr U8 INVALID_TEXTURE_BINDING
std::underlying_type_t< Type > BaseType
constexpr U32 VK_VENDOR_ID_ARM
constexpr RenderTargetID INVALID_RENDER_TARGET_ID
constexpr bool isPowerOfTwo(const T x) noexcept
@ Vulkan
not supported yet
static PFN_vkCmdSetColorWriteMaskEXT vkCmdSetColorWriteMaskEXT
void efficient_clear(eastl::fixed_vector< T, nodeCount, bEnableOverflow, OverflowAllocator > &fixed_vector)
constexpr U8 to_U8(const T value)
bool IsEmpty(const BufferLocks &locks) noexcept
static const mat4< F32 > MAT4_ZERO
constexpr U32 VK_VENDOR_ID_IMGTECH
constexpr size_t to_size(const T value)
std::string VKErrorString(VkResult errorCode)
std::array< VkPrimitiveTopology, to_base(PrimitiveTopology::COUNT)> vkPrimitiveTypeTable
constexpr U32 INVALID_VK_QUEUE_INDEX
::value constexpr void CLAMP(T &n, T min, T max) noexcept
Clamps value n between min and max.
bool COMPARE(T X, U Y) noexcept
std::array< VkCullModeFlags, to_base(CullMode::COUNT)> vkCullModeTable
VertexInputDescription getVertexDescription(const AttributeMap &vertexFormat)
constexpr I32 to_I32(const T value)
@ VK_DEVICE_CREATE_FAILED
FORCE_INLINE T * Get(const Handle< T > handle)
constexpr U32 VK_VENDOR_ID_NVIDIA
constexpr U32 VK_VENDOR_ID_AMD
Project const SceneEntry & entry
std::array< VkStencilOp, to_base(StencilOperation::COUNT)> vkStencilOpTable
static PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR
constexpr auto to_base(const Type value) -> Type
VKAPI_ATTR VkBool32 VKAPI_CALL divide_debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *)
BufferUsageType _usageType
vkShaderProgram * _program
VkPipeline _vkPipelineWireframe
PrimitiveTopology _topology
VkShaderStageFlags _stageFlags
VkPipelineLayout _vkPipelineLayout
VkPipelineBindPoint _bindPoint
struct Divide::Configuration::Runtime runtime
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void printfn(const char *format, T &&... args)
vke::DescriptorAllocatorHandle _handle
SamplerDescriptor _sampler
DescriptorImageView _imageView
ShaderBufferEntry _buffer
DescriptorSetBindingType _type
DescriptorCombinedImageSampler _sampledImage
U16 _shaderStageVisibility
DescriptorSetBindingData _data
RTDrawDescriptor _descriptor
RTClearDescriptor _clearDescriptor
RenderTargetID _destination
Handle< Texture > _texture
UColour4 _clearColour
r = depth, g = stencil if target is a depth(+stencil) attachment
Handle< Texture > _texture
U8 _destinationMSAASamples
Handle< Texture > _destination
Handle< Texture > _source
vec3< U32 > _computeGroupSize
RTTransitionMask _transitionMask
TextureLayoutChanges _textureLayoutChanges
PixelAlignment _pixelPackAlignment
Handle< Texture > _texture
DELEGATE_STD< void, const ImageReadbackData & > _callback
PushConstantsStruct _fastData
UniformData * _uniformData
IndirectIndexedDrawCommand _cmd
const Texture * _srcTexture
bool lockRange(BufferRange range, SyncObjectHandle &sync) const
VkPipelineLayout _pipelineLayout
VkPipelineMultisampleStateCreateInfo _multisampling
VkPipelineInputAssemblyStateCreateInfo _inputAssembly
std::vector< VkPipelineShaderStageCreateInfo > _shaderStages
VkPipeline build_graphics_pipeline(VkDevice device, VkPipelineCache pipelineCache)
VkPipelineTessellationStateCreateInfo _tessellation
eastl::fixed_vector< VkPipelineColorBlendAttachmentState, to_base(RTColourAttachmentSlot::COUNT), false > _colorBlendAttachments
VkPipelineVertexInputStateCreateInfo _vertexInputInfo
VkPipelineDepthStencilStateCreateInfo _depthStencil
VkPipeline build_compute_pipeline(VkDevice device, VkPipelineCache pipelineCache)
VkPipelineRasterizationStateCreateInfo _rasterizer
VkPipeline build_pipeline(VkDevice device, VkPipelineCache pipelineCache, bool graphics)
PrimitiveTopology _primitiveTopology
AttributeMap _vertexFormat
Handle< ShaderProgram > _shaderProgramHandle
RTBlendStates _blendStates
RenderStateBlock _stateBlock
const F32 * dataPtr() const
bool set() const noexcept
static constexpr size_t Size() noexcept
std::array< BlendingSettings, to_base(RTColourAttachmentSlot::COUNT)> _settings
StringReturnType< N > string() const noexcept
static constexpr size_t INVALID_SAMPLER_HASH
static constexpr size_t INVALID_SYNC_ID
std::deque< std::pair< QueuedItem, U8 > > _deletionQueue
void push(QueuedItem &&function)
void flush(VkDevice device, bool force=false)
static constexpr U8 BUFFER_COUNT
VKImmediateCmdContext(VKDevice &context, QueueType type)
void flushCommandBuffer(FlushCallback &&function, const char *scopeName)
std::function< void(VkCommandBuffer cmd, QueueType queue, U32 queueIndex)> FlushCallback
std::array< VkCommandBuffer, BUFFER_COUNT > _commandBuffers
std::array< VkFence, BUFFER_COUNT > _bufferFences
VkCommandPool _commandPool
struct Divide::VKPerWindowState::VKDynamicState _activeState
VKSwapChain_uptr _swapChain
VkBuffer _drawIndirectBuffer
CompiledPipeline _pipeline
DebugScope _lastInsertedDebugMessage
VKImmediateCmdContext * IMCmdContext(QueueType type) const
VkShaderStageFlags _pipelineStageMask
vec2< U16 > _activeRenderTargetDimensions
size_t _drawIndirectBufferOffset
std::array< VKImmediateCmdContext_uptr, to_base(QueueType::COUNT)> _cmdContexts
RenderTargetID _activeRenderTargetID
void init(VKDevice *device, VKPerWindowState *mainWindow)
std::array< DescriptorAllocator, to_base(DescriptorSetUsage::COUNT)> _descriptorAllocators
VKPerWindowState * _activeWindow
DebugScope _debugScope[Config::MAX_DEBUG_SCOPE_DEPTH]
VkPipelineRenderingCreateInfo _pipelineRenderInfo
VkPipelineStageFlags2 dstStageMask
VkAccessFlags2 dstAccessMask
std::deque< TransferRequest > _requests
const BufferParams _params
vector< VkBufferCopy2 > _copiesPerBuffer
VkCommandBuffer * _cmdBuffer
#define VK_PROFILE(FUNCTION,...)