citro3d  1.2.0
texture.h
Go to the documentation of this file.
1 #pragma once
2 #include "types.h"
3 
4 typedef struct
5 {
6  void* data[6];
8 
9 typedef struct
10 {
11  union
12  {
13  void* data;
15  };
16 
17  GPU_TEXCOLOR fmt : 4;
18  size_t size : 28;
19 
20  union
21  {
22  u32 dim;
23  struct
24  {
25  u16 height;
26  u16 width;
27  };
28  };
29 
30  u32 param;
31  u32 border;
32  union
33  {
34  u32 lodParam;
35  struct
36  {
37  u16 lodBias;
40  };
41  };
42 } C3D_Tex;
43 
44 typedef struct ALIGN(8)
45 {
46  u16 width;
47  u16 height;
48  u8 maxLevel : 4;
49  GPU_TEXCOLOR format : 4;
50  GPU_TEXTURE_MODE_PARAM type : 3;
51  bool onVram : 1;
53 
55 void C3D_TexLoadImage(C3D_Tex* tex, const void* data, GPU_TEXFACE face, int level);
56 void C3D_TexGenerateMipmap(C3D_Tex* tex, GPU_TEXFACE face);
57 void C3D_TexBind(int unitId, C3D_Tex* tex);
58 void C3D_TexFlush(C3D_Tex* tex);
59 void C3D_TexDelete(C3D_Tex* tex);
60 
61 void C3D_TexShadowParams(bool perspective, float bias);
62 
63 static inline int C3D_TexCalcMaxLevel(u32 width, u32 height)
64 {
65  return (31-__builtin_clz(width < height ? width : height)) - 3; // avoid sizes smaller than 8
66 }
67 
68 static inline u32 C3D_TexCalcLevelSize(u32 size, int level)
69 {
70  return size >> (2*level);
71 }
72 
73 static inline u32 C3D_TexCalcTotalSize(u32 size, int maxLevel)
74 {
75  /*
76  S = s + sr + sr^2 + sr^3 + ... + sr^n
77  Sr = sr + sr^2 + sr^3 + ... + sr^(n+1)
78  S-Sr = s - sr^(n+1)
79  S(1-r) = s(1 - r^(n+1))
80  S = s (1 - r^(n+1)) / (1-r)
81 
82  r = 1/4
83  1-r = 3/4
84 
85  S = 4s (1 - (1/4)^(n+1)) / 3
86  S = 4s (1 - 1/4^(n+1)) / 3
87  S = (4/3) (s - s/4^(n+1))
88  S = (4/3) (s - s/(1<<(2n+2)))
89  S = (4/3) (s - s>>(2n+2))
90  */
91  return (size - C3D_TexCalcLevelSize(size,maxLevel+1)) * 4 / 3;
92 }
93 
94 static inline bool C3D_TexInit(C3D_Tex* tex, u16 width, u16 height, GPU_TEXCOLOR format)
95 {
96  return C3D_TexInitWithParams(tex, NULL,
97  (C3D_TexInitParams){ width, height, 0, format, GPU_TEX_2D, false });
98 }
99 
100 static inline bool C3D_TexInitMipmap(C3D_Tex* tex, u16 width, u16 height, GPU_TEXCOLOR format)
101 {
102  return C3D_TexInitWithParams(tex, NULL,
103  (C3D_TexInitParams){ width, height, (u8)C3D_TexCalcMaxLevel(width, height), format, GPU_TEX_2D, false });
104 }
105 
106 static inline bool C3D_TexInitCube(C3D_Tex* tex, C3D_TexCube* cube, u16 width, u16 height, GPU_TEXCOLOR format)
107 {
108  return C3D_TexInitWithParams(tex, cube,
109  (C3D_TexInitParams){ width, height, 0, format, GPU_TEX_CUBE_MAP, false });
110 }
111 
112 static inline bool C3D_TexInitVRAM(C3D_Tex* tex, u16 width, u16 height, GPU_TEXCOLOR format)
113 {
114  return C3D_TexInitWithParams(tex, NULL,
115  (C3D_TexInitParams){ width, height, 0, format, GPU_TEX_2D, true });
116 }
117 
118 static inline bool C3D_TexInitShadow(C3D_Tex* tex, u16 width, u16 height)
119 {
120  return C3D_TexInitWithParams(tex, NULL,
121  (C3D_TexInitParams){ width, height, 0, GPU_RGBA8, GPU_TEX_SHADOW_2D, true });
122 }
123 
124 static inline bool C3D_TexInitShadowCube(C3D_Tex* tex, C3D_TexCube* cube, u16 width, u16 height)
125 {
126  return C3D_TexInitWithParams(tex, cube,
127  (C3D_TexInitParams){ width, height, 0, GPU_RGBA8, GPU_TEX_SHADOW_CUBE, true });
128 }
129 
130 static inline GPU_TEXTURE_MODE_PARAM C3D_TexGetType(C3D_Tex* tex)
131 {
132  return (GPU_TEXTURE_MODE_PARAM)((tex->param>>28)&0x7);
133 }
134 
135 static inline void* C3D_TexGetImagePtr(C3D_Tex* tex, void* data, int level, u32* size)
136 {
137  if (size) *size = level >= 0 ? C3D_TexCalcLevelSize(tex->size, level) : C3D_TexCalcTotalSize(tex->size, tex->maxLevel);
138  if (!level) return data;
139  return (u8*)data + (level > 0 ? C3D_TexCalcTotalSize(tex->size, level-1) : 0);
140 }
141 
142 static inline void* C3D_Tex2DGetImagePtr(C3D_Tex* tex, int level, u32* size)
143 {
144  return C3D_TexGetImagePtr(tex, tex->data, level, size);
145 }
146 
147 static inline void* C3D_TexCubeGetImagePtr(C3D_Tex* tex, GPU_TEXFACE face, int level, u32* size)
148 {
149  return C3D_TexGetImagePtr(tex, tex->cube->data[face], level, size);
150 }
151 
152 static inline void C3D_TexUpload(C3D_Tex* tex, const void* data)
153 {
154  C3D_TexLoadImage(tex, data, GPU_TEXFACE_2D, 0);
155 }
156 
157 static inline void C3D_TexSetFilter(C3D_Tex* tex, GPU_TEXTURE_FILTER_PARAM magFilter, GPU_TEXTURE_FILTER_PARAM minFilter)
158 {
159  tex->param &= ~(GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR));
160  tex->param |= GPU_TEXTURE_MAG_FILTER(magFilter) | GPU_TEXTURE_MIN_FILTER(minFilter);
161 }
162 
163 static inline void C3D_TexSetFilterMipmap(C3D_Tex* tex, GPU_TEXTURE_FILTER_PARAM filter)
164 {
165  tex->param &= ~GPU_TEXTURE_MIP_FILTER(GPU_LINEAR);
166  tex->param |= GPU_TEXTURE_MIP_FILTER(filter);
167 }
168 
169 static inline void C3D_TexSetWrap(C3D_Tex* tex, GPU_TEXTURE_WRAP_PARAM wrapS, GPU_TEXTURE_WRAP_PARAM wrapT)
170 {
171  tex->param &= ~(GPU_TEXTURE_WRAP_S(3) | GPU_TEXTURE_WRAP_T(3));
172  tex->param |= GPU_TEXTURE_WRAP_S(wrapS) | GPU_TEXTURE_WRAP_T(wrapT);
173 }
174 
175 static inline void C3D_TexSetLodBias(C3D_Tex* tex, float lodBias)
176 {
177  int iLodBias = (int)(lodBias*0x100);
178  if (iLodBias > 0xFFF)
179  iLodBias = 0xFFF;
180  else if (iLodBias < -0x1000)
181  iLodBias = -0x1000;
182  tex->lodBias = iLodBias & 0x1FFF;
183 }
Definition: texture.h:5
void * data[6]
Definition: texture.h:6
Definition: texture.h:10
u16 width
Definition: texture.h:26
C3D_TexCube * cube
Definition: texture.h:14
size_t size
Definition: texture.h:18
u16 lodBias
Definition: texture.h:37
GPU_TEXCOLOR fmt
Definition: texture.h:17
u32 lodParam
Definition: texture.h:34
u32 border
Definition: texture.h:31
u16 height
Definition: texture.h:25
void * data
Definition: texture.h:13
u8 maxLevel
Definition: texture.h:38
u32 dim
Definition: texture.h:22
u32 param
Definition: texture.h:30
u8 minLevel
Definition: texture.h:39
static bool C3D_TexInit(C3D_Tex *tex, u16 width, u16 height, GPU_TEXCOLOR format)
Definition: texture.h:94
static bool C3D_TexInitShadow(C3D_Tex *tex, u16 width, u16 height)
Definition: texture.h:118
static bool C3D_TexInitMipmap(C3D_Tex *tex, u16 width, u16 height, GPU_TEXCOLOR format)
Definition: texture.h:100
void C3D_TexFlush(C3D_Tex *tex)
Definition: texture.c:242
void C3D_TexBind(int unitId, C3D_Tex *tex)
Definition: texture.c:228
static int C3D_TexCalcMaxLevel(u32 width, u32 height)
Definition: texture.h:63
static void C3D_TexUpload(C3D_Tex *tex, const void *data)
Definition: texture.h:152
static bool C3D_TexInitVRAM(C3D_Tex *tex, u16 width, u16 height, GPU_TEXCOLOR format)
Definition: texture.h:112
static void * C3D_TexCubeGetImagePtr(C3D_Tex *tex, GPU_TEXFACE face, int level, u32 *size)
Definition: texture.h:147
static GPU_TEXTURE_MODE_PARAM C3D_TexGetType(C3D_Tex *tex)
Definition: texture.h:130
struct ALIGN(8)
Definition: texture.h:44
static void * C3D_TexGetImagePtr(C3D_Tex *tex, void *data, int level, u32 *size)
Definition: texture.h:135
static bool C3D_TexInitCube(C3D_Tex *tex, C3D_TexCube *cube, u16 width, u16 height, GPU_TEXCOLOR format)
Definition: texture.h:106
static void C3D_TexSetFilter(C3D_Tex *tex, GPU_TEXTURE_FILTER_PARAM magFilter, GPU_TEXTURE_FILTER_PARAM minFilter)
Definition: texture.h:157
static void C3D_TexSetLodBias(C3D_Tex *tex, float lodBias)
Definition: texture.h:175
void C3D_TexGenerateMipmap(C3D_Tex *tex, GPU_TEXFACE face)
Definition: texture.c:161
void C3D_TexLoadImage(C3D_Tex *tex, const void *data, GPU_TEXFACE face, int level)
Definition: texture.c:118
static void C3D_TexSetFilterMipmap(C3D_Tex *tex, GPU_TEXTURE_FILTER_PARAM filter)
Definition: texture.h:163
void C3D_TexShadowParams(bool perspective, float bias)
Definition: texture.c:256
static u32 C3D_TexCalcTotalSize(u32 size, int maxLevel)
Definition: texture.h:73
void C3D_TexDelete(C3D_Tex *tex)
Definition: texture.c:248
static bool C3D_TexInitShadowCube(C3D_Tex *tex, C3D_TexCube *cube, u16 width, u16 height)
Definition: texture.h:124
C3D_TexInitParams
Definition: texture.h:52
static void C3D_TexSetWrap(C3D_Tex *tex, GPU_TEXTURE_WRAP_PARAM wrapS, GPU_TEXTURE_WRAP_PARAM wrapT)
Definition: texture.h:169
static u32 C3D_TexCalcLevelSize(u32 size, int level)
Definition: texture.h:68
bool C3D_TexInitWithParams(C3D_Tex *tex, C3D_TexCube *cube, C3D_TexInitParams p)
Definition: texture.c:69
static void * C3D_Tex2DGetImagePtr(C3D_Tex *tex, int level, u32 *size)
Definition: texture.h:142
float24Uniform_s * data
Definition: uniforms.c:16