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_format.h"
41 #include "util/u_format_tests.h"
42 #include "util/u_format_s3tc.h"
44 #include "gallivm/lp_bld_format.h"
49 write_tsv_header(FILE *fp
)
60 write_tsv_row(FILE *fp
,
61 const struct util_format_description
*desc
,
64 fprintf(fp
, "%s\t", success
? "pass" : "fail");
66 fprintf(fp
, "%s\n", desc
->name
);
73 (*fetch_ptr_t
)(float *, const void *packed
,
74 unsigned i
, unsigned j
);
76 /** cast wrapper to avoid warnings */
78 void_to_fetch_ptr_t(void *p
)
91 add_fetch_rgba_test(LLVMModuleRef lp_build_module
,
92 const struct util_format_description
*desc
)
96 LLVMValueRef packed_ptr
;
97 LLVMValueRef rgba_ptr
;
100 LLVMBasicBlockRef block
;
101 LLVMBuilderRef builder
;
104 args
[0] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
105 args
[1] = LLVMPointerType(LLVMInt8Type(), 0);
106 args
[3] = args
[2] = LLVMInt32Type();
108 func
= LLVMAddFunction(lp_build_module
, "fetch", LLVMFunctionType(LLVMVoidType(), args
, Elements(args
), 0));
109 LLVMSetFunctionCallConv(func
, LLVMCCallConv
);
110 rgba_ptr
= LLVMGetParam(func
, 0);
111 packed_ptr
= LLVMGetParam(func
, 1);
112 i
= LLVMGetParam(func
, 2);
113 j
= LLVMGetParam(func
, 3);
115 block
= LLVMAppendBasicBlock(func
, "entry");
116 builder
= LLVMCreateBuilder();
117 LLVMPositionBuilderAtEnd(builder
, block
);
119 rgba
= lp_build_fetch_rgba_aos(builder
, desc
, packed_ptr
, i
, j
);
121 LLVMBuildStore(builder
, rgba
, rgba_ptr
);
123 LLVMBuildRetVoid(builder
);
125 LLVMDisposeBuilder(builder
);
132 test_format(unsigned verbose
, FILE *fp
,
133 const struct util_format_description
*desc
,
134 const struct util_format_test_case
*test
)
136 LLVMValueRef fetch
= NULL
;
137 LLVMPassManagerRef pass
= NULL
;
138 fetch_ptr_t fetch_ptr
;
143 fetch
= add_fetch_rgba_test(lp_build_module
, desc
);
145 if (LLVMVerifyFunction(fetch
, LLVMPrintMessageAction
)) {
146 LLVMDumpValue(fetch
);
151 pass
= LLVMCreatePassManager();
152 LLVMAddTargetData(LLVMGetExecutionEngineTargetData(lp_build_engine
), pass
);
153 /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
154 * but there are more on SVN. */
155 LLVMAddConstantPropagationPass(pass
);
156 LLVMAddInstructionCombiningPass(pass
);
157 LLVMAddPromoteMemoryToRegisterPass(pass
);
158 LLVMAddGVNPass(pass
);
159 LLVMAddCFGSimplificationPass(pass
);
160 LLVMRunPassManager(pass
, lp_build_module
);
165 fetch_ptr
= void_to_fetch_ptr_t(LLVMGetPointerToGlobal(lp_build_engine
, fetch
));
167 for (i
= 0; i
< desc
->block
.height
; ++i
) {
168 for (j
= 0; j
< desc
->block
.width
; ++j
) {
170 memset(unpacked
, 0, sizeof unpacked
);
172 fetch_ptr(unpacked
, test
->packed
, j
, i
);
175 for(k
= 0; k
< 4; ++k
)
176 if (fabs((float)test
->unpacked
[i
][j
][k
] - unpacked
[k
]) > FLT_EPSILON
)
181 printf(" Packed: %02x %02x %02x %02x\n",
182 test
->packed
[0], test
->packed
[1], test
->packed
[2], test
->packed
[3]);
183 printf(" Unpacked (%u,%u): %f %f %f %f obtained\n",
185 unpacked
[0], unpacked
[1], unpacked
[2], unpacked
[3]);
186 printf(" %f %f %f %f expected\n",
187 test
->unpacked
[i
][j
][0],
188 test
->unpacked
[i
][j
][1],
189 test
->unpacked
[i
][j
][2],
190 test
->unpacked
[i
][j
][3]);
196 LLVMDumpValue(fetch
);
198 LLVMFreeMachineCodeForFunction(lp_build_engine
, fetch
);
199 LLVMDeleteFunction(fetch
);
202 LLVMDisposePassManager(pass
);
205 write_tsv_row(fp
, desc
, success
);
213 test_one(unsigned verbose
, FILE *fp
,
214 const struct util_format_description
*format_desc
)
217 boolean first
= TRUE
;
218 boolean success
= TRUE
;
220 for (i
= 0; i
< util_format_nr_test_cases
; ++i
) {
221 const struct util_format_test_case
*test
= &util_format_test_cases
[i
];
223 if (test
->format
== format_desc
->format
) {
226 printf("Testing %s ...\n",
231 if (!test_format(verbose
, fp
, format_desc
, test
)) {
242 test_all(unsigned verbose
, FILE *fp
)
244 enum pipe_format format
;
245 boolean success
= TRUE
;
247 for (format
= 1; format
< PIPE_FORMAT_COUNT
; ++format
) {
248 const struct util_format_description
*format_desc
;
250 format_desc
= util_format_description(format
);
259 if (format_desc
->colorspace
== UTIL_FORMAT_COLORSPACE_ZS
) {
263 if (format_desc
->layout
== UTIL_FORMAT_LAYOUT_S3TC
&&
264 !util_format_s3tc_enabled
) {
268 if (!test_one(verbose
, fp
, format_desc
)) {
278 test_some(unsigned verbose
, FILE *fp
, unsigned long n
)
280 return test_all(verbose
, fp
);