1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
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 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.
26 **************************************************************************/
33 #include "gallivm/lp_bld.h"
34 #include "gallivm/lp_bld_debug.h"
35 #include "gallivm/lp_bld_init.h"
36 #include <llvm-c/Analysis.h>
37 #include <llvm-c/Target.h>
38 #include <llvm-c/Transforms/Scalar.h>
40 #include "util/u_memory.h"
41 #include "util/u_pointer.h"
42 #include "util/u_string.h"
43 #include "util/u_format.h"
44 #include "util/u_format_tests.h"
45 #include "util/u_format_s3tc.h"
47 #include "gallivm/lp_bld_format.h"
52 write_tsv_header(FILE *fp
)
63 write_tsv_row(FILE *fp
,
64 const struct util_format_description
*desc
,
67 fprintf(fp
, "%s\t", success
? "pass" : "fail");
69 fprintf(fp
, "%s\n", desc
->name
);
76 (*fetch_ptr_t
)(void *unpacked
, const void *packed
,
77 unsigned i
, unsigned j
);
81 add_fetch_rgba_test(unsigned verbose
,
82 const struct util_format_description
*desc
,
88 LLVMValueRef packed_ptr
;
89 LLVMValueRef offset
= LLVMConstNull(LLVMInt32Type());
90 LLVMValueRef rgba_ptr
;
93 LLVMBasicBlockRef block
;
94 LLVMBuilderRef builder
;
97 util_snprintf(name
, sizeof name
, "fetch_%s_%s", desc
->short_name
,
98 type
.floating
? "float" : "unorm8");
100 args
[0] = LLVMPointerType(lp_build_vec_type(type
), 0);
101 args
[1] = LLVMPointerType(LLVMInt8Type(), 0);
102 args
[3] = args
[2] = LLVMInt32Type();
104 func
= LLVMAddFunction(lp_build_module
, name
,
105 LLVMFunctionType(LLVMVoidType(), 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);
112 block
= LLVMAppendBasicBlock(func
, "entry");
113 builder
= LLVMCreateBuilder();
114 LLVMPositionBuilderAtEnd(builder
, block
);
116 rgba
= lp_build_fetch_rgba_aos(builder
, desc
, type
,
117 packed_ptr
, offset
, i
, j
);
119 LLVMBuildStore(builder
, rgba
, rgba_ptr
);
121 LLVMBuildRetVoid(builder
);
123 LLVMDisposeBuilder(builder
);
125 if (LLVMVerifyFunction(func
, LLVMPrintMessageAction
)) {
130 LLVMRunFunctionPassManager(lp_build_pass
, func
);
142 test_format_float(unsigned verbose
, FILE *fp
,
143 const struct util_format_description
*desc
)
145 LLVMValueRef fetch
= NULL
;
146 fetch_ptr_t fetch_ptr
;
147 PIPE_ALIGN_VAR(16) float unpacked
[4];
148 boolean first
= TRUE
;
149 boolean success
= TRUE
;
153 fetch
= add_fetch_rgba_test(verbose
, desc
, lp_float32_vec4_type());
155 f
= LLVMGetPointerToGlobal(lp_build_engine
, fetch
);
156 fetch_ptr
= (fetch_ptr_t
) pointer_to_func(f
);
162 for (l
= 0; l
< util_format_nr_test_cases
; ++l
) {
163 const struct util_format_test_case
*test
= &util_format_test_cases
[l
];
165 if (test
->format
== desc
->format
) {
168 printf("Testing %s (float) ...\n",
173 for (i
= 0; i
< desc
->block
.height
; ++i
) {
174 for (j
= 0; j
< desc
->block
.width
; ++j
) {
177 memset(unpacked
, 0, sizeof unpacked
);
179 fetch_ptr(unpacked
, test
->packed
, j
, i
);
182 for(k
= 0; k
< 4; ++k
)
183 if (fabs((float)test
->unpacked
[i
][j
][k
] - unpacked
[k
]) > FLT_EPSILON
)
188 printf(" Packed: %02x %02x %02x %02x\n",
189 test
->packed
[0], test
->packed
[1], test
->packed
[2], test
->packed
[3]);
190 printf(" Unpacked (%u,%u): %f %f %f %f obtained\n",
192 unpacked
[0], unpacked
[1], unpacked
[2], unpacked
[3]);
193 printf(" %f %f %f %f expected\n",
194 test
->unpacked
[i
][j
][0],
195 test
->unpacked
[i
][j
][1],
196 test
->unpacked
[i
][j
][2],
197 test
->unpacked
[i
][j
][3]);
207 LLVMDumpValue(fetch
);
211 LLVMFreeMachineCodeForFunction(lp_build_engine
, fetch
);
212 LLVMDeleteFunction(fetch
);
215 write_tsv_row(fp
, desc
, success
);
223 test_format_unorm8(unsigned verbose
, FILE *fp
,
224 const struct util_format_description
*desc
)
226 LLVMValueRef fetch
= NULL
;
227 fetch_ptr_t fetch_ptr
;
229 boolean first
= TRUE
;
230 boolean success
= TRUE
;
234 fetch
= add_fetch_rgba_test(verbose
, desc
, lp_unorm8_vec4_type());
236 f
= LLVMGetPointerToGlobal(lp_build_engine
, fetch
);
237 fetch_ptr
= (fetch_ptr_t
) pointer_to_func(f
);
243 for (l
= 0; l
< util_format_nr_test_cases
; ++l
) {
244 const struct util_format_test_case
*test
= &util_format_test_cases
[l
];
246 if (test
->format
== desc
->format
) {
249 printf("Testing %s (unorm8) ...\n",
254 for (i
= 0; i
< desc
->block
.height
; ++i
) {
255 for (j
= 0; j
< desc
->block
.width
; ++j
) {
258 memset(unpacked
, 0, sizeof unpacked
);
260 fetch_ptr(unpacked
, test
->packed
, j
, i
);
263 for(k
= 0; k
< 4; ++k
) {
264 int error
= float_to_ubyte(test
->unpacked
[i
][j
][k
]) - unpacked
[k
];
273 printf(" Packed: %02x %02x %02x %02x\n",
274 test
->packed
[0], test
->packed
[1], test
->packed
[2], test
->packed
[3]);
275 printf(" Unpacked (%u,%u): %02x %02x %02x %02x obtained\n",
277 unpacked
[0], unpacked
[1], unpacked
[2], unpacked
[3]);
278 printf(" %02x %02x %02x %02x expected\n",
279 float_to_ubyte(test
->unpacked
[i
][j
][0]),
280 float_to_ubyte(test
->unpacked
[i
][j
][1]),
281 float_to_ubyte(test
->unpacked
[i
][j
][2]),
282 float_to_ubyte(test
->unpacked
[i
][j
][3]));
291 LLVMDumpValue(fetch
);
293 LLVMFreeMachineCodeForFunction(lp_build_engine
, fetch
);
294 LLVMDeleteFunction(fetch
);
297 write_tsv_row(fp
, desc
, success
);
306 test_one(unsigned verbose
, FILE *fp
,
307 const struct util_format_description
*format_desc
)
309 boolean success
= TRUE
;
311 if (!test_format_float(verbose
, fp
, format_desc
)) {
315 if (!test_format_unorm8(verbose
, fp
, format_desc
)) {
324 test_all(unsigned verbose
, FILE *fp
)
326 enum pipe_format format
;
327 boolean success
= TRUE
;
329 util_format_s3tc_init();
331 for (format
= 1; format
< PIPE_FORMAT_COUNT
; ++format
) {
332 const struct util_format_description
*format_desc
;
334 format_desc
= util_format_description(format
);
343 if (format_desc
->colorspace
== UTIL_FORMAT_COLORSPACE_ZS
) {
347 if (format_desc
->layout
== UTIL_FORMAT_LAYOUT_S3TC
&&
348 !util_format_s3tc_enabled
) {
352 if (!test_one(verbose
, fp
, format_desc
)) {
362 test_some(unsigned verbose
, FILE *fp
, unsigned long n
)
364 return test_all(verbose
, fp
);
369 test_single(unsigned verbose
, FILE *fp
)
371 printf("no test_single()");