mirror of
https://github.com/BinomialLLC/basis_universal.git
synced 2026-07-12 08:58:52 +00:00
124 lines
5.5 KiB
C++
124 lines
5.5 KiB
C++
// basisu_dds_export.h
|
|
// Copyright (C) 2019-2025 Binomial LLC. All Rights Reserved.
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
// Basic DX10-style .DDS writer for basisu_tool's -dds command. It consumes the prepared source image
|
|
// slices from a basis_compressor that has been run in process_source_images() mode (so all the image
|
|
// loading, mipmap generation, and cubemap/array layout is done by the encoder), then packs each slice
|
|
// into the requested output format and writes a modern DX10 (DDS_HEADER_DXT10) .dds file.
|
|
//
|
|
// Supported -dds_format tokens (see parse_dds_output_format):
|
|
// Block compressed: bc1 bc2 bc3 bc4 bc5 bc7
|
|
// Uncompressed: a8r8g8b8 r8 r8g8 r5g6b5 a1r5g5b5 a4r4g4b4
|
|
//
|
|
// The sRGB-vs-UNORM DXGI variant is selected from the compressor's transfer function flag
|
|
// (m_ktx2_and_basis_srgb_transfer_function, set by -srgb/-photo/-linear); only bc1/bc2/bc3/bc7/a8r8g8b8/a8b8g8r8
|
|
// have an sRGB DXGI variant, the rest are always written as UNORM. No transfer-function conversion is
|
|
// ever applied to the texel data - we only pick the format tag and pack the bytes as-is.
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include "../transcoder/basisu.h" // for basisu::uint8_vec
|
|
|
|
namespace basisu
|
|
{
|
|
class basis_compressor;
|
|
|
|
// The output formats supported by the -dds command.
|
|
enum dds_output_format
|
|
{
|
|
cDDSFmtInvalid = -1,
|
|
|
|
// Block compressed (packed with the real-time BC encoders).
|
|
cDDSFmtBC1,
|
|
cDDSFmtBC2,
|
|
cDDSFmtBC3,
|
|
cDDSFmtBC4,
|
|
cDDSFmtBC5,
|
|
cDDSFmtBC7,
|
|
|
|
// Uncompressed (simple pixel format conversion).
|
|
cDDSFmtA8R8G8B8, // DXGI B8G8R8A8 (32bpp, BGRA in memory), has sRGB variant
|
|
cDDSFmtA8B8G8R8, // DXGI R8G8B8A8 (32bpp, RGBA in memory), has sRGB variant
|
|
cDDSFmtR8, // DXGI R8 (8bpp)
|
|
cDDSFmtR8G8, // DXGI R8G8 (16bpp), source R->R, source G->G (like BC5)
|
|
cDDSFmtR5G6B5, // DXGI B5G6R5 (16bpp)
|
|
cDDSFmtA1R5G5B5, // DXGI B5G5R5A1 (16bpp)
|
|
cDDSFmtA4R4G4B4, // DXGI B4G4R4A4 (16bpp)
|
|
|
|
cDDSFmtTotal
|
|
};
|
|
|
|
// Parses a -dds_format token (case-insensitive) into a dds_output_format. Returns false (and sets
|
|
// fmt to cDDSFmtInvalid) on an unrecognized token.
|
|
bool parse_dds_output_format(const char* pToken, dds_output_format& fmt);
|
|
|
|
// Returns the canonical token string for a format (for messages), or "?" if invalid.
|
|
const char* get_dds_output_format_string(dds_output_format fmt);
|
|
|
|
// True if the format has a distinct sRGB DXGI variant (bc1/bc3/bc7/a8r8g8b8); false for the formats
|
|
// that are always written UNORM. Lets a caller report the actually-emitted variant accurately.
|
|
bool dds_output_format_has_srgb_variant(dds_output_format fmt);
|
|
|
|
// Which BC7 base packer to use for bc7 output. (Eventually a third encoder may be added.)
|
|
enum dds_bc7_encoder
|
|
{
|
|
cDDSBC7Encoder_Default = -1, // "not specified" sentinel (CLI use); resolves to the dds_export_params default
|
|
cDDSBC7Encoder_BC7F = 0, // built-in fast real-time packer (basist::bc7f), default
|
|
cDDSBC7Encoder_BC7E_Scalar = 1 // higher-quality (slower) scalar bc7e encoder
|
|
};
|
|
|
|
// bc7f quality level -> which analytical mode flags the bc7f packer uses (higher = slower/better).
|
|
enum dds_bc7f_level
|
|
{
|
|
cDDSBC7FLevel_Analytical = 0, // cPackBC7FlagDefault
|
|
cDDSBC7FLevel_PartiallyAnalytical = 1, // cPackBC7FlagDefaultPartiallyAnalytical (default)
|
|
cDDSBC7FLevel_NonAnalytical = 2 // cPackBC7FlagDefaultNonAnalytical (slowest/best)
|
|
};
|
|
|
|
// Input parameters for build_dds(). Intended to grow as more -dds options are added (BC1 quality, etc.).
|
|
struct dds_export_params
|
|
{
|
|
dds_output_format m_format;
|
|
|
|
// BC7-only knobs (ignored for non-bc7 formats):
|
|
dds_bc7_encoder m_bc7_encoder; // which BC7 base packer
|
|
int m_bc7f_level; // dds_bc7f_level [0,2]: analytical / partially / non analytical (bc7f only)
|
|
int m_bc7e_scalar_level; // bc7e_scalar quality level [0,6], 0=ultrafast..6=slowest (bc7e_scalar only)
|
|
|
|
dds_export_params()
|
|
: m_format(cDDSFmtInvalid),
|
|
m_bc7_encoder(cDDSBC7Encoder_BC7F),
|
|
m_bc7f_level(cDDSBC7FLevel_PartiallyAnalytical),
|
|
m_bc7e_scalar_level(2)
|
|
{ }
|
|
explicit dds_export_params(dds_output_format format)
|
|
: m_format(format),
|
|
m_bc7_encoder(cDDSBC7Encoder_BC7F),
|
|
m_bc7f_level(cDDSBC7FLevel_PartiallyAnalytical),
|
|
m_bc7e_scalar_level(2)
|
|
{ }
|
|
};
|
|
|
|
// Builds an in-memory DX10 .dds file from the prepared slices of comp (which must have had a successful
|
|
// process_source_images() call) into dds_data (which is resize(0)'d first, then appended to). The caller
|
|
// is responsible for writing dds_data out (or using it however it likes). Picks the UNORM vs sRGB DXGI
|
|
// variant from comp's transfer function flag. On failure returns false and sets error_msg. On success,
|
|
// the optional out_* values report the texture's dimensions/structure (for a caller summary).
|
|
bool build_dds(uint8_vec& dds_data, const basis_compressor& comp, const dds_export_params& params,
|
|
std::string& error_msg,
|
|
uint32_t* pOut_width = nullptr, uint32_t* pOut_height = nullptr,
|
|
uint32_t* pOut_levels = nullptr, uint32_t* pOut_layers = nullptr, uint32_t* pOut_faces = nullptr);
|
|
|
|
} // namespace basisu
|