@@ -375,9 +375,7 @@ void RenderBackend::renderFrame(const bool presentToScreen) {
375375
376376 // transition swapchain image to present
377377 auto & swapchainPresentImage = getImageRef (m_swapchainInputImageHandle);
378- const auto & transitionToPresentBarrier = createImageBarriers (swapchainPresentImage,
379- VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0 , 1 );
380- issueBarriersCommand (frameResources.commandBuffer , transitionToPresentBarrier, std::vector<VkBufferMemoryBarrier> {});
378+ recordImageLayoutTransition (swapchainPresentImage, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, frameResources.commandBuffer );
381379
382380 endCommandBufferRecording (frameResources.commandBuffer );
383381
@@ -1245,7 +1243,7 @@ Image RenderBackend::createImageInternal(const ImageDescription& desc, const Dat
12451243 transferDataIntoImageImmediate (image, initialData, m_transferResources);
12461244 }
12471245 if (desc.autoCreateMips ) {
1248- generateMipChain (image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1246+ generateMipChainImmediate (image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, m_transferResources. transientCmdPool );
12491247 }
12501248
12511249 // most textures with sampled usage are used by the material system
@@ -1254,7 +1252,7 @@ Image RenderBackend::createImageInternal(const ImageDescription& desc, const Dat
12541252 // to avoid issues all sampled images without mip generation are manually transitioned to read_only_optimal
12551253 const bool manualLayoutTransitionRequired = bool (desc.usageFlags & ImageUsageFlags::Sampled) && !desc.autoCreateMips ;
12561254 if (manualLayoutTransitionRequired) {
1257- manualImageLayoutTransition (image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1255+ imageLayoutTransitionImmediate (image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, m_transferResources. transientCmdPool );
12581256 }
12591257
12601258 const bool imageCanBeSampled = bool (desc.usageFlags & ImageUsageFlags::Sampled);
@@ -1264,28 +1262,6 @@ Image RenderBackend::createImageInternal(const ImageDescription& desc, const Dat
12641262 return image;
12651263}
12661264
1267- void RenderBackend::manualImageLayoutTransition (Image& image, const VkImageLayout newLayout) {
1268-
1269- const VkCommandBuffer transitionCmdBuffer = allocateCommandBuffer (VK_COMMAND_BUFFER_LEVEL_PRIMARY, m_transferResources.transientCmdPool );
1270- beginCommandBuffer (transitionCmdBuffer, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
1271-
1272- const auto newLayoutBarriers = createImageBarriers (
1273- image,
1274- newLayout,
1275- VK_ACCESS_TRANSFER_WRITE_BIT,
1276- 0 ,
1277- (uint32_t )image.viewPerMip .size ());
1278-
1279- issueBarriersCommand (transitionCmdBuffer, newLayoutBarriers, std::vector<VkBufferMemoryBarrier> {});
1280- endCommandBufferRecording (transitionCmdBuffer);
1281-
1282- const VkFence fence = submitOneTimeUseCmdBuffer (transitionCmdBuffer, vkContext.transferQueue );
1283- waitForFence (fence);
1284-
1285- vkDestroyFence (vkContext.device , fence, nullptr );
1286- vkFreeCommandBuffers (vkContext.device , m_transferResources.transientCmdPool , 1 , &transitionCmdBuffer);
1287- }
1288-
12891265void RenderBackend::addImageToGlobalDescriptorSetLayout (Image& image) {
12901266 const bool isFreeIndexAvailable = m_globalTextureArrayDescriptorSetFreeTextureIndices.size () > 0 ;
12911267 if (isFreeIndexAvailable) {
@@ -1311,79 +1287,6 @@ Buffer RenderBackend::createBufferInternal(const VkDeviceSize size, const std::v
13111287 return buffer;
13121288}
13131289
1314- void RenderBackend::generateMipChain (Image& image, const VkImageLayout newLayout) {
1315-
1316- // check for linear filtering support
1317- VkFormatProperties formatProps;
1318- vkGetPhysicalDeviceFormatProperties (vkContext.physicalDevice , image.format , &formatProps);
1319- if (!(formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) {
1320- throw std::runtime_error (" physical device lacks linear filtering support for used format" );
1321- }
1322-
1323- VkImageBlit blitInfo;
1324-
1325- // offset base stays zero
1326- blitInfo.srcOffsets [0 ].x = 0 ;
1327- blitInfo.srcOffsets [0 ].y = 0 ;
1328- blitInfo.srcOffsets [0 ].z = 0 ;
1329-
1330- blitInfo.dstOffsets [0 ].x = 0 ;
1331- blitInfo.dstOffsets [0 ].y = 0 ;
1332- blitInfo.dstOffsets [0 ].z = 0 ;
1333-
1334- // initial offset extent
1335- blitInfo.srcOffsets [1 ].x = image.desc .width ;
1336- blitInfo.srcOffsets [1 ].y = image.desc .height ;
1337- blitInfo.srcOffsets [1 ].z = image.desc .depth ;
1338-
1339- blitInfo.dstOffsets [1 ].x = blitInfo.srcOffsets [1 ].x != 1 ? blitInfo.srcOffsets [1 ].x / 2 : 1 ;
1340- blitInfo.dstOffsets [1 ].y = blitInfo.srcOffsets [1 ].y != 1 ? blitInfo.srcOffsets [1 ].y / 2 : 1 ;
1341- blitInfo.dstOffsets [1 ].z = blitInfo.srcOffsets [1 ].z != 1 ? blitInfo.srcOffsets [1 ].z / 2 : 1 ;
1342-
1343- const VkCommandBuffer blitCmdBuffer = allocateCommandBuffer (VK_COMMAND_BUFFER_LEVEL_PRIMARY, m_transferResources.transientCmdPool );
1344- beginCommandBuffer (blitCmdBuffer, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
1345-
1346- for (uint32_t srcMip = 0 ; srcMip < image.viewPerMip .size () - 1 ; srcMip++) {
1347-
1348- // barriers
1349- auto barriers = createImageBarriers (image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, srcMip, 1 ); // src
1350- const auto dstBarriers = createImageBarriers (image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, srcMip + 1 , 1 ); // dst
1351- barriers.insert (barriers.end (), dstBarriers.begin (), dstBarriers.end ());
1352-
1353- issueBarriersCommand (blitCmdBuffer, barriers, std::vector<VkBufferMemoryBarrier> {});
1354-
1355- // blit operation
1356- blitInfo.srcSubresource = createSubresourceLayers (image, srcMip );
1357- blitInfo.dstSubresource = createSubresourceLayers (image, srcMip + 1 );
1358-
1359- vkCmdBlitImage (blitCmdBuffer, image.vulkanHandle , VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image.vulkanHandle ,
1360- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1 , &blitInfo, VK_FILTER_LINEAR);
1361-
1362- // update offsets
1363- blitInfo.srcOffsets [1 ].x /= blitInfo.srcOffsets [1 ].x != 1 ? 2 : 1 ;
1364- blitInfo.srcOffsets [1 ].y /= blitInfo.srcOffsets [1 ].y != 1 ? 2 : 1 ;
1365- blitInfo.srcOffsets [1 ].z /= blitInfo.srcOffsets [1 ].z != 1 ? 2 : 1 ;
1366-
1367- blitInfo.dstOffsets [1 ].x = blitInfo.srcOffsets [1 ].x != 1 ? blitInfo.srcOffsets [1 ].x / 2 : 1 ;
1368- blitInfo.dstOffsets [1 ].y = blitInfo.srcOffsets [1 ].y != 1 ? blitInfo.srcOffsets [1 ].y / 2 : 1 ;
1369- blitInfo.dstOffsets [1 ].z = blitInfo.srcOffsets [1 ].z != 1 ? blitInfo.srcOffsets [1 ].z / 2 : 1 ;
1370- }
1371-
1372- // bring image into new layout
1373- const auto newLayoutBarriers = createImageBarriers (image, newLayout, VK_ACCESS_TRANSFER_WRITE_BIT, 0 , (uint32_t )image.viewPerMip .size ());
1374- issueBarriersCommand (blitCmdBuffer, newLayoutBarriers, std::vector<VkBufferMemoryBarrier> {});
1375-
1376- endCommandBufferRecording (blitCmdBuffer);
1377-
1378- // submit
1379- const VkFence fence = submitOneTimeUseCmdBuffer (blitCmdBuffer, vkContext.transferQueue );
1380- waitForFence (fence);
1381-
1382- // cleanup
1383- vkDestroyFence (vkContext.device , fence, nullptr );
1384- vkFreeCommandBuffers (vkContext.device , m_transferResources.transientCmdPool , 1 , &blitCmdBuffer);
1385- }
1386-
13871290VkDescriptorPool RenderBackend::findFittingDescriptorPool (const DescriptorPoolAllocationSizes& requiredSizes){
13881291
13891292 VkDescriptorPool fittingPool = VK_NULL_HANDLE;
@@ -1535,28 +1438,18 @@ ComputePass RenderBackend::createComputePassInternal(const ComputePassDescriptio
15351438
15361439 pass.descriptorSetLayout = createDescriptorSetLayout (reflection.shaderLayout );
15371440
1441+ ShaderSpecialisationStructs specialisationStructs;
1442+ createShaderSpecialisationStructs (desc.shaderDescription .specialisationConstants , &specialisationStructs);
1443+ VkPipelineShaderStageCreateInfo shaderStageInfo = createPipelineShaderStageInfos (module , stageFlags, &specialisationStructs.info );
1444+
15381445 const VkDescriptorSetLayout setLayouts[3 ] = {
15391446 m_globalDescriptorSetLayout,
15401447 pass.descriptorSetLayout ,
15411448 m_globalTextureArrayDescriporSetLayout };
15421449
15431450 pass.pipelineLayout = createPipelineLayout (setLayouts, reflection.pushConstantByteSize , stageFlags);
15441451 pass.pushConstantSize = reflection.pushConstantByteSize ;
1545-
1546- ShaderSpecialisationStructs specialisationStructs;
1547- createShaderSpecialisationStructs (desc.shaderDescription .specialisationConstants , &specialisationStructs);
1548-
1549- VkComputePipelineCreateInfo pipelineInfo;
1550- pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
1551- pipelineInfo.pNext = nullptr ;
1552- pipelineInfo.flags = 0 ;
1553- pipelineInfo.stage = createPipelineShaderStageInfos (module , stageFlags, &specialisationStructs.info );
1554- pipelineInfo.layout = pass.pipelineLayout ;
1555- pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
1556- pipelineInfo.basePipelineIndex = 0 ;
1557-
1558- auto res = vkCreateComputePipelines (vkContext.device , VK_NULL_HANDLE, 1 , &pipelineInfo, nullptr , &pass.pipeline );
1559- checkVulkanResult (res);
1452+ pass.pipeline = createVulkanComputePipeline (pass.pipelineLayout , shaderStageInfo);
15601453
15611454 vkDestroyShaderModule (vkContext.device , module , nullptr );
15621455
@@ -1693,7 +1586,9 @@ GraphicPass RenderBackend::createGraphicPassInternal(const GraphicPassDescriptio
16931586
16941587 GraphicPassSpecialisationStructs specialisationStructs;
16951588 const auto shaderStages = createGraphicPipelineShaderCreateInfo (
1696- desc.shaderDescriptions , shaderModules, &specialisationStructs);
1589+ desc.shaderDescriptions ,
1590+ shaderModules,
1591+ &specialisationStructs);
16971592
16981593 const ShaderReflection reflection = performShaderReflection (spirV);
16991594 const VkShaderStageFlags pipelineShaderStageFlags = getGraphicPassShaderStageFlags (shaderModules);
0 commit comments