Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/basis_universal/encoder/basisu_gpu_texture.h
9902 views
1
// basisu_gpu_texture.h
2
// Copyright (C) 2019-2024 Binomial LLC. All Rights Reserved.
3
//
4
// Licensed under the Apache License, Version 2.0 (the "License");
5
// you may not use this file except in compliance with the License.
6
// You may obtain a copy of the License at
7
//
8
// http://www.apache.org/licenses/LICENSE-2.0
9
//
10
// Unless required by applicable law or agreed to in writing, software
11
// distributed under the License is distributed on an "AS IS" BASIS,
12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
// See the License for the specific language governing permissions and
14
// limitations under the License.
15
#pragma once
16
#include "../transcoder/basisu.h"
17
#include "basisu_etc.h"
18
19
namespace basisu
20
{
21
// GPU texture "image"
22
class gpu_image
23
{
24
public:
25
enum { cMaxBlockSize = 12 };
26
27
gpu_image()
28
{
29
clear();
30
}
31
32
gpu_image(texture_format fmt, uint32_t width, uint32_t height)
33
{
34
init(fmt, width, height);
35
}
36
37
void clear()
38
{
39
m_fmt = texture_format::cInvalidTextureFormat;
40
m_width = 0;
41
m_height = 0;
42
m_block_width = 0;
43
m_block_height = 0;
44
m_blocks_x = 0;
45
m_blocks_y = 0;
46
m_qwords_per_block = 0;
47
m_blocks.clear();
48
}
49
50
inline texture_format get_format() const { return m_fmt; }
51
inline bool is_hdr() const { return is_hdr_texture_format(m_fmt); }
52
53
// Width/height in pixels
54
inline uint32_t get_pixel_width() const { return m_width; }
55
inline uint32_t get_pixel_height() const { return m_height; }
56
57
// Width/height in blocks, row pitch is assumed to be m_blocks_x.
58
inline uint32_t get_blocks_x() const { return m_blocks_x; }
59
inline uint32_t get_blocks_y() const { return m_blocks_y; }
60
61
// Size of each block in pixels
62
inline uint32_t get_block_width() const { return m_block_width; }
63
inline uint32_t get_block_height() const { return m_block_height; }
64
65
inline uint32_t get_qwords_per_block() const { return m_qwords_per_block; }
66
inline uint32_t get_total_blocks() const { return m_blocks_x * m_blocks_y; }
67
inline uint32_t get_bytes_per_block() const { return get_qwords_per_block() * sizeof(uint64_t); }
68
inline uint32_t get_row_pitch_in_bytes() const { return get_bytes_per_block() * get_blocks_x(); }
69
70
inline const uint64_vec &get_blocks() const { return m_blocks; }
71
72
inline const uint64_t *get_ptr() const { return &m_blocks[0]; }
73
inline uint64_t *get_ptr() { return &m_blocks[0]; }
74
75
inline uint32_t get_size_in_bytes() const { return get_total_blocks() * get_qwords_per_block() * sizeof(uint64_t); }
76
77
inline const void *get_block_ptr(uint32_t block_x, uint32_t block_y, uint32_t element_index = 0) const
78
{
79
assert(block_x < m_blocks_x && block_y < m_blocks_y);
80
return &m_blocks[(block_x + block_y * m_blocks_x) * m_qwords_per_block + element_index];
81
}
82
83
inline void *get_block_ptr(uint32_t block_x, uint32_t block_y, uint32_t element_index = 0)
84
{
85
assert(block_x < m_blocks_x && block_y < m_blocks_y && element_index < m_qwords_per_block);
86
return &m_blocks[(block_x + block_y * m_blocks_x) * m_qwords_per_block + element_index];
87
}
88
89
void init(texture_format fmt, uint32_t width, uint32_t height)
90
{
91
m_fmt = fmt;
92
m_width = width;
93
m_height = height;
94
m_block_width = basisu::get_block_width(m_fmt);
95
m_block_height = basisu::get_block_height(m_fmt);
96
m_blocks_x = (m_width + m_block_width - 1) / m_block_width;
97
m_blocks_y = (m_height + m_block_height - 1) / m_block_height;
98
m_qwords_per_block = basisu::get_qwords_per_block(m_fmt);
99
100
m_blocks.resize(0);
101
m_blocks.resize(m_blocks_x * m_blocks_y * m_qwords_per_block);
102
}
103
104
// Unpacks LDR textures only.
105
bool unpack(image& img) const;
106
107
// Unpacks HDR textures only.
108
bool unpack_hdr(imagef& img) const;
109
110
inline void override_dimensions(uint32_t w, uint32_t h)
111
{
112
m_width = w;
113
m_height = h;
114
}
115
116
private:
117
texture_format m_fmt;
118
uint32_t m_width, m_height, m_blocks_x, m_blocks_y, m_block_width, m_block_height, m_qwords_per_block;
119
uint64_vec m_blocks;
120
};
121
122
typedef basisu::vector<gpu_image> gpu_image_vec;
123
124
// KTX1 file writing
125
bool create_ktx_texture_file(uint8_vec &ktx_data, const basisu::vector<gpu_image_vec>& gpu_images, bool cubemap_flag);
126
127
bool does_dds_support_format(texture_format fmt);
128
bool write_dds_file(uint8_vec& dds_data, const basisu::vector<gpu_image_vec>& gpu_images, bool cubemap_flag, bool use_srgb_format);
129
bool write_dds_file(const char* pFilename, const basisu::vector<gpu_image_vec>& gpu_images, bool cubemap_flag, bool use_srgb_format);
130
131
// Currently reads 2D 32bpp RGBA, 16-bit HALF RGBA, or 32-bit FLOAT RGBA, with or without mipmaps. No tex arrays or cubemaps, yet.
132
bool read_uncompressed_dds_file(const char* pFilename, basisu::vector<image>& ldr_mips, basisu::vector<imagef>& hdr_mips);
133
134
// Supports DDS and KTX
135
bool write_compressed_texture_file(const char *pFilename, const basisu::vector<gpu_image_vec>& g, bool cubemap_flag, bool use_srgb_format);
136
bool write_compressed_texture_file(const char* pFilename, const gpu_image_vec& g, bool use_srgb_format);
137
bool write_compressed_texture_file(const char *pFilename, const gpu_image &g, bool use_srgb_format);
138
139
bool write_3dfx_out_file(const char* pFilename, const gpu_image& gi);
140
141
// GPU texture block unpacking
142
// For ETC1, use in basisu_etc.h: bool unpack_etc1(const etc_block& block, color_rgba *pDst, bool preserve_alpha)
143
void unpack_etc2_eac(const void *pBlock_bits, color_rgba *pPixels);
144
bool unpack_bc1(const void *pBlock_bits, color_rgba *pPixels, bool set_alpha);
145
void unpack_bc4(const void *pBlock_bits, uint8_t *pPixels, uint32_t stride);
146
bool unpack_bc3(const void *pBlock_bits, color_rgba *pPixels);
147
void unpack_bc5(const void *pBlock_bits, color_rgba *pPixels);
148
bool unpack_bc7_mode6(const void *pBlock_bits, color_rgba *pPixels);
149
bool unpack_bc7(const void* pBlock_bits, color_rgba* pPixels); // full format
150
bool 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)
151
void unpack_atc(const void* pBlock_bits, color_rgba* pPixels);
152
// We only support CC_MIXED non-alpha blocks here because that's the only mode the transcoder uses at the moment.
153
bool unpack_fxt1(const void* p, color_rgba* pPixels);
154
// 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.
155
bool unpack_pvrtc2(const void* p, color_rgba* pPixels);
156
void unpack_etc2_eac_r(const void *p, color_rgba* pPixels, uint32_t c);
157
void unpack_etc2_eac_rg(const void* p, color_rgba* pPixels);
158
159
// unpack_block() is primarily intended to unpack texture data created by the transcoder.
160
// For some texture formats (like ETC2 RGB, PVRTC2, FXT1) it's not yet a complete implementation.
161
// Unpacks LDR texture formats only.
162
bool unpack_block(texture_format fmt, const void *pBlock, color_rgba *pPixels);
163
164
// Unpacks HDR texture formats only.
165
bool unpack_block_hdr(texture_format fmt, const void* pBlock, vec4F* pPixels);
166
167
bool 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);
168
169
} // namespace basisu
170
171
172