1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
29 #include "pipe/p_compiler.h"
30 #include "pipe/p_format.h"
31 #include "pipe/p_state.h"
32 #include "util/u_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"
38 #include "st_device.h"
39 #include "st_sample.h"
43 * Use our own pseudo random generator to ensure consistent runs among
44 * multiple runs and platforms.
46 * @sa http://en.wikipedia.org/wiki/Linear_congruential_generator
48 static uint32_t st_random(void) {
49 static uint64_t seed
= UINT64_C(0xbb9a063afb0a739d);
51 seed
= UINT64_C(134775813) * seed
+ UINT64_C(1);
53 return (uint32_t)(seed
>> 32);
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
69 static const struct dxt_data
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
90 {0xf2, 0xd7, 0xb0, 0x20, 0xae, 0x2c, 0x6f, 0x97}
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
111 {0x73, 0xb6, 0x4d, 0x20, 0x98, 0x2b, 0xe1, 0xb8}
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
132 {0xe7, 0xdd, 0x7f, 0x01, 0xf9, 0xab, 0x08, 0x80}
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
153 {0x3a, 0x9d, 0x24, 0x69, 0xbd, 0x9f, 0xb4, 0x39}
158 static const struct dxt_data
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
179 {0xff, 0x2f, 0xa4, 0x72, 0xeb, 0xb2, 0xbd, 0xbe}
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
200 {0x30, 0x69, 0x0c, 0xb7, 0x4d, 0xf7, 0x0f, 0x67}
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
221 {0x28, 0x23, 0x31, 0xc4, 0x17, 0xc0, 0xd3, 0x7f}
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
242 {0xea, 0x78, 0x13, 0xc7, 0x7f, 0xfc, 0x33, 0xb6}
247 static const struct dxt_data
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
268 {0xe7, 0x4a, 0x8f, 0x96, 0x5b, 0xc1, 0x1c, 0x84, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a}
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
289 {0x69, 0x99, 0xf2, 0x55, 0x34, 0x9e, 0xb6, 0xb9, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22}
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
310 {0xd0, 0xbc, 0xca, 0x6c, 0xd2, 0x3e, 0x55, 0xe1, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4}
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
331 {0x22, 0xe1, 0x3d, 0x07, 0xa3, 0xc7, 0x9a, 0xa4, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93}
336 static const struct dxt_data
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
357 {0xf8, 0x11, 0xc5, 0x0c, 0x9a, 0x73, 0xb4, 0x9c, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a}
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
378 {0xfb, 0x2a, 0x34, 0x19, 0xdc, 0xbf, 0xe8, 0x71, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22}
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
399 {0xf5, 0x00, 0x81, 0x36, 0xa9, 0x17, 0xec, 0x1e, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4}
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
420 {0xe8, 0x05, 0x7f, 0x80, 0x33, 0x5f, 0xb5, 0x79, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93}
426 st_sample_dxt_pixel_block(enum pipe_format format
,
428 float *rgba
, unsigned rgba_stride
,
429 unsigned w
, unsigned h
)
431 const struct dxt_data
*data
;
437 case PIPE_FORMAT_DXT1_RGB
:
438 data
= dxt1_rgb_data
;
439 n
= sizeof(dxt1_rgb_data
)/sizeof(dxt1_rgb_data
[0]);
441 case PIPE_FORMAT_DXT1_RGBA
:
442 data
= dxt1_rgba_data
;
443 n
= sizeof(dxt1_rgba_data
)/sizeof(dxt1_rgba_data
[0]);
445 case PIPE_FORMAT_DXT3_RGBA
:
446 data
= dxt3_rgba_data
;
447 n
= sizeof(dxt3_rgba_data
)/sizeof(dxt3_rgba_data
[0]);
449 case PIPE_FORMAT_DXT5_RGBA
:
450 data
= dxt5_rgba_data
;
451 n
= sizeof(dxt5_rgba_data
)/sizeof(dxt5_rgba_data
[0]);
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
;
465 memcpy(raw
, data
[i
].raw
, util_format_get_blocksize(format
));
470 st_sample_generic_pixel_block(enum pipe_format format
,
472 float *rgba
, unsigned rgba_stride
,
473 unsigned w
, unsigned h
,
478 int blocksize
= util_format_get_blocksize(format
);
481 for (y
= 0; y
< h
; ++y
) {
482 for (x
= 0; x
< w
; ++x
) {
483 for (ch
= 0; ch
< 4; ++ch
) {
484 unsigned offset
= y
*rgba_stride
+ x
*4 + ch
;
485 rgba
[offset
] = (st_random() & 0xff) / (double)0xff;
490 util_format_write_4f(format
,
491 rgba
, rgba_stride
* sizeof(float),
492 raw
, util_format_get_stride(format
, w
),
496 for (i
= 0; i
< blocksize
; ++i
)
497 raw
[i
] = (uint8_t)st_random();
500 util_format_read_4f(format
,
501 rgba
, rgba_stride
* sizeof(float),
502 raw
, util_format_get_stride(format
, w
),
505 if (format
== PIPE_FORMAT_UYVY
|| format
== PIPE_FORMAT_YUYV
) {
506 for (y
= 0; y
< h
; ++y
) {
507 for (x
= 0; x
< w
; ++x
) {
508 for (ch
= 0; ch
< 4; ++ch
) {
509 unsigned offset
= y
*rgba_stride
+ x
*4 + ch
;
510 rgba
[offset
] = CLAMP(rgba
[offset
], 0.0f
, 1.0f
);
519 * Randomly sample pixels.
522 st_sample_pixel_block(enum pipe_format format
,
524 float *rgba
, unsigned rgba_stride
,
525 unsigned w
, unsigned h
,
529 case PIPE_FORMAT_DXT1_RGB
:
530 case PIPE_FORMAT_DXT1_RGBA
:
531 case PIPE_FORMAT_DXT3_RGBA
:
532 case PIPE_FORMAT_DXT5_RGBA
:
533 st_sample_dxt_pixel_block(format
, raw
, rgba
, rgba_stride
, w
, h
);
537 st_sample_generic_pixel_block(format
, raw
, rgba
, rgba_stride
, w
, h
, norm
);
544 st_sample_surface(struct pipe_context
*pipe
,
545 struct st_surface
*surface
,
549 struct pipe_resource
*texture
= surface
->texture
;
550 unsigned width
= u_minify(texture
->width0
, surface
->level
);
551 unsigned height
= u_minify(texture
->height0
, surface
->level
);
552 uint rgba_stride
= width
* 4;
553 struct pipe_transfer
*transfer
;
556 transfer
= pipe_get_transfer(pipe
,
568 raw
= pipe
->transfer_map(pipe
, transfer
);
570 enum pipe_format format
= texture
->format
;
572 int nblocksx
= util_format_get_nblocksx(format
, width
);
573 int nblocksy
= util_format_get_nblocksy(format
, height
);
574 int blockwidth
= util_format_get_blockwidth(format
);
575 int blockheight
= util_format_get_blockheight(format
);
576 int blocksize
= util_format_get_blocksize(format
);
579 for (y
= 0; y
< nblocksy
; ++y
) {
580 for (x
= 0; x
< nblocksx
; ++x
) {
581 st_sample_pixel_block(format
,
582 (uint8_t *) raw
+ y
* transfer
->stride
+ x
* blocksize
,
583 rgba
+ y
* blockheight
* rgba_stride
+ x
* blockwidth
* 4,
585 MIN2(blockwidth
, width
- x
*blockwidth
),
586 MIN2(blockheight
, height
- y
*blockheight
),
591 pipe
->transfer_unmap(pipe
, transfer
);
594 pipe
->transfer_destroy(pipe
, transfer
);