TextureImpl.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. // Copyright (C) 2009-2019, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <anki/gr/vulkan/TextureImpl.h>
  6. #include <anki/gr/Sampler.h>
  7. #include <anki/gr/GrManager.h>
  8. #include <anki/gr/vulkan/GrManagerImpl.h>
  9. #include <anki/gr/CommandBuffer.h>
  10. #include <anki/gr/vulkan/CommandBufferImpl.h>
  11. #include <anki/gr/common/Misc.h>
  12. namespace anki
  13. {
  14. TextureImpl::~TextureImpl()
  15. {
  16. #if ANKI_ASSERTS_ENABLED
  17. if(m_usage != m_usedFor)
  18. {
  19. ANKI_VK_LOGW("Texture %s hasn't been used in all types of usages", getName().cstr());
  20. }
  21. #endif
  22. for(auto it : m_viewsMap)
  23. {
  24. if(it != VK_NULL_HANDLE)
  25. {
  26. vkDestroyImageView(getDevice(), it, nullptr);
  27. }
  28. }
  29. m_viewsMap.destroy(getAllocator());
  30. if(m_imageHandle && !(m_usage & TextureUsageBit::PRESENT))
  31. {
  32. vkDestroyImage(getDevice(), m_imageHandle, nullptr);
  33. }
  34. if(m_memHandle)
  35. {
  36. getGrManagerImpl().getGpuMemoryManager().freeMemory(m_memHandle);
  37. }
  38. if(m_dedicatedMem)
  39. {
  40. vkFreeMemory(getDevice(), m_dedicatedMem, nullptr);
  41. }
  42. }
  43. Error TextureImpl::initInternal(VkImage externalImage, const TextureInitInfo& init_)
  44. {
  45. TextureInitInfo init = init_;
  46. ANKI_ASSERT(init.isValid());
  47. if(externalImage)
  48. {
  49. ANKI_ASSERT(!!(init.m_usage & TextureUsageBit::PRESENT));
  50. }
  51. // Set some stuff
  52. m_width = init.m_width;
  53. m_height = init.m_height;
  54. m_depth = init.m_depth;
  55. m_texType = init.m_type;
  56. if(m_texType == TextureType::_3D)
  57. {
  58. m_mipCount = min<U>(init.m_mipmapCount, computeMaxMipmapCount3d(m_width, m_height, m_depth));
  59. }
  60. else
  61. {
  62. m_mipCount = min<U>(init.m_mipmapCount, computeMaxMipmapCount2d(m_width, m_height));
  63. }
  64. init.m_mipmapCount = m_mipCount;
  65. m_layerCount = init.m_layerCount;
  66. m_format = init.m_format;
  67. m_vkFormat = convertFormat(m_format);
  68. m_aspect = getImageAspectFromFormat(m_format);
  69. m_usage = init.m_usage;
  70. if(externalImage)
  71. {
  72. m_imageHandle = externalImage;
  73. }
  74. else
  75. {
  76. ANKI_CHECK(initImage(init));
  77. }
  78. // Init the template
  79. zeroMemory(m_viewCreateInfoTemplate); // zero it, it will be used for hashing
  80. m_viewCreateInfoTemplate.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  81. m_viewCreateInfoTemplate.image = m_imageHandle;
  82. m_viewCreateInfoTemplate.viewType = convertTextureViewType(init.m_type);
  83. m_viewCreateInfoTemplate.format = m_vkFormat;
  84. m_viewCreateInfoTemplate.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
  85. m_viewCreateInfoTemplate.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
  86. m_viewCreateInfoTemplate.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
  87. m_viewCreateInfoTemplate.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
  88. m_viewCreateInfoTemplate.subresourceRange.aspectMask = convertImageAspect(m_aspect);
  89. m_viewCreateInfoTemplate.subresourceRange.baseArrayLayer = 0;
  90. m_viewCreateInfoTemplate.subresourceRange.baseMipLevel = 0;
  91. m_viewCreateInfoTemplate.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
  92. m_viewCreateInfoTemplate.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
  93. // Transition the image layout from undefined to something relevant
  94. if(!!init.m_initialUsage)
  95. {
  96. ANKI_ASSERT(usageValid(init.m_initialUsage));
  97. ANKI_ASSERT(!(init.m_initialUsage & TextureUsageBit::GENERATE_MIPMAPS) && "That doesn't make any sense");
  98. CommandBufferInitInfo cmdbinit;
  99. cmdbinit.m_flags = CommandBufferFlag::GRAPHICS_WORK | CommandBufferFlag::SMALL_BATCH;
  100. CommandBufferPtr cmdb = getManager().newCommandBuffer(cmdbinit);
  101. VkImageSubresourceRange range;
  102. range.aspectMask = convertImageAspect(m_aspect);
  103. range.baseArrayLayer = 0;
  104. range.baseMipLevel = 0;
  105. range.layerCount = m_layerCount;
  106. range.levelCount = m_mipCount;
  107. static_cast<CommandBufferImpl&>(*cmdb).setTextureBarrierRange(
  108. TexturePtr(this), TextureUsageBit::NONE, init.m_initialUsage, range);
  109. static_cast<CommandBufferImpl&>(*cmdb).endRecording();
  110. getGrManagerImpl().flushCommandBuffer(cmdb, nullptr);
  111. }
  112. return Error::NONE;
  113. }
  114. VkFormatFeatureFlags TextureImpl::calcFeatures(const TextureInitInfo& init)
  115. {
  116. VkFormatFeatureFlags flags = 0;
  117. if(init.m_mipmapCount > 1 && !!(init.m_usage & TextureUsageBit::GENERATE_MIPMAPS))
  118. {
  119. // May be used for mip gen.
  120. flags |= VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT;
  121. }
  122. if(!!(init.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE))
  123. {
  124. if(formatIsDepthStencil(init.m_format))
  125. {
  126. flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
  127. }
  128. else
  129. {
  130. flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
  131. }
  132. }
  133. if(!!(init.m_usage & TextureUsageBit::SAMPLED_ALL))
  134. {
  135. flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
  136. }
  137. ANKI_ASSERT(flags);
  138. return flags;
  139. }
  140. VkImageCreateFlags TextureImpl::calcCreateFlags(const TextureInitInfo& init)
  141. {
  142. VkImageCreateFlags flags = 0;
  143. if(init.m_type == TextureType::CUBE || init.m_type == TextureType::CUBE_ARRAY)
  144. {
  145. flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
  146. }
  147. return flags;
  148. }
  149. Bool TextureImpl::imageSupported(const TextureInitInfo& init)
  150. {
  151. VkImageFormatProperties props = {};
  152. VkResult res = vkGetPhysicalDeviceImageFormatProperties(getGrManagerImpl().getPhysicalDevice(),
  153. m_vkFormat,
  154. convertTextureType(init.m_type),
  155. VK_IMAGE_TILING_OPTIMAL,
  156. convertTextureUsage(init.m_usage, init.m_format),
  157. calcCreateFlags(init),
  158. &props);
  159. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  160. {
  161. return false;
  162. }
  163. else
  164. {
  165. ANKI_ASSERT(res == VK_SUCCESS);
  166. return true;
  167. }
  168. }
  169. Error TextureImpl::initImage(const TextureInitInfo& init_)
  170. {
  171. TextureInitInfo init = init_;
  172. Bool useDedicatedMemory = !!(init.m_usage & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE)
  173. && !!(getGrManagerImpl().getExtensions() & VulkanExtensions::KHR_DEDICATED_ALLOCATION);
  174. // Check if format is supported
  175. Bool supported;
  176. while(!(supported = imageSupported(init)))
  177. {
  178. // Try to find a fallback
  179. if(init.m_format >= Format::R8G8B8_UNORM && init.m_format <= Format::R8G8B8_SRGB)
  180. {
  181. ANKI_ASSERT(!(init.m_usage & TextureUsageBit::IMAGE_ALL) && "Can't do that ATM");
  182. const U idx = U(init.m_format) - U(Format::R8G8B8_UNORM);
  183. init.m_format = Format(U(Format::R8G8B8A8_UNORM) + idx);
  184. ANKI_ASSERT(init.m_format >= Format::R8G8B8A8_UNORM && init.m_format <= Format::R8G8B8A8_SRGB);
  185. m_format = init.m_format;
  186. m_vkFormat = convertFormat(m_format);
  187. m_workarounds = TextureImplWorkaround::R8G8B8_TO_R8G8B8A8;
  188. }
  189. else if(init.m_format == Format::S8_UINT)
  190. {
  191. ANKI_ASSERT(
  192. !(init.m_usage & (TextureUsageBit::IMAGE_ALL | TextureUsageBit::TRANSFER_ALL)) && "Can't do that ATM");
  193. init.m_format = Format::D24_UNORM_S8_UINT;
  194. m_format = init.m_format;
  195. m_vkFormat = convertFormat(m_format);
  196. m_workarounds = TextureImplWorkaround::S8_TO_D24S8;
  197. }
  198. else if(init.m_format == Format::D24_UNORM_S8_UINT)
  199. {
  200. ANKI_ASSERT(
  201. !(init.m_usage & (TextureUsageBit::IMAGE_ALL | TextureUsageBit::TRANSFER_ALL)) && "Can't do that ATM");
  202. init.m_format = Format::D32_SFLOAT_S8_UINT;
  203. m_format = init.m_format;
  204. m_vkFormat = convertFormat(m_format);
  205. m_workarounds = TextureImplWorkaround::D24S8_TO_D32S8;
  206. }
  207. else
  208. {
  209. break;
  210. }
  211. }
  212. if(!supported)
  213. {
  214. ANKI_VK_LOGE("Unsupported texture format: %u", U(init.m_format));
  215. return Error::FUNCTION_FAILED;
  216. }
  217. // Contunue with the creation
  218. VkImageCreateInfo ci = {};
  219. ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
  220. ci.flags = calcCreateFlags(init);
  221. ci.imageType = convertTextureType(m_texType);
  222. ci.format = m_vkFormat;
  223. ci.extent.width = init.m_width;
  224. ci.extent.height = init.m_height;
  225. switch(m_texType)
  226. {
  227. case TextureType::_1D:
  228. case TextureType::_2D:
  229. ci.extent.depth = 1;
  230. ci.arrayLayers = 1;
  231. break;
  232. case TextureType::_2D_ARRAY:
  233. ci.extent.depth = 1;
  234. ci.arrayLayers = init.m_layerCount;
  235. break;
  236. case TextureType::CUBE:
  237. ci.extent.depth = 1;
  238. ci.arrayLayers = 6;
  239. break;
  240. case TextureType::CUBE_ARRAY:
  241. ci.extent.depth = 1;
  242. ci.arrayLayers = 6 * init.m_layerCount;
  243. break;
  244. case TextureType::_3D:
  245. ci.extent.depth = init.m_depth;
  246. ci.arrayLayers = 1;
  247. break;
  248. default:
  249. ANKI_ASSERT(0);
  250. }
  251. ci.mipLevels = m_mipCount;
  252. ci.samples = VK_SAMPLE_COUNT_1_BIT;
  253. ci.tiling = VK_IMAGE_TILING_OPTIMAL;
  254. ci.usage = convertTextureUsage(init.m_usage, init.m_format);
  255. ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
  256. ci.queueFamilyIndexCount = 1;
  257. U32 queueIdx = getGrManagerImpl().getGraphicsQueueFamily();
  258. ci.pQueueFamilyIndices = &queueIdx;
  259. ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  260. VkDedicatedAllocationImageCreateInfoNV dedicatedMemCi = {};
  261. if(useDedicatedMemory)
  262. {
  263. dedicatedMemCi.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV;
  264. dedicatedMemCi.dedicatedAllocation = true;
  265. ci.pNext = &dedicatedMemCi;
  266. }
  267. ANKI_VK_CHECK(vkCreateImage(getDevice(), &ci, nullptr, &m_imageHandle));
  268. getGrManagerImpl().trySetVulkanHandleName(init.getName(), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, m_imageHandle);
  269. #if 0
  270. printf("Creating texture %p %s\n",
  271. static_cast<void*>(m_imageHandle),
  272. init.getName() ? init.getName().cstr() : "Unnamed");
  273. #endif
  274. // Allocate memory
  275. //
  276. VkMemoryRequirements req = {};
  277. vkGetImageMemoryRequirements(getDevice(), m_imageHandle, &req);
  278. U memIdx = getGrManagerImpl().getGpuMemoryManager().findMemoryType(
  279. req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
  280. // Fallback
  281. if(memIdx == MAX_U32)
  282. {
  283. memIdx = getGrManagerImpl().getGpuMemoryManager().findMemoryType(
  284. req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0);
  285. }
  286. ANKI_ASSERT(memIdx != MAX_U32);
  287. if(!useDedicatedMemory)
  288. {
  289. // Allocate
  290. getGrManagerImpl().getGpuMemoryManager().allocateMemory(memIdx, req.size, req.alignment, false, m_memHandle);
  291. // Bind mem to image
  292. ANKI_TRACE_SCOPED_EVENT(VK_BIND_OBJECT);
  293. ANKI_VK_CHECK(vkBindImageMemory(getDevice(), m_imageHandle, m_memHandle.m_memory, m_memHandle.m_offset));
  294. }
  295. else
  296. {
  297. VkDedicatedAllocationMemoryAllocateInfoNV dedicatedInfo = {};
  298. dedicatedInfo.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
  299. dedicatedInfo.image = m_imageHandle;
  300. VkMemoryAllocateInfo memAllocCi = {};
  301. memAllocCi.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
  302. memAllocCi.pNext = &dedicatedInfo;
  303. memAllocCi.allocationSize = req.size;
  304. memAllocCi.memoryTypeIndex = memIdx;
  305. ANKI_VK_CHECK(vkAllocateMemory(getDevice(), &memAllocCi, nullptr, &m_dedicatedMem));
  306. getGrManagerImpl().trySetVulkanHandleName(
  307. init.getName(), VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, ptrToNumber(m_dedicatedMem));
  308. ANKI_TRACE_SCOPED_EVENT(VK_BIND_OBJECT);
  309. ANKI_VK_CHECK(vkBindImageMemory(getDevice(), m_imageHandle, m_dedicatedMem, 0));
  310. }
  311. return Error::NONE;
  312. }
  313. void TextureImpl::computeBarrierInfo(TextureUsageBit before,
  314. TextureUsageBit after,
  315. U level,
  316. VkPipelineStageFlags& srcStages,
  317. VkAccessFlags& srcAccesses,
  318. VkPipelineStageFlags& dstStages,
  319. VkAccessFlags& dstAccesses) const
  320. {
  321. ANKI_ASSERT(level < m_mipCount);
  322. ANKI_ASSERT(usageValid(before) && usageValid(after));
  323. srcStages = 0;
  324. srcAccesses = 0;
  325. dstStages = 0;
  326. dstAccesses = 0;
  327. const Bool lastLevel = level == m_mipCount - 1u;
  328. const Bool depthStencil = !!m_aspect;
  329. //
  330. // Before
  331. //
  332. if(!!(before & TextureUsageBit::SAMPLED_VERTEX))
  333. {
  334. srcStages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
  335. srcAccesses |= VK_ACCESS_SHADER_READ_BIT;
  336. }
  337. if(!!(before & TextureUsageBit::SAMPLED_TESSELLATION_CONTROL))
  338. {
  339. srcStages |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
  340. srcAccesses |= VK_ACCESS_SHADER_READ_BIT;
  341. }
  342. if(!!(before & TextureUsageBit::SAMPLED_TESSELLATION_EVALUATION))
  343. {
  344. srcStages |= VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
  345. srcAccesses |= VK_ACCESS_SHADER_READ_BIT;
  346. }
  347. if(!!(before & TextureUsageBit::SAMPLED_GEOMETRY))
  348. {
  349. srcStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
  350. srcAccesses |= VK_ACCESS_SHADER_READ_BIT;
  351. }
  352. if(!!(before & TextureUsageBit::SAMPLED_FRAGMENT))
  353. {
  354. srcStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  355. srcAccesses |= VK_ACCESS_SHADER_READ_BIT;
  356. }
  357. if(!!(before & TextureUsageBit::SAMPLED_COMPUTE) || !!(before & TextureUsageBit::IMAGE_COMPUTE_READ))
  358. {
  359. srcStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  360. srcAccesses |= VK_ACCESS_SHADER_READ_BIT;
  361. }
  362. if(!!(before & TextureUsageBit::IMAGE_COMPUTE_WRITE))
  363. {
  364. srcStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  365. srcAccesses |= VK_ACCESS_SHADER_WRITE_BIT;
  366. }
  367. if(!!(before & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ))
  368. {
  369. if(depthStencil)
  370. {
  371. srcStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  372. srcAccesses |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
  373. }
  374. else
  375. {
  376. srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // See Table 4 in the spec
  377. srcAccesses |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
  378. }
  379. }
  380. if(!!(before & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE))
  381. {
  382. if(depthStencil)
  383. {
  384. srcStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  385. srcAccesses |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  386. }
  387. else
  388. {
  389. srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  390. srcAccesses |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  391. }
  392. }
  393. if(!!(before & TextureUsageBit::GENERATE_MIPMAPS))
  394. {
  395. srcStages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
  396. if(!lastLevel)
  397. {
  398. srcAccesses |= VK_ACCESS_TRANSFER_READ_BIT;
  399. }
  400. else
  401. {
  402. srcAccesses |= VK_ACCESS_TRANSFER_WRITE_BIT;
  403. }
  404. }
  405. if(!!(before & TextureUsageBit::TRANSFER_DESTINATION))
  406. {
  407. srcStages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
  408. srcAccesses |= VK_ACCESS_TRANSFER_WRITE_BIT;
  409. }
  410. if(!!(before & TextureUsageBit::CLEAR))
  411. {
  412. srcStages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
  413. srcAccesses |= VK_ACCESS_TRANSFER_WRITE_BIT;
  414. }
  415. if(srcStages == 0)
  416. {
  417. srcStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
  418. }
  419. //
  420. // After
  421. //
  422. if(!!(after & TextureUsageBit::SAMPLED_VERTEX))
  423. {
  424. dstStages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
  425. dstAccesses |= VK_ACCESS_SHADER_READ_BIT;
  426. }
  427. if(!!(after & TextureUsageBit::SAMPLED_TESSELLATION_CONTROL))
  428. {
  429. dstStages |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
  430. dstAccesses |= VK_ACCESS_SHADER_READ_BIT;
  431. }
  432. if(!!(after & TextureUsageBit::SAMPLED_TESSELLATION_EVALUATION))
  433. {
  434. dstStages |= VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
  435. dstAccesses |= VK_ACCESS_SHADER_READ_BIT;
  436. }
  437. if(!!(after & TextureUsageBit::SAMPLED_GEOMETRY))
  438. {
  439. dstStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
  440. dstAccesses |= VK_ACCESS_SHADER_READ_BIT;
  441. }
  442. if(!!(after & TextureUsageBit::SAMPLED_FRAGMENT))
  443. {
  444. dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  445. dstAccesses |= VK_ACCESS_SHADER_READ_BIT;
  446. }
  447. if(!!(after & TextureUsageBit::SAMPLED_COMPUTE) || !!(after & TextureUsageBit::IMAGE_COMPUTE_READ))
  448. {
  449. dstStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  450. dstAccesses |= VK_ACCESS_SHADER_READ_BIT;
  451. }
  452. if(!!(after & TextureUsageBit::IMAGE_COMPUTE_WRITE))
  453. {
  454. dstStages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  455. dstAccesses |= VK_ACCESS_SHADER_WRITE_BIT;
  456. }
  457. if(!!(after & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ))
  458. {
  459. if(depthStencil)
  460. {
  461. dstStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  462. dstAccesses |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
  463. }
  464. else
  465. {
  466. dstStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  467. dstAccesses |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
  468. }
  469. }
  470. if(!!(after & TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE))
  471. {
  472. if(depthStencil)
  473. {
  474. dstStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  475. dstAccesses |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  476. }
  477. else
  478. {
  479. dstStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  480. dstAccesses |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  481. }
  482. }
  483. if(!!(after & TextureUsageBit::GENERATE_MIPMAPS))
  484. {
  485. dstStages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
  486. if(level == 0)
  487. {
  488. dstAccesses |= VK_ACCESS_TRANSFER_READ_BIT;
  489. }
  490. else
  491. {
  492. ANKI_ASSERT(0 && "This will happen in generateMipmaps");
  493. }
  494. }
  495. if(!!(after & TextureUsageBit::TRANSFER_DESTINATION))
  496. {
  497. dstStages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
  498. dstAccesses |= VK_ACCESS_TRANSFER_WRITE_BIT;
  499. }
  500. if(!!(after & TextureUsageBit::CLEAR))
  501. {
  502. dstStages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
  503. dstAccesses |= VK_ACCESS_TRANSFER_WRITE_BIT;
  504. }
  505. if(!!(after & TextureUsageBit::PRESENT))
  506. {
  507. dstStages |= VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  508. dstAccesses |= VK_ACCESS_MEMORY_READ_BIT;
  509. }
  510. ANKI_ASSERT(dstStages);
  511. }
  512. VkImageLayout TextureImpl::computeLayout(TextureUsageBit usage, U level) const
  513. {
  514. ANKI_ASSERT(level < m_mipCount);
  515. ANKI_ASSERT(usageValid(usage));
  516. VkImageLayout out = VK_IMAGE_LAYOUT_MAX_ENUM;
  517. const Bool lastLevel = level == m_mipCount - 1u;
  518. const Bool depthStencil = !!m_aspect;
  519. if(usage == TextureUsageBit::NONE)
  520. {
  521. out = VK_IMAGE_LAYOUT_UNDEFINED;
  522. }
  523. else if(!(usage & ~TextureUsageBit::SAMPLED_ALL))
  524. {
  525. // Only sampling
  526. out = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  527. }
  528. else if(!(usage & ~TextureUsageBit::IMAGE_COMPUTE_READ_WRITE))
  529. {
  530. // Only image load/store
  531. out = VK_IMAGE_LAYOUT_GENERAL;
  532. }
  533. else if(!(usage & ~TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE))
  534. {
  535. // Only FB access
  536. if(depthStencil)
  537. {
  538. out = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  539. }
  540. else
  541. {
  542. out = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  543. }
  544. }
  545. else if(depthStencil && !(usage & ~(TextureUsageBit::SAMPLED_ALL | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ)))
  546. {
  547. // FB read & shader read
  548. out = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
  549. }
  550. else if(depthStencil
  551. && !(usage & ~(TextureUsageBit::SAMPLED_ALL_GRAPHICS | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE)))
  552. {
  553. // Wild guess: One aspect is shader read and the other is read write
  554. out = VK_IMAGE_LAYOUT_GENERAL;
  555. }
  556. else if(usage == TextureUsageBit::GENERATE_MIPMAPS)
  557. {
  558. if(!lastLevel)
  559. {
  560. out = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
  561. }
  562. else
  563. {
  564. out = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
  565. }
  566. }
  567. else if(usage == TextureUsageBit::CLEAR)
  568. {
  569. out = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
  570. }
  571. else if(!depthStencil && usage == TextureUsageBit::TRANSFER_DESTINATION)
  572. {
  573. out = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
  574. }
  575. else if(usage == TextureUsageBit::PRESENT)
  576. {
  577. out = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
  578. }
  579. else
  580. {
  581. // Can't set it to something, chose general
  582. out = VK_IMAGE_LAYOUT_GENERAL;
  583. }
  584. ANKI_ASSERT(out != VK_IMAGE_LAYOUT_MAX_ENUM);
  585. return out;
  586. }
  587. VkImageView TextureImpl::getOrCreateView(const TextureSubresourceInfo& subresource, TextureType& newTexType) const
  588. {
  589. LockGuard<Mutex> lock(m_viewsMapMtx);
  590. auto it = m_viewsMap.find(subresource);
  591. if(it != m_viewsMap.getEnd())
  592. {
  593. // Fixup the image view type
  594. newTexType = computeNewTexTypeOfSubresource(subresource);
  595. return *it;
  596. }
  597. else
  598. {
  599. // Compute the VkImageViewCreateInfo
  600. VkImageViewCreateInfo viewCi;
  601. computeVkImageViewCreateInfo(subresource, viewCi, newTexType);
  602. VkImageView view = VK_NULL_HANDLE;
  603. ANKI_VK_CHECKF(vkCreateImageView(getDevice(), &viewCi, nullptr, &view));
  604. getGrManagerImpl().trySetVulkanHandleName(
  605. getName(), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, ptrToNumber(view));
  606. m_viewsMap.emplace(getAllocator(), subresource, view);
  607. #if 0
  608. printf("Creating image view %p. Texture %p %s\n",
  609. static_cast<void*>(view),
  610. static_cast<void*>(m_imageHandle),
  611. getName() ? getName().cstr() : "Unnamed");
  612. #endif
  613. return view;
  614. }
  615. }
  616. } // end namespace anki