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
);
78 add_fetch_rgba_test(LLVMModuleRef lp_build_module
,
79 const struct util_format_description
*desc
)
83 LLVMValueRef packed_ptr
;
84 LLVMValueRef rgba_ptr
;
87 LLVMBasicBlockRef block
;
88 LLVMBuilderRef builder
;
91 args
[0] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
92 args
[1] = LLVMPointerType(LLVMInt8Type(), 0);
93 args
[3] = args
[2] = LLVMInt32Type();
95 func
= LLVMAddFunction(lp_build_module
, "fetch", LLVMFunctionType(LLVMVoidType(), args
, Elements(args
), 0));
96 LLVMSetFunctionCallConv(func
, LLVMCCallConv
);
97 rgba_ptr
= LLVMGetParam(func
, 0);
98 packed_ptr
= LLVMGetParam(func
, 1);
99 i
= LLVMGetParam(func
, 2);
100 j
= LLVMGetParam(func
, 3);
102 block
= LLVMAppendBasicBlock(func
, "entry");
103 builder
= LLVMCreateBuilder();
104 LLVMPositionBuilderAtEnd(builder
, block
);
106 rgba
= lp_build_fetch_rgba_aos(builder
, desc
, packed_ptr
, i
, j
);
108 LLVMBuildStore(builder
, rgba
, rgba_ptr
);
110 LLVMBuildRetVoid(builder
);
112 LLVMDisposeBuilder(builder
);
119 test_format(unsigned verbose
, FILE *fp
,
120 const struct util_format_description
*desc
,
121 const struct util_format_test_case
*test
)
123 LLVMValueRef fetch
= NULL
;
124 LLVMPassManagerRef pass
= NULL
;
125 fetch_ptr_t fetch_ptr
;
130 fetch
= add_fetch_rgba_test(lp_build_module
, desc
);
132 if (LLVMVerifyFunction(fetch
, LLVMPrintMessageAction
)) {
133 LLVMDumpValue(fetch
);
138 pass
= LLVMCreatePassManager();
139 LLVMAddTargetData(LLVMGetExecutionEngineTargetData(lp_build_engine
), pass
);
140 /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
141 * but there are more on SVN. */
142 LLVMAddConstantPropagationPass(pass
);
143 LLVMAddInstructionCombiningPass(pass
);
144 LLVMAddPromoteMemoryToRegisterPass(pass
);
145 LLVMAddGVNPass(pass
);
146 LLVMAddCFGSimplificationPass(pass
);
147 LLVMRunPassManager(pass
, lp_build_module
);
152 fetch_ptr
= (fetch_ptr_t
) LLVMGetPointerToGlobal(lp_build_engine
, fetch
);
154 for (i
= 0; i
< desc
->block
.height
; ++i
) {
155 for (j
= 0; j
< desc
->block
.width
; ++j
) {
157 memset(unpacked
, 0, sizeof unpacked
);
159 fetch_ptr(unpacked
, test
->packed
, j
, i
);
162 for(k
= 0; k
< 4; ++k
)
163 if (fabs((float)test
->unpacked
[i
][j
][k
] - unpacked
[k
]) > FLT_EPSILON
)
168 printf(" Packed: %02x %02x %02x %02x\n",
169 test
->packed
[0], test
->packed
[1], test
->packed
[2], test
->packed
[3]);
170 printf(" Unpacked (%u,%u): %f %f %f %f obtained\n",
172 unpacked
[0], unpacked
[1], unpacked
[2], unpacked
[3]);
173 printf(" %f %f %f %f expected\n",
174 test
->unpacked
[i
][j
][0],
175 test
->unpacked
[i
][j
][1],
176 test
->unpacked
[i
][j
][2],
177 test
->unpacked
[i
][j
][3]);
183 LLVMDumpValue(fetch
);
185 LLVMFreeMachineCodeForFunction(lp_build_engine
, fetch
);
186 LLVMDeleteFunction(fetch
);
189 LLVMDisposePassManager(pass
);
192 write_tsv_row(fp
, desc
, success
);
200 test_one(unsigned verbose
, FILE *fp
,
201 const struct util_format_description
*format_desc
)
207 for (i
= 0; i
< util_format_nr_test_cases
; ++i
) {
208 const struct util_format_test_case
*test
= &util_format_test_cases
[i
];
210 if (test
->format
== format_desc
->format
) {
213 printf("Testing %s ...\n",
218 if (!test_format(verbose
, fp
, format_desc
, test
)) {
229 test_all(unsigned verbose
, FILE *fp
)
231 enum pipe_format format
;
234 for (format
= 1; format
< PIPE_FORMAT_COUNT
; ++format
) {
235 const struct util_format_description
*format_desc
;
237 format_desc
= util_format_description(format
);
246 if (format_desc
->colorspace
== UTIL_FORMAT_COLORSPACE_ZS
) {
250 if (format_desc
->layout
== UTIL_FORMAT_LAYOUT_S3TC
&&
251 !util_format_s3tc_enabled
) {
255 if (!test_one(verbose
, fp
, format_desc
)) {
265 test_some(unsigned verbose
, FILE *fp
, unsigned long n
)
267 return test_all(verbose
, fp
);