From f6ee1de34253100f79caf7461957e659ceb739c2 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 6 Dec 2024 17:24:48 +0200 Subject: [PATCH 1/7] Ktx library + ImageLoaderKtx --- 3rdParty/CMakeLists.txt | 3 +- 3rdParty/ktx-software/CMakeLists.txt | 19 +++++ openVulkanoCpp/CMakeLists.txt | 2 +- openVulkanoCpp/Image/Image.hpp | 2 + openVulkanoCpp/Image/ImageLoaderKtx.cpp | 109 ++++++++++++++++++++++++ openVulkanoCpp/Image/ImageLoaderKtx.hpp | 25 ++++++ 6 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 3rdParty/ktx-software/CMakeLists.txt create mode 100644 openVulkanoCpp/Image/ImageLoaderKtx.cpp create mode 100644 openVulkanoCpp/Image/ImageLoaderKtx.hpp diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index eb47921..c9bc665 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -41,4 +41,5 @@ if(ENABLE_TEST) add_subdirectory(catch2) endif() -add_subdirectory(tinyusdz) \ No newline at end of file +add_subdirectory(tinyusdz) +add_subdirectory(ktx-software) \ No newline at end of file diff --git a/3rdParty/ktx-software/CMakeLists.txt b/3rdParty/ktx-software/CMakeLists.txt new file mode 100644 index 0000000..34f8475 --- /dev/null +++ b/3rdParty/ktx-software/CMakeLists.txt @@ -0,0 +1,19 @@ +include(FetchContent) + +if(NOT DEFINED KTX_REPO) + set(KTX_REPO https://github.com/KhronosGroup/KTX-Software.git) +endif () + +FetchContent_Declare( + ktx + EXCLUDE_FROM_ALL + GIT_REPOSITORY ${KTX_REPO} + GIT_TAG v4.3.2 + GIT_SHALLOW TRUE +) + +set(LIB_TYPE_DEFAULT OFF CACHE BOOL "" FORCE) +set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) +set(KTX_FEATURE_STATIC_LIBRARY ON CACHE BOOL "" FORCE) + +FetchContent_MakeAvailable(ktx) \ No newline at end of file diff --git a/openVulkanoCpp/CMakeLists.txt b/openVulkanoCpp/CMakeLists.txt index 8ed12cd..dfb5641 100644 --- a/openVulkanoCpp/CMakeLists.txt +++ b/openVulkanoCpp/CMakeLists.txt @@ -67,7 +67,7 @@ if (NOT ANDROID AND NOT IOS) endif() endif() -target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense units) +target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense units ktx) LinkAssimp(openVulkanoCpp) LinkLibArchive(openVulkanoCpp) LinkLibJpegTurbo(openVulkanoCpp) diff --git a/openVulkanoCpp/Image/Image.hpp b/openVulkanoCpp/Image/Image.hpp index b440de3..22a43f0 100644 --- a/openVulkanoCpp/Image/Image.hpp +++ b/openVulkanoCpp/Image/Image.hpp @@ -17,6 +17,8 @@ namespace OpenVulkano::Image JPEG, PNG, BMP, + KTX, + DDS, }; struct Image diff --git a/openVulkanoCpp/Image/ImageLoaderKtx.cpp b/openVulkanoCpp/Image/ImageLoaderKtx.cpp new file mode 100644 index 0000000..4b18ec9 --- /dev/null +++ b/openVulkanoCpp/Image/ImageLoaderKtx.cpp @@ -0,0 +1,109 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "ImageLoaderKtx.hpp" + +#include + +#include +#include +#include +#include + +namespace OpenVulkano::Image +{ + std::unique_ptr ImageLoaderKtx::loadFromFile(const std::string& filePath) + { + ktxTexture* texture; + KTX_error_code result = + ktxTexture_CreateFromNamedFile(filePath.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &texture); + + if (result != KTX_SUCCESS) + { + throw std::runtime_error("Failed to load KTX texture: " + std::string(ktxErrorString(result))); + } + + auto image = ExtractImage(texture); + ktxTexture_Destroy(texture); + return image; + } + + std::unique_ptr ImageLoaderKtx::loadFromMemory(const std::vector& buffer) + { + ktxTexture* texture; + KTX_error_code result = + ktxTexture_CreateFromMemory(buffer.data(), buffer.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &texture); + + if (result != KTX_SUCCESS) + { + throw std::runtime_error("Failed to load KTX texture from memory: " + std::string(ktxErrorString(result))); + } + + auto image = ExtractImage(texture); + ktxTexture_Destroy(texture); + return image; + } + + Math::Vector2i ImageLoaderKtx::GetImageDimensions(const std::string& filename) + { + ktxTexture* texture; + KTX_error_code result = + ktxTexture_CreateFromNamedFile(filename.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &texture); + + if (result != KTX_SUCCESS) + { + throw std::runtime_error("Failed to load KTX texture for dimensions: " + + std::string(ktxErrorString(result))); + } + + Math::Vector2i dimensions(texture->baseWidth, texture->baseHeight); + ktxTexture_Destroy(texture); + return dimensions; + } + + std::unique_ptr ImageLoaderKtx::ExtractImage(ktxTexture* texture) + { + if (!texture->pData) + { + throw std::runtime_error("No image data found in KTX texture."); + } + + auto width = static_cast(texture->baseWidth); + auto height = static_cast(texture->baseHeight); + + auto image = std::make_unique(); + image->resolution.x = width; + image->resolution.y = height; + image->resolution.z = 1; + + if (texture->classId == ktxTexture1_c) + { + ktxTexture1* tx = reinterpret_cast(texture); + DataFormat format = DataFormat::Format::UNDEFINED; + switch (tx->glInternalformat) + { + case 0x8051: /* GL_RGB8_EXT */ format = DataFormat::Format::R8G8B8_UNORM; break; + case 0x8054: /* GL_RGB16_EXT */ format = DataFormat::Format::R16G16B16_UNORM; break; + case 0x8057: /* GL_RGB5_A1_EXT */ format = DataFormat::Format::R5G5B5A1_UNORM_PACK16; break; + case 0x8058: /* GL_RGBA8_EXT */ format = DataFormat::Format::R8G8B8A8_UNORM; break; + case 0x8059: /* GL_RGB10_A2_EXT */ format = DataFormat::Format::A2R10G10B10_UNORM_PACK32; break; + case 0x805B: /* GL_RGBA16_EXT */ format = DataFormat::Format::R16G16B16A16_UNORM; break; + default: throw std::runtime_error("Unhandled texture1 format: " + tx->glInternalformat); + } + image->dataFormat = format; + } + else if (texture->classId == ktxTexture2_c) + { + ktxTexture2* tx = reinterpret_cast(texture); + image->dataFormat = *reinterpret_cast(&tx->vkFormat); + } + + image->data = Array(texture->dataSize); + memcpy(image->data.Data(), texture->pData, image->data.Size()); + + return image; + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Image/ImageLoaderKtx.hpp b/openVulkanoCpp/Image/ImageLoaderKtx.hpp new file mode 100644 index 0000000..c9f9db9 --- /dev/null +++ b/openVulkanoCpp/Image/ImageLoaderKtx.hpp @@ -0,0 +1,25 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "ImageLoader.hpp" + +struct ktxTexture; + +namespace OpenVulkano::Image +{ + class ImageLoaderKtx : public IImageLoader + { + public: + std::unique_ptr loadFromFile(const std::string& filePath) override; + std::unique_ptr loadFromMemory(const std::vector& buffer) override; + Math::Vector2i GetImageDimensions(const std::string& filename) override; + + protected: + std::unique_ptr ExtractImage(ktxTexture* texture); + }; +} From 412f9bb68c9bac261d5fd03a258af178ac59b95a Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Sun, 8 Dec 2024 22:57:45 +0200 Subject: [PATCH 2/7] DDS library + ImageLoaderDds --- 3rdParty/CMakeLists.txt | 3 +- 3rdParty/dds_image/CMakeLists.txt | 15 ++ openVulkanoCpp/CMakeLists.txt | 2 +- openVulkanoCpp/Image/ImageLoaderDds.cpp | 294 ++++++++++++++++++++++++ openVulkanoCpp/Image/ImageLoaderDds.hpp | 28 +++ 5 files changed, 340 insertions(+), 2 deletions(-) create mode 100644 3rdParty/dds_image/CMakeLists.txt create mode 100644 openVulkanoCpp/Image/ImageLoaderDds.cpp create mode 100644 openVulkanoCpp/Image/ImageLoaderDds.hpp diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index c9bc665..d327508 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -42,4 +42,5 @@ if(ENABLE_TEST) endif() add_subdirectory(tinyusdz) -add_subdirectory(ktx-software) \ No newline at end of file +add_subdirectory(ktx-software) +add_subdirectory(dds_image) \ No newline at end of file diff --git a/3rdParty/dds_image/CMakeLists.txt b/3rdParty/dds_image/CMakeLists.txt new file mode 100644 index 0000000..0f37104 --- /dev/null +++ b/3rdParty/dds_image/CMakeLists.txt @@ -0,0 +1,15 @@ +include(FetchContent) + +if(NOT DEFINED DDS_IMAGE_REPO) + set(DDS_IMAGE_REPO https://github.com/spnda/dds_image.git) +endif () + +FetchContent_Declare( + dds_image + EXCLUDE_FROM_ALL + GIT_REPOSITORY ${DDS_IMAGE_REPO} + GIT_TAG main + GIT_SHALLOW TRUE +) + +FetchContent_MakeAvailable(dds_image) \ No newline at end of file diff --git a/openVulkanoCpp/CMakeLists.txt b/openVulkanoCpp/CMakeLists.txt index dfb5641..6a86577 100644 --- a/openVulkanoCpp/CMakeLists.txt +++ b/openVulkanoCpp/CMakeLists.txt @@ -67,7 +67,7 @@ if (NOT ANDROID AND NOT IOS) endif() endif() -target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense units ktx) +target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense units ktx dds_image) LinkAssimp(openVulkanoCpp) LinkLibArchive(openVulkanoCpp) LinkLibJpegTurbo(openVulkanoCpp) diff --git a/openVulkanoCpp/Image/ImageLoaderDds.cpp b/openVulkanoCpp/Image/ImageLoaderDds.cpp new file mode 100644 index 0000000..cdf1c6e --- /dev/null +++ b/openVulkanoCpp/Image/ImageLoaderDds.cpp @@ -0,0 +1,294 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "ImageLoaderDds.hpp" + +#include + +namespace OpenVulkano::Image +{ + std::unique_ptr ImageLoaderDds::loadFromFile(const std::string& filePath) + { + dds::Image image; + if (dds::readFile(filePath, &image) != dds::ReadResult::Success) + { + throw std::runtime_error("Failed to load DDS texture"); + } + return ExtractImage(&image); + } + + std::unique_ptr ImageLoaderDds::loadFromMemory(const std::vector& buffer) + { + dds::Image image; + if (dds::readImage(const_cast(buffer.data()), buffer.size(), &image) != dds::ReadResult::Success) + { + throw std::runtime_error("Failed to load DDS texture"); + } + return ExtractImage(&image); + } + + Math::Vector2i ImageLoaderDds::GetImageDimensions(const std::string& filename) + { + dds::Image image; + if (dds::readFile(filename, &image) != dds::ReadResult::Success) + { + throw std::runtime_error("Failed to load DDS texture"); + } + + Math::Vector2i result; + result.x = image.width; + result.y = image.height; + + return result; + } + + std::unique_ptr ImageLoaderDds::ExtractImage(dds::Image* ddsImage) + { + auto image = std::make_unique(); + + image->resolution.x = ddsImage->width; + image->resolution.y = ddsImage->height; + image->resolution.z = 1; + + if (ddsImage->mipmaps.size() == 0) + { + throw std::runtime_error("Failed to read an image from a texture with no mipmaps"); + } + + dds::span texture = ddsImage->mipmaps[0]; + + image->data = Array(texture.size_bytes()); + memcpy(image->data.Data(), texture.data(), texture.size_bytes()); + + image->dataFormat = DataFormat::Format::UNDEFINED; + switch (ddsImage->format) + { + case DXGI_FORMAT_R32G32B32A32_FLOAT: + image->dataFormat = DataFormat::Format::R32G32B32A32_SFLOAT; + break; + case DXGI_FORMAT_R32G32B32A32_UINT: + image->dataFormat = DataFormat::Format::R32G32B32A32_UINT; + break; + case DXGI_FORMAT_R32G32B32A32_SINT: + image->dataFormat = DataFormat::Format::R32G32B32A32_SINT; + break; + case DXGI_FORMAT_R32G32B32_FLOAT: + image->dataFormat = DataFormat::Format::R32G32B32_SFLOAT; + break; + case DXGI_FORMAT_R32G32B32_UINT: + image->dataFormat = DataFormat::Format::R32G32B32_UINT; + break; + case DXGI_FORMAT_R32G32B32_SINT: + image->dataFormat = DataFormat::Format::R32G32B32_SINT; + break; + + case DXGI_FORMAT_R16G16B16A16_FLOAT: + image->dataFormat = DataFormat::Format::R16G16B16A16_SFLOAT; + break; + case DXGI_FORMAT_R16G16B16A16_UNORM: + image->dataFormat = DataFormat::Format::R16G16B16A16_UNORM; + break; + case DXGI_FORMAT_R16G16B16A16_UINT: + image->dataFormat = DataFormat::Format::R16G16B16A16_UINT; + break; + case DXGI_FORMAT_R16G16B16A16_SNORM: + image->dataFormat = DataFormat::Format::R16G16B16A16_SNORM; + break; + case DXGI_FORMAT_R16G16B16A16_SINT: + image->dataFormat = DataFormat::Format::R16G16B16A16_SINT; + break; + + case DXGI_FORMAT_R32G32_FLOAT: + image->dataFormat = DataFormat::Format::R32G32_SFLOAT; + break; + case DXGI_FORMAT_R32G32_UINT: + image->dataFormat = DataFormat::Format::R32G32_UINT; + break; + case DXGI_FORMAT_R32G32_SINT: + image->dataFormat = DataFormat::Format::R32G32_SINT; + break; + + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + image->dataFormat = DataFormat::Format::D32_SFLOAT_S8_UINT; + break; + + case DXGI_FORMAT_R8G8B8A8_UNORM: + image->dataFormat = DataFormat::Format::R8G8B8A8_UNORM; + break; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + image->dataFormat = DataFormat::Format::R8G8B8A8_SRGB; + break; + case DXGI_FORMAT_R8G8B8A8_UINT: + image->dataFormat = DataFormat::Format::R8G8B8A8_UINT; + break; + case DXGI_FORMAT_R8G8B8A8_SNORM: + image->dataFormat = DataFormat::Format::R8G8B8A8_SNORM; + break; + case DXGI_FORMAT_R8G8B8A8_SINT: + image->dataFormat = DataFormat::Format::R8G8B8A8_SINT; + break; + + case DXGI_FORMAT_R16G16_FLOAT: + image->dataFormat = DataFormat::Format::R16G16_SFLOAT; + break; + case DXGI_FORMAT_R16G16_UNORM: + image->dataFormat = DataFormat::Format::R16G16_UNORM; + break; + case DXGI_FORMAT_R16G16_UINT: + image->dataFormat = DataFormat::Format::R16G16_UINT; + break; + case DXGI_FORMAT_R16G16_SNORM: + image->dataFormat = DataFormat::Format::R16G16_SNORM; + break; + case DXGI_FORMAT_R16G16_SINT: + image->dataFormat = DataFormat::Format::R16G16_SINT; + break; + + case DXGI_FORMAT_D32_FLOAT: + image->dataFormat = DataFormat::Format::D32_SFLOAT; + break; + + case DXGI_FORMAT_R32_FLOAT: + image->dataFormat = DataFormat::Format::R32_SFLOAT; + break; + case DXGI_FORMAT_R32_UINT: + image->dataFormat = DataFormat::Format::R32_UINT; + break; + case DXGI_FORMAT_R32_SINT: + image->dataFormat = DataFormat::Format::R32_SINT; + break; + + case DXGI_FORMAT_D24_UNORM_S8_UINT: + image->dataFormat = DataFormat::Format::D24_UNORM_S8_UINT; + break; + + case DXGI_FORMAT_R8G8_UNORM: + image->dataFormat = DataFormat::Format::R8G8_UNORM; + break; + case DXGI_FORMAT_R8G8_UINT: + image->dataFormat = DataFormat::Format::R8G8_UINT; + break; + case DXGI_FORMAT_R8G8_SNORM: + image->dataFormat = DataFormat::Format::R8G8_SNORM; + break; + case DXGI_FORMAT_R8G8_SINT: + image->dataFormat = DataFormat::Format::R8G8_SINT; + break; + + case DXGI_FORMAT_D16_UNORM: + image->dataFormat = DataFormat::Format::D16_UNORM; + break; + case DXGI_FORMAT_R16_FLOAT: + image->dataFormat = DataFormat::Format::R16_SFLOAT; + break; + case DXGI_FORMAT_R16_UNORM: + image->dataFormat = DataFormat::Format::R16_UNORM; + break; + case DXGI_FORMAT_R16_UINT: + image->dataFormat = DataFormat::Format::R16_UINT; + break; + case DXGI_FORMAT_R16_SNORM: + image->dataFormat = DataFormat::Format::R16_SNORM; + break; + case DXGI_FORMAT_R16_SINT: + image->dataFormat = DataFormat::Format::R16_SINT; + break; + + case DXGI_FORMAT_R8_UNORM: + image->dataFormat = DataFormat::Format::R8_UNORM; + break; + case DXGI_FORMAT_R8_UINT: + image->dataFormat = DataFormat::Format::R8_UINT; + break; + case DXGI_FORMAT_R8_SNORM: + image->dataFormat = DataFormat::Format::R8_SNORM; + break; + case DXGI_FORMAT_R8_SINT: + image->dataFormat = DataFormat::Format::R8_SINT; + break; + + case DXGI_FORMAT_BC1_UNORM: + image->dataFormat = DataFormat::Format::BC1_RGBA_UNORM_BLOCK; + break; + case DXGI_FORMAT_BC1_UNORM_SRGB: + image->dataFormat = DataFormat::Format::BC1_RGBA_SRGB_BLOCK; + break; + + case DXGI_FORMAT_BC2_UNORM: + image->dataFormat = DataFormat::Format::BC2_UNORM_BLOCK; + break; + case DXGI_FORMAT_BC2_UNORM_SRGB: + image->dataFormat = DataFormat::Format::BC2_SRGB_BLOCK; + break; + + case DXGI_FORMAT_BC3_UNORM: + image->dataFormat = DataFormat::Format::BC3_UNORM_BLOCK; + break; + case DXGI_FORMAT_BC3_UNORM_SRGB: + image->dataFormat = DataFormat::Format::BC3_SRGB_BLOCK; + break; + + case DXGI_FORMAT_BC4_UNORM: + image->dataFormat = DataFormat::Format::BC4_UNORM_BLOCK; + break; + case DXGI_FORMAT_BC4_SNORM: + image->dataFormat = DataFormat::Format::BC4_SNORM_BLOCK; + break; + + case DXGI_FORMAT_BC5_UNORM: + image->dataFormat = DataFormat::Format::BC5_UNORM_BLOCK; + break; + case DXGI_FORMAT_BC5_SNORM: + image->dataFormat = DataFormat::Format::BC5_SNORM_BLOCK; + break; + + case DXGI_FORMAT_B5G6R5_UNORM: + image->dataFormat = DataFormat::Format::B5G6R5_UNORM_PACK16; + break; + case DXGI_FORMAT_B5G5R5A1_UNORM: + image->dataFormat = DataFormat::Format::B5G5R5A1_UNORM_PACK16; + break; + + case DXGI_FORMAT_B8G8R8A8_UNORM: + image->dataFormat = DataFormat::Format::B8G8R8A8_UNORM; + break; + case DXGI_FORMAT_B8G8R8X8_UNORM: + image->dataFormat = DataFormat::Format::B8G8R8A8_SNORM; + break; + + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + image->dataFormat = DataFormat::Format::B8G8R8A8_SRGB; + break; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + image->dataFormat = DataFormat::Format::B8G8R8A8_SRGB; + break; + + case DXGI_FORMAT_BC6H_UF16: + image->dataFormat = DataFormat::Format::BC6H_UFLOAT_BLOCK; + break; + case DXGI_FORMAT_BC6H_SF16: + image->dataFormat = DataFormat::Format::BC6H_SFLOAT_BLOCK; + break; + + case DXGI_FORMAT_BC7_UNORM: + image->dataFormat = DataFormat::Format::BC7_UNORM_BLOCK; + break; + case DXGI_FORMAT_BC7_UNORM_SRGB: + image->dataFormat = DataFormat::Format::BC7_SRGB_BLOCK; + break; + + case DXGI_FORMAT_B4G4R4A4_UNORM: + image->dataFormat = DataFormat::Format::B4G4R4A4_UNORM_PACK16; + break; + + default: + throw std::runtime_error("Unhandled DDS texture format: " + + std::to_string(*reinterpret_cast(&ddsImage->format))); + } + + return image; + } +} diff --git a/openVulkanoCpp/Image/ImageLoaderDds.hpp b/openVulkanoCpp/Image/ImageLoaderDds.hpp new file mode 100644 index 0000000..05717c3 --- /dev/null +++ b/openVulkanoCpp/Image/ImageLoaderDds.hpp @@ -0,0 +1,28 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "ImageLoader.hpp" + +namespace dds +{ + struct Image; +} + +namespace OpenVulkano::Image +{ + class ImageLoaderDds : public IImageLoader + { + public: + std::unique_ptr loadFromFile(const std::string& filePath) override; + std::unique_ptr loadFromMemory(const std::vector& buffer) override; + Math::Vector2i GetImageDimensions(const std::string& filename) override; + + protected: + std::unique_ptr ExtractImage(dds::Image* ddsImage); + }; +} From 2da2d0ef9c0ed6ea646912b9fe38646d101604ac Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 9 Dec 2024 15:57:15 +0200 Subject: [PATCH 3/7] Changed switch statement to unordered_map, added extra exception information --- openVulkanoCpp/Image/ImageLoaderDds.cpp | 335 ++++++++---------------- 1 file changed, 107 insertions(+), 228 deletions(-) diff --git a/openVulkanoCpp/Image/ImageLoaderDds.cpp b/openVulkanoCpp/Image/ImageLoaderDds.cpp index cdf1c6e..903c772 100644 --- a/openVulkanoCpp/Image/ImageLoaderDds.cpp +++ b/openVulkanoCpp/Image/ImageLoaderDds.cpp @@ -7,6 +7,103 @@ #include "ImageLoaderDds.hpp" #include +#include +#include + +#include + +namespace +{ + std::unordered_map DXGI_TO_OV_DATAFORMAT = { + { DXGI_FORMAT_R32G32B32A32_FLOAT, OpenVulkano::DataFormat::Format::R32G32B32A32_SFLOAT }, + { DXGI_FORMAT_R32G32B32A32_UINT, OpenVulkano::DataFormat::Format::R32G32B32A32_UINT }, + { DXGI_FORMAT_R32G32B32A32_SINT, OpenVulkano::DataFormat::Format::R32G32B32A32_SINT }, + { DXGI_FORMAT_R32G32B32_FLOAT, OpenVulkano::DataFormat::Format::R32G32B32_SFLOAT }, + { DXGI_FORMAT_R32G32B32_UINT, OpenVulkano::DataFormat::Format::R32G32B32_UINT }, + { DXGI_FORMAT_R32G32B32_SINT, OpenVulkano::DataFormat::Format::R32G32B32_SINT }, + + { DXGI_FORMAT_R16G16B16A16_FLOAT, OpenVulkano::DataFormat::Format::R16G16B16A16_SFLOAT }, + { DXGI_FORMAT_R16G16B16A16_UNORM, OpenVulkano::DataFormat::Format::R16G16B16A16_UNORM }, + { DXGI_FORMAT_R16G16B16A16_UINT, OpenVulkano::DataFormat::Format::R16G16B16A16_UINT }, + { DXGI_FORMAT_R16G16B16A16_SNORM, OpenVulkano::DataFormat::Format::R16G16B16A16_SNORM }, + { DXGI_FORMAT_R16G16B16A16_SINT, OpenVulkano::DataFormat::Format::R16G16B16A16_SINT }, + + { DXGI_FORMAT_R32G32_FLOAT, OpenVulkano::DataFormat::Format::R32G32_SFLOAT }, + { DXGI_FORMAT_R32G32_UINT, OpenVulkano::DataFormat::Format::R32G32_UINT }, + { DXGI_FORMAT_R32G32_SINT, OpenVulkano::DataFormat::Format::R32G32_SINT }, + + { DXGI_FORMAT_D32_FLOAT_S8X24_UINT, OpenVulkano::DataFormat::Format::D32_SFLOAT_S8_UINT }, + + { DXGI_FORMAT_R8G8B8A8_UNORM, OpenVulkano::DataFormat::Format::R8G8B8A8_UNORM }, + { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, OpenVulkano::DataFormat::Format::R8G8B8A8_SRGB }, + { DXGI_FORMAT_R8G8B8A8_UINT, OpenVulkano::DataFormat::Format::R8G8B8A8_UINT }, + { DXGI_FORMAT_R8G8B8A8_SNORM, OpenVulkano::DataFormat::Format::R8G8B8A8_SNORM }, + { DXGI_FORMAT_R8G8B8A8_SINT, OpenVulkano::DataFormat::Format::R8G8B8A8_SINT }, + + { DXGI_FORMAT_R16G16_FLOAT, OpenVulkano::DataFormat::Format::R16G16_SFLOAT }, + { DXGI_FORMAT_R16G16_UNORM, OpenVulkano::DataFormat::Format::R16G16_UNORM }, + { DXGI_FORMAT_R16G16_UINT, OpenVulkano::DataFormat::Format::R16G16_UINT }, + { DXGI_FORMAT_R16G16_SNORM, OpenVulkano::DataFormat::Format::R16G16_SNORM }, + { DXGI_FORMAT_R16G16_SINT, OpenVulkano::DataFormat::Format::R16G16_SINT }, + + { DXGI_FORMAT_D32_FLOAT, OpenVulkano::DataFormat::Format::D32_SFLOAT }, + + { DXGI_FORMAT_R32_FLOAT, OpenVulkano::DataFormat::Format::R32_SFLOAT }, + { DXGI_FORMAT_R32_UINT, OpenVulkano::DataFormat::Format::R32_UINT }, + { DXGI_FORMAT_R32_SINT, OpenVulkano::DataFormat::Format::R32_SINT }, + + { DXGI_FORMAT_D24_UNORM_S8_UINT, OpenVulkano::DataFormat::Format::D24_UNORM_S8_UINT }, + + { DXGI_FORMAT_R8G8_UNORM, OpenVulkano::DataFormat::Format::R8G8_UNORM }, + { DXGI_FORMAT_R8G8_UINT, OpenVulkano::DataFormat::Format::R8G8_UINT }, + { DXGI_FORMAT_R8G8_SNORM, OpenVulkano::DataFormat::Format::R8G8_SNORM }, + { DXGI_FORMAT_R8G8_SINT, OpenVulkano::DataFormat::Format::R8G8_SINT }, + + { DXGI_FORMAT_D16_UNORM, OpenVulkano::DataFormat::Format::D16_UNORM }, + { DXGI_FORMAT_R16_FLOAT, OpenVulkano::DataFormat::Format::R16_SFLOAT }, + { DXGI_FORMAT_R16_UNORM, OpenVulkano::DataFormat::Format::R16_UNORM }, + { DXGI_FORMAT_R16_UINT, OpenVulkano::DataFormat::Format::R16_UINT }, + { DXGI_FORMAT_R16_SNORM, OpenVulkano::DataFormat::Format::R16_SNORM }, + { DXGI_FORMAT_R16_SINT, OpenVulkano::DataFormat::Format::R16_SINT }, + + { DXGI_FORMAT_R8_UNORM, OpenVulkano::DataFormat::Format::R8_UNORM }, + { DXGI_FORMAT_R8_UINT, OpenVulkano::DataFormat::Format::R8_UINT }, + { DXGI_FORMAT_R8_SNORM, OpenVulkano::DataFormat::Format::R8_SNORM }, + { DXGI_FORMAT_R8_SINT, OpenVulkano::DataFormat::Format::R8_SINT }, + + { DXGI_FORMAT_BC1_UNORM, OpenVulkano::DataFormat::Format::BC1_RGBA_UNORM_BLOCK }, + { DXGI_FORMAT_BC1_UNORM_SRGB, OpenVulkano::DataFormat::Format::BC1_RGBA_SRGB_BLOCK }, + + { DXGI_FORMAT_BC2_UNORM, OpenVulkano::DataFormat::Format::BC2_UNORM_BLOCK }, + { DXGI_FORMAT_BC2_UNORM_SRGB, OpenVulkano::DataFormat::Format::BC2_SRGB_BLOCK }, + + { DXGI_FORMAT_BC3_UNORM, OpenVulkano::DataFormat::Format::BC3_UNORM_BLOCK }, + { DXGI_FORMAT_BC3_UNORM_SRGB, OpenVulkano::DataFormat::Format::BC3_SRGB_BLOCK }, + + { DXGI_FORMAT_BC4_UNORM, OpenVulkano::DataFormat::Format::BC4_UNORM_BLOCK }, + { DXGI_FORMAT_BC4_SNORM, OpenVulkano::DataFormat::Format::BC4_SNORM_BLOCK }, + + { DXGI_FORMAT_BC5_UNORM, OpenVulkano::DataFormat::Format::BC5_UNORM_BLOCK }, + { DXGI_FORMAT_BC5_SNORM, OpenVulkano::DataFormat::Format::BC5_SNORM_BLOCK }, + + { DXGI_FORMAT_B5G6R5_UNORM, OpenVulkano::DataFormat::Format::B5G6R5_UNORM_PACK16 }, + { DXGI_FORMAT_B5G5R5A1_UNORM, OpenVulkano::DataFormat::Format::B5G5R5A1_UNORM_PACK16 }, + + { DXGI_FORMAT_B8G8R8A8_UNORM, OpenVulkano::DataFormat::Format::B8G8R8A8_UNORM }, + { DXGI_FORMAT_B8G8R8X8_UNORM, OpenVulkano::DataFormat::Format::B8G8R8A8_SNORM }, + + { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, OpenVulkano::DataFormat::Format::B8G8R8A8_SRGB }, + { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, OpenVulkano::DataFormat::Format::B8G8R8A8_SRGB }, + + { DXGI_FORMAT_BC6H_UF16, OpenVulkano::DataFormat::Format::BC6H_UFLOAT_BLOCK }, + { DXGI_FORMAT_BC6H_SF16, OpenVulkano::DataFormat::Format::BC6H_SFLOAT_BLOCK }, + + { DXGI_FORMAT_BC7_UNORM, OpenVulkano::DataFormat::Format::BC7_UNORM_BLOCK }, + { DXGI_FORMAT_BC7_UNORM_SRGB, OpenVulkano::DataFormat::Format::BC7_SRGB_BLOCK }, + + { DXGI_FORMAT_B4G4R4A4_UNORM, OpenVulkano::DataFormat::Format::B4G4R4A4_UNORM_PACK16 }, + }; +} namespace OpenVulkano::Image { @@ -52,243 +149,25 @@ namespace OpenVulkano::Image image->resolution.x = ddsImage->width; image->resolution.y = ddsImage->height; image->resolution.z = 1; - + + if (DXGI_TO_OV_DATAFORMAT.contains(ddsImage->format)) + { + image->dataFormat = DXGI_TO_OV_DATAFORMAT[ddsImage->format]; + } + else + { + throw std::runtime_error(fmt::format("Unhandled DDS texture format: {} ({})", magic_enum::enum_name(ddsImage->format), static_cast(ddsImage->format))); + } + if (ddsImage->mipmaps.size() == 0) { throw std::runtime_error("Failed to read an image from a texture with no mipmaps"); } dds::span texture = ddsImage->mipmaps[0]; - image->data = Array(texture.size_bytes()); memcpy(image->data.Data(), texture.data(), texture.size_bytes()); - image->dataFormat = DataFormat::Format::UNDEFINED; - switch (ddsImage->format) - { - case DXGI_FORMAT_R32G32B32A32_FLOAT: - image->dataFormat = DataFormat::Format::R32G32B32A32_SFLOAT; - break; - case DXGI_FORMAT_R32G32B32A32_UINT: - image->dataFormat = DataFormat::Format::R32G32B32A32_UINT; - break; - case DXGI_FORMAT_R32G32B32A32_SINT: - image->dataFormat = DataFormat::Format::R32G32B32A32_SINT; - break; - case DXGI_FORMAT_R32G32B32_FLOAT: - image->dataFormat = DataFormat::Format::R32G32B32_SFLOAT; - break; - case DXGI_FORMAT_R32G32B32_UINT: - image->dataFormat = DataFormat::Format::R32G32B32_UINT; - break; - case DXGI_FORMAT_R32G32B32_SINT: - image->dataFormat = DataFormat::Format::R32G32B32_SINT; - break; - - case DXGI_FORMAT_R16G16B16A16_FLOAT: - image->dataFormat = DataFormat::Format::R16G16B16A16_SFLOAT; - break; - case DXGI_FORMAT_R16G16B16A16_UNORM: - image->dataFormat = DataFormat::Format::R16G16B16A16_UNORM; - break; - case DXGI_FORMAT_R16G16B16A16_UINT: - image->dataFormat = DataFormat::Format::R16G16B16A16_UINT; - break; - case DXGI_FORMAT_R16G16B16A16_SNORM: - image->dataFormat = DataFormat::Format::R16G16B16A16_SNORM; - break; - case DXGI_FORMAT_R16G16B16A16_SINT: - image->dataFormat = DataFormat::Format::R16G16B16A16_SINT; - break; - - case DXGI_FORMAT_R32G32_FLOAT: - image->dataFormat = DataFormat::Format::R32G32_SFLOAT; - break; - case DXGI_FORMAT_R32G32_UINT: - image->dataFormat = DataFormat::Format::R32G32_UINT; - break; - case DXGI_FORMAT_R32G32_SINT: - image->dataFormat = DataFormat::Format::R32G32_SINT; - break; - - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - image->dataFormat = DataFormat::Format::D32_SFLOAT_S8_UINT; - break; - - case DXGI_FORMAT_R8G8B8A8_UNORM: - image->dataFormat = DataFormat::Format::R8G8B8A8_UNORM; - break; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - image->dataFormat = DataFormat::Format::R8G8B8A8_SRGB; - break; - case DXGI_FORMAT_R8G8B8A8_UINT: - image->dataFormat = DataFormat::Format::R8G8B8A8_UINT; - break; - case DXGI_FORMAT_R8G8B8A8_SNORM: - image->dataFormat = DataFormat::Format::R8G8B8A8_SNORM; - break; - case DXGI_FORMAT_R8G8B8A8_SINT: - image->dataFormat = DataFormat::Format::R8G8B8A8_SINT; - break; - - case DXGI_FORMAT_R16G16_FLOAT: - image->dataFormat = DataFormat::Format::R16G16_SFLOAT; - break; - case DXGI_FORMAT_R16G16_UNORM: - image->dataFormat = DataFormat::Format::R16G16_UNORM; - break; - case DXGI_FORMAT_R16G16_UINT: - image->dataFormat = DataFormat::Format::R16G16_UINT; - break; - case DXGI_FORMAT_R16G16_SNORM: - image->dataFormat = DataFormat::Format::R16G16_SNORM; - break; - case DXGI_FORMAT_R16G16_SINT: - image->dataFormat = DataFormat::Format::R16G16_SINT; - break; - - case DXGI_FORMAT_D32_FLOAT: - image->dataFormat = DataFormat::Format::D32_SFLOAT; - break; - - case DXGI_FORMAT_R32_FLOAT: - image->dataFormat = DataFormat::Format::R32_SFLOAT; - break; - case DXGI_FORMAT_R32_UINT: - image->dataFormat = DataFormat::Format::R32_UINT; - break; - case DXGI_FORMAT_R32_SINT: - image->dataFormat = DataFormat::Format::R32_SINT; - break; - - case DXGI_FORMAT_D24_UNORM_S8_UINT: - image->dataFormat = DataFormat::Format::D24_UNORM_S8_UINT; - break; - - case DXGI_FORMAT_R8G8_UNORM: - image->dataFormat = DataFormat::Format::R8G8_UNORM; - break; - case DXGI_FORMAT_R8G8_UINT: - image->dataFormat = DataFormat::Format::R8G8_UINT; - break; - case DXGI_FORMAT_R8G8_SNORM: - image->dataFormat = DataFormat::Format::R8G8_SNORM; - break; - case DXGI_FORMAT_R8G8_SINT: - image->dataFormat = DataFormat::Format::R8G8_SINT; - break; - - case DXGI_FORMAT_D16_UNORM: - image->dataFormat = DataFormat::Format::D16_UNORM; - break; - case DXGI_FORMAT_R16_FLOAT: - image->dataFormat = DataFormat::Format::R16_SFLOAT; - break; - case DXGI_FORMAT_R16_UNORM: - image->dataFormat = DataFormat::Format::R16_UNORM; - break; - case DXGI_FORMAT_R16_UINT: - image->dataFormat = DataFormat::Format::R16_UINT; - break; - case DXGI_FORMAT_R16_SNORM: - image->dataFormat = DataFormat::Format::R16_SNORM; - break; - case DXGI_FORMAT_R16_SINT: - image->dataFormat = DataFormat::Format::R16_SINT; - break; - - case DXGI_FORMAT_R8_UNORM: - image->dataFormat = DataFormat::Format::R8_UNORM; - break; - case DXGI_FORMAT_R8_UINT: - image->dataFormat = DataFormat::Format::R8_UINT; - break; - case DXGI_FORMAT_R8_SNORM: - image->dataFormat = DataFormat::Format::R8_SNORM; - break; - case DXGI_FORMAT_R8_SINT: - image->dataFormat = DataFormat::Format::R8_SINT; - break; - - case DXGI_FORMAT_BC1_UNORM: - image->dataFormat = DataFormat::Format::BC1_RGBA_UNORM_BLOCK; - break; - case DXGI_FORMAT_BC1_UNORM_SRGB: - image->dataFormat = DataFormat::Format::BC1_RGBA_SRGB_BLOCK; - break; - - case DXGI_FORMAT_BC2_UNORM: - image->dataFormat = DataFormat::Format::BC2_UNORM_BLOCK; - break; - case DXGI_FORMAT_BC2_UNORM_SRGB: - image->dataFormat = DataFormat::Format::BC2_SRGB_BLOCK; - break; - - case DXGI_FORMAT_BC3_UNORM: - image->dataFormat = DataFormat::Format::BC3_UNORM_BLOCK; - break; - case DXGI_FORMAT_BC3_UNORM_SRGB: - image->dataFormat = DataFormat::Format::BC3_SRGB_BLOCK; - break; - - case DXGI_FORMAT_BC4_UNORM: - image->dataFormat = DataFormat::Format::BC4_UNORM_BLOCK; - break; - case DXGI_FORMAT_BC4_SNORM: - image->dataFormat = DataFormat::Format::BC4_SNORM_BLOCK; - break; - - case DXGI_FORMAT_BC5_UNORM: - image->dataFormat = DataFormat::Format::BC5_UNORM_BLOCK; - break; - case DXGI_FORMAT_BC5_SNORM: - image->dataFormat = DataFormat::Format::BC5_SNORM_BLOCK; - break; - - case DXGI_FORMAT_B5G6R5_UNORM: - image->dataFormat = DataFormat::Format::B5G6R5_UNORM_PACK16; - break; - case DXGI_FORMAT_B5G5R5A1_UNORM: - image->dataFormat = DataFormat::Format::B5G5R5A1_UNORM_PACK16; - break; - - case DXGI_FORMAT_B8G8R8A8_UNORM: - image->dataFormat = DataFormat::Format::B8G8R8A8_UNORM; - break; - case DXGI_FORMAT_B8G8R8X8_UNORM: - image->dataFormat = DataFormat::Format::B8G8R8A8_SNORM; - break; - - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - image->dataFormat = DataFormat::Format::B8G8R8A8_SRGB; - break; - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - image->dataFormat = DataFormat::Format::B8G8R8A8_SRGB; - break; - - case DXGI_FORMAT_BC6H_UF16: - image->dataFormat = DataFormat::Format::BC6H_UFLOAT_BLOCK; - break; - case DXGI_FORMAT_BC6H_SF16: - image->dataFormat = DataFormat::Format::BC6H_SFLOAT_BLOCK; - break; - - case DXGI_FORMAT_BC7_UNORM: - image->dataFormat = DataFormat::Format::BC7_UNORM_BLOCK; - break; - case DXGI_FORMAT_BC7_UNORM_SRGB: - image->dataFormat = DataFormat::Format::BC7_SRGB_BLOCK; - break; - - case DXGI_FORMAT_B4G4R4A4_UNORM: - image->dataFormat = DataFormat::Format::B4G4R4A4_UNORM_PACK16; - break; - - default: - throw std::runtime_error("Unhandled DDS texture format: " - + std::to_string(*reinterpret_cast(&ddsImage->format))); - } - return image; } } From 524e806c18507d836118dc390173a42c3e232c7e Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 9 Dec 2024 15:58:36 +0200 Subject: [PATCH 4/7] Handling exceptions and destroying texture on exception, added else branch in case if classId is something else --- openVulkanoCpp/Image/ImageLoaderKtx.cpp | 50 ++++++++++++++++++------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/openVulkanoCpp/Image/ImageLoaderKtx.cpp b/openVulkanoCpp/Image/ImageLoaderKtx.cpp index 4b18ec9..d410d0a 100644 --- a/openVulkanoCpp/Image/ImageLoaderKtx.cpp +++ b/openVulkanoCpp/Image/ImageLoaderKtx.cpp @@ -18,33 +18,53 @@ namespace OpenVulkano::Image std::unique_ptr ImageLoaderKtx::loadFromFile(const std::string& filePath) { ktxTexture* texture; - KTX_error_code result = + KTX_error_code error_code = ktxTexture_CreateFromNamedFile(filePath.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &texture); - if (result != KTX_SUCCESS) + if (error_code != KTX_SUCCESS) { - throw std::runtime_error("Failed to load KTX texture: " + std::string(ktxErrorString(result))); + throw std::runtime_error("Failed to load KTX texture: " + std::string(ktxErrorString(error_code))); } - auto image = ExtractImage(texture); - ktxTexture_Destroy(texture); - return image; + try + { + auto result = ExtractImage(texture); + ktxTexture_Destroy(texture); + return result; + } + catch (...) + { + ktxTexture_Destroy(texture); + throw; + } + + return {}; } std::unique_ptr ImageLoaderKtx::loadFromMemory(const std::vector& buffer) { ktxTexture* texture; - KTX_error_code result = + KTX_error_code error_code = ktxTexture_CreateFromMemory(buffer.data(), buffer.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &texture); - if (result != KTX_SUCCESS) + if (error_code != KTX_SUCCESS) { - throw std::runtime_error("Failed to load KTX texture from memory: " + std::string(ktxErrorString(result))); + throw std::runtime_error("Failed to load KTX texture from memory: " + std::string(ktxErrorString(error_code))); } - auto image = ExtractImage(texture); - ktxTexture_Destroy(texture); - return image; + try + { + auto result = ExtractImage(texture); + ktxTexture_Destroy(texture); + return result; + } + catch (...) + { + ktxTexture_Destroy(texture); + throw; + } + + return {}; } Math::Vector2i ImageLoaderKtx::GetImageDimensions(const std::string& filename) @@ -98,7 +118,11 @@ namespace OpenVulkano::Image else if (texture->classId == ktxTexture2_c) { ktxTexture2* tx = reinterpret_cast(texture); - image->dataFormat = *reinterpret_cast(&tx->vkFormat); + image->dataFormat = reinterpret_cast(tx->vkFormat); + } + else [[unlikely]] + { + throw std::runtime_error("ktxTexture has unhandled classId!"); } image->data = Array(texture->dataSize); From a465063baef978656f99c3d83dda4b02560a111c Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 9 Dec 2024 18:01:38 +0200 Subject: [PATCH 5/7] Using unique_ptr to properly destroy images --- openVulkanoCpp/Image/ImageLoaderDds.cpp | 4 +- openVulkanoCpp/Image/ImageLoaderKtx.cpp | 54 ++++++++++--------------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/openVulkanoCpp/Image/ImageLoaderDds.cpp b/openVulkanoCpp/Image/ImageLoaderDds.cpp index 903c772..9b94f9f 100644 --- a/openVulkanoCpp/Image/ImageLoaderDds.cpp +++ b/openVulkanoCpp/Image/ImageLoaderDds.cpp @@ -156,7 +156,9 @@ namespace OpenVulkano::Image } else { - throw std::runtime_error(fmt::format("Unhandled DDS texture format: {} ({})", magic_enum::enum_name(ddsImage->format), static_cast(ddsImage->format))); + throw std::runtime_error(fmt::format("Unhandled DDS texture format: {} ({})", + magic_enum::enum_name(ddsImage->format), + static_cast(ddsImage->format))); } if (ddsImage->mipmaps.size() == 0) diff --git a/openVulkanoCpp/Image/ImageLoaderKtx.cpp b/openVulkanoCpp/Image/ImageLoaderKtx.cpp index d410d0a..afef434 100644 --- a/openVulkanoCpp/Image/ImageLoaderKtx.cpp +++ b/openVulkanoCpp/Image/ImageLoaderKtx.cpp @@ -13,65 +13,54 @@ #include #include +namespace +{ + void KtxDestroy(ktxTexture* tex) + { + ktxTexture_Destroy(tex); + } +} + namespace OpenVulkano::Image { std::unique_ptr ImageLoaderKtx::loadFromFile(const std::string& filePath) { - ktxTexture* texture; + ktxTexture* tmp = nullptr; KTX_error_code error_code = - ktxTexture_CreateFromNamedFile(filePath.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &texture); + ktxTexture_CreateFromNamedFile(filePath.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &tmp); + std::unique_ptr texture(tmp, &KtxDestroy); if (error_code != KTX_SUCCESS) { throw std::runtime_error("Failed to load KTX texture: " + std::string(ktxErrorString(error_code))); } - try - { - auto result = ExtractImage(texture); - ktxTexture_Destroy(texture); - return result; - } - catch (...) - { - ktxTexture_Destroy(texture); - throw; - } - - return {}; + auto result = ExtractImage(texture.get()); + return result; } std::unique_ptr ImageLoaderKtx::loadFromMemory(const std::vector& buffer) { - ktxTexture* texture; + ktxTexture* tmp = nullptr; KTX_error_code error_code = - ktxTexture_CreateFromMemory(buffer.data(), buffer.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &texture); + ktxTexture_CreateFromMemory(buffer.data(), buffer.size(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &tmp); + std::unique_ptr texture(tmp, &KtxDestroy); if (error_code != KTX_SUCCESS) { throw std::runtime_error("Failed to load KTX texture from memory: " + std::string(ktxErrorString(error_code))); } - try - { - auto result = ExtractImage(texture); - ktxTexture_Destroy(texture); - return result; - } - catch (...) - { - ktxTexture_Destroy(texture); - throw; - } - - return {}; + auto result = ExtractImage(texture.get()); + return result; } Math::Vector2i ImageLoaderKtx::GetImageDimensions(const std::string& filename) { - ktxTexture* texture; + ktxTexture* tmp = nullptr; KTX_error_code result = - ktxTexture_CreateFromNamedFile(filename.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &texture); + ktxTexture_CreateFromNamedFile(filename.c_str(), KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT, &tmp); + std::unique_ptr texture(tmp, &KtxDestroy); if (result != KTX_SUCCESS) { @@ -80,7 +69,6 @@ namespace OpenVulkano::Image } Math::Vector2i dimensions(texture->baseWidth, texture->baseHeight); - ktxTexture_Destroy(texture); return dimensions; } From 998cd92a7c145f328bece21e1150283212bb2ea3 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 9 Dec 2024 18:06:46 +0200 Subject: [PATCH 6/7] Using auto instead of span --- openVulkanoCpp/Image/ImageLoaderDds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openVulkanoCpp/Image/ImageLoaderDds.cpp b/openVulkanoCpp/Image/ImageLoaderDds.cpp index 9b94f9f..e0bee3f 100644 --- a/openVulkanoCpp/Image/ImageLoaderDds.cpp +++ b/openVulkanoCpp/Image/ImageLoaderDds.cpp @@ -166,7 +166,7 @@ namespace OpenVulkano::Image throw std::runtime_error("Failed to read an image from a texture with no mipmaps"); } - dds::span texture = ddsImage->mipmaps[0]; + auto texture = ddsImage->mipmaps[0]; image->data = Array(texture.size_bytes()); memcpy(image->data.Data(), texture.data(), texture.size_bytes()); From e69c2bb2360930e0160365479e735066dae972f0 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 9 Dec 2024 18:26:33 +0200 Subject: [PATCH 7/7] Disabled BASISU_SUPPORT_SSE --- 3rdParty/ktx-software/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/3rdParty/ktx-software/CMakeLists.txt b/3rdParty/ktx-software/CMakeLists.txt index 34f8475..6997606 100644 --- a/3rdParty/ktx-software/CMakeLists.txt +++ b/3rdParty/ktx-software/CMakeLists.txt @@ -14,6 +14,7 @@ FetchContent_Declare( set(LIB_TYPE_DEFAULT OFF CACHE BOOL "" FORCE) set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) +set(BASISU_SUPPORT_SSE OFF CACHE BOOL "" FORCE) set(KTX_FEATURE_STATIC_LIBRARY ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(ktx) \ No newline at end of file