|
1 | 1 | /* |
2 | | - * Copyright (c) 2022-2025, NVIDIA CORPORATION. All rights reserved. |
| 2 | + * Copyright (c) 2022-2026, NVIDIA CORPORATION. All rights reserved. |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
13 | 13 | * See the License for the specific language governing permissions and |
14 | 14 | * limitations under the License. |
15 | 15 | * |
16 | | - * SPDX-FileCopyrightText: Copyright (c) 2022-2025, NVIDIA CORPORATION. |
| 16 | + * SPDX-FileCopyrightText: Copyright (c) 2022-2026, NVIDIA CORPORATION. |
17 | 17 | * SPDX-License-Identifier: Apache-2.0 |
18 | 18 | */ |
19 | 19 |
|
@@ -50,6 +50,34 @@ namespace { |
50 | 50 | constexpr std::string_view kMemCategoryGeometry = "Geometry"; |
51 | 51 | constexpr std::string_view kMemCategorySceneData = "SceneData"; |
52 | 52 | constexpr std::string_view kMemCategoryImages = "Images"; |
| 53 | + |
| 54 | +// Convert KTX swizzle to Vulkan component swizzle |
| 55 | +VkComponentSwizzle ktxSwizzleToVk(nv_ktx::KTX_SWIZZLE swizzle) |
| 56 | +{ |
| 57 | + switch(swizzle) |
| 58 | + { |
| 59 | + case nv_ktx::KTX_SWIZZLE::ZERO: |
| 60 | + return VK_COMPONENT_SWIZZLE_ZERO; |
| 61 | + case nv_ktx::KTX_SWIZZLE::ONE: |
| 62 | + return VK_COMPONENT_SWIZZLE_ONE; |
| 63 | + case nv_ktx::KTX_SWIZZLE::R: |
| 64 | + return VK_COMPONENT_SWIZZLE_R; |
| 65 | + case nv_ktx::KTX_SWIZZLE::G: |
| 66 | + return VK_COMPONENT_SWIZZLE_G; |
| 67 | + case nv_ktx::KTX_SWIZZLE::B: |
| 68 | + return VK_COMPONENT_SWIZZLE_B; |
| 69 | + case nv_ktx::KTX_SWIZZLE::A: |
| 70 | + return VK_COMPONENT_SWIZZLE_A; |
| 71 | + default: |
| 72 | + return VK_COMPONENT_SWIZZLE_IDENTITY; |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +// Convert KTX swizzle array to VkComponentMapping |
| 77 | +VkComponentMapping ktxSwizzleToVkComponentMapping(const std::array<nv_ktx::KTX_SWIZZLE, 4>& swizzle) |
| 78 | +{ |
| 79 | + return {ktxSwizzleToVk(swizzle[0]), ktxSwizzleToVk(swizzle[1]), ktxSwizzleToVk(swizzle[2]), ktxSwizzleToVk(swizzle[3])}; |
| 80 | +} |
53 | 81 | } // namespace |
54 | 82 |
|
55 | 83 | //-------------------------------------------------------------------------------------------------- |
@@ -1211,7 +1239,8 @@ void nvvkgltf::SceneVk::loadImage(const std::filesystem::path& basedir, const ti |
1211 | 1239 | LOGW("This KTX image had %u array elements, but loadImage() cannot handle array textures.\n", ktxImage.num_layers_possibly_0); |
1212 | 1240 | return; |
1213 | 1241 | } |
1214 | | - image.format = texture_formats::tryForceVkFormatTransferFunction(ktxImage.format, image.srgb); |
| 1242 | + image.format = texture_formats::tryForceVkFormatTransferFunction(ktxImage.format, image.srgb); |
| 1243 | + image.componentMapping = ktxSwizzleToVkComponentMapping(ktxImage.swizzle); |
1215 | 1244 |
|
1216 | 1245 | // Add all mip-levels. We don't need the ktxImage after this so we can move instead of copy. |
1217 | 1246 | for(uint32_t i = 0; i < ktxImage.num_mips; i++) |
@@ -1268,6 +1297,8 @@ void nvvkgltf::SceneVk::loadImage(const std::filesystem::path& basedir, const ti |
1268 | 1297 | { |
1269 | 1298 | case 1: |
1270 | 1299 | image.format = is16Bit ? VK_FORMAT_R16_UNORM : VK_FORMAT_R8_UNORM; |
| 1300 | + // For 1-component textures, expand the single channel to RGB for proper grayscale display |
| 1301 | + image.componentMapping = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ONE}; |
1271 | 1302 | break; |
1272 | 1303 | case 4: |
1273 | 1304 | image.format = is16Bit ? VK_FORMAT_R16G16B16A16_UNORM : |
@@ -1327,8 +1358,12 @@ bool nvvkgltf::SceneVk::createImage(const VkCommandBuffer& cmd, nvvk::StagingUpl |
1327 | 1358 | imageCreateInfo.mipLevels = nvvk::mipLevels(imgSize); |
1328 | 1359 | } |
1329 | 1360 |
|
| 1361 | + // Use custom view info with component mapping (e.g. for grayscale textures) |
| 1362 | + VkImageViewCreateInfo imageViewCreateInfo = DEFAULT_VkImageViewCreateInfo; |
| 1363 | + imageViewCreateInfo.components = image.componentMapping; |
| 1364 | + |
1330 | 1365 | nvvk::Image resultImage; |
1331 | | - NVVK_CHECK(m_alloc->createImage(resultImage, imageCreateInfo, DEFAULT_VkImageViewCreateInfo)); |
| 1366 | + NVVK_CHECK(m_alloc->createImage(resultImage, imageCreateInfo, imageViewCreateInfo)); |
1332 | 1367 | NVVK_DBG_NAME(resultImage.image); |
1333 | 1368 | NVVK_DBG_NAME(resultImage.descriptor.imageView); |
1334 | 1369 |
|
|
0 commit comments