Add GECompressorBPTCBC7
This commit is contained in:
parent
3e2de9419e
commit
57c5446e55
@ -64,6 +64,7 @@ endif()
|
||||
set(GE_SOURCES
|
||||
src/gl.c
|
||||
src/ge_compressor_astc_4x4.cpp
|
||||
src/ge_compressor_bptc_bc7.cpp
|
||||
src/ge_compressor_s3tc_bc3.cpp
|
||||
src/ge_culling_tool.cpp
|
||||
src/ge_dx9_texture.cpp
|
||||
@ -97,7 +98,22 @@ if(NOT APPLE OR DLOPEN_MOLTENVK)
|
||||
set(GE_SOURCES ${GE_SOURCES} src/vulkan.c)
|
||||
endif()
|
||||
|
||||
option(BC7_ISPC "Enable BC7 (BPTC) support (requires ispc and cmake >= 3.19)" OFF)
|
||||
if(BC7_ISPC)
|
||||
add_definitions(-DBC7_ISPC)
|
||||
enable_language(ISPC)
|
||||
set(CMAKE_ISPC_FLAGS "${CMAKE_ISPC_FLAGS} --opt=fast-math --opt=disable-assertions --pic")
|
||||
set(GE_SOURCES
|
||||
${GE_SOURCES}
|
||||
src/bc7e.ispc
|
||||
)
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
add_library(graphics_engine STATIC ${GE_SOURCES})
|
||||
if(BC7_ISPC)
|
||||
set_property(TARGET graphics_engine PROPERTY ISPC_INSTRUCTION_SETS avx2)
|
||||
endif()
|
||||
|
||||
target_link_libraries(graphics_engine ${SQUISH_LIBRARY})
|
||||
|
||||
|
@ -37,6 +37,8 @@ bool supportsComputeInMainQueue();
|
||||
// ----------------------------------------------------------------------------
|
||||
bool supportsS3TCBC3();
|
||||
// ----------------------------------------------------------------------------
|
||||
bool supportsBPTCBC7();
|
||||
// ----------------------------------------------------------------------------
|
||||
bool supportsASTC4x4();
|
||||
}; // GEVulkanFeatures
|
||||
|
||||
|
4952
lib/graphics_engine/src/bc7e.ispc
Normal file
4952
lib/graphics_engine/src/bc7e.ispc
Normal file
File diff suppressed because it is too large
Load Diff
92
lib/graphics_engine/src/ge_compressor_bptc_bc7.cpp
Normal file
92
lib/graphics_engine/src/ge_compressor_bptc_bc7.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "ge_compressor_bptc_bc7.hpp"
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_vulkan_features.hpp"
|
||||
|
||||
#ifdef BC7_ISPC
|
||||
#include <bc7e_ispc.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace GE
|
||||
{
|
||||
// ============================================================================
|
||||
void GECompressorBPTCBC7::init()
|
||||
{
|
||||
#ifdef BC7_ISPC
|
||||
if (!GEVulkanFeatures::supportsBPTCBC7())
|
||||
return;
|
||||
ispc::bc7e_compress_block_init();
|
||||
#endif
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GECompressorBPTCBC7::GECompressorBPTCBC7(uint8_t* texture, unsigned channels,
|
||||
const irr::core::dimension2d<irr::u32>& size,
|
||||
bool normal_map)
|
||||
: GEMipmapGenerator(texture, channels, size, normal_map)
|
||||
{
|
||||
#ifdef BC7_ISPC
|
||||
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;
|
||||
}
|
||||
|
||||
ispc::bc7e_compress_block_params p = {};
|
||||
ispc::bc7e_compress_block_params_init_ultrafast(&p, true/*perceptual*/);
|
||||
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)
|
||||
{
|
||||
uint8_t* out = cur_offset;
|
||||
for (unsigned y = 0; y < level.m_dim.Height; y += 4)
|
||||
{
|
||||
for (unsigned x = 0; x < level.m_dim.Width; x += 4)
|
||||
{
|
||||
// build the 4x4 block of pixels
|
||||
uint32_t source_rgba[16] = {};
|
||||
uint8_t* target_pixel = (uint8_t*)source_rgba;
|
||||
for (unsigned py = 0; py < 4; py++)
|
||||
{
|
||||
for (unsigned px = 0; px < 4; px++)
|
||||
{
|
||||
// get the source pixel in the image
|
||||
unsigned sx = x + px;
|
||||
unsigned sy = y + py;
|
||||
// enable if we're in the image
|
||||
if (sx < level.m_dim.Width && sy < level.m_dim.Height)
|
||||
{
|
||||
uint8_t* rgba = (uint8_t*)level.m_data;
|
||||
const unsigned pitch = level.m_dim.Width * 4;
|
||||
uint8_t* source_pixel = rgba + pitch * sy + 4 * sx;
|
||||
memcpy(target_pixel, source_pixel, 4);
|
||||
}
|
||||
// advance to the next pixel
|
||||
target_pixel += 4;
|
||||
}
|
||||
}
|
||||
ispc::bc7e_compress_blocks(1, (uint64_t*)out, source_rgba, &p);
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
unsigned cur_size = get4x4CompressedTextureSize(level.m_dim.Width,
|
||||
level.m_dim.Height);
|
||||
compressed_levels.push_back({ level.m_dim, cur_size, cur_offset });
|
||||
cur_offset += cur_size;
|
||||
}
|
||||
freeMipmapCascade();
|
||||
std::swap(compressed_levels, m_levels);
|
||||
#endif
|
||||
} // GECompressorBPTCBC7
|
||||
|
||||
}
|
25
lib/graphics_engine/src/ge_compressor_bptc_bc7.hpp
Normal file
25
lib/graphics_engine/src/ge_compressor_bptc_bc7.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef HEADER_GE_COMPRESSOR_BPTC_BC7_HPP
|
||||
#define HEADER_GE_COMPRESSOR_BPTC_BC7_HPP
|
||||
|
||||
#include "ge_mipmap_generator.hpp"
|
||||
|
||||
namespace GE
|
||||
{
|
||||
class GECompressorBPTCBC7 : public GEMipmapGenerator
|
||||
{
|
||||
private:
|
||||
uint8_t* m_compressed_data;
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
static void init();
|
||||
// ------------------------------------------------------------------------
|
||||
GECompressorBPTCBC7(uint8_t* texture, unsigned channels,
|
||||
const irr::core::dimension2d<irr::u32>& size,
|
||||
bool normal_map);
|
||||
// ------------------------------------------------------------------------
|
||||
~GECompressorBPTCBC7() { delete [] m_compressed_data; }
|
||||
}; // GECompressorBPTCBC7
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -3,6 +3,7 @@
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_mipmap_generator.hpp"
|
||||
#include "ge_compressor_astc_4x4.hpp"
|
||||
#include "ge_compressor_bptc_bc7.hpp"
|
||||
#include "ge_compressor_s3tc_bc3.hpp"
|
||||
#include "ge_texture.hpp"
|
||||
#include "ge_vulkan_command_loader.hpp"
|
||||
@ -156,6 +157,17 @@ void GEVulkanArrayTexture::reloadInternal(const std::vector<io::path>& list,
|
||||
mipmap_generator = new GECompressorASTC4x4(texture_data, 4, m_size,
|
||||
normal_map);
|
||||
}
|
||||
else if (texture_compression && GEVulkanFeatures::supportsBPTCBC7())
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
image_size = get4x4CompressedTextureSize(m_size.Width,
|
||||
m_size.Height);
|
||||
m_internal_format = VK_FORMAT_BC7_UNORM_BLOCK;
|
||||
}
|
||||
mipmap_generator = new GECompressorBPTCBC7(texture_data, 4, m_size,
|
||||
normal_map);
|
||||
}
|
||||
else if (texture_compression && GEVulkanFeatures::supportsS3TCBC3())
|
||||
{
|
||||
if (i == 0)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "ge_vulkan_driver.hpp"
|
||||
|
||||
#include "ge_compressor_astc_4x4.hpp"
|
||||
#include "ge_compressor_bptc_bc7.hpp"
|
||||
#include "ge_main.hpp"
|
||||
|
||||
#include "ge_vulkan_2d_renderer.hpp"
|
||||
@ -636,6 +637,7 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
|
||||
GEVulkanShaderManager::getMeshTextureLayer(),
|
||||
GEVulkanFeatures::supportsBindMeshTexturesAtOnce());
|
||||
GECompressorASTC4x4::init();
|
||||
GECompressorBPTCBC7::init();
|
||||
GEVulkanFeatures::printStats();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../source/Irrlicht/os.h"
|
||||
#include <SDL_cpuinfo.h>
|
||||
|
||||
namespace GE
|
||||
{
|
||||
@ -28,6 +29,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_bptc_bc7 = false;
|
||||
bool g_supports_astc_4x4 = false;
|
||||
} // GEVulkanFeatures
|
||||
|
||||
@ -72,6 +74,16 @@ 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;
|
||||
#ifdef BC7_ISPC
|
||||
format_properties = {};
|
||||
// We compile bc7e.ispc with avx2 on
|
||||
if (SDL_HasAVX2() == SDL_TRUE)
|
||||
{
|
||||
vkGetPhysicalDeviceFormatProperties(vk->getPhysicalDevice(),
|
||||
VK_FORMAT_BC7_UNORM_BLOCK, &format_properties);
|
||||
g_supports_bptc_bc7 = format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
|
||||
}
|
||||
#endif
|
||||
format_properties = {};
|
||||
vkGetPhysicalDeviceFormatProperties(vk->getPhysicalDevice(),
|
||||
VK_FORMAT_ASTC_4x4_UNORM_BLOCK, &format_properties);
|
||||
@ -196,6 +208,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 BPTC texture compression (bc7)",
|
||||
g_supports_bptc_bc7 ? "true" : "false");
|
||||
os::Printer::log(
|
||||
"Vulkan supports adaptive scalable texture compression (4x4 block)",
|
||||
supportsASTC4x4() ? "true" : "false");
|
||||
@ -284,6 +299,12 @@ bool GEVulkanFeatures::supportsS3TCBC3()
|
||||
return g_supports_s3tc_bc3;
|
||||
} // supportsS3TCBC3
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool GEVulkanFeatures::supportsBPTCBC7()
|
||||
{
|
||||
return g_supports_bptc_bc7;
|
||||
} // supportsBPTCBC7
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool GEVulkanFeatures::supportsASTC4x4()
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "ge_main.hpp"
|
||||
#include "ge_mipmap_generator.hpp"
|
||||
#include "ge_compressor_astc_4x4.hpp"
|
||||
#include "ge_compressor_bptc_bc7.hpp"
|
||||
#include "ge_compressor_s3tc_bc3.hpp"
|
||||
#include "ge_texture.hpp"
|
||||
#include "ge_vulkan_command_loader.hpp"
|
||||
@ -159,6 +160,14 @@ bool GEVulkanTexture::createTextureImage(uint8_t* texture_data,
|
||||
mipmap_generator = new GECompressorASTC4x4(texture_data, channels,
|
||||
m_size, normal_map);
|
||||
}
|
||||
else if (texture_compression && GEVulkanFeatures::supportsBPTCBC7())
|
||||
{
|
||||
image_size = get4x4CompressedTextureSize(m_size.Width,
|
||||
m_size.Height);
|
||||
m_internal_format = VK_FORMAT_BC7_UNORM_BLOCK;
|
||||
mipmap_generator = new GECompressorBPTCBC7(texture_data, channels,
|
||||
m_size, normal_map);
|
||||
}
|
||||
else if (texture_compression && GEVulkanFeatures::supportsS3TCBC3())
|
||||
{
|
||||
image_size = get4x4CompressedTextureSize(m_size.Width,
|
||||
|
Loading…
Reference in New Issue
Block a user