Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / state_trackers / python / st_sample.c
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include "pipe/p_compiler.h"
30 #include "pipe/p_format.h"
31 #include "pipe/p_state.h"
32 #include "pipe/p_inlines.h"
33 #include "util/u_format.h"
34 #include "util/u_tile.h"
35 #include "util/u_math.h"
36 #include "util/u_memory.h"
37
38 #include "st_device.h"
39 #include "st_sample.h"
40
41
42 /**
43 * Use our own pseudo random generator to ensure consistent runs among
44 * multiple runs and platforms.
45 *
46 * @sa http://en.wikipedia.org/wiki/Linear_congruential_generator
47 */
48 static uint32_t st_random(void) {
49 static uint64_t seed = UINT64_C(0xbb9a063afb0a739d);
50
51 seed = UINT64_C(134775813) * seed + UINT64_C(1);
52
53 return (uint16_t)(seed >> 32);
54 }
55
56
57 /**
58 * We don't want to include the patent-encumbered DXT code here, so instead
59 * we store several uncompressed/compressed data pairs for hardware testing
60 * purposes.
61 */
62 struct dxt_data
63 {
64 uint8_t rgba[16*4];
65 uint8_t raw[16];
66 };
67
68
69 static const struct dxt_data
70 dxt1_rgb_data[] = {
71 {
72 {
73 0x99, 0xb0, 0x8e, 0xff,
74 0x5d, 0x62, 0x89, 0xff,
75 0x99, 0xb0, 0x8e, 0xff,
76 0x99, 0xb0, 0x8e, 0xff,
77 0xd6, 0xff, 0x94, 0xff,
78 0x5d, 0x62, 0x89, 0xff,
79 0x99, 0xb0, 0x8e, 0xff,
80 0xd6, 0xff, 0x94, 0xff,
81 0x5d, 0x62, 0x89, 0xff,
82 0x5d, 0x62, 0x89, 0xff,
83 0x99, 0xb0, 0x8e, 0xff,
84 0x21, 0x14, 0x84, 0xff,
85 0x5d, 0x62, 0x89, 0xff,
86 0x21, 0x14, 0x84, 0xff,
87 0x21, 0x14, 0x84, 0xff,
88 0x99, 0xb0, 0x8e, 0xff
89 },
90 {0xf2, 0xd7, 0xb0, 0x20, 0xae, 0x2c, 0x6f, 0x97}
91 },
92 {
93 {
94 0xb5, 0xcf, 0x9c, 0xff,
95 0x83, 0x8c, 0x8b, 0xff,
96 0x21, 0x08, 0x6b, 0xff,
97 0x83, 0x8c, 0x8b, 0xff,
98 0x52, 0x4a, 0x7b, 0xff,
99 0x83, 0x8c, 0x8b, 0xff,
100 0x83, 0x8c, 0x8b, 0xff,
101 0xb5, 0xcf, 0x9c, 0xff,
102 0x21, 0x08, 0x6b, 0xff,
103 0xb5, 0xcf, 0x9c, 0xff,
104 0x83, 0x8c, 0x8b, 0xff,
105 0x52, 0x4a, 0x7b, 0xff,
106 0xb5, 0xcf, 0x9c, 0xff,
107 0x83, 0x8c, 0x8b, 0xff,
108 0x52, 0x4a, 0x7b, 0xff,
109 0x83, 0x8c, 0x8b, 0xff
110 },
111 {0x73, 0xb6, 0x4d, 0x20, 0x98, 0x2b, 0xe1, 0xb8}
112 },
113 {
114 {
115 0x00, 0x2c, 0xff, 0xff,
116 0x94, 0x8d, 0x7b, 0xff,
117 0x4a, 0x5c, 0xbd, 0xff,
118 0x4a, 0x5c, 0xbd, 0xff,
119 0x4a, 0x5c, 0xbd, 0xff,
120 0x94, 0x8d, 0x7b, 0xff,
121 0x94, 0x8d, 0x7b, 0xff,
122 0x94, 0x8d, 0x7b, 0xff,
123 0xde, 0xbe, 0x39, 0xff,
124 0x94, 0x8d, 0x7b, 0xff,
125 0xde, 0xbe, 0x39, 0xff,
126 0xde, 0xbe, 0x39, 0xff,
127 0xde, 0xbe, 0x39, 0xff,
128 0xde, 0xbe, 0x39, 0xff,
129 0xde, 0xbe, 0x39, 0xff,
130 0x94, 0x8d, 0x7b, 0xff
131 },
132 {0xe7, 0xdd, 0x7f, 0x01, 0xf9, 0xab, 0x08, 0x80}
133 },
134 {
135 {
136 0x6b, 0x24, 0x21, 0xff,
137 0x7b, 0x4f, 0x5d, 0xff,
138 0x7b, 0x4f, 0x5d, 0xff,
139 0x8b, 0x7a, 0x99, 0xff,
140 0x7b, 0x4f, 0x5d, 0xff,
141 0x7b, 0x4f, 0x5d, 0xff,
142 0x6b, 0x24, 0x21, 0xff,
143 0x8b, 0x7a, 0x99, 0xff,
144 0x9c, 0xa6, 0xd6, 0xff,
145 0x6b, 0x24, 0x21, 0xff,
146 0x7b, 0x4f, 0x5d, 0xff,
147 0x8b, 0x7a, 0x99, 0xff,
148 0x6b, 0x24, 0x21, 0xff,
149 0x8b, 0x7a, 0x99, 0xff,
150 0x7b, 0x4f, 0x5d, 0xff,
151 0x9c, 0xa6, 0xd6, 0xff
152 },
153 {0x3a, 0x9d, 0x24, 0x69, 0xbd, 0x9f, 0xb4, 0x39}
154 }
155 };
156
157
158 static const struct dxt_data
159 dxt1_rgba_data[] = {
160 {
161 {
162 0x00, 0x00, 0x00, 0x00,
163 0x4e, 0xaa, 0x90, 0xff,
164 0x4e, 0xaa, 0x90, 0xff,
165 0x00, 0x00, 0x00, 0x00,
166 0x4e, 0xaa, 0x90, 0xff,
167 0x29, 0xff, 0xff, 0xff,
168 0x00, 0x00, 0x00, 0x00,
169 0x4e, 0xaa, 0x90, 0xff,
170 0x73, 0x55, 0x21, 0xff,
171 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00,
173 0x4e, 0xaa, 0x90, 0xff,
174 0x4e, 0xaa, 0x90, 0xff,
175 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00,
177 0x4e, 0xaa, 0x90, 0xff
178 },
179 {0xff, 0x2f, 0xa4, 0x72, 0xeb, 0xb2, 0xbd, 0xbe}
180 },
181 {
182 {
183 0xb5, 0xe3, 0x63, 0xff,
184 0x00, 0x00, 0x00, 0x00,
185 0x6b, 0x24, 0x84, 0xff,
186 0xb5, 0xe3, 0x63, 0xff,
187 0x00, 0x00, 0x00, 0x00,
188 0xb5, 0xe3, 0x63, 0xff,
189 0x00, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00,
193 0x6b, 0x24, 0x84, 0xff,
194 0x6b, 0x24, 0x84, 0xff,
195 0x00, 0x00, 0x00, 0x00,
196 0xb5, 0xe3, 0x63, 0xff,
197 0x90, 0x83, 0x73, 0xff,
198 0xb5, 0xe3, 0x63, 0xff
199 },
200 {0x30, 0x69, 0x0c, 0xb7, 0x4d, 0xf7, 0x0f, 0x67}
201 },
202 {
203 {
204 0x00, 0x00, 0x00, 0x00,
205 0xc6, 0x86, 0x8c, 0xff,
206 0xc6, 0x86, 0x8c, 0xff,
207 0x21, 0x65, 0x42, 0xff,
208 0x21, 0x65, 0x42, 0xff,
209 0x21, 0x65, 0x42, 0xff,
210 0x21, 0x65, 0x42, 0xff,
211 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00,
213 0x21, 0x65, 0x42, 0xff,
214 0xc6, 0x86, 0x8c, 0xff,
215 0x00, 0x00, 0x00, 0x00,
216 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00,
219 0xc6, 0x86, 0x8c, 0xff
220 },
221 {0x28, 0x23, 0x31, 0xc4, 0x17, 0xc0, 0xd3, 0x7f}
222 },
223 {
224 {
225 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00,
228 0xc6, 0xe3, 0x9c, 0xff,
229 0x7b, 0x1c, 0x52, 0xff,
230 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x00, 0x00,
234 0x7b, 0x1c, 0x52, 0xff,
235 0x00, 0x00, 0x00, 0x00,
236 0x7b, 0x1c, 0x52, 0xff,
237 0xa0, 0x7f, 0x77, 0xff,
238 0xc6, 0xe3, 0x9c, 0xff,
239 0x00, 0x00, 0x00, 0x00,
240 0xa0, 0x7f, 0x77, 0xff
241 },
242 {0xea, 0x78, 0x13, 0xc7, 0x7f, 0xfc, 0x33, 0xb6}
243 },
244 };
245
246
247 static const struct dxt_data
248 dxt3_rgba_data[] = {
249 {
250 {
251 0x6d, 0xc6, 0x96, 0x77,
252 0x6d, 0xc6, 0x96, 0xee,
253 0x6d, 0xc6, 0x96, 0xaa,
254 0x8c, 0xff, 0xb5, 0x44,
255 0x6d, 0xc6, 0x96, 0xff,
256 0x6d, 0xc6, 0x96, 0x88,
257 0x31, 0x55, 0x5a, 0x66,
258 0x6d, 0xc6, 0x96, 0x99,
259 0x31, 0x55, 0x5a, 0xbb,
260 0x31, 0x55, 0x5a, 0x55,
261 0x31, 0x55, 0x5a, 0x11,
262 0x6d, 0xc6, 0x96, 0xcc,
263 0x6d, 0xc6, 0x96, 0xcc,
264 0x6d, 0xc6, 0x96, 0x11,
265 0x31, 0x55, 0x5a, 0x44,
266 0x31, 0x55, 0x5a, 0x88
267 },
268 {0xe7, 0x4a, 0x8f, 0x96, 0x5b, 0xc1, 0x1c, 0x84, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a}
269 },
270 {
271 {
272 0xad, 0xeb, 0x73, 0x99,
273 0x97, 0xaa, 0x86, 0x66,
274 0x6b, 0x28, 0xad, 0x99,
275 0xad, 0xeb, 0x73, 0x99,
276 0x6b, 0x28, 0xad, 0x22,
277 0xad, 0xeb, 0x73, 0xff,
278 0x97, 0xaa, 0x86, 0x55,
279 0x6b, 0x28, 0xad, 0x55,
280 0x6b, 0x28, 0xad, 0x44,
281 0xad, 0xeb, 0x73, 0x33,
282 0x6b, 0x28, 0xad, 0xee,
283 0x6b, 0x28, 0xad, 0x99,
284 0x97, 0xaa, 0x86, 0x66,
285 0xad, 0xeb, 0x73, 0xbb,
286 0x97, 0xaa, 0x86, 0x99,
287 0xad, 0xeb, 0x73, 0xbb
288 },
289 {0x69, 0x99, 0xf2, 0x55, 0x34, 0x9e, 0xb6, 0xb9, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22}
290 },
291 {
292 {
293 0x63, 0xd7, 0xd6, 0x00,
294 0x57, 0x62, 0x5d, 0xdd,
295 0x57, 0x62, 0x5d, 0xcc,
296 0x57, 0x62, 0x5d, 0xbb,
297 0x52, 0x28, 0x21, 0xaa,
298 0x57, 0x62, 0x5d, 0xcc,
299 0x57, 0x62, 0x5d, 0xcc,
300 0x57, 0x62, 0x5d, 0x66,
301 0x57, 0x62, 0x5d, 0x22,
302 0x57, 0x62, 0x5d, 0xdd,
303 0x63, 0xd7, 0xd6, 0xee,
304 0x57, 0x62, 0x5d, 0x33,
305 0x63, 0xd7, 0xd6, 0x55,
306 0x52, 0x28, 0x21, 0x55,
307 0x57, 0x62, 0x5d, 0x11,
308 0x5d, 0x9c, 0x99, 0xee
309 },
310 {0xd0, 0xbc, 0xca, 0x6c, 0xd2, 0x3e, 0x55, 0xe1, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4}
311 },
312 {
313 {
314 0x94, 0x6f, 0x60, 0x22,
315 0x94, 0x6f, 0x60, 0x22,
316 0xc5, 0xab, 0x76, 0x11,
317 0xc5, 0xab, 0x76, 0xee,
318 0x63, 0x34, 0x4a, 0xdd,
319 0x63, 0x34, 0x4a, 0x33,
320 0x94, 0x6f, 0x60, 0x77,
321 0xf7, 0xe7, 0x8c, 0x00,
322 0x94, 0x6f, 0x60, 0x33,
323 0x63, 0x34, 0x4a, 0xaa,
324 0x94, 0x6f, 0x60, 0x77,
325 0x63, 0x34, 0x4a, 0xcc,
326 0x94, 0x6f, 0x60, 0xaa,
327 0xf7, 0xe7, 0x8c, 0x99,
328 0x63, 0x34, 0x4a, 0x44,
329 0xc5, 0xab, 0x76, 0xaa
330 },
331 {0x22, 0xe1, 0x3d, 0x07, 0xa3, 0xc7, 0x9a, 0xa4, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93}
332 },
333 };
334
335
336 static const struct dxt_data
337 dxt5_rgba_data[] = {
338 {
339 {
340 0x6d, 0xc6, 0x96, 0x74,
341 0x6d, 0xc6, 0x96, 0xf8,
342 0x6d, 0xc6, 0x96, 0xb6,
343 0x8c, 0xff, 0xb5, 0x53,
344 0x6d, 0xc6, 0x96, 0xf8,
345 0x6d, 0xc6, 0x96, 0x95,
346 0x31, 0x55, 0x5a, 0x53,
347 0x6d, 0xc6, 0x96, 0x95,
348 0x31, 0x55, 0x5a, 0xb6,
349 0x31, 0x55, 0x5a, 0x53,
350 0x31, 0x55, 0x5a, 0x11,
351 0x6d, 0xc6, 0x96, 0xd7,
352 0x6d, 0xc6, 0x96, 0xb6,
353 0x6d, 0xc6, 0x96, 0x11,
354 0x31, 0x55, 0x5a, 0x32,
355 0x31, 0x55, 0x5a, 0x95
356 },
357 {0xf8, 0x11, 0xc5, 0x0c, 0x9a, 0x73, 0xb4, 0x9c, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a}
358 },
359 {
360 {
361 0xad, 0xeb, 0x73, 0xa1,
362 0x97, 0xaa, 0x86, 0x65,
363 0x6b, 0x28, 0xad, 0xa1,
364 0xad, 0xeb, 0x73, 0xa1,
365 0x6b, 0x28, 0xad, 0x2a,
366 0xad, 0xeb, 0x73, 0xfb,
367 0x97, 0xaa, 0x86, 0x47,
368 0x6b, 0x28, 0xad, 0x65,
369 0x6b, 0x28, 0xad, 0x47,
370 0xad, 0xeb, 0x73, 0x47,
371 0x6b, 0x28, 0xad, 0xdd,
372 0x6b, 0x28, 0xad, 0xa1,
373 0x97, 0xaa, 0x86, 0x65,
374 0xad, 0xeb, 0x73, 0xbf,
375 0x97, 0xaa, 0x86, 0xa1,
376 0xad, 0xeb, 0x73, 0xbf
377 },
378 {0xfb, 0x2a, 0x34, 0x19, 0xdc, 0xbf, 0xe8, 0x71, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22}
379 },
380 {
381 {
382 0x63, 0xd7, 0xd6, 0x00,
383 0x57, 0x62, 0x5d, 0xf5,
384 0x57, 0x62, 0x5d, 0xd2,
385 0x57, 0x62, 0x5d, 0xaf,
386 0x52, 0x28, 0x21, 0xaf,
387 0x57, 0x62, 0x5d, 0xd2,
388 0x57, 0x62, 0x5d, 0xd2,
389 0x57, 0x62, 0x5d, 0x69,
390 0x57, 0x62, 0x5d, 0x23,
391 0x57, 0x62, 0x5d, 0xd2,
392 0x63, 0xd7, 0xd6, 0xf5,
393 0x57, 0x62, 0x5d, 0x46,
394 0x63, 0xd7, 0xd6, 0x46,
395 0x52, 0x28, 0x21, 0x69,
396 0x57, 0x62, 0x5d, 0x23,
397 0x5d, 0x9c, 0x99, 0xf5
398 },
399 {0xf5, 0x00, 0x81, 0x36, 0xa9, 0x17, 0xec, 0x1e, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4}
400 },
401 {
402 {
403 0x94, 0x6f, 0x60, 0x25,
404 0x94, 0x6f, 0x60, 0x25,
405 0xc5, 0xab, 0x76, 0x05,
406 0xc5, 0xab, 0x76, 0xe8,
407 0x63, 0x34, 0x4a, 0xe8,
408 0x63, 0x34, 0x4a, 0x25,
409 0x94, 0x6f, 0x60, 0x86,
410 0xf7, 0xe7, 0x8c, 0x05,
411 0x94, 0x6f, 0x60, 0x25,
412 0x63, 0x34, 0x4a, 0xa7,
413 0x94, 0x6f, 0x60, 0x66,
414 0x63, 0x34, 0x4a, 0xc7,
415 0x94, 0x6f, 0x60, 0xa7,
416 0xf7, 0xe7, 0x8c, 0xa7,
417 0x63, 0x34, 0x4a, 0x45,
418 0xc5, 0xab, 0x76, 0xa7
419 },
420 {0xe8, 0x05, 0x7f, 0x80, 0x33, 0x5f, 0xb5, 0x79, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93}
421 },
422 };
423
424
425 static INLINE void
426 st_sample_dxt_pixel_block(enum pipe_format format,
427 uint8_t *raw,
428 float *rgba, unsigned rgba_stride,
429 unsigned w, unsigned h)
430 {
431 const struct dxt_data *data;
432 unsigned n;
433 unsigned i;
434 unsigned x, y, ch;
435
436 switch(format) {
437 case PIPE_FORMAT_DXT1_RGB:
438 data = dxt1_rgb_data;
439 n = sizeof(dxt1_rgb_data)/sizeof(dxt1_rgb_data[0]);
440 break;
441 case PIPE_FORMAT_DXT1_RGBA:
442 data = dxt1_rgba_data;
443 n = sizeof(dxt1_rgba_data)/sizeof(dxt1_rgba_data[0]);
444 break;
445 case PIPE_FORMAT_DXT3_RGBA:
446 data = dxt3_rgba_data;
447 n = sizeof(dxt3_rgba_data)/sizeof(dxt3_rgba_data[0]);
448 break;
449 case PIPE_FORMAT_DXT5_RGBA:
450 data = dxt5_rgba_data;
451 n = sizeof(dxt5_rgba_data)/sizeof(dxt5_rgba_data[0]);
452 break;
453 default:
454 assert(0);
455 return;
456 }
457
458 i = st_random() % n;
459
460 for(y = 0; y < h; ++y)
461 for(x = 0; x < w; ++x)
462 for(ch = 0; ch < 4; ++ch)
463 rgba[y*rgba_stride + x*4 + ch] = (float)(data[i].rgba[y*4*4 + x*4 + ch])/255.0f;
464
465 memcpy(raw, data[i].raw, util_format_get_blocksize(format));
466 }
467
468
469 static INLINE void
470 st_sample_generic_pixel_block(enum pipe_format format,
471 uint8_t *raw,
472 float *rgba, unsigned rgba_stride,
473 unsigned w, unsigned h)
474 {
475 unsigned i;
476 unsigned x, y, ch;
477 int blocksize = util_format_get_blocksize(format);
478
479 for(i = 0; i < blocksize; ++i)
480 raw[i] = (uint8_t)st_random();
481
482
483 pipe_tile_raw_to_rgba(format,
484 raw,
485 w, h,
486 rgba, rgba_stride);
487
488 if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV) {
489 for(y = 0; y < h; ++y) {
490 for(x = 0; x < w; ++x) {
491 for(ch = 0; ch < 4; ++ch) {
492 unsigned offset = y*rgba_stride + x*4 + ch;
493 rgba[offset] = CLAMP(rgba[offset], 0.0f, 1.0f);
494 }
495 }
496 }
497 }
498 }
499
500
501 /**
502 * Randomly sample pixels.
503 */
504 void
505 st_sample_pixel_block(enum pipe_format format,
506 void *raw,
507 float *rgba, unsigned rgba_stride,
508 unsigned w, unsigned h)
509 {
510 switch(format) {
511 case PIPE_FORMAT_DXT1_RGB:
512 case PIPE_FORMAT_DXT1_RGBA:
513 case PIPE_FORMAT_DXT3_RGBA:
514 case PIPE_FORMAT_DXT5_RGBA:
515 st_sample_dxt_pixel_block(format, raw, rgba, rgba_stride, w, h);
516 break;
517
518 default:
519 st_sample_generic_pixel_block(format, raw, rgba, rgba_stride, w, h);
520 break;
521 }
522 }
523
524
525 void
526 st_sample_surface(struct st_surface *surface, float *rgba)
527 {
528 struct pipe_texture *texture = surface->texture;
529 struct pipe_screen *screen = texture->screen;
530 unsigned width = u_minify(texture->width0, surface->level);
531 unsigned height = u_minify(texture->height0, surface->level);
532 uint rgba_stride = width * 4;
533 struct pipe_transfer *transfer;
534 void *raw;
535
536 transfer = screen->get_tex_transfer(screen,
537 surface->texture,
538 surface->face,
539 surface->level,
540 surface->zslice,
541 PIPE_TRANSFER_WRITE,
542 0, 0,
543 width,
544 height);
545 if (!transfer)
546 return;
547
548 raw = screen->transfer_map(screen, transfer);
549 if (raw) {
550 enum pipe_format format = texture->format;
551 uint x, y;
552 int nblocksx = util_format_get_nblocksx(format, width);
553 int nblocksy = util_format_get_nblocksy(format, height);
554 int blockwidth = util_format_get_blockwidth(format);
555 int blockheight = util_format_get_blockheight(format);
556 int blocksize = util_format_get_blocksize(format);
557
558
559 for (y = 0; y < nblocksy; ++y) {
560 for (x = 0; x < nblocksx; ++x) {
561 st_sample_pixel_block(format,
562 (uint8_t *) raw + y * transfer->stride + x * blocksize,
563 rgba + y * blockheight * rgba_stride + x * blockwidth * 4,
564 rgba_stride,
565 MIN2(blockwidth, width - x*blockwidth),
566 MIN2(blockheight, height - y*blockheight));
567 }
568 }
569
570 screen->transfer_unmap(screen, transfer);
571 }
572
573 screen->tex_transfer_destroy(transfer);
574 }