Path: blob/master/thirdparty/basis_universal/encoder/basisu_gpu_texture.h
9902 views
// basisu_gpu_texture.h1// Copyright (C) 2019-2024 Binomial LLC. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14#pragma once15#include "../transcoder/basisu.h"16#include "basisu_etc.h"1718namespace basisu19{20// GPU texture "image"21class gpu_image22{23public:24enum { cMaxBlockSize = 12 };2526gpu_image()27{28clear();29}3031gpu_image(texture_format fmt, uint32_t width, uint32_t height)32{33init(fmt, width, height);34}3536void clear()37{38m_fmt = texture_format::cInvalidTextureFormat;39m_width = 0;40m_height = 0;41m_block_width = 0;42m_block_height = 0;43m_blocks_x = 0;44m_blocks_y = 0;45m_qwords_per_block = 0;46m_blocks.clear();47}4849inline texture_format get_format() const { return m_fmt; }50inline bool is_hdr() const { return is_hdr_texture_format(m_fmt); }5152// Width/height in pixels53inline uint32_t get_pixel_width() const { return m_width; }54inline uint32_t get_pixel_height() const { return m_height; }5556// Width/height in blocks, row pitch is assumed to be m_blocks_x.57inline uint32_t get_blocks_x() const { return m_blocks_x; }58inline uint32_t get_blocks_y() const { return m_blocks_y; }5960// Size of each block in pixels61inline uint32_t get_block_width() const { return m_block_width; }62inline uint32_t get_block_height() const { return m_block_height; }6364inline uint32_t get_qwords_per_block() const { return m_qwords_per_block; }65inline uint32_t get_total_blocks() const { return m_blocks_x * m_blocks_y; }66inline uint32_t get_bytes_per_block() const { return get_qwords_per_block() * sizeof(uint64_t); }67inline uint32_t get_row_pitch_in_bytes() const { return get_bytes_per_block() * get_blocks_x(); }6869inline const uint64_vec &get_blocks() const { return m_blocks; }7071inline const uint64_t *get_ptr() const { return &m_blocks[0]; }72inline uint64_t *get_ptr() { return &m_blocks[0]; }7374inline uint32_t get_size_in_bytes() const { return get_total_blocks() * get_qwords_per_block() * sizeof(uint64_t); }7576inline const void *get_block_ptr(uint32_t block_x, uint32_t block_y, uint32_t element_index = 0) const77{78assert(block_x < m_blocks_x && block_y < m_blocks_y);79return &m_blocks[(block_x + block_y * m_blocks_x) * m_qwords_per_block + element_index];80}8182inline void *get_block_ptr(uint32_t block_x, uint32_t block_y, uint32_t element_index = 0)83{84assert(block_x < m_blocks_x && block_y < m_blocks_y && element_index < m_qwords_per_block);85return &m_blocks[(block_x + block_y * m_blocks_x) * m_qwords_per_block + element_index];86}8788void init(texture_format fmt, uint32_t width, uint32_t height)89{90m_fmt = fmt;91m_width = width;92m_height = height;93m_block_width = basisu::get_block_width(m_fmt);94m_block_height = basisu::get_block_height(m_fmt);95m_blocks_x = (m_width + m_block_width - 1) / m_block_width;96m_blocks_y = (m_height + m_block_height - 1) / m_block_height;97m_qwords_per_block = basisu::get_qwords_per_block(m_fmt);9899m_blocks.resize(0);100m_blocks.resize(m_blocks_x * m_blocks_y * m_qwords_per_block);101}102103// Unpacks LDR textures only.104bool unpack(image& img) const;105106// Unpacks HDR textures only.107bool unpack_hdr(imagef& img) const;108109inline void override_dimensions(uint32_t w, uint32_t h)110{111m_width = w;112m_height = h;113}114115private:116texture_format m_fmt;117uint32_t m_width, m_height, m_blocks_x, m_blocks_y, m_block_width, m_block_height, m_qwords_per_block;118uint64_vec m_blocks;119};120121typedef basisu::vector<gpu_image> gpu_image_vec;122123// KTX1 file writing124bool create_ktx_texture_file(uint8_vec &ktx_data, const basisu::vector<gpu_image_vec>& gpu_images, bool cubemap_flag);125126bool does_dds_support_format(texture_format fmt);127bool write_dds_file(uint8_vec& dds_data, const basisu::vector<gpu_image_vec>& gpu_images, bool cubemap_flag, bool use_srgb_format);128bool write_dds_file(const char* pFilename, const basisu::vector<gpu_image_vec>& gpu_images, bool cubemap_flag, bool use_srgb_format);129130// Currently reads 2D 32bpp RGBA, 16-bit HALF RGBA, or 32-bit FLOAT RGBA, with or without mipmaps. No tex arrays or cubemaps, yet.131bool read_uncompressed_dds_file(const char* pFilename, basisu::vector<image>& ldr_mips, basisu::vector<imagef>& hdr_mips);132133// Supports DDS and KTX134bool write_compressed_texture_file(const char *pFilename, const basisu::vector<gpu_image_vec>& g, bool cubemap_flag, bool use_srgb_format);135bool write_compressed_texture_file(const char* pFilename, const gpu_image_vec& g, bool use_srgb_format);136bool write_compressed_texture_file(const char *pFilename, const gpu_image &g, bool use_srgb_format);137138bool write_3dfx_out_file(const char* pFilename, const gpu_image& gi);139140// GPU texture block unpacking141// For ETC1, use in basisu_etc.h: bool unpack_etc1(const etc_block& block, color_rgba *pDst, bool preserve_alpha)142void unpack_etc2_eac(const void *pBlock_bits, color_rgba *pPixels);143bool unpack_bc1(const void *pBlock_bits, color_rgba *pPixels, bool set_alpha);144void unpack_bc4(const void *pBlock_bits, uint8_t *pPixels, uint32_t stride);145bool unpack_bc3(const void *pBlock_bits, color_rgba *pPixels);146void unpack_bc5(const void *pBlock_bits, color_rgba *pPixels);147bool unpack_bc7_mode6(const void *pBlock_bits, color_rgba *pPixels);148bool unpack_bc7(const void* pBlock_bits, color_rgba* pPixels); // full format149bool unpack_bc6h(const void* pSrc_block, void* pDst_block, bool is_signed, uint32_t dest_pitch_in_halfs = 4 * 3); // full format, outputs HALF values, RGB texels only (not RGBA)150void unpack_atc(const void* pBlock_bits, color_rgba* pPixels);151// We only support CC_MIXED non-alpha blocks here because that's the only mode the transcoder uses at the moment.152bool unpack_fxt1(const void* p, color_rgba* pPixels);153// PVRTC2 is currently limited to only what our transcoder outputs (non-interpolated, hard_flag=1 modulation=0). In this mode, PVRTC2 looks much like BC1/ATC.154bool unpack_pvrtc2(const void* p, color_rgba* pPixels);155void unpack_etc2_eac_r(const void *p, color_rgba* pPixels, uint32_t c);156void unpack_etc2_eac_rg(const void* p, color_rgba* pPixels);157158// unpack_block() is primarily intended to unpack texture data created by the transcoder.159// For some texture formats (like ETC2 RGB, PVRTC2, FXT1) it's not yet a complete implementation.160// Unpacks LDR texture formats only.161bool unpack_block(texture_format fmt, const void *pBlock, color_rgba *pPixels);162163// Unpacks HDR texture formats only.164bool unpack_block_hdr(texture_format fmt, const void* pBlock, vec4F* pPixels);165166bool write_astc_file(const char* pFilename, const void* pBlocks, uint32_t block_width, uint32_t block_height, uint32_t dim_x, uint32_t dim_y);167168} // namespace basisu169170171172