1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 Google Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief SPIR-V Assembly Tests for images and samplers.
22 *//*--------------------------------------------------------------------*/
24 #include "vktSpvAsmImageSamplerTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
29 #include "vkImageUtil.hpp"
30 #include "tcuTextureUtil.hpp"
34 namespace SpirVAssembly
49 TESTTYPE_LOCAL_VARIABLES = 0,
50 TESTTYPE_PASS_IMAGE_TO_FUNCTION,
51 TESTTYPE_PASS_SAMPLER_TO_FUNCTION,
52 TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION,
62 READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD,
63 READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD,
70 DESCRIPTOR_TYPE_STORAGE_IMAGE = 0, // Storage image
71 DESCRIPTOR_TYPE_SAMPLED_IMAGE, // Sampled image
72 DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // Combined image sampler
73 DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES, // Combined image sampler with separate shader variables
74 DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS, // Combined image sampler where image and sampler variables are taken from two different desciptors
81 DEPTH_PROPERTY_NON_DEPTH = 0,
83 DEPTH_PROPERTY_UNKNOWN,
88 bool isValidTestCase (TestType testType, DescriptorType descriptorType, ReadOp readOp)
90 // Check valid descriptor type and test type combinations
93 case TESTTYPE_PASS_IMAGE_TO_FUNCTION:
94 if (descriptorType != DESCRIPTOR_TYPE_STORAGE_IMAGE &&
95 descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
96 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
97 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
101 case TESTTYPE_PASS_SAMPLER_TO_FUNCTION:
102 if (descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
103 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
104 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
108 case TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION:
109 if (descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
110 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
111 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
119 // Check valid descriptor type and read operation combinations
122 case READOP_IMAGEREAD:
123 if (descriptorType != DESCRIPTOR_TYPE_STORAGE_IMAGE)
127 case READOP_IMAGEFETCH:
128 if (descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
129 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
130 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
131 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
135 case READOP_IMAGESAMPLE:
136 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
137 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
138 if (descriptorType != DESCRIPTOR_TYPE_SAMPLED_IMAGE &&
139 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
140 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES &&
141 descriptorType != DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
152 const char* getTestTypeName (TestType testType)
156 case TESTTYPE_LOCAL_VARIABLES:
157 return "all_local_variables";
159 case TESTTYPE_PASS_IMAGE_TO_FUNCTION:
160 return "pass_image_to_function";
162 case TESTTYPE_PASS_SAMPLER_TO_FUNCTION:
163 return "pass_sampler_to_function";
165 case TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION:
166 return "pass_image_and_sampler_to_function";
169 DE_FATAL("Unknown test type");
174 const char* getReadOpName (ReadOp readOp)
178 case READOP_IMAGEREAD:
181 case READOP_IMAGEFETCH:
184 case READOP_IMAGESAMPLE:
185 return "imagesample";
187 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
188 return "imagesample_dref_implicit_lod";
190 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
191 return "imagesample_dref_explicit_lod";
194 DE_FATAL("Unknown readop");
199 const char* getDescriptorName (DescriptorType descType)
203 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
204 return "storage_image";
206 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
207 return "sampled_image";
209 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
210 return "combined_image_sampler";
212 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
213 return "combined_image_sampler_separate_variables";
215 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
216 return "combined_image_sampler_separate_descriptors";
219 DE_FATAL("Unknown descriptor type");
224 const char* getDepthPropertyName (DepthProperty depthProperty)
226 switch (depthProperty)
228 case DEPTH_PROPERTY_NON_DEPTH:
231 case DEPTH_PROPERTY_DEPTH:
234 case DEPTH_PROPERTY_UNKNOWN:
238 DE_FATAL("Unknown depth property");
243 VkDescriptorType getVkDescriptorType (DescriptorType descType)
247 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
248 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
250 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
251 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
253 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
254 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
255 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
256 return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
259 DE_FATAL("Unknown descriptor type");
260 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
264 VkFormat getImageFormat (ReadOp readOp)
268 case READOP_IMAGEREAD:
269 case READOP_IMAGEFETCH:
270 case READOP_IMAGESAMPLE:
271 return VK_FORMAT_R32G32B32A32_SFLOAT;
273 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
274 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
275 return VK_FORMAT_D32_SFLOAT;
278 DE_FATAL("Unknown readop");
279 return VK_FORMAT_UNDEFINED;
283 // Get variables that are declared in the read function, ie. not passed as parameters
284 std::string getFunctionDstVariableStr (ReadOp readOp, DescriptorType descType, TestType testType)
286 const bool passNdx = (testType == TESTTYPE_LOCAL_VARIABLES);
287 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
288 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
290 std::string result = "";
294 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
298 case READOP_IMAGEREAD:
300 return " %func_img = OpLoad %Image %InputData\n";
304 DE_FATAL("Not possible");
309 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
310 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
314 case READOP_IMAGEFETCH:
316 return " %func_img = OpLoad %Image %InputData\n";
318 if (passSmp && !passImg)
319 return " %func_tmp = OpLoad %Image %InputData\n"
320 " %func_smi = OpSampledImage %SampledImage %func_tmp %func_smp\n"
321 " %func_img = OpImage %Image %func_smi\n";
323 if (passSmp && passImg)
324 return " %func_smi = OpSampledImage %SampledImage %func_tmp %func_smp\n"
325 " %func_img = OpImage %Image %func_smi\n";
328 case READOP_IMAGESAMPLE:
329 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
330 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
332 return " %func_img = OpLoad %Image %InputData\n"
333 " %func_smp = OpLoad %Sampler %SamplerData\n"
334 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
336 if (passImg && !passSmp)
337 return " %func_smp = OpLoad %Sampler %SamplerData\n"
338 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
340 if (passSmp && !passImg)
341 return " %func_img = OpLoad %Image %InputData\n"
342 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
344 if (passSmp && passImg)
345 return " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
349 DE_FATAL("Not possible");
354 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
358 case READOP_IMAGEFETCH:
360 return " %func_smi = OpLoad %SampledImage %InputData\n"
361 " %func_img = OpImage %Image %func_smi\n";
364 case READOP_IMAGESAMPLE:
365 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
366 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
368 return " %func_smi = OpLoad %SampledImage %InputData\n";
372 DE_FATAL("Not possible");
377 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
381 case READOP_IMAGEFETCH:
383 return " %func_img = OpLoad %Image %InputData2\n";
385 if (passSmp && !passImg)
386 return " %func_tmp = OpLoad %Image %InputData2\n"
387 " %func_smi = OpSampledImage %SampledImage %func_tmp %func_smp\n"
388 " %func_img = OpImage %Image %func_smi\n";
390 if (passSmp && passImg)
391 return " %func_smi = OpSampledImage %SampledImage %func_tmp %func_smp\n"
392 " %func_img = OpImage %Image %func_smi\n";
395 case READOP_IMAGESAMPLE:
396 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
397 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
399 return " %func_img = OpLoad %Image %InputData2\n"
400 " %func_smp = OpLoad %Sampler %SamplerData\n"
401 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
403 if (passImg && !passSmp)
404 return " %func_smp = OpLoad %Sampler %SamplerData\n"
405 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
407 if (passSmp && !passImg)
408 return " %func_img = OpLoad %Image %InputData2\n"
409 " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
411 if (passSmp && passImg)
412 return " %func_smi = OpSampledImage %SampledImage %func_img %func_smp\n";
416 DE_FATAL("Not possible");
422 DE_FATAL("Unknown descriptor type");
428 // Get variables that are passed to the read function
429 std::string getFunctionSrcVariableStr (ReadOp readOp, DescriptorType descType, TestType testType)
431 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
432 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
438 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
442 case READOP_IMAGEREAD:
444 result += " %call_img = OpLoad %Image %InputData\n";
448 DE_FATAL("Not possible");
452 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
453 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
457 case READOP_IMAGEFETCH:
458 case READOP_IMAGESAMPLE:
459 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
460 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
462 result += " %call_img = OpLoad %Image %InputData\n";
465 result += " %call_smp = OpLoad %Sampler %SamplerData\n";
469 DE_FATAL("Not possible");
473 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
477 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
481 case READOP_IMAGEFETCH:
482 case READOP_IMAGESAMPLE:
483 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
484 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
486 result += " %call_img = OpLoad %Image %InputData2\n";
489 result += " %call_smp = OpLoad %Sampler %SamplerData\n";
493 DE_FATAL("Not possible");
498 DE_FATAL("Unknown descriptor type");
504 // Get parameter types for OpTypeFunction
505 std::string getFunctionParamTypeStr (TestType testType)
507 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
508 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
516 result += " %Sampler";
521 // Get argument names for OpFunctionCall
522 std::string getFunctionSrcParamStr (TestType testType)
524 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
525 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
530 result += " %call_img";
533 result += " %call_smp";
538 // Get OpFunctionParameters
539 std::string getFunctionDstParamStr (ReadOp readOp, TestType testType)
541 const bool passImg = ((testType == TESTTYPE_PASS_IMAGE_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
542 const bool passSmp = ((testType == TESTTYPE_PASS_SAMPLER_TO_FUNCTION) || (testType == TESTTYPE_PASS_IMAGE_AND_SAMPLER_TO_FUNCTION));
546 if (readOp == READOP_IMAGESAMPLE)
549 result += " %func_img = OpFunctionParameter %Image\n";
552 result += " %func_smp = OpFunctionParameter %Sampler\n";
556 if (passImg && !passSmp)
557 result += " %func_img = OpFunctionParameter %Image\n";
559 if (passSmp && !passImg)
560 result += " %func_smp = OpFunctionParameter %Sampler\n";
562 if (passImg && passSmp)
563 result += " %func_tmp = OpFunctionParameter %Image\n"
564 " %func_smp = OpFunctionParameter %Sampler\n";
570 // Get read operation
571 std::string getImageReadOpStr (ReadOp readOp)
575 case READOP_IMAGEREAD:
576 return "OpImageRead %v4f32 %func_img %coord";
578 case READOP_IMAGEFETCH:
579 return "OpImageFetch %v4f32 %func_img %coord";
581 case READOP_IMAGESAMPLE:
582 return "OpImageSampleExplicitLod %v4f32 %func_smi %normalcoordf Lod %c_f32_0";
584 case READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD:
585 return "OpImageSampleDrefImplicitLod %f32 %func_smi %normalcoordf %c_f32_0_5 Bias %c_f32_0";
587 case READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD:
588 return "OpImageSampleDrefExplicitLod %f32 %func_smi %normalcoordf %c_f32_0_5 Lod %c_f32_0";
591 DE_FATAL("Unknown readop");
596 bool isImageSampleDrefReadOp (ReadOp readOp)
598 return (readOp == READOP_IMAGESAMPLE_DREF_IMPLICIT_LOD) || (readOp == READOP_IMAGESAMPLE_DREF_EXPLICIT_LOD);
601 // Get types and pointers for input images and samplers
602 std::string getImageSamplerTypeStr (DescriptorType descType, ReadOp readOp, deUint32 depthProperty)
604 const string imageFormat = isImageSampleDrefReadOp(readOp) ? "R32f" : "Rgba32f";
608 case DESCRIPTOR_TYPE_STORAGE_IMAGE:
609 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 2 " + imageFormat + "\n"
610 " %ImagePtr = OpTypePointer UniformConstant %Image\n"
611 " %InputData = OpVariable %ImagePtr UniformConstant\n";
613 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
614 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 1 " + imageFormat + "\n"
615 " %ImagePtr = OpTypePointer UniformConstant %Image\n"
616 " %InputData = OpVariable %ImagePtr UniformConstant\n"
618 " %Sampler = OpTypeSampler\n"
619 " %SamplerPtr = OpTypePointer UniformConstant %Sampler\n"
620 " %SamplerData = OpVariable %SamplerPtr UniformConstant\n"
621 " %SampledImage = OpTypeSampledImage %Image\n";
623 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
624 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 1 " + imageFormat + "\n"
625 " %SampledImage = OpTypeSampledImage %Image\n"
626 " %SamplerPtr = OpTypePointer UniformConstant %SampledImage\n"
627 " %InputData = OpVariable %SamplerPtr UniformConstant\n";
629 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
630 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 1 " + imageFormat + "\n"
631 " %ImagePtr = OpTypePointer UniformConstant %Image\n"
632 " %InputData = OpVariable %ImagePtr UniformConstant\n"
634 " %Sampler = OpTypeSampler\n"
635 " %SamplerPtr = OpTypePointer UniformConstant %Sampler\n"
636 " %SamplerData = OpVariable %SamplerPtr UniformConstant\n"
637 " %SampledImage = OpTypeSampledImage %Image\n";
639 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
640 return " %Image = OpTypeImage %f32 2D " + de::toString(depthProperty) + " 0 0 1 " + imageFormat + "\n"
641 " %ImagePtr = OpTypePointer UniformConstant %Image\n"
642 " %InputData = OpVariable %ImagePtr UniformConstant\n"
643 " %InputData2 = OpVariable %ImagePtr UniformConstant\n"
645 " %Sampler = OpTypeSampler\n"
646 " %SamplerPtr = OpTypePointer UniformConstant %Sampler\n"
647 " %SamplerData = OpVariable %SamplerPtr UniformConstant\n"
648 " %SamplerData2 = OpVariable %SamplerPtr UniformConstant\n"
649 " %SampledImage = OpTypeSampledImage %Image\n";
652 DE_FATAL("Unknown descriptor type");
657 std::string getSamplerDecoration (DescriptorType descType)
661 // Separate image and sampler
662 case DESCRIPTOR_TYPE_SAMPLED_IMAGE:
663 return " OpDecorate %SamplerData DescriptorSet 0\n"
664 " OpDecorate %SamplerData Binding 1\n";
666 // Combined image sampler with separate variables
667 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_VARIABLES:
668 return " OpDecorate %SamplerData DescriptorSet 0\n"
669 " OpDecorate %SamplerData Binding 0\n";
671 // Two combined image samplers with separate variables
672 case DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS:
673 return " OpDecorate %SamplerData DescriptorSet 0\n"
674 " OpDecorate %SamplerData Binding 0\n"
675 " OpDecorate %InputData2 DescriptorSet 0\n"
676 " OpDecorate %InputData2 Binding 1\n"
677 " OpDecorate %SamplerData2 DescriptorSet 0\n"
678 " OpDecorate %SamplerData2 Binding 1\n";
685 void addComputeImageSamplerTest (tcu::TestCaseGroup* group)
687 tcu::TestContext& testCtx = group->getTestContext();
689 de::Random rnd (deStringHash(group->getName()));
690 const deUint32 numDataPoints = 64;
691 RGBA defaultColors[4];
692 vector<tcu::Vec4> inputData;
694 inputData.reserve(numDataPoints);
696 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
697 inputData.push_back(tcu::Vec4(rnd.getFloat(), rnd.getFloat(), rnd.getFloat(), rnd.getFloat()));
699 for (deUint32 opNdx = 0u; opNdx <= READOP_IMAGESAMPLE; opNdx++)
701 de::MovePtr<tcu::TestCaseGroup> readOpGroup (new tcu::TestCaseGroup(testCtx, getReadOpName((ReadOp)opNdx), ""));
703 for (deUint32 descNdx = 0u; descNdx < DESCRIPTOR_TYPE_LAST; descNdx++)
705 de::MovePtr<tcu::TestCaseGroup> descGroup (new tcu::TestCaseGroup(testCtx, getDescriptorName((DescriptorType)descNdx), ""));
707 for (deUint32 testNdx = 0u; testNdx < TESTTYPE_LAST; testNdx++)
709 if (!isValidTestCase((TestType)testNdx, (DescriptorType)descNdx, (ReadOp)opNdx))
712 const std::string imageReadOp = getImageReadOpStr((ReadOp)opNdx);
714 const std::string imageSamplerTypes = getImageSamplerTypeStr((DescriptorType)descNdx, (ReadOp)opNdx, DEPTH_PROPERTY_NON_DEPTH);
715 const std::string functionParamTypes = getFunctionParamTypeStr((TestType)testNdx);
717 const std::string functionSrcVariables = getFunctionSrcVariableStr((ReadOp)opNdx, (DescriptorType)descNdx, (TestType)testNdx);
718 const std::string functionDstVariables = getFunctionDstVariableStr((ReadOp)opNdx, (DescriptorType)descNdx, (TestType)testNdx);
720 const std::string functionSrcParams = getFunctionSrcParamStr(TestType(testNdx));
721 const std::string functionDstParams = getFunctionDstParamStr((ReadOp)opNdx, TestType(testNdx));
723 getDefaultColors(defaultColors);
725 ComputeShaderSpec spec;
727 spec.numWorkGroups = IVec3(numDataPoints, 1, 1);
729 spec.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
731 // Separate sampler for sampled images
732 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_SAMPLED_IMAGE)
734 vector<tcu::Vec4> dummyData;
735 spec.inputs.push_back(Resource(BufferSp(new Vec4Buffer(dummyData))));
736 spec.inputs[1].setDescriptorType(VK_DESCRIPTOR_TYPE_SAMPLER);
739 // Second combined image sampler with different image data
740 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
742 for (size_t i = 0; i < inputData.size(); i++)
743 inputData[i] = tcu::Vec4(1.0f) - inputData[i];
745 spec.inputs.push_back(BufferSp(new Vec4Buffer(inputData)));
746 spec.inputs[1].setDescriptorType(getVkDescriptorType((DescriptorType)descNdx));
749 // Shader is expected to pass the input image data to the output buffer
750 spec.outputs.push_back(BufferSp(new Vec4Buffer(inputData)));
752 const std::string samplerDecoration = getSamplerDecoration((DescriptorType)descNdx);
754 const string shaderSource =
755 " OpCapability Shader\n"
756 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
757 " OpMemoryModel Logical GLSL450\n"
758 " OpEntryPoint GLCompute %main \"main\" %id\n"
759 " OpExecutionMode %main LocalSize 1 1 1\n"
760 " OpSource GLSL 430\n"
761 " OpDecorate %id BuiltIn GlobalInvocationId\n"
762 " OpDecorate %_arr_v4f_u32_64 ArrayStride 16\n"
763 " OpMemberDecorate %Output 0 Offset 0\n"
764 " OpDecorate %Output BufferBlock\n"
765 " OpDecorate %InputData DescriptorSet 0\n"
766 " OpDecorate %InputData Binding 0\n"
768 + samplerDecoration +
770 " OpDecorate %OutputData DescriptorSet 0\n"
771 " OpDecorate %OutputData Binding " + de::toString(spec.inputs.size()) + "\n"
773 " %void = OpTypeVoid\n"
774 " %3 = OpTypeFunction %void\n"
775 " %u32 = OpTypeInt 32 0\n"
776 " %i32 = OpTypeInt 32 1\n"
777 " %f32 = OpTypeFloat 32\n"
778 " %_ptr_Function_uint = OpTypePointer Function %u32\n"
779 " %v3u32 = OpTypeVector %u32 3\n"
780 " %_ptr_Input_v3u32 = OpTypePointer Input %v3u32\n"
781 " %id = OpVariable %_ptr_Input_v3u32 Input\n"
782 " %c_f32_0 = OpConstant %f32 0.0\n"
783 " %c_u32_0 = OpConstant %u32 0\n"
784 " %c_i32_0 = OpConstant %i32 0\n"
785 " %_ptr_Input_uint = OpTypePointer Input %u32\n"
786 " %v2u32 = OpTypeVector %u32 2\n"
787 " %v2f32 = OpTypeVector %f32 2\n"
788 " %v4f32 = OpTypeVector %f32 4\n"
789 " %uint_128 = OpConstant %u32 128\n"
790 " %c_u32_64 = OpConstant %u32 64\n"
791 " %c_u32_8 = OpConstant %u32 8\n"
792 " %c_f32_8 = OpConstant %f32 8.0\n"
793 " %c_v2f32_8_8 = OpConstantComposite %v2f32 %c_f32_8 %c_f32_8\n"
794 " %_arr_v4f_u32_64 = OpTypeArray %v4f32 %c_u32_64\n"
795 " %_ptr_Uniform_v4f = OpTypePointer Uniform %v4f32\n"
796 " %Output = OpTypeStruct %_arr_v4f_u32_64\n"
797 "%_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
798 " %OutputData = OpVariable %_ptr_Uniform_Output Uniform\n"
800 + imageSamplerTypes +
802 " %read_func_type = OpTypeFunction %void %u32" + functionParamTypes + "\n"
804 " %read_func = OpFunction %void None %read_func_type\n"
805 " %func_ndx = OpFunctionParameter %u32\n"
807 + functionDstParams +
809 " %funcentry = OpLabel\n"
810 " %row = OpUMod %u32 %func_ndx %c_u32_8\n"
811 " %col = OpUDiv %u32 %func_ndx %c_u32_8\n"
812 " %coord = OpCompositeConstruct %v2u32 %row %col\n"
813 " %coordf = OpConvertUToF %v2f32 %coord\n"
814 " %normalcoordf = OpFDiv %v2f32 %coordf %c_v2f32_8_8\n"
816 + functionDstVariables +
818 " %color = " + imageReadOp + "\n"
819 " %36 = OpAccessChain %_ptr_Uniform_v4f %OutputData %c_u32_0 %func_ndx\n"
820 " OpStore %36 %color\n"
824 " %main = OpFunction %void None %3\n"
826 " %i = OpVariable %_ptr_Function_uint Function\n"
827 " %14 = OpAccessChain %_ptr_Input_uint %id %c_u32_0\n"
828 " %15 = OpLoad %u32 %14\n"
830 " %index = OpLoad %u32 %14\n"
832 + functionSrcVariables +
834 " %res = OpFunctionCall %void %read_func %index" + functionSrcParams + "\n"
838 spec.assembly = shaderSource;
840 descGroup->addChild(new SpvAsmComputeShaderCase(testCtx, getTestTypeName((TestType)testNdx), "", spec));
842 readOpGroup->addChild(descGroup.release());
844 group->addChild(readOpGroup.release());
848 map<string, string> generateGraphicsImageSamplerSource (ReadOp readOp, DescriptorType descriptorType, TestType testType, DepthProperty depthProperty, deUint32 outputBinding)
850 map<string, string> source;
852 const std::string imageReadOp = getImageReadOpStr(readOp);
853 const std::string imageSamplerTypes = getImageSamplerTypeStr(descriptorType, readOp, depthProperty);
854 const std::string functionParamTypes = getFunctionParamTypeStr(testType);
855 const std::string functionSrcVariables = getFunctionSrcVariableStr(readOp, descriptorType, testType);
856 const std::string functionDstVariables = getFunctionDstVariableStr(readOp, descriptorType, testType);
857 const std::string functionSrcParams = getFunctionSrcParamStr(testType);
858 const std::string functionDstParams = getFunctionDstParamStr(readOp, testType);
859 const std::string samplerDecoration = getSamplerDecoration(descriptorType);
860 const std::string outputUniformPtr = isImageSampleDrefReadOp(readOp) ? "%_ptr_Uniform_f32" : "%_ptr_Uniform_v4f32";
861 const std::string outputArrayStruct = isImageSampleDrefReadOp(readOp) ? "%_arr_f32_u32_64" : "%_arr_v4f32_u32_64";
864 " %c_u32_64 = OpConstant %u32 64\n"
865 " %c_i32_64 = OpConstant %i32 64\n"
866 " %c_i32_8 = OpConstant %i32 8\n"
867 " %c_v2f32_8_8 = OpConstantComposite %v2f32 %c_f32_8 %c_f32_8\n"
869 " %_arr_f32_u32_64 = OpTypeArray %f32 %c_u32_64\n"
870 " %_arr_v4f32_u32_64 = OpTypeArray %v4f32 %c_u32_64\n"
871 " %_ptr_Uniform_f32 = OpTypePointer Uniform %f32\n"
872 " %_ptr_Uniform_v4f32 = OpTypePointer Uniform %v4f32\n"
874 " %Output = OpTypeStruct " + outputArrayStruct + "\n"
875 "%_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
876 " %OutputData = OpVariable %_ptr_Uniform_Output Uniform\n"
878 + imageSamplerTypes +
880 " %read_func_type = OpTypeFunction %void %i32" + functionParamTypes + "\n";
882 source["decoration"] =
883 " OpDecorate %_arr_f32_u32_64 ArrayStride 4\n"
884 " OpDecorate %_arr_v4f32_u32_64 ArrayStride 16\n"
885 " OpMemberDecorate %Output 0 Offset 0\n"
886 " OpDecorate %Output BufferBlock\n"
887 " OpDecorate %InputData DescriptorSet 0\n"
888 " OpDecorate %InputData Binding 0\n"
890 + samplerDecoration +
892 "OpDecorate %OutputData DescriptorSet 0\n"
893 "OpDecorate %OutputData Binding " + de::toString(outputBinding) + "\n";
896 " %read_func = OpFunction %void None %read_func_type\n"
897 " %func_ndx = OpFunctionParameter %i32\n"
899 + functionDstParams +
901 " %funcentry = OpLabel\n"
903 " %row = OpSRem %i32 %func_ndx %c_i32_8\n"
904 " %col = OpSDiv %i32 %func_ndx %c_i32_8\n"
905 " %coord = OpCompositeConstruct %v2i32 %row %col\n"
906 " %coordf = OpConvertSToF %v2f32 %coord\n"
907 " %normalcoordf = OpFDiv %v2f32 %coordf %c_v2f32_8_8\n"
909 + functionDstVariables +
911 " %color = " + imageReadOp + "\n"
912 " %36 = OpAccessChain " + outputUniformPtr + " %OutputData %c_i32_0 %func_ndx\n"
913 " OpStore %36 %color\n"
918 " %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
919 " %param = OpFunctionParameter %v4f32\n"
921 " %entry = OpLabel\n"
923 " %i = OpVariable %fp_i32 Function\n"
924 " OpStore %i %c_i32_0\n"
928 " %15 = OpLoad %i32 %i\n"
929 " %lt = OpSLessThan %bool %15 %c_i32_64\n"
930 " OpLoopMerge %merge %inc None\n"
931 " OpBranchConditional %lt %write %merge\n"
933 " %write = OpLabel\n"
934 " %index = OpLoad %i32 %i\n"
936 + functionSrcVariables +
938 " %res = OpFunctionCall %void %read_func %index" + functionSrcParams + "\n"
943 " %37 = OpLoad %i32 %i\n"
944 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
948 " %merge = OpLabel\n"
949 " OpReturnValue %param\n"
955 void addGraphicsImageSamplerTest (tcu::TestCaseGroup* group)
957 tcu::TestContext& testCtx = group->getTestContext();
959 de::Random rnd (deStringHash(group->getName()));
960 const deUint32 numDataPoints = 64;
961 RGBA defaultColors[4];
963 SpecConstants noSpecConstants;
964 PushConstants noPushConstants;
965 GraphicsInterfaces noInterfaces;
966 std::vector<std::string> noFeatures;
967 std::vector<std::string> noExtensions;
968 VulkanFeatures vulkanFeatures = VulkanFeatures();
970 vector<tcu::Vec4> inputData(numDataPoints);
971 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
972 inputData[numIdx] = tcu::Vec4(rnd.getFloat(), rnd.getFloat(), rnd.getFloat(), rnd.getFloat());
974 for (deUint32 opNdx = 0u; opNdx <= READOP_IMAGESAMPLE; opNdx++)
976 de::MovePtr<tcu::TestCaseGroup> readOpGroup (new tcu::TestCaseGroup(testCtx, getReadOpName((ReadOp)opNdx), ""));
978 for (deUint32 descNdx = 0u; descNdx < DESCRIPTOR_TYPE_LAST; descNdx++)
980 de::MovePtr<tcu::TestCaseGroup> descGroup (new tcu::TestCaseGroup(testCtx, getDescriptorName((DescriptorType)descNdx), ""));
982 for (deUint32 testNdx = 0u; testNdx < TESTTYPE_LAST; testNdx++)
984 if (!isValidTestCase((TestType)testNdx, (DescriptorType)descNdx, (ReadOp)opNdx))
987 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, getTestTypeName((TestType)testNdx), ""));
989 GraphicsResources resources;
991 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
993 // Separate sampler for sampled images
994 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_SAMPLED_IMAGE)
996 vector<tcu::Vec4> dummyData;
997 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(dummyData)), VK_DESCRIPTOR_TYPE_SAMPLER));
1000 // Second combined image sampler with different image data
1001 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
1003 for (size_t i = 0; i < inputData.size(); i++)
1004 inputData[i] = tcu::Vec4(1.0f) - inputData[i];
1006 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
1009 // Shader is expected to pass the input image data to output buffer
1010 resources.outputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
1012 getDefaultColors(defaultColors);
1014 const map<string, string> fragments = generateGraphicsImageSamplerSource((ReadOp)opNdx, (DescriptorType)descNdx, (TestType)testNdx, DEPTH_PROPERTY_NON_DEPTH, (deUint32)resources.inputs.size());
1016 vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
1017 vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_FALSE;
1018 createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, "shader_vert", defaultColors, defaultColors, fragments, noSpecConstants,
1019 noPushConstants, resources, noInterfaces, noExtensions, noFeatures, vulkanFeatures, typeGroup.get());
1021 createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "shader_tessc", defaultColors, defaultColors, fragments, noSpecConstants,
1022 noPushConstants, resources, noInterfaces, noExtensions, noFeatures, vulkanFeatures, typeGroup.get());
1024 createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "shader_tesse", defaultColors, defaultColors, fragments, noSpecConstants,
1025 noPushConstants, resources, noInterfaces, noExtensions, noFeatures, vulkanFeatures, typeGroup.get());
1027 createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, "shader_geom", defaultColors, defaultColors, fragments, noSpecConstants,
1028 noPushConstants, resources, noInterfaces, noExtensions, noFeatures, vulkanFeatures, typeGroup.get());
1030 vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
1031 vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_TRUE;
1032 createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, "shader_frag", defaultColors, defaultColors, fragments, noSpecConstants,
1033 noPushConstants, resources, noInterfaces, noExtensions, noFeatures, vulkanFeatures, typeGroup.get());
1035 descGroup->addChild(typeGroup.release());
1037 readOpGroup->addChild(descGroup.release());
1039 group->addChild(readOpGroup.release());
1043 bool verifyDepthCompareResult (const std::vector<Resource>& originalFloats,
1044 const std::vector<AllocationSp>& outputAllocs,
1045 const std::vector<Resource>& expectedOutputs,
1048 DE_UNREF(originalFloats);
1050 if (outputAllocs.size() != expectedOutputs.size())
1053 vector<deUint8> expectedBytes;
1054 expectedOutputs[0].getBytes(expectedBytes);
1056 const float* returnedAsFloat = static_cast<const float*>(outputAllocs[0]->getHostPtr());
1057 const float* expectedAsFloat = reinterpret_cast<const float*>(&expectedBytes.front());
1059 for (deUint32 elementNdx = 0; elementNdx < static_cast<deUint32>(expectedBytes.size() / sizeof(float)); ++elementNdx)
1061 const float input = expectedAsFloat[elementNdx];
1062 const float result = returnedAsFloat[elementNdx];
1064 // VK_COMPARE_OP_LESS: D = 1.0 if D < Dref, otherwise D = 0.0
1065 if ((input < 0.5f && result != 0.0f) || (input >= 0.5f && result != 1.0f))
1072 void addGraphicsDepthPropertyTest (tcu::TestCaseGroup* group)
1074 tcu::TestContext& testCtx = group->getTestContext();
1076 de::Random rnd (deStringHash(group->getName()));
1077 const deUint32 numDataPoints = 64;
1078 RGBA defaultColors[4];
1079 vector<Vec4> inputDataVec4;
1081 SpecConstants noSpecConstants;
1082 PushConstants noPushConstants;
1083 GraphicsInterfaces noInterfaces;
1084 std::vector<std::string> noFeatures;
1085 std::vector<std::string> noExtensions;
1086 VulkanFeatures vulkanFeatures = VulkanFeatures();
1088 vulkanFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
1089 vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = DE_TRUE;
1091 inputDataVec4.reserve(numDataPoints);
1093 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
1094 inputDataVec4.push_back(Vec4(rnd.getFloat(), rnd.getFloat(), rnd.getFloat(), rnd.getFloat()));
1096 de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "depth_property", ""));
1098 for (deUint32 propertyNdx = 0u; propertyNdx < DEPTH_PROPERTY_LAST; propertyNdx++)
1100 de::MovePtr<tcu::TestCaseGroup> depthPropertyGroup (new tcu::TestCaseGroup(testCtx, getDepthPropertyName((DepthProperty)propertyNdx), ""));
1102 for (deUint32 opNdx = 0u; opNdx < READOP_LAST; opNdx++)
1104 de::MovePtr<tcu::TestCaseGroup> readOpGroup (new tcu::TestCaseGroup(testCtx, getReadOpName((ReadOp)opNdx), ""));
1106 for (deUint32 descNdx = DESCRIPTOR_TYPE_SAMPLED_IMAGE; descNdx < DESCRIPTOR_TYPE_LAST; descNdx++)
1108 de::MovePtr<tcu::TestCaseGroup> descGroup (new tcu::TestCaseGroup(testCtx, getDescriptorName((DescriptorType)descNdx), ""));
1110 if (!isValidTestCase(TESTTYPE_LOCAL_VARIABLES, (DescriptorType)descNdx, (ReadOp)opNdx))
1113 const VkFormat imageFormat = getImageFormat((ReadOp)opNdx);
1114 const bool hasDpethComponent = tcu::hasDepthComponent(vk::mapVkFormat(imageFormat).order);
1116 GraphicsResources resources;
1117 resources.inputFormat = imageFormat;
1119 std::vector<Vec4> inputData = inputDataVec4;
1121 // Depth images have one channel, thus only needing 1/4 of the data
1122 if (hasDpethComponent)
1123 inputData.resize(numDataPoints / 4u);
1125 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
1127 // Separate sampler for sampled images
1128 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1130 vector<Vec4> dummyData;
1131 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(dummyData)), VK_DESCRIPTOR_TYPE_SAMPLER));
1134 // Second combined image sampler with different image data
1135 if ((DescriptorType)descNdx == DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER_SEPARATE_DESCRIPTORS)
1137 for (size_t i = 0; i < inputData.size(); i++)
1138 inputData[i] = Vec4(1.0f) - inputData[i];
1140 resources.inputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), getVkDescriptorType((DescriptorType)descNdx)));
1143 // Read image without depth reference: shader is expected to pass the input image data to output buffer
1144 resources.outputs.push_back(Resource(BufferSp(new Vec4Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
1146 // Read image with depth reference: shader is expected to pass the depth comparison result to output buffer
1147 if (hasDpethComponent)
1148 resources.verifyIO = verifyDepthCompareResult;
1150 const map<string, string> fragments = generateGraphicsImageSamplerSource((ReadOp)opNdx, (DescriptorType)descNdx, TESTTYPE_LOCAL_VARIABLES, (DepthProperty)propertyNdx, (deUint32)resources.inputs.size());
1152 getDefaultColors(defaultColors);
1154 createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, "shader_frag", defaultColors, defaultColors, fragments, noSpecConstants,
1155 noPushConstants, resources, noInterfaces, noExtensions, noFeatures, vulkanFeatures, descGroup.get());
1157 readOpGroup->addChild(descGroup.release());
1159 depthPropertyGroup->addChild(readOpGroup.release());
1161 testGroup->addChild(depthPropertyGroup.release());
1163 group->addChild(testGroup.release());
1167 tcu::TestCaseGroup* createImageSamplerComputeGroup (tcu::TestContext& testCtx)
1169 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "image_sampler", "Compute tests for combining images and samplers."));
1170 addComputeImageSamplerTest(group.get());
1172 return group.release();
1175 tcu::TestCaseGroup* createImageSamplerGraphicsGroup (tcu::TestContext& testCtx)
1177 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "image_sampler", "Graphics tests for combining images and samplers."));
1179 addGraphicsImageSamplerTest(group.get());
1180 addGraphicsDepthPropertyTest(group.get());
1182 return group.release();