Add GECompressorASTC4x4
This commit is contained in:
parent
93dc6ed770
commit
d7390a1824
1
.gitignore
vendored
1
.gitignore
vendored
@ -89,5 +89,6 @@ lib/openssl
|
||||
lib/harfbuzz
|
||||
lib/sdl2
|
||||
lib/mbedtls
|
||||
lib/astc-encoder
|
||||
|
||||
.DS_Store
|
||||
|
@ -59,6 +59,8 @@ set(LIBSAMPLERATE_LIBRARY ${PROJECT_SOURCE_DIR}/dependencies\${EFFECTIVE_PLATFOR
|
||||
set(LIBSAMPLERATE_INCLUDEDIR ${PROJECT_SOURCE_DIR}/dependencies-iphoneos/include CACHE STRING "")
|
||||
set(MOLTENVK_LIBRARY ${PROJECT_SOURCE_DIR}/dependencies\${EFFECTIVE_PLATFORM_NAME}/lib/libMoltenVK.a CACHE STRING "")
|
||||
set(VULKAN_INCLUDEDIR ${PROJECT_SOURCE_DIR}/dependencies-iphoneos/include CACHE STRING "")
|
||||
set(LIBASTCENC_LIBRARY ${PROJECT_SOURCE_DIR}/dependencies\${EFFECTIVE_PLATFORM_NAME}/lib/libastcenc.a CACHE STRING "")
|
||||
set(LIBASTCENC_INCLUDEDIR ${PROJECT_SOURCE_DIR}/dependencies-iphoneos/include CACHE STRING "")
|
||||
|
||||
# For universal iOS and simulator
|
||||
set(LIBRESOLV_LIBRARY -lresolv CACHE STRING "")
|
||||
|
@ -1,3 +1,42 @@
|
||||
# Distro package just use libastcenc.so, find it first
|
||||
find_library(LIBASTCENC_LIBRARY NAMES libastcenc astcenc astcenc-avx2-static astcenc-sse4.1-static astcenc-sse2-static astcenc-neon-static astcenc-native-static)
|
||||
find_path(LIBASTCENC_INCLUDEDIR NAMES astcenc.h PATHS)
|
||||
if (LIBASTCENC_LIBRARY AND LIBASTCENC_INCLUDEDIR)
|
||||
set(ENABLE_LIBASTCENC 1)
|
||||
add_definitions(-DENABLE_LIBASTCENC)
|
||||
include_directories("${LIBASTCENC_INCLUDEDIR}")
|
||||
message(STATUS "Use libastcenc: ${LIBASTCENC_LIBRARY}")
|
||||
|
||||
if (NOT MSVC)
|
||||
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_INCLUDES ${LIBASTCENC_INCLUDEDIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${LIBASTCENC_LIBRARY})
|
||||
include(CheckCXXSourceCompiles)
|
||||
check_cxx_source_compiles("
|
||||
#define ASTCENC_DYNAMIC_LIBRARY 1
|
||||
#include <astcenc.h>
|
||||
int main()
|
||||
{
|
||||
astcenc_context_free(NULL);
|
||||
return 0;
|
||||
}
|
||||
" ASTCENC_DLL)
|
||||
if (NOT MSVC)
|
||||
unset(CMAKE_REQUIRED_FLAGS)
|
||||
endif()
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
if (ASTCENC_DLL)
|
||||
message(STATUS "libastcenc: -DASTCENC_DYNAMIC_LIBRARY required")
|
||||
add_definitions(-DASTCENC_DYNAMIC_LIBRARY)
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(WARNING "Missing astc-encoder for astc support, "
|
||||
"visit https://github.com/ARM-software/astc-encoder for details")
|
||||
endif()
|
||||
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/graphics_engine/include")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/graphics_utils")
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib/irrlicht/include")
|
||||
@ -24,6 +63,7 @@ endif()
|
||||
|
||||
set(GE_SOURCES
|
||||
src/gl.c
|
||||
src/ge_compressor_astc_4x4.cpp
|
||||
src/ge_compressor_s3tc_bc3.cpp
|
||||
src/ge_culling_tool.cpp
|
||||
src/ge_dx9_texture.cpp
|
||||
@ -58,3 +98,7 @@ endif()
|
||||
add_library(graphics_engine STATIC ${GE_SOURCES})
|
||||
|
||||
target_link_libraries(graphics_engine ${SQUISH_LIBRARY})
|
||||
|
||||
if(ENABLE_LIBASTCENC)
|
||||
target_link_libraries(graphics_engine ${LIBASTCENC_LIBRARY})
|
||||
endif()
|
||||
|
134
lib/graphics_engine/src/ge_compressor_astc_4x4.cpp
Normal file
134
lib/graphics_engine/src/ge_compressor_astc_4x4.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#include "ge_compressor_astc_4x4.hpp"
|
||||
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_vulkan_command_loader.hpp"
|
||||
#include "ge_vulkan_features.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#ifdef ENABLE_LIBASTCENC
|
||||
#include <astcenc.h>
|
||||
#include <SDL_cpuinfo.h>
|
||||
#endif
|
||||
|
||||
namespace GE
|
||||
{
|
||||
// ============================================================================
|
||||
#ifdef ENABLE_LIBASTCENC
|
||||
namespace GEVulkanFeatures
|
||||
{
|
||||
extern bool g_supports_astc_4x4;
|
||||
}
|
||||
|
||||
std::vector<astcenc_context*> g_astc_contexts;
|
||||
#endif
|
||||
// ============================================================================
|
||||
void GECompressorASTC4x4::init()
|
||||
{
|
||||
#ifdef ENABLE_LIBASTCENC
|
||||
if (!GEVulkanFeatures::g_supports_astc_4x4)
|
||||
return;
|
||||
|
||||
// Check for neon existence because libastcenc doesn't do that
|
||||
// x86 will exit in astcenc_context_alloc if sse2 / sse4.1 is not supported
|
||||
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined (_M_ARM64)
|
||||
if (SDL_HasNEON() == SDL_FALSE)
|
||||
return;
|
||||
#endif
|
||||
|
||||
astcenc_config cfg = {};
|
||||
float quality = ASTCENC_PRE_FASTEST;
|
||||
if (astcenc_config_init(ASTCENC_PRF_LDR, 4, 4, 1, quality, 0, &cfg) !=
|
||||
ASTCENC_SUCCESS)
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < GEVulkanCommandLoader::getLoaderCount(); i++)
|
||||
{
|
||||
astcenc_context* context = NULL;
|
||||
if (astcenc_context_alloc(&cfg, 1, &context) != ASTCENC_SUCCESS)
|
||||
{
|
||||
destroy();
|
||||
return;
|
||||
}
|
||||
g_astc_contexts.push_back(context);
|
||||
}
|
||||
#endif
|
||||
} // init
|
||||
|
||||
// ============================================================================
|
||||
void GECompressorASTC4x4::destroy()
|
||||
{
|
||||
#ifdef ENABLE_LIBASTCENC
|
||||
for (astcenc_context* context : g_astc_contexts)
|
||||
astcenc_context_free(context);
|
||||
g_astc_contexts.clear();
|
||||
#endif
|
||||
} // destroy
|
||||
|
||||
// ============================================================================
|
||||
bool GECompressorASTC4x4::loaded()
|
||||
{
|
||||
#ifdef ENABLE_LIBASTCENC
|
||||
return !g_astc_contexts.empty();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
} // loaded
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GECompressorASTC4x4::GECompressorASTC4x4(uint8_t* texture, unsigned channels,
|
||||
const irr::core::dimension2d<irr::u32>& size,
|
||||
bool normal_map)
|
||||
: GEMipmapGenerator(texture, channels, size, normal_map)
|
||||
{
|
||||
#ifdef ENABLE_LIBASTCENC
|
||||
assert(channels == 4);
|
||||
size_t total_size = 0;
|
||||
m_mipmap_sizes = 0;
|
||||
for (unsigned i = 0; i < m_levels.size(); i++)
|
||||
{
|
||||
GEImageLevel& level = m_levels[i];
|
||||
unsigned cur_size = get4x4CompressedTextureSize(level.m_dim.Width,
|
||||
level.m_dim.Height);
|
||||
total_size += cur_size;
|
||||
if (i > 0)
|
||||
m_mipmap_sizes += cur_size;
|
||||
}
|
||||
|
||||
std::vector<GEImageLevel> compressed_levels;
|
||||
m_compressed_data = new uint8_t[total_size];
|
||||
uint8_t* cur_offset = m_compressed_data;
|
||||
|
||||
for (GEImageLevel& level : m_levels)
|
||||
{
|
||||
astcenc_image img;
|
||||
img.dim_x = level.m_dim.Width;
|
||||
img.dim_y = level.m_dim.Height;
|
||||
img.dim_z = 1;
|
||||
img.data_type = ASTCENC_TYPE_U8;
|
||||
img.data = &level.m_data;
|
||||
|
||||
astcenc_swizzle swizzle;
|
||||
swizzle.r = ASTCENC_SWZ_R;
|
||||
swizzle.g = ASTCENC_SWZ_G;
|
||||
swizzle.b = ASTCENC_SWZ_B;
|
||||
swizzle.a = ASTCENC_SWZ_A;
|
||||
|
||||
unsigned cur_size = get4x4CompressedTextureSize(level.m_dim.Width,
|
||||
level.m_dim.Height);
|
||||
if (astcenc_compress_image(
|
||||
g_astc_contexts[GEVulkanCommandLoader::getLoaderId()], &img,
|
||||
&swizzle, cur_offset, cur_size, 0) != ASTCENC_SUCCESS)
|
||||
printf("astcenc_compress_image failed!\n");
|
||||
compressed_levels.push_back({ level.m_dim, cur_size, cur_offset });
|
||||
cur_offset += cur_size;
|
||||
}
|
||||
freeMipmapCascade();
|
||||
std::swap(compressed_levels, m_levels);
|
||||
#endif
|
||||
} // GECompressorASTC4x4
|
||||
|
||||
}
|
29
lib/graphics_engine/src/ge_compressor_astc_4x4.hpp
Normal file
29
lib/graphics_engine/src/ge_compressor_astc_4x4.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef HEADER_GE_ASTC_COMPRESSOR_HPP
|
||||
#define HEADER_GE_ASTC_COMPRESSOR_HPP
|
||||
|
||||
#include "ge_mipmap_generator.hpp"
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GECompressorASTC4x4 : public GEMipmapGenerator
|
||||
{
|
||||
private:
|
||||
uint8_t* m_compressed_data;
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
static void init();
|
||||
// ------------------------------------------------------------------------
|
||||
static void destroy();
|
||||
// ------------------------------------------------------------------------
|
||||
static bool loaded();
|
||||
// ------------------------------------------------------------------------
|
||||
GECompressorASTC4x4(uint8_t* texture, unsigned channels,
|
||||
const irr::core::dimension2d<irr::u32>& size,
|
||||
bool normal_map);
|
||||
// ------------------------------------------------------------------------
|
||||
~GECompressorASTC4x4() { delete [] m_compressed_data; }
|
||||
}; // GEASTCCompressor
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -84,7 +84,7 @@ void GEVulkanCommandLoader::init(GEVulkanDriver* vk)
|
||||
}
|
||||
}
|
||||
|
||||
g_loader_count.store(thread_count - 1);
|
||||
g_loader_count.store(thread_count);
|
||||
for (unsigned i = 0; i < thread_count - 1; i++)
|
||||
{
|
||||
g_loaders.emplace_back(
|
||||
@ -153,6 +153,12 @@ bool GEVulkanCommandLoader::isUsingMultiThreadingNow()
|
||||
return g_loader_id != 0;
|
||||
} // isUsingMultiThreadingNow
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
unsigned GEVulkanCommandLoader::getLoaderCount()
|
||||
{
|
||||
return g_loader_count.load();
|
||||
} // getLoaderCount
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
int GEVulkanCommandLoader::getLoaderId()
|
||||
{
|
||||
|
@ -19,6 +19,8 @@ bool multiThreadingEnabled();
|
||||
// ----------------------------------------------------------------------------
|
||||
bool isUsingMultiThreadingNow();
|
||||
// ----------------------------------------------------------------------------
|
||||
unsigned getLoaderCount();
|
||||
// ----------------------------------------------------------------------------
|
||||
int getLoaderId();
|
||||
// ----------------------------------------------------------------------------
|
||||
VkCommandPool getCurrentCommandPool();
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "ge_vulkan_driver.hpp"
|
||||
|
||||
#include "ge_compressor_astc_4x4.hpp"
|
||||
#include "ge_main.hpp"
|
||||
|
||||
#include "ge_vulkan_2d_renderer.hpp"
|
||||
@ -632,6 +633,7 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
|
||||
GEVulkanShaderManager::getSamplerSize(),
|
||||
GEVulkanShaderManager::getMeshTextureLayer(),
|
||||
GEVulkanFeatures::supportsBindMeshTexturesAtOnce());
|
||||
GECompressorASTC4x4::init();
|
||||
GEVulkanFeatures::printStats();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
@ -651,6 +653,7 @@ GEVulkanDriver::~GEVulkanDriver()
|
||||
// ----------------------------------------------------------------------------
|
||||
void GEVulkanDriver::destroyVulkan()
|
||||
{
|
||||
GECompressorASTC4x4::destroy();
|
||||
if (m_depth_texture)
|
||||
{
|
||||
m_depth_texture->drop();
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "ge_vulkan_features.hpp"
|
||||
|
||||
#include "ge_compressor_astc_4x4.hpp"
|
||||
#include "ge_vulkan_driver.hpp"
|
||||
#include "ge_vulkan_shader_manager.hpp"
|
||||
|
||||
@ -27,6 +28,7 @@ bool g_supports_multi_draw_indirect = false;
|
||||
bool g_supports_base_vertex_rendering = true;
|
||||
bool g_supports_compute_in_main_queue = false;
|
||||
bool g_supports_s3tc_bc3 = false;
|
||||
bool g_supports_astc_4x4 = false;
|
||||
} // GEVulkanFeatures
|
||||
|
||||
// ============================================================================
|
||||
@ -70,6 +72,10 @@ void GEVulkanFeatures::init(GEVulkanDriver* vk)
|
||||
vkGetPhysicalDeviceFormatProperties(vk->getPhysicalDevice(),
|
||||
VK_FORMAT_BC3_UNORM_BLOCK, &format_properties);
|
||||
g_supports_s3tc_bc3 = format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
|
||||
format_properties = {};
|
||||
vkGetPhysicalDeviceFormatProperties(vk->getPhysicalDevice(),
|
||||
VK_FORMAT_ASTC_4x4_UNORM_BLOCK, &format_properties);
|
||||
g_supports_astc_4x4 = format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
|
||||
|
||||
uint32_t extension_count;
|
||||
vkEnumerateDeviceExtensionProperties(vk->getPhysicalDevice(), NULL,
|
||||
@ -190,6 +196,9 @@ void GEVulkanFeatures::printStats()
|
||||
os::Printer::log(
|
||||
"Vulkan supports s3 texture compression (bc3, dxt5)",
|
||||
g_supports_s3tc_bc3 ? "true" : "false");
|
||||
os::Printer::log(
|
||||
"Vulkan supports adaptive scalable texture compression (4x4 block)",
|
||||
supportsASTC4x4() ? "true" : "false");
|
||||
os::Printer::log(
|
||||
"Vulkan descriptor indexes can be dynamically non-uniform",
|
||||
g_supports_non_uniform_indexing ? "true" : "false");
|
||||
@ -275,4 +284,10 @@ bool GEVulkanFeatures::supportsS3TCBC3()
|
||||
return g_supports_s3tc_bc3;
|
||||
} // supportsS3TCBC3
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool GEVulkanFeatures::supportsASTC4x4()
|
||||
{
|
||||
return g_supports_astc_4x4 && GECompressorASTC4x4::loaded();
|
||||
} // supportsASTC4x4
|
||||
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ bool supportsBaseVertexRendering();
|
||||
bool supportsComputeInMainQueue();
|
||||
// ----------------------------------------------------------------------------
|
||||
bool supportsS3TCBC3();
|
||||
// ----------------------------------------------------------------------------
|
||||
bool supportsASTC4x4();
|
||||
}; // GEVulkanFeatures
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_mipmap_generator.hpp"
|
||||
#include "ge_compressor_astc_4x4.hpp"
|
||||
#include "ge_compressor_s3tc_bc3.hpp"
|
||||
#include "ge_texture.hpp"
|
||||
#include "ge_vulkan_command_loader.hpp"
|
||||
@ -123,7 +124,15 @@ bool GEVulkanTexture::createTextureImage(uint8_t* texture_data,
|
||||
const bool normal_map = (std::string(NamedPath.getPtr()).find(
|
||||
"_Normal.") != std::string::npos);
|
||||
bool texture_compression = getGEConfig()->m_texture_compression;
|
||||
if (texture_compression && GEVulkanFeatures::supportsS3TCBC3())
|
||||
if (texture_compression && GEVulkanFeatures::supportsASTC4x4())
|
||||
{
|
||||
image_size = get4x4CompressedTextureSize(m_size.Width,
|
||||
m_size.Height);
|
||||
m_internal_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
|
||||
mipmap_generator = new GECompressorASTC4x4(texture_data, channels,
|
||||
m_size, normal_map);
|
||||
}
|
||||
else if (texture_compression && GEVulkanFeatures::supportsS3TCBC3())
|
||||
{
|
||||
image_size = get4x4CompressedTextureSize(m_size.Width,
|
||||
m_size.Height);
|
||||
|
Loading…
Reference in New Issue
Block a user