Use quality settings for BCn formats in texture_optimize.

This commit is contained in:
Alberto Torres 2024-09-10 00:50:33 +02:00
parent f7108225bd
commit dd75d19399
3 changed files with 33 additions and 7 deletions

View file

@ -22,7 +22,8 @@ typedef struct {
int32_t width; int32_t width;
int32_t height; int32_t height;
int8_t format; // BCn format to use. 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; } EncodeBcInput;
typedef struct { typedef struct {
@ -39,6 +40,7 @@ typedef enum {
UNSUPPORTED_FORMAT_ERROR = 4, UNSUPPORTED_FORMAT_ERROR = 4,
INVALID_INPUT_LENGTH_ERROR = 5, INVALID_INPUT_LENGTH_ERROR = 5,
INVALID_OUTPUT_LENGTH_ERROR = 6, INVALID_OUTPUT_LENGTH_ERROR = 6,
INVALID_SETTINGS = 7,
} EncodeBcError; } EncodeBcError;
extern "C" EncodeBcError encode_bc(EncodeBcInput &input, EncodeBcOutput &output, bool verbose) 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: default:
return UNSUPPORTED_FORMAT_ERROR; 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 width = input.width;
int32_t height = input.height; int32_t height = input.height;
if(width == 0 || height == 0){ if(width == 0 || height == 0){

View file

@ -23,7 +23,8 @@ type EncodeBcInput* {.bycopy.} = object
width*: int32 width*: int32
height*: int32 height*: int32
format*: int8 ## BCn format to use. 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 type EncodeBcOutput* {.bycopy.} = object
data*: pointer data*: pointer
@ -33,7 +34,8 @@ type EncodeBcOutput* {.bycopy.} = object
type EncodeBcError* {.size:4.} = enum type EncodeBcError* {.size:4.} = enum
NO_ERROR = 0, ENCODER_INIT_ERROR = 1, ENCODE_ERROR = 2, NO_ERROR = 0, ENCODER_INIT_ERROR = 1, ENCODE_ERROR = 2,
INVALID_SIZE_ERROR = 3, UNSUPPORTED_FORMAT_ERROR = 4, 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.} proc encode_bc*(input: var EncodeBcInput, output: var EncodeBcOutput, verbose: bool): EncodeBcError {.importc, cdecl.}

View file

@ -45,7 +45,6 @@ import ../types
import ./texture_decode import ./texture_decode
from dds_ktx import KtxInfo, KtxPart, KtxInfoParts, get_ASTC_internal_format from dds_ktx import KtxInfo, KtxPart, KtxInfoParts, get_ASTC_internal_format
import arr_ref import arr_ref
import loadable
import zstd/decompress import zstd/decompress
import stb_image_resize import stb_image_resize
import std/monotimes import std/monotimes
@ -152,15 +151,26 @@ proc make_mipmaps(tex: Texture, pixels: SliceMem[byte], compress: CompressMipmap
return (parts, data_refs) return (parts, data_refs)
when defined(myouUseBC7Encoder): 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): when not defined(android):
let (bpp, internal_format) = get_bc_bpp_internal_format(bc_format, tex.is_sRGB) 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 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.} = proc compress(w, h: int32, p: pointer, len: int32): CompressMipmapResult {.closure.} =
var input = EncodeBcInput( var input = EncodeBcInput(
data: p, len: len, data: p, len: len,
width: w, height: h, width: w, height: h,
format: bc_format, 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 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) 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 # echo "progress ", p
var ctx: ptr AstcencContext var ctx: ptr AstcencContext
astc_assert astcenc_context_alloc(config.addr, 1, ctx) 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.} = proc compress(w, h: int32, p: pointer, len: int32): CompressMipmapResult {.closure.} =
let buffer_size = block_file_size(w, h, 1, let buffer_size = block_file_size(w, h, 1,
config.block_x, config.block_y, config.block_z, 16) 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 4.int8 # BC4
else: else:
settings.bc_format_for_RGB.int8 # BC1 or BC7 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 if not will_encode_all: return
when defined(myouUseAstcEncoder): when defined(myouUseAstcEncoder):
if has_astc_support or will_encode_all: if has_astc_support or will_encode_all: