Files
basis_universal/basisu_gpu_texture.h
Rich Geldreich 33996b1a5f Important: Changing the Basis file version, so any existing files will need to be recompressed!
Adding new fields to the basis header: texture type and framerate. Texture type may be 2D, 2D array, video, volume, or cubemap array. The compressor makes sure that anything other than pure 2D follows certain constraints (cubemap arrays must have a multiple of 6 input images, videos/texture array images all must have the same resolution/# of mipmaps, etc.)
When unpacking cubemaps, the -unpack command now writes cubemap .KTX files which various tools like PVRTexTool support.
2019-05-02 16:09:11 -07:00

137 lines
4.5 KiB
C++

// basisu_gpu_texture.h
// Copyright (C) 2017-2019 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.
#pragma once
#include "transcoder/basisu.h"
#include "basisu_etc.h"
namespace basisu
{
// GPU texture image
class gpu_image
{
public:
enum { cMaxBlockSize = 12 };
gpu_image()
{
clear();
}
gpu_image(texture_format fmt, uint32_t width, uint32_t height)
{
init(fmt, width, height);
}
void clear()
{
m_fmt = cInvalidTextureFormat;
m_width = 0;
m_height = 0;
m_block_width = 0;
m_block_height = 0;
m_blocks_x = 0;
m_blocks_y = 0;
m_qwords_per_block = 0;
m_blocks.clear();
}
inline texture_format get_format() const { return m_fmt; }
inline uint32_t get_width() const { return m_width; }
inline uint32_t get_height() const { return m_height; }
inline uint32_t get_blocks_x() const { return m_blocks_x; }
inline uint32_t get_blocks_y() const { return m_blocks_y; }
inline uint32_t get_block_width() const { return m_block_width; }
inline uint32_t get_block_height() const { return m_block_height; }
inline uint32_t get_qwords_per_block() const { return m_qwords_per_block; }
inline uint32_t get_total_blocks() const { return m_blocks_x * m_blocks_y; }
inline const uint64_vec &get_blocks() const { return m_blocks; }
inline const uint64_t *get_ptr() const { return &m_blocks[0]; }
inline uint64_t *get_ptr() { return &m_blocks[0]; }
inline uint32_t get_size_in_bytes() const { return get_total_blocks() * get_qwords_per_block() * sizeof(uint64_t); }
inline const void *get_block_ptr(uint32_t block_x, uint32_t block_y, uint32_t element_index = 0) const
{
assert(block_x < m_blocks_x && block_y < m_blocks_y);
return &m_blocks[(block_x + block_y * m_blocks_x) * m_qwords_per_block + element_index];
}
inline void *get_block_ptr(uint32_t block_x, uint32_t block_y, uint32_t element_index = 0)
{
assert(block_x < m_blocks_x && block_y < m_blocks_y && element_index < m_qwords_per_block);
return &m_blocks[(block_x + block_y * m_blocks_x) * m_qwords_per_block + element_index];
}
void init(texture_format fmt, uint32_t width, uint32_t height)
{
m_fmt = fmt;
m_width = width;
m_height = height;
m_block_width = basisu::get_block_width(m_fmt);
m_block_height = basisu::get_block_height(m_fmt);
m_blocks_x = (m_width + m_block_width - 1) / m_block_width;
m_blocks_y = (m_height + m_block_height - 1) / m_block_height;
m_qwords_per_block = basisu::get_qwords_per_block(m_fmt);
m_blocks.resize(0);
m_blocks.resize(m_blocks_x * m_blocks_y * m_qwords_per_block);
}
bool unpack(image& img, bool pvrtc_wrap_addressing = true) const;
void override_dimensions(uint32_t w, uint32_t h)
{
m_width = w;
m_height = h;
}
private:
texture_format m_fmt;
uint32_t m_width, m_height, m_blocks_x, m_blocks_y, m_block_width, m_block_height, m_qwords_per_block;
uint64_vec m_blocks;
};
typedef std::vector<gpu_image> gpu_image_vec;
// KTX file writing
bool create_ktx_texture_file(uint8_vec &ktx_data, const std::vector<gpu_image_vec>& gpu_images, bool cubemap_flag);
bool write_compressed_texture_file(const char *pFilename, const std::vector<gpu_image_vec>& g, bool cubemap_flag);
inline bool write_compressed_texture_file(const char *pFilename, const gpu_image_vec &g)
{
std::vector<gpu_image_vec> a;
a.push_back(g);
return write_compressed_texture_file(pFilename, a, false);
}
bool write_compressed_texture_file(const char *pFilename, const gpu_image &g);
// GPU texture block unpacking
void unpack_etc2_eac(const void *pBlock_bits, color_rgba *pPixels);
bool unpack_bc1(const void *pBlock_bits, color_rgba *pPixels, bool set_alpha);
void unpack_bc4(const void *pBlock_bits, uint8_t *pPixels, uint32_t stride);
bool unpack_bc3(const void *pBlock_bits, color_rgba *pPixels);
void unpack_bc5(const void *pBlock_bits, color_rgba *pPixels);
bool unpack_bc7_mode6(const void *pBlock_bits, color_rgba *pPixels);
bool unpack_block(texture_format fmt, const void *pBlock, color_rgba *pPixels);
} // namespace basisu