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_init.h"
35 #include <llvm-c/Analysis.h>
36 #include <llvm-c/Target.h>
37 #include <llvm-c/Transforms/Scalar.h>
39 #include "util/u_memory.h"
40 #include "util/u_pointer.h"
41 #include "util/u_format.h"
42 #include "util/u_format_tests.h"
43 #include "util/u_format_s3tc.h"
45 #include "gallivm/lp_bld_format.h"
50 write_tsv_header(FILE *fp
)
61 write_tsv_row(FILE *fp
,
62 const struct util_format_description
*desc
,
65 fprintf(fp
, "%s\t", success
? "pass" : "fail");
67 fprintf(fp
, "%s\n", desc
->name
);
74 (*fetch_ptr_t
)(float *, const void *packed
,
75 unsigned i
, unsigned j
);
79 add_fetch_rgba_test(LLVMModuleRef lp_build_module
,
80 const struct util_format_description
*desc
)
84 LLVMValueRef packed_ptr
;
85 LLVMValueRef rgba_ptr
;
88 LLVMBasicBlockRef block
;
89 LLVMBuilderRef builder
;
92 args
[0] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
93 args
[1] = LLVMPointerType(LLVMInt8Type(), 0);
94 args
[3] = args
[2] = LLVMInt32Type();
96 func
= LLVMAddFunction(lp_build_module
, "fetch", LLVMFunctionType(LLVMVoidType(), args
, Elements(args
), 0));
97 LLVMSetFunctionCallConv(func
, LLVMCCallConv
);
98 rgba_ptr
= LLVMGetParam(func
, 0);
99 packed_ptr
= LLVMGetParam(func
, 1);
100 i
= LLVMGetParam(func
, 2);
101 j
= LLVMGetParam(func
, 3);
103 block
= LLVMAppendBasicBlock(func
, "entry");
104 builder
= LLVMCreateBuilder();
105 LLVMPositionBuilderAtEnd(builder
, block
);
107 rgba
= lp_build_fetch_rgba_aos(builder
, desc
, packed_ptr
, i
, j
);
109 LLVMBuildStore(builder
, rgba
, rgba_ptr
);
111 LLVMBuildRetVoid(builder
);
113 LLVMDisposeBuilder(builder
);
120 test_format(unsigned verbose
, FILE *fp
,
121 const struct util_format_description
*desc
,
122 const struct util_format_test_case
*test
)
124 LLVMValueRef fetch
= NULL
;
125 LLVMPassManagerRef pass
= NULL
;
126 fetch_ptr_t fetch_ptr
;
127 PIPE_ALIGN_VAR(16) float unpacked
[4];
131 fetch
= add_fetch_rgba_test(lp_build_module
, desc
);
133 if (LLVMVerifyFunction(fetch
, LLVMPrintMessageAction
)) {
134 LLVMDumpValue(fetch
);
139 pass
= LLVMCreatePassManager();
140 LLVMAddTargetData(LLVMGetExecutionEngineTargetData(lp_build_engine
), pass
);
141 /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
142 * but there are more on SVN. */
143 LLVMAddConstantPropagationPass(pass
);
144 LLVMAddInstructionCombiningPass(pass
);
145 LLVMAddPromoteMemoryToRegisterPass(pass
);
146 LLVMAddGVNPass(pass
);
147 LLVMAddCFGSimplificationPass(pass
);
148 LLVMRunPassManager(pass
, lp_build_module
);
153 fetch_ptr
= (fetch_ptr_t
)pointer_to_func(LLVMGetPointerToGlobal(lp_build_engine
, fetch
));
155 for (i
= 0; i
< desc
->block
.height
; ++i
) {
156 for (j
= 0; j
< desc
->block
.width
; ++j
) {
158 memset(unpacked
, 0, sizeof unpacked
);
160 fetch_ptr(unpacked
, test
->packed
, j
, i
);
163 for(k
= 0; k
< 4; ++k
)
164 if (fabs((float)test
->unpacked
[i
][j
][k
] - unpacked
[k
]) > FLT_EPSILON
)
169 printf(" Packed: %02x %02x %02x %02x\n",
170 test
->packed
[0], test
->packed
[1], test
->packed
[2], test
->packed
[3]);
171 printf(" Unpacked (%u,%u): %f %f %f %f obtained\n",
173 unpacked
[0], unpacked
[1], unpacked
[2], unpacked
[3]);
174 printf(" %f %f %f %f expected\n",
175 test
->unpacked
[i
][j
][0],
176 test
->unpacked
[i
][j
][1],
177 test
->unpacked
[i
][j
][2],
178 test
->unpacked
[i
][j
][3]);
184 LLVMDumpValue(fetch
);
186 LLVMFreeMachineCodeForFunction(lp_build_engine
, fetch
);
187 LLVMDeleteFunction(fetch
);
190 LLVMDisposePassManager(pass
);
193 write_tsv_row(fp
, desc
, success
);
201 test_one(unsigned verbose
, FILE *fp
,
202 const struct util_format_description
*format_desc
)
205 boolean first
= TRUE
;
206 boolean success
= TRUE
;
208 for (i
= 0; i
< util_format_nr_test_cases
; ++i
) {
209 const struct util_format_test_case
*test
= &util_format_test_cases
[i
];
211 if (test
->format
== format_desc
->format
) {
214 printf("Testing %s ...\n",
219 if (!test_format(verbose
, fp
, format_desc
, test
)) {
230 test_all(unsigned verbose
, FILE *fp
)
232 enum pipe_format format
;
233 boolean success
= TRUE
;
235 util_format_s3tc_init();
237 for (format
= 1; format
< PIPE_FORMAT_COUNT
; ++format
) {
238 const struct util_format_description
*format_desc
;
240 format_desc
= util_format_description(format
);
249 if (format_desc
->colorspace
== UTIL_FORMAT_COLORSPACE_ZS
) {
253 if (format_desc
->layout
== UTIL_FORMAT_LAYOUT_S3TC
&&
254 !util_format_s3tc_enabled
) {
258 if (!test_one(verbose
, fp
, format_desc
)) {
268 test_some(unsigned verbose
, FILE *fp
, unsigned long n
)
270 return test_all(verbose
, fp
);