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
3 changes: 3 additions & 0 deletions include/ktx.h
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,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
312 changes: 311 additions & 1 deletion lib/astc_encode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ astcSwizzle(const ktxAstcParams &params) {

static void
astcBlockDimensions(ktx_uint32_t block_size,
uint32_t& block_x, uint32_t& block_y, uint32_t& block_z) {
uint32_t& block_x, uint32_t& block_y, uint32_t& block_z) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we have another tabs v. spaces thing here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a925f3f

switch (block_size) {
case KTX_PACK_ASTC_BLOCK_DIMENSION_4x4 : block_x = 4; block_y = 4; block_z = 1; break;
case KTX_PACK_ASTC_BLOCK_DIMENSION_5x4 : block_x = 5; block_y = 4; block_z = 1; break;
Expand Down Expand Up @@ -391,6 +391,87 @@ astcBlockDimensions(ktx_uint32_t block_size,
}
}

static void
astcBlockDimensions(VkFormat format,
uint32_t &x, uint32_t &y, uint32_t &z) noexcept {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a925f3f

switch (format) {
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: x = 4; y = 4; z = 0; break;
case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: x = 4; y = 4; z = 0; break;
case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: x = 5; y = 4; z = 0; break;
case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: x = 5; y = 4; z = 0; break;
case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: x = 5; y = 5; z = 0; break;
case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: x = 5; y = 5; z = 0; break;
case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: x = 6; y = 5; z = 0; break;
case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: x = 6; y = 5; z = 0; break;
case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: x = 6; y = 6; z = 0; break;
case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: x = 6; y = 6; z = 0; break;
case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: x = 8; y = 5; z = 0; break;
case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: x = 8; y = 5; z = 0; break;
case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: x = 8; y = 6; z = 0; break;
case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: x = 8; y = 6; z = 0; break;
case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: x = 8; y = 8; z = 0; break;
case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: x = 8; y = 8; z = 0; break;
case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: x = 10; y = 5; z = 0; break;
case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: x = 10; y = 5; z = 0; break;
case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: x = 10; y = 6; z = 0; break;
case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: x = 10; y = 6; z = 0; break;
case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: x = 10; y = 8; z = 0; break;
case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: x = 10; y = 8; z = 0; break;
case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: x = 10; y = 10; z = 0; break;
case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: x = 10; y = 10; z = 0; break;
case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: x = 12; y = 10; z = 0; break;
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: x = 12; y = 10; z = 0; break;
case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: x = 12; y = 12; z = 0; break;
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: x = 12; y = 12; z = 0; break;
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK: x = 4; y = 4; z = 0; break;
case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK: x = 5; y = 4; z = 0; break;
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK: x = 5; y = 5; z = 0; break;
case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK: x = 6; y = 5; z = 0; break;
case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK: x = 6; y = 6; z = 0; break;
case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK: x = 8; y = 5; z = 0; break;
case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK: x = 8; y = 6; z = 0; break;
case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK: x = 8; y = 8; z = 0; break;
case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK: x = 10; y = 5; z = 0; break;
case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK: x = 10; y = 6; z = 0; break;
case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK: x = 10; y = 8; z = 0; break;
case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK: x = 10; y = 10; z = 0; break;
case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK: x = 12; y = 10; z = 0; break;
case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK: x = 12; y = 12; z = 0; break;
case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT: x = 3; y = 3; z = 3; break;
case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT: x = 3; y = 3; z = 3; break;
case VK_FORMAT_ASTC_3x3x3_SFLOAT_BLOCK_EXT: x = 3; y = 3; z = 3; break;
case VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT: x = 4; y = 3; z = 3; break;
case VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT: x = 4; y = 3; z = 3; break;
case VK_FORMAT_ASTC_4x3x3_SFLOAT_BLOCK_EXT: x = 4; y = 3; z = 3; break;
case VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT: x = 4; y = 4; z = 3; break;
case VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT: x = 4; y = 4; z = 3; break;
case VK_FORMAT_ASTC_4x4x3_SFLOAT_BLOCK_EXT: x = 4; y = 4; z = 3; break;
case VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT: x = 4; y = 4; z = 4; break;
case VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT: x = 4; y = 4; z = 4; break;
case VK_FORMAT_ASTC_4x4x4_SFLOAT_BLOCK_EXT: x = 4; y = 4; z = 4; break;
case VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT: x = 5; y = 4; z = 4; break;
case VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT: x = 5; y = 4; z = 4; break;
case VK_FORMAT_ASTC_5x4x4_SFLOAT_BLOCK_EXT: x = 5; y = 4; z = 4; break;
case VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT: x = 5; y = 5; z = 4; break;
case VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT: x = 5; y = 5; z = 4; break;
case VK_FORMAT_ASTC_5x5x4_SFLOAT_BLOCK_EXT: x = 5; y = 5; z = 4; break;
case VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT: x = 5; y = 5; z = 5; break;
case VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT: x = 5; y = 5; z = 5; break;
case VK_FORMAT_ASTC_5x5x5_SFLOAT_BLOCK_EXT: x = 5; y = 5; z = 5; break;
case VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT: x = 6; y = 5; z = 5; break;
case VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT: x = 6; y = 5; z = 5; break;
case VK_FORMAT_ASTC_6x5x5_SFLOAT_BLOCK_EXT: x = 6; y = 5; z = 5; break;
case VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT: x = 6; y = 6; z = 5; break;
case VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT: x = 6; y = 6; z = 5; break;
case VK_FORMAT_ASTC_6x6x5_SFLOAT_BLOCK_EXT: x = 6; y = 6; z = 5; break;
case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT: x = 6; y = 6; z = 6; break;
case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT: x = 6; y = 6; z = 6; break;
case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT: x = 6; y = 6; z = 6; break;
default:
x = 0; y = 0; z = 0;
}
}

static float
astcQuality(ktx_uint32_t quality_level) {
switch (quality_level) {
Expand Down Expand Up @@ -803,3 +884,232 @@ ktxTexture2_CompressAstc(ktxTexture2* This, ktx_uint32_t quality) {

return ktxTexture2_CompressAstcEx(This, &params);
}

struct decompression_workload
{
astcenc_context* context;
uint8_t* data;
size_t data_len;
astcenc_image* image_out;
astcenc_swizzle swizzle;
astcenc_error error;
};

/**
* @brief Runner callback function for a decompression worker thread.
*
* @param thread_count The number of threads in the worker pool.
* @param thread_id The index of this thread in the worker pool.
* @param payload The parameters for this thread.
*/
static void decompression_workload_runner(int thread_count, int thread_id, void* payload) {
(void)thread_count;

decompression_workload* work = static_cast<decompression_workload*>(payload);
astcenc_error error = astcenc_decompress_image(work->context, work->data, work->data_len,
work->image_out, &work->swizzle, thread_id);
// This is a racy update, so which error gets returned is a random, but it
// will reliably report an error if an error occurs
if (error != ASTCENC_SUCCESS)
{
work->error = error;
}
}

/**
* @brief Decodes the provided ktx2 texture if its astc encoded
*
* @param This The texture to decode
* @param vkformat The decoding format to use
*/
// will update "This" with the uncompressed copy
KTX_API KTX_error_code KTX_APIENTRY
ktxTexture2_DecodeAstc(ktxTexture2 *This, ktx_uint32_t vkformat) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@MarkCallow In-case it didn't register, as you can see I have introduced this "Decode" method inside ktx.h and astc_encode.cpp this might sound a bit weird but I didn't think creating a seprate astc_decode.cpp file was worth it. If you don't agree please shout.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It did register but thanks for the added notice. Does the decoder share much code with what is already in astc_encode.cpp? If it does not it is probably better to create astc_decode.cpp. Maybe we can change command_extract.cpp to use it. On second thoughts maybe not. It only needs to decode the image(s) being extracted not the whole texture.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does reuse bits from astc_encode.cpp thats mainly why I put it there and some more decode specific bits I added too but more importantly it will be using bits from astc_encode.cpp for HDR stuff as well going forward.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Okay. Leave it in the same file. Let's rename the file to astc_codec.cpp.

// Decompress This using astc-encoder
uint32_t* BDB = This->pDfd + 1;
khr_df_model_e colorModel = (khr_df_model_e)KHR_DFDVAL(BDB, MODEL);
if (colorModel != KHR_DF_MODEL_ASTC && This->supercompressionScheme != KTX_SS_NONE) // No supercompression supported yet
{
return KTX_INVALID_OPERATION; // Not in valid astc decodable format
}

DECLARE_PRIVATE(priv, This);

uint32_t channelId = KHR_DFDSVAL(BDB, 0, CHANNELID);
if (channelId == KHR_DF_CHANNEL_ASTC_DATA) {
// Found astc data
}
else
return KTX_FILE_DATA_ERROR;

// Create a prototype texture to use for calculating sizes in the target
// format and, as useful side effects, provide us with a properly sized
// data allocation and the DFD for the target format.
ktxTextureCreateInfo createInfo;
createInfo.glInternalformat = 0;
createInfo.vkFormat = vkformat;
createInfo.baseWidth = This->baseWidth;
createInfo.baseHeight = This->baseHeight;
createInfo.baseDepth = This->baseDepth;
createInfo.generateMipmaps = This->generateMipmaps;
createInfo.isArray = This->isArray;
createInfo.numDimensions = This->numDimensions;
createInfo.numFaces = This->numFaces;
createInfo.numLayers = This->numLayers;
createInfo.numLevels = This->numLevels;
createInfo.pDfd = nullptr;

KTX_error_code result;
ktxTexture2* prototype;
result = ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &prototype);

if (result != KTX_SUCCESS) {
assert(result == KTX_OUT_OF_MEMORY); // The only run time error
return result;
}

if (!This->pData) {
if (ktxTexture_isActiveStream((ktxTexture*)This)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you can just call ktxTexture2_LoadImageData within the if (!This->pData) block. If there is no stream it will return KTX_INVALID_OPERATION. If the result is != KTX_SUCCESS then destroy the prototype and return the result.

// Load pending. Complete it.
result = ktxTexture2_LoadImageData(This, NULL, 0);
if (result != KTX_SUCCESS)
{
ktxTexture2_Destroy(prototype);
return result;
}
} else {
// No data to transcode.
ktxTexture2_Destroy(prototype);
return KTX_INVALID_OPERATION;
}
}

// This is where I do the decompression from "This" to prototype target
astcenc_profile profile{ASTCENC_PRF_LDR_SRGB};
astcenc_swizzle swizzle{ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A};

uint32_t block_size_x{4}; // Get the right blocks from vkformat
uint32_t block_size_y{4};
uint32_t block_size_z{1};
float quality{ASTCENC_PRE_MEDIUM};
uint32_t flags{0}; // TODO: Use normals mode to reconstruct normals params->normalMap ? ASTCENC_FLG_MAP_NORMAL : 0};

astcBlockDimensions((VkFormat)vkformat, block_size_x, block_size_y, block_size_z);

// quality = astcQuality(params->qualityLevel);
// profile = astcEncoderAction(*params, BDB);
// swizzle = astcSwizzle(*params);

// if(params->perceptual) flags |= ASTCENC_FLG_USE_PERCEPTUAL;

uint32_t threadCount{1}; // Decompression isn't the bottlneck and only used when checking for psnr and ssim
Copy link
Collaborator

Choose a reason for hiding this comment

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

Another tab vs space thing?

Copy link
Contributor Author

@wasimabbas-arm wasimabbas-arm Dec 9, 2023

Choose a reason for hiding this comment

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

This is very annoying. I have https://www.emacswiki.org/emacs/SmartTabs on, as we spoke about it before as well. I still think this is the best way to indent code but it needs to be done for the whole project. We spoke about this before doing such indentation via clang-format. I created #545 PR. It was closed without any conlcusion though.

For now I have added a pre-commit git-hook for myself. Maybe if the repo won't accept commits a githook should be installed for users.

#!/bin/sh

# Reject commits that adds tabs

if git diff --cached | egrep '^\+.*\t'>/dev/null; then
    echo "Can't commit due to introduction of tabs in the following lines"
    git diff --cached | egrep '^\+.*\t'
  exit 1
fi

Copy link
Collaborator

Choose a reason for hiding this comment

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

Replying just to this for now. Will look over the other changes later.

I closed #545 because there had been many changes to the code you'd opened. Since then Khronos has contracted with RasterGrid to set up something clang-format based to ensure uniform code style. That work has not yet started.

Until then the pre-commit hook seems like a good idea.

astcenc_config astc_config;
astcenc_context *astc_context;
astcenc_error astc_error = astcenc_config_init(profile,
block_size_x, block_size_y, block_size_z,
quality, flags,
&astc_config);

if (astc_error != ASTCENC_SUCCESS)
return KTX_INVALID_OPERATION;

astc_error = astcenc_context_alloc(&astc_config, threadCount, &astc_context);

if (astc_error != ASTCENC_SUCCESS)
return KTX_INVALID_OPERATION;

decompression_workload work;
work.context = astc_context;
work.swizzle = swizzle;
work.error = ASTCENC_SUCCESS;

for (uint32_t levelIndex = 0; levelIndex < This->numLevels; ++levelIndex) {
const uint32_t imageWidth = std::max(This->baseWidth >> levelIndex, 1u);
const uint32_t imageHeight = std::max(This->baseHeight >> levelIndex, 1u);
const uint32_t imageDepths = std::max(This->baseDepth >> levelIndex, 1u);

for (uint32_t layerIndex = 0; layerIndex < This->numLayers; ++layerIndex) {
for (uint32_t faceIndex = 0; faceIndex < This->numFaces; ++faceIndex) {
for (uint32_t depthSliceIndex = 0; depthSliceIndex < imageDepths; ++depthSliceIndex) {

ktx_size_t levelImageSizeIn = ktxTexture_calcImageSize(ktxTexture(This), levelIndex, KTX_FORMAT_VERSION_TWO);

ktx_size_t imageOffsetIn;
ktx_size_t imageOffsetOut;

ktxTexture2_GetImageOffset(This, levelIndex, layerIndex, faceIndex + depthSliceIndex, &imageOffsetIn);
ktxTexture2_GetImageOffset(prototype, levelIndex, layerIndex, faceIndex + depthSliceIndex, &imageOffsetOut);

auto* imageDataIn = This->pData + imageOffsetIn;
auto* imageDataOut = prototype->pData + imageOffsetOut;

astcenc_image imageOut;
imageOut.dim_x = imageWidth;
imageOut.dim_y = imageHeight;
imageOut.dim_z = imageDepths;
imageOut.data_type = ASTCENC_TYPE_U8; // TODO: Fix for HDR types
imageOut.data = (void**)&imageDataOut; // TODO: Fix for HDR types

work.data = imageDataIn;
work.data_len = levelImageSizeIn;
work.image_out = &imageOut;

// Only launch worker threads for multi-threaded use - it makes basic
// single-threaded profiling and debugging a little less convoluted
if (threadCount > 1) {
launchThreads(threadCount, decompression_workload_runner, &work);
} else {
work.error = astcenc_decompress_image(work.context, work.data, work.data_len,
work.image_out, &work.swizzle, 0);
}

// Reset ASTC context for next image
astcenc_decompress_reset(astc_context);

if (work.error != ASTCENC_SUCCESS) {
std::cout << "ASTC decompressor failed\n" << astcenc_get_error_string(work.error) << std::endl;

astcenc_context_free(astc_context);
return KTX_INVALID_OPERATION;
}
}
}
}
}

// We are done with astcencoder
Copy link
Collaborator

Choose a reason for hiding this comment

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

decoder?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a925f3f

astcenc_context_free(astc_context);

if (result == KTX_SUCCESS) {
// Fix up the current texture
DECLARE_PROTECTED(thisPrtctd, This);
DECLARE_PRIVATE(protoPriv, prototype);
DECLARE_PROTECTED(protoPrtctd, prototype);
memcpy(&thisPrtctd._formatSize, &protoPrtctd._formatSize,
sizeof(ktxFormatSize));
This->vkFormat = vkformat;
This->isCompressed = prototype->isCompressed;
This->supercompressionScheme = KTX_SS_NONE;
priv._requiredLevelAlignment = protoPriv._requiredLevelAlignment;
// Copy the levelIndex from the prototype to This.
memcpy(priv._levelIndex, protoPriv._levelIndex,
This->numLevels * sizeof(ktxLevelIndexEntry));
// Move the DFD and data from the prototype to This.
free(This->pDfd);
This->pDfd = prototype->pDfd;
prototype->pDfd = 0;
free(This->pData);
This->pData = prototype->pData;
This->dataSize = prototype->dataSize;
prototype->pData = 0;
prototype->dataSize = 0;
// Free SGD data
This->_private->_sgdByteLength = 0;
if (This->_private->_supercompressionGlobalData) {
free(This->_private->_supercompressionGlobalData);
This->_private->_supercompressionGlobalData = NULL;
}
}
ktxTexture2_Destroy(prototype);
return result;
}
6 changes: 3 additions & 3 deletions tools/ktx/command_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ struct OptionsCreate {

void init(cxxopts::Options& opts) {
opts.add_options()
(kFormat, "KTX format enum that specifies the image data format."
(kFormat, "The data format of the images in the output KTX file."
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/The/VkFormat enum that specifies the/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a925f3f

" 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 format of the input files before the encoding step."
Copy link
Collaborator

@MarkCallow MarkCallow Dec 5, 2023

Choose a reason for hiding this comment

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

s/input files/texture object created as input to the encoding step/

For this and the previous comment, also change the Doxygen docs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a925f3f

Expand Down Expand Up @@ -582,7 +582,7 @@ Create a KTX2 file from various input files.
The following options are available:
<dl>
<dt>\--format &lt;enum&gt;</dt>
<dd>KTX format enum that specifies the image data format.
<dd>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.<br />
When used with --encode it specifies the format of the input files before the encoding step.
Expand All @@ -601,7 +601,7 @@ Create a KTX2 file from various input files.
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
@snippet{doc} ktx/astc_utils.h command options_astc
<dt>\--1d</dt>
<dd>Create a 1D texture. If not set the texture will be a 2D or 3D texture.</dd>
<dt>\--cubemap</dt>
Expand Down
Loading
Loading