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