citro3d
Loading...
Searching...
No Matches
texture.h
Go to the documentation of this file.
1/**
2 * @file texture.h
3 * @brief Create and manipulate textures
4 */
5#pragma once
6#include "types.h"
7
8/// Cubemap texture data
9typedef struct
10{
11 void* data[6];
13
14/// Texture data
15typedef struct
16{
17 union
18 {
19 void* data;
20 C3D_TexCube* cube;
21 };
22
23 GPU_TEXCOLOR fmt : 4;
24 size_t size : 28;
25
26 union
27 {
28 u32 dim;
29 struct
30 {
31 u16 height;
32 u16 width;
33 };
34 };
35
36 u32 param;
37 u32 border;
38 union
39 {
40 u32 lodParam;
41 struct
42 {
43 u16 lodBias;
44 u8 maxLevel;
45 u8 minLevel;
46 };
47 };
48} C3D_Tex;
49
50/// Parameters for \ref C3D_TexInitWithParams()
51typedef struct CTR_ALIGN(8)
52{
53 u16 width; ///< Width of texture in pixels. (must be a power of 2)
54 u16 height; ///< Height of texture in pixels. (must be a power of 2)
55 u8 maxLevel : 4; ///< Maximum mipmap level.
56 GPU_TEXCOLOR format : 4; ///< GPU texture format.
57 GPU_TEXTURE_MODE_PARAM type : 3; ///< Texture type
58 bool onVram : 1; ///< Specifies whether to allocate texture data in Vram or linearMemory
59} C3D_TexInitParams;
60
61/**
62 * @brief Initializes texture with specified parameters
63 * @param[out] tex Pointer to uninitialized \ref C3D_Tex.
64 * @param[out] cube Pointer to \ref C3D_TexCube. (Only used if texture type is cubemap)
65 * @param[in] p Parameters. See \ref C3D_TexInitParams.
66 * @return True if texture was initialized successfully, otherwise false.
67 */
68bool C3D_TexInitWithParams(C3D_Tex* tex, C3D_TexCube* cube, C3D_TexInitParams p);
69
70/**
71 * @brief Copies raw texture data into \ref C3D_Tex
72 * @param[out] tex Pointer to \ref C3D_Tex.
73 * @param[in] data Pointer to raw texture data.
74 * @param[in] face Specifies texture face.
75 * @param[in] level Specifies mipmap level.
76 */
77void C3D_TexLoadImage(C3D_Tex* tex, const void* data, GPU_TEXFACE face, int level);
78
79/**
80 * @brief Generates mipmaps for \ref C3D_Tex using previously specified max level
81 * The max level should have been specified using \ref C3D_TexInitMipmap() or \ref C3D_TexInitWithParams()
82 * @note Does not support generating mipmaps for VRAM textures.
83 * @param[in,out] tex Pointer to \ref C3D_Tex.
84 * @param[in] face Specifies texture face.
85 */
87
88/**
89 * @brief Binds C3D_Tex to texture unit
90 * @note The 3DS has 3 normal texture units (IDs 0 through 2).
91 * @param[in] unitId Specifies texture unit.
92 * @param[in] tex Pointer to \ref C3D_Tex.
93 */
94void C3D_TexBind(int unitId, C3D_Tex* tex);
95
96/**
97 * @brief Flushes texture data from cache into memory
98 * @param[in] tex Pointer to \ref C3D_Tex.
99 * @sa GSPGPU_FlushDataCache()
100 */
102
103/**
104 * @brief Deletes texture data
105 * @param[in] tex Pointer to \ref C3D_Tex.
106 */
108
109/**
110 * @brief Configues texunit0 shadow depth texture properties
111 * @param[in] perspective true if the shadow texture was generated with perspective projection,
112 * false if the shadow texture was generated with orthogonal projection.
113 * @param[in] bias Bias subtracted from the texture0w value in the shader.
114 */
115void C3D_TexShadowParams(bool perspective, float bias);
116
117/**
118 * @brief Calculates maximum mipmap level for given texture size
119 * @param[in] width Width of texture.
120 * @param[in] height Height of texture.
121 * @returns Calculated maximum mipmap level.
122 */
123static inline int C3D_TexCalcMaxLevel(u32 width, u32 height)
124{
125 return (31-__builtin_clz(width < height ? width : height)) - 3; // avoid sizes smaller than 8
126}
127
128/**
129 * @brief Calculates size of mipmap level
130 * @param[in] size Size of original texture.
131 * @param[in] level Mipmap level.
132 * @returns Calculated level size.
133 */
134static inline u32 C3D_TexCalcLevelSize(u32 size, int level)
135{
136 return size >> (2*level);
137}
138
139/**
140 * @brief Calculates total size of mipmap texture data
141 * @param[in] size Size of original texture.
142 * @param[in] maxLevel Maximum mipmap level.
143 * @returns Calculated total size.
144 */
145static inline u32 C3D_TexCalcTotalSize(u32 size, int maxLevel)
146{
147 /*
148 S = s + sr + sr^2 + sr^3 + ... + sr^n
149 Sr = sr + sr^2 + sr^3 + ... + sr^(n+1)
150 S-Sr = s - sr^(n+1)
151 S(1-r) = s(1 - r^(n+1))
152 S = s (1 - r^(n+1)) / (1-r)
153
154 r = 1/4
155 1-r = 3/4
156
157 S = 4s (1 - (1/4)^(n+1)) / 3
158 S = 4s (1 - 1/4^(n+1)) / 3
159 S = (4/3) (s - s/4^(n+1))
160 S = (4/3) (s - s/(1<<(2n+2)))
161 S = (4/3) (s - s>>(2n+2))
162 */
163 return (size - C3D_TexCalcLevelSize(size,maxLevel+1)) * 4 / 3;
164}
165
166/**
167 * @brief Initializes standard 2D texture
168 * @param[out] tex Pointer to uninitialized \ref C3D_Tex.
169 * @param[in] width Specifies width of texture. (must be a power of 2)
170 * @param[in] height Specifies height of texture. (must be a power of 2)
171 * @param[in] format Specifies texture format.
172 * @return True if texture was initialized successfully, otherwise false.
173 */
174static inline bool C3D_TexInit(C3D_Tex* tex, u16 width, u16 height, GPU_TEXCOLOR format)
175{
176 return C3D_TexInitWithParams(tex, NULL,
177 (C3D_TexInitParams){ width, height, 0, format, GPU_TEX_2D, false });
178}
179
180/**
181 * @brief Initializes standard 2D texture with mipmap
182 * Maximum miplevel is calculated using \ref C3D_TexCalcMaxLevel()
183 * @param[out] tex Pointer to uninitialized \ref C3D_Tex.
184 * @param[in] width Specifies width of texture. (must be a power of 2)
185 * @param[in] height Specifies height of texture. (must be a power of 2)
186 * @param[in] format Specifies texture format.
187 * @return True if texture was initialized successfully, otherwise false.
188 */
189static inline bool C3D_TexInitMipmap(C3D_Tex* tex, u16 width, u16 height, GPU_TEXCOLOR format)
190{
191 return C3D_TexInitWithParams(tex, NULL,
192 (C3D_TexInitParams){ width, height, (u8)C3D_TexCalcMaxLevel(width, height), format, GPU_TEX_2D, false });
193}
194
195/**
196 * @brief Initializes cubemap texture
197 * @param[out] tex Pointer to uninitialized \ref C3D_Tex.
198 * @param[out] cube Pointer to \ref C3D_TexCube.
199 * @param[in] width Specifies width of texture. (must be a power of 2)
200 * @param[in] height Specifies height of texture. (must be a power of 2)
201 * @param[in] format Specifies texture format.
202 * @return True if texture was initialized successfully, otherwise false.
203 */
204static inline bool C3D_TexInitCube(C3D_Tex* tex, C3D_TexCube* cube, u16 width, u16 height, GPU_TEXCOLOR format)
205{
206 return C3D_TexInitWithParams(tex, cube,
207 (C3D_TexInitParams){ width, height, 0, format, GPU_TEX_CUBE_MAP, false });
208}
209
210/**
211 * @brief Initializes 2D texture in VRAM
212 * @param[out] tex Pointer to uninitialized \ref C3D_Tex.
213 * @param[in] width Specifies width of texture. (must be a power of 2)
214 * @param[in] height Specifies height of texture. (must be a power of 2)
215 * @param[in] format Specifies texture format.
216 * @return True if texture was initialized successfully, otherwise false.
217 */
218static inline bool C3D_TexInitVRAM(C3D_Tex* tex, u16 width, u16 height, GPU_TEXCOLOR format)
219{
220 return C3D_TexInitWithParams(tex, NULL,
221 (C3D_TexInitParams){ width, height, 0, format, GPU_TEX_2D, true });
222}
223
224/**
225 * @brief Initializes 2D shadowmap texture
226 * @param[out] tex Pointer to uninitialized \ref C3D_Tex.
227 * @param[in] width Specifies width of texture. (must be a power of 2)
228 * @param[in] height Specifies height of texture. (must be a power of 2)
229 * @return True if texture was initialized successfully, otherwise false.
230 */
231static inline bool C3D_TexInitShadow(C3D_Tex* tex, u16 width, u16 height)
232{
233 return C3D_TexInitWithParams(tex, NULL,
234 (C3D_TexInitParams){ width, height, 0, GPU_RGBA8, GPU_TEX_SHADOW_2D, true });
235}
236
237/**
238 * @brief Initializes shadowmap cubemap texture
239 * @param[out] tex Pointer to uninitialized \ref C3D_Tex.
240 * @param[out] cube Pointer to \ref C3D_TexCube.
241 * @param[in] width Specifies width of texture. (must be a power of 2)
242 * @param[in] height Specifies height of texture. (must be a power of 2)
243 * @return True if texture was initialized successfully, otherwise false.
244 */
245static inline bool C3D_TexInitShadowCube(C3D_Tex* tex, C3D_TexCube* cube, u16 width, u16 height)
246{
247 return C3D_TexInitWithParams(tex, cube,
248 (C3D_TexInitParams){ width, height, 0, GPU_RGBA8, GPU_TEX_SHADOW_CUBE, true });
249}
250
251/**
252 * @brief Gets type of texture
253 * @param[in] tex Pointer to \ref C3D_Tex.
254 */
256{
257 return (GPU_TEXTURE_MODE_PARAM)((tex->param>>28)&0x7);
258}
259
260/**
261 * @brief Gets pointer to texture image
262 * @param[in] tex Pointer to \ref C3D_Tex.
263 * @param[in] data Pointer texture face.
264 * @param[in] level Specifies mipmap level.
265 * @param[out] size Can be used to get the size of the image data.
266 * @returns Pointer to raw image data.
267 */
268static inline void* C3D_TexGetImagePtr(C3D_Tex* tex, void* data, int level, u32* size)
269{
270 if (size) *size = level >= 0 ? C3D_TexCalcLevelSize(tex->size, level) : C3D_TexCalcTotalSize(tex->size, tex->maxLevel);
271 if (!level) return data;
272 return (u8*)data + (level > 0 ? C3D_TexCalcTotalSize(tex->size, level-1) : 0);
273}
274
275/**
276 * @brief Gets pointer to 2D texture image
277 * @param[in] tex Pointer to \ref C3D_Tex.
278 * @param[in] level Specifies mipmap level.
279 * @param[out] size Can be used to get the size of the image data.
280 * @returns Pointer to raw image data.
281 */
282static inline void* C3D_Tex2DGetImagePtr(C3D_Tex* tex, int level, u32* size)
283{
284 return C3D_TexGetImagePtr(tex, tex->data, level, size);
285}
286
287/**
288 * @brief Gets pointer to cubemap texture image
289 * @param[in] tex Pointer to \ref C3D_Tex.
290 * @param[in] face Specifies the cubemap texture face.
291 * @param[in] level Specifies mipmap level.
292 * @param[out] size Can be used to get the size of the image data.
293 * @returns Pointer to raw image data.
294 */
295static inline void* C3D_TexCubeGetImagePtr(C3D_Tex* tex, GPU_TEXFACE face, int level, u32* size)
296{
297 return C3D_TexGetImagePtr(tex, tex->cube->data[face], level, size);
298}
299
300/**
301 * @brief Copies raw texture data into standard 2D texture
302 * @param[out] tex Pointer to \ref C3D_Tex.
303 * @param[in] data Pointer to raw texture data.
304 */
305static inline void C3D_TexUpload(C3D_Tex* tex, const void* data)
306{
307 C3D_TexLoadImage(tex, data, GPU_TEXFACE_2D, 0);
308}
309
310/**
311 * @brief Configures texture magnification and minification filters
312 * @param[out] tex Pointer to \ref C3D_Tex.
313 * @param[in] magFilter Specifies the filtering to use when magnifying the the texture.
314 * @param[in] minFilter Specifies the filtering to use when minifying the the texture.
315 */
316static inline void C3D_TexSetFilter(C3D_Tex* tex, GPU_TEXTURE_FILTER_PARAM magFilter, GPU_TEXTURE_FILTER_PARAM minFilter)
317{
319 tex->param |= GPU_TEXTURE_MAG_FILTER(magFilter) | GPU_TEXTURE_MIN_FILTER(minFilter);
320}
321
322/**
323 * @brief Configures texture mipmap minification filters
324 * @param[out] tex Pointer to \ref C3D_Tex.
325 * @param[in] filter Specifies the filtering to use when minifying the the mipmap.
326 */
328{
329 tex->param &= ~GPU_TEXTURE_MIP_FILTER(GPU_LINEAR);
330 tex->param |= GPU_TEXTURE_MIP_FILTER(filter);
331}
332
333/**
334 * @brief Configures texture wrapping options
335 * @param[out] tex Pointer to \ref C3D_Tex.
336 * @param[in] wrapS Specifies the texture wrapping mode for texture coordinate S (aka U).
337 * @param[in] wrapT Specifies the texture wrapping mode for texture coordinate T (aka V).
338 */
340{
341 tex->param &= ~(GPU_TEXTURE_WRAP_S(3) | GPU_TEXTURE_WRAP_T(3));
342 tex->param |= GPU_TEXTURE_WRAP_S(wrapS) | GPU_TEXTURE_WRAP_T(wrapT);
343}
344
345/**
346 * @brief Configures texture level of detail bias used to select the correct mipmap during sampling
347 * @param[out] tex Pointer to \ref C3D_Tex.
348 * @param[in] lodBias Specifies the texture level of detail bias.
349 */
350static inline void C3D_TexSetLodBias(C3D_Tex* tex, float lodBias)
351{
352 int iLodBias = (int)(lodBias*0x100);
353 if (iLodBias > 0xFFF)
354 iLodBias = 0xFFF;
355 else if (iLodBias < -0x1000)
356 iLodBias = -0x1000;
357 tex->lodBias = iLodBias & 0x1FFF;
358}
#define GPU_TEXTURE_MAG_FILTER(v)
#define GPU_TEXTURE_MIP_FILTER(v)
GPU_TEXTURE_FILTER_PARAM
GPU_LINEAR
GPU_TEXFACE
GPU_TEXFACE_2D
GPU_TEXTURE_MODE_PARAM
GPU_TEX_SHADOW_2D
GPU_TEX_SHADOW_CUBE
GPU_TEX_2D
GPU_TEX_CUBE_MAP
GPU_TEXCOLOR
GPU_RGBA8
#define GPU_TEXTURE_WRAP_S(v)
#define GPU_TEXTURE_WRAP_T(v)
#define GPU_TEXTURE_MIN_FILTER(v)
GPU_TEXTURE_WRAP_PARAM
Cubemap texture data.
Definition texture.h:10
Texture data.
Definition texture.h:16
static bool C3D_TexInit(C3D_Tex *tex, u16 width, u16 height, GPU_TEXCOLOR format)
Initializes standard 2D texture.
Definition texture.h:174
static bool C3D_TexInitShadow(C3D_Tex *tex, u16 width, u16 height)
Initializes 2D shadowmap texture.
Definition texture.h:231
static void * C3D_TexGetImagePtr(C3D_Tex *tex, void *data, int level, u32 *size)
Gets pointer to texture image.
Definition texture.h:268
static bool C3D_TexInitMipmap(C3D_Tex *tex, u16 width, u16 height, GPU_TEXCOLOR format)
Initializes standard 2D texture with mipmap Maximum miplevel is calculated using C3D_TexCalcMaxLevel(...
Definition texture.h:189
struct CTR_ALIGN(8)
Parameters for C3D_TexInitWithParams()
Definition texture.h:51
void C3D_TexFlush(C3D_Tex *tex)
Flushes texture data from cache into memory.
void C3D_TexBind(int unitId, C3D_Tex *tex)
Binds C3D_Tex to texture unit.
static void * C3D_Tex2DGetImagePtr(C3D_Tex *tex, int level, u32 *size)
Gets pointer to 2D texture image.
Definition texture.h:282
static int C3D_TexCalcMaxLevel(u32 width, u32 height)
Calculates maximum mipmap level for given texture size.
Definition texture.h:123
static void C3D_TexUpload(C3D_Tex *tex, const void *data)
Copies raw texture data into standard 2D texture.
Definition texture.h:305
static bool C3D_TexInitVRAM(C3D_Tex *tex, u16 width, u16 height, GPU_TEXCOLOR format)
Initializes 2D texture in VRAM.
Definition texture.h:218
static GPU_TEXTURE_MODE_PARAM C3D_TexGetType(C3D_Tex *tex)
Gets type of texture.
Definition texture.h:255
static bool C3D_TexInitCube(C3D_Tex *tex, C3D_TexCube *cube, u16 width, u16 height, GPU_TEXCOLOR format)
Initializes cubemap texture.
Definition texture.h:204
static void C3D_TexSetFilter(C3D_Tex *tex, GPU_TEXTURE_FILTER_PARAM magFilter, GPU_TEXTURE_FILTER_PARAM minFilter)
Configures texture magnification and minification filters.
Definition texture.h:316
static void C3D_TexSetLodBias(C3D_Tex *tex, float lodBias)
Configures texture level of detail bias used to select the correct mipmap during sampling.
Definition texture.h:350
void C3D_TexGenerateMipmap(C3D_Tex *tex, GPU_TEXFACE face)
Generates mipmaps for C3D_Tex using previously specified max level The max level should have been spe...
void C3D_TexLoadImage(C3D_Tex *tex, const void *data, GPU_TEXFACE face, int level)
Copies raw texture data into C3D_Tex.
static void C3D_TexSetFilterMipmap(C3D_Tex *tex, GPU_TEXTURE_FILTER_PARAM filter)
Configures texture mipmap minification filters.
Definition texture.h:327
void C3D_TexShadowParams(bool perspective, float bias)
Configues texunit0 shadow depth texture properties.
static u32 C3D_TexCalcTotalSize(u32 size, int maxLevel)
Calculates total size of mipmap texture data.
Definition texture.h:145
void C3D_TexDelete(C3D_Tex *tex)
Deletes texture data.
static bool C3D_TexInitShadowCube(C3D_Tex *tex, C3D_TexCube *cube, u16 width, u16 height)
Initializes shadowmap cubemap texture.
Definition texture.h:245
static void C3D_TexSetWrap(C3D_Tex *tex, GPU_TEXTURE_WRAP_PARAM wrapS, GPU_TEXTURE_WRAP_PARAM wrapT)
Configures texture wrapping options.
Definition texture.h:339
static u32 C3D_TexCalcLevelSize(u32 size, int level)
Calculates size of mipmap level.
Definition texture.h:134
static void * C3D_TexCubeGetImagePtr(C3D_Tex *tex, GPU_TEXFACE face, int level, u32 *size)
Gets pointer to cubemap texture image.
Definition texture.h:295
bool C3D_TexInitWithParams(C3D_Tex *tex, C3D_TexCube *cube, C3D_TexInitParams p)
Initializes texture with specified parameters.
uint8_t u8
uint16_t u16
uint32_t u32