Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Encode astc support #810

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,14 @@ cmake --build build-macos-universal
file build-macos-universal/Debug/libktx.dylib
# outputs:
# build-macos-universal/Debug/libktx.dylib: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64]
# build-macos-universal/Debug/libktx.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
# build-macos-universal/Debug/libktx.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
# build-macos-universal/Debug/libktx.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
# build-macos-universal/Debug/libktx.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64

file build-macos-universal/Debug/ktx
# outputs:
# build-macos-universal/Debug/ktx: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
# build-macos-universal/Debug/ktx (for architecture x86_64): Mach-O 64-bit executable x86_64
# build-macos-universal/Debug/ktx (for architecture arm64): Mach-O 64-bit executable arm64
# build-macos-universal/Debug/ktx (for architecture x86_64): Mach-O 64-bit executable x86_64
# build-macos-universal/Debug/ktx (for architecture arm64): Mach-O 64-bit executable arm64
```

To explicity build for one or the other architecture use
Expand Down
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,9 @@ set(KTX_MAIN_SRC
)

if (KTX_FEATURE_ETC_UNPACK)
list(APPEND KTX_MAIN_SRC
external/etcdec/etcdec.cxx
)
list(APPEND KTX_MAIN_SRC
external/etcdec/etcdec.cxx
)
endif()

set(BASISU_ENCODER_CXX_SRC
Expand Down
3 changes: 3 additions & 0 deletions include/ktx.h
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,9 @@ ktxTexture2_CompressAstcEx(ktxTexture2* This, ktxAstcParams* params);
KTX_API KTX_error_code KTX_APIENTRY
ktxTexture2_CompressAstc(ktxTexture2* This, ktx_uint32_t quality);

KTX_API KTX_error_code KTX_APIENTRY
ktxTexture2_DecodeAstc(ktxTexture2* This, ktx_uint32_t vkformat);

/**
* @memberof ktxTexture2
* @~English
Expand Down
318 changes: 315 additions & 3 deletions lib/astc_encode.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions scripts/build_macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ cmake_args+=( \
"-D" "KTX_FEATURE_TESTS=$FEATURE_TESTS" \
"-D" "KTX_FEATURE_TOOLS=$FEATURE_TOOLS" \
"-D" "KTX_FEATURE_TOOLS_CTS=$FEATURE_TOOLS_CTS" \
"-D" "KTX_LOADTEST_APPS_USE_LOCAL_DEPENDENCIES=$LOADTESTS_USE_LOCAL_DEPENDENCIES" \
"-D" "KTX_WERROR=$WERROR" \
"-D" "BASISU_SUPPORT_OPENCL=$SUPPORT_OPENCL" \
"-D" "BASISU_SUPPORT_SSE=$SUPPORT_SSE"
Expand Down
2 changes: 1 addition & 1 deletion tests/cts
Submodule cts updated 5434 files
1 change: 1 addition & 0 deletions tools/ktx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ add_executable(ktxtools
command_create.cpp
command_deflate.cpp
command_encode.cpp
command_encode_astc.cpp
command_extract.cpp
command_help.cpp
command_info.cpp
Expand Down
117 changes: 117 additions & 0 deletions tools/ktx/astc_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright 2022-2023 The Khronos Group Inc.
// Copyright 2022-2023 RasterGrid Kft.
// SPDX-License-Identifier: Apache-2.0

#include "command.h"
#include "utility.h"
#include <thread>

namespace ktx {

/**
//! [command options_astc]
<dl>
Copy link
Collaborator

@MarkCallow MarkCallow Dec 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the <dl> should be here. Is it in the other snippets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In encode_utils.h it has, and from the source c4cc963#diff-8ca48860d1bd768774f38f0f522ba91ef7dbb887e660917c74b7088da850752aL604 where I brought this from, it had it too.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. When this PR is further along we can build the docs and check what it looks like. I'll leave this conversation open to remind us.

<dt>\--astc-quality &lt;level&gt;</dt>
<dd>The quality level configures the quality-performance
tradeoff for the compressor; more complete searches of the
search space improve image quality at the expense of
compression time. Default is 'medium'. The quality level can be
set between fastest (0) and exhaustive (100) via the
following fixed quality presets:
<table>
<tr><th>Level </th> <th> Quality </th></tr>
<tr><td>fastest </td> <td>(equivalent to quality = 0) </td></tr>
<tr><td>fast </td> <td>(equivalent to quality = 10) </td></tr>
<tr><td>medium </td> <td>(equivalent to quality = 60) </td></tr>
<tr><td>thorough </td> <td>(equivalent to quality = 98) </td></tr>
<tr><td>exhaustive </td> <td>(equivalent to quality = 100) </td></tr>
</table>
</dd>
<dt>\--astc-perceptual</dt>
<dd>The codec should optimize for perceptual error, instead of
direct RMS error. This aims to improve perceived image quality,
but typically lowers the measured PSNR score. Perceptual
methods are currently only available for normal maps and RGB
color data.</dd>
</dl>
//! [command options_astc]
*/
struct OptionsASTC : public ktxAstcParams {
inline static const char* kAstcQuality = "astc-quality";
inline static const char* kAstcPerceptual = "astc-perceptual";

std::string astcOptions{};
bool encodeASTC = false;
ClampedOption<ktx_uint32_t> qualityLevel{ktxAstcParams::qualityLevel, 0, KTX_PACK_ASTC_QUALITY_LEVEL_MAX};

OptionsASTC() : ktxAstcParams() {
threadCount = std::thread::hardware_concurrency();
if (threadCount == 0)
threadCount = 1;
structSize = sizeof(ktxAstcParams);
normalMap = false;
for (int i = 0; i < 4; i++)
inputSwizzle[i] = 0;
qualityLevel.clear();
}

void init(cxxopts::Options& opts) {
opts.add_options("Encode ASTC")
(kAstcQuality,
"The quality level configures the quality-performance tradeoff for "
"the compressor; more complete searches of the search space "
"improve image quality at the expense of compression time. Default "
"is 'medium'. The quality level can be set between fastest (0) and "
"exhaustive (100) via the following fixed quality presets:\n\n"
" Level | Quality\n"
" ---------- | -----------------------------\n"
" fastest | (equivalent to quality = 0)\n"
" fast | (equivalent to quality = 10)\n"
" medium | (equivalent to quality = 60)\n"
" thorough | (equivalent to quality = 98)\n"
" exhaustive | (equivalent to quality = 100)",
cxxopts::value<std::string>(), "<level>")
(kAstcPerceptual,
"The codec should optimize for perceptual error, instead of direct "
"RMS error. This aims to improve perceived image quality, but "
"typically lowers the measured PSNR score. Perceptual methods are "
"currently only available for normal maps and RGB color data.");
}

void captureASTCOption(const char* name) {
astcOptions += fmt::format(" --{}", name);
}

template <typename T>
T captureASTCOption(cxxopts::ParseResult& args, const char* name) {
const T value = args[name].as<T>();
astcOptions += fmt::format(" --{} {}", name, value);
return value;
}

void process(cxxopts::Options&, cxxopts::ParseResult& args, Reporter& report) {
if (args[kAstcQuality].count()) {
static std::unordered_map<std::string, ktx_pack_astc_quality_levels_e> astc_quality_mapping{
{"fastest", KTX_PACK_ASTC_QUALITY_LEVEL_FASTEST},
{"fast", KTX_PACK_ASTC_QUALITY_LEVEL_FAST},
{"medium", KTX_PACK_ASTC_QUALITY_LEVEL_MEDIUM},
{"thorough", KTX_PACK_ASTC_QUALITY_LEVEL_THOROUGH},
{"exhaustive", KTX_PACK_ASTC_QUALITY_LEVEL_EXHAUSTIVE}
};
const auto qualityLevelStr = to_lower_copy(captureASTCOption<std::string>(args, kAstcQuality));
const auto it = astc_quality_mapping.find(qualityLevelStr);
if (it == astc_quality_mapping.end())
report.fatal_usage("Invalid astc-quality: \"{}\"", qualityLevelStr);
qualityLevel = it->second;
} else {
qualityLevel = KTX_PACK_ASTC_QUALITY_LEVEL_MEDIUM;
}

if (args[kAstcPerceptual].count()) {
captureASTCOption(kAstcPerceptual);
perceptual = KTX_TRUE;
}
}
};

} // namespace ktx
15 changes: 10 additions & 5 deletions tools/ktx/command_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <fmt/ostream.h>
#include <fmt/printf.h>
#include "ktx.h"
#include "astc_utils.h"
#include "image.hpp"
#include "imageio.h"

Expand Down Expand Up @@ -100,10 +101,11 @@ struct OptionsCreate {

void init(cxxopts::Options& opts) {
opts.add_options()
(kFormat, "KTX format enum that specifies the image data format."
(kFormat, "VkFormat enum that specifies the data format of the images in the output KTX file."
" The enum names are matching the VkFormats without the VK_FORMAT_ prefix."
" The VK_FORMAT_ prefix is ignored if present."
"\nWhen used with --encode it specifies the target format before the encoding step."
"\nWhen used with --encode it specifies the format of the texture object created as input to "
" the encoding step before the encoding step."
" In this case it must be one of:"
"\n R8_UNORM"
"\n R8_SRGB"
Expand Down Expand Up @@ -599,7 +601,7 @@ Create a KTX2 file from various input files.
The following are available:
<dl>
<dt>\--format &lt;enum&gt;</dt>
<dd>KTX format enum that specifies the data format of the images in the created texture.
<dd>VkFormat enum that specifies the data format of the images in the output KTX file.
The enum names are matching the VkFormats without the VK_FORMAT_ prefix.
The VK_FORMAT_ prefix is ignored if present. Case insensitive. Required.<br />
<br />
Expand All @@ -624,8 +626,11 @@ Create a KTX2 file from various input files.
<li>R8G8B8A8_UNORM</li>
<li>R8G8B8A8_SRGB</li>
</ul>
The format will be used to verify and load all input files into a texture before
performing any specified encoding.
If the format is an ASTC format the ASTC encoder specific options become valid,
otherwise they are ignored.<br />
The format will be used to verify and load all input files into a texture before encoding.<br />
Case insensitive. Required.</dd>
@snippet{doc} ktx/astc_utils.h command options_astc
</dd>
<dt>\--encode basis-lz | uastc</dt>
<dd>Encode the texture with the specified codec before saving it.
Expand Down
Loading
Loading