xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/api/vktApiSmokeTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  *//*!
20  * \file
21  * \brief Simple Smoke Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktApiTests.hpp"
25 
26 #include "vktTestCaseUtil.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkStrUtil.hpp"
31 #include "vkRef.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkDeviceUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 
42 #include "tcuTestLog.hpp"
43 #include "tcuFormatUtil.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuImageCompare.hpp"
46 
47 #include "rrRenderer.hpp"
48 
49 #include "deUniquePtr.hpp"
50 
51 namespace vkt
52 {
53 namespace api
54 {
55 
56 namespace
57 {
58 
59 using namespace vk;
60 using de::UniquePtr;
61 using std::vector;
62 using tcu::TestLog;
63 
createSamplerTest(Context & context)64 tcu::TestStatus createSamplerTest(Context &context)
65 {
66     const VkDevice vkDevice   = context.getDevice();
67     const DeviceInterface &vk = context.getDeviceInterface();
68 
69     {
70         const struct VkSamplerCreateInfo samplerInfo = {
71             VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,   // sType
72             DE_NULL,                                 // pNext
73             0u,                                      // flags
74             VK_FILTER_NEAREST,                       // magFilter
75             VK_FILTER_NEAREST,                       // minFilter
76             VK_SAMPLER_MIPMAP_MODE_NEAREST,          // mipmapMode
77             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // addressModeU
78             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // addressModeV
79             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // addressModeW
80             0.0f,                                    // mipLodBias
81             VK_FALSE,                                // anisotropyEnable
82             1.0f,                                    // maxAnisotropy
83             false,                                   // compareEnable
84             VK_COMPARE_OP_ALWAYS,                    // compareOp
85             0.0f,                                    // minLod
86             0.0f,                                    // maxLod
87             VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor
88             VK_FALSE,                                // unnormalizedCoords
89         };
90 
91         Move<VkSampler> tmpSampler = createSampler(vk, vkDevice, &samplerInfo);
92         Move<VkSampler> tmp2Sampler;
93 
94         tmp2Sampler = tmpSampler;
95 
96         const Unique<VkSampler> sampler(tmp2Sampler);
97     }
98 
99     return tcu::TestStatus::pass("Creating sampler succeeded");
100 }
101 
createShaderProgs(SourceCollections & dst)102 void createShaderProgs(SourceCollections &dst)
103 {
104     dst.glslSources.add("test") << glu::VertexSource("#version 310 es\n"
105                                                      "layout(location = 0) in highp vec4 a_position;\n"
106                                                      "void main (void) { gl_Position = a_position; }\n");
107 }
108 
createShaderModuleTest(Context & context)109 tcu::TestStatus createShaderModuleTest(Context &context)
110 {
111     const VkDevice vkDevice   = context.getDevice();
112     const DeviceInterface &vk = context.getDeviceInterface();
113     const Unique<VkShaderModule> shader(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("test"), 0));
114 
115     return tcu::TestStatus::pass("Creating shader module succeeded");
116 }
117 
createTriangleAsmProgs(SourceCollections & dst)118 void createTriangleAsmProgs(SourceCollections &dst)
119 {
120     dst.spirvAsmSources.add("vert") << "         OpCapability Shader\n"
121                                        "%1 =     OpExtInstImport \"GLSL.std.450\"\n"
122                                        "         OpMemoryModel Logical GLSL450\n"
123                                        "         OpEntryPoint Vertex %4 \"main\" %10 %12 %16 %17\n"
124                                        "         OpSource ESSL 300\n"
125                                        "         OpName %4 \"main\"\n"
126                                        "         OpName %10 \"gl_Position\"\n"
127                                        "         OpName %12 \"a_position\"\n"
128                                        "         OpName %16 \"gl_VertexIndex\"\n"
129                                        "         OpName %17 \"gl_InstanceIndex\"\n"
130                                        "         OpDecorate %10 BuiltIn Position\n"
131                                        "         OpDecorate %12 Location 0\n"
132                                        "         OpDecorate %16 BuiltIn VertexIndex\n"
133                                        "         OpDecorate %17 BuiltIn InstanceIndex\n"
134                                        "%2 =     OpTypeVoid\n"
135                                        "%3 =     OpTypeFunction %2\n"
136                                        "%7 =     OpTypeFloat 32\n"
137                                        "%8 =     OpTypeVector %7 4\n"
138                                        "%9 =     OpTypePointer Output %8\n"
139                                        "%10 =     OpVariable %9 Output\n"
140                                        "%11 =     OpTypePointer Input %8\n"
141                                        "%12 =     OpVariable %11 Input\n"
142                                        "%14 =     OpTypeInt 32 1\n"
143                                        "%15 =     OpTypePointer Input %14\n"
144                                        "%16 =     OpVariable %15 Input\n"
145                                        "%17 =     OpVariable %15 Input\n"
146                                        "%4 =     OpFunction %2 None %3\n"
147                                        "%5 =     OpLabel\n"
148                                        "%13 =     OpLoad %8 %12\n"
149                                        "         OpStore %10 %13\n"
150                                        "         OpBranch %6\n"
151                                        "%6 =     OpLabel\n"
152                                        "         OpReturn\n"
153                                        "         OpFunctionEnd\n";
154     dst.spirvAsmSources.add("frag") << "        OpCapability Shader\n"
155                                        "%1 =    OpExtInstImport \"GLSL.std.450\"\n"
156                                        "        OpMemoryModel Logical GLSL450\n"
157                                        "        OpEntryPoint Fragment %4 \"main\" %10\n"
158                                        "        OpExecutionMode %4 OriginUpperLeft\n"
159                                        "        OpSource ESSL 300\n"
160                                        "        OpName %4 \"main\"\n"
161                                        "        OpName %10 \"o_color\"\n"
162                                        "        OpDecorate %10 RelaxedPrecision\n"
163                                        "        OpDecorate %10 Location 0\n"
164                                        "%2 =    OpTypeVoid\n"
165                                        "%3 =    OpTypeFunction %2\n"
166                                        "%7 =    OpTypeFloat 32\n"
167                                        "%8 =    OpTypeVector %7 4\n"
168                                        "%9 =    OpTypePointer Output %8\n"
169                                        "%10 =    OpVariable %9 Output\n"
170                                        "%11 =    OpConstant %7 1065353216\n"
171                                        "%12 =    OpConstant %7 0\n"
172                                        "%13 =    OpConstantComposite %8 %11 %12 %11 %11\n"
173                                        "%4 =    OpFunction %2 None %3\n"
174                                        "%5 =    OpLabel\n"
175                                        "        OpStore %10 %13\n"
176                                        "        OpBranch %6\n"
177                                        "%6 =    OpLabel\n"
178                                        "        OpReturn\n"
179                                        "        OpFunctionEnd\n";
180 }
181 
createTriangleProgs(SourceCollections & dst)182 void createTriangleProgs(SourceCollections &dst)
183 {
184     dst.glslSources.add("vert") << glu::VertexSource("#version 310 es\n"
185                                                      "layout(location = 0) in highp vec4 a_position;\n"
186                                                      "void main (void) { gl_Position = a_position; }\n");
187     dst.glslSources.add("frag") << glu::FragmentSource("#version 310 es\n"
188                                                        "layout(location = 0) out lowp vec4 o_color;\n"
189                                                        "void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
190 }
191 
createProgsNoOpName(SourceCollections & dst)192 void createProgsNoOpName(SourceCollections &dst)
193 {
194     dst.spirvAsmSources.add("vert") << "OpCapability Shader\n"
195                                        "%1 = OpExtInstImport \"GLSL.std.450\"\n"
196                                        "OpMemoryModel Logical GLSL450\n"
197                                        "OpEntryPoint Vertex %4 \"main\" %20 %22 %26\n"
198                                        "OpSource ESSL 310\n"
199                                        "OpMemberDecorate %18 0 BuiltIn Position\n"
200                                        "OpMemberDecorate %18 1 BuiltIn PointSize\n"
201                                        "OpDecorate %18 Block\n"
202                                        "OpDecorate %22 Location 0\n"
203                                        "OpDecorate %26 Location 2\n"
204                                        "%2 = OpTypeVoid\n"
205                                        "%3 = OpTypeFunction %2\n"
206                                        "%6 = OpTypeFloat 32\n"
207                                        "%7 = OpTypeVector %6 4\n"
208                                        "%8 = OpTypeStruct %7\n"
209                                        "%9 = OpTypePointer Function %8\n"
210                                        "%11 = OpTypeInt 32 1\n"
211                                        "%12 = OpConstant %11 0\n"
212                                        "%13 = OpConstant %6 1\n"
213                                        "%14 = OpConstant %6 0\n"
214                                        "%15 = OpConstantComposite %7 %13 %14 %13 %13\n"
215                                        "%16 = OpTypePointer Function %7\n"
216                                        "%18 = OpTypeStruct %7 %6\n"
217                                        "%19 = OpTypePointer Output %18\n"
218                                        "%20 = OpVariable %19 Output\n"
219                                        "%21 = OpTypePointer Input %7\n"
220                                        "%22 = OpVariable %21 Input\n"
221                                        "%24 = OpTypePointer Output %7\n"
222                                        "%26 = OpVariable %24 Output\n"
223                                        "%4 = OpFunction %2 None %3\n"
224                                        "%5 = OpLabel\n"
225                                        "%10 = OpVariable %9 Function\n"
226                                        "%17 = OpAccessChain %16 %10 %12\n"
227                                        "OpStore %17 %15\n"
228                                        "%23 = OpLoad %7 %22\n"
229                                        "%25 = OpAccessChain %24 %20 %12\n"
230                                        "OpStore %25 %23\n"
231                                        "%27 = OpAccessChain %16 %10 %12\n"
232                                        "%28 = OpLoad %7 %27\n"
233                                        "OpStore %26 %28\n"
234                                        "OpReturn\n"
235                                        "OpFunctionEnd\n";
236     dst.spirvAsmSources.add("frag") << "OpCapability Shader\n"
237                                        "%1 = OpExtInstImport \"GLSL.std.450\"\n"
238                                        "OpMemoryModel Logical GLSL450\n"
239                                        "OpEntryPoint Fragment %4 \"main\" %9 %11\n"
240                                        "OpExecutionMode %4 OriginUpperLeft\n"
241                                        "OpSource ESSL 310\n"
242                                        "OpDecorate %9 RelaxedPrecision\n"
243                                        "OpDecorate %9 Location 0\n"
244                                        "OpDecorate %11 Location 2\n"
245                                        "%2 = OpTypeVoid\n"
246                                        "%3 = OpTypeFunction %2\n"
247                                        "%6 = OpTypeFloat 32\n"
248                                        "%7 = OpTypeVector %6 4\n"
249                                        "%8 = OpTypePointer Output %7\n"
250                                        "%9 = OpVariable %8 Output\n"
251                                        "%10 = OpTypePointer Input %7\n"
252                                        "%11 = OpVariable %10 Input\n"
253                                        "%4 = OpFunction %2 None %3\n"
254                                        "%5 = OpLabel\n"
255                                        "%12 = OpLoad %7 %11\n"
256                                        "OpStore %9 %12\n"
257                                        "OpReturn\n"
258                                        "OpFunctionEnd\n";
259 }
260 
261 class RefVertexShader : public rr::VertexShader
262 {
263 public:
RefVertexShader(void)264     RefVertexShader(void) : rr::VertexShader(1, 0)
265     {
266         m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
267     }
268 
~RefVertexShader()269     virtual ~RefVertexShader()
270     {
271     }
272 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const273     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const
274     {
275         for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
276         {
277             packets[packetNdx]->position =
278                 rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
279         }
280     }
281 };
282 
283 class RefFragmentShader : public rr::FragmentShader
284 {
285 public:
RefFragmentShader(void)286     RefFragmentShader(void) : rr::FragmentShader(0, 1)
287     {
288         m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
289     }
290 
~RefFragmentShader()291     virtual ~RefFragmentShader()
292     {
293     }
294 
shadeFragments(rr::FragmentPacket *,const int numPackets,const rr::FragmentShadingContext & context) const295     void shadeFragments(rr::FragmentPacket *, const int numPackets, const rr::FragmentShadingContext &context) const
296     {
297         for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
298         {
299             for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
300             {
301                 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
302             }
303         }
304     }
305 };
306 
renderReferenceTriangle(const tcu::PixelBufferAccess & dst,const tcu::Vec4 (& vertices)[3],const int subpixelBits)307 void renderReferenceTriangle(const tcu::PixelBufferAccess &dst, const tcu::Vec4 (&vertices)[3], const int subpixelBits)
308 {
309     const RefVertexShader vertShader;
310     const RefFragmentShader fragShader;
311     const rr::Program program(&vertShader, &fragShader);
312     const rr::MultisamplePixelBufferAccess colorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(dst);
313     const rr::RenderTarget renderTarget(colorBuffer);
314     const rr::RenderState renderState((rr::ViewportState(colorBuffer)), subpixelBits,
315                                       rr::VIEWPORTORIENTATION_UPPER_LEFT);
316     const rr::Renderer renderer;
317     const rr::VertexAttrib vertexAttribs[] = {
318         rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, vertices[0].getPtr())};
319 
320     renderer.draw(rr::DrawCommand(renderState, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs),
321                                   &vertexAttribs[0],
322                                   rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, DE_LENGTH_OF_ARRAY(vertices), 0)));
323 }
324 
renderTriangleTest(Context & context)325 tcu::TestStatus renderTriangleTest(Context &context)
326 {
327     const VkDevice vkDevice         = context.getDevice();
328     const DeviceInterface &vk       = context.getDeviceInterface();
329     const VkQueue queue             = context.getUniversalQueue();
330     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
331     SimpleAllocator memAlloc(
332         vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
333     const tcu::IVec2 renderSize(256, 256);
334     const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
335     const tcu::Vec4 clearColor(0.125f, 0.25f, 0.75f, 1.0f);
336 
337     const tcu::Vec4 vertices[] = {tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
338                                   tcu::Vec4(0.0f, +0.5f, 0.0f, 1.0f)};
339 
340     const VkBufferCreateInfo vertexBufferParams = {
341         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
342         DE_NULL,                              // pNext
343         0u,                                   // flags
344         (VkDeviceSize)sizeof(vertices),       // size
345         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // usage
346         VK_SHARING_MODE_EXCLUSIVE,            // sharingMode
347         1u,                                   // queueFamilyIndexCount
348         &queueFamilyIndex,                    // pQueueFamilyIndices
349     };
350     const Unique<VkBuffer> vertexBuffer(createBuffer(vk, vkDevice, &vertexBufferParams));
351     const UniquePtr<Allocation> vertexBufferMemory(
352         memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
353 
354     VK_CHECK(
355         vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
356 
357     const VkDeviceSize imageSizeBytes              = (VkDeviceSize)(sizeof(uint32_t) * renderSize.x() * renderSize.y());
358     const VkBufferCreateInfo readImageBufferParams = {
359         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
360         DE_NULL,                              // pNext
361         (VkBufferCreateFlags)0u,              // flags
362         imageSizeBytes,                       // size
363         VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // usage
364         VK_SHARING_MODE_EXCLUSIVE,            // sharingMode
365         1u,                                   // queueFamilyIndexCount
366         &queueFamilyIndex,                    // pQueueFamilyIndices
367     };
368     const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
369     const UniquePtr<Allocation> readImageBufferMemory(
370         memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
371 
372     VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(),
373                                  readImageBufferMemory->getOffset()));
374 
375     const VkImageCreateInfo imageParams = {
376         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                   // sType
377         DE_NULL,                                                               // pNext
378         0u,                                                                    // flags
379         VK_IMAGE_TYPE_2D,                                                      // imageType
380         VK_FORMAT_R8G8B8A8_UNORM,                                              // format
381         {(uint32_t)renderSize.x(), (uint32_t)renderSize.y(), 1},               // extent
382         1u,                                                                    // mipLevels
383         1u,                                                                    // arraySize
384         VK_SAMPLE_COUNT_1_BIT,                                                 // samples
385         VK_IMAGE_TILING_OPTIMAL,                                               // tiling
386         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
387         VK_SHARING_MODE_EXCLUSIVE,                                             // sharingMode
388         1u,                                                                    // queueFamilyIndexCount
389         &queueFamilyIndex,                                                     // pQueueFamilyIndices
390         VK_IMAGE_LAYOUT_UNDEFINED,                                             // initialLayout
391     };
392 
393     const Unique<VkImage> image(createImage(vk, vkDevice, &imageParams));
394     const UniquePtr<Allocation> imageMemory(
395         memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any));
396 
397     VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
398 
399     const Unique<VkRenderPass> renderPass(makeRenderPass(vk, vkDevice, VK_FORMAT_R8G8B8A8_UNORM));
400 
401     const VkImageViewCreateInfo colorAttViewParams = {
402         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                                                         // sType
403         DE_NULL,                                                                                          // pNext
404         0u,                                                                                               // flags
405         *image,                                                                                           // image
406         VK_IMAGE_VIEW_TYPE_2D,                                                                            // viewType
407         VK_FORMAT_R8G8B8A8_UNORM,                                                                         // format
408         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, // components
409         {
410             VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
411             0u,                        // baseMipLevel
412             1u,                        // levelCount
413             0u,                        // baseArrayLayer
414             1u,                        // layerCount
415         },                             // subresourceRange
416     };
417     const Unique<VkImageView> colorAttView(createImageView(vk, vkDevice, &colorAttViewParams));
418 
419     // Pipeline layout
420     const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
421         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
422         DE_NULL,                                       // pNext
423         (vk::VkPipelineLayoutCreateFlags)0,
424         0u,      // setLayoutCount
425         DE_NULL, // pSetLayouts
426         0u,      // pushConstantRangeCount
427         DE_NULL, // pPushConstantRanges
428     };
429     const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
430 
431     // Shaders
432     const Unique<VkShaderModule> vertShaderModule(
433         createShaderModule(vk, vkDevice, context.getBinaryCollection().get("vert"), 0));
434     const Unique<VkShaderModule> fragShaderModule(
435         createShaderModule(vk, vkDevice, context.getBinaryCollection().get("frag"), 0));
436 
437     // Pipeline
438     const std::vector<VkViewport> viewports(1, makeViewport(renderSize));
439     const std::vector<VkRect2D> scissors(1, makeRect2D(renderSize));
440 
441     const Unique<VkPipeline> pipeline(
442         makeGraphicsPipeline(vk,                // const DeviceInterface&            vk
443                              vkDevice,          // const VkDevice                    device
444                              *pipelineLayout,   // const VkPipelineLayout            pipelineLayout
445                              *vertShaderModule, // const VkShaderModule              vertexShaderModule
446                              DE_NULL,           // const VkShaderModule              tessellationControlModule
447                              DE_NULL,           // const VkShaderModule              tessellationEvalModule
448                              DE_NULL,           // const VkShaderModule              geometryShaderModule
449                              *fragShaderModule, // const VkShaderModule              fragmentShaderModule
450                              *renderPass,       // const VkRenderPass                renderPass
451                              viewports,         // const std::vector<VkViewport>&    viewports
452                              scissors));        // const std::vector<VkRect2D>&      scissors
453 
454     // Framebuffer
455     const VkFramebufferCreateInfo framebufferParams = {
456         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
457         DE_NULL,                                   // pNext
458         0u,                                        // flags
459         *renderPass,                               // renderPass
460         1u,                                        // attachmentCount
461         &*colorAttView,                            // pAttachments
462         (uint32_t)renderSize.x(),                  // width
463         (uint32_t)renderSize.y(),                  // height
464         1u,                                        // layers
465     };
466     const Unique<VkFramebuffer> framebuffer(createFramebuffer(vk, vkDevice, &framebufferParams));
467 
468     const VkCommandPoolCreateInfo cmdPoolParams = {
469         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,      // sType
470         DE_NULL,                                         // pNext
471         VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
472         queueFamilyIndex,                                // queueFamilyIndex
473     };
474     const Unique<VkCommandPool> cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
475 
476     // Command buffer
477     const VkCommandBufferAllocateInfo cmdBufParams = {
478         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
479         DE_NULL,                                        // pNext
480         *cmdPool,                                       // pool
481         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                // level
482         1u,                                             // bufferCount
483     };
484     const Unique<VkCommandBuffer> cmdBuf(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
485 
486     // Record commands
487     beginCommandBuffer(vk, *cmdBuf);
488 
489     {
490         const VkMemoryBarrier vertFlushBarrier = {
491             VK_STRUCTURE_TYPE_MEMORY_BARRIER,    // sType
492             DE_NULL,                             // pNext
493             VK_ACCESS_HOST_WRITE_BIT,            // srcAccessMask
494             VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // dstAccessMask
495         };
496         const VkImageMemoryBarrier colorAttBarrier = {
497             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                       // sType
498             DE_NULL,                                                                      // pNext
499             0u,                                                                           // srcAccessMask
500             (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask
501             VK_IMAGE_LAYOUT_UNDEFINED,                                                    // oldLayout
502             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                     // newLayout
503             queueFamilyIndex,                                                             // srcQueueFamilyIndex
504             queueFamilyIndex,                                                             // dstQueueFamilyIndex
505             *image,                                                                       // image
506             {
507                 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
508                 0u,                        // baseMipLevel
509                 1u,                        // levelCount
510                 0u,                        // baseArrayLayer
511                 1u,                        // layerCount
512             }                              // subresourceRange
513         };
514         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
515                               (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
516                               &colorAttBarrier);
517     }
518 
519     beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()),
520                     clearColor);
521 
522     vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
523     {
524         const VkDeviceSize bindingOffset = 0;
525         vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
526     }
527     vk.cmdDraw(*cmdBuf, 3u, 1u, 0u, 0u);
528     endRenderPass(vk, *cmdBuf);
529     copyImageToBuffer(vk, *cmdBuf, *image, *readImageBuffer, renderSize);
530     endCommandBuffer(vk, *cmdBuf);
531 
532     // Upload vertex data
533     deMemcpy(vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
534     flushAlloc(vk, vkDevice, *vertexBufferMemory);
535 
536     // Submit & wait for completion
537     submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
538 
539     // Read results, render reference, compare
540     {
541         const tcu::TextureFormat tcuFormat = vk::mapVkFormat(colorFormat);
542         const tcu::ConstPixelBufferAccess resultAccess(tcuFormat, renderSize.x(), renderSize.y(), 1,
543                                                        readImageBufferMemory->getHostPtr());
544 
545         invalidateAlloc(vk, vkDevice, *readImageBufferMemory);
546 
547         {
548             tcu::TextureLevel refImage(tcuFormat, renderSize.x(), renderSize.y());
549             const tcu::UVec4 threshold(0u);
550             const tcu::IVec3 posDeviation(1, 1, 0);
551 
552             tcu::clear(refImage.getAccess(), clearColor);
553             renderReferenceTriangle(refImage.getAccess(), vertices,
554                                     context.getDeviceProperties().limits.subPixelPrecisionBits);
555 
556             if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(), "ComparisonResult",
557                                                           "Image comparison result", refImage.getAccess(), resultAccess,
558                                                           threshold, posDeviation, false, tcu::COMPARE_LOG_RESULT))
559                 return tcu::TestStatus::pass("Rendering succeeded");
560             else
561                 return tcu::TestStatus::fail("Image comparison failed");
562         }
563     }
564 
565     return tcu::TestStatus::pass("Rendering succeeded");
566 }
567 
568 struct VoidVulkanStruct
569 {
570     VkStructureType sType;
571     const void *pNext;
572 };
573 
renderTriangleUnusedResolveAttachmentTest(Context & context)574 tcu::TestStatus renderTriangleUnusedResolveAttachmentTest(Context &context)
575 {
576     const VkDevice vkDevice         = context.getDevice();
577     const DeviceInterface &vk       = context.getDeviceInterface();
578     const VkQueue queue             = context.getUniversalQueue();
579     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
580     SimpleAllocator memAlloc(
581         vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
582     const tcu::IVec2 renderSize(256, 256);
583     const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
584     const tcu::Vec4 clearColor(0.125f, 0.25f, 0.75f, 1.0f);
585 
586     const tcu::Vec4 vertices[] = {tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
587                                   tcu::Vec4(0.0f, +0.5f, 0.0f, 1.0f)};
588 
589     const VkBufferCreateInfo vertexBufferParams = {
590         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
591         DE_NULL,                              // pNext
592         0u,                                   // flags
593         (VkDeviceSize)sizeof(vertices),       // size
594         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // usage
595         VK_SHARING_MODE_EXCLUSIVE,            // sharingMode
596         1u,                                   // queueFamilyIndexCount
597         &queueFamilyIndex,                    // pQueueFamilyIndices
598     };
599     const Unique<VkBuffer> vertexBuffer(createBuffer(vk, vkDevice, &vertexBufferParams));
600     const UniquePtr<Allocation> vertexBufferMemory(
601         memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
602 
603     VK_CHECK(
604         vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
605 
606     const VkDeviceSize imageSizeBytes              = (VkDeviceSize)(sizeof(uint32_t) * renderSize.x() * renderSize.y());
607     const VkBufferCreateInfo readImageBufferParams = {
608         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
609         DE_NULL,                              // pNext
610         (VkBufferCreateFlags)0u,              // flags
611         imageSizeBytes,                       // size
612         VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // usage
613         VK_SHARING_MODE_EXCLUSIVE,            // sharingMode
614         1u,                                   // queueFamilyIndexCount
615         &queueFamilyIndex,                    // pQueueFamilyIndices
616     };
617     const Unique<VkBuffer> readImageBuffer(createBuffer(vk, vkDevice, &readImageBufferParams));
618     const UniquePtr<Allocation> readImageBufferMemory(
619         memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
620 
621     VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(),
622                                  readImageBufferMemory->getOffset()));
623 
624     const VkImageCreateInfo imageParams = {
625         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                   // sType
626         DE_NULL,                                                               // pNext
627         0u,                                                                    // flags
628         VK_IMAGE_TYPE_2D,                                                      // imageType
629         VK_FORMAT_R8G8B8A8_UNORM,                                              // format
630         {(uint32_t)renderSize.x(), (uint32_t)renderSize.y(), 1},               // extent
631         1u,                                                                    // mipLevels
632         1u,                                                                    // arraySize
633         VK_SAMPLE_COUNT_1_BIT,                                                 // samples
634         VK_IMAGE_TILING_OPTIMAL,                                               // tiling
635         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
636         VK_SHARING_MODE_EXCLUSIVE,                                             // sharingMode
637         1u,                                                                    // queueFamilyIndexCount
638         &queueFamilyIndex,                                                     // pQueueFamilyIndices
639         VK_IMAGE_LAYOUT_UNDEFINED,                                             // initialLayout
640     };
641 
642     const Unique<VkImage> image(createImage(vk, vkDevice, &imageParams));
643     const UniquePtr<Allocation> imageMemory(
644         memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any));
645 
646     VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
647 
648     const VkAttachmentDescription colorAttDesc = {
649         0u,                                       // flags
650         VK_FORMAT_R8G8B8A8_UNORM,                 // format
651         VK_SAMPLE_COUNT_1_BIT,                    // samples
652         VK_ATTACHMENT_LOAD_OP_CLEAR,              // loadOp
653         VK_ATTACHMENT_STORE_OP_STORE,             // storeOp
654         VK_ATTACHMENT_LOAD_OP_DONT_CARE,          // stencilLoadOp
655         VK_ATTACHMENT_STORE_OP_DONT_CARE,         // stencilStoreOp
656         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
657         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout
658     };
659     const VkAttachmentReference colorAttRef = {
660         0u,                                       // attachment
661         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout
662     };
663     const VkAttachmentReference resolveAttRef = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL};
664     const VkSubpassDescription subpassDesc    = {
665         (VkSubpassDescriptionFlags)0u,   // flags
666         VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
667         0u,                              // inputAttachmentCount
668         DE_NULL,                         // pInputAttachments
669         1u,                              // colorAttachmentCount
670         &colorAttRef,                    // pColorAttachments
671         &resolveAttRef,                  // pResolveAttachments
672         DE_NULL,                         // depthStencilAttachment
673         0u,                              // preserveAttachmentCount
674         DE_NULL,                         // pPreserveAttachments
675     };
676     const VkRenderPassCreateInfo renderPassParams = {
677         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType
678         DE_NULL,                                   // pNext
679         0u,                                        // flags
680         1u,                                        // attachmentCount
681         &colorAttDesc,                             // pAttachments
682         1u,                                        // subpassCount
683         &subpassDesc,                              // pSubpasses
684         0u,                                        // dependencyCount
685         DE_NULL,                                   // pDependencies
686     };
687     const Unique<VkRenderPass> renderPass(createRenderPass(vk, vkDevice, &renderPassParams));
688 
689     const VkImageViewCreateInfo colorAttViewParams = {
690         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                                                         // sType
691         DE_NULL,                                                                                          // pNext
692         0u,                                                                                               // flags
693         *image,                                                                                           // image
694         VK_IMAGE_VIEW_TYPE_2D,                                                                            // viewType
695         VK_FORMAT_R8G8B8A8_UNORM,                                                                         // format
696         {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, // components
697         {
698             VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
699             0u,                        // baseMipLevel
700             1u,                        // levelCount
701             0u,                        // baseArrayLayer
702             1u,                        // layerCount
703         },                             // subresourceRange
704     };
705     const Unique<VkImageView> colorAttView(createImageView(vk, vkDevice, &colorAttViewParams));
706 
707     // Pipeline layout
708     const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
709         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
710         DE_NULL,                                       // pNext
711         (vk::VkPipelineLayoutCreateFlags)0,
712         0u,      // setLayoutCount
713         DE_NULL, // pSetLayouts
714         0u,      // pushConstantRangeCount
715         DE_NULL, // pPushConstantRanges
716     };
717     const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
718 
719     // Shaders
720     const Unique<VkShaderModule> vertShaderModule(
721         createShaderModule(vk, vkDevice, context.getBinaryCollection().get("vert"), 0));
722     const Unique<VkShaderModule> fragShaderModule(
723         createShaderModule(vk, vkDevice, context.getBinaryCollection().get("frag"), 0));
724 
725     // Pipeline
726     const std::vector<VkViewport> viewports(1, makeViewport(renderSize));
727     const std::vector<VkRect2D> scissors(1, makeRect2D(renderSize));
728 
729     const Unique<VkPipeline> pipeline(
730         makeGraphicsPipeline(vk,                // const DeviceInterface&            vk
731                              vkDevice,          // const VkDevice                    device
732                              *pipelineLayout,   // const VkPipelineLayout            pipelineLayout
733                              *vertShaderModule, // const VkShaderModule              vertexShaderModule
734                              DE_NULL,           // const VkShaderModule              tessellationControlShaderModule
735                              DE_NULL,           // const VkShaderModule              tessellationEvalShaderModule
736                              DE_NULL,           // const VkShaderModule              geometryShaderModule
737                              *fragShaderModule, // const VkShaderModule              fragmentShaderModule
738                              *renderPass,       // const VkRenderPass                renderPass
739                              viewports,         // const std::vector<VkViewport>&    viewports
740                              scissors));        // const std::vector<VkRect2D>&      scissors
741 
742     // Framebuffer
743     const VkFramebufferCreateInfo framebufferParams = {
744         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
745         DE_NULL,                                   // pNext
746         0u,                                        // flags
747         *renderPass,                               // renderPass
748         1u,                                        // attachmentCount
749         &*colorAttView,                            // pAttachments
750         (uint32_t)renderSize.x(),                  // width
751         (uint32_t)renderSize.y(),                  // height
752         1u,                                        // layers
753     };
754     const Unique<VkFramebuffer> framebuffer(createFramebuffer(vk, vkDevice, &framebufferParams));
755 
756     const VkCommandPoolCreateInfo cmdPoolParams = {
757         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,      // sType
758         DE_NULL,                                         // pNext
759         VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
760         queueFamilyIndex,                                // queueFamilyIndex
761     };
762     const Unique<VkCommandPool> cmdPool(createCommandPool(vk, vkDevice, &cmdPoolParams));
763 
764     // Command buffer
765     const VkCommandBufferAllocateInfo cmdBufParams = {
766         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
767         DE_NULL,                                        // pNext
768         *cmdPool,                                       // pool
769         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                // level
770         1u,                                             // bufferCount
771     };
772     const Unique<VkCommandBuffer> cmdBuf(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
773 
774     // Record commands
775     beginCommandBuffer(vk, *cmdBuf);
776 
777     {
778         const VkMemoryBarrier vertFlushBarrier = {
779             VK_STRUCTURE_TYPE_MEMORY_BARRIER,    // sType
780             DE_NULL,                             // pNext
781             VK_ACCESS_HOST_WRITE_BIT,            // srcAccessMask
782             VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // dstAccessMask
783         };
784         const VkImageMemoryBarrier colorAttBarrier = {
785             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                       // sType
786             DE_NULL,                                                                      // pNext
787             0u,                                                                           // srcAccessMask
788             (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), // dstAccessMask
789             VK_IMAGE_LAYOUT_UNDEFINED,                                                    // oldLayout
790             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                     // newLayout
791             queueFamilyIndex,                                                             // srcQueueFamilyIndex
792             queueFamilyIndex,                                                             // dstQueueFamilyIndex
793             *image,                                                                       // image
794             {
795                 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
796                 0u,                        // baseMipLevel
797                 1u,                        // levelCount
798                 0u,                        // baseArrayLayer
799                 1u,                        // layerCount
800             }                              // subresourceRange
801         };
802         vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
803                               (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
804                               &colorAttBarrier);
805     }
806 
807     beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()),
808                     clearColor);
809 
810     vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
811     {
812         const VkDeviceSize bindingOffset = 0;
813         vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
814     }
815     vk.cmdDraw(*cmdBuf, 3u, 1u, 0u, 0u);
816     endRenderPass(vk, *cmdBuf);
817     copyImageToBuffer(vk, *cmdBuf, *image, *readImageBuffer, renderSize);
818     endCommandBuffer(vk, *cmdBuf);
819 
820     // Upload vertex data
821     deMemcpy(vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
822     flushAlloc(vk, vkDevice, *vertexBufferMemory);
823 
824     // Submit & wait for completion
825     submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
826 
827     // Read results, render reference, compare
828     {
829         const tcu::TextureFormat tcuFormat = vk::mapVkFormat(colorFormat);
830         const tcu::ConstPixelBufferAccess resultAccess(tcuFormat, renderSize.x(), renderSize.y(), 1,
831                                                        readImageBufferMemory->getHostPtr());
832 
833         invalidateAlloc(vk, vkDevice, *readImageBufferMemory);
834 
835         {
836             tcu::TextureLevel refImage(tcuFormat, renderSize.x(), renderSize.y());
837             const tcu::UVec4 threshold(0u);
838             const tcu::IVec3 posDeviation(1, 1, 0);
839 
840             tcu::clear(refImage.getAccess(), clearColor);
841             renderReferenceTriangle(refImage.getAccess(), vertices,
842                                     context.getDeviceProperties().limits.subPixelPrecisionBits);
843 
844             if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(), "ComparisonResult",
845                                                           "Image comparison result", refImage.getAccess(), resultAccess,
846                                                           threshold, posDeviation, false, tcu::COMPARE_LOG_RESULT))
847                 return tcu::TestStatus::pass("Rendering succeeded");
848             else
849                 return tcu::TestStatus::fail("Image comparison failed");
850         }
851     }
852 
853     return tcu::TestStatus::pass("Rendering succeeded");
854 }
855 
856 } // namespace
857 
createSmokeTests(tcu::TestContext & testCtx)858 tcu::TestCaseGroup *createSmokeTests(tcu::TestContext &testCtx)
859 {
860     de::MovePtr<tcu::TestCaseGroup> smokeTests(new tcu::TestCaseGroup(testCtx, "smoke"));
861 
862     addFunctionCase(smokeTests.get(), "create_sampler", createSamplerTest);
863     addFunctionCaseWithPrograms(smokeTests.get(), "create_shader", createShaderProgs, createShaderModuleTest);
864     addFunctionCaseWithPrograms(smokeTests.get(), "triangle", createTriangleProgs, renderTriangleTest);
865     addFunctionCaseWithPrograms(smokeTests.get(), "asm_triangle", createTriangleAsmProgs, renderTriangleTest);
866     addFunctionCaseWithPrograms(smokeTests.get(), "asm_triangle_no_opname", createProgsNoOpName, renderTriangleTest);
867     addFunctionCaseWithPrograms(smokeTests.get(), "unused_resolve_attachment", createTriangleProgs,
868                                 renderTriangleUnusedResolveAttachmentTest);
869 
870     return smokeTests.release();
871 }
872 
873 } // namespace api
874 } // namespace vkt
875