Add ktx
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# Copyright 2017-2020 The Khronos Group Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_executable( transcodetests
|
||||
transcodetests.cc
|
||||
../tests.cmake
|
||||
)
|
||||
set_test_properties(transcodetests)
|
||||
set_code_sign(transcodetests)
|
||||
|
||||
target_include_directories(
|
||||
transcodetests
|
||||
PRIVATE
|
||||
${PROJECT_SOURCE_DIR}/lib
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
transcodetests
|
||||
gtest
|
||||
ktx
|
||||
obj_basisu_cbind
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
|
||||
target_compile_definitions(
|
||||
transcodetests
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:ktx,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
|
||||
target_compile_features(transcodetests PUBLIC cxx_std_11)
|
||||
|
||||
gtest_discover_tests( transcodetests
|
||||
TEST_PREFIX transcodetest.
|
||||
# With the 5s default we get periodic timeouts on Travis & GitHub CI.
|
||||
DISCOVERY_TIMEOUT 15
|
||||
EXTRA_ARGS "${PROJECT_SOURCE_DIR}/tests/testimages/"
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_compile_definitions(
|
||||
transcodetests
|
||||
PRIVATE
|
||||
$<$<STREQUAL:"${BASISU_CBIND_LIBTYPE}","STATIC">:KHRONOS_STATIC>
|
||||
)
|
||||
|
||||
# Retrieve and set warning settings for the 2 files from the ktx target.
|
||||
# See comment in ../../CMakeLists.txt around line 625.
|
||||
if (transcoder_options)
|
||||
set_source_files_properties(
|
||||
"${PROJECT_SOURCE_DIR}/external/basisu/transcoder/basisu_transcoder.cpp"
|
||||
PROPERTIES COMPILE_OPTIONS "${transcoder_options}"
|
||||
)
|
||||
endif()
|
||||
if (zstd_options)
|
||||
set_source_files_properties(
|
||||
"${PROJECT_SOURCE_DIR}/external/basisu/zstd/zstd.c"
|
||||
PROPERTIES COMPILE_OPTIONS "${zstd_options}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# The Windows ktx.dll does not export needed symbols. This is a workaround to get it linking.
|
||||
add_library(obj_tmp_basisu OBJECT
|
||||
$<$<BOOL:${BUILD_SHARED_LIBS}>:${PROJECT_SOURCE_DIR}/external/basisu/transcoder/basisu_transcoder.cpp>
|
||||
"${PROJECT_SOURCE_DIR}/external/basisu/zstd/zstd.c"
|
||||
)
|
||||
target_compile_definitions(
|
||||
obj_tmp_basisu
|
||||
PUBLIC # only for basisu_c_binding.
|
||||
BASISU_NO_ITERATOR_DEBUG_LEVEL
|
||||
)
|
||||
target_link_libraries(transcodetests obj_tmp_basisu)
|
||||
endif()
|
||||
@@ -0,0 +1,243 @@
|
||||
// Copyright 2019 Andreas Atteneder, All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define OS_SEP '\\'
|
||||
#define UNIX_SEP '/'
|
||||
#else
|
||||
#define OS_SEP '/'
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "gl_format.h"
|
||||
#include "ktx.h"
|
||||
extern "C" {
|
||||
#include "ktxint.h"
|
||||
#include "filestream.h"
|
||||
#include "memstream.h"
|
||||
}
|
||||
#include "gtest/gtest.h"
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#include "basisu_c_binding.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string image_path;
|
||||
|
||||
namespace {
|
||||
|
||||
typedef struct {
|
||||
string ktxPath;
|
||||
string basisuPath;
|
||||
bool isPo2;
|
||||
bool hasAlpha;
|
||||
} TextureSet;
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const TextureSet& h)
|
||||
{
|
||||
return out << h.ktxPath;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
ktx_transcode_fmt_e format;
|
||||
bool supportsNonPo2;
|
||||
bool supportsNonAlpha;
|
||||
} FormatFeature;
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const FormatFeature& h)
|
||||
{
|
||||
return out << ktxTranscodeFormatString(h.format);
|
||||
}
|
||||
|
||||
vector<TextureSet> allTextureSets = {
|
||||
{"color_grid_basis.ktx2","color_grid.basis",true,false},
|
||||
#if 1
|
||||
{"kodim17_basis.ktx2","kodim17.basis",false,false},
|
||||
{"alpha_simple_basis.ktx2","alpha_simple.basis",true,true}
|
||||
#endif
|
||||
};
|
||||
|
||||
vector<FormatFeature> allFormats = {
|
||||
#if 1
|
||||
{KTX_TTF_ETC1_RGB,true,true},
|
||||
{KTX_TTF_ETC2_RGBA,true,true},
|
||||
{KTX_TTF_BC1_RGB,true,true},
|
||||
{KTX_TTF_BC3_RGBA,true,true},
|
||||
{KTX_TTF_BC4_R,true,true},
|
||||
{KTX_TTF_BC5_RG,true,true},
|
||||
{KTX_TTF_BC7_RGBA,true,true},
|
||||
{KTX_TTF_PVRTC1_4_RGB,false,true},
|
||||
{KTX_TTF_PVRTC1_4_RGBA,false,false},
|
||||
{KTX_TTF_ASTC_4x4_RGBA,true,true},
|
||||
{KTX_TTF_PVRTC2_4_RGB,true,true},
|
||||
{KTX_TTF_PVRTC2_4_RGBA,true,true},
|
||||
// {KTX_TTF_ETC2_EAC_R11,true,true},
|
||||
{KTX_TTF_ETC2_EAC_RG11,true,true},
|
||||
{KTX_TTF_RGBA32,true,true},
|
||||
{KTX_TTF_RGB565,true,true},
|
||||
{KTX_TTF_BGR565,true,true},
|
||||
#endif
|
||||
{KTX_TTF_RGBA4444,true,true}
|
||||
// ATC and FXT1 formats are not supported by KTX2 as there
|
||||
// are no equivalent VkFormats.
|
||||
};
|
||||
|
||||
class TextureCombinationsTest :
|
||||
public ::testing::TestWithParam<tuple<TextureSet,FormatFeature>> {};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(AllCombinations,
|
||||
TextureCombinationsTest,
|
||||
::testing::Combine(::testing::ValuesIn(allTextureSets),
|
||||
::testing::ValuesIn(allFormats)));
|
||||
|
||||
bool read_file( string path, void** data, unsigned long *fsize ) {
|
||||
FILE *f = fopen(path.data(),"rb");
|
||||
if(f==NULL) {
|
||||
return false;
|
||||
}
|
||||
fseek(f, 0, SEEK_END);
|
||||
*fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET); /* same as rewind(f); */
|
||||
|
||||
*data = malloc(*fsize);
|
||||
size_t numRead = fread(*data, 1, *fsize, f);
|
||||
fclose(f);
|
||||
return numRead == *fsize;
|
||||
}
|
||||
|
||||
bool isPo2(uint32_t i) {
|
||||
return (i&(i-1))==0;
|
||||
}
|
||||
|
||||
string combine_paths(string const a, string const b) {
|
||||
if (a.back() == OS_SEP) {
|
||||
return a + b;
|
||||
#if defined(_WIN32)
|
||||
} else if (a.back() == UNIX_SEP) {
|
||||
return a + b;
|
||||
#endif
|
||||
} else {
|
||||
return a+OS_SEP+b;
|
||||
}
|
||||
}
|
||||
|
||||
void test_texture_set( TextureSet & textureSet, FormatFeature & format ) {
|
||||
|
||||
void * basisData = nullptr;
|
||||
unsigned long basisSize = 0;
|
||||
|
||||
string path = combine_paths(image_path,textureSet.basisuPath);
|
||||
bool read_success = read_file(path, &basisData, &basisSize);
|
||||
|
||||
ASSERT_TRUE(read_success) << "Could not open or read texture file " << path;
|
||||
|
||||
basis_file basisu;
|
||||
|
||||
basisu.open((uint8_t*)basisData, (uint32_t)basisSize);
|
||||
uint32_t bWidth = basisu.getImageWidth(0,0);
|
||||
uint32_t bHeight = basisu.getImageHeight(0,0);
|
||||
|
||||
bool hasAlpha = basisu.getHasAlpha() > 0;
|
||||
|
||||
ASSERT_EQ(hasAlpha,textureSet.hasAlpha);
|
||||
|
||||
if( !hasAlpha && !format.supportsNonAlpha ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(isPo2(bWidth) && isPo2(bHeight))
|
||||
&& !format.supportsNonPo2 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t finalSize = basisu.getImageTranscodedSizeInBytes(0,0,format.format);
|
||||
ktx_uint8_t* basisTranscodedData = (ktx_uint8_t*) malloc(finalSize);
|
||||
basisu.startTranscoding();
|
||||
uint32_t bRes = basisu.transcodeImage((void*)basisTranscodedData,finalSize,0,0,format.format,0,0);
|
||||
|
||||
ASSERT_TRUE(bRes);
|
||||
|
||||
basisu.close();
|
||||
|
||||
void * data = 0; // = 0 to silence over-enthusiastic gcc 11 warning.
|
||||
unsigned long fsize;
|
||||
|
||||
path = combine_paths(image_path,textureSet.ktxPath);
|
||||
read_success = read_file(path, &data, &fsize);
|
||||
|
||||
ASSERT_TRUE(read_success) << "Could not open texture file " << path;
|
||||
|
||||
KTX_error_code result;
|
||||
|
||||
ktxTexture2* newTex = 0;
|
||||
|
||||
result = ktxTexture2_CreateFromMemory(
|
||||
(const ktx_uint8_t*) data,
|
||||
(ktx_size_t) fsize,
|
||||
KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
|
||||
(ktxTexture2**)&newTex
|
||||
);
|
||||
|
||||
ASSERT_EQ(result,KTX_SUCCESS);
|
||||
|
||||
result = ktxTexture2_TranscodeBasis(
|
||||
newTex,
|
||||
format.format,
|
||||
0
|
||||
);
|
||||
ASSERT_EQ(result,KTX_SUCCESS) << "Format " << format.format;
|
||||
|
||||
EXPECT_EQ(bWidth,newTex->baseWidth);
|
||||
EXPECT_EQ(bHeight,newTex->baseHeight);
|
||||
EXPECT_EQ(finalSize,newTex->dataSize);
|
||||
|
||||
int cmp = std::memcmp(basisTranscodedData,newTex->pData,finalSize);
|
||||
|
||||
ASSERT_EQ(cmp,0);
|
||||
|
||||
ktxTexture_Destroy(ktxTexture(newTex));
|
||||
|
||||
free(data);
|
||||
free(basisTranscodedData);
|
||||
|
||||
free(basisData);
|
||||
}
|
||||
|
||||
TEST_P(TextureCombinationsTest, Basic) {
|
||||
TextureSet ts = get<0>(GetParam());
|
||||
FormatFeature format = get<1>(GetParam());
|
||||
test_texture_set(ts,format);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
if(!::testing::FLAGS_gtest_list_tests) {
|
||||
if(argc!=2) {
|
||||
cerr << "Usage: " << argv[0] << " <test images path>\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
image_path = string(argv[1]);
|
||||
|
||||
struct stat info;
|
||||
|
||||
if( stat( image_path.data(), &info ) != 0 ) {
|
||||
cerr << "Cannot access " << image_path << '\n';
|
||||
return -2;
|
||||
} else if( ! (info.st_mode & S_IFDIR) ) {
|
||||
cerr << image_path << "is not a valid directory\n";
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
ktx_basisu_basis_init();
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user