From dd75d19399bc0465651e3624f54994cecda2e849 Mon Sep 17 00:00:00 2001 From: Alberto Torres Date: Tue, 10 Sep 2024 00:50:33 +0200 Subject: [PATCH] Use quality settings for BCn formats in `texture_optimize`. --- libs/bc7enc/bc7enc.cpp | 17 ++++++++++++++++- libs/bc7enc/bc7enc.nim | 6 ++++-- src/gpu_formats/texture_optimize.nim | 17 +++++++++++++---- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/libs/bc7enc/bc7enc.cpp b/libs/bc7enc/bc7enc.cpp index af12805..af4cce2 100644 --- a/libs/bc7enc/bc7enc.cpp +++ b/libs/bc7enc/bc7enc.cpp @@ -22,7 +22,8 @@ typedef struct { int32_t width; int32_t height; int8_t format; // BCn format to use. - // TODO: encoding settings + int8_t bc1_quality; // between 0 and 18 + int8_t bc7_quality; // between 0 and 6 } EncodeBcInput; typedef struct { @@ -39,6 +40,7 @@ typedef enum { UNSUPPORTED_FORMAT_ERROR = 4, INVALID_INPUT_LENGTH_ERROR = 5, INVALID_OUTPUT_LENGTH_ERROR = 6, + INVALID_SETTINGS = 7, } EncodeBcError; extern "C" EncodeBcError encode_bc(EncodeBcInput &input, EncodeBcOutput &output, bool verbose) @@ -77,6 +79,19 @@ extern "C" EncodeBcError encode_bc(EncodeBcInput &input, EncodeBcOutput &output, default: return UNSUPPORTED_FORMAT_ERROR; } + rp.m_bc1_quality_level = input.bc1_quality; + if (((int)rp.m_bc1_quality_level < (int)rgbcx::MIN_LEVEL) || ((int)rp.m_bc1_quality_level > (int)(rgbcx::MAX_LEVEL + 1))) + { + fprintf(stderr, "Invalid BC1 quality\n"); + return INVALID_SETTINGS; + } + rp.m_bc7_uber_level = input.bc7_quality; + if ((rp.m_bc7_uber_level < 0) || (rp.m_bc7_uber_level > 6)) //BC7ENC_MAX_UBER_LEVEL)) + { + fprintf(stderr, "Invalid BC7 quality\n"); + return INVALID_SETTINGS; + } + int32_t width = input.width; int32_t height = input.height; if(width == 0 || height == 0){ diff --git a/libs/bc7enc/bc7enc.nim b/libs/bc7enc/bc7enc.nim index 0293b70..374d763 100644 --- a/libs/bc7enc/bc7enc.nim +++ b/libs/bc7enc/bc7enc.nim @@ -23,7 +23,8 @@ type EncodeBcInput* {.bycopy.} = object width*: int32 height*: int32 format*: int8 ## BCn format to use. - ## TODO: encoding settings + bc1_quality*: int8 ## between 0 and 18 + bc7_quality*: int8 ## between 0 and 6 type EncodeBcOutput* {.bycopy.} = object data*: pointer @@ -33,7 +34,8 @@ type EncodeBcOutput* {.bycopy.} = object type EncodeBcError* {.size:4.} = enum NO_ERROR = 0, ENCODER_INIT_ERROR = 1, ENCODE_ERROR = 2, INVALID_SIZE_ERROR = 3, UNSUPPORTED_FORMAT_ERROR = 4, - INVALID_INPUT_LENGTH_ERROR = 5, INVALID_OUTPUT_LENGTH_ERROR = 6 + INVALID_INPUT_LENGTH_ERROR = 5, INVALID_OUTPUT_LENGTH_ERROR = 6, + INVALID_SETTINGS = 7, proc encode_bc*(input: var EncodeBcInput, output: var EncodeBcOutput, verbose: bool): EncodeBcError {.importc, cdecl.} diff --git a/src/gpu_formats/texture_optimize.nim b/src/gpu_formats/texture_optimize.nim index f6e0263..df1d827 100644 --- a/src/gpu_formats/texture_optimize.nim +++ b/src/gpu_formats/texture_optimize.nim @@ -45,7 +45,6 @@ import ../types import ./texture_decode from dds_ktx import KtxInfo, KtxPart, KtxInfoParts, get_ASTC_internal_format import arr_ref -import loadable import zstd/decompress import stb_image_resize import std/monotimes @@ -152,15 +151,26 @@ proc make_mipmaps(tex: Texture, pixels: SliceMem[byte], compress: CompressMipmap return (parts, data_refs) when defined(myouUseBC7Encoder): - proc bcn_compress*(tex: Texture, pixels: SliceMem[byte], callback: CallbackCompressed, bc_format: int8) = + proc bcn_compress*(tex: Texture, pixels: SliceMem[byte], callback: CallbackCompressed, bc_format: int8, quality_speed: EncodingSpeed) = when not defined(android): let (bpp, internal_format) = get_bc_bpp_internal_format(bc_format, tex.is_sRGB) let block_size_bytes = (4*4*bpp.int) div 8 + let (bc1_quality, bc7_quality) = case quality_speed: + of UltraFast: (0,0) + of VeryFast: (5,1) + of Fast: (10,2) + of Basic: (15,3) + of Slow: (16,4) + of VerySlow: (17,5) + of Slowest: (18,6) + proc compress(w, h: int32, p: pointer, len: int32): CompressMipmapResult {.closure.} = var input = EncodeBcInput( data: p, len: len, width: w, height: h, format: bc_format, + bc1_quality: bc1_quality.int8, + bc7_quality: bc7_quality.int8, ) let out_len = block_file_size(w,h,1, 4,4,1, block_size_bytes) let row_len = block_file_size(w,1,1, 4,4,1, block_size_bytes) @@ -228,7 +238,6 @@ when defined(myouUseAstcEncoder): # echo "progress ", p var ctx: ptr AstcencContext astc_assert astcenc_context_alloc(config.addr, 1, ctx) - let time = getmonotime().ticks.float/1000000000 proc compress(w, h: int32, p: pointer, len: int32): CompressMipmapResult {.closure.} = let buffer_size = block_file_size(w, h, 1, config.block_x, config.block_y, config.block_z, 16) @@ -341,7 +350,7 @@ proc loadOptimized*(tex: Texture, slices: seq[SliceMem[byte]], 4.int8 # BC4 else: settings.bc_format_for_RGB.int8 # BC1 or BC7 - bcn_compress(tex, pixels, cb, bc_format) + bcn_compress(tex, pixels, cb, bc_format, settings.quality_speed) if not will_encode_all: return when defined(myouUseAstcEncoder): if has_astc_support or will_encode_all: