153f4eebdaf5b40ae9a5df307397c05e98820fe4
[mesa.git] / src / gallium / drivers / r300 / r300_texture.h
1 /*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22
23 #ifndef R300_TEXTURE_H
24 #define R300_TEXTURE_H
25
26 #include "pipe/p_video_state.h"
27 #include "util/u_format.h"
28
29 #include "r300_reg.h"
30
31 struct r300_texture;
32
33 void r300_init_screen_texture_functions(struct pipe_screen* screen);
34
35 unsigned r300_texture_get_stride(struct r300_screen* screen,
36 struct r300_texture* tex, unsigned level);
37
38 unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
39 unsigned zslice, unsigned face);
40
41 void r300_texture_reinterpret_format(struct pipe_screen *screen,
42 struct pipe_texture *tex,
43 enum pipe_format new_format);
44
45 /* Translate a pipe_format into a useful texture format for sampling.
46 *
47 * R300_EASY_TX_FORMAT swizzles the texture.
48 * Note the signature of R300_EASY_TX_FORMAT:
49 * R300_EASY_TX_FORMAT(B, G, R, A, FORMAT);
50 *
51 * The FORMAT specifies how the texture sampler will treat the texture, and
52 * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
53 static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
54 {
55 uint32_t result = 0;
56 const struct util_format_description *desc;
57 unsigned components = 0, i;
58 boolean uniform = TRUE;
59 const uint32_t swizzle_shift[4] = {
60 R300_TX_FORMAT_R_SHIFT,
61 R300_TX_FORMAT_G_SHIFT,
62 R300_TX_FORMAT_B_SHIFT,
63 R300_TX_FORMAT_A_SHIFT
64 };
65 const uint32_t sign_bit[4] = {
66 R300_TX_FORMAT_SIGNED_X,
67 R300_TX_FORMAT_SIGNED_Y,
68 R300_TX_FORMAT_SIGNED_Z,
69 R300_TX_FORMAT_SIGNED_W,
70 };
71
72 desc = util_format_description(format);
73
74 /* Colorspace (return non-RGB formats directly). */
75 switch (desc->colorspace) {
76 /* Depth stencil formats. */
77 case UTIL_FORMAT_COLORSPACE_ZS:
78 switch (format) {
79 case PIPE_FORMAT_Z16_UNORM:
80 return R300_EASY_TX_FORMAT(X, X, X, X, X16);
81 case PIPE_FORMAT_Z24X8_UNORM:
82 case PIPE_FORMAT_Z24S8_UNORM:
83 return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
84 default:
85 return ~0; /* Unsupported. */
86 }
87
88 /* YUV formats. */
89 case UTIL_FORMAT_COLORSPACE_YUV:
90 result |= R300_TX_FORMAT_YUV_TO_RGB;
91
92 switch (format) {
93 case PIPE_FORMAT_YCBCR:
94 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
95 case PIPE_FORMAT_YCBCR_REV:
96 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
97 default:
98 return ~0; /* Unsupported/unknown. */
99 }
100
101 /* Add gamma correction. */
102 case UTIL_FORMAT_COLORSPACE_SRGB:
103 result |= R300_TX_FORMAT_GAMMA;
104 break;
105
106 default:;
107 }
108
109 /* Add swizzle. */
110 for (i = 0; i < 4; i++) {
111 switch (desc->swizzle[i]) {
112 case UTIL_FORMAT_SWIZZLE_X:
113 case UTIL_FORMAT_SWIZZLE_NONE:
114 result |= R300_TX_FORMAT_X << swizzle_shift[i];
115 break;
116 case UTIL_FORMAT_SWIZZLE_Y:
117 result |= R300_TX_FORMAT_Y << swizzle_shift[i];
118 break;
119 case UTIL_FORMAT_SWIZZLE_Z:
120 result |= R300_TX_FORMAT_Z << swizzle_shift[i];
121 break;
122 case UTIL_FORMAT_SWIZZLE_W:
123 result |= R300_TX_FORMAT_W << swizzle_shift[i];
124 break;
125 case UTIL_FORMAT_SWIZZLE_0:
126 result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
127 break;
128 case UTIL_FORMAT_SWIZZLE_1:
129 result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
130 break;
131 default:
132 return ~0; /* Unsupported. */
133 }
134 }
135
136 /* Compressed formats. */
137 if (desc->layout == UTIL_FORMAT_LAYOUT_DXT) {
138 switch (format) {
139 case PIPE_FORMAT_DXT1_RGB:
140 case PIPE_FORMAT_DXT1_RGBA:
141 case PIPE_FORMAT_DXT1_SRGB:
142 case PIPE_FORMAT_DXT1_SRGBA:
143 return R300_TX_FORMAT_DXT1 | result;
144 case PIPE_FORMAT_DXT3_RGBA:
145 case PIPE_FORMAT_DXT3_SRGBA:
146 return R300_TX_FORMAT_DXT3 | result;
147 case PIPE_FORMAT_DXT5_RGBA:
148 case PIPE_FORMAT_DXT5_SRGBA:
149 return R300_TX_FORMAT_DXT5 | result;
150 default:
151 return ~0; /* Unsupported/unknown. */
152 }
153 }
154
155 /* Get the number of components. */
156 for (i = 0; i < 4; i++) {
157 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
158 ++components;
159 }
160 }
161
162 /* Add sign. */
163 for (i = 0; i < components; i++) {
164 if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
165 result |= sign_bit[i];
166 }
167 }
168
169 /* See whether the components are of the same size. */
170 for (i = 1; i < components; i++) {
171 uniform = uniform && desc->channel[0].size == desc->channel[i].size;
172 }
173
174 /* Non-uniform formats. */
175 if (!uniform) {
176 switch (components) {
177 case 3:
178 if (desc->channel[0].size == 5 &&
179 desc->channel[1].size == 6 &&
180 desc->channel[2].size == 5) {
181 return R300_TX_FORMAT_Z5Y6X5 | result;
182 }
183 if (desc->channel[0].size == 5 &&
184 desc->channel[1].size == 5 &&
185 desc->channel[2].size == 6) {
186 return R300_TX_FORMAT_Z6Y5X5 | result;
187 }
188 return ~0; /* Unsupported/unknown. */
189
190 case 4:
191 if (desc->channel[0].size == 5 &&
192 desc->channel[1].size == 5 &&
193 desc->channel[2].size == 5 &&
194 desc->channel[3].size == 1) {
195 return R300_TX_FORMAT_W1Z5Y5X5 | result;
196 }
197 if (desc->channel[0].size == 10 &&
198 desc->channel[1].size == 10 &&
199 desc->channel[2].size == 10 &&
200 desc->channel[3].size == 2) {
201 return R300_TX_FORMAT_W2Z10Y10X10 | result;
202 }
203 }
204 return ~0; /* Unsupported/unknown. */
205 }
206
207 /* And finally, uniform formats. */
208 switch (desc->channel[0].type) {
209 case UTIL_FORMAT_TYPE_UNSIGNED:
210 case UTIL_FORMAT_TYPE_SIGNED:
211 if (!desc->channel[0].normalized) {
212 return ~0;
213 }
214
215 switch (desc->channel[0].size) {
216 case 4:
217 switch (components) {
218 case 2:
219 return R300_TX_FORMAT_Y4X4 | result;
220 case 4:
221 return R300_TX_FORMAT_W4Z4Y4X4 | result;
222 }
223 return ~0;
224
225 case 8:
226 switch (components) {
227 case 1:
228 return R300_TX_FORMAT_X8 | result;
229 case 2:
230 return R300_TX_FORMAT_Y8X8 | result;
231 case 4:
232 return R300_TX_FORMAT_W8Z8Y8X8 | result;
233 }
234 return ~0;
235
236 case 16:
237 switch (components) {
238 case 1:
239 return R300_TX_FORMAT_X16 | result;
240 case 2:
241 return R300_TX_FORMAT_Y16X16 | result;
242 case 4:
243 return R300_TX_FORMAT_W16Z16Y16X16 | result;
244 }
245 }
246 return ~0;
247
248 /* XXX Enable float textures here. */
249 #if 0
250 case UTIL_FORMAT_TYPE_FLOAT:
251 switch (desc->channel[0].size) {
252 case 16:
253 switch (components) {
254 case 1:
255 return R300_TX_FORMAT_16F | result;
256 case 2:
257 return R300_TX_FORMAT_16F_16F | result;
258 case 4:
259 return R300_TX_FORMAT_16F_16F_16F_16F | result;
260 }
261 return ~0;
262
263 case 32:
264 switch (components) {
265 case 1:
266 return R300_TX_FORMAT_32F | result;
267 case 2:
268 return R300_TX_FORMAT_32F_32F | result;
269 case 4:
270 return R300_TX_FORMAT_32F_32F_32F_32F | result;
271 }
272 }
273 #endif
274 }
275
276 return ~0; /* Unsupported/unknown. */
277 }
278
279 struct r300_video_surface
280 {
281 struct pipe_video_surface base;
282 struct pipe_texture *tex;
283 };
284
285 static INLINE struct r300_video_surface *
286 r300_video_surface(struct pipe_video_surface *pvs)
287 {
288 return (struct r300_video_surface *)pvs;
289 }
290
291 #ifndef R300_WINSYS_H
292
293 boolean r300_get_texture_buffer(struct pipe_screen* screen,
294 struct pipe_texture* texture,
295 struct pipe_buffer** buffer,
296 unsigned* stride);
297
298 #endif /* R300_WINSYS_H */
299
300 #endif /* R300_TEXTURE_H */