Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/**************************************************************************
2
 *
3
 * Copyright 2009 VMware, Inc.
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 VMWARE 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 
30
#include 
31
#include 
32
 
33
#include "util/u_memory.h"
34
#include "util/u_pointer.h"
35
#include "util/u_string.h"
36
#include "util/u_format.h"
37
#include "util/u_format_tests.h"
38
#include "util/u_format_s3tc.h"
39
 
40
#include "gallivm/lp_bld.h"
41
#include "gallivm/lp_bld_debug.h"
42
#include "gallivm/lp_bld_format.h"
43
#include "gallivm/lp_bld_init.h"
44
 
45
#include "lp_test.h"
46
 
47
 
48
void
49
write_tsv_header(FILE *fp)
50
{
51
   fprintf(fp,
52
           "result\t"
53
           "format\n");
54
 
55
   fflush(fp);
56
}
57
 
58
 
59
static void
60
write_tsv_row(FILE *fp,
61
              const struct util_format_description *desc,
62
              boolean success)
63
{
64
   fprintf(fp, "%s\t", success ? "pass" : "fail");
65
 
66
   fprintf(fp, "%s\n", desc->name);
67
 
68
   fflush(fp);
69
}
70
 
71
 
72
typedef void
73
(*fetch_ptr_t)(void *unpacked, const void *packed,
74
               unsigned i, unsigned j);
75
 
76
 
77
static LLVMValueRef
78
add_fetch_rgba_test(struct gallivm_state *gallivm, unsigned verbose,
79
                    const struct util_format_description *desc,
80
                    struct lp_type type)
81
{
82
   char name[256];
83
   LLVMContextRef context = gallivm->context;
84
   LLVMModuleRef module = gallivm->module;
85
   LLVMBuilderRef builder = gallivm->builder;
86
   LLVMTypeRef args[4];
87
   LLVMValueRef func;
88
   LLVMValueRef packed_ptr;
89
   LLVMValueRef offset = LLVMConstNull(LLVMInt32TypeInContext(context));
90
   LLVMValueRef rgba_ptr;
91
   LLVMValueRef i;
92
   LLVMValueRef j;
93
   LLVMBasicBlockRef block;
94
   LLVMValueRef rgba;
95
 
96
   util_snprintf(name, sizeof name, "fetch_%s_%s", desc->short_name,
97
                 type.floating ? "float" : "unorm8");
98
 
99
   args[0] = LLVMPointerType(lp_build_vec_type(gallivm, type), 0);
100
   args[1] = LLVMPointerType(LLVMInt8TypeInContext(context), 0);
101
   args[3] = args[2] = LLVMInt32TypeInContext(context);
102
 
103
   func = LLVMAddFunction(module, name,
104
                          LLVMFunctionType(LLVMVoidTypeInContext(context),
105
                                           args, Elements(args), 0));
106
   LLVMSetFunctionCallConv(func, LLVMCCallConv);
107
   rgba_ptr = LLVMGetParam(func, 0);
108
   packed_ptr = LLVMGetParam(func, 1);
109
   i = LLVMGetParam(func, 2);
110
   j = LLVMGetParam(func, 3);
111
 
112
   block = LLVMAppendBasicBlockInContext(context, func, "entry");
113
   LLVMPositionBuilderAtEnd(builder, block);
114
 
115
   rgba = lp_build_fetch_rgba_aos(gallivm, desc, type,
116
                                  packed_ptr, offset, i, j);
117
 
118
   LLVMBuildStore(builder, rgba, rgba_ptr);
119
 
120
   LLVMBuildRetVoid(builder);
121
 
122
   gallivm_verify_function(gallivm, func);
123
 
124
   return func;
125
}
126
 
127
 
128
PIPE_ALIGN_STACK
129
static boolean
130
test_format_float(unsigned verbose, FILE *fp,
131
                  const struct util_format_description *desc)
132
{
133
   struct gallivm_state *gallivm;
134
   LLVMValueRef fetch = NULL;
135
   fetch_ptr_t fetch_ptr;
136
   PIPE_ALIGN_VAR(16) float unpacked[4];
137
   boolean first = TRUE;
138
   boolean success = TRUE;
139
   unsigned i, j, k, l;
140
 
141
   gallivm = gallivm_create();
142
 
143
   fetch = add_fetch_rgba_test(gallivm, verbose, desc, lp_float32_vec4_type());
144
 
145
   gallivm_compile_module(gallivm);
146
 
147
   fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch);
148
 
149
   for (l = 0; l < util_format_nr_test_cases; ++l) {
150
      const struct util_format_test_case *test = &util_format_test_cases[l];
151
 
152
      if (test->format == desc->format) {
153
 
154
         if (first) {
155
            printf("Testing %s (float) ...\n",
156
                   desc->name);
157
            first = FALSE;
158
         }
159
 
160
         for (i = 0; i < desc->block.height; ++i) {
161
            for (j = 0; j < desc->block.width; ++j) {
162
               boolean match = TRUE;
163
 
164
               memset(unpacked, 0, sizeof unpacked);
165
 
166
               fetch_ptr(unpacked, test->packed, j, i);
167
 
168
               for(k = 0; k < 4; ++k) {
169
                  if (util_double_inf_sign(test->unpacked[i][j][k]) != util_inf_sign(unpacked[k])) {
170
                     match = FALSE;
171
                  }
172
 
173
                  if (util_is_double_nan(test->unpacked[i][j][k]) != util_is_nan(unpacked[k])) {
174
                     match = FALSE;
175
                  }
176
 
177
                  if (!util_is_double_inf_or_nan(test->unpacked[i][j][k]) &&
178
                      fabs((float)test->unpacked[i][j][k] - unpacked[k]) > FLT_EPSILON) {
179
                     match = FALSE;
180
                  }
181
               }
182
 
183
               if (!match) {
184
                  printf("FAILED\n");
185
                  printf("  Packed: %02x %02x %02x %02x\n",
186
                         test->packed[0], test->packed[1], test->packed[2], test->packed[3]);
187
                  printf("  Unpacked (%u,%u): %.9g %.9g %.9g %.9g obtained\n",
188
                         j, i,
189
                         unpacked[0], unpacked[1], unpacked[2], unpacked[3]);
190
                  printf("                  %.9g %.9g %.9g %.9g expected\n",
191
                         test->unpacked[i][j][0],
192
                         test->unpacked[i][j][1],
193
                         test->unpacked[i][j][2],
194
                         test->unpacked[i][j][3]);
195
                  success = FALSE;
196
               }
197
            }
198
         }
199
      }
200
   }
201
 
202
   gallivm_free_function(gallivm, fetch, fetch_ptr);
203
 
204
   gallivm_destroy(gallivm);
205
 
206
   if(fp)
207
      write_tsv_row(fp, desc, success);
208
 
209
   return success;
210
}
211
 
212
 
213
PIPE_ALIGN_STACK
214
static boolean
215
test_format_unorm8(unsigned verbose, FILE *fp,
216
                   const struct util_format_description *desc)
217
{
218
   struct gallivm_state *gallivm;
219
   LLVMValueRef fetch = NULL;
220
   fetch_ptr_t fetch_ptr;
221
   uint8_t unpacked[4];
222
   boolean first = TRUE;
223
   boolean success = TRUE;
224
   unsigned i, j, k, l;
225
 
226
   gallivm = gallivm_create();
227
 
228
   fetch = add_fetch_rgba_test(gallivm, verbose, desc, lp_unorm8_vec4_type());
229
 
230
   gallivm_compile_module(gallivm);
231
 
232
   fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch);
233
 
234
   for (l = 0; l < util_format_nr_test_cases; ++l) {
235
      const struct util_format_test_case *test = &util_format_test_cases[l];
236
 
237
      if (test->format == desc->format) {
238
 
239
         if (first) {
240
            printf("Testing %s (unorm8) ...\n",
241
                   desc->name);
242
            first = FALSE;
243
         }
244
 
245
         for (i = 0; i < desc->block.height; ++i) {
246
            for (j = 0; j < desc->block.width; ++j) {
247
               boolean match;
248
 
249
               memset(unpacked, 0, sizeof unpacked);
250
 
251
               fetch_ptr(unpacked, test->packed, j, i);
252
 
253
               match = TRUE;
254
               for(k = 0; k < 4; ++k) {
255
                  int error = float_to_ubyte(test->unpacked[i][j][k]) - unpacked[k];
256
 
257
                  if (util_is_double_nan(test->unpacked[i][j][k]))
258
                     continue;
259
 
260
                  if (error < 0)
261
                     error = -error;
262
 
263
                  if (error > 1)
264
                     match = FALSE;
265
               }
266
 
267
               if (!match) {
268
                  printf("FAILED\n");
269
                  printf("  Packed: %02x %02x %02x %02x\n",
270
                         test->packed[0], test->packed[1], test->packed[2], test->packed[3]);
271
                  printf("  Unpacked (%u,%u): %02x %02x %02x %02x obtained\n",
272
                         j, i,
273
                         unpacked[0], unpacked[1], unpacked[2], unpacked[3]);
274
                  printf("                  %02x %02x %02x %02x expected\n",
275
                         float_to_ubyte(test->unpacked[i][j][0]),
276
                         float_to_ubyte(test->unpacked[i][j][1]),
277
                         float_to_ubyte(test->unpacked[i][j][2]),
278
                         float_to_ubyte(test->unpacked[i][j][3]));
279
 
280
                  success = FALSE;
281
               }
282
            }
283
         }
284
      }
285
   }
286
 
287
   gallivm_free_function(gallivm, fetch, fetch_ptr);
288
 
289
   gallivm_destroy(gallivm);
290
 
291
   if(fp)
292
      write_tsv_row(fp, desc, success);
293
 
294
   return success;
295
}
296
 
297
 
298
 
299
 
300
static boolean
301
test_one(unsigned verbose, FILE *fp,
302
         const struct util_format_description *format_desc)
303
{
304
   boolean success = TRUE;
305
 
306
   if (!test_format_float(verbose, fp, format_desc)) {
307
     success = FALSE;
308
   }
309
 
310
   if (!test_format_unorm8(verbose, fp, format_desc)) {
311
     success = FALSE;
312
   }
313
 
314
   return success;
315
}
316
 
317
 
318
boolean
319
test_all(unsigned verbose, FILE *fp)
320
{
321
   enum pipe_format format;
322
   boolean success = TRUE;
323
 
324
   util_format_s3tc_init();
325
 
326
   for (format = 1; format < PIPE_FORMAT_COUNT; ++format) {
327
      const struct util_format_description *format_desc;
328
 
329
      format_desc = util_format_description(format);
330
      if (!format_desc) {
331
         continue;
332
      }
333
 
334
 
335
      /*
336
       * TODO: test more
337
       */
338
 
339
      if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
340
         continue;
341
      }
342
 
343
      if (util_format_is_pure_integer(format))
344
	 continue;
345
 
346
      if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC &&
347
          !util_format_s3tc_enabled) {
348
         continue;
349
      }
350
 
351
      if (!test_one(verbose, fp, format_desc)) {
352
           success = FALSE;
353
      }
354
   }
355
 
356
   return success;
357
}
358
 
359
 
360
boolean
361
test_some(unsigned verbose, FILE *fp,
362
          unsigned long n)
363
{
364
   return test_all(verbose, fp);
365
}
366
 
367
 
368
boolean
369
test_single(unsigned verbose, FILE *fp)
370
{
371
   printf("no test_single()");
372
   return TRUE;
373
}