Skip to content

Commit

Permalink
Support array and 3d textures. (#468)
Browse files Browse the repository at this point in the history
* Fix array & 3d texture creation.
* Disable mipmap generation for 3d textures as they need completely different resampling code.
* Add tests.
* Fix ktxTexture2_SetImageFromStream's failure to check the return value of ktxTexture_GetImageOffset.

Co-authored-by: unknown <[email protected]>
  • Loading branch information
MarkCallow and tuket authored Aug 15, 2021
1 parent 4eca0ef commit b053253
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 24 deletions.
9 changes: 7 additions & 2 deletions lib/writer2.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,20 @@ ktxTexture2_setImageFromStream(ktxTexture2* This, ktx_uint32_t level,
{
ktx_size_t imageByteLength;
ktx_size_t imageByteOffset;
ktx_error_code_e result;

if (!This || !src)
return KTX_INVALID_VALUE;

if (!This->pData)
return KTX_INVALID_OPERATION;

ktxTexture_GetImageOffset(ktxTexture(This), level, layer, faceSlice,
&imageByteOffset);
result = ktxTexture_GetImageOffset(ktxTexture(This),
level, layer, faceSlice,
&imageByteOffset);
if (result != KTX_SUCCESS)
return result;

imageByteLength = ktxTexture_GetImageSize(ktxTexture(This), level);

if (srcSize != imageByteLength)
Expand Down
3 changes: 3 additions & 0 deletions tests/srcimages/blue16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/srcimages/green16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/srcimages/indigo16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/srcimages/orange16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/srcimages/red16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/srcimages/violet16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/srcimages/yellow16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/testimages/3dtex_7_reference_u.ktx2
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/testimages/arraytex_7_mipmap_reference_u.ktx2
Git LFS file not shown
3 changes: 3 additions & 0 deletions tests/testimages/arraytex_7_reference_u.ktx2
Git LFS file not shown
6 changes: 5 additions & 1 deletion tests/testimages/genref
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,8 @@ $toktx --test --encode astc --astc_blk_d 8x6 astc_ldr_8x6_FlightHelmet_baseCo
$toktx --test --encode astc --astc_blk_d 10x5 astc_ldr_10x5_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png
$toktx --test --encode astc --astc_blk_d 8x8 astc_ldr_8x8_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png
$toktx --test --encode astc --astc_blk_d 12x10 astc_ldr_12x10_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png
$toktx --test --encode astc --astc_blk_d 12x12 astc_ldr_12x12_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png
$toktx --test --encode astc --astc_blk_d 12x12 astc_ldr_12x12_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png

$toktx --test --layers 7 --t2 arraytex_7_reference_u.ktx2 ../srcimages/red16.png ../srcimages/orange16.png ../srcimages/yellow16.png ../srcimages/green16.png ../srcimages/blue16.png ../srcimages/indigo16.png ../srcimages/violet16.png
$toktx --test --depth 7 --t2 3dtex_7_reference_u.ktx2 ../srcimages/red16.png ../srcimages/orange16.png ../srcimages/yellow16.png ../srcimages/green16.png ../srcimages/blue16.png ../srcimages/indigo16.png ../srcimages/violet16.png
$toktx --test --layers 7 --genmipmap --t2 arraytex_7_mipmap_reference_u.ktx2 ../srcimages/red16.png ../srcimages/orange16.png ../srcimages/yellow16.png ../srcimages/green16.png ../srcimages/blue16.png ../srcimages/indigo16.png ../srcimages/violet16.png
15 changes: 14 additions & 1 deletion tests/toktx-tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ add_test( NAME toktx-different-colortype-second-file-warning
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/testimages
)

add_test( NAME toktx-depth-layers
COMMAND toktx --depth 4 --layers 4 a b c d e
)

add_test( NAME toktx-depth-genmipmap
COMMAND toktx --test --depth 7 --genmipmap --t2 3dtex_7_mipmap_reference_u.ktx2 ../srcimages/red16.png ../srcimages/orange16.png ../srcimages/yellow16.png ../srcimages/green16.png ../srcimages/blue16.png ../srcimages/indigo16.png ../srcimages/violet16.png
)

set_tests_properties(
toktx-test-foobar
toktx-automipmap-mipmaps
Expand All @@ -98,6 +106,8 @@ set_tests_properties(
toktx-invalid-swizzle-char
toktx-invalid-target-type
toktx-different-colortype-second-file-error
toktx-depth-layers
toktx-depth-genmipmap
PROPERTIES
WILL_FAIL TRUE
)
Expand Down Expand Up @@ -227,4 +237,7 @@ gencmpktx( astc_ldr_8x6_FlightHelmet_baseColor astc_ldr_8x6_FlightHelmet_base
gencmpktx( astc_ldr_10x5_FlightHelmet_baseColor astc_ldr_10x5_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png "--test --encode astc --astc_blk_d 10x5" "" "")
gencmpktx( astc_ldr_8x8_FlightHelmet_baseColor astc_ldr_8x8_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png "--test --encode astc --astc_blk_d 8x8" "" "")
gencmpktx( astc_ldr_12x10_FlightHelmet_baseColor astc_ldr_12x10_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png "--test --encode astc --astc_blk_d 12x10" "" "")
gencmpktx( astc_ldr_12x12_FlightHelmet_baseColor astc_ldr_12x12_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png "--test --encode astc --astc_blk_d 12x12" "" "")
gencmpktx( astc_ldr_12x12_FlightHelmet_baseColor astc_ldr_12x12_FlightHelmet_baseColor.ktx2 ../srcimages/FlightHelmet_baseColor.png "--test --encode astc --astc_blk_d 12x12" "" "")
gencmpktx( 3dtex_7_reference_u 3dtex_7_reference_u.ktx2 ../srcimages/red16.png ../srcimages/orange16.png ../srcimages/yellow16.png ../srcimages/green16.png ../srcimages/blue16.png ../srcimages/indigo16.png ../srcimages/violet16.png "--test --t2 --depth 7" "" "")
gencmpktx( arraytex_7_reference_u arraytex_7_reference_u.ktx2 ../srcimages/red16.png ../srcimages/orange16.png ../srcimages/yellow16.png ../srcimages/green16.png ../srcimages/blue16.png ../srcimages/indigo16.png ../srcimages/violet16.png "--test --t2 --layers 7" "" "")
gencmpktx( arraytex_7_mipmap_reference_u arraytex_7_mipmap_reference_u.ktx2 ../srcimages/red16.png ../srcimages/orange16.png ../srcimages/yellow16.png ../srcimages/green16.png ../srcimages/blue16.png ../srcimages/indigo16.png ../srcimages/violet16.png "--test --t2 --layers 7 --genmipmap" "" "")
73 changes: 53 additions & 20 deletions tools/toktx/toktx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -717,9 +717,8 @@ toktxApp::main(int argc, _TCHAR *argv[])
else
createInfo.numFaces = 1;

// TO DO: handle array textures
createInfo.numLayers = options.layers;
createInfo.isArray = KTX_FALSE;
createInfo.isArray = options.layers > 1;

// TO DO: handle 3D textures.

Expand Down Expand Up @@ -1089,7 +1088,11 @@ toktxApp::main(int argc, _TCHAR *argv[])
createInfo.baseWidth = levelWidth = image->getWidth();
createInfo.baseHeight = levelHeight = image->getHeight();
createInfo.baseDepth = levelDepth = options.depth;
if (image->getHeight() == 1 && !options.two_d)
if (options.depth > 1) {
// In this case, don't care about image->getHeight(). Images are
// always considered to be 2d. No need to set options.two_d.
createInfo.numDimensions = 3;
} else if (image->getHeight() == 1 && !options.two_d)
createInfo.numDimensions = 1;
else
createInfo.numDimensions = 2;
Expand Down Expand Up @@ -1172,6 +1175,7 @@ toktxApp::main(int argc, _TCHAR *argv[])
level = 0;
levelWidth = createInfo.baseWidth;
levelHeight = createInfo.baseHeight;
levelDepth = createInfo.baseDepth;
if (faceSlice == (options.cubemap ? 6 : levelDepth)) {
faceSlice = 0;
layer++;
Expand All @@ -1198,12 +1202,19 @@ toktxApp::main(int argc, _TCHAR *argv[])
cout << ", imageSize = " << imageSize << endl;
}
#endif
ktxTexture_SetImageFromMemory(ktxTexture(texture),
level,
layer,
faceSlice,
*image,
image->getByteCount());
ret = ktxTexture_SetImageFromMemory(ktxTexture(texture),
level,
layer,
faceSlice,
*image,
image->getByteCount());
// Only an error in this program could lead to ret != SUCCESS
// hence no user message.
assert(ret == KTX_SUCCESS);

// This does not work for mipmaps for 3d textures. For those it is
// necessary to present the base images for each slice to a
// resampler that can sample across images.
if (options.genmipmap) {
for (uint32_t glevel = 1; glevel < createInfo.numLevels; glevel++)
{
Expand All @@ -1230,12 +1241,13 @@ toktxApp::main(int argc, _TCHAR *argv[])
//if (options.gmopts.mipRenormalize)
// levelImage->renormalize_normal_map();

ktxTexture_SetImageFromMemory(ktxTexture(texture),
ret = ktxTexture_SetImageFromMemory(ktxTexture(texture),
glevel,
layer,
faceSlice,
*levelImage,
levelImage->getByteCount());
assert(ret == KTX_SUCCESS);
delete levelImage;
}
}
Expand All @@ -1255,21 +1267,36 @@ toktxApp::main(int argc, _TCHAR *argv[])

/*
* Add orientation metadata.
* Note: 1D textures and 2D textures with a height of 1 don't need
* orientation metadata
*/
if (options.metadata && createInfo.baseHeight > 1) {
if (options.metadata) {
ktxHashList* ht = &texture->kvDataHead;
char orientation[10];
char orientation[20];
if (options.ktx2) {
orientation[0] = 'r';
orientation[1] = options.lower_left_maps_to_s0t0 ? 'u' : 'd';
orientation[2] = 0;
if (createInfo.baseHeight > 1) {
orientation[1] = options.lower_left_maps_to_s0t0 ? 'u' : 'd';
if (createInfo.baseDepth > 1) {
orientation[2] = options.lower_left_maps_to_s0t0
? 'o' : 'i';
}
else {
orientation[2] = 0;
}
} else {
orientation[1] = 0;
}
} else {
assert(strlen(KTX_ORIENTATION2_FMT) < sizeof(orientation));

snprintf(orientation, sizeof(orientation), KTX_ORIENTATION2_FMT,
'r', options.lower_left_maps_to_s0t0 ? 'u' : 'd');
assert(strlen(KTX_ORIENTATION3_FMT) < sizeof(orientation));
if (createInfo.baseHeight == 1) {
snprintf(orientation, sizeof(orientation), KTX_ORIENTATION1_FMT,
'r');
} else if (createInfo.baseDepth == 1) {
snprintf(orientation, sizeof(orientation), KTX_ORIENTATION2_FMT,
'r', options.lower_left_maps_to_s0t0 ? 'u' : 'd');
} else
snprintf(orientation, sizeof(orientation), KTX_ORIENTATION3_FMT,
'r', options.lower_left_maps_to_s0t0 ? 'u' : 'd',
options.lower_left_maps_to_s0t0 ? 'o' : 'i');
}
ktxHashList_AddKVPair(ht, KTX_ORIENTATION_KEY,
(unsigned int)strlen(orientation) + 1,
Expand Down Expand Up @@ -1467,6 +1494,12 @@ toktxApp::validateOptions()
exit(1);
}

if (options.depth > 1 && options.genmipmap) {
error("generation of mipmaps for 3d textures is not supported.\n"
"A PR to add this feature will be gratefully accepted!");
exit(1);
}

if (options.outfile.compare(_T("-")) != 0
&& options.outfile.find_last_of('.') == _tstring::npos)
{
Expand Down

0 comments on commit b053253

Please sign in to comment.