VkTexture.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. // Copyright (C) 2009-present, 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/VkTexture.h>
  6. #include <AnKi/Gr/Vulkan/VkGrManager.h>
  7. #include <AnKi/Gr/Vulkan/VkDescriptor.h>
  8. namespace anki {
  9. Texture* Texture::newInstance(const TextureInitInfo& init)
  10. {
  11. TextureImpl* impl = anki::newInstance<TextureImpl>(GrMemoryPool::getSingleton(), init.getName());
  12. const Error err = impl->init(init);
  13. if(err)
  14. {
  15. deleteInstance(GrMemoryPool::getSingleton(), impl);
  16. impl = nullptr;
  17. }
  18. return impl;
  19. }
  20. U32 Texture::getOrCreateBindlessTextureIndex(const TextureSubresourceDesc& subresource)
  21. {
  22. ANKI_VK_SELF(TextureImpl);
  23. ANKI_ASSERT(TextureView(this, subresource).isGoodForSampling());
  24. const TextureImpl::TextureViewEntry& entry = self.getTextureViewEntry(subresource);
  25. LockGuard lock(entry.m_bindlessIndexLock);
  26. if(entry.m_bindlessIndex == kMaxU32) [[unlikely]]
  27. {
  28. entry.m_bindlessIndex = BindlessDescriptorSet::getSingleton().bindTexture(entry.m_handle, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
  29. }
  30. return entry.m_bindlessIndex;
  31. }
  32. static Bool isAstcLdrFormat(const VkFormat format)
  33. {
  34. return format >= VK_FORMAT_ASTC_4x4_UNORM_BLOCK && format <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
  35. }
  36. static Bool isAstcSrgbFormat(const VkFormat format)
  37. {
  38. switch(format)
  39. {
  40. case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
  41. case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
  42. case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
  43. case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
  44. case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
  45. case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
  46. case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
  47. case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
  48. case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
  49. case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
  50. case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
  51. case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
  52. case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
  53. case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
  54. return true;
  55. default:
  56. return false;
  57. }
  58. }
  59. TextureImpl::~TextureImpl()
  60. {
  61. #if ANKI_ASSERTIONS_ENABLED
  62. if(m_usage != m_usedFor)
  63. {
  64. ANKI_VK_LOGW("Texture %s hasn't been used in all types of usages", getName().cstr());
  65. }
  66. #endif
  67. auto destroyTextureView = [&](TextureViewEntry& entry) {
  68. if(entry.m_bindlessIndex != kMaxU32)
  69. {
  70. BindlessDescriptorSet::getSingleton().unbindTexture(entry.m_bindlessIndex);
  71. }
  72. if(entry.m_handle)
  73. {
  74. vkDestroyImageView(getVkDevice(), entry.m_handle, nullptr);
  75. }
  76. };
  77. for(ViewClass c : EnumIterable<ViewClass>())
  78. {
  79. for(TextureViewEntry& entry : m_textureViews[c])
  80. {
  81. destroyTextureView(entry);
  82. }
  83. destroyTextureView(m_wholeTextureViews[c]);
  84. }
  85. if(m_imageHandle && !(m_usage & TextureUsageBit::kPresent))
  86. {
  87. vkDestroyImage(getVkDevice(), m_imageHandle, nullptr);
  88. }
  89. if(m_memHandle)
  90. {
  91. GpuMemoryManager::getSingleton().freeMemory(m_memHandle);
  92. }
  93. }
  94. Error TextureImpl::initInternal(VkImage externalImage, const TextureInitInfo& init_)
  95. {
  96. TextureInitInfo init = init_;
  97. ANKI_ASSERT(init.isValid());
  98. if(externalImage)
  99. {
  100. ANKI_ASSERT(!!(init.m_usage & TextureUsageBit::kPresent));
  101. }
  102. ANKI_ASSERT(getGrManagerImpl().getDeviceCapabilities().m_vrs || !(init.m_usage & TextureUsageBit::kShadingRate));
  103. // Set some stuff
  104. m_width = init.m_width;
  105. m_height = init.m_height;
  106. m_depth = init.m_depth;
  107. m_texType = init.m_type;
  108. if(m_texType == TextureType::k3D)
  109. {
  110. m_mipCount = min(init.m_mipmapCount, computeMaxMipmapCount3d(m_width, m_height, m_depth));
  111. }
  112. else
  113. {
  114. m_mipCount = min(init.m_mipmapCount, computeMaxMipmapCount2d(m_width, m_height));
  115. }
  116. init.m_mipmapCount = m_mipCount;
  117. m_layerCount = init.m_layerCount;
  118. m_format = init.m_format;
  119. m_vkFormat = convertFormat(m_format);
  120. m_aspect = getImageAspectFromFormat(m_format);
  121. m_usage = init.m_usage;
  122. if(externalImage)
  123. {
  124. m_imageHandle = externalImage;
  125. }
  126. else
  127. {
  128. ANKI_CHECK(initImage(init));
  129. }
  130. ANKI_CHECK(initViews());
  131. return Error::kNone;
  132. }
  133. VkImageCreateFlags TextureImpl::calcCreateFlags(const TextureInitInfo& init)
  134. {
  135. VkImageCreateFlags flags = 0;
  136. if(init.m_type == TextureType::kCube || init.m_type == TextureType::kCubeArray)
  137. {
  138. flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
  139. }
  140. return flags;
  141. }
  142. Bool TextureImpl::imageSupported(const TextureInitInfo& init)
  143. {
  144. VkImageFormatProperties props = {};
  145. const VkResult res = vkGetPhysicalDeviceImageFormatProperties(getGrManagerImpl().getPhysicalDevice(), m_vkFormat, convertTextureType(init.m_type),
  146. VK_IMAGE_TILING_OPTIMAL, convertTextureUsage(init.m_usage, init.m_format),
  147. calcCreateFlags(init), &props);
  148. if(res == VK_ERROR_FORMAT_NOT_SUPPORTED)
  149. {
  150. return false;
  151. }
  152. else
  153. {
  154. ANKI_ASSERT(res == VK_SUCCESS);
  155. return true;
  156. }
  157. }
  158. Error TextureImpl::initImage(const TextureInitInfo& init)
  159. {
  160. // Check if format is supported
  161. if(!imageSupported(init))
  162. {
  163. ANKI_VK_LOGE("TextureInitInfo contains a combination of parameters that it's not supported by the device. "
  164. "Texture format is %s",
  165. getFormatInfo(init.m_format).m_name);
  166. return Error::kFunctionFailed;
  167. }
  168. // Contunue with the creation
  169. VkImageCreateInfo ci = {};
  170. ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
  171. ci.flags = calcCreateFlags(init);
  172. ci.imageType = convertTextureType(m_texType);
  173. ci.format = m_vkFormat;
  174. ci.extent.width = init.m_width;
  175. ci.extent.height = init.m_height;
  176. switch(m_texType)
  177. {
  178. case TextureType::k1D:
  179. case TextureType::k2D:
  180. ci.extent.depth = 1;
  181. ci.arrayLayers = 1;
  182. break;
  183. case TextureType::k2DArray:
  184. ci.extent.depth = 1;
  185. ci.arrayLayers = init.m_layerCount;
  186. break;
  187. case TextureType::kCube:
  188. ci.extent.depth = 1;
  189. ci.arrayLayers = 6;
  190. break;
  191. case TextureType::kCubeArray:
  192. ci.extent.depth = 1;
  193. ci.arrayLayers = 6 * init.m_layerCount;
  194. break;
  195. case TextureType::k3D:
  196. ci.extent.depth = init.m_depth;
  197. ci.arrayLayers = 1;
  198. break;
  199. default:
  200. ANKI_ASSERT(0);
  201. }
  202. ci.mipLevels = m_mipCount;
  203. ci.samples = VK_SAMPLE_COUNT_1_BIT;
  204. ci.tiling = VK_IMAGE_TILING_OPTIMAL;
  205. ci.usage = convertTextureUsage(init.m_usage, init.m_format);
  206. m_vkUsageFlags = ci.usage;
  207. ci.queueFamilyIndexCount = getGrManagerImpl().getQueueFamilies().getSize();
  208. ci.pQueueFamilyIndices = &getGrManagerImpl().getQueueFamilies()[0];
  209. ci.sharingMode = (ci.queueFamilyIndexCount > 1) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
  210. ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  211. ANKI_VK_CHECK(vkCreateImage(getVkDevice(), &ci, nullptr, &m_imageHandle));
  212. getGrManagerImpl().trySetVulkanHandleName(init.getName(), VK_OBJECT_TYPE_IMAGE, m_imageHandle);
  213. #if 0
  214. printf("Creating texture %p %s\n", static_cast<void*>(m_imageHandle),
  215. init.getName() ? init.getName().cstr() : "Unnamed");
  216. #endif
  217. // Allocate memory
  218. //
  219. VkMemoryDedicatedRequirementsKHR dedicatedRequirements;
  220. VkMemoryRequirements2 requirements;
  221. GpuMemoryManager::getSingleton().getImageMemoryRequirements(m_imageHandle, dedicatedRequirements, requirements);
  222. U32 memIdx = GpuMemoryManager::getSingleton().findMemoryType(requirements.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
  223. VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
  224. // Fallback
  225. if(memIdx == kMaxU32)
  226. {
  227. memIdx =
  228. GpuMemoryManager::getSingleton().findMemoryType(requirements.memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0);
  229. }
  230. ANKI_ASSERT(memIdx != kMaxU32);
  231. // Allocate
  232. if(!dedicatedRequirements.prefersDedicatedAllocation)
  233. {
  234. GpuMemoryManager::getSingleton().allocateMemory(memIdx, requirements.memoryRequirements.size, U32(requirements.memoryRequirements.alignment),
  235. m_memHandle);
  236. }
  237. else
  238. {
  239. GpuMemoryManager::getSingleton().allocateMemoryDedicated(memIdx, requirements.memoryRequirements.size, m_imageHandle, m_memHandle);
  240. }
  241. // Bind
  242. ANKI_VK_CHECK(vkBindImageMemory(getVkDevice(), m_imageHandle, m_memHandle.m_memory, m_memHandle.m_offset));
  243. return Error::kNone;
  244. }
  245. void TextureImpl::computeBarrierInfo(TextureUsageBit usage, VkPipelineStageFlags& stages, VkAccessFlags& accesses) const
  246. {
  247. ANKI_ASSERT(usageValid(usage));
  248. stages = 0;
  249. accesses = 0;
  250. const Bool depthStencil = !!m_aspect;
  251. const Bool rt = getGrManagerImpl().getDeviceCapabilities().m_rayTracingEnabled;
  252. if(!!(usage & TextureUsageBit::kSrvGeometry))
  253. {
  254. stages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
  255. | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
  256. accesses |= VK_ACCESS_SHADER_READ_BIT;
  257. }
  258. if(!!(usage & TextureUsageBit::kUavGeometry))
  259. {
  260. stages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
  261. | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
  262. accesses |= VK_ACCESS_SHADER_WRITE_BIT;
  263. }
  264. if(!!(usage & TextureUsageBit::kSrvPixel))
  265. {
  266. stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  267. accesses |= VK_ACCESS_SHADER_READ_BIT;
  268. }
  269. if(!!(usage & TextureUsageBit::kUavPixel))
  270. {
  271. stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
  272. accesses |= VK_ACCESS_SHADER_WRITE_BIT;
  273. }
  274. if(!!(usage & TextureUsageBit::kSrvCompute))
  275. {
  276. stages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  277. accesses |= VK_ACCESS_SHADER_READ_BIT;
  278. }
  279. if(!!(usage & TextureUsageBit::kUavCompute))
  280. {
  281. stages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
  282. accesses |= VK_ACCESS_SHADER_WRITE_BIT;
  283. }
  284. if(!!(usage & TextureUsageBit::kSrvDispatchRays) && rt)
  285. {
  286. stages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
  287. accesses |= VK_ACCESS_SHADER_READ_BIT;
  288. }
  289. if(!!(usage & TextureUsageBit::kUavDispatchRays) && rt)
  290. {
  291. stages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
  292. accesses |= VK_ACCESS_SHADER_WRITE_BIT;
  293. }
  294. if(!!(usage & TextureUsageBit::kRtvDsvRead))
  295. {
  296. if(depthStencil)
  297. {
  298. stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  299. accesses |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
  300. }
  301. else
  302. {
  303. stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  304. accesses |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
  305. }
  306. }
  307. if(!!(usage & TextureUsageBit::kRtvDsvWrite))
  308. {
  309. if(depthStencil)
  310. {
  311. stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
  312. accesses |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  313. }
  314. else
  315. {
  316. stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  317. accesses |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
  318. }
  319. }
  320. if(!!(usage & TextureUsageBit::kShadingRate))
  321. {
  322. stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
  323. accesses |= VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
  324. }
  325. if(!!(usage & TextureUsageBit::kCopyDestination))
  326. {
  327. stages |= VK_PIPELINE_STAGE_TRANSFER_BIT;
  328. accesses |= VK_ACCESS_TRANSFER_WRITE_BIT;
  329. }
  330. if(!!(usage & TextureUsageBit::kPresent))
  331. {
  332. stages |= VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  333. accesses |= VK_ACCESS_MEMORY_READ_BIT;
  334. }
  335. }
  336. VkImageMemoryBarrier TextureImpl::computeBarrierInfo(TextureUsageBit before, TextureUsageBit after, const TextureSubresourceDesc& subresource,
  337. VkPipelineStageFlags& srcStages, VkPipelineStageFlags& dstStages) const
  338. {
  339. ANKI_ASSERT(usageValid(before));
  340. ANKI_ASSERT(usageValid(after));
  341. VkImageMemoryBarrier barrier = {};
  342. barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
  343. barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  344. barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
  345. barrier.image = m_imageHandle;
  346. barrier.subresourceRange = computeVkImageSubresourceRange(subresource);
  347. barrier.oldLayout = computeLayout(before);
  348. barrier.newLayout = computeLayout(after);
  349. VkPipelineStageFlags srcStages2, dstStages2;
  350. computeBarrierInfo(before, srcStages2, barrier.srcAccessMask);
  351. computeBarrierInfo(after, dstStages2, barrier.dstAccessMask);
  352. if(srcStages2 == 0)
  353. {
  354. srcStages2 = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
  355. }
  356. ANKI_ASSERT(dstStages2);
  357. srcStages |= srcStages2;
  358. dstStages |= dstStages2;
  359. return barrier;
  360. }
  361. VkImageLayout TextureImpl::computeLayout(TextureUsageBit usage) const
  362. {
  363. ANKI_ASSERT(usageValid(usage));
  364. VkImageLayout out = VK_IMAGE_LAYOUT_MAX_ENUM;
  365. const Bool depthStencil = !!m_aspect;
  366. if(usage == TextureUsageBit::kNone)
  367. {
  368. out = VK_IMAGE_LAYOUT_UNDEFINED;
  369. }
  370. else if(depthStencil)
  371. {
  372. if(!(usage & ~(TextureUsageBit::kAllSrv | TextureUsageBit::kRtvDsvRead)))
  373. {
  374. // Only depth tests and sampled
  375. out = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
  376. }
  377. else
  378. {
  379. // Only attachment write, the rest (eg transfer) are not supported for now
  380. ANKI_ASSERT(usage == TextureUsageBit::kRtvDsvWrite || usage == TextureUsageBit::kAllRtvDsv);
  381. out = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  382. }
  383. }
  384. else if(!(usage & ~TextureUsageBit::kAllRtvDsv))
  385. {
  386. // Color attachment
  387. out = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  388. }
  389. else if(!(usage & ~TextureUsageBit::kShadingRate))
  390. {
  391. // SRI
  392. out = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
  393. }
  394. else if(!(usage & ~TextureUsageBit::kAllUav))
  395. {
  396. // Only image load/store
  397. out = VK_IMAGE_LAYOUT_GENERAL;
  398. }
  399. else if(!(usage & ~TextureUsageBit::kAllSrv))
  400. {
  401. // Only sampled
  402. out = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  403. }
  404. else if(usage == TextureUsageBit::kCopyDestination)
  405. {
  406. out = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
  407. }
  408. else if(usage == TextureUsageBit::kPresent)
  409. {
  410. out = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
  411. }
  412. else
  413. {
  414. // No idea so play it safe
  415. out = VK_IMAGE_LAYOUT_GENERAL;
  416. }
  417. return out;
  418. }
  419. Error TextureImpl::initViews()
  420. {
  421. const VkImageAspectFlags vkaspect = convertImageAspect(m_aspect);
  422. VkImageViewCreateInfo ci = {};
  423. ci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
  424. ci.image = m_imageHandle;
  425. ci.viewType = convertTextureViewType(m_texType);
  426. ci.format = m_vkFormat;
  427. ci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
  428. ci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
  429. ci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
  430. ci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
  431. ci.subresourceRange.aspectMask = vkaspect;
  432. ci.subresourceRange.baseArrayLayer = 0;
  433. ci.subresourceRange.baseMipLevel = 0;
  434. ci.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
  435. ci.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
  436. VkImageViewASTCDecodeModeEXT astcDecodeMode;
  437. if(!!(getGrManagerImpl().getExtensions() & VulkanExtensions::kEXT_astc_decode_mode) && isAstcLdrFormat(m_vkFormat)
  438. && !isAstcSrgbFormat(m_vkFormat))
  439. {
  440. astcDecodeMode = {};
  441. astcDecodeMode.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT;
  442. astcDecodeMode.decodeMode = VK_FORMAT_R8G8B8A8_UNORM;
  443. appendPNextList(ci, &astcDecodeMode);
  444. }
  445. auto createImageView = [&](VkImageView& view) -> Error {
  446. ANKI_VK_CHECK(vkCreateImageView(getVkDevice(), &ci, nullptr, &view));
  447. getGrManagerImpl().trySetVulkanHandleName(getName(), VK_OBJECT_TYPE_IMAGE_VIEW, view);
  448. return Error::kNone;
  449. };
  450. ANKI_CHECK(createImageView(m_wholeTextureViews[ViewClass::kDefault].m_handle));
  451. if(m_aspect == DepthStencilAspectBit::kDepthStencil)
  452. {
  453. ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
  454. ANKI_CHECK(createImageView(m_wholeTextureViews[ViewClass::kDepth].m_handle));
  455. ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
  456. ANKI_CHECK(createImageView(m_wholeTextureViews[ViewClass::kStencil].m_handle));
  457. }
  458. // Create the rest of the views
  459. const U32 faceCount = textureTypeIsCube(m_texType) ? 6 : 1;
  460. const Bool needsMoreViews = m_layerCount > 1 || m_mipCount > 1 || faceCount > 1;
  461. if(needsMoreViews)
  462. {
  463. m_textureViews[ViewClass::kDefault].resize(m_layerCount * faceCount * m_mipCount);
  464. if(m_aspect == DepthStencilAspectBit::kDepthStencil)
  465. {
  466. m_textureViews[ViewClass::kDefault].resize(m_layerCount * faceCount * m_mipCount);
  467. m_textureViews[ViewClass::kStencil].resize(m_layerCount * faceCount * m_mipCount);
  468. }
  469. const TextureType surfaceOrVolumeTexType = (m_texType == TextureType::k3D) ? TextureType::k3D : TextureType::k2D;
  470. ci.viewType = convertTextureViewType(surfaceOrVolumeTexType);
  471. ci.subresourceRange.layerCount = 1;
  472. ci.subresourceRange.levelCount = 1;
  473. for(U32 layer = 0; layer < m_layerCount; ++layer)
  474. {
  475. for(U32 face = 0; face < faceCount; ++face)
  476. {
  477. for(U32 mip = 0; mip < m_mipCount; ++mip)
  478. {
  479. const U32 idx = translateSurfaceOrVolume(layer, face, mip);
  480. TextureViewEntry& entry = m_textureViews[ViewClass::kDefault][idx];
  481. ci.subresourceRange.baseArrayLayer = layer * faceCount + face;
  482. ci.subresourceRange.baseMipLevel = mip;
  483. ci.subresourceRange.aspectMask = vkaspect;
  484. ANKI_CHECK(createImageView(entry.m_handle));
  485. if(m_textureViews[ViewClass::kDepth].getSize())
  486. {
  487. ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
  488. ANKI_CHECK(createImageView(m_textureViews[ViewClass::kDepth][idx].m_handle));
  489. }
  490. if(m_textureViews[ViewClass::kStencil].getSize())
  491. {
  492. ci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
  493. ANKI_CHECK(createImageView(m_textureViews[ViewClass::kStencil][idx].m_handle));
  494. }
  495. }
  496. }
  497. }
  498. }
  499. return Error::kNone;
  500. }
  501. const TextureImpl::TextureViewEntry& TextureImpl::getTextureViewEntry(const TextureSubresourceDesc& subresource) const
  502. {
  503. const TextureView view(this, subresource);
  504. // Find class
  505. ViewClass c;
  506. if(view.getDepthStencilAspect() == m_aspect)
  507. {
  508. c = ViewClass::kDefault;
  509. }
  510. else if(view.getDepthStencilAspect() == DepthStencilAspectBit::kDepth)
  511. {
  512. c = ViewClass::kDepth;
  513. }
  514. else
  515. {
  516. ANKI_ASSERT(view.getDepthStencilAspect() == DepthStencilAspectBit::kStencil);
  517. c = ViewClass::kStencil;
  518. }
  519. // Get
  520. if(view.isAllSurfacesOrVolumes())
  521. {
  522. return m_wholeTextureViews[c];
  523. }
  524. else
  525. {
  526. const U32 idx = translateSurfaceOrVolume(view.getFirstLayer(), view.getFirstFace(), view.getFirstMipmap());
  527. return m_textureViews[c][idx];
  528. }
  529. }
  530. } // end namespace anki